1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) University of Cambridge 1995 - 2017 */
6 /* See the file NOTICE for conditions of use and distribution. */
13 /* This module contains tables that define the lookup methods and drivers
14 that are actually included in the binary. Its contents are controlled by
15 various macros in config.h that ultimately come from Local/Makefile. They are
16 all described in src/EDITME. */
19 lookup_info **lookup_list;
20 int lookup_list_count = 0;
22 /* Table of information about all possible authentication mechanisms. All
23 entries are always present if any mechanism is declared, but the functions are
24 set to NULL for those that are not compiled into the binary. */
27 #include "auths/cram_md5.h"
30 #ifdef AUTH_CYRUS_SASL
31 #include "auths/cyrus_sasl.h"
35 #include "auths/dovecot.h"
39 #include "auths/gsasl_exim.h"
42 #ifdef AUTH_HEIMDAL_GSSAPI
43 #include "auths/heimdal_gssapi.h"
47 #include "auths/plaintext.h"
51 #include "auths/spa.h"
55 #include "auths/tls.h"
58 auth_info auths_available[] = {
60 /* Checking by an expansion condition on plain text */
64 .driver_name = US"cram_md5", /* lookup name */
65 .options = auth_cram_md5_options,
66 .options_count = &auth_cram_md5_options_count,
67 .options_block = &auth_cram_md5_option_defaults,
68 .options_len = sizeof(auth_cram_md5_options_block),
69 .init = auth_cram_md5_init,
70 .servercode = auth_cram_md5_server,
71 .clientcode = auth_cram_md5_client,
72 .version_report = NULL
76 #ifdef AUTH_CYRUS_SASL
78 .driver_name = US"cyrus_sasl",
79 .options = auth_cyrus_sasl_options,
80 .options_count = &auth_cyrus_sasl_options_count,
81 .options_block = &auth_cyrus_sasl_option_defaults,
82 .options_len = sizeof(auth_cyrus_sasl_options_block),
83 .init = auth_cyrus_sasl_init,
84 .servercode = auth_cyrus_sasl_server,
86 .version_report = auth_cyrus_sasl_version_report
92 .driver_name = US"dovecot",
93 .options = auth_dovecot_options,
94 .options_count = &auth_dovecot_options_count,
95 .options_block = &auth_dovecot_option_defaults,
96 .options_len = sizeof(auth_dovecot_options_block),
97 .init = auth_dovecot_init,
98 .servercode = auth_dovecot_server,
100 .version_report = NULL
106 .driver_name = US"gsasl",
107 .options = auth_gsasl_options,
108 .options_count = &auth_gsasl_options_count,
109 .options_block = &auth_gsasl_option_defaults,
110 .options_len = sizeof(auth_gsasl_options_block),
111 .init = auth_gsasl_init,
112 .servercode = auth_gsasl_server,
114 .version_report = auth_gsasl_version_report
118 #ifdef AUTH_HEIMDAL_GSSAPI
120 .driver_name = US"heimdal_gssapi",
121 .options = auth_heimdal_gssapi_options,
122 .options_count &auth_heimdal_gssapi_options_count,
123 .options_block = &auth_heimdal_gssapi_option_defaults,
124 .options_len = sizeof(auth_heimdal_gssapi_options_block),
125 .init = auth_heimdal_gssapi_init,
126 .servercode = auth_heimdal_gssapi_server,
128 .version_report = auth_heimdal_gssapi_version_report
132 #ifdef AUTH_PLAINTEXT
134 .driver_name = US"plaintext",
135 .options = auth_plaintext_options,
136 .options_count = &auth_plaintext_options_count,
137 .options_block = &auth_plaintext_option_defaults,
138 .options_len = sizeof(auth_plaintext_options_block),
139 .init = auth_plaintext_init,
140 .servercode = auth_plaintext_server,
141 .clientcode = auth_plaintext_client,
142 .version_report = NULL
148 .driver_name = US"spa",
149 .options = auth_spa_options,
150 .options_count = &auth_spa_options_count,
151 .options_block = &auth_spa_option_defaults,
152 .options_len = sizeof(auth_spa_options_block),
153 .init = auth_spa_init,
154 .servercode = auth_spa_server,
155 .clientcode = auth_spa_client,
156 .version_report = NULL
162 .driver_name = US"tls",
163 .options = auth_tls_options,
164 .options_count = &auth_tls_options_count,
165 .options_block = &auth_tls_option_defaults,
166 .options_len = sizeof(auth_tls_options_block),
167 .init = auth_tls_init,
168 .servercode = auth_tls_server,
170 .version_report = NULL
174 { .driver_name = US"" } /* end marker */
178 auth_show_supported(FILE * f)
181 fprintf(f, "Authenticators:");
182 for (ai = auths_available; ai->driver_name[0]; ai++)
183 fprintf(f, " %s", ai->driver_name);
188 /* Tables of information about which routers and transports are included in the
191 /* Pull in the necessary header files */
193 #include "routers/rf_functions.h"
196 #include "routers/accept.h"
199 #ifdef ROUTER_DNSLOOKUP
200 #include "routers/dnslookup.h"
203 #ifdef ROUTER_MANUALROUTE
204 #include "routers/manualroute.h"
207 #ifdef ROUTER_IPLITERAL
208 #include "routers/ipliteral.h"
211 #ifdef ROUTER_IPLOOKUP
212 #include "routers/iplookup.h"
215 #ifdef ROUTER_QUERYPROGRAM
216 #include "routers/queryprogram.h"
219 #ifdef ROUTER_REDIRECT
220 #include "routers/redirect.h"
223 #ifdef TRANSPORT_APPENDFILE
224 #include "transports/appendfile.h"
227 #ifdef TRANSPORT_AUTOREPLY
228 #include "transports/autoreply.h"
231 #ifdef TRANSPORT_LMTP
232 #include "transports/lmtp.h"
235 #ifdef TRANSPORT_PIPE
236 #include "transports/pipe.h"
239 #ifdef EXPERIMENTAL_QUEUEFILE
240 #include "transports/queuefile.h"
243 #ifdef TRANSPORT_SMTP
244 #include "transports/smtp.h"
248 /* Now set up the structures, terminated by an entry with a null name. */
250 router_info routers_available[] = {
253 .driver_name = US"accept",
254 .options = accept_router_options,
255 .options_count = &accept_router_options_count,
256 .options_block = &accept_router_option_defaults,
257 .options_len = sizeof(accept_router_options_block),
258 .init = accept_router_init,
259 .code = accept_router_entry,
260 .tidyup = NULL, /* no tidyup entry */
261 .ri_flags = ri_yestransport
264 #ifdef ROUTER_DNSLOOKUP
266 .driver_name = US"dnslookup",
267 .options = dnslookup_router_options,
268 .options_count = &dnslookup_router_options_count,
269 .options_block = &dnslookup_router_option_defaults,
270 .options_len = sizeof(dnslookup_router_options_block),
271 .init = dnslookup_router_init,
272 .code = dnslookup_router_entry,
273 .tidyup = NULL, /* no tidyup entry */
274 .ri_flags = ri_yestransport
277 #ifdef ROUTER_IPLITERAL
279 .driver_name = US"ipliteral",
280 .options = ipliteral_router_options,
281 .options_count = &ipliteral_router_options_count,
282 .options_block = &ipliteral_router_option_defaults,
283 .options_len = sizeof(ipliteral_router_options_block),
284 .init = ipliteral_router_init,
285 .code = ipliteral_router_entry,
286 .tidyup = NULL, /* no tidyup entry */
287 .ri_flags = ri_yestransport
290 #ifdef ROUTER_IPLOOKUP
292 .driver_name = US"iplookup",
293 .options = iplookup_router_options,
294 .options_count = &iplookup_router_options_count,
295 .options_block = &iplookup_router_option_defaults,
296 .options_len = sizeof(iplookup_router_options_block),
297 .init = iplookup_router_init,
298 .code = iplookup_router_entry,
299 .tidyup = NULL, /* no tidyup entry */
300 .ri_flags = ri_notransport
303 #ifdef ROUTER_MANUALROUTE
305 .driver_name = US"manualroute",
306 .options = manualroute_router_options,
307 .options_count = &manualroute_router_options_count,
308 .options_block = &manualroute_router_option_defaults,
309 .options_len = sizeof(manualroute_router_options_block),
310 .init = manualroute_router_init,
311 .code = manualroute_router_entry,
312 .tidyup = NULL, /* no tidyup entry */
316 #ifdef ROUTER_QUERYPROGRAM
318 .driver_name = US"queryprogram",
319 .options = queryprogram_router_options,
320 .options_count = &queryprogram_router_options_count,
321 .options_block = &queryprogram_router_option_defaults,
322 .options_len = sizeof(queryprogram_router_options_block),
323 .init = queryprogram_router_init,
324 .code = queryprogram_router_entry,
325 .tidyup = NULL, /* no tidyup entry */
329 #ifdef ROUTER_REDIRECT
331 .driver_name = US"redirect",
332 .options = redirect_router_options,
333 .options_count = &redirect_router_options_count,
334 .options_block = &redirect_router_option_defaults,
335 .options_len = sizeof(redirect_router_options_block),
336 .init = redirect_router_init,
337 .code = redirect_router_entry,
338 .tidyup = NULL, /* no tidyup entry */
339 .ri_flags = ri_notransport
347 route_show_supported(FILE * f)
350 fprintf(f, "Routers:");
351 for (rr = routers_available; rr->driver_name[0]; rr++)
352 fprintf(f, " %s", rr->driver_name);
359 transport_info transports_available[] = {
360 #ifdef TRANSPORT_APPENDFILE
362 .driver_name = US"appendfile",
363 .options = appendfile_transport_options,
364 .options_count = &appendfile_transport_options_count,
365 .options_block = &appendfile_transport_option_defaults, /* private options defaults */
366 .options_len = sizeof(appendfile_transport_options_block),
367 .init = appendfile_transport_init,
368 .code = appendfile_transport_entry,
374 #ifdef TRANSPORT_AUTOREPLY
376 .driver_name = US"autoreply",
377 .options = autoreply_transport_options,
378 .options_count = &autoreply_transport_options_count,
379 .options_block = &autoreply_transport_option_defaults,
380 .options_len = sizeof(autoreply_transport_options_block),
381 .init = autoreply_transport_init,
382 .code = autoreply_transport_entry,
388 #ifdef TRANSPORT_LMTP
390 .driver_name = US"lmtp",
391 .options = lmtp_transport_options,
392 .options_count = &lmtp_transport_options_count,
393 .options_block = &lmtp_transport_option_defaults,
394 .options_len = sizeof(lmtp_transport_options_block),
395 .init = lmtp_transport_init,
396 .code = lmtp_transport_entry,
402 #ifdef TRANSPORT_PIPE
404 .driver_name = US"pipe",
405 .options = pipe_transport_options,
406 .options_count = &pipe_transport_options_count,
407 .options_block = &pipe_transport_option_defaults,
408 .options_len = sizeof(pipe_transport_options_block),
409 .init = pipe_transport_init,
410 .code = pipe_transport_entry,
416 #ifdef EXPERIMENTAL_QUEUEFILE
418 .driver_name = US"queuefile",
419 .options = queuefile_transport_options,
420 .options_count = &queuefile_transport_options_count,
421 .options_block = &queuefile_transport_option_defaults,
422 .options_len = sizeof(queuefile_transport_options_block),
423 .init = queuefile_transport_init,
424 .code = queuefile_transport_entry,
430 #ifdef TRANSPORT_SMTP
432 .driver_name = US"smtp",
433 .options = smtp_transport_options,
434 .options_count = &smtp_transport_options_count,
435 .options_block = &smtp_transport_option_defaults,
436 .options_len = sizeof(smtp_transport_options_block),
437 .init = smtp_transport_init,
438 .code = smtp_transport_entry,
440 .closedown = smtp_transport_closedown,
448 transport_show_supported(FILE * f)
450 fprintf(f, "Transports:");
451 #ifdef TRANSPORT_APPENDFILE
452 fprintf(f, " appendfile");
453 #ifdef SUPPORT_MAILDIR
454 fprintf(f, "/maildir"); /* damn these subclasses */
456 #ifdef SUPPORT_MAILSTORE
457 fprintf(f, "/mailstore");
463 #ifdef TRANSPORT_AUTOREPLY
464 fprintf(f, " autoreply");
466 #ifdef TRANSPORT_LMTP
469 #ifdef TRANSPORT_PIPE
472 #ifdef EXPERIMENTAL_QUEUEFILE
473 fprintf(f, " queuefile");
475 #ifdef TRANSPORT_SMTP
484 struct lookupmodulestr
487 struct lookup_module_info *info;
488 struct lookupmodulestr *next;
491 static struct lookupmodulestr *lookupmodules = NULL;
494 addlookupmodule(void *dl, struct lookup_module_info *info)
496 struct lookupmodulestr *p = store_malloc(sizeof(struct lookupmodulestr));
500 p->next = lookupmodules;
502 lookup_list_count += info->lookupcount;
505 /* only valid after lookup_list and lookup_list_count are assigned */
507 add_lookup_to_list(lookup_info *info)
509 /* need to add the lookup to lookup_list, sorted */
512 /* strategy is to go through the list until we find
513 either an empty spot or a name that is higher.
514 this can't fail because we have enough space. */
516 while (lookup_list[pos] && (Ustrcmp(lookup_list[pos]->name, info->name) <= 0))
519 if (lookup_list[pos])
521 /* need to insert it, so move all the other items up
522 (last slot is still empty, of course) */
524 memmove(&lookup_list[pos+1],
526 sizeof(lookup_info *) * (lookup_list_count-pos-1));
528 lookup_list[pos] = info;
532 /* These need to be at file level for old versions of gcc (2.95.2 reported),
533 * which give parse errors on an extern in function scope. Each entry needs
534 * to also be invoked in init_lookup_list() below */
536 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
537 extern lookup_module_info cdb_lookup_module_info;
539 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
540 extern lookup_module_info dbmdb_lookup_module_info;
542 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
543 extern lookup_module_info dnsdb_lookup_module_info;
545 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
546 extern lookup_module_info dsearch_lookup_module_info;
548 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
549 extern lookup_module_info ibase_lookup_module_info;
551 #if defined(LOOKUP_LDAP)
552 extern lookup_module_info ldap_lookup_module_info;
554 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
555 extern lookup_module_info lsearch_lookup_module_info;
557 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
558 extern lookup_module_info mysql_lookup_module_info;
560 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
561 extern lookup_module_info nis_lookup_module_info;
563 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
564 extern lookup_module_info nisplus_lookup_module_info;
566 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
567 extern lookup_module_info oracle_lookup_module_info;
569 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
570 extern lookup_module_info passwd_lookup_module_info;
572 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
573 extern lookup_module_info pgsql_lookup_module_info;
575 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
576 extern lookup_module_info redis_lookup_module_info;
578 #if defined(EXPERIMENTAL_LMDB)
579 extern lookup_module_info lmdb_lookup_module_info;
581 #if defined(EXPERIMENTAL_SPF)
582 extern lookup_module_info spf_lookup_module_info;
584 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
585 extern lookup_module_info sqlite_lookup_module_info;
587 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
588 extern lookup_module_info testdb_lookup_module_info;
590 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
591 extern lookup_module_info whoson_lookup_module_info;
596 init_lookup_list(void)
598 #ifdef LOOKUP_MODULE_DIR
601 int countmodules = 0;
602 int moduleerrors = 0;
604 struct lookupmodulestr *p;
605 static BOOL lookup_list_init_done = FALSE;
608 if (lookup_list_init_done)
610 lookup_list_init_done = TRUE;
612 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
613 addlookupmodule(NULL, &cdb_lookup_module_info);
616 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
617 addlookupmodule(NULL, &dbmdb_lookup_module_info);
620 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
621 addlookupmodule(NULL, &dnsdb_lookup_module_info);
624 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
625 addlookupmodule(NULL, &dsearch_lookup_module_info);
628 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
629 addlookupmodule(NULL, &ibase_lookup_module_info);
633 addlookupmodule(NULL, &ldap_lookup_module_info);
636 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
637 addlookupmodule(NULL, &lsearch_lookup_module_info);
640 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
641 addlookupmodule(NULL, &mysql_lookup_module_info);
644 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
645 addlookupmodule(NULL, &nis_lookup_module_info);
648 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
649 addlookupmodule(NULL, &nisplus_lookup_module_info);
652 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
653 addlookupmodule(NULL, &oracle_lookup_module_info);
656 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
657 addlookupmodule(NULL, &passwd_lookup_module_info);
660 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
661 addlookupmodule(NULL, &pgsql_lookup_module_info);
664 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
665 addlookupmodule(NULL, &redis_lookup_module_info);
668 #ifdef EXPERIMENTAL_LMDB
669 addlookupmodule(NULL, &lmdb_lookup_module_info);
672 #ifdef EXPERIMENTAL_SPF
673 addlookupmodule(NULL, &spf_lookup_module_info);
676 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
677 addlookupmodule(NULL, &sqlite_lookup_module_info);
680 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
681 addlookupmodule(NULL, &testdb_lookup_module_info);
684 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
685 addlookupmodule(NULL, &whoson_lookup_module_info);
688 #ifdef LOOKUP_MODULE_DIR
689 dd = opendir(LOOKUP_MODULE_DIR);
691 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
692 log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
695 const pcre *regex_islookupmod = regex_must_compile(
696 US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE);
698 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
699 while ((ent = readdir(dd)) != NULL) {
700 char *name = ent->d_name;
701 int len = (int)strlen(name);
702 if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0) {
703 int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
705 struct lookup_module_info *info;
706 const char *errormsg;
708 /* SRH: am I being paranoid here or what? */
709 if (pathnamelen > big_buffer_size) {
710 fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
711 log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
715 /* SRH: snprintf here? */
716 sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
718 dl = dlopen(CS big_buffer, RTLD_NOW);// TJ was LAZY
720 fprintf(stderr, "Error loading %s: %s\n", name, dlerror());
722 log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, dlerror());
726 /* FreeBSD nsdispatch() can trigger dlerror() errors about
727 * _nss_cache_cycle_prevention_function; we need to clear the dlerror()
728 * state before calling dlsym(), so that any error afterwards only
729 * comes from dlsym().
731 errormsg = dlerror();
733 info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
734 if ((errormsg = dlerror()) != NULL) {
735 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
738 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
741 if (info->magic != LOOKUP_MODULE_INFO_MAGIC) {
742 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
745 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
749 addlookupmodule(dl, info);
750 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
754 store_free((void*)regex_islookupmod);
758 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
761 DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
763 lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count);
764 memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count);
766 /* now add all lookups to the real list */
770 struct lookupmodulestr *pnext;
772 for (j = 0; j < p->info->lookupcount; j++)
773 add_lookup_to_list(p->info->lookups[j]);
779 /* just to be sure */
780 lookupmodules = NULL;
783 #endif /*!MACRO_PREDEF*/
784 /* End of drtables.c */