1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
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/external.h"
43 #include "auths/gsasl_exim.h"
46 #ifdef AUTH_HEIMDAL_GSSAPI
47 #include "auths/heimdal_gssapi.h"
51 #include "auths/plaintext.h"
55 #include "auths/spa.h"
59 #include "auths/tls.h"
62 auth_info auths_available[] = {
64 /* Checking by an expansion condition on plain text */
68 .driver_name = US"cram_md5", /* lookup name */
69 .options = auth_cram_md5_options,
70 .options_count = &auth_cram_md5_options_count,
71 .options_block = &auth_cram_md5_option_defaults,
72 .options_len = sizeof(auth_cram_md5_options_block),
73 .init = auth_cram_md5_init,
74 .servercode = auth_cram_md5_server,
75 .clientcode = auth_cram_md5_client,
76 .version_report = NULL
80 #ifdef AUTH_CYRUS_SASL
82 .driver_name = US"cyrus_sasl",
83 .options = auth_cyrus_sasl_options,
84 .options_count = &auth_cyrus_sasl_options_count,
85 .options_block = &auth_cyrus_sasl_option_defaults,
86 .options_len = sizeof(auth_cyrus_sasl_options_block),
87 .init = auth_cyrus_sasl_init,
88 .servercode = auth_cyrus_sasl_server,
90 .version_report = auth_cyrus_sasl_version_report
96 .driver_name = US"dovecot",
97 .options = auth_dovecot_options,
98 .options_count = &auth_dovecot_options_count,
99 .options_block = &auth_dovecot_option_defaults,
100 .options_len = sizeof(auth_dovecot_options_block),
101 .init = auth_dovecot_init,
102 .servercode = auth_dovecot_server,
104 .version_report = NULL
110 .driver_name = US"external",
111 .options = auth_external_options,
112 .options_count = &auth_external_options_count,
113 .options_block = &auth_external_option_defaults,
114 .options_len = sizeof(auth_external_options_block),
115 .init = auth_external_init,
116 .servercode = auth_external_server,
117 .clientcode = auth_external_client,
118 .version_report = NULL
124 .driver_name = US"gsasl",
125 .options = auth_gsasl_options,
126 .options_count = &auth_gsasl_options_count,
127 .options_block = &auth_gsasl_option_defaults,
128 .options_len = sizeof(auth_gsasl_options_block),
129 .init = auth_gsasl_init,
130 .servercode = auth_gsasl_server,
132 .version_report = auth_gsasl_version_report
136 #ifdef AUTH_HEIMDAL_GSSAPI
138 .driver_name = US"heimdal_gssapi",
139 .options = auth_heimdal_gssapi_options,
140 .options_count = &auth_heimdal_gssapi_options_count,
141 .options_block = &auth_heimdal_gssapi_option_defaults,
142 .options_len = sizeof(auth_heimdal_gssapi_options_block),
143 .init = auth_heimdal_gssapi_init,
144 .servercode = auth_heimdal_gssapi_server,
146 .version_report = auth_heimdal_gssapi_version_report
150 #ifdef AUTH_PLAINTEXT
152 .driver_name = US"plaintext",
153 .options = auth_plaintext_options,
154 .options_count = &auth_plaintext_options_count,
155 .options_block = &auth_plaintext_option_defaults,
156 .options_len = sizeof(auth_plaintext_options_block),
157 .init = auth_plaintext_init,
158 .servercode = auth_plaintext_server,
159 .clientcode = auth_plaintext_client,
160 .version_report = NULL
166 .driver_name = US"spa",
167 .options = auth_spa_options,
168 .options_count = &auth_spa_options_count,
169 .options_block = &auth_spa_option_defaults,
170 .options_len = sizeof(auth_spa_options_block),
171 .init = auth_spa_init,
172 .servercode = auth_spa_server,
173 .clientcode = auth_spa_client,
174 .version_report = NULL
180 .driver_name = US"tls",
181 .options = auth_tls_options,
182 .options_count = &auth_tls_options_count,
183 .options_block = &auth_tls_option_defaults,
184 .options_len = sizeof(auth_tls_options_block),
185 .init = auth_tls_init,
186 .servercode = auth_tls_server,
188 .version_report = NULL
192 { .driver_name = US"" } /* end marker */
196 auth_show_supported(FILE * f)
198 fprintf(f, "Authenticators:");
199 for (auth_info * ai = auths_available; ai->driver_name[0]; ai++)
200 fprintf(f, " %s", ai->driver_name);
205 /* Tables of information about which routers and transports are included in the
208 /* Pull in the necessary header files */
210 #include "routers/rf_functions.h"
213 #include "routers/accept.h"
216 #ifdef ROUTER_DNSLOOKUP
217 #include "routers/dnslookup.h"
220 #ifdef ROUTER_MANUALROUTE
221 #include "routers/manualroute.h"
224 #ifdef ROUTER_IPLITERAL
225 #include "routers/ipliteral.h"
228 #ifdef ROUTER_IPLOOKUP
229 #include "routers/iplookup.h"
232 #ifdef ROUTER_QUERYPROGRAM
233 #include "routers/queryprogram.h"
236 #ifdef ROUTER_REDIRECT
237 #include "routers/redirect.h"
240 #ifdef TRANSPORT_APPENDFILE
241 #include "transports/appendfile.h"
244 #ifdef TRANSPORT_AUTOREPLY
245 #include "transports/autoreply.h"
248 #ifdef TRANSPORT_LMTP
249 #include "transports/lmtp.h"
252 #ifdef TRANSPORT_PIPE
253 #include "transports/pipe.h"
256 #ifdef EXPERIMENTAL_QUEUEFILE
257 #include "transports/queuefile.h"
260 #ifdef TRANSPORT_SMTP
261 #include "transports/smtp.h"
265 /* Now set up the structures, terminated by an entry with a null name. */
267 router_info routers_available[] = {
270 .driver_name = US"accept",
271 .options = accept_router_options,
272 .options_count = &accept_router_options_count,
273 .options_block = &accept_router_option_defaults,
274 .options_len = sizeof(accept_router_options_block),
275 .init = accept_router_init,
276 .code = accept_router_entry,
277 .tidyup = NULL, /* no tidyup entry */
278 .ri_flags = ri_yestransport
281 #ifdef ROUTER_DNSLOOKUP
283 .driver_name = US"dnslookup",
284 .options = dnslookup_router_options,
285 .options_count = &dnslookup_router_options_count,
286 .options_block = &dnslookup_router_option_defaults,
287 .options_len = sizeof(dnslookup_router_options_block),
288 .init = dnslookup_router_init,
289 .code = dnslookup_router_entry,
290 .tidyup = NULL, /* no tidyup entry */
291 .ri_flags = ri_yestransport
294 #ifdef ROUTER_IPLITERAL
296 .driver_name = US"ipliteral",
297 .options = ipliteral_router_options,
298 .options_count = &ipliteral_router_options_count,
299 .options_block = &ipliteral_router_option_defaults,
300 .options_len = sizeof(ipliteral_router_options_block),
301 .init = ipliteral_router_init,
302 .code = ipliteral_router_entry,
303 .tidyup = NULL, /* no tidyup entry */
304 .ri_flags = ri_yestransport
307 #ifdef ROUTER_IPLOOKUP
309 .driver_name = US"iplookup",
310 .options = iplookup_router_options,
311 .options_count = &iplookup_router_options_count,
312 .options_block = &iplookup_router_option_defaults,
313 .options_len = sizeof(iplookup_router_options_block),
314 .init = iplookup_router_init,
315 .code = iplookup_router_entry,
316 .tidyup = NULL, /* no tidyup entry */
317 .ri_flags = ri_notransport
320 #ifdef ROUTER_MANUALROUTE
322 .driver_name = US"manualroute",
323 .options = manualroute_router_options,
324 .options_count = &manualroute_router_options_count,
325 .options_block = &manualroute_router_option_defaults,
326 .options_len = sizeof(manualroute_router_options_block),
327 .init = manualroute_router_init,
328 .code = manualroute_router_entry,
329 .tidyup = NULL, /* no tidyup entry */
333 #ifdef ROUTER_QUERYPROGRAM
335 .driver_name = US"queryprogram",
336 .options = queryprogram_router_options,
337 .options_count = &queryprogram_router_options_count,
338 .options_block = &queryprogram_router_option_defaults,
339 .options_len = sizeof(queryprogram_router_options_block),
340 .init = queryprogram_router_init,
341 .code = queryprogram_router_entry,
342 .tidyup = NULL, /* no tidyup entry */
346 #ifdef ROUTER_REDIRECT
348 .driver_name = US"redirect",
349 .options = redirect_router_options,
350 .options_count = &redirect_router_options_count,
351 .options_block = &redirect_router_option_defaults,
352 .options_len = sizeof(redirect_router_options_block),
353 .init = redirect_router_init,
354 .code = redirect_router_entry,
355 .tidyup = NULL, /* no tidyup entry */
356 .ri_flags = ri_notransport
364 route_show_supported(FILE * f)
366 fprintf(f, "Routers:");
367 for (router_info * rr = routers_available; rr->driver_name[0]; rr++)
368 fprintf(f, " %s", rr->driver_name);
375 transport_info transports_available[] = {
376 #ifdef TRANSPORT_APPENDFILE
378 .driver_name = US"appendfile",
379 .options = appendfile_transport_options,
380 .options_count = &appendfile_transport_options_count,
381 .options_block = &appendfile_transport_option_defaults, /* private options defaults */
382 .options_len = sizeof(appendfile_transport_options_block),
383 .init = appendfile_transport_init,
384 .code = appendfile_transport_entry,
390 #ifdef TRANSPORT_AUTOREPLY
392 .driver_name = US"autoreply",
393 .options = autoreply_transport_options,
394 .options_count = &autoreply_transport_options_count,
395 .options_block = &autoreply_transport_option_defaults,
396 .options_len = sizeof(autoreply_transport_options_block),
397 .init = autoreply_transport_init,
398 .code = autoreply_transport_entry,
404 #ifdef TRANSPORT_LMTP
406 .driver_name = US"lmtp",
407 .options = lmtp_transport_options,
408 .options_count = &lmtp_transport_options_count,
409 .options_block = &lmtp_transport_option_defaults,
410 .options_len = sizeof(lmtp_transport_options_block),
411 .init = lmtp_transport_init,
412 .code = lmtp_transport_entry,
418 #ifdef TRANSPORT_PIPE
420 .driver_name = US"pipe",
421 .options = pipe_transport_options,
422 .options_count = &pipe_transport_options_count,
423 .options_block = &pipe_transport_option_defaults,
424 .options_len = sizeof(pipe_transport_options_block),
425 .init = pipe_transport_init,
426 .code = pipe_transport_entry,
432 #ifdef EXPERIMENTAL_QUEUEFILE
434 .driver_name = US"queuefile",
435 .options = queuefile_transport_options,
436 .options_count = &queuefile_transport_options_count,
437 .options_block = &queuefile_transport_option_defaults,
438 .options_len = sizeof(queuefile_transport_options_block),
439 .init = queuefile_transport_init,
440 .code = queuefile_transport_entry,
446 #ifdef TRANSPORT_SMTP
448 .driver_name = US"smtp",
449 .options = smtp_transport_options,
450 .options_count = &smtp_transport_options_count,
451 .options_block = &smtp_transport_option_defaults,
452 .options_len = sizeof(smtp_transport_options_block),
453 .init = smtp_transport_init,
454 .code = smtp_transport_entry,
456 .closedown = smtp_transport_closedown,
464 transport_show_supported(FILE * f)
466 fprintf(f, "Transports:");
467 #ifdef TRANSPORT_APPENDFILE
468 fprintf(f, " appendfile");
469 #ifdef SUPPORT_MAILDIR
470 fprintf(f, "/maildir"); /* damn these subclasses */
472 #ifdef SUPPORT_MAILSTORE
473 fprintf(f, "/mailstore");
479 #ifdef TRANSPORT_AUTOREPLY
480 fprintf(f, " autoreply");
482 #ifdef TRANSPORT_LMTP
485 #ifdef TRANSPORT_PIPE
488 #ifdef EXPERIMENTAL_QUEUEFILE
489 fprintf(f, " queuefile");
491 #ifdef TRANSPORT_SMTP
500 struct lookupmodulestr
503 struct lookup_module_info *info;
504 struct lookupmodulestr *next;
507 static struct lookupmodulestr *lookupmodules = NULL;
510 addlookupmodule(void *dl, struct lookup_module_info *info)
512 struct lookupmodulestr *p = store_get(sizeof(struct lookupmodulestr), FALSE);
516 p->next = lookupmodules;
518 lookup_list_count += info->lookupcount;
521 /* only valid after lookup_list and lookup_list_count are assigned */
523 add_lookup_to_list(lookup_info *info)
525 /* need to add the lookup to lookup_list, sorted */
528 /* strategy is to go through the list until we find
529 either an empty spot or a name that is higher.
530 this can't fail because we have enough space. */
532 while (lookup_list[pos] && (Ustrcmp(lookup_list[pos]->name, info->name) <= 0))
535 if (lookup_list[pos])
537 /* need to insert it, so move all the other items up
538 (last slot is still empty, of course) */
540 memmove(&lookup_list[pos+1],
542 sizeof(lookup_info *) * (lookup_list_count-pos-1));
544 lookup_list[pos] = info;
548 /* These need to be at file level for old versions of gcc (2.95.2 reported),
549 * which give parse errors on an extern in function scope. Each entry needs
550 * to also be invoked in init_lookup_list() below */
552 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
553 extern lookup_module_info cdb_lookup_module_info;
555 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
556 extern lookup_module_info dbmdb_lookup_module_info;
558 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
559 extern lookup_module_info dnsdb_lookup_module_info;
561 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
562 extern lookup_module_info dsearch_lookup_module_info;
564 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
565 extern lookup_module_info ibase_lookup_module_info;
567 #if defined(LOOKUP_JSON)
568 extern lookup_module_info json_lookup_module_info;
570 #if defined(LOOKUP_LDAP)
571 extern lookup_module_info ldap_lookup_module_info;
573 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
574 extern lookup_module_info lsearch_lookup_module_info;
576 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
577 extern lookup_module_info mysql_lookup_module_info;
579 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
580 extern lookup_module_info nis_lookup_module_info;
582 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
583 extern lookup_module_info nisplus_lookup_module_info;
585 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
586 extern lookup_module_info oracle_lookup_module_info;
588 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
589 extern lookup_module_info passwd_lookup_module_info;
591 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
592 extern lookup_module_info pgsql_lookup_module_info;
594 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
595 extern lookup_module_info redis_lookup_module_info;
597 #if defined(EXPERIMENTAL_LMDB)
598 extern lookup_module_info lmdb_lookup_module_info;
600 #if defined(SUPPORT_SPF)
601 extern lookup_module_info spf_lookup_module_info;
603 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
604 extern lookup_module_info sqlite_lookup_module_info;
606 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
607 extern lookup_module_info testdb_lookup_module_info;
609 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
610 extern lookup_module_info whoson_lookup_module_info;
615 init_lookup_list(void)
617 #ifdef LOOKUP_MODULE_DIR
620 int countmodules = 0;
621 int moduleerrors = 0;
623 static BOOL lookup_list_init_done = FALSE;
626 if (lookup_list_init_done)
628 reset_point = store_mark();
629 lookup_list_init_done = TRUE;
631 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
632 addlookupmodule(NULL, &cdb_lookup_module_info);
635 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
636 addlookupmodule(NULL, &dbmdb_lookup_module_info);
639 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
640 addlookupmodule(NULL, &dnsdb_lookup_module_info);
643 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
644 addlookupmodule(NULL, &dsearch_lookup_module_info);
647 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
648 addlookupmodule(NULL, &ibase_lookup_module_info);
652 addlookupmodule(NULL, &ldap_lookup_module_info);
656 addlookupmodule(NULL, &json_lookup_module_info);
659 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
660 addlookupmodule(NULL, &lsearch_lookup_module_info);
663 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
664 addlookupmodule(NULL, &mysql_lookup_module_info);
667 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
668 addlookupmodule(NULL, &nis_lookup_module_info);
671 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
672 addlookupmodule(NULL, &nisplus_lookup_module_info);
675 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
676 addlookupmodule(NULL, &oracle_lookup_module_info);
679 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
680 addlookupmodule(NULL, &passwd_lookup_module_info);
683 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
684 addlookupmodule(NULL, &pgsql_lookup_module_info);
687 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
688 addlookupmodule(NULL, &redis_lookup_module_info);
691 #ifdef EXPERIMENTAL_LMDB
692 addlookupmodule(NULL, &lmdb_lookup_module_info);
696 addlookupmodule(NULL, &spf_lookup_module_info);
699 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
700 addlookupmodule(NULL, &sqlite_lookup_module_info);
703 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
704 addlookupmodule(NULL, &testdb_lookup_module_info);
707 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
708 addlookupmodule(NULL, &whoson_lookup_module_info);
711 #ifdef LOOKUP_MODULE_DIR
712 dd = opendir(LOOKUP_MODULE_DIR);
714 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
715 log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
718 const pcre *regex_islookupmod = regex_must_compile(
719 US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE);
721 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
722 while ((ent = readdir(dd)) != NULL) {
723 char *name = ent->d_name;
724 int len = (int)strlen(name);
725 if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0) {
726 int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
728 struct lookup_module_info *info;
729 const char *errormsg;
731 /* SRH: am I being paranoid here or what? */
732 if (pathnamelen > big_buffer_size) {
733 fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
734 log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
738 /* SRH: snprintf here? */
739 sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
741 dl = dlopen(CS big_buffer, RTLD_NOW);// TJ was LAZY
743 fprintf(stderr, "Error loading %s: %s\n", name, dlerror());
745 log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, dlerror());
749 /* FreeBSD nsdispatch() can trigger dlerror() errors about
750 * _nss_cache_cycle_prevention_function; we need to clear the dlerror()
751 * state before calling dlsym(), so that any error afterwards only
752 * comes from dlsym().
754 errormsg = dlerror();
756 info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
757 if ((errormsg = dlerror()) != NULL) {
758 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
761 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
764 if (info->magic != LOOKUP_MODULE_INFO_MAGIC) {
765 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
768 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
772 addlookupmodule(dl, info);
773 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
777 store_free((void*)regex_islookupmod);
781 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
784 DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
786 lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count);
787 memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count);
789 /* now add all lookups to the real list */
790 for (struct lookupmodulestr * p = lookupmodules; p; p = p->next)
791 for (int j = 0; j < p->info->lookupcount; j++)
792 add_lookup_to_list(p->info->lookups[j]);
793 store_reset(reset_point);
794 /* just to be sure */
795 lookupmodules = NULL;
798 #endif /*!MACRO_PREDEF*/
799 /* End of drtables.c */