1 /* $Cambridge: exim/src/src/drtables.c,v 1.11 2009/11/16 19:50:36 nm4 Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Copyright (c) University of Cambridge 1995 - 2009 */
8 /* See the file NOTICE for conditions of use and distribution. */
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 int lookup_list_count = 0;
24 static int lookup_list_init_done = 0;
26 /* Table of information about all possible authentication mechamisms. All
27 entries are always present if any mechanism is declared, but the functions are
28 set to NULL for those that are not compiled into the binary. */
31 #include "auths/cram_md5.h"
34 #ifdef AUTH_CYRUS_SASL
35 #include "auths/cyrus_sasl.h"
39 #include "auths/dovecot.h"
43 #include "auths/plaintext.h"
47 #include "auths/spa.h"
50 auth_info auths_available[] = {
52 /* Checking by an expansion condition on plain text */
56 US"cram_md5", /* lookup name */
57 auth_cram_md5_options,
58 &auth_cram_md5_options_count,
59 &auth_cram_md5_option_defaults,
60 sizeof(auth_cram_md5_options_block),
61 auth_cram_md5_init, /* init function */
62 auth_cram_md5_server, /* server function */
63 auth_cram_md5_client /* client function */
67 #ifdef AUTH_CYRUS_SASL
69 US"cyrus_sasl", /* lookup name */
70 auth_cyrus_sasl_options,
71 &auth_cyrus_sasl_options_count,
72 &auth_cyrus_sasl_option_defaults,
73 sizeof(auth_cyrus_sasl_options_block),
74 auth_cyrus_sasl_init, /* init function */
75 auth_cyrus_sasl_server, /* server function */
76 NULL /* client function */
82 US"dovecot", /* lookup name */
84 &auth_dovecot_options_count,
85 &auth_dovecot_option_defaults,
86 sizeof(auth_dovecot_options_block),
87 auth_dovecot_init, /* init function */
88 auth_dovecot_server, /* server function */
89 NULL /* client function */
95 US"plaintext", /* lookup name */
96 auth_plaintext_options,
97 &auth_plaintext_options_count,
98 &auth_plaintext_option_defaults,
99 sizeof(auth_plaintext_options_block),
100 auth_plaintext_init, /* init function */
101 auth_plaintext_server, /* server function */
102 auth_plaintext_client /* client function */
108 US"spa", /* lookup name */
110 &auth_spa_options_count,
111 &auth_spa_option_defaults,
112 sizeof(auth_spa_options_block),
113 auth_spa_init, /* init function */
114 auth_spa_server, /* server function */
115 auth_spa_client /* client function */
119 { US"", NULL, NULL, NULL, 0, NULL, NULL, NULL }
123 /* Tables of information about which routers and transports are included in the
126 /* Pull in the necessary header files */
128 #include "routers/rf_functions.h"
131 #include "routers/accept.h"
134 #ifdef ROUTER_DNSLOOKUP
135 #include "routers/dnslookup.h"
138 #ifdef ROUTER_MANUALROUTE
139 #include "routers/manualroute.h"
142 #ifdef ROUTER_IPLITERAL
143 #include "routers/ipliteral.h"
146 #ifdef ROUTER_IPLOOKUP
147 #include "routers/iplookup.h"
150 #ifdef ROUTER_QUERYPROGRAM
151 #include "routers/queryprogram.h"
154 #ifdef ROUTER_REDIRECT
155 #include "routers/redirect.h"
158 #ifdef TRANSPORT_APPENDFILE
159 #include "transports/appendfile.h"
162 #ifdef TRANSPORT_AUTOREPLY
163 #include "transports/autoreply.h"
166 #ifdef TRANSPORT_LMTP
167 #include "transports/lmtp.h"
170 #ifdef TRANSPORT_PIPE
171 #include "transports/pipe.h"
174 #ifdef TRANSPORT_SMTP
175 #include "transports/smtp.h"
179 /* Now set up the structures, terminated by an entry with a null name. */
181 router_info routers_available[] = {
185 accept_router_options,
186 &accept_router_options_count,
187 &accept_router_option_defaults,
188 sizeof(accept_router_options_block),
191 NULL, /* no tidyup entry */
195 #ifdef ROUTER_DNSLOOKUP
198 dnslookup_router_options,
199 &dnslookup_router_options_count,
200 &dnslookup_router_option_defaults,
201 sizeof(dnslookup_router_options_block),
202 dnslookup_router_init,
203 dnslookup_router_entry,
204 NULL, /* no tidyup entry */
208 #ifdef ROUTER_IPLITERAL
211 ipliteral_router_options,
212 &ipliteral_router_options_count,
213 &ipliteral_router_option_defaults,
214 sizeof(ipliteral_router_options_block),
215 ipliteral_router_init,
216 ipliteral_router_entry,
217 NULL, /* no tidyup entry */
221 #ifdef ROUTER_IPLOOKUP
224 iplookup_router_options,
225 &iplookup_router_options_count,
226 &iplookup_router_option_defaults,
227 sizeof(iplookup_router_options_block),
228 iplookup_router_init,
229 iplookup_router_entry,
230 NULL, /* no tidyup entry */
234 #ifdef ROUTER_MANUALROUTE
237 manualroute_router_options,
238 &manualroute_router_options_count,
239 &manualroute_router_option_defaults,
240 sizeof(manualroute_router_options_block),
241 manualroute_router_init,
242 manualroute_router_entry,
243 NULL, /* no tidyup entry */
247 #ifdef ROUTER_QUERYPROGRAM
250 queryprogram_router_options,
251 &queryprogram_router_options_count,
252 &queryprogram_router_option_defaults,
253 sizeof(queryprogram_router_options_block),
254 queryprogram_router_init,
255 queryprogram_router_entry,
256 NULL, /* no tidyup entry */
260 #ifdef ROUTER_REDIRECT
263 redirect_router_options,
264 &redirect_router_options_count,
265 &redirect_router_option_defaults,
266 sizeof(redirect_router_options_block),
267 redirect_router_init,
268 redirect_router_entry,
269 NULL, /* no tidyup entry */
273 { US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, 0 }
278 transport_info transports_available[] = {
279 #ifdef TRANSPORT_APPENDFILE
281 US"appendfile", /* driver name */
282 appendfile_transport_options, /* local options table */
283 &appendfile_transport_options_count, /* number of entries */
284 &appendfile_transport_option_defaults, /* private options defaults */
285 sizeof(appendfile_transport_options_block), /* size of private block */
286 appendfile_transport_init, /* init entry point */
287 appendfile_transport_entry, /* main entry point */
288 NULL, /* no tidyup entry */
289 NULL, /* no closedown entry */
290 TRUE, /* local flag */
293 #ifdef TRANSPORT_AUTOREPLY
295 US"autoreply", /* driver name */
296 autoreply_transport_options, /* local options table */
297 &autoreply_transport_options_count, /* number of entries */
298 &autoreply_transport_option_defaults, /* private options defaults */
299 sizeof(autoreply_transport_options_block), /* size of private block */
300 autoreply_transport_init, /* init entry point */
301 autoreply_transport_entry, /* main entry point */
302 NULL, /* no tidyup entry */
303 NULL, /* no closedown entry */
304 TRUE /* local flag */
307 #ifdef TRANSPORT_LMTP
309 US"lmtp", /* driver name */
310 lmtp_transport_options, /* local options table */
311 &lmtp_transport_options_count, /* number of entries */
312 &lmtp_transport_option_defaults, /* private options defaults */
313 sizeof(lmtp_transport_options_block), /* size of private block */
314 lmtp_transport_init, /* init entry point */
315 lmtp_transport_entry, /* main entry point */
316 NULL, /* no tidyup entry */
317 NULL, /* no closedown entry */
318 TRUE /* local flag */
321 #ifdef TRANSPORT_PIPE
323 US"pipe", /* driver name */
324 pipe_transport_options, /* local options table */
325 &pipe_transport_options_count, /* number of entries */
326 &pipe_transport_option_defaults, /* private options defaults */
327 sizeof(pipe_transport_options_block), /* size of private block */
328 pipe_transport_init, /* init entry point */
329 pipe_transport_entry, /* main entry point */
330 NULL, /* no tidyup entry */
331 NULL, /* no closedown entry */
332 TRUE /* local flag */
335 #ifdef TRANSPORT_SMTP
337 US"smtp", /* driver name */
338 smtp_transport_options, /* local options table */
339 &smtp_transport_options_count, /* number of entries */
340 &smtp_transport_option_defaults, /* private options defaults */
341 sizeof(smtp_transport_options_block), /* size of private block */
342 smtp_transport_init, /* init entry point */
343 smtp_transport_entry, /* main entry point */
344 NULL, /* no tidyup entry */
345 smtp_transport_closedown, /* close down passed channel */
346 FALSE /* local flag */
349 { US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, FALSE }
352 struct lookupmodulestr
355 struct lookup_module_info *info;
356 struct lookupmodulestr *next;
359 static struct lookupmodulestr *lookupmodules = NULL;
361 static void addlookupmodule(void *dl, struct lookup_module_info *info)
363 struct lookupmodulestr *p = store_malloc(sizeof(struct lookupmodulestr));
366 p->next = lookupmodules;
368 lookup_list_count += info->lookupcount;
371 /* only valid after lookup_list and lookup_list_count are assigned */
372 static void add_lookup_to_list(lookup_info *info)
374 /* need to add the lookup to lookup_list, sorted */
377 /* strategy is to go through the list until we find
378 * either an empty spot or a name that is higher.
379 * this can't fail because we have enough space. */
380 while (lookup_list[pos]
381 && (Ustrcmp(lookup_list[pos]->name, info->name) <= 0)) {
384 if (lookup_list[pos]) {
385 /* need to insert it, so move all the other items up
386 * (last slot is still empty, of course) */
387 memmove(&lookup_list[pos+1],
389 sizeof(lookup_info **) * (lookup_list_count-pos-1));
391 lookup_list[pos] = info;
395 /* These need to be at file level for old versions of gcc (2.95.2 reported),
396 * which give parse errors on an extern in function scope. Each entry needs
397 * to also be invoked in init_lookup_list() below */
399 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
400 extern lookup_module_info whoson_lookup_module_info;
402 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
403 extern lookup_module_info testdb_lookup_module_info;
405 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
406 extern lookup_module_info sqlite_lookup_module_info;
408 #ifdef EXPERIMENTAL_SPF
409 extern lookup_module_info spf_lookup_module_info;
411 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
412 extern lookup_module_info pgsql_lookup_module_info;
414 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
415 extern lookup_module_info passwd_lookup_module_info;
417 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
418 extern lookup_module_info oracle_lookup_module_info;
420 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
421 extern lookup_module_info nisplus_lookup_module_info;
423 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
424 extern lookup_module_info nis_lookup_module_info;
426 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
427 extern lookup_module_info mysql_lookup_module_info;
429 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
430 extern lookup_module_info lsearch_lookup_module_info;
433 extern lookup_module_info ldap_lookup_module_info;
435 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
436 extern lookup_module_info ibase_lookup_module_info;
438 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
439 extern lookup_module_info dsearch_lookup_module_info;
441 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
442 extern lookup_module_info dnsdb_lookup_module_info;
444 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
445 extern lookup_module_info dbmdb_lookup_module_info;
447 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
448 extern lookup_module_info cdb_lookup_module_info;
451 void init_lookup_list(void)
455 const pcre *regex_islookupmod = regex_must_compile(US"\\.so$", FALSE, TRUE);
456 int countmodules = 0;
457 int moduleerrors = 0;
458 struct lookupmodulestr *p;
460 if (lookup_list_init_done)
462 lookup_list_init_done = 1;
464 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
465 addlookupmodule(NULL, &cdb_lookup_module_info);
468 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
469 addlookupmodule(NULL, &dbmdb_lookup_module_info);
472 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
473 addlookupmodule(NULL, &dnsdb_lookup_module_info);
476 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
477 addlookupmodule(NULL, &dsearch_lookup_module_info);
480 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
481 addlookupmodule(NULL, &ibase_lookup_module_info);
485 addlookupmodule(NULL, &ldap_lookup_module_info);
488 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
489 addlookupmodule(NULL, &lsearch_lookup_module_info);
492 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
493 addlookupmodule(NULL, &mysql_lookup_module_info);
496 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
497 addlookupmodule(NULL, &nis_lookup_module_info);
500 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
501 addlookupmodule(NULL, &nisplus_lookup_module_info);
504 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
505 addlookupmodule(NULL, &oracle_lookup_module_info);
508 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
509 addlookupmodule(NULL, &passwd_lookup_module_info);
512 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
513 addlookupmodule(NULL, &pgsql_lookup_module_info);
516 #ifdef EXPERIMENTAL_SPF
517 addlookupmodule(NULL, &spf_lookup_module_info);
520 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
521 addlookupmodule(NULL, &sqlite_lookup_module_info);
524 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
525 addlookupmodule(NULL, &testdb_lookup_module_info);
528 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
529 addlookupmodule(NULL, &whoson_lookup_module_info);
532 #ifdef LOOKUP_MODULE_DIR
533 dd = opendir(LOOKUP_MODULE_DIR);
535 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
536 log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
539 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
540 while ((ent = readdir(dd)) != NULL) {
541 char *name = ent->d_name;
542 int len = (int)strlen(name);
543 if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0) {
544 int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
546 struct lookup_module_info *info;
547 const char *errormsg;
549 /* SRH: am I being paranoid here or what? */
550 if (pathnamelen > big_buffer_size) {
551 fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
552 log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
556 /* SRH: snprintf here? */
557 sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
559 dl = dlopen(CS big_buffer, RTLD_NOW);// TJ was LAZY
561 fprintf(stderr, "Error loading %s: %s\n", name, dlerror());
563 log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, dlerror());
567 /* FreeBSD nsdispatch() can trigger dlerror() errors about
568 * _nss_cache_cycle_prevention_function; we need to clear the dlerror()
569 * state before calling dlsym(), so that any error afterwards only
570 * comes from dlsym().
572 errormsg = dlerror();
574 info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
575 if ((errormsg = dlerror()) != NULL) {
576 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
579 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
582 if (info->magic != LOOKUP_MODULE_INFO_MAGIC) {
583 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
586 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
590 addlookupmodule(dl, info);
591 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
598 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
601 store_free((void*)regex_islookupmod);
603 DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
605 lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count);
606 memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count);
608 /* now add all lookups to the real list */
612 struct lookupmodulestr *pnext;
614 for (j = 0; j < p->info->lookupcount; j++)
615 add_lookup_to_list(p->info->lookups[j]);
621 /* just to be sure */
622 lookupmodules = NULL;
625 /* End of drtables.c */