1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) The Exim Maintainers 2020 - 2023 */
6 /* Copyright (c) University of Cambridge 1995 - 2018 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
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 /* Table of information about all possible authentication mechanisms. 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/external.h"
45 #include "auths/gsasl_exim.h"
48 #ifdef AUTH_HEIMDAL_GSSAPI
49 #include "auths/heimdal_gssapi.h"
53 #include "auths/plaintext.h"
57 #include "auths/spa.h"
61 #include "auths/tls.h"
64 auth_info * auths_available_newlist = NULL;
65 auth_info auths_available_oldarray[] = {
67 /* Checking by an expansion condition on plain text */
72 .driver_name = US"cram_md5", /* lookup name */
73 .options = auth_cram_md5_options,
74 .options_count = &auth_cram_md5_options_count,
75 .options_block = &auth_cram_md5_option_defaults,
76 .options_len = sizeof(auth_cram_md5_options_block),
77 .init = auth_cram_md5_init,
79 .servercode = auth_cram_md5_server,
80 .clientcode = auth_cram_md5_client,
81 .version_report = NULL,
82 .macros_create = NULL,
86 #ifdef AUTH_CYRUS_SASL
89 .driver_name = US"cyrus_sasl",
90 .options = auth_cyrus_sasl_options,
91 .options_count = &auth_cyrus_sasl_options_count,
92 .options_block = &auth_cyrus_sasl_option_defaults,
93 .options_len = sizeof(auth_cyrus_sasl_options_block),
94 .init = auth_cyrus_sasl_init,
96 .servercode = auth_cyrus_sasl_server,
98 .version_report = auth_cyrus_sasl_version_report,
99 .macros_create = NULL,
106 .driver_name = US"dovecot",
107 .options = auth_dovecot_options,
108 .options_count = &auth_dovecot_options_count,
109 .options_block = &auth_dovecot_option_defaults,
110 .options_len = sizeof(auth_dovecot_options_block),
111 .init = auth_dovecot_init,
113 .servercode = auth_dovecot_server,
115 .version_report = NULL,
116 .macros_create = NULL,
123 .driver_name = US"external",
124 .options = auth_external_options,
125 .options_count = &auth_external_options_count,
126 .options_block = &auth_external_option_defaults,
127 .options_len = sizeof(auth_external_options_block),
128 .init = auth_external_init,
130 .servercode = auth_external_server,
131 .clientcode = auth_external_client,
132 .version_report = NULL,
133 .macros_create = NULL,
140 .driver_name = US"gsasl",
141 .options = auth_gsasl_options,
142 .options_count = &auth_gsasl_options_count,
143 .options_block = &auth_gsasl_option_defaults,
144 .options_len = sizeof(auth_gsasl_options_block),
145 .init = auth_gsasl_init,
147 .servercode = auth_gsasl_server,
148 .clientcode = auth_gsasl_client,
149 .version_report = auth_gsasl_version_report,
150 .macros_create = auth_gsasl_macros,
154 #ifdef AUTH_HEIMDAL_GSSAPI
157 .driver_name = US"heimdal_gssapi",
158 .options = auth_heimdal_gssapi_options,
159 .options_count = &auth_heimdal_gssapi_options_count,
160 .options_block = &auth_heimdal_gssapi_option_defaults,
161 .options_len = sizeof(auth_heimdal_gssapi_options_block),
162 .init = auth_heimdal_gssapi_init,
164 .servercode = auth_heimdal_gssapi_server,
166 .version_report = auth_heimdal_gssapi_version_report,
167 .macros_create = NULL,
171 #ifdef AUTH_PLAINTEXT
174 .driver_name = US"plaintext",
175 .options = auth_plaintext_options,
176 .options_count = &auth_plaintext_options_count,
177 .options_block = &auth_plaintext_option_defaults,
178 .options_len = sizeof(auth_plaintext_options_block),
179 .init = auth_plaintext_init,
181 .servercode = auth_plaintext_server,
182 .clientcode = auth_plaintext_client,
183 .version_report = NULL,
184 .macros_create = NULL,
191 .driver_name = US"spa",
192 .options = auth_spa_options,
193 .options_count = &auth_spa_options_count,
194 .options_block = &auth_spa_option_defaults,
195 .options_len = sizeof(auth_spa_options_block),
196 .init = auth_spa_init,
198 .servercode = auth_spa_server,
199 .clientcode = auth_spa_client,
200 .version_report = NULL,
201 .macros_create = NULL,
208 .driver_name = US"tls",
209 .options = auth_tls_options,
210 .options_count = &auth_tls_options_count,
211 .options_block = &auth_tls_option_defaults,
212 .options_len = sizeof(auth_tls_options_block),
213 .init = auth_tls_init,
215 .servercode = auth_tls_server,
217 .version_report = NULL,
218 .macros_create = NULL,
222 { .drinfo = { .driver_name = US"" }} /* end marker */
226 /* Tables of information about which routers and transports are included in the
229 /* Pull in the necessary header files */
231 #include "routers/rf_functions.h"
234 # include "routers/accept.h"
237 #ifdef ROUTER_DNSLOOKUP
238 # include "routers/dnslookup.h"
241 #ifdef ROUTER_MANUALROUTE
242 # include "routers/manualroute.h"
245 #ifdef ROUTER_IPLITERAL
246 # include "routers/ipliteral.h"
249 #ifdef ROUTER_IPLOOKUP
250 # include "routers/iplookup.h"
253 #ifdef ROUTER_QUERYPROGRAM
254 # include "routers/queryprogram.h"
257 #ifdef ROUTER_REDIRECT
258 # include "routers/redirect.h"
261 #ifdef TRANSPORT_APPENDFILE
262 # include "transports/appendfile.h"
265 #ifdef TRANSPORT_AUTOREPLY
266 # include "transports/autoreply.h"
269 #ifdef TRANSPORT_LMTP
270 # include "transports/lmtp.h"
273 #ifdef TRANSPORT_PIPE
274 # include "transports/pipe.h"
277 #ifdef EXPERIMENTAL_QUEUEFILE
278 # include "transports/queuefile.h"
281 #ifdef TRANSPORT_SMTP
282 # include "transports/smtp.h"
286 router_info * routers_available_newlist = NULL;
288 /* Now set up the structures, terminated by an entry with a null name. */
290 router_info routers_available_oldarray[] = {
294 .driver_name = US"accept",
295 .options = accept_router_options,
296 .options_count = &accept_router_options_count,
297 .options_block = &accept_router_option_defaults,
298 .options_len = sizeof(accept_router_options_block),
299 .init = accept_router_init,
301 .code = accept_router_entry,
302 .tidyup = NULL, /* no tidyup entry */
303 .ri_flags = ri_yestransport
306 #ifdef ROUTER_DNSLOOKUP
309 .driver_name = US"dnslookup",
310 .options = dnslookup_router_options,
311 .options_count = &dnslookup_router_options_count,
312 .options_block = &dnslookup_router_option_defaults,
313 .options_len = sizeof(dnslookup_router_options_block),
314 .init = dnslookup_router_init,
316 .code = dnslookup_router_entry,
317 .tidyup = NULL, /* no tidyup entry */
318 .ri_flags = ri_yestransport
321 #ifdef ROUTER_IPLITERAL
324 .driver_name = US"ipliteral",
325 .options = ipliteral_router_options,
326 .options_count = &ipliteral_router_options_count,
327 .options_block = &ipliteral_router_option_defaults,
328 .options_len = sizeof(ipliteral_router_options_block),
329 .init = ipliteral_router_init,
331 .code = ipliteral_router_entry,
332 .tidyup = NULL, /* no tidyup entry */
333 .ri_flags = ri_yestransport
336 #ifdef ROUTER_IPLOOKUP
339 .driver_name = US"iplookup",
340 .options = iplookup_router_options,
341 .options_count = &iplookup_router_options_count,
342 .options_block = &iplookup_router_option_defaults,
343 .options_len = sizeof(iplookup_router_options_block),
344 .init = iplookup_router_init,
346 .code = iplookup_router_entry,
347 .tidyup = NULL, /* no tidyup entry */
348 .ri_flags = ri_notransport
351 #ifdef ROUTER_MANUALROUTE
354 .driver_name = US"manualroute",
355 .options = manualroute_router_options,
356 .options_count = &manualroute_router_options_count,
357 .options_block = &manualroute_router_option_defaults,
358 .options_len = sizeof(manualroute_router_options_block),
359 .init = manualroute_router_init,
361 .code = manualroute_router_entry,
362 .tidyup = NULL, /* no tidyup entry */
366 #ifdef ROUTER_REDIRECT
369 .driver_name = US"redirect",
370 .options = redirect_router_options,
371 .options_count = &redirect_router_options_count,
372 .options_block = &redirect_router_option_defaults,
373 .options_len = sizeof(redirect_router_options_block),
374 .init = redirect_router_init,
376 .code = redirect_router_entry,
377 .tidyup = NULL, /* no tidyup entry */
378 .ri_flags = ri_notransport
381 { .drinfo = { .driver_name = US"" }}
386 transport_info * transports_available_newlist = NULL;
387 transport_info transports_available_oldarray[] = {
388 #ifdef TRANSPORT_APPENDFILE
391 .driver_name = US"appendfile",
392 .options = appendfile_transport_options,
393 .options_count = &appendfile_transport_options_count,
394 .options_block = &appendfile_transport_option_defaults, /* private options defaults */
395 .options_len = sizeof(appendfile_transport_options_block),
396 .init = appendfile_transport_init,
398 .code = appendfile_transport_entry,
404 #ifdef TRANSPORT_AUTOREPLY
407 .driver_name = US"autoreply",
408 .options = autoreply_transport_options,
409 .options_count = &autoreply_transport_options_count,
410 .options_block = &autoreply_transport_option_defaults,
411 .options_len = sizeof(autoreply_transport_options_block),
412 .init = autoreply_transport_init,
414 .code = autoreply_transport_entry,
420 #ifdef TRANSPORT_LMTP
423 .driver_name = US"lmtp",
424 .options = lmtp_transport_options,
425 .options_count = &lmtp_transport_options_count,
426 .options_block = &lmtp_transport_option_defaults,
427 .options_len = sizeof(lmtp_transport_options_block),
428 .init = lmtp_transport_init,
430 .code = lmtp_transport_entry,
436 #ifdef TRANSPORT_PIPE
439 .driver_name = US"pipe",
440 .options = pipe_transport_options,
441 .options_count = &pipe_transport_options_count,
442 .options_block = &pipe_transport_option_defaults,
443 .options_len = sizeof(pipe_transport_options_block),
444 .init = pipe_transport_init,
446 .code = pipe_transport_entry,
452 #ifdef EXPERIMENTAL_QUEUEFILE
455 .driver_name = US"queuefile",
456 .options = queuefile_transport_options,
457 .options_count = &queuefile_transport_options_count,
458 .options_block = &queuefile_transport_option_defaults,
459 .options_len = sizeof(queuefile_transport_options_block),
460 .init = queuefile_transport_init,
462 .code = queuefile_transport_entry,
468 #ifdef TRANSPORT_SMTP
471 .driver_name = US"smtp",
472 .options = smtp_transport_options,
473 .options_count = &smtp_transport_options_count,
474 .options_block = &smtp_transport_option_defaults,
475 .options_len = sizeof(smtp_transport_options_block),
476 .init = smtp_transport_init,
478 .code = smtp_transport_entry,
480 .closedown = smtp_transport_closedown,
484 { .drinfo = { .driver_name = US"" }}
490 auth_show_supported(gstring * g)
492 g = string_cat(g, US"Authenticators:");
493 /*XXX these run off the static list as we want them before the conf is read */
494 /*XXX Could possibly check for dyn flag + file presence */
495 for (auth_info * ai = auths_available_oldarray; ai->drinfo.driver_name[0]; ai++)
496 g = string_fmt_append(g, " %s", ai->drinfo.driver_name);
497 return string_cat(g, US"\n");
501 route_show_supported(gstring * g)
503 gstring * b = NULL, * d = NULL;
506 g = string_cat(g, US"Routers:");
507 /*XXX these run off the static list as we want them before the conf is read */
508 /*XXX lookup_show_supported is in exim.c and just works off the #defines, with hardoded strings */
509 for (router_info * rr = routers_available_oldarray; rr->drinfo.driver_name[0]; rr++)
510 g = string_fmt_append(g, " %s", rr->drinfo.driver_name);
514 # if ROUTER_ACCEPT!=2
515 b = string_cat(b, US" accept");
517 d = string_cat(d, US" cdb");
520 #ifdef ROUTER_DNSLOOKUP
521 # if ROUTER_DNSLOOKUP!=2
522 b = string_cat(g, US" dnslookup");
524 d = string_cat(g, US" dnslookup");
527 # ifdef ROUTER_IPLITERAL
528 # if ROUTER_IPLITERAL!=2
529 b = string_cat(g, US" ipliteral");
531 d = string_cat(g, US" ipliteral");
534 #ifdef ROUTER_IPLOOKUP
535 # if ROUTER_IPLOOKUP!=2
536 b = string_cat(g, US" iplookup");
538 d = string_cat(g, US" iplookup");
541 #ifdef ROUTER_MANUALROUTE
542 # if ROUTER_MANUALROUTE!=2
543 b = string_cat(g, US" manualroute");
545 d = string_cat(g, US" manualroute");
548 #ifdef ROUTER_REDIRECT
549 # if ROUTER_REDIRECT!=2
550 b = string_cat(g, US" redirect");
552 d = string_cat(g, US" redirect");
555 #ifdef ROUTER_QUERYPROGRAM
556 # if ROUTER_QUERYPROGRAM!=2
557 b = string_cat(g, US" queryprogram");
559 d = string_cat(g, US" queryprogram");
563 if (b) g = string_fmt_append(g, "Routers (built-in):%Y\n", b);
564 if (d) g = string_fmt_append(g, "Routers (dynamic): %Y\n", d);
566 return string_cat(g, US"\n");
570 transport_show_supported(gstring * g)
572 g = string_cat(g, US"Transports:");
573 #ifdef TRANSPORT_APPENDFILE
574 g = string_cat(g, US" appendfile");
575 #ifdef SUPPORT_MAILDIR
576 g = string_cat(g, US"/maildir"); /* damn these subclasses */
578 #ifdef SUPPORT_MAILSTORE
579 g = string_cat(g, US"/mailstore");
582 g = string_cat(g, US"/mbx");
585 #ifdef TRANSPORT_AUTOREPLY
586 g = string_cat(g, US" autoreply");
588 #ifdef TRANSPORT_LMTP
589 g = string_cat(g, US" lmtp");
591 #ifdef TRANSPORT_PIPE
592 g = string_cat(g, US" pipe");
594 #ifdef EXPERIMENTAL_QUEUEFILE
595 g = string_cat(g, US" queuefile");
597 #ifdef TRANSPORT_SMTP
598 g = string_cat(g, US" smtp");
600 return string_cat(g, US"\n");
605 struct lookupmodulestr
608 struct lookup_module_info *info;
609 struct lookupmodulestr *next;
612 static struct lookupmodulestr *lookupmodules = NULL;
615 addlookupmodule(void *dl, struct lookup_module_info *info)
617 struct lookupmodulestr * p =
618 store_get(sizeof(struct lookupmodulestr), GET_UNTAINTED);
622 p->next = lookupmodules;
624 lookup_list_count += info->lookupcount;
627 /* only valid after lookup_list and lookup_list_count are assigned */
629 add_lookup_to_list(lookup_info *info)
631 /* need to add the lookup to lookup_list, sorted */
634 /* strategy is to go through the list until we find
635 either an empty spot or a name that is higher.
636 this can't fail because we have enough space. */
638 while (lookup_list[pos] && (Ustrcmp(lookup_list[pos]->name, info->name) <= 0))
641 if (lookup_list[pos])
643 /* need to insert it, so move all the other items up
644 (last slot is still empty, of course) */
646 memmove(&lookup_list[pos+1], &lookup_list[pos],
647 sizeof(lookup_info *) * (lookup_list_count-pos-1));
649 lookup_list[pos] = info;
653 /* These need to be at file level for old versions of gcc (2.95.2 reported),
654 which give parse errors on an extern in function scope. Each entry needs
655 to also be invoked in init_lookup_list() below */
657 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
658 extern lookup_module_info cdb_lookup_module_info;
660 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
661 extern lookup_module_info dbmdb_lookup_module_info;
663 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
664 extern lookup_module_info dnsdb_lookup_module_info;
666 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
667 extern lookup_module_info dsearch_lookup_module_info;
669 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
670 extern lookup_module_info ibase_lookup_module_info;
672 #if defined(LOOKUP_JSON) && LOOKUP_JSON!=2
673 extern lookup_module_info json_lookup_module_info;
675 #if defined(LOOKUP_LDAP)
676 extern lookup_module_info ldap_lookup_module_info;
678 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
679 extern lookup_module_info lsearch_lookup_module_info;
681 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
682 extern lookup_module_info mysql_lookup_module_info;
684 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
685 extern lookup_module_info nis_lookup_module_info;
687 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
688 extern lookup_module_info nisplus_lookup_module_info;
690 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
691 extern lookup_module_info oracle_lookup_module_info;
693 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
694 extern lookup_module_info passwd_lookup_module_info;
696 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
697 extern lookup_module_info pgsql_lookup_module_info;
699 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
700 extern lookup_module_info redis_lookup_module_info;
702 #if defined(LOOKUP_LMDB)
703 extern lookup_module_info lmdb_lookup_module_info;
705 #if defined(SUPPORT_SPF)
706 extern lookup_module_info spf_lookup_module_info;
708 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
709 extern lookup_module_info sqlite_lookup_module_info;
711 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
712 extern lookup_module_info testdb_lookup_module_info;
714 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
715 extern lookup_module_info whoson_lookup_module_info;
718 extern lookup_module_info readsock_lookup_module_info;
722 init_lookup_list(void)
724 #ifdef LOOKUP_MODULE_DIR
727 int countmodules = 0;
728 int moduleerrors = 0;
730 static BOOL lookup_list_init_done = FALSE;
733 if (lookup_list_init_done)
735 reset_point = store_mark();
736 lookup_list_init_done = TRUE;
738 #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
739 addlookupmodule(NULL, &cdb_lookup_module_info);
742 #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
743 addlookupmodule(NULL, &dbmdb_lookup_module_info);
746 #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
747 addlookupmodule(NULL, &dnsdb_lookup_module_info);
750 #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
751 addlookupmodule(NULL, &dsearch_lookup_module_info);
754 #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
755 addlookupmodule(NULL, &ibase_lookup_module_info);
759 addlookupmodule(NULL, &ldap_lookup_module_info);
762 #if defined(LOOKUP_JSON) && LOOKUP_JSON!=2
763 addlookupmodule(NULL, &json_lookup_module_info);
766 #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
767 addlookupmodule(NULL, &lsearch_lookup_module_info);
770 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
771 addlookupmodule(NULL, &mysql_lookup_module_info);
774 #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
775 addlookupmodule(NULL, &nis_lookup_module_info);
778 #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
779 addlookupmodule(NULL, &nisplus_lookup_module_info);
782 #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
783 addlookupmodule(NULL, &oracle_lookup_module_info);
786 #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
787 addlookupmodule(NULL, &passwd_lookup_module_info);
790 #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
791 addlookupmodule(NULL, &pgsql_lookup_module_info);
794 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
795 addlookupmodule(NULL, &redis_lookup_module_info);
799 addlookupmodule(NULL, &lmdb_lookup_module_info);
803 addlookupmodule(NULL, &spf_lookup_module_info);
806 #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
807 addlookupmodule(NULL, &sqlite_lookup_module_info);
810 #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
811 addlookupmodule(NULL, &testdb_lookup_module_info);
814 #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
815 addlookupmodule(NULL, &whoson_lookup_module_info);
818 /* This is a custom expansion, and not available as either
819 a list-syntax lookup or a lookup expansion. However, it is
820 implemented by a lookup module. */
822 addlookupmodule(NULL, &readsock_lookup_module_info);
824 #ifdef LOOKUP_MODULE_DIR
825 if (!(dd = exim_opendir(CUS LOOKUP_MODULE_DIR)))
827 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
828 log_write(0, LOG_MAIN|LOG_PANIC,
829 "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
833 const pcre2_code * regex_islookupmod = regex_must_compile(
834 US"_lookup\\." DYNLIB_FN_EXT "$", MCS_NOFLAGS, TRUE);
836 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
837 while ((ent = readdir(dd)))
839 char * name = ent->d_name;
840 int len = (int)strlen(name);
841 if (regex_match(regex_islookupmod, US name, len, NULL))
843 int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
845 struct lookup_module_info *info;
846 const char *errormsg;
848 /* SRH: am I being paranoid here or what? */
849 if (pathnamelen > big_buffer_size)
851 fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
852 log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
856 /* SRH: snprintf here? */
857 sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
859 if (!(dl = dlopen(CS big_buffer, RTLD_NOW)))
861 errormsg = dlerror();
862 fprintf(stderr, "Error loading %s: %s\n", name, errormsg);
863 log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, errormsg);
868 /* FreeBSD nsdispatch() can trigger dlerror() errors about
869 _nss_cache_cycle_prevention_function; we need to clear the dlerror()
870 state before calling dlsym(), so that any error afterwards only comes
873 errormsg = dlerror();
875 info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
876 if ((errormsg = dlerror()))
878 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
879 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
884 if (info->magic != LOOKUP_MODULE_INFO_MAGIC)
886 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
887 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
893 addlookupmodule(dl, info);
894 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
898 store_free((void*)regex_islookupmod);
902 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
905 DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
907 lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count);
908 memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count);
910 /* now add all lookups to the real list */
911 for (struct lookupmodulestr * p = lookupmodules; p; p = p->next)
912 for (int j = 0; j < p->info->lookupcount; j++)
913 add_lookup_to_list(p->info->lookups[j]);
914 store_reset(reset_point);
915 /* just to be sure */
916 lookupmodules = NULL;
919 #endif /*!MACRO_PREDEF*/
920 /* End of drtables.c */