SPF: switch to NO_DATA for SPF-rr lookups. Bug 1294
[exim.git] / src / src / drtables.c
CommitLineData
059ec3d9
PH
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
f9ba5e22 5/* Copyright (c) University of Cambridge 1995 - 2018 */
059ec3d9
PH
6/* See the file NOTICE for conditions of use and distribution. */
7
8
9#include "exim.h"
10
e6d225ae 11#include <string.h>
059ec3d9
PH
12
13/* This module contains tables that define the lookup methods and drivers
14that are actually included in the binary. Its contents are controlled by
15various macros in config.h that ultimately come from Local/Makefile. They are
16all described in src/EDITME. */
17
18
e6d225ae
DW
19lookup_info **lookup_list;
20int lookup_list_count = 0;
059ec3d9 21
4c04137d 22/* Table of information about all possible authentication mechanisms. All
059ec3d9
PH
23entries are always present if any mechanism is declared, but the functions are
24set to NULL for those that are not compiled into the binary. */
25
26#ifdef AUTH_CRAM_MD5
27#include "auths/cram_md5.h"
28#endif
29
30#ifdef AUTH_CYRUS_SASL
31#include "auths/cyrus_sasl.h"
32#endif
33
14aa5a05
PH
34#ifdef AUTH_DOVECOT
35#include "auths/dovecot.h"
36#endif
37
b53c265b
JH
38#ifdef AUTH_EXTERNAL
39#include "auths/external.h"
40#endif
41
44bbabb5
PP
42#ifdef AUTH_GSASL
43#include "auths/gsasl_exim.h"
44#endif
45
dde3daac
PP
46#ifdef AUTH_HEIMDAL_GSSAPI
47#include "auths/heimdal_gssapi.h"
48#endif
49
059ec3d9
PH
50#ifdef AUTH_PLAINTEXT
51#include "auths/plaintext.h"
52#endif
53
54#ifdef AUTH_SPA
55#include "auths/spa.h"
56#endif
57
b3ef41c9
JH
58#ifdef AUTH_TLS
59#include "auths/tls.h"
60#endif
61
059ec3d9
PH
62auth_info auths_available[] = {
63
64/* Checking by an expansion condition on plain text */
65
66#ifdef AUTH_CRAM_MD5
67 {
f2ed27cf
JH
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,
25bd12fd
JH
76 .version_report = NULL,
77 .macros_create = NULL,
059ec3d9
PH
78 },
79#endif
80
81#ifdef AUTH_CYRUS_SASL
82 {
f2ed27cf
JH
83 .driver_name = US"cyrus_sasl",
84 .options = auth_cyrus_sasl_options,
85 .options_count = &auth_cyrus_sasl_options_count,
86 .options_block = &auth_cyrus_sasl_option_defaults,
87 .options_len = sizeof(auth_cyrus_sasl_options_block),
88 .init = auth_cyrus_sasl_init,
89 .servercode = auth_cyrus_sasl_server,
90 .clientcode = NULL,
25bd12fd
JH
91 .version_report = auth_cyrus_sasl_version_report,
92 .macros_create = NULL,
059ec3d9
PH
93 },
94#endif
95
14aa5a05
PH
96#ifdef AUTH_DOVECOT
97 {
f2ed27cf
JH
98 .driver_name = US"dovecot",
99 .options = auth_dovecot_options,
100 .options_count = &auth_dovecot_options_count,
101 .options_block = &auth_dovecot_option_defaults,
102 .options_len = sizeof(auth_dovecot_options_block),
103 .init = auth_dovecot_init,
104 .servercode = auth_dovecot_server,
105 .clientcode = NULL,
25bd12fd
JH
106 .version_report = NULL,
107 .macros_create = NULL,
44bbabb5
PP
108 },
109#endif
110
b53c265b
JH
111#ifdef AUTH_EXTERNAL
112 {
113 .driver_name = US"external",
114 .options = auth_external_options,
115 .options_count = &auth_external_options_count,
116 .options_block = &auth_external_option_defaults,
117 .options_len = sizeof(auth_external_options_block),
118 .init = auth_external_init,
119 .servercode = auth_external_server,
120 .clientcode = auth_external_client,
25bd12fd
JH
121 .version_report = NULL,
122 .macros_create = NULL,
b53c265b
JH
123 },
124#endif
125
44bbabb5
PP
126#ifdef AUTH_GSASL
127 {
f2ed27cf
JH
128 .driver_name = US"gsasl",
129 .options = auth_gsasl_options,
130 .options_count = &auth_gsasl_options_count,
131 .options_block = &auth_gsasl_option_defaults,
132 .options_len = sizeof(auth_gsasl_options_block),
133 .init = auth_gsasl_init,
134 .servercode = auth_gsasl_server,
14a806d6 135 .clientcode = auth_gsasl_client,
25bd12fd
JH
136 .version_report = auth_gsasl_version_report,
137 .macros_create = auth_gsasl_macros,
14aa5a05
PH
138 },
139#endif
140
dde3daac
PP
141#ifdef AUTH_HEIMDAL_GSSAPI
142 {
f2ed27cf
JH
143 .driver_name = US"heimdal_gssapi",
144 .options = auth_heimdal_gssapi_options,
7be14582 145 .options_count = &auth_heimdal_gssapi_options_count,
f2ed27cf
JH
146 .options_block = &auth_heimdal_gssapi_option_defaults,
147 .options_len = sizeof(auth_heimdal_gssapi_options_block),
148 .init = auth_heimdal_gssapi_init,
149 .servercode = auth_heimdal_gssapi_server,
150 .clientcode = NULL,
25bd12fd
JH
151 .version_report = auth_heimdal_gssapi_version_report,
152 .macros_create = NULL,
dde3daac
PP
153 },
154#endif
155
059ec3d9
PH
156#ifdef AUTH_PLAINTEXT
157 {
f2ed27cf
JH
158 .driver_name = US"plaintext",
159 .options = auth_plaintext_options,
160 .options_count = &auth_plaintext_options_count,
161 .options_block = &auth_plaintext_option_defaults,
162 .options_len = sizeof(auth_plaintext_options_block),
163 .init = auth_plaintext_init,
164 .servercode = auth_plaintext_server,
165 .clientcode = auth_plaintext_client,
25bd12fd
JH
166 .version_report = NULL,
167 .macros_create = NULL,
059ec3d9
PH
168 },
169#endif
170
171#ifdef AUTH_SPA
172 {
f2ed27cf
JH
173 .driver_name = US"spa",
174 .options = auth_spa_options,
175 .options_count = &auth_spa_options_count,
176 .options_block = &auth_spa_option_defaults,
177 .options_len = sizeof(auth_spa_options_block),
178 .init = auth_spa_init,
179 .servercode = auth_spa_server,
180 .clientcode = auth_spa_client,
25bd12fd
JH
181 .version_report = NULL,
182 .macros_create = NULL,
059ec3d9
PH
183 },
184#endif
185
b3ef41c9
JH
186#ifdef AUTH_TLS
187 {
f2ed27cf
JH
188 .driver_name = US"tls",
189 .options = auth_tls_options,
190 .options_count = &auth_tls_options_count,
191 .options_block = &auth_tls_option_defaults,
192 .options_len = sizeof(auth_tls_options_block),
193 .init = auth_tls_init,
194 .servercode = auth_tls_server,
195 .clientcode = NULL,
25bd12fd
JH
196 .version_report = NULL,
197 .macros_create = NULL,
b3ef41c9
JH
198 },
199#endif
200
adf73d37 201 { .driver_name = US"" } /* end marker */
059ec3d9
PH
202};
203
adf73d37
JH
204void
205auth_show_supported(FILE * f)
206{
adf73d37 207fprintf(f, "Authenticators:");
d7978c0f 208for (auth_info * ai = auths_available; ai->driver_name[0]; ai++)
adf73d37
JH
209 fprintf(f, " %s", ai->driver_name);
210fprintf(f, "\n");
211}
212
059ec3d9
PH
213
214/* Tables of information about which routers and transports are included in the
215exim binary. */
216
217/* Pull in the necessary header files */
218
219#include "routers/rf_functions.h"
220
221#ifdef ROUTER_ACCEPT
222#include "routers/accept.h"
223#endif
224
225#ifdef ROUTER_DNSLOOKUP
226#include "routers/dnslookup.h"
227#endif
228
229#ifdef ROUTER_MANUALROUTE
230#include "routers/manualroute.h"
231#endif
232
233#ifdef ROUTER_IPLITERAL
234#include "routers/ipliteral.h"
235#endif
236
237#ifdef ROUTER_IPLOOKUP
238#include "routers/iplookup.h"
239#endif
240
241#ifdef ROUTER_QUERYPROGRAM
242#include "routers/queryprogram.h"
243#endif
244
245#ifdef ROUTER_REDIRECT
246#include "routers/redirect.h"
247#endif
248
249#ifdef TRANSPORT_APPENDFILE
250#include "transports/appendfile.h"
251#endif
252
253#ifdef TRANSPORT_AUTOREPLY
254#include "transports/autoreply.h"
255#endif
256
257#ifdef TRANSPORT_LMTP
258#include "transports/lmtp.h"
259#endif
260
261#ifdef TRANSPORT_PIPE
262#include "transports/pipe.h"
263#endif
264
3369a853
ACK
265#ifdef EXPERIMENTAL_QUEUEFILE
266#include "transports/queuefile.h"
267#endif
268
059ec3d9
PH
269#ifdef TRANSPORT_SMTP
270#include "transports/smtp.h"
271#endif
272
273
274/* Now set up the structures, terminated by an entry with a null name. */
275
276router_info routers_available[] = {
277#ifdef ROUTER_ACCEPT
278 {
f2ed27cf
JH
279 .driver_name = US"accept",
280 .options = accept_router_options,
281 .options_count = &accept_router_options_count,
282 .options_block = &accept_router_option_defaults,
283 .options_len = sizeof(accept_router_options_block),
284 .init = accept_router_init,
285 .code = accept_router_entry,
286 .tidyup = NULL, /* no tidyup entry */
287 .ri_flags = ri_yestransport
059ec3d9
PH
288 },
289#endif
290#ifdef ROUTER_DNSLOOKUP
291 {
f2ed27cf
JH
292 .driver_name = US"dnslookup",
293 .options = dnslookup_router_options,
294 .options_count = &dnslookup_router_options_count,
295 .options_block = &dnslookup_router_option_defaults,
296 .options_len = sizeof(dnslookup_router_options_block),
297 .init = dnslookup_router_init,
298 .code = dnslookup_router_entry,
299 .tidyup = NULL, /* no tidyup entry */
300 .ri_flags = ri_yestransport
059ec3d9
PH
301 },
302#endif
303#ifdef ROUTER_IPLITERAL
304 {
f2ed27cf
JH
305 .driver_name = US"ipliteral",
306 .options = ipliteral_router_options,
307 .options_count = &ipliteral_router_options_count,
308 .options_block = &ipliteral_router_option_defaults,
309 .options_len = sizeof(ipliteral_router_options_block),
310 .init = ipliteral_router_init,
311 .code = ipliteral_router_entry,
312 .tidyup = NULL, /* no tidyup entry */
313 .ri_flags = ri_yestransport
059ec3d9
PH
314 },
315#endif
316#ifdef ROUTER_IPLOOKUP
317 {
f2ed27cf
JH
318 .driver_name = US"iplookup",
319 .options = iplookup_router_options,
320 .options_count = &iplookup_router_options_count,
321 .options_block = &iplookup_router_option_defaults,
322 .options_len = sizeof(iplookup_router_options_block),
323 .init = iplookup_router_init,
324 .code = iplookup_router_entry,
325 .tidyup = NULL, /* no tidyup entry */
326 .ri_flags = ri_notransport
059ec3d9
PH
327 },
328#endif
329#ifdef ROUTER_MANUALROUTE
330 {
f2ed27cf
JH
331 .driver_name = US"manualroute",
332 .options = manualroute_router_options,
333 .options_count = &manualroute_router_options_count,
334 .options_block = &manualroute_router_option_defaults,
335 .options_len = sizeof(manualroute_router_options_block),
336 .init = manualroute_router_init,
337 .code = manualroute_router_entry,
338 .tidyup = NULL, /* no tidyup entry */
339 .ri_flags = 0
059ec3d9
PH
340 },
341#endif
342#ifdef ROUTER_QUERYPROGRAM
343 {
f2ed27cf
JH
344 .driver_name = US"queryprogram",
345 .options = queryprogram_router_options,
346 .options_count = &queryprogram_router_options_count,
347 .options_block = &queryprogram_router_option_defaults,
348 .options_len = sizeof(queryprogram_router_options_block),
349 .init = queryprogram_router_init,
350 .code = queryprogram_router_entry,
351 .tidyup = NULL, /* no tidyup entry */
352 .ri_flags = 0
059ec3d9
PH
353 },
354#endif
355#ifdef ROUTER_REDIRECT
356 {
f2ed27cf
JH
357 .driver_name = US"redirect",
358 .options = redirect_router_options,
359 .options_count = &redirect_router_options_count,
360 .options_block = &redirect_router_option_defaults,
361 .options_len = sizeof(redirect_router_options_block),
362 .init = redirect_router_init,
363 .code = redirect_router_entry,
364 .tidyup = NULL, /* no tidyup entry */
365 .ri_flags = ri_notransport
059ec3d9
PH
366 },
367#endif
adf73d37 368 { US"" }
059ec3d9
PH
369};
370
371
adf73d37
JH
372void
373route_show_supported(FILE * f)
374{
adf73d37 375fprintf(f, "Routers:");
d7978c0f 376for (router_info * rr = routers_available; rr->driver_name[0]; rr++)
adf73d37
JH
377 fprintf(f, " %s", rr->driver_name);
378fprintf(f, "\n");
379}
380
381
382
059ec3d9
PH
383
384transport_info transports_available[] = {
385#ifdef TRANSPORT_APPENDFILE
386 {
f2ed27cf
JH
387 .driver_name = US"appendfile",
388 .options = appendfile_transport_options,
389 .options_count = &appendfile_transport_options_count,
390 .options_block = &appendfile_transport_option_defaults, /* private options defaults */
391 .options_len = sizeof(appendfile_transport_options_block),
392 .init = appendfile_transport_init,
393 .code = appendfile_transport_entry,
394 .tidyup = NULL,
395 .closedown = NULL,
396 .local = TRUE
059ec3d9
PH
397 },
398#endif
399#ifdef TRANSPORT_AUTOREPLY
400 {
f2ed27cf
JH
401 .driver_name = US"autoreply",
402 .options = autoreply_transport_options,
403 .options_count = &autoreply_transport_options_count,
404 .options_block = &autoreply_transport_option_defaults,
405 .options_len = sizeof(autoreply_transport_options_block),
406 .init = autoreply_transport_init,
407 .code = autoreply_transport_entry,
408 .tidyup = NULL,
409 .closedown = NULL,
410 .local = TRUE
059ec3d9
PH
411 },
412#endif
413#ifdef TRANSPORT_LMTP
414 {
f2ed27cf
JH
415 .driver_name = US"lmtp",
416 .options = lmtp_transport_options,
417 .options_count = &lmtp_transport_options_count,
418 .options_block = &lmtp_transport_option_defaults,
419 .options_len = sizeof(lmtp_transport_options_block),
420 .init = lmtp_transport_init,
421 .code = lmtp_transport_entry,
422 .tidyup = NULL,
423 .closedown = NULL,
424 .local = TRUE
059ec3d9
PH
425 },
426#endif
427#ifdef TRANSPORT_PIPE
428 {
f2ed27cf
JH
429 .driver_name = US"pipe",
430 .options = pipe_transport_options,
431 .options_count = &pipe_transport_options_count,
432 .options_block = &pipe_transport_option_defaults,
433 .options_len = sizeof(pipe_transport_options_block),
434 .init = pipe_transport_init,
435 .code = pipe_transport_entry,
436 .tidyup = NULL,
437 .closedown = NULL,
438 .local = TRUE
059ec3d9
PH
439 },
440#endif
3369a853
ACK
441#ifdef EXPERIMENTAL_QUEUEFILE
442 {
f2ed27cf
JH
443 .driver_name = US"queuefile",
444 .options = queuefile_transport_options,
445 .options_count = &queuefile_transport_options_count,
446 .options_block = &queuefile_transport_option_defaults,
447 .options_len = sizeof(queuefile_transport_options_block),
448 .init = queuefile_transport_init,
449 .code = queuefile_transport_entry,
450 .tidyup = NULL,
451 .closedown = NULL,
452 .local = TRUE
3369a853
ACK
453 },
454#endif
059ec3d9
PH
455#ifdef TRANSPORT_SMTP
456 {
f2ed27cf
JH
457 .driver_name = US"smtp",
458 .options = smtp_transport_options,
459 .options_count = &smtp_transport_options_count,
460 .options_block = &smtp_transport_option_defaults,
461 .options_len = sizeof(smtp_transport_options_block),
462 .init = smtp_transport_init,
463 .code = smtp_transport_entry,
464 .tidyup = NULL,
465 .closedown = smtp_transport_closedown,
466 .local = FALSE
059ec3d9
PH
467 },
468#endif
adf73d37 469 { US"" }
059ec3d9
PH
470};
471
adf73d37
JH
472void
473transport_show_supported(FILE * f)
474{
475fprintf(f, "Transports:");
476#ifdef TRANSPORT_APPENDFILE
477 fprintf(f, " appendfile");
478 #ifdef SUPPORT_MAILDIR
479 fprintf(f, "/maildir"); /* damn these subclasses */
480 #endif
481 #ifdef SUPPORT_MAILSTORE
482 fprintf(f, "/mailstore");
483 #endif
484 #ifdef SUPPORT_MBX
485 fprintf(f, "/mbx");
486 #endif
487#endif
488#ifdef TRANSPORT_AUTOREPLY
489 fprintf(f, " autoreply");
490#endif
491#ifdef TRANSPORT_LMTP
492 fprintf(f, " lmtp");
493#endif
494#ifdef TRANSPORT_PIPE
495 fprintf(f, " pipe");
496#endif
497#ifdef EXPERIMENTAL_QUEUEFILE
498 fprintf(f, " queuefile");
499#endif
500#ifdef TRANSPORT_SMTP
501 fprintf(f, " smtp");
502#endif
503fprintf(f, "\n");
504}
505
d185889f
JH
506
507#ifndef MACRO_PREDEF
508
e6d225ae
DW
509struct lookupmodulestr
510{
511 void *dl;
512 struct lookup_module_info *info;
513 struct lookupmodulestr *next;
514};
515
516static struct lookupmodulestr *lookupmodules = NULL;
517
96f5fe4c
JH
518static void
519addlookupmodule(void *dl, struct lookup_module_info *info)
e6d225ae 520{
f3ebb786 521struct lookupmodulestr *p = store_get(sizeof(struct lookupmodulestr), FALSE);
96f5fe4c
JH
522
523p->dl = dl;
524p->info = info;
525p->next = lookupmodules;
526lookupmodules = p;
527lookup_list_count += info->lookupcount;
e6d225ae
DW
528}
529
530/* only valid after lookup_list and lookup_list_count are assigned */
96f5fe4c
JH
531static void
532add_lookup_to_list(lookup_info *info)
e6d225ae 533{
96f5fe4c
JH
534/* need to add the lookup to lookup_list, sorted */
535int pos = 0;
536
537/* strategy is to go through the list until we find
538either an empty spot or a name that is higher.
539this can't fail because we have enough space. */
540
541while (lookup_list[pos] && (Ustrcmp(lookup_list[pos]->name, info->name) <= 0))
542 pos++;
543
544if (lookup_list[pos])
545 {
546 /* need to insert it, so move all the other items up
547 (last slot is still empty, of course) */
548
549 memmove(&lookup_list[pos+1],
550 &lookup_list[pos],
551 sizeof(lookup_info *) * (lookup_list_count-pos-1));
e6d225ae 552 }
96f5fe4c 553lookup_list[pos] = info;
e6d225ae
DW
554}
555
4d805ee9
PP
556
557/* These need to be at file level for old versions of gcc (2.95.2 reported),
558 * which give parse errors on an extern in function scope. Each entry needs
559 * to also be invoked in init_lookup_list() below */
560
78f72498
JH
561#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
562extern lookup_module_info cdb_lookup_module_info;
4d805ee9 563#endif
78f72498
JH
564#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
565extern lookup_module_info dbmdb_lookup_module_info;
4d805ee9 566#endif
78f72498
JH
567#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
568extern lookup_module_info dnsdb_lookup_module_info;
4d805ee9 569#endif
78f72498
JH
570#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
571extern lookup_module_info dsearch_lookup_module_info;
4d805ee9 572#endif
78f72498
JH
573#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
574extern lookup_module_info ibase_lookup_module_info;
4d805ee9 575#endif
ffc92d69
JH
576#if defined(LOOKUP_JSON)
577extern lookup_module_info json_lookup_module_info;
578#endif
78f72498
JH
579#if defined(LOOKUP_LDAP)
580extern lookup_module_info ldap_lookup_module_info;
de78e2d5 581#endif
78f72498
JH
582#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
583extern lookup_module_info lsearch_lookup_module_info;
4d805ee9 584#endif
78f72498
JH
585#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
586extern lookup_module_info mysql_lookup_module_info;
4d805ee9
PP
587#endif
588#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
589extern lookup_module_info nis_lookup_module_info;
590#endif
78f72498
JH
591#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
592extern lookup_module_info nisplus_lookup_module_info;
4d805ee9 593#endif
78f72498
JH
594#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
595extern lookup_module_info oracle_lookup_module_info;
4d805ee9 596#endif
78f72498
JH
597#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
598extern lookup_module_info passwd_lookup_module_info;
4d805ee9 599#endif
78f72498
JH
600#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
601extern lookup_module_info pgsql_lookup_module_info;
4d805ee9 602#endif
78f72498
JH
603#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
604extern lookup_module_info redis_lookup_module_info;
4d805ee9 605#endif
5bde3efa
ACK
606#if defined(EXPERIMENTAL_LMDB)
607extern lookup_module_info lmdb_lookup_module_info;
608#endif
7952eef9 609#if defined(SUPPORT_SPF)
78f72498 610extern lookup_module_info spf_lookup_module_info;
4d805ee9 611#endif
78f72498
JH
612#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
613extern lookup_module_info sqlite_lookup_module_info;
4d805ee9 614#endif
78f72498
JH
615#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
616extern lookup_module_info testdb_lookup_module_info;
617#endif
618#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
619extern lookup_module_info whoson_lookup_module_info;
4d805ee9
PP
620#endif
621
96f5fe4c
JH
622
623void
624init_lookup_list(void)
e6d225ae 625{
fb2bba55 626#ifdef LOOKUP_MODULE_DIR
e6d225ae
DW
627 DIR *dd;
628 struct dirent *ent;
e6d225ae
DW
629 int countmodules = 0;
630 int moduleerrors = 0;
fb2bba55 631#endif
cab0c277 632 static BOOL lookup_list_init_done = FALSE;
f3ebb786 633 rmark reset_point;
e6d225ae 634
6545de78
PP
635 if (lookup_list_init_done)
636 return;
f3ebb786 637 reset_point = store_mark();
cab0c277 638 lookup_list_init_done = TRUE;
6545de78 639
e6d225ae 640#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
e6d225ae
DW
641 addlookupmodule(NULL, &cdb_lookup_module_info);
642#endif
643
644#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
e6d225ae
DW
645 addlookupmodule(NULL, &dbmdb_lookup_module_info);
646#endif
647
648#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
e6d225ae
DW
649 addlookupmodule(NULL, &dnsdb_lookup_module_info);
650#endif
651
652#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
e6d225ae
DW
653 addlookupmodule(NULL, &dsearch_lookup_module_info);
654#endif
655
656#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
e6d225ae
DW
657 addlookupmodule(NULL, &ibase_lookup_module_info);
658#endif
659
660#ifdef LOOKUP_LDAP
e6d225ae
DW
661 addlookupmodule(NULL, &ldap_lookup_module_info);
662#endif
663
ffc92d69
JH
664#ifdef LOOKUP_JSON
665 addlookupmodule(NULL, &json_lookup_module_info);
666#endif
667
e6d225ae 668#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
e6d225ae
DW
669 addlookupmodule(NULL, &lsearch_lookup_module_info);
670#endif
671
672#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
e6d225ae
DW
673 addlookupmodule(NULL, &mysql_lookup_module_info);
674#endif
675
676#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
e6d225ae
DW
677 addlookupmodule(NULL, &nis_lookup_module_info);
678#endif
679
680#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
e6d225ae
DW
681 addlookupmodule(NULL, &nisplus_lookup_module_info);
682#endif
683
684#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
e6d225ae
DW
685 addlookupmodule(NULL, &oracle_lookup_module_info);
686#endif
687
688#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
e6d225ae
DW
689 addlookupmodule(NULL, &passwd_lookup_module_info);
690#endif
691
692#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
e6d225ae
DW
693 addlookupmodule(NULL, &pgsql_lookup_module_info);
694#endif
695
de78e2d5 696#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
9bdd29ad
TL
697 addlookupmodule(NULL, &redis_lookup_module_info);
698#endif
699
5bde3efa
ACK
700#ifdef EXPERIMENTAL_LMDB
701 addlookupmodule(NULL, &lmdb_lookup_module_info);
702#endif
703
7952eef9 704#ifdef SUPPORT_SPF
e6d225ae
DW
705 addlookupmodule(NULL, &spf_lookup_module_info);
706#endif
707
708#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
e6d225ae
DW
709 addlookupmodule(NULL, &sqlite_lookup_module_info);
710#endif
711
712#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
e6d225ae
DW
713 addlookupmodule(NULL, &testdb_lookup_module_info);
714#endif
715
716#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
e6d225ae
DW
717 addlookupmodule(NULL, &whoson_lookup_module_info);
718#endif
719
720#ifdef LOOKUP_MODULE_DIR
721 dd = opendir(LOOKUP_MODULE_DIR);
722 if (dd == NULL) {
1594a79a 723 DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
e6d225ae
DW
724 log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
725 }
726 else {
f322340b
JH
727 const pcre *regex_islookupmod = regex_must_compile(
728 US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE);
729
1594a79a 730 DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
e6d225ae
DW
731 while ((ent = readdir(dd)) != NULL) {
732 char *name = ent->d_name;
733 int len = (int)strlen(name);
734 if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0) {
735 int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
736 void *dl;
737 struct lookup_module_info *info;
1ba28e2b 738 const char *errormsg;
e6d225ae
DW
739
740 /* SRH: am I being paranoid here or what? */
741 if (pathnamelen > big_buffer_size) {
742 fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
743 log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
744 continue;
745 }
746
747 /* SRH: snprintf here? */
748 sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);
749
750 dl = dlopen(CS big_buffer, RTLD_NOW);// TJ was LAZY
751 if (dl == NULL) {
752 fprintf(stderr, "Error loading %s: %s\n", name, dlerror());
753 moduleerrors++;
754 log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, dlerror());
755 continue;
756 }
757
56e0c4ce
PP
758 /* FreeBSD nsdispatch() can trigger dlerror() errors about
759 * _nss_cache_cycle_prevention_function; we need to clear the dlerror()
760 * state before calling dlsym(), so that any error afterwards only
761 * comes from dlsym().
762 */
763 errormsg = dlerror();
764
e6d225ae
DW
765 info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
766 if ((errormsg = dlerror()) != NULL) {
767 fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
768 dlclose(dl);
769 moduleerrors++;
770 log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
771 continue;
772 }
773 if (info->magic != LOOKUP_MODULE_INFO_MAGIC) {
774 fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
775 dlclose(dl);
776 moduleerrors++;
777 log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
778 continue;
779 }
780
781 addlookupmodule(dl, info);
1594a79a 782 DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
e6d225ae
DW
783 countmodules++;
784 }
785 }
f322340b 786 store_free((void*)regex_islookupmod);
e6d225ae
DW
787 closedir(dd);
788 }
789
1594a79a 790 DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
e6d225ae
DW
791#endif
792
1594a79a 793 DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);
e6d225ae
DW
794
795 lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count);
796 memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count);
797
798 /* now add all lookups to the real list */
f3ebb786 799 for (struct lookupmodulestr * p = lookupmodules; p; p = p->next)
d7978c0f 800 for (int j = 0; j < p->info->lookupcount; j++)
e6d225ae 801 add_lookup_to_list(p->info->lookups[j]);
f3ebb786 802 store_reset(reset_point);
e6d225ae
DW
803 /* just to be sure */
804 lookupmodules = NULL;
805}
806
d185889f 807#endif /*!MACRO_PREDEF*/
059ec3d9 808/* End of drtables.c */