From 51a87a4dd1f2999485da7fe50c313e821dcc8dba Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Fri, 16 Aug 2024 19:33:48 +0100 Subject: [PATCH] authenticator dynamic modules --- doc/doc-docbook/spec.xfpt | 4 +- doc/doc-txt/ChangeLog | 5 + doc/doc-txt/NewStuff | 5 +- src/OS/Makefile-Base | 8 +- src/scripts/Configure-Makefile | 3 +- src/scripts/MakeLinks | 9 +- src/scripts/drivers-Makefile | 22 +- src/src/EDITME | 14 ++ src/src/auths/Makefile | 89 +++++--- src/src/auths/cram_md5.c | 26 ++- src/src/auths/cyrus_sasl.c | 23 ++ src/src/auths/dovecot.c | 40 +++- src/src/auths/external.c | 22 ++ src/src/auths/{gsasl_exim.c => gsasl.c} | 26 ++- src/src/auths/{gsasl_exim.h => gsasl.h} | 0 src/src/auths/heimdal_gssapi.c | 32 ++- src/src/auths/heimdal_gssapi.h | 2 +- src/src/auths/plaintext.c | 23 ++ src/src/auths/spa.c | 22 ++ src/src/auths/tls.c | 22 ++ src/src/drtables.c | 278 ++++++------------------ src/src/exim.c | 3 +- src/src/globals.h | 3 +- src/src/readconf.c | 71 ++++-- src/src/transports/Makefile | 6 +- test/confs/0000 | 1 + test/runtest | 7 +- test/stderr/0402 | 15 ++ test/stderr/0544 | 6 + test/stderr/5410 | 18 ++ 30 files changed, 490 insertions(+), 315 deletions(-) rename src/src/auths/{gsasl_exim.c => gsasl.c} (98%) rename src/src/auths/{gsasl_exim.h => gsasl.h} (100%) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 9fbf7a2db..f73792ac5 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -2073,6 +2073,7 @@ withdrawn. .cindex "lookup modules" .cindex "router modules" .cindex "transport modules" +.cindex "authenticator modules" .cindex "dynamic modules" .cindex ".so building" On some platforms, Exim supports not compiling all lookup types directly into @@ -2084,7 +2085,8 @@ dependencies. Most, but not all, lookup types can be built this way. .new -Similarly, router and transport drivers can be built as external modules. +Similarly, authenticator, router and transport drivers can be built +as external modules. This permits a smaller exim binary, growing only as needed for the runtime cofiguration. .wen diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 3a0e3efc5..adfd5cb8f 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -40,6 +40,11 @@ JH/07 Bug 3106: Fix coding in SPA authenticator. A macro argument was not JH/08 The output of "exim -bV" now includes lookup types built as dynamic-load modules. +JH/09 Not a change, but worthy of note: There is no test coverage of the + heimdall-gssapi authenticator driver. It does build, though with (on at + least one platform) library version conflicts with the gsasl auth + driver). Confidence in its operation is lacking. + Exim version 4.98 ----------------- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index be0f0c679..1910ad002 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -14,8 +14,9 @@ Version 4.98 3. Events smtp:fail:protocol and smtp:fail:syntax - 4. JSON lookup support, all the router drivers except manualroute, and all the transport - drivers except smtp can now be built as lodable modules + 4. JSON lookup support, all the router drivers except manualroute, all the + transport drivers except smtp, and all the authenticator drivers except + plaintext, gsasl and spa can now be built as loadable modules Version 4.98 ------------ diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base index d45524561..3f2d4d883 100644 --- a/src/OS/Makefile-Base +++ b/src/OS/Makefile-Base @@ -119,7 +119,7 @@ OBJ_MACRO = macro_predef.o \ macro-appendfile.o macro-autoreply.o macro-lmtp.o macro-pipe.o macro-queuefile.o \ macro-smtp.o macro-accept.o macro-dnslookup.o macro-ipliteral.o macro-iplookup.o \ macro-manualroute.o macro-queryprogram.o macro-redirect.o \ - macro-auth-spa.o macro-cram_md5.o macro-cyrus_sasl.o macro-dovecot.o macro-gsasl_exim.o \ + macro-auth-spa.o macro-cram_md5.o macro-cyrus_sasl.o macro-dovecot.o macro-gsasl.o \ macro-heimdal_gssapi.o macro-plaintext.o macro-spa.o macro-authtls.o macro-external.o \ macro-dkim.o macro-malware.o macro-signing.o @@ -206,9 +206,9 @@ macro-dovecot.o: auths/dovecot.c macro-external.o: auths/external.c @echo "$(CC) -DMACRO_PREDEF auths/external.c" $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ auths/external.c -macro-gsasl_exim.o : auths/gsasl_exim.c - @echo "$(CC) -DMACRO_PREDEF auths/gsasl_exim.c" - $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ auths/gsasl_exim.c +macro-gsasl.o : auths/gsasl.c + @echo "$(CC) -DMACRO_PREDEF auths/gsasl.c" + $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ auths/gsasl.c macro-heimdal_gssapi.o: auths/heimdal_gssapi.c @echo "$(CC) -DMACRO_PREDEF auths/heimdal_gssapi.c" $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ auths/heimdal_gssapi.c diff --git a/src/scripts/Configure-Makefile b/src/scripts/Configure-Makefile index 79ab19dcc..9179392f3 100755 --- a/src/scripts/Configure-Makefile +++ b/src/scripts/Configure-Makefile @@ -298,8 +298,9 @@ do mv $class/Makefile.postdynamic $class/Makefile rm $class/Makefile.predynamic done <<-END - routers ROUTER ACCEPT DNSLOOKUP IPLITERAL IPLOOKUP MANUALROUTE QUERYPROGRAM REDIRECT + routers ROUTER ACCEPT DNSLOOKUP IPLITERAL IPLOOKUP MANUALROUTE QUERYPROGRAM REDIRECT transports TRANSPORT APPENDFILE AUTOREPLY LMTP PIPE QUEUEFILE SMTP + auths AUTH CRAM_MD5 CYRUS_SASL DOVECOT EXTERNAL GSASL HEIMDAL_GSSAPI PLAINTEXT SPA TLS END # See if there is a definition of EXIM_PERL in what we have built so far. diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks index 998b73bf9..76859ce9a 100755 --- a/src/scripts/MakeLinks +++ b/src/scripts/MakeLinks @@ -77,11 +77,12 @@ cd .. d="auths" mkdir $d cd $d -for f in README Makefile call_pam.c call_pwcheck.c \ - call_radius.c check_serv_cond.c cyrus_sasl.c cyrus_sasl.h gsasl_exim.c \ - gsasl_exim.h get_data.c get_no64_data.c heimdal_gssapi.c heimdal_gssapi.h \ +# Makefile is generated +for f in README call_pam.c call_pwcheck.c \ + call_radius.c check_serv_cond.c cyrus_sasl.c cyrus_sasl.h gsasl.c \ + gsasl.h get_data.c get_no64_data.c heimdal_gssapi.c heimdal_gssapi.h \ cram_md5.c cram_md5.h plaintext.c plaintext.h \ - pwcheck.c pwcheck.h auth-spa.c auth-spa.h dovecot.c dovecot.h sha1.c spa.c \ + pwcheck.c pwcheck.h auth-spa.c auth-spa.h dovecot.c dovecot.h spa.c \ spa.h tls.c tls.h external.c external.h do ln -s ../../src/$d/$f $f diff --git a/src/scripts/drivers-Makefile b/src/scripts/drivers-Makefile index 0c3da19cb..2dd958043 100755 --- a/src/scripts/drivers-Makefile +++ b/src/scripts/drivers-Makefile @@ -3,7 +3,6 @@ # Copyright (c) The Exim Maintainers 1995 - 2024 # SPDX-License-Identifier: GPL-2.0-or-later -set -e class=${CLASS:?} classdef=${CLASSDEF:?} drnames="${DRNAMES:?}" @@ -137,16 +136,17 @@ emit_module_rule() { exit 1 fi MODS="${MODS} ${mod_name}.so" -# pkgconf=$(grep "^${classdef}_${name}_PC" "$defs_source") -# if [ $? -eq 0 ]; then -# pkgconf=$(echo $pkgconf | sed 's/^.*= *//') -# echo "${classdef}_${mod_name}_INCLUDE = $(pkg-config --cflags $pkgconf)" -# echo "${classdef}_${mod_name}_LIBS = $(pkg-config --libs $pkgconf)" -# else -# grep "^${classdef}_${name}_" "$defs_source" -# echo "${classdef}_${mod_name}_INCLUDE = \$(${classdef}_${name}_INCLUDE)" -# echo "${classdef}_${mod_name}_LIBS = \$(${classdef}_${name}_LIBS)" -# fi + grep "^${classdef}_${name}_PC" "$defs_source" 1>&2 + pkgconf=$(grep "^${classdef}_${name}_PC" "$defs_source") + if [ $? -eq 0 ]; then + pkgconf=$(echo $pkgconf | sed 's/^.*= *//') + echo "${classdef}_${mod_name}_INCLUDE = $(pkg-config --cflags $pkgconf)" + echo "${classdef}_${mod_name}_LIBS = $(pkg-config --libs $pkgconf)" + else + grep "^${classdef}_${name}_" "$defs_source" + echo "${classdef}_${mod_name}_INCLUDE = \$(${classdef}_${name}_INCLUDE)" + echo "${classdef}_${mod_name}_LIBS = \$(${classdef}_${name}_LIBS)" + fi elif want_at_all "$name" then OBJ="${OBJ} ${mod_name}.o" diff --git a/src/src/EDITME b/src/src/EDITME index 820793032..b930f00a7 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -827,6 +827,20 @@ FIXED_NEVER_USERS=root # you must uncomment at least one of the following, so that appropriate code is # included in the Exim binary. You will then need to set up the run time # configuration to make use of the mechanism(s) selected. +# +# If set to "2" instead of "yes" then the corresponding driver will be +# built as a module and must be installed into LOOKUP_MODULE_DIR (the name +# is historic). +# You need to add -export-dynamic -rdynamic to EXTRALIBS. You may also need to +# add -ldl to EXTRALIBS so that dlopen() is available to Exim. You need to +# define CFLAGS_DYNAIC and LOOKUP_MODULE_DIR below so the builds are done right, +# and so the exim binary actually loads dynamic lookup modules. +# +# Libraries being built as modules should be added to respective +# LOOKUP_*_INCLUDE and LOOKUP_*_LIBS rather than the the ones for the +# core exim build. This gets them linked with the module instead +# Only the cram_md5, cyrus_sasl, dovecot, external and tls builds for modules +# are known to work. The heimdal does build, but we have no test coverage. # AUTH_CRAM_MD5=yes # AUTH_CYRUS_SASL=yes diff --git a/src/src/auths/Makefile b/src/src/auths/Makefile index ac5cf865b..fa60acba9 100644 --- a/src/src/auths/Makefile +++ b/src/src/auths/Makefile @@ -4,40 +4,61 @@ # linked in only when needed. This Makefile is called from the main make file, # after cd'ing to the auths subdirectory. When the relevant AUTH_ macros are # defined, the equivalent modules herein is not included in the final binary. +# +# Copyright (c) The Exim Maintainers 2024 -OBJ = auth-spa.o call_pam.o call_pwcheck.o \ - call_radius.o check_serv_cond.o cram_md5.o cyrus_sasl.o dovecot.o \ - external.o get_data.o get_no64_data.o gsasl_exim.o heimdal_gssapi.o \ - plaintext.o pwcheck.o \ - spa.o tls.o - -auths.a: $(OBJ) - @$(RM_COMMAND) -f auths.a - @echo "$(AR) auths.a" - $(FE)$(AR) auths.a $(OBJ) - $(RANLIB) $@ - -.SUFFIXES: .o .c -.c.o:; @echo "$(CC) $*.c" - $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) $*.c - -auth-spa.o: $(HDRS) auth-spa.c -call_pam.o: $(HDRS) call_pam.c -call_pwcheck.o: $(HDRS) call_pwcheck.c pwcheck.h -call_radius.o: $(HDRS) call_radius.c -check_serv_cond.o: $(HDRS) check_serv_cond.c -get_data.o: $(HDRS) get_data.c -get_no64_data.o: $(HDRS) get_no64_data.c -pwcheck.o: $(HDRS) pwcheck.c pwcheck.h - -cram_md5.o: $(HDRS) cram_md5.c cram_md5.h -cyrus_sasl.o: $(HDRS) cyrus_sasl.c cyrus_sasl.h -dovecot.o: $(HDRS) dovecot.c dovecot.h -external.o: $(HDRS) external.c external.h -gsasl_exim.o: $(HDRS) gsasl_exim.c gsasl_exim.h -heimdal_gssapi.o: $(HDRS) heimdal_gssapi.c heimdal_gssapi.h -plaintext.o: $(HDRS) plaintext.c plaintext.h -spa.o: $(HDRS) spa.c spa.h -tls.o: $(HDRS) tls.c tls.h +# nb: at build time, the version of this file used will have had some +# extra variable definitions and prepended to it and module build rules +# interpolated below. This is done by scripts/drivers-Makefile with +# definitions from scripts/Configure-Makefile + +# MAGIC-TAG-MODS-OBJ-RULES-GO-HERE + +OBJ += auth-spa.o call_pam.o call_pwcheck.o call_radius.o check_serv_cond.o \ + get_data.o get_no64_data.o pwcheck.o + +all: auths.a $(MODS) + +auths.a: $(OBJ) + @$(RM_COMMAND) -f auths.a + @echo "$(AR) auths.a" + $(FE)$(AR) auths.a $(OBJ) + $(RANLIB) $@ + +.SUFFIXES: .o .c .so +.c.o:; @echo "$(CC) $*.c" + $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) $*.c + +SO_FLAGS = -DDYNLOOKUP $(CFLAGS_DYNAMIC) $(CFLAGS) $(INCLUDE) $(DLFLAGS) +.c.so:; @echo "$(CC) -shared $*.c" + $(FE)$(CC) $(SO_FLAGS) $(AUTH_$*_INCLUDE) $(AUTH_$*_LIBS) \ + $*.c -o $@ + + +$(OBJ) $(MOD): $(HDRS) + +auth-spa.o: auth-spa.c +call_pam.o: call_pam.c +call_pwcheck.o: call_pwcheck.c pwcheck.h +call_radius.o: call_radius.c +check_serv_cond.o: check_serv_cond.c +get_data.o: get_data.c +get_no64_data.o: get_no64_data.c +pwcheck.o: pwcheck.c pwcheck.h + +cram_md5.o: cram_md5.c cram_md5.h +cyrus_sasl.o: cyrus_sasl.c cyrus_sasl.h +dovecot.o: dovecot.c dovecot.h +external.o: external.c external.h +gsasl.o: gsasl.c gsasl.h +heimdal_gssapi.o: heimdal_gssapi.c heimdal_gssapi.h +plaintext.o: plaintext.c plaintext.h +spa.o: spa.c spa.h +tls.o: tls.c tls.h + +# These depend on more than one .c source + +spa.so: spa.c auth-spa.c spa.h + $(FE)$(CC) $(SO_FLAGS) spa.c auth-spa.c -o $@ # End diff --git a/src/src/auths/cram_md5.c b/src/src/auths/cram_md5.c index a64177f2a..7b41ee065 100644 --- a/src/src/auths/cram_md5.c +++ b/src/src/auths/cram_md5.c @@ -334,10 +334,34 @@ if (smtp_write_command(sx, SCMD_FLUSH, "%s\r\n", b64encode(CUS big_buffer, return smtp_read_response(sx, US buffer, buffsize, '2', timeout) ? OK : FAIL; } + + +# ifdef DYNLOOKUP +# define cram_md5_auth_info _auth_info +# endif + +auth_info cram_md5_auth_info = { +.drinfo = { + .driver_name = US"cram_md5", /* lookup name */ + .options = auth_cram_md5_options, + .options_count = &auth_cram_md5_options_count, + .options_block = &auth_cram_md5_option_defaults, + .options_len = sizeof(auth_cram_md5_options_block), + .init = auth_cram_md5_init, +# ifdef DYNLOOKUP + .dyn_magic = AUTH_MAGIC, +# endif + }, +.servercode = auth_cram_md5_server, +.clientcode = auth_cram_md5_client, +.version_report = NULL, +.macros_create = NULL, +}; + + # endif /*AUTH_CRAM_MD5*/ # endif /*!STAND_ALONE*/ - /************************************************* ************************************************** * Stand-alone test program * diff --git a/src/src/auths/cyrus_sasl.c b/src/src/auths/cyrus_sasl.c index 8266e2319..ed0995637 100644 --- a/src/src/auths/cyrus_sasl.c +++ b/src/src/auths/cyrus_sasl.c @@ -508,6 +508,29 @@ auth_cyrus_sasl_client( return FAIL; } + +# ifdef DYNLOOKUP +# define cyrus_sasl_auth_info _auth_info +# endif + +auth_info cyrus_sasl_auth_info = { +.drinfo = { + .driver_name = US"cyrus_sasl", /* lookup name */ + .options = auth_cyrus_sasl_options, + .options_count = &auth_cyrus_sasl_options_count, + .options_block = &auth_cyrus_sasl_option_defaults, + .options_len = sizeof(auth_cyrus_sasl_options_block), + .init = auth_cyrus_sasl_init, +# ifdef DYNLOOKUP + .dyn_magic = AUTH_MAGIC, +# endif + }, +.servercode = auth_cyrus_sasl_server, +.clientcode = NULL, +.version_report = auth_cyrus_sasl_version_report, +.macros_create = NULL, +}; + #endif /*!MACRO_PREDEF*/ #endif /* AUTH_CYRUS_SASL */ diff --git a/src/src/auths/dovecot.c b/src/src/auths/dovecot.c index fdfdbc749..ee69436be 100644 --- a/src/src/auths/dovecot.c +++ b/src/src/auths/dovecot.c @@ -1,13 +1,13 @@ /* - * Copyright (c) The Exim Maintainers 2006 - 2024 - * Copyright (c) 2004 Andrey Panin - * SPDX-License-Identifier: GPL-2.0-or-later - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ +Copyright (c) The Exim Maintainers 2006 - 2024 +Copyright (c) 2004 Andrey Panin +SPDX-License-Identifier: GPL-2.0-or-later + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published +by the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. +*/ /* A number of modifications have been made to the original code. Originally I commented them specially, but now they are getting quite extensive, so I have @@ -541,6 +541,28 @@ return ret; } +# ifdef DYNLOOKUP +# define dovecot_auth_info _auth_info +# endif + +auth_info dovecot_auth_info = { +.drinfo = { + .driver_name = US"dovecot", /* lookup name */ + .options = auth_dovecot_options, + .options_count = &auth_dovecot_options_count, + .options_block = &auth_dovecot_option_defaults, + .options_len = sizeof(auth_dovecot_options_block), + .init = auth_dovecot_init, +# ifdef DYNLOOKUP + .dyn_magic = AUTH_MAGIC, +# endif + }, +.servercode = auth_dovecot_server, +.clientcode = NULL, +.version_report = NULL, +.macros_create = NULL, +}; + #endif /*!MACRO_PREDEF*/ #endif /*AUTH_DOVECOT*/ /* end of auths/dovecot.c */ diff --git a/src/src/auths/external.c b/src/src/auths/external.c index 137d1e043..de0d07f86 100644 --- a/src/src/auths/external.c +++ b/src/src/auths/external.c @@ -159,6 +159,28 @@ return OK; +# ifdef DYNLOOKUP +# define external_auth_info _auth_info +# endif + +auth_info external_auth_info = { +.drinfo = { + .driver_name = US"external", /* lookup name */ + .options = auth_external_options, + .options_count = &auth_external_options_count, + .options_block = &auth_external_option_defaults, + .options_len = sizeof(auth_external_options_block), + .init = auth_external_init, +# ifdef DYNLOOKUP + .dyn_magic = AUTH_MAGIC, +# endif + }, +.servercode = auth_external_server, +.clientcode = auth_external_client, +.version_report = NULL, +.macros_create = NULL, +}; + #endif /*!MACRO_PREDEF*/ #endif /*AUTH_EXTERNAL*/ /* End of external.c */ diff --git a/src/src/auths/gsasl_exim.c b/src/src/auths/gsasl.c similarity index 98% rename from src/src/auths/gsasl_exim.c rename to src/src/auths/gsasl.c index 55ac15b4b..e128dac69 100644 --- a/src/src/auths/gsasl_exim.c +++ b/src/src/auths/gsasl.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) The Exim Maintainers 2019 - 2023 */ +/* Copyright (c) The Exim Maintainers 2019 - 2024 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ /* SPDX-License-Identifier: GPL-2.0-or-later */ @@ -37,7 +37,7 @@ static void dummy(int x) { dummy2(x-1); } #else #include -#include "gsasl_exim.h" +#include "gsasl.h" #if GSASL_VERSION_MAJOR == 2 @@ -1060,6 +1060,28 @@ return string_fmt_append(g, "Library version: GNU SASL: Compile: %s\n" /* Dummy */ void auth_gsasl_macros(void) {} +# ifdef DYNLOOKUP +# define gsasl_auth_info _auth_info +# endif + +auth_info gsasl_auth_info = { +.drinfo = { + .driver_name = US"gsasl", /* lookup name */ + .options = auth_gsasl_options, + .options_count = &auth_gsasl_options_count, + .options_block = &auth_gsasl_option_defaults, + .options_len = sizeof(auth_gsasl_options_block), + .init = auth_gsasl_init, +# ifdef DYNLOOKUP + .dyn_magic = AUTH_MAGIC, +# endif + }, +.servercode = auth_gsasl_server, +.clientcode = auth_gsasl_client, +.version_report = auth_gsasl_version_report, +.macros_create = auth_gsasl_macros, +}; + #endif /*!MACRO_PREDEF*/ #endif /* AUTH_GSASL */ diff --git a/src/src/auths/gsasl_exim.h b/src/src/auths/gsasl.h similarity index 100% rename from src/src/auths/gsasl_exim.h rename to src/src/auths/gsasl.h diff --git a/src/src/auths/heimdal_gssapi.c b/src/src/auths/heimdal_gssapi.c index a5eef8d95..8e9e38660 100644 --- a/src/src/auths/heimdal_gssapi.c +++ b/src/src/auths/heimdal_gssapi.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) The Exim Maintainers 2020 - 2023 */ +/* Copyright (c) The Exim Maintainers 2020 - 2024 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ /* SPDX-License-Identifier: GPL-2.0-or-later */ @@ -228,7 +228,7 @@ int auth_heimdal_gssapi_server(auth_instance *ablock, uschar *initial_data) { auth_heimdal_gssapi_options_block * ob = - (auth_heimdal_gssapi_options_block *)(ablock->drinfo.options_block); + (auth_heimdal_gssapi_options_block *)(ablock->drinst.options_block); gss_name_t gclient = GSS_C_NO_NAME; gss_name_t gserver = GSS_C_NO_NAME; gss_cred_id_t gcred = GSS_C_NO_CREDENTIAL; @@ -250,7 +250,7 @@ uschar requested_qop; store_reset_point = store_mark(); HDEBUG(D_auth) - debug_printf("heimdal: initialising auth context for %s\n", ablock->name); + debug_printf("heimdal: initialising auth context for %s\n", ablock->drinst.name); /* Construct our gss_name_t gserver describing ourselves */ tmp1 = expand_string(ob->server_service); @@ -548,7 +548,7 @@ va_list ap; OM_uint32 maj_stat, min_stat; OM_uint32 msgcontext = 0; gss_buffer_desc status_string; -gstring * g; +gstring * g = NULL; HDEBUG(D_auth) { @@ -610,9 +610,31 @@ build-time and export the result as a string into a header ourselves. */ return string_fmt_append(g, "Library version: Heimdal: Runtime: %s\n" " Build Info: %s\n", - heimdal_version, heimdal_long_version)); + heimdal_version, heimdal_long_version); } +# ifdef DYNLOOKUP +# define heimdal_gssapi_auth_info _auth_info +# endif + +auth_info heimdal_gssapi_auth_info = { +.drinfo = { + .driver_name = US"heimdal_gssapi", /* lookup name */ + .options = auth_heimdal_gssapi_options, + .options_count = &auth_heimdal_gssapi_options_count, + .options_block = &auth_heimdal_gssapi_option_defaults, + .options_len = sizeof(auth_heimdal_gssapi_options_block), + .init = auth_heimdal_gssapi_init, +# ifdef DYNLOOKUP + .dyn_magic = AUTH_MAGIC, +# endif + }, +.servercode = auth_heimdal_gssapi_server, +.clientcode = NULL, +.version_report = auth_heimdal_gssapi_version_report, +.macros_create = NULL, +}; + #endif /*!MACRO_PREDEF*/ #endif /* AUTH_HEIMDAL_GSSAPI */ diff --git a/src/src/auths/heimdal_gssapi.h b/src/src/auths/heimdal_gssapi.h index c438aae91..e1d308ac9 100644 --- a/src/src/auths/heimdal_gssapi.h +++ b/src/src/auths/heimdal_gssapi.h @@ -35,6 +35,6 @@ extern auth_heimdal_gssapi_options_block auth_heimdal_gssapi_option_defaults; extern void auth_heimdal_gssapi_init(driver_instance *); extern int auth_heimdal_gssapi_server(auth_instance *, uschar *); extern int auth_heimdal_gssapi_client(auth_instance *, void *, int, uschar *, int); -extern void auth_heimdal_gssapi_version_report(BOOL); +extern gstring * auth_heimdal_gssapi_version_report(gstring *); /* End of heimdal_gssapi.h */ diff --git a/src/src/auths/plaintext.c b/src/src/auths/plaintext.c index 26ac4aeff..13d05d1e5 100644 --- a/src/src/auths/plaintext.c +++ b/src/src/auths/plaintext.c @@ -180,6 +180,29 @@ while ((s = string_nextinlist(&text, &sep, NULL, 0))) return FAIL; } + +# ifdef DYNLOOKUP +# define plaintext_auth_info _auth_info +# endif + +auth_info plaintext_auth_info = { +.drinfo = { + .driver_name = US"plaintext", /* lookup name */ + .options = auth_plaintext_options, + .options_count = &auth_plaintext_options_count, + .options_block = &auth_plaintext_option_defaults, + .options_len = sizeof(auth_plaintext_options_block), + .init = auth_plaintext_init, +# ifdef DYNLOOKUP + .dyn_magic = AUTH_MAGIC, +# endif + }, +.servercode = auth_plaintext_server, +.clientcode = auth_plaintext_client, +.version_report = NULL, +.macros_create = NULL, +}; + #endif /*!MACRO_PREDEF*/ #endif /*AUTH_PLAINTEST*/ /* End of plaintext.c */ diff --git a/src/src/auths/spa.c b/src/src/auths/spa.c index 09d4e43a6..e76e0fc16 100644 --- a/src/src/auths/spa.c +++ b/src/src/auths/spa.c @@ -375,6 +375,28 @@ if (errno != 0 || buffer[0] != '3') return FAIL; } +# ifdef DYNLOOKUP +# define spa_auth_info _auth_info +# endif + +auth_info spa_auth_info = { +.drinfo = { + .driver_name = US"spa", /* lookup name */ + .options = auth_spa_options, + .options_count = &auth_spa_options_count, + .options_block = &auth_spa_option_defaults, + .options_len = sizeof(auth_spa_options_block), + .init = auth_spa_init, +# ifdef DYNLOOKUP + .dyn_magic = AUTH_MAGIC, +# endif + }, +.servercode = auth_spa_server, +.clientcode = auth_spa_client, +.version_report = NULL, +.macros_create = NULL, +}; + #endif /*!MACRO_PREDEF*/ #endif /*AUTH_SPA*/ /* End of spa.c */ diff --git a/src/src/auths/tls.c b/src/src/auths/tls.c index 0bcb675f7..534b53639 100644 --- a/src/src/auths/tls.c +++ b/src/src/auths/tls.c @@ -95,6 +95,28 @@ return auth_check_serv_cond(ablock); } +# ifdef DYNLOOKUP +# define tls_auth_info _auth_info +# endif + +auth_info tls_auth_info = { +.drinfo = { + .driver_name = US"tls", /* lookup name */ + .options = auth_tls_options, + .options_count = &auth_tls_options_count, + .options_block = &auth_tls_option_defaults, + .options_len = sizeof(auth_tls_options_block), + .init = auth_tls_init, +# ifdef DYNLOOKUP + .dyn_magic = AUTH_MAGIC, +# endif + }, +.servercode = auth_tls_server, +.clientcode = NULL, +.version_report = NULL, +.macros_create = NULL, +}; + #endif /*!MACRO_PREDEF*/ #endif /*AUTH_TLS*/ /* End of tls.c */ diff --git a/src/src/drtables.c b/src/src/drtables.c index 026f2ff97..c490e7f86 100644 --- a/src/src/drtables.c +++ b/src/src/drtables.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) The Exim Maintainers 2020 - 2023 */ +/* Copyright (c) The Exim Maintainers 2020 - 2024 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ /* SPDX-License-Identifier: GPL-2.0-or-later */ @@ -21,230 +21,82 @@ all described in src/EDITME. */ lookup_info **lookup_list; int lookup_list_count = 0; -/* Table of information about all possible authentication mechanisms. All -entries are always present if any mechanism is declared, but the functions are -set to NULL for those that are not compiled into the binary. */ +/* Lists of information about which drivers are included in the exim binary. */ -#ifdef AUTH_CRAM_MD5 -#include "auths/cram_md5.h" -#endif +auth_info * auths_available= NULL; +router_info * routers_available = NULL; +transport_info * transports_available = NULL; -#ifdef AUTH_CYRUS_SASL -#include "auths/cyrus_sasl.h" -#endif -#ifdef AUTH_DOVECOT -#include "auths/dovecot.h" -#endif -#ifdef AUTH_EXTERNAL -#include "auths/external.h" -#endif +#ifndef MACRO_PREDEF -#ifdef AUTH_GSASL -#include "auths/gsasl_exim.h" +gstring * +auth_show_supported(gstring * g) +{ +uschar * b = US"" /* static-build authenticatornames */ +#if defined(AUTH_CRAM_MD5) && AUTH_CRAM_MD5!=2 + " cram_md5" #endif - -#ifdef AUTH_HEIMDAL_GSSAPI -#include "auths/heimdal_gssapi.h" +#if defined(AUTH_CYRUS_SASL) && AUTH_CYRUS_SASL!=2 + " cyrus_sasl" #endif - -#ifdef AUTH_PLAINTEXT -#include "auths/plaintext.h" +#if defined(AUTH_DOVECOT) && AUTH_DOVECOT!=2 + " dovecot" #endif - -#ifdef AUTH_SPA -#include "auths/spa.h" +#if defined(AUTH_EXTERNAL) && AUTH_EXTERNAL!=2 + " external" #endif - -#ifdef AUTH_TLS -#include "auths/tls.h" +#if defined(AUTH_GSASL) && AUTH_GSASL!=2 + " gsasl" #endif +#if defined(AUTH_HEIMDAL_GSSAPI) && AUTH_HEIMDAL_GSSAPI!=2 + " heimdal_gssapi" +#endif +#if defined(AUTH_PLAINTEXT) && AUTH_PLAINTEXT!=2 + " plaintext" +#endif +#if defined(AUTH_SPA) && AUTH_SPA!=2 + " spa" +#endif +#if defined(AUTH_TLS) && AUTH_TLS!=2 + " tls" +#endif + ; -auth_info * auths_available_newlist = NULL; -auth_info auths_available_oldarray[] = { - -/* Checking by an expansion condition on plain text */ - -#ifdef AUTH_CRAM_MD5 - { - .drinfo = { - .driver_name = US"cram_md5", /* lookup name */ - .options = auth_cram_md5_options, - .options_count = &auth_cram_md5_options_count, - .options_block = &auth_cram_md5_option_defaults, - .options_len = sizeof(auth_cram_md5_options_block), - .init = auth_cram_md5_init, - }, - .servercode = auth_cram_md5_server, - .clientcode = auth_cram_md5_client, - .version_report = NULL, - .macros_create = NULL, - }, -#endif - -#ifdef AUTH_CYRUS_SASL - { - .drinfo = { - .driver_name = US"cyrus_sasl", - .options = auth_cyrus_sasl_options, - .options_count = &auth_cyrus_sasl_options_count, - .options_block = &auth_cyrus_sasl_option_defaults, - .options_len = sizeof(auth_cyrus_sasl_options_block), - .init = auth_cyrus_sasl_init, - }, - .servercode = auth_cyrus_sasl_server, - .clientcode = NULL, - .version_report = auth_cyrus_sasl_version_report, - .macros_create = NULL, - }, -#endif - -#ifdef AUTH_DOVECOT - { - .drinfo = { - .driver_name = US"dovecot", - .options = auth_dovecot_options, - .options_count = &auth_dovecot_options_count, - .options_block = &auth_dovecot_option_defaults, - .options_len = sizeof(auth_dovecot_options_block), - .init = auth_dovecot_init, - }, - .servercode = auth_dovecot_server, - .clientcode = NULL, - .version_report = NULL, - .macros_create = NULL, - }, -#endif - -#ifdef AUTH_EXTERNAL - { - .drinfo = { - .driver_name = US"external", - .options = auth_external_options, - .options_count = &auth_external_options_count, - .options_block = &auth_external_option_defaults, - .options_len = sizeof(auth_external_options_block), - .init = auth_external_init, - }, - .servercode = auth_external_server, - .clientcode = auth_external_client, - .version_report = NULL, - .macros_create = NULL, - }, -#endif - -#ifdef AUTH_GSASL - { - .drinfo = { - .driver_name = US"gsasl", - .options = auth_gsasl_options, - .options_count = &auth_gsasl_options_count, - .options_block = &auth_gsasl_option_defaults, - .options_len = sizeof(auth_gsasl_options_block), - .init = auth_gsasl_init, - }, - .servercode = auth_gsasl_server, - .clientcode = auth_gsasl_client, - .version_report = auth_gsasl_version_report, - .macros_create = auth_gsasl_macros, - }, -#endif - -#ifdef AUTH_HEIMDAL_GSSAPI - { - .drinfo = { - .driver_name = US"heimdal_gssapi", - .options = auth_heimdal_gssapi_options, - .options_count = &auth_heimdal_gssapi_options_count, - .options_block = &auth_heimdal_gssapi_option_defaults, - .options_len = sizeof(auth_heimdal_gssapi_options_block), - .init = auth_heimdal_gssapi_init, - }, - .servercode = auth_heimdal_gssapi_server, - .clientcode = NULL, - .version_report = auth_heimdal_gssapi_version_report, - .macros_create = NULL, - }, -#endif - -#ifdef AUTH_PLAINTEXT - { - .drinfo = { - .driver_name = US"plaintext", - .options = auth_plaintext_options, - .options_count = &auth_plaintext_options_count, - .options_block = &auth_plaintext_option_defaults, - .options_len = sizeof(auth_plaintext_options_block), - .init = auth_plaintext_init, - }, - .servercode = auth_plaintext_server, - .clientcode = auth_plaintext_client, - .version_report = NULL, - .macros_create = NULL, - }, -#endif - -#ifdef AUTH_SPA - { - .drinfo = { - .driver_name = US"spa", - .options = auth_spa_options, - .options_count = &auth_spa_options_count, - .options_block = &auth_spa_option_defaults, - .options_len = sizeof(auth_spa_options_block), - .init = auth_spa_init, - }, - .servercode = auth_spa_server, - .clientcode = auth_spa_client, - .version_report = NULL, - .macros_create = NULL, - }, -#endif - -#ifdef AUTH_TLS - { - .drinfo = { - .driver_name = US"tls", - .options = auth_tls_options, - .options_count = &auth_tls_options_count, - .options_block = &auth_tls_option_defaults, - .options_len = sizeof(auth_tls_options_block), - .init = auth_tls_init, - }, - .servercode = auth_tls_server, - .clientcode = NULL, - .version_report = NULL, - .macros_create = NULL, - }, -#endif - - { .drinfo = { .driver_name = US"" }} /* end marker */ -}; - - -/* Tables of information about which routers and transports are included in the -exim binary. */ - -/* Pull in the necessary header files */ - -#include "routers/rf_functions.h" - - -router_info * routers_available = NULL; -transport_info * transports_available = NULL; - - - -#ifndef MACRO_PREDEF +uschar * d = US"" /* dynamic-module authenticator names */ +#if defined(AUTH_CRAM_MD5) && AUTH_CRAM_MD5==2 + " cram_md5" +#endif +#if defined(AUTH_CYRUS_SASL) && AUTH_CYRUS_SASL==2 + " cyrus_sasl" +#endif +#if defined(AUTH_DOVECOT) && AUTH_DOVECOT==2 + " dovecot" +#endif +#if defined(AUTH_EXTERNAL) && AUTH_EXTERNAL==2 + " external" +#endif +#if defined(AUTH_GSASL) && AUTH_GSASL==2 + " gsasl" +#endif +#if defined(AUTH_HEIMDAL_GSSAPI) && AUTH_HEIMDAL_GSSAPI==2 + " heimdal_gssapi" +#endif +#if defined(AUTH_PLAINTEXT) && AUTH_PLAINTEXT==2 + " plaintext" +#endif +#if defined(AUTH_SPA) && AUTH_SPA==2 + " spa" +#endif +#if defined(AUTH_TLS) && AUTH_TLS==2 + " tls" +#endif + ; -gstring * -auth_show_supported(gstring * g) -{ -g = string_cat(g, US"Authenticators:"); -for (auth_info * ai = auths_available_oldarray; ai->drinfo.driver_name[0]; ai++) - g = string_fmt_append(g, " %s", ai->drinfo.driver_name); -return string_cat(g, US"\n"); +if (*b) g = string_fmt_append(g, "Authenticators (built-in):%s\n", b); +if (*d) g = string_fmt_append(g, "Authenticators (dynamic): %s\n", d); +return g; } gstring * diff --git a/src/src/exim.c b/src/src/exim.c index 8eb602a17..66746e6bb 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1382,8 +1382,7 @@ g = show_db_version(g); show_string(is_stdout, g); g = NULL; -//for (auth_info * ai= auths_available; *ai->drinfo.driver_name != '\0'; ai++) -for (auth_info * ai = auths_available_newlist; ai; ai = (auth_info *)ai->drinfo.next) +for (auth_info * ai = auths_available; ai; ai = (auth_info *)ai->drinfo.next) if (ai->version_report) g = (*ai->version_report)(g); diff --git a/src/src/globals.h b/src/src/globals.h index 7fc888f5b..9731b7b58 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -374,8 +374,7 @@ extern uschar *authenticated_sender; /* From AUTH on MAIL */ extern BOOL authentication_failed; /* TRUE if AUTH was tried and failed */ extern uschar *authenticator_name; /* for debug and error messages */ extern uschar *auth_advertise_hosts; /* Only advertise to these */ -extern auth_info auths_available_oldarray[]; /* Vector of available auth mechanisms */ -extern auth_info * auths_available_newlist; +extern auth_info * auths_available; /* List of available auth mechanisms */ extern auth_instance *auths; /* Chain of instantiated auths */ extern auth_instance auth_defaults; /* Default values */ extern uschar *auth_defer_msg; /* Error message for log */ diff --git a/src/src/readconf.c b/src/src/readconf.c index 57788afc3..532e0774c 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -435,10 +435,7 @@ uschar buf[EXIM_DRIVERNAME_MAX]; options_from_list(optionlist_auths, optionlist_auths_size, US"AUTHENTICATORS", NULL); -#ifdef old -for (struct auth_info * ai = auths_available; ai->drinfo.driver_name[0]; ai++) -#endif -for (driver_info * di = (driver_info *)auths_available_newlist; di; di = di->next) +for (driver_info * di = (driver_info *)auths_available; di; di = di->next) { auth_info * ai = (auth_info *)di; @@ -3738,7 +3735,7 @@ driver_info * di; int len; DIR * dd; -/* First scan the list of statically-built drivers. */ +/* First scan the list of driver seen so far. */ for (di = *info_anchor; di; di = di->next) if (Ustrcmp(d->driver_name, di->driver_name) == 0) @@ -3859,8 +3856,8 @@ Arguments: instance_size size of instance block driver_optionlist generic option list driver_optionlist_count count of generic option list - class "router", "transport", or "authenticator" - for error message + class "router", "transport", or "auth" + for filename component (and error message) Returns: nothing */ @@ -4328,25 +4325,65 @@ auths_init(void) #ifndef DISABLE_PIPE_CONNECT int nauths = 0; #endif - -for (auth_info * tblent = auths_available_oldarray; - *tblent->drinfo.driver_name; tblent++) +int old_pool = store_pool; +store_pool = POOL_PERM; { - driver_info * listent = store_get(sizeof(auth_info), tblent); - memcpy(listent, tblent, sizeof(auth_info)); - listent->next = (driver_info *)auths_available_newlist; - auths_available_newlist = (auth_info *)listent; + driver_info ** anchor = (driver_info **) &auths_available; + extern auth_info cram_md5_auth_info; + extern auth_info cyrus_sasl_auth_info; + extern auth_info dovecot_auth_info; + extern auth_info external_auth_info; + extern auth_info gsasl_auth_info; + extern auth_info heimdal_gssapi_auth_info; + extern auth_info plaintext_auth_info; + extern auth_info spa_auth_info; + extern auth_info tls_auth_info; + + /* Add the transport drivers that are built for static linkage to the + list of availables. */ + +#if defined(AUTH_CRAM_MD5) && AUTH_CRAM_MD5!=2 + add_driver_info(anchor, &cram_md5_auth_info.drinfo, sizeof(auth_info)); +#endif +#if defined(AUTH_CYRUS_SASL) && AUTH_CYRUS_SASL!=2 + add_driver_info(anchor, &cyrus_sasl_auth_info.drinfo, sizeof(auth_info)); +#endif +#if defined(AUTH_DOVECOT) && AUTH_DOVECOT!=2 + add_driver_info(anchor, &dovecot_auth_info.drinfo, sizeof(auth_info)); +#endif +#if defined(AUTH_EXTERNAL) && AUTH_EXTERNAL!=2 + add_driver_info(anchor, &external_auth_info.drinfo, sizeof(auth_info)); +#endif +#if defined(AUTH_GSASL) && AUTH_GSASL!=2 + add_driver_info(anchor, &gsasl_auth_info.drinfo, sizeof(auth_info)); +#endif +#if defined(AUTH_HEIMDAL_GSSAPI) && AUTH_HEIMDAL_GSSAPI!=2 + add_driver_info(anchor, &heimdal_gssapi_auth_info.drinfo, sizeof(auth_info)); +#endif +#if defined(AUTH_PLAINTEXT) && AUTH_PLAINTEXT!=2 + add_driver_info(anchor, &plaintext_auth_info.drinfo, sizeof(auth_info)); +#endif +#if defined(AUTH_SPA) && AUTH_SPA!=2 + add_driver_info(anchor, &spa_auth_info.drinfo, sizeof(auth_info)); +#endif +#if defined(AUTH_TLS) && AUTH_TLS!=2 + add_driver_info(anchor, &tls_auth_info.drinfo, sizeof(auth_info)); +#endif } +store_pool = old_pool; +/* Read the config file "authenticators" section, creating an auth instance list. +For any yet-undiscovered driver, check for a loadable module and add it to +those available. */ readconf_driver_init((driver_instance **)&auths, /* chain anchor */ - (driver_info **)&auths_available_newlist, /* available drivers */ + (driver_info **)&auths_available, /* available drivers */ sizeof(auth_info), /* size of info block */ &auth_defaults, /* default values for generic options */ sizeof(auth_instance), /* size of instance block */ optionlist_auths, /* generic options */ optionlist_auths_size, - US"authenticator"); + US"auth"); for (auth_instance * au = auths; au; au = au->drinst.next) { @@ -4367,7 +4404,7 @@ for (auth_instance * au = auths; au; au = au->drinst.next) #endif } #ifndef DISABLE_PIPE_CONNECT -f.smtp_in_early_pipe_no_auth = nauths > 16; +f.smtp_in_early_pipe_no_auth = nauths > 16; /* bits in bitmap limit */ #endif } diff --git a/src/src/transports/Makefile b/src/src/transports/Makefile index 43418fd22..895dad57f 100644 --- a/src/src/transports/Makefile +++ b/src/src/transports/Makefile @@ -25,8 +25,9 @@ transports.a: $(OBJ) smtp_socks.o tf_maildir.o .c.o:; @echo "$(CC) $*.c" $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) $*.c +SO_FLAGS = -DDYNLOOKUP $(CFLAGS_DYNAMIC) $(CFLAGS) $(INCLUDE) $(DLFLAGS) .c.so:; @echo "$(CC) -shared $*.c" - $(FE)$(CC) -DDYNLOOKUP $(CFLAGS_DYNAMIC) $(CFLAGS) $(INCLUDE) $(DLFLAGS) $*.c -o $@ + $(FE)$(CC) $(SO_FLAGS) $*.c -o $@ $(OBJ) $(MOD): $(HDRS) @@ -47,7 +48,6 @@ tf_maildir.o: tf_maildir.c tf_maildir.h appendfile.h appendfile.so: appendfile.c appendfile.h tf_maildir.c tf_maildir.h @echo "$(CC) -shared appendfile.c tf_maildir.c" - $(FE)$(CC) -DDYNLOOKUP $(CFLAGS_DYNAMIC) $(CFLAGS) $(INCLUDE) $(DLFLAGS) \ - appendfile.c tf_maildir.c -o $@ + $(FE)$(CC) $(SO_FLAGS) appendfile.c tf_maildir.c -o $@ # End diff --git a/test/confs/0000 b/test/confs/0000 index 5db8ac8cf..e25ac4b4f 100644 --- a/test/confs/0000 +++ b/test/confs/0000 @@ -12,5 +12,6 @@ keep_environment = begin routers begin transports +begin authenticators # End diff --git a/test/runtest b/test/runtest index 632672324..0c9f2808b 100755 --- a/test/runtest +++ b/test/runtest @@ -1160,7 +1160,7 @@ RESET_AFTER_EXTRA_LINE_READ: (?: .*\sBerkeley\ DB | \sProbably\ (?:Berkeley\ DB|ndbm|GDBM) | \sUsing\ (?:tdb|sqlite3) - | Authenticators: + | Authenticators\ \((?:built-in|dynamic)\): | Lookups(?:\(built-in\))?: | Support\ for: | Routers\ \((?:built-in|dynamic)\): @@ -3741,12 +3741,13 @@ while () @parm_lookups{keys %temp_lookups} = values %temp_lookups; } - elsif (/^Authenticators: (.*)/) + elsif (/^Authenticators \((?:built-in|dynamic)\): ?(.*)/) { print; @temp = split /(\s+)/, $1; push(@temp, ' '); - %parm_authenticators = @temp; + my %temp_auths= @temp; + @parm_authenticators{keys %temp_auths} = values %temp_auths; } elsif (/^Routers \((?:built-in|dynamic)\): ?(.*)/) diff --git a/test/stderr/0402 b/test/stderr/0402 index 8c4dda874..d0906810d 100644 --- a/test/stderr/0402 +++ b/test/stderr/0402 @@ -546,6 +546,9 @@ expanded: 'TESTSUITE/test-mail/junk' file is not a filter file parse_forward_list: TESTSUITE/test-mail/junk extract item: TESTSUITE/test-mail/junk +try option errors_to +try option headers_add +try option headers_remove try option file_transport try option transport set transport ft1 @@ -604,6 +607,9 @@ expanded: 'TESTSUITE/test-mail/junk' file is not a filter file parse_forward_list: TESTSUITE/test-mail/junk extract item: TESTSUITE/test-mail/junk +try option errors_to +try option headers_add +try option headers_remove try option file_transport try option transport set transport ft1 @@ -650,6 +656,9 @@ try option set calling r3 router r3 router called for userz@test.ex domain = test.ex +try option errors_to +try option headers_add +try option headers_remove try option transport set transport t2 queued for t2 transport: local_part = userz @@ -688,6 +697,9 @@ try option set calling r2 router r2 router called for usery@test.ex domain = test.ex +try option errors_to +try option headers_add +try option headers_remove try option transport set transport t1 queued for t1 transport: local_part = usery @@ -719,6 +731,9 @@ try option set calling r1 router r1 router called for CALLER@test.ex domain = test.ex +try option errors_to +try option headers_add +try option headers_remove try option transport set transport t1 queued for t1 transport: local_part = CALLER diff --git a/test/stderr/0544 b/test/stderr/0544 index de449b123..84ecb04f3 100644 --- a/test/stderr/0544 +++ b/test/stderr/0544 @@ -369,10 +369,16 @@ admin user dropping to exim gid; retaining priv uid try option router_home_directory try option set +try option errors_to +try option headers_add +try option headers_remove try option transport try option unseen try option router_home_directory try option set +try option errors_to +try option headers_add +try option headers_remove try option transport try option unseen try option multi_domain diff --git a/test/stderr/5410 b/test/stderr/5410 index 4ee810ac3..471e04156 100644 --- a/test/stderr/5410 +++ b/test/stderr/5410 @@ -95,6 +95,9 @@ processing address_data domain.com in "*"? list element: * domain.com in "*"? yes (matched "*") +try option errors_to +try option headers_add +try option headers_remove try option transport try option unseen ----------- end verify ------------ @@ -122,6 +125,9 @@ processing address_data domain.com in "*"? list element: * domain.com in "*"? yes (matched "*") +try option errors_to +try option headers_add +try option headers_remove try option transport try option unseen try option interface @@ -766,6 +772,9 @@ processing address_data domain.com in "*"? list element: * domain.com in "*"? yes (matched "*") +try option errors_to +try option headers_add +try option headers_remove try option transport try option unseen ----------- end verify ------------ @@ -793,6 +802,9 @@ processing address_data domain.com in "*"? list element: * domain.com in "*"? yes (matched "*") +try option errors_to +try option headers_add +try option headers_remove try option transport try option unseen try option interface @@ -1386,6 +1398,9 @@ processing address_data domain.com in "*"? list element: * domain.com in "*"? yes (matched "*") +try option errors_to +try option headers_add +try option headers_remove try option transport try option unseen ----------- end verify ------------ @@ -1413,6 +1428,9 @@ processing address_data domain.com in "*"? list element: * domain.com in "*"? yes (matched "*") +try option errors_to +try option headers_add +try option headers_remove try option transport try option unseen try option interface -- 2.30.2