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 /* Hunt for the lookup with the given acquisition number */
255 static unsigned hunt_acq;
258 acq_cb(uschar * name, uschar * ptr, void * ctx)
260 lookup_info * li = (lookup_info *)ptr;
261 if (li->acq_num == hunt_acq) *(lookup_info **)ctx = li;
265 lookup_with_acq_num(unsigned k)
267 const lookup_info * li = NULL;
269 tree_walk(lookups_tree, acq_cb, &li);
275 /* These need to be at file level for old versions of gcc (2.95.2 reported),
276 which give parse errors on an extern in function scope. Each entry needs
277 to also be invoked in init_lookup_list() below */
279 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
280 extern lookup_module_info cdb_lookup_module_info;
282 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
283 extern lookup_module_info dbmdb_lookup_module_info;
285 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
286 extern lookup_module_info dnsdb_lookup_module_info;
288 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
289 extern lookup_module_info dsearch_lookup_module_info;
291 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
292 extern lookup_module_info ibase_lookup_module_info;
294 #if defined(LOOKUP_JSON) && LOOKUP_JSON!=2
295 extern lookup_module_info json_lookup_module_info;
297 #if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
298 extern lookup_module_info ldap_lookup_module_info;
300 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
301 extern lookup_module_info lsearch_lookup_module_info;
303 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
304 extern lookup_module_info mysql_lookup_module_info;
306 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
307 extern lookup_module_info nis_lookup_module_info;
309 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
310 extern lookup_module_info nisplus_lookup_module_info;
312 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
313 extern lookup_module_info oracle_lookup_module_info;
315 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
316 extern lookup_module_info passwd_lookup_module_info;
318 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
319 extern lookup_module_info pgsql_lookup_module_info;
321 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
322 extern lookup_module_info redis_lookup_module_info;
324 #if defined(LOOKUP_LMDB) && LOOKUP_LMDB!=2
325 extern lookup_module_info lmdb_lookup_module_info;
327 #if defined(SUPPORT_SPF)
328 extern lookup_module_info spf_lookup_module_info;
330 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
331 extern lookup_module_info sqlite_lookup_module_info;
333 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
334 extern lookup_module_info testdb_lookup_module_info;
336 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
337 extern lookup_module_info whoson_lookup_module_info;
340 extern lookup_module_info readsock_lookup_module_info;
343 #ifdef LOOKUP_MODULE_DIR
344 /* Try to load a lookup module with the given name.
347 name name of the lookup
348 errstr if not NULL, place "open fail" error message here
350 Return: boolean success
354 lookup_mod_load(const uschar * name, uschar ** errstr)
356 const uschar * path = string_sprintf(
357 LOOKUP_MODULE_DIR "/%s_lookup." DYNLIB_FN_EXT, name);
359 struct lookup_module_info * info;
360 const char * errormsg;
362 if (!(dl = dlopen(CS path, RTLD_NOW)))
365 *errstr = string_sprintf("Error loading %s: %s", name, dlerror());
367 (void) dlerror(); /* clear out error state */
371 /* FreeBSD nsdispatch() can trigger dlerror() errors about
372 _nss_cache_cycle_prevention_function; we need to clear the dlerror()
373 state before calling dlsym(), so that any error afterwards only comes
376 errormsg = dlerror();
378 info = (struct lookup_module_info *) dlsym(dl, "_lookup_module_info");
379 if ((errormsg = dlerror()))
381 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
382 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)", name, errormsg);
386 if (info->magic != LOOKUP_MODULE_INFO_MAGIC)
388 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
389 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim", name);
394 addlookupmodule(info);
395 DEBUG(D_lookup) debug_printf_indent("Loaded \"%s\" (%d lookup type%s)\n",
396 name, info->lookupcount,
397 info->lookupcount > 1 ? "s" : "");
402 /* Try to load a lookup module, assuming the module name is the same
403 as the lookup type name. This will only work for single-method modules.
404 Other have to be always-load (see the RE in init_lookup_list() below).
408 lookup_one_mod_load(const uschar * name, uschar ** errstr)
410 if (!lookup_mod_load(name, errstr)) return FALSE;
411 /*XXX notify daemon? */
415 #endif /*LOOKUP_MODULE_DIR*/
422 init_lookup_list(void)
424 #ifdef LOOKUP_MODULE_DIR
426 int countmodules = 0;
428 static BOOL lookup_list_init_done = FALSE;
430 if (lookup_list_init_done)
432 lookup_list_init_done = TRUE;
434 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
435 addlookupmodule(&cdb_lookup_module_info);
438 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
439 addlookupmodule(&dbmdb_lookup_module_info);
442 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
443 addlookupmodule(&dnsdb_lookup_module_info);
446 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
447 addlookupmodule(&dsearch_lookup_module_info);
450 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
451 addlookupmodule(&ibase_lookup_module_info);
454 #if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
455 addlookupmodule(&ldap_lookup_module_info);
458 #if defined(LOOKUP_JSON) && LOOKUP_JSON!=2
459 addlookupmodule(&json_lookup_module_info);
462 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
463 addlookupmodule(&lsearch_lookup_module_info);
466 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
467 addlookupmodule(&mysql_lookup_module_info);
470 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
471 addlookupmodule(&nis_lookup_module_info);
474 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
475 addlookupmodule(&nisplus_lookup_module_info);
478 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
479 addlookupmodule(&oracle_lookup_module_info);
482 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
483 addlookupmodule(&passwd_lookup_module_info);
486 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
487 addlookupmodule(&pgsql_lookup_module_info);
490 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
491 addlookupmodule(&redis_lookup_module_info);
494 #if defined(LOOKUP_LMDB) && LOOKUP_LMDB!=2
495 addlookupmodule(&lmdb_lookup_module_info);
499 addlookupmodule(&spf_lookup_module_info);
502 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
503 addlookupmodule(&sqlite_lookup_module_info);
506 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
507 addlookupmodule(&testdb_lookup_module_info);
510 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
511 addlookupmodule(&whoson_lookup_module_info);
514 /* This is a custom expansion, and not available as either
515 a list-syntax lookup or a lookup expansion. However, it is
516 implemented by a lookup module. */
518 addlookupmodule(&readsock_lookup_module_info);
520 DEBUG(D_lookup) debug_printf("Total %d built-in lookups\n", lookup_list_count);
523 #ifdef LOOKUP_MODULE_DIR
524 if (!(dd = exim_opendir(CUS LOOKUP_MODULE_DIR)))
526 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
527 log_write(0, LOG_MAIN|LOG_PANIC,
528 "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
532 /* Look specifically for modules we know offer several lookup types and
533 load them now, since we cannot load-on-first-use. */
536 const pcre2_code * regex_islookupmod = regex_must_compile(
537 US"(lsearch|ldap|nis)_lookup\\." DYNLIB_FN_EXT "$", MCS_NOFLAGS, TRUE);
539 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
540 while ((ent = readdir(dd)))
542 char * name = ent->d_name;
543 int len = (int)strlen(name);
544 if (regex_match_and_setup(regex_islookupmod, US name, 0, 0))
547 if (lookup_mod_load(expand_nstring[1], &errstr))
551 fprintf(stderr, "%s\n", errstr);
552 log_write(0, LOG_MAIN|LOG_PANIC, "%s", errstr);
559 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
566 #endif /*!MACRO_PREDEF*/
567 /* End of drtables.c */