1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) The Exim Maintainers 2020 - 2024 */
6 /* Copyright (c) University of Cambridge 1995 - 2018 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
15 /* This module contains tables that define the lookup methods and drivers
16 that are actually included in the binary. Its contents are controlled by
17 various macros in config.h that ultimately come from Local/Makefile. They are
18 all described in src/EDITME. */
21 //lookup_info **lookup_list;
22 tree_node * lookups_tree = NULL;
23 unsigned lookup_list_count = 0;
25 /* Lists of information about which drivers are included in the exim binary. */
27 auth_info * auths_available= NULL;
28 router_info * routers_available = NULL;
29 transport_info * transports_available = NULL;
36 auth_show_supported(gstring * g)
38 uschar * b = US"" /* static-build authenticatornames */
39 #if defined(AUTH_CRAM_MD5) && AUTH_CRAM_MD5!=2
42 #if defined(AUTH_CYRUS_SASL) && AUTH_CYRUS_SASL!=2
45 #if defined(AUTH_DOVECOT) && AUTH_DOVECOT!=2
48 #if defined(AUTH_EXTERNAL) && AUTH_EXTERNAL!=2
51 #if defined(AUTH_GSASL) && AUTH_GSASL!=2
54 #if defined(AUTH_HEIMDAL_GSSAPI) && AUTH_HEIMDAL_GSSAPI!=2
57 #if defined(AUTH_PLAINTEXT) && AUTH_PLAINTEXT!=2
60 #if defined(AUTH_SPA) && AUTH_SPA!=2
63 #if defined(AUTH_TLS) && AUTH_TLS!=2
68 uschar * d = US"" /* dynamic-module authenticator names */
69 #if defined(AUTH_CRAM_MD5) && AUTH_CRAM_MD5==2
72 #if defined(AUTH_CYRUS_SASL) && AUTH_CYRUS_SASL==2
75 #if defined(AUTH_DOVECOT) && AUTH_DOVECOT==2
78 #if defined(AUTH_EXTERNAL) && AUTH_EXTERNAL==2
81 #if defined(AUTH_GSASL) && AUTH_GSASL==2
84 #if defined(AUTH_HEIMDAL_GSSAPI) && AUTH_HEIMDAL_GSSAPI==2
87 #if defined(AUTH_PLAINTEXT) && AUTH_PLAINTEXT==2
90 #if defined(AUTH_SPA) && AUTH_SPA==2
93 #if defined(AUTH_TLS) && AUTH_TLS==2
98 if (*b) g = string_fmt_append(g, "Authenticators (built-in):%s\n", b);
99 if (*d) g = string_fmt_append(g, "Authenticators (dynamic): %s\n", d);
104 route_show_supported(gstring * g)
106 uschar * b = US"" /* static-build router names */
107 #if defined(ROUTER_ACCEPT) && ROUTER_ACCEPT!=2
110 #if defined(ROUTER_DNSLOOKUP) && ROUTER_DNSLOOKUP!=2
113 # if defined(ROUTER_IPLITERAL) && ROUTER_IPLITERAL!=2
116 #if defined(ROUTER_IPLOOKUP) && ROUTER_IPLOOKUP!=2
119 #if defined(ROUTER_MANUALROUTE) && ROUTER_MANUALROUTE!=2
122 #if defined(ROUTER_REDIRECT) && ROUTER_REDIRECT!=2
125 #if defined(ROUTER_QUERYPROGRAM) && ROUTER_QUERYPROGRAM!=2
130 uschar * d = US"" /* dynamic-module router names */
131 #if defined(ROUTER_ACCEPT) && ROUTER_ACCEPT==2
134 #if defined(ROUTER_DNSLOOKUP) && ROUTER_DNSLOOKUP==2
137 # if defined(ROUTER_IPLITERAL) && ROUTER_IPLITERAL==2
140 #if defined(ROUTER_IPLOOKUP) && ROUTER_IPLOOKUP==2
143 #if defined(ROUTER_MANUALROUTE) && ROUTER_MANUALROUTE==2
146 #if defined(ROUTER_REDIRECT) && ROUTER_REDIRECT==2
149 #if defined(ROUTER_QUERYPROGRAM) && ROUTER_QUERYPROGRAM==2
154 if (*b) g = string_fmt_append(g, "Routers (built-in):%s\n", b);
155 if (*d) g = string_fmt_append(g, "Routers (dynamic): %s\n", d);
160 transport_show_supported(gstring * g)
162 uschar * b = US"" /* static-build transportnames */
163 #if defined(TRANSPORT_APPENDFILE) && TRANSPORT_APPENDFILE!=2
165 # ifdef SUPPORT_MAILDIR
168 # ifdef SUPPORT_MAILSTORE
175 #if defined(TRANSPORT_AUTOREPLY) && TRANSPORT_AUTOREPLY!=2
178 #if defined(TRANSPORT_LMTP) && TRANSPORT_LMTP!=2
181 #if defined(TRANSPORT_PIPE) && TRANSPORT_PIPE!=2
184 #if defined(EXPERIMENTAL_QUEUEFILE) && EXPERIMENTAL_QUEUEFILE!=2
187 #if defined(TRANSPORT_SMTP) && TRANSPORT_SMTP!=2
192 uschar * d = US"" /* dynamic-module transportnames */
193 #if defined(TRANSPORT_APPENDFILE) && TRANSPORT_APPENDFILE==2
195 # ifdef SUPPORT_MAILDIR
198 # ifdef SUPPORT_MAILSTORE
205 #if defined(TRANSPORT_AUTOREPLY) && TRANSPORT_AUTOREPLY==2
208 #if defined(TRANSPORT_LMTP) && TRANSPORT_LMTP==2
211 #if defined(TRANSPORT_PIPE) && TRANSPORT_PIPE==2
214 #if defined(EXPERIMENTAL_QUEUEFILE) && EXPERIMENTAL_QUEUEFILE==2
217 #if defined(TRANSPORT_SMTP) && TRANSPORT_SMTP==2
222 if (*b) g = string_fmt_append(g, "Transports (built-in):%s\n", b);
223 if (*d) g = string_fmt_append(g, "Transports (dynamic): %s\n", d);
230 add_lookup_to_tree(lookup_info * li)
232 tree_node * new = store_get_perm(sizeof(tree_node) + Ustrlen(li->name),
234 new->data.ptr = (void *)li;
235 Ustrcpy(new->name, li->name);
236 if (tree_insertnode(&lookups_tree, new))
237 li->acq_num = lookup_list_count++;
239 log_write(0, LOG_MAIN|LOG_PANIC, "Duplicate lookup name '%s'", li->name);
243 /* Add all the lookup types provided by the module */
245 addlookupmodule(const struct lookup_module_info * lmi)
247 for (int j = 0; j < lmi->lookupcount; j++)
248 add_lookup_to_tree(lmi->lookups[j]);
253 static unsigned hunt_acq;
256 acq_cb(uschar * name, uschar * ptr, void * ctx)
258 lookup_info * li = (lookup_info *)ptr;
259 if (li->acq_num == hunt_acq) *(lookup_info **)ctx = li;
262 /*XXX many of the calls here could instead use a name on the quoted-pool */
264 lookup_with_acq_num(unsigned k)
266 const lookup_info * li = NULL;
268 tree_walk(lookups_tree, acq_cb, &li);
274 /* These need to be at file level for old versions of gcc (2.95.2 reported),
275 which give parse errors on an extern in function scope. Each entry needs
276 to also be invoked in init_lookup_list() below */
278 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
279 extern lookup_module_info cdb_lookup_module_info;
281 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
282 extern lookup_module_info dbmdb_lookup_module_info;
284 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
285 extern lookup_module_info dnsdb_lookup_module_info;
287 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
288 extern lookup_module_info dsearch_lookup_module_info;
290 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
291 extern lookup_module_info ibase_lookup_module_info;
293 #if defined(LOOKUP_JSON) && LOOKUP_JSON!=2
294 extern lookup_module_info json_lookup_module_info;
296 #if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
297 extern lookup_module_info ldap_lookup_module_info;
299 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
300 extern lookup_module_info lsearch_lookup_module_info;
302 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
303 extern lookup_module_info mysql_lookup_module_info;
305 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
306 extern lookup_module_info nis_lookup_module_info;
308 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
309 extern lookup_module_info nisplus_lookup_module_info;
311 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
312 extern lookup_module_info oracle_lookup_module_info;
314 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
315 extern lookup_module_info passwd_lookup_module_info;
317 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
318 extern lookup_module_info pgsql_lookup_module_info;
320 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
321 extern lookup_module_info redis_lookup_module_info;
323 #if defined(LOOKUP_LMDB) && LOOKUP_LMDB!=2
324 extern lookup_module_info lmdb_lookup_module_info;
326 #if defined(SUPPORT_SPF)
327 extern lookup_module_info spf_lookup_module_info;
329 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
330 extern lookup_module_info sqlite_lookup_module_info;
332 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
333 extern lookup_module_info testdb_lookup_module_info;
335 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
336 extern lookup_module_info whoson_lookup_module_info;
339 extern lookup_module_info readsock_lookup_module_info;
343 init_lookup_list(void)
345 #ifdef LOOKUP_MODULE_DIR
348 int countmodules = 0;
349 int moduleerrors = 0;
351 static BOOL lookup_list_init_done = FALSE;
353 if (lookup_list_init_done)
355 lookup_list_init_done = TRUE;
357 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
358 addlookupmodule(&cdb_lookup_module_info);
361 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
362 addlookupmodule(&dbmdb_lookup_module_info);
365 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
366 addlookupmodule(&dnsdb_lookup_module_info);
369 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
370 addlookupmodule(&dsearch_lookup_module_info);
373 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
374 addlookupmodule(&ibase_lookup_module_info);
377 #if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
378 addlookupmodule(&ldap_lookup_module_info);
381 #if defined(LOOKUP_JSON) && LOOKUP_JSON!=2
382 addlookupmodule(&json_lookup_module_info);
385 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
386 addlookupmodule(&lsearch_lookup_module_info);
389 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
390 addlookupmodule(&mysql_lookup_module_info);
393 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
394 addlookupmodule(&nis_lookup_module_info);
397 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
398 addlookupmodule(&nisplus_lookup_module_info);
401 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
402 addlookupmodule(&oracle_lookup_module_info);
405 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
406 addlookupmodule(&passwd_lookup_module_info);
409 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
410 addlookupmodule(&pgsql_lookup_module_info);
413 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
414 addlookupmodule(&redis_lookup_module_info);
417 #if defined(LOOKUP_LMDB) && LOOKUP_LMDB!=2
418 addlookupmodule(&lmdb_lookup_module_info);
422 addlookupmodule(&spf_lookup_module_info);
425 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
426 addlookupmodule(&sqlite_lookup_module_info);
429 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
430 addlookupmodule(&testdb_lookup_module_info);
433 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
434 addlookupmodule(&whoson_lookup_module_info);
437 /* This is a custom expansion, and not available as either
438 a list-syntax lookup or a lookup expansion. However, it is
439 implemented by a lookup module. */
441 addlookupmodule(&readsock_lookup_module_info);
443 #ifdef LOOKUP_MODULE_DIR
444 if (!(dd = exim_opendir(CUS LOOKUP_MODULE_DIR)))
446 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
447 log_write(0, LOG_MAIN|LOG_PANIC,
448 "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
452 const pcre2_code * regex_islookupmod = regex_must_compile(
453 US"_lookup\\." DYNLIB_FN_EXT "$", MCS_NOFLAGS, TRUE);
455 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
456 while ((ent = readdir(dd)))
458 char * name = ent->d_name;
459 int len = (int)strlen(name);
460 if (regex_match(regex_islookupmod, US name, len, NULL))
462 int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
464 struct lookup_module_info *info;
465 const char *errormsg;
467 /* SRH: am I being paranoid here or what? */
468 if (pathnamelen > big_buffer_size)
470 fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
471 log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
475 /* SRH: snprintf here? */
476 sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
478 if (!(dl = dlopen(CS big_buffer, RTLD_NOW)))
480 errormsg = dlerror();
481 fprintf(stderr, "Error loading %s: %s\n", name, errormsg);
482 log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, errormsg);
487 /* FreeBSD nsdispatch() can trigger dlerror() errors about
488 _nss_cache_cycle_prevention_function; we need to clear the dlerror()
489 state before calling dlsym(), so that any error afterwards only comes
492 errormsg = dlerror();
494 info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
495 if ((errormsg = dlerror()))
497 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
498 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
503 if (info->magic != LOOKUP_MODULE_INFO_MAGIC)
505 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
506 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
512 addlookupmodule(info);
513 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
517 store_free((void*)regex_islookupmod);
521 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
524 DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
528 #endif /*!MACRO_PREDEF*/
529 /* End of drtables.c */