1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) University of Cambridge 1995 - 2009 */
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"
45 #include "auths/plaintext.h"
49 #include "auths/spa.h"
52 auth_info auths_available[] = {
54 /* Checking by an expansion condition on plain text */
58 US"cram_md5", /* lookup name */
59 auth_cram_md5_options,
60 &auth_cram_md5_options_count,
61 &auth_cram_md5_option_defaults,
62 sizeof(auth_cram_md5_options_block),
63 auth_cram_md5_init, /* init function */
64 auth_cram_md5_server, /* server function */
65 auth_cram_md5_client, /* client function */
66 NULL /* diagnostic function */
70 #ifdef AUTH_CYRUS_SASL
72 US"cyrus_sasl", /* lookup name */
73 auth_cyrus_sasl_options,
74 &auth_cyrus_sasl_options_count,
75 &auth_cyrus_sasl_option_defaults,
76 sizeof(auth_cyrus_sasl_options_block),
77 auth_cyrus_sasl_init, /* init function */
78 auth_cyrus_sasl_server, /* server function */
79 NULL, /* client function */
80 auth_cyrus_sasl_version_report /* diagnostic function */
86 US"dovecot", /* lookup name */
88 &auth_dovecot_options_count,
89 &auth_dovecot_option_defaults,
90 sizeof(auth_dovecot_options_block),
91 auth_dovecot_init, /* init function */
92 auth_dovecot_server, /* server function */
93 NULL, /* client function */
94 NULL /* diagnostic function */
100 US"gsasl", /* lookup name */
102 &auth_gsasl_options_count,
103 &auth_gsasl_option_defaults,
104 sizeof(auth_gsasl_options_block),
105 auth_gsasl_init, /* init function */
106 auth_gsasl_server, /* server function */
107 NULL, /* client function */
108 auth_gsasl_version_report /* diagnostic function */
112 #ifdef AUTH_PLAINTEXT
114 US"plaintext", /* lookup name */
115 auth_plaintext_options,
116 &auth_plaintext_options_count,
117 &auth_plaintext_option_defaults,
118 sizeof(auth_plaintext_options_block),
119 auth_plaintext_init, /* init function */
120 auth_plaintext_server, /* server function */
121 auth_plaintext_client, /* client function */
122 NULL /* diagnostic function */
128 US"spa", /* lookup name */
130 &auth_spa_options_count,
131 &auth_spa_option_defaults,
132 sizeof(auth_spa_options_block),
133 auth_spa_init, /* init function */
134 auth_spa_server, /* server function */
135 auth_spa_client, /* client function */
136 NULL /* diagnostic function */
140 { US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL }
144 /* Tables of information about which routers and transports are included in the
147 /* Pull in the necessary header files */
149 #include "routers/rf_functions.h"
152 #include "routers/accept.h"
155 #ifdef ROUTER_DNSLOOKUP
156 #include "routers/dnslookup.h"
159 #ifdef ROUTER_MANUALROUTE
160 #include "routers/manualroute.h"
163 #ifdef ROUTER_IPLITERAL
164 #include "routers/ipliteral.h"
167 #ifdef ROUTER_IPLOOKUP
168 #include "routers/iplookup.h"
171 #ifdef ROUTER_QUERYPROGRAM
172 #include "routers/queryprogram.h"
175 #ifdef ROUTER_REDIRECT
176 #include "routers/redirect.h"
179 #ifdef TRANSPORT_APPENDFILE
180 #include "transports/appendfile.h"
183 #ifdef TRANSPORT_AUTOREPLY
184 #include "transports/autoreply.h"
187 #ifdef TRANSPORT_LMTP
188 #include "transports/lmtp.h"
191 #ifdef TRANSPORT_PIPE
192 #include "transports/pipe.h"
195 #ifdef TRANSPORT_SMTP
196 #include "transports/smtp.h"
200 /* Now set up the structures, terminated by an entry with a null name. */
202 router_info routers_available[] = {
206 accept_router_options,
207 &accept_router_options_count,
208 &accept_router_option_defaults,
209 sizeof(accept_router_options_block),
212 NULL, /* no tidyup entry */
216 #ifdef ROUTER_DNSLOOKUP
219 dnslookup_router_options,
220 &dnslookup_router_options_count,
221 &dnslookup_router_option_defaults,
222 sizeof(dnslookup_router_options_block),
223 dnslookup_router_init,
224 dnslookup_router_entry,
225 NULL, /* no tidyup entry */
229 #ifdef ROUTER_IPLITERAL
232 ipliteral_router_options,
233 &ipliteral_router_options_count,
234 &ipliteral_router_option_defaults,
235 sizeof(ipliteral_router_options_block),
236 ipliteral_router_init,
237 ipliteral_router_entry,
238 NULL, /* no tidyup entry */
242 #ifdef ROUTER_IPLOOKUP
245 iplookup_router_options,
246 &iplookup_router_options_count,
247 &iplookup_router_option_defaults,
248 sizeof(iplookup_router_options_block),
249 iplookup_router_init,
250 iplookup_router_entry,
251 NULL, /* no tidyup entry */
255 #ifdef ROUTER_MANUALROUTE
258 manualroute_router_options,
259 &manualroute_router_options_count,
260 &manualroute_router_option_defaults,
261 sizeof(manualroute_router_options_block),
262 manualroute_router_init,
263 manualroute_router_entry,
264 NULL, /* no tidyup entry */
268 #ifdef ROUTER_QUERYPROGRAM
271 queryprogram_router_options,
272 &queryprogram_router_options_count,
273 &queryprogram_router_option_defaults,
274 sizeof(queryprogram_router_options_block),
275 queryprogram_router_init,
276 queryprogram_router_entry,
277 NULL, /* no tidyup entry */
281 #ifdef ROUTER_REDIRECT
284 redirect_router_options,
285 &redirect_router_options_count,
286 &redirect_router_option_defaults,
287 sizeof(redirect_router_options_block),
288 redirect_router_init,
289 redirect_router_entry,
290 NULL, /* no tidyup entry */
294 { US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, 0 }
299 transport_info transports_available[] = {
300 #ifdef TRANSPORT_APPENDFILE
302 US"appendfile", /* driver name */
303 appendfile_transport_options, /* local options table */
304 &appendfile_transport_options_count, /* number of entries */
305 &appendfile_transport_option_defaults, /* private options defaults */
306 sizeof(appendfile_transport_options_block), /* size of private block */
307 appendfile_transport_init, /* init entry point */
308 appendfile_transport_entry, /* main entry point */
309 NULL, /* no tidyup entry */
310 NULL, /* no closedown entry */
311 TRUE, /* local flag */
314 #ifdef TRANSPORT_AUTOREPLY
316 US"autoreply", /* driver name */
317 autoreply_transport_options, /* local options table */
318 &autoreply_transport_options_count, /* number of entries */
319 &autoreply_transport_option_defaults, /* private options defaults */
320 sizeof(autoreply_transport_options_block), /* size of private block */
321 autoreply_transport_init, /* init entry point */
322 autoreply_transport_entry, /* main entry point */
323 NULL, /* no tidyup entry */
324 NULL, /* no closedown entry */
325 TRUE /* local flag */
328 #ifdef TRANSPORT_LMTP
330 US"lmtp", /* driver name */
331 lmtp_transport_options, /* local options table */
332 &lmtp_transport_options_count, /* number of entries */
333 &lmtp_transport_option_defaults, /* private options defaults */
334 sizeof(lmtp_transport_options_block), /* size of private block */
335 lmtp_transport_init, /* init entry point */
336 lmtp_transport_entry, /* main entry point */
337 NULL, /* no tidyup entry */
338 NULL, /* no closedown entry */
339 TRUE /* local flag */
342 #ifdef TRANSPORT_PIPE
344 US"pipe", /* driver name */
345 pipe_transport_options, /* local options table */
346 &pipe_transport_options_count, /* number of entries */
347 &pipe_transport_option_defaults, /* private options defaults */
348 sizeof(pipe_transport_options_block), /* size of private block */
349 pipe_transport_init, /* init entry point */
350 pipe_transport_entry, /* main entry point */
351 NULL, /* no tidyup entry */
352 NULL, /* no closedown entry */
353 TRUE /* local flag */
356 #ifdef TRANSPORT_SMTP
358 US"smtp", /* driver name */
359 smtp_transport_options, /* local options table */
360 &smtp_transport_options_count, /* number of entries */
361 &smtp_transport_option_defaults, /* private options defaults */
362 sizeof(smtp_transport_options_block), /* size of private block */
363 smtp_transport_init, /* init entry point */
364 smtp_transport_entry, /* main entry point */
365 NULL, /* no tidyup entry */
366 smtp_transport_closedown, /* close down passed channel */
367 FALSE /* local flag */
370 { US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, FALSE }
373 struct lookupmodulestr
376 struct lookup_module_info *info;
377 struct lookupmodulestr *next;
380 static struct lookupmodulestr *lookupmodules = NULL;
382 static void addlookupmodule(void *dl, struct lookup_module_info *info)
384 struct lookupmodulestr *p = store_malloc(sizeof(struct lookupmodulestr));
387 p->next = lookupmodules;
389 lookup_list_count += info->lookupcount;
392 /* only valid after lookup_list and lookup_list_count are assigned */
393 static void add_lookup_to_list(lookup_info *info)
395 /* need to add the lookup to lookup_list, sorted */
398 /* strategy is to go through the list until we find
399 * either an empty spot or a name that is higher.
400 * this can't fail because we have enough space. */
401 while (lookup_list[pos]
402 && (Ustrcmp(lookup_list[pos]->name, info->name) <= 0)) {
405 if (lookup_list[pos]) {
406 /* need to insert it, so move all the other items up
407 * (last slot is still empty, of course) */
408 memmove(&lookup_list[pos+1],
410 sizeof(lookup_info **) * (lookup_list_count-pos-1));
412 lookup_list[pos] = info;
416 /* These need to be at file level for old versions of gcc (2.95.2 reported),
417 * which give parse errors on an extern in function scope. Each entry needs
418 * to also be invoked in init_lookup_list() below */
420 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
421 extern lookup_module_info whoson_lookup_module_info;
423 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
424 extern lookup_module_info testdb_lookup_module_info;
426 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
427 extern lookup_module_info sqlite_lookup_module_info;
429 #ifdef EXPERIMENTAL_SPF
430 extern lookup_module_info spf_lookup_module_info;
432 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
433 extern lookup_module_info pgsql_lookup_module_info;
435 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
436 extern lookup_module_info passwd_lookup_module_info;
438 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
439 extern lookup_module_info oracle_lookup_module_info;
441 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
442 extern lookup_module_info nisplus_lookup_module_info;
444 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
445 extern lookup_module_info nis_lookup_module_info;
447 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
448 extern lookup_module_info mysql_lookup_module_info;
450 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
451 extern lookup_module_info lsearch_lookup_module_info;
454 extern lookup_module_info ldap_lookup_module_info;
456 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
457 extern lookup_module_info ibase_lookup_module_info;
459 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
460 extern lookup_module_info dsearch_lookup_module_info;
462 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
463 extern lookup_module_info dnsdb_lookup_module_info;
465 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
466 extern lookup_module_info dbmdb_lookup_module_info;
468 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
469 extern lookup_module_info cdb_lookup_module_info;
472 void init_lookup_list(void)
476 const pcre *regex_islookupmod = regex_must_compile(
477 US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE);
478 int countmodules = 0;
479 int moduleerrors = 0;
480 struct lookupmodulestr *p;
482 if (lookup_list_init_done)
484 lookup_list_init_done = 1;
486 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
487 addlookupmodule(NULL, &cdb_lookup_module_info);
490 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
491 addlookupmodule(NULL, &dbmdb_lookup_module_info);
494 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
495 addlookupmodule(NULL, &dnsdb_lookup_module_info);
498 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
499 addlookupmodule(NULL, &dsearch_lookup_module_info);
502 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
503 addlookupmodule(NULL, &ibase_lookup_module_info);
507 addlookupmodule(NULL, &ldap_lookup_module_info);
510 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
511 addlookupmodule(NULL, &lsearch_lookup_module_info);
514 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
515 addlookupmodule(NULL, &mysql_lookup_module_info);
518 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
519 addlookupmodule(NULL, &nis_lookup_module_info);
522 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
523 addlookupmodule(NULL, &nisplus_lookup_module_info);
526 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
527 addlookupmodule(NULL, &oracle_lookup_module_info);
530 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
531 addlookupmodule(NULL, &passwd_lookup_module_info);
534 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
535 addlookupmodule(NULL, &pgsql_lookup_module_info);
538 #ifdef EXPERIMENTAL_SPF
539 addlookupmodule(NULL, &spf_lookup_module_info);
542 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
543 addlookupmodule(NULL, &sqlite_lookup_module_info);
546 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
547 addlookupmodule(NULL, &testdb_lookup_module_info);
550 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
551 addlookupmodule(NULL, &whoson_lookup_module_info);
554 #ifdef LOOKUP_MODULE_DIR
555 dd = opendir(LOOKUP_MODULE_DIR);
557 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
558 log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
561 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
562 while ((ent = readdir(dd)) != NULL) {
563 char *name = ent->d_name;
564 int len = (int)strlen(name);
565 if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0) {
566 int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
568 struct lookup_module_info *info;
569 const char *errormsg;
571 /* SRH: am I being paranoid here or what? */
572 if (pathnamelen > big_buffer_size) {
573 fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
574 log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
578 /* SRH: snprintf here? */
579 sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
581 dl = dlopen(CS big_buffer, RTLD_NOW);// TJ was LAZY
583 fprintf(stderr, "Error loading %s: %s\n", name, dlerror());
585 log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, dlerror());
589 /* FreeBSD nsdispatch() can trigger dlerror() errors about
590 * _nss_cache_cycle_prevention_function; we need to clear the dlerror()
591 * state before calling dlsym(), so that any error afterwards only
592 * comes from dlsym().
594 errormsg = dlerror();
596 info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
597 if ((errormsg = dlerror()) != NULL) {
598 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
601 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
604 if (info->magic != LOOKUP_MODULE_INFO_MAGIC) {
605 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
608 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
612 addlookupmodule(dl, info);
613 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
620 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
623 store_free((void*)regex_islookupmod);
625 DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
627 lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count);
628 memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count);
630 /* now add all lookups to the real list */
634 struct lookupmodulestr *pnext;
636 for (j = 0; j < p->info->lookupcount; j++)
637 add_lookup_to_list(p->info->lookups[j]);
643 /* just to be sure */
644 lookupmodules = NULL;
647 /* End of drtables.c */