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;
344 init_lookup_list(void)
346 #ifdef LOOKUP_MODULE_DIR
349 int countmodules = 0;
350 int moduleerrors = 0;
352 static BOOL lookup_list_init_done = FALSE;
354 if (lookup_list_init_done)
356 lookup_list_init_done = TRUE;
358 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
359 addlookupmodule(&cdb_lookup_module_info);
362 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
363 addlookupmodule(&dbmdb_lookup_module_info);
366 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
367 addlookupmodule(&dnsdb_lookup_module_info);
370 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
371 addlookupmodule(&dsearch_lookup_module_info);
374 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
375 addlookupmodule(&ibase_lookup_module_info);
378 #if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
379 addlookupmodule(&ldap_lookup_module_info);
382 #if defined(LOOKUP_JSON) && LOOKUP_JSON!=2
383 addlookupmodule(&json_lookup_module_info);
386 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
387 addlookupmodule(&lsearch_lookup_module_info);
390 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
391 addlookupmodule(&mysql_lookup_module_info);
394 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
395 addlookupmodule(&nis_lookup_module_info);
398 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
399 addlookupmodule(&nisplus_lookup_module_info);
402 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
403 addlookupmodule(&oracle_lookup_module_info);
406 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
407 addlookupmodule(&passwd_lookup_module_info);
410 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
411 addlookupmodule(&pgsql_lookup_module_info);
414 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
415 addlookupmodule(&redis_lookup_module_info);
418 #if defined(LOOKUP_LMDB) && LOOKUP_LMDB!=2
419 addlookupmodule(&lmdb_lookup_module_info);
423 addlookupmodule(&spf_lookup_module_info);
426 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
427 addlookupmodule(&sqlite_lookup_module_info);
430 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
431 addlookupmodule(&testdb_lookup_module_info);
434 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
435 addlookupmodule(&whoson_lookup_module_info);
438 /* This is a custom expansion, and not available as either
439 a list-syntax lookup or a lookup expansion. However, it is
440 implemented by a lookup module. */
442 addlookupmodule(&readsock_lookup_module_info);
444 #ifdef LOOKUP_MODULE_DIR
445 if (!(dd = exim_opendir(CUS LOOKUP_MODULE_DIR)))
447 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
448 log_write(0, LOG_MAIN|LOG_PANIC,
449 "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
453 const pcre2_code * regex_islookupmod = regex_must_compile(
454 US"_lookup\\." DYNLIB_FN_EXT "$", MCS_NOFLAGS, TRUE);
456 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
457 while ((ent = readdir(dd)))
459 char * name = ent->d_name;
460 int len = (int)strlen(name);
461 if (regex_match(regex_islookupmod, US name, len, NULL))
463 int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
465 struct lookup_module_info *info;
466 const char *errormsg;
468 /* SRH: am I being paranoid here or what? */
469 if (pathnamelen > big_buffer_size)
471 fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
472 log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
476 /* SRH: snprintf here? */
477 sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
479 if (!(dl = dlopen(CS big_buffer, RTLD_NOW)))
481 errormsg = dlerror();
482 fprintf(stderr, "Error loading %s: %s\n", name, errormsg);
483 log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, errormsg);
488 /* FreeBSD nsdispatch() can trigger dlerror() errors about
489 _nss_cache_cycle_prevention_function; we need to clear the dlerror()
490 state before calling dlsym(), so that any error afterwards only comes
493 errormsg = dlerror();
495 info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
496 if ((errormsg = dlerror()))
498 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
499 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
504 if (info->magic != LOOKUP_MODULE_INFO_MAGIC)
506 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
507 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
513 addlookupmodule(info);
514 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
518 store_free((void*)regex_islookupmod);
522 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
525 DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
529 #endif /*!MACRO_PREDEF*/
530 /* End of drtables.c */