1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) University of Cambridge 1995 - 2014 */
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 static int lookup_list_init_done = 0;
24 /* Table of information about all possible authentication mechamisms. All
25 entries are always present if any mechanism is declared, but the functions are
26 set to NULL for those that are not compiled into the binary. */
29 #include "auths/cram_md5.h"
32 #ifdef AUTH_CYRUS_SASL
33 #include "auths/cyrus_sasl.h"
37 #include "auths/dovecot.h"
41 #include "auths/gsasl_exim.h"
44 #ifdef AUTH_HEIMDAL_GSSAPI
45 #include "auths/heimdal_gssapi.h"
49 #include "auths/plaintext.h"
53 #include "auths/spa.h"
56 auth_info auths_available[] = {
58 /* Checking by an expansion condition on plain text */
62 US"cram_md5", /* lookup name */
63 auth_cram_md5_options,
64 &auth_cram_md5_options_count,
65 &auth_cram_md5_option_defaults,
66 sizeof(auth_cram_md5_options_block),
67 auth_cram_md5_init, /* init function */
68 auth_cram_md5_server, /* server function */
69 auth_cram_md5_client, /* client function */
70 NULL /* diagnostic function */
74 #ifdef AUTH_CYRUS_SASL
76 US"cyrus_sasl", /* lookup name */
77 auth_cyrus_sasl_options,
78 &auth_cyrus_sasl_options_count,
79 &auth_cyrus_sasl_option_defaults,
80 sizeof(auth_cyrus_sasl_options_block),
81 auth_cyrus_sasl_init, /* init function */
82 auth_cyrus_sasl_server, /* server function */
83 NULL, /* client function */
84 auth_cyrus_sasl_version_report /* diagnostic function */
90 US"dovecot", /* lookup name */
92 &auth_dovecot_options_count,
93 &auth_dovecot_option_defaults,
94 sizeof(auth_dovecot_options_block),
95 auth_dovecot_init, /* init function */
96 auth_dovecot_server, /* server function */
97 NULL, /* client function */
98 NULL /* diagnostic function */
104 US"gsasl", /* lookup name */
106 &auth_gsasl_options_count,
107 &auth_gsasl_option_defaults,
108 sizeof(auth_gsasl_options_block),
109 auth_gsasl_init, /* init function */
110 auth_gsasl_server, /* server function */
111 NULL, /* client function */
112 auth_gsasl_version_report /* diagnostic function */
116 #ifdef AUTH_HEIMDAL_GSSAPI
118 US"heimdal_gssapi", /* lookup name */
119 auth_heimdal_gssapi_options,
120 &auth_heimdal_gssapi_options_count,
121 &auth_heimdal_gssapi_option_defaults,
122 sizeof(auth_heimdal_gssapi_options_block),
123 auth_heimdal_gssapi_init, /* init function */
124 auth_heimdal_gssapi_server, /* server function */
125 NULL, /* client function */
126 auth_heimdal_gssapi_version_report /* diagnostic function */
130 #ifdef AUTH_PLAINTEXT
132 US"plaintext", /* lookup name */
133 auth_plaintext_options,
134 &auth_plaintext_options_count,
135 &auth_plaintext_option_defaults,
136 sizeof(auth_plaintext_options_block),
137 auth_plaintext_init, /* init function */
138 auth_plaintext_server, /* server function */
139 auth_plaintext_client, /* client function */
140 NULL /* diagnostic function */
146 US"spa", /* lookup name */
148 &auth_spa_options_count,
149 &auth_spa_option_defaults,
150 sizeof(auth_spa_options_block),
151 auth_spa_init, /* init function */
152 auth_spa_server, /* server function */
153 auth_spa_client, /* client function */
154 NULL /* diagnostic function */
158 { US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL }
162 /* Tables of information about which routers and transports are included in the
165 /* Pull in the necessary header files */
167 #include "routers/rf_functions.h"
170 #include "routers/accept.h"
173 #ifdef ROUTER_DNSLOOKUP
174 #include "routers/dnslookup.h"
177 #ifdef ROUTER_MANUALROUTE
178 #include "routers/manualroute.h"
181 #ifdef ROUTER_IPLITERAL
182 #include "routers/ipliteral.h"
185 #ifdef ROUTER_IPLOOKUP
186 #include "routers/iplookup.h"
189 #ifdef ROUTER_QUERYPROGRAM
190 #include "routers/queryprogram.h"
193 #ifdef ROUTER_REDIRECT
194 #include "routers/redirect.h"
197 #ifdef TRANSPORT_APPENDFILE
198 #include "transports/appendfile.h"
201 #ifdef TRANSPORT_AUTOREPLY
202 #include "transports/autoreply.h"
205 #ifdef TRANSPORT_LMTP
206 #include "transports/lmtp.h"
209 #ifdef TRANSPORT_PIPE
210 #include "transports/pipe.h"
213 #ifdef TRANSPORT_SMTP
214 #include "transports/smtp.h"
218 /* Now set up the structures, terminated by an entry with a null name. */
220 router_info routers_available[] = {
224 accept_router_options,
225 &accept_router_options_count,
226 &accept_router_option_defaults,
227 sizeof(accept_router_options_block),
230 NULL, /* no tidyup entry */
234 #ifdef ROUTER_DNSLOOKUP
237 dnslookup_router_options,
238 &dnslookup_router_options_count,
239 &dnslookup_router_option_defaults,
240 sizeof(dnslookup_router_options_block),
241 dnslookup_router_init,
242 dnslookup_router_entry,
243 NULL, /* no tidyup entry */
247 #ifdef ROUTER_IPLITERAL
250 ipliteral_router_options,
251 &ipliteral_router_options_count,
252 &ipliteral_router_option_defaults,
253 sizeof(ipliteral_router_options_block),
254 ipliteral_router_init,
255 ipliteral_router_entry,
256 NULL, /* no tidyup entry */
260 #ifdef ROUTER_IPLOOKUP
263 iplookup_router_options,
264 &iplookup_router_options_count,
265 &iplookup_router_option_defaults,
266 sizeof(iplookup_router_options_block),
267 iplookup_router_init,
268 iplookup_router_entry,
269 NULL, /* no tidyup entry */
273 #ifdef ROUTER_MANUALROUTE
276 manualroute_router_options,
277 &manualroute_router_options_count,
278 &manualroute_router_option_defaults,
279 sizeof(manualroute_router_options_block),
280 manualroute_router_init,
281 manualroute_router_entry,
282 NULL, /* no tidyup entry */
286 #ifdef ROUTER_QUERYPROGRAM
289 queryprogram_router_options,
290 &queryprogram_router_options_count,
291 &queryprogram_router_option_defaults,
292 sizeof(queryprogram_router_options_block),
293 queryprogram_router_init,
294 queryprogram_router_entry,
295 NULL, /* no tidyup entry */
299 #ifdef ROUTER_REDIRECT
302 redirect_router_options,
303 &redirect_router_options_count,
304 &redirect_router_option_defaults,
305 sizeof(redirect_router_options_block),
306 redirect_router_init,
307 redirect_router_entry,
308 NULL, /* no tidyup entry */
312 { US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, 0 }
317 transport_info transports_available[] = {
318 #ifdef TRANSPORT_APPENDFILE
320 US"appendfile", /* driver name */
321 appendfile_transport_options, /* local options table */
322 &appendfile_transport_options_count, /* number of entries */
323 &appendfile_transport_option_defaults, /* private options defaults */
324 sizeof(appendfile_transport_options_block), /* size of private block */
325 appendfile_transport_init, /* init entry point */
326 appendfile_transport_entry, /* main entry point */
327 NULL, /* no tidyup entry */
328 NULL, /* no closedown entry */
329 TRUE, /* local flag */
332 #ifdef TRANSPORT_AUTOREPLY
334 US"autoreply", /* driver name */
335 autoreply_transport_options, /* local options table */
336 &autoreply_transport_options_count, /* number of entries */
337 &autoreply_transport_option_defaults, /* private options defaults */
338 sizeof(autoreply_transport_options_block), /* size of private block */
339 autoreply_transport_init, /* init entry point */
340 autoreply_transport_entry, /* main entry point */
341 NULL, /* no tidyup entry */
342 NULL, /* no closedown entry */
343 TRUE /* local flag */
346 #ifdef TRANSPORT_LMTP
348 US"lmtp", /* driver name */
349 lmtp_transport_options, /* local options table */
350 &lmtp_transport_options_count, /* number of entries */
351 &lmtp_transport_option_defaults, /* private options defaults */
352 sizeof(lmtp_transport_options_block), /* size of private block */
353 lmtp_transport_init, /* init entry point */
354 lmtp_transport_entry, /* main entry point */
355 NULL, /* no tidyup entry */
356 NULL, /* no closedown entry */
357 TRUE /* local flag */
360 #ifdef TRANSPORT_PIPE
362 US"pipe", /* driver name */
363 pipe_transport_options, /* local options table */
364 &pipe_transport_options_count, /* number of entries */
365 &pipe_transport_option_defaults, /* private options defaults */
366 sizeof(pipe_transport_options_block), /* size of private block */
367 pipe_transport_init, /* init entry point */
368 pipe_transport_entry, /* main entry point */
369 NULL, /* no tidyup entry */
370 NULL, /* no closedown entry */
371 TRUE /* local flag */
374 #ifdef TRANSPORT_SMTP
376 US"smtp", /* driver name */
377 smtp_transport_options, /* local options table */
378 &smtp_transport_options_count, /* number of entries */
379 &smtp_transport_option_defaults, /* private options defaults */
380 sizeof(smtp_transport_options_block), /* size of private block */
381 smtp_transport_init, /* init entry point */
382 smtp_transport_entry, /* main entry point */
383 NULL, /* no tidyup entry */
384 smtp_transport_closedown, /* close down passed channel */
385 FALSE /* local flag */
388 { US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, FALSE }
391 struct lookupmodulestr
394 struct lookup_module_info *info;
395 struct lookupmodulestr *next;
398 static struct lookupmodulestr *lookupmodules = NULL;
400 static void addlookupmodule(void *dl, struct lookup_module_info *info)
402 struct lookupmodulestr *p = store_malloc(sizeof(struct lookupmodulestr));
405 p->next = lookupmodules;
407 lookup_list_count += info->lookupcount;
410 /* only valid after lookup_list and lookup_list_count are assigned */
411 static void add_lookup_to_list(lookup_info *info)
413 /* need to add the lookup to lookup_list, sorted */
416 /* strategy is to go through the list until we find
417 * either an empty spot or a name that is higher.
418 * this can't fail because we have enough space. */
419 while (lookup_list[pos]
420 && (Ustrcmp(lookup_list[pos]->name, info->name) <= 0)) {
423 if (lookup_list[pos]) {
424 /* need to insert it, so move all the other items up
425 * (last slot is still empty, of course) */
426 memmove(&lookup_list[pos+1],
428 sizeof(lookup_info **) * (lookup_list_count-pos-1));
430 lookup_list[pos] = info;
434 /* These need to be at file level for old versions of gcc (2.95.2 reported),
435 * which give parse errors on an extern in function scope. Each entry needs
436 * to also be invoked in init_lookup_list() below */
438 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
439 extern lookup_module_info whoson_lookup_module_info;
441 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
442 extern lookup_module_info testdb_lookup_module_info;
444 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
445 extern lookup_module_info sqlite_lookup_module_info;
447 #ifdef EXPERIMENTAL_SPF
448 extern lookup_module_info spf_lookup_module_info;
450 #ifdef EXPERIMENTAL_REDIS
451 extern lookup_module_info redis_lookup_module_info;
453 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
454 extern lookup_module_info pgsql_lookup_module_info;
456 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
457 extern lookup_module_info passwd_lookup_module_info;
459 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
460 extern lookup_module_info oracle_lookup_module_info;
462 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
463 extern lookup_module_info nisplus_lookup_module_info;
465 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
466 extern lookup_module_info nis_lookup_module_info;
468 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
469 extern lookup_module_info mysql_lookup_module_info;
471 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
472 extern lookup_module_info lsearch_lookup_module_info;
475 extern lookup_module_info ldap_lookup_module_info;
477 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
478 extern lookup_module_info ibase_lookup_module_info;
480 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
481 extern lookup_module_info dsearch_lookup_module_info;
483 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
484 extern lookup_module_info dnsdb_lookup_module_info;
486 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
487 extern lookup_module_info dbmdb_lookup_module_info;
489 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
490 extern lookup_module_info cdb_lookup_module_info;
493 void init_lookup_list(void)
495 #ifdef LOOKUP_MODULE_DIR
498 int countmodules = 0;
499 int moduleerrors = 0;
501 struct lookupmodulestr *p;
502 const pcre *regex_islookupmod = regex_must_compile(
503 US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE);
505 if (lookup_list_init_done)
507 lookup_list_init_done = 1;
509 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
510 addlookupmodule(NULL, &cdb_lookup_module_info);
513 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
514 addlookupmodule(NULL, &dbmdb_lookup_module_info);
517 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
518 addlookupmodule(NULL, &dnsdb_lookup_module_info);
521 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
522 addlookupmodule(NULL, &dsearch_lookup_module_info);
525 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
526 addlookupmodule(NULL, &ibase_lookup_module_info);
530 addlookupmodule(NULL, &ldap_lookup_module_info);
533 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
534 addlookupmodule(NULL, &lsearch_lookup_module_info);
537 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
538 addlookupmodule(NULL, &mysql_lookup_module_info);
541 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
542 addlookupmodule(NULL, &nis_lookup_module_info);
545 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
546 addlookupmodule(NULL, &nisplus_lookup_module_info);
549 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
550 addlookupmodule(NULL, &oracle_lookup_module_info);
553 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
554 addlookupmodule(NULL, &passwd_lookup_module_info);
557 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
558 addlookupmodule(NULL, &pgsql_lookup_module_info);
561 #ifdef EXPERIMENTAL_REDIS
562 addlookupmodule(NULL, &redis_lookup_module_info);
565 #ifdef EXPERIMENTAL_SPF
566 addlookupmodule(NULL, &spf_lookup_module_info);
569 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
570 addlookupmodule(NULL, &sqlite_lookup_module_info);
573 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
574 addlookupmodule(NULL, &testdb_lookup_module_info);
577 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
578 addlookupmodule(NULL, &whoson_lookup_module_info);
581 #ifdef LOOKUP_MODULE_DIR
582 dd = opendir(LOOKUP_MODULE_DIR);
584 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
585 log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
588 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
589 while ((ent = readdir(dd)) != NULL) {
590 char *name = ent->d_name;
591 int len = (int)strlen(name);
592 if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0) {
593 int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
595 struct lookup_module_info *info;
596 const char *errormsg;
598 /* SRH: am I being paranoid here or what? */
599 if (pathnamelen > big_buffer_size) {
600 fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
601 log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
605 /* SRH: snprintf here? */
606 sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
608 dl = dlopen(CS big_buffer, RTLD_NOW);// TJ was LAZY
610 fprintf(stderr, "Error loading %s: %s\n", name, dlerror());
612 log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, dlerror());
616 /* FreeBSD nsdispatch() can trigger dlerror() errors about
617 * _nss_cache_cycle_prevention_function; we need to clear the dlerror()
618 * state before calling dlsym(), so that any error afterwards only
619 * comes from dlsym().
621 errormsg = dlerror();
623 info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
624 if ((errormsg = dlerror()) != NULL) {
625 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
628 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
631 if (info->magic != LOOKUP_MODULE_INFO_MAGIC) {
632 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
635 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
639 addlookupmodule(dl, info);
640 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
647 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
650 store_free((void*)regex_islookupmod);
652 DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
654 lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count);
655 memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count);
657 /* now add all lookups to the real list */
661 struct lookupmodulestr *pnext;
663 for (j = 0; j < p->info->lookupcount; j++)
664 add_lookup_to_list(p->info->lookups[j]);
670 /* just to be sure */
671 lookupmodules = NULL;
674 /* End of drtables.c */