From: Philip Hazel Date: Tue, 22 Mar 2005 14:11:54 +0000 (+0000) Subject: 1. Added Tony F's ${dlfunc expansion, slightly modified (see NewStuff). X-Git-Tag: exim-4_51~48 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/1a46a8c5c398c91f20c3f4def0ceb448ec8de96a 1. Added Tony F's ${dlfunc expansion, slightly modified (see NewStuff). 2. Recognize ${perl even if not compiled, and give suitable error message. --- diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index b2a43652c..f366edf2c 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.93 2005/03/22 10:11:42 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.94 2005/03/22 14:11:54 ph10 Exp $ Change log file for Exim from version 4.21 ------------------------------------------- @@ -7,53 +7,59 @@ Change log file for Exim from version 4.21 Exim version 4.51 ----------------- -TK/01. Added Yahoo DomainKeys support via libdomainkeys. See - doc/experimental-spec.txt for details. (http://domainkeys.sf.net) - -TK/02. Fix ACL "control" statment not being available in MIME ACL. - -TK/03. Fix ACL "regex" condition not being available in MIME ACL. - -PH/01. Installed a patch from the Sieve maintainer that allows -bf to be used - to test Sieve filters that use "vacation". - -PH/02. Installed a slightly modified version of Nikos Mavrogiannopoulos' patch - that changes the way the GnuTLS parameters are stored in the cache file. - The new format can be generated externally. For backward compatibility, - if the data in the cache doesn't make sense, Exim assumes it has read an - old-format file, and it generates new data and writes a new file. This - means that you can't go back to an older release without removing the - file. - -PH/03. A redirect router that has both "unseen" and "one_time" set does not - work if there are any delivery delays because "one_time" forces the - parent to be marked "delivered", so its unseen clone is never tried - again. For this reason, Exim now forbids the simultaneous setting of - these two options. - -PH/04. Change 4.11/85 fixed an obscure bug concerned with addresses that are - redirected to themselves ("homonym" addresses). Read the long ChangeLog - entry if you want to know the details. The fix, however, neglected to - consider the case when local delivery batching is involved. The test for - "previously delivered" was not happening when checking to see if an - address could be batched with a previous (undelivered) one; under - certain circumstances this could lead to multiple deliveries to the same - address. A one-line patch to add the appropriate test fixes the bug. - -PH/05. Renamed the macro SOCKLEN_T as EXIM_SOCKLEN_T because AIX uses SOCKLEN_T - in its include files, and this causes problems building Exim. - -PH/06. A number of "verify =" ACL conditions have no options (e.g. verify = - header_syntax) but Exim was just ignoring anything given after a slash. - In particular, this caused confusion with an attempt to use "verify = - reverse_host_lookup/defer_ok". An error is now given when options are - supplied for verify items that do not have them. (Maybe reverse_host_ - lookup should have a defer_ok option, but that's a different point.) - -PH/07. Increase the size of the buffer for incoming SMTP commands from 512 (as - defined by RFC 821) to 2048, because there were problems with some AUTH - commands, and RFC 1869 says the size should be increased for extended - SMTP commands that take arguments. +TK/01 Added Yahoo DomainKeys support via libdomainkeys. See + doc/experimental-spec.txt for details. (http://domainkeys.sf.net) + +TK/02 Fix ACL "control" statment not being available in MIME ACL. + +TK/03 Fix ACL "regex" condition not being available in MIME ACL. + +PH/01 Installed a patch from the Sieve maintainer that allows -bf to be used + to test Sieve filters that use "vacation". + +PH/02 Installed a slightly modified version of Nikos Mavrogiannopoulos' patch + that changes the way the GnuTLS parameters are stored in the cache file. + The new format can be generated externally. For backward compatibility, + if the data in the cache doesn't make sense, Exim assumes it has read an + old-format file, and it generates new data and writes a new file. This + means that you can't go back to an older release without removing the + file. + +PH/03 A redirect router that has both "unseen" and "one_time" set does not + work if there are any delivery delays because "one_time" forces the + parent to be marked "delivered", so its unseen clone is never tried + again. For this reason, Exim now forbids the simultaneous setting of + these two options. + +PH/04 Change 4.11/85 fixed an obscure bug concerned with addresses that are + redirected to themselves ("homonym" addresses). Read the long ChangeLog + entry if you want to know the details. The fix, however, neglected to + consider the case when local delivery batching is involved. The test for + "previously delivered" was not happening when checking to see if an + address could be batched with a previous (undelivered) one; under + certain circumstances this could lead to multiple deliveries to the same + address. A one-line patch to add the appropriate test fixes the bug. + +PH/05 Renamed the macro SOCKLEN_T as EXIM_SOCKLEN_T because AIX uses SOCKLEN_T + in its include files, and this causes problems building Exim. + +PH/06 A number of "verify =" ACL conditions have no options (e.g. verify = + header_syntax) but Exim was just ignoring anything given after a slash. + In particular, this caused confusion with an attempt to use "verify = + reverse_host_lookup/defer_ok". An error is now given when options are + supplied for verify items that do not have them. (Maybe reverse_host_ + lookup should have a defer_ok option, but that's a different point.) + +PH/07 Increase the size of the buffer for incoming SMTP commands from 512 (as + defined by RFC 821) to 2048, because there were problems with some AUTH + commands, and RFC 1869 says the size should be increased for extended + SMTP commands that take arguments. + +PH/08 Added ${dlfunc dynamically loaded function for expansion (code from Tony + Finch). + +PH/09 Previously, an attempt to use ${perl when it wasn't compiled gave an + "unknown" error; now it says that the functionality isn't in the binary. A note about Exim versions 4.44 and 4.50 diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 827c5d1dc..383c0f6f4 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/NewStuff,v 1.27 2005/03/08 11:38:21 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/NewStuff,v 1.28 2005/03/22 14:11:54 ph10 Exp $ New Features in Exim -------------------- @@ -12,32 +12,72 @@ file contains a listing of all changes, including bug fixes. Version 4.51 ------------ -PH/01. The format in which GnuTLS parameters are written to the gnutls-param - file in the spool directory has been changed. This change has been made - to alleviate problems that some people had with the generation of the - parameters by Exim when /dev/random was exhausted. In this situation, - Exim would hang until /dev/random acquired some more entropy. - - The new code exports and imports the DH and RSA parameters in PEM - format. This means that the parameters can be generated externally using - the certtool command that is part of GnuTLS. - - To replace the parameters with new ones, instead of deleting the file - and letting Exim re-create it, you can generate new parameters using - certtool and, when this has been done, replace Exim's cache file by - renaming. The relevant commands are something like this: - - # rm -f new.params - # touch new.params - # chown exim:exim new.params - # chmod 0400 new.params - # certtool --generate-privkey --bits 512 >new.params - # echo "" >>new.params - # certtool --generate-dh-params --bits 1024 >> new.params - # mv new.params params - - If Exim never has to generate the parameters itself, the possibility of - stalling is removed. +PH/01 The format in which GnuTLS parameters are written to the gnutls-param + file in the spool directory has been changed. This change has been made + to alleviate problems that some people had with the generation of the + parameters by Exim when /dev/random was exhausted. In this situation, + Exim would hang until /dev/random acquired some more entropy. + + The new code exports and imports the DH and RSA parameters in PEM + format. This means that the parameters can be generated externally using + the certtool command that is part of GnuTLS. + + To replace the parameters with new ones, instead of deleting the file + and letting Exim re-create it, you can generate new parameters using + certtool and, when this has been done, replace Exim's cache file by + renaming. The relevant commands are something like this: + + # rm -f new.params + # touch new.params + # chown exim:exim new.params + # chmod 0400 new.params + # certtool --generate-privkey --bits 512 >new.params + # echo "" >>new.params + # certtool --generate-dh-params --bits 1024 >> new.params + # mv new.params params + + If Exim never has to generate the parameters itself, the possibility of + stalling is removed. + +PH/02 A new expansion item for dynamically loading and calling a locally- + written C function is now provided, if Exim is compiled with + + EXPAND_DLFUNC=yes + + set in Local/Makefile. The facility is not included by default (a + suitable error is given if you try to use it when it is not there.) + You load and call the function like this: + + ${dlfunc{/some/file}{function}{arg1}{arg2}...} + + Once loaded, Exim remembers it so that it doesn't reload it in the same + Exim process (but of course Exim does start new processes frequently). + + There may be from zero to eight arguments to the function. When compiling + a local function that is to be called in this way, local_scan.h should be + included. The Exim variables and functions that are defined by that API + are also available for dynamically loaded functions. The function itself + must have the following type: + + int dlfunction(uschar **yield, int argc, uschar *argv[]) + + Where "uschar" is a typedef for "unsigned char" in local_scan.h. The + function should return one of the following values: + + OK Success. The string that is placed in "yield" is put into + the expanded string that is being built. + + FAIL A non-forced expansion failure occurs, with the error + message taken from "yield", if it is set. + + FAIL_FORCED A forced expansion failure occurs, with the error message + taken from "yield" if it is set. + + ERROR Same as FAIL, except that a panic log entry is written. + + When compiling a function that is to be used in this way with gcc, + you need to add -shared to the gcc command. Also, in the Exim build-time + configuration, you must add -export-dynamic to EXTRALIBS. Version 4.50 diff --git a/src/ACKNOWLEDGMENTS b/src/ACKNOWLEDGMENTS index 8314c699a..0982973d2 100644 --- a/src/ACKNOWLEDGMENTS +++ b/src/ACKNOWLEDGMENTS @@ -1,4 +1,4 @@ -$Cambridge: exim/src/ACKNOWLEDGMENTS,v 1.15 2005/03/15 12:27:54 ph10 Exp $ +$Cambridge: exim/src/ACKNOWLEDGMENTS,v 1.16 2005/03/22 14:11:54 ph10 Exp $ EXIM ACKNOWLEDGEMENTS @@ -20,7 +20,7 @@ relatively small patches. Philip Hazel Lists created: 20 November 2002 -Last updated: 15 March 2005 +Last updated: 22 March 2005 THE OLD LIST @@ -78,7 +78,7 @@ Richard Birkett Fix for empty -f address crash Nick Burrett Patch for CONFIGURE_FILE_USE_EUID in exicyclog Matthew Byng-Maddick Patch for qualify_domain in redirect router Patch for ignore_target_hosts in ipliteral router - The cyrus_sasl authenticator + The cyrus_sasl authenticator Steve Campbell eximstats extensions and continued maintenance Brian Candler Use h_errno for gethostbyname() Suggested patch for .ifdef etc @@ -93,7 +93,7 @@ Andrew Doran Patch for NetBSD configuration files Patch for ifreq alignment and size problems Michael Deutschmann Suggested patch for treating bind() failure like connect() Patch for $sender_data and $recipient_data - Suggested patch for null address match lookup bug + Suggested patch for null address match lookup bug Oliver Eikemeier Patch to skip Received: if expansion is empty Patch for "eqi" Nico Erfurth Fix for bug in ${readfile} @@ -121,9 +121,10 @@ Tony Finch Expansion extensions A number of useful code criticisms Timezone patch for exiwhat Patch for more daemon exiwhat information - Patch for -dd - Patch for mxh lookup type in dnsdb - Patch for defer_foo in dndsb + Patch for -dd + Patch for mxh lookup type in dnsdb + Patch for defer_foo in dndsb + Patch for ${dlfunc Giuliano Gavazzi Patches for OSX compilation Dominic Germain Patch for exiqgrep MacOS X bug Oliver Gorwits $load_average patch @@ -138,7 +139,7 @@ Michael Haardt Tidies to make the code stricter Module to support Sieve (RFC 3028) filters and continued maintenance of same Patch for faster sort algorithm in queue.c - Patch for LDAP timeout handling + Patch for LDAP timeout handling Thomas Hager Patch for saslauthd crash bug Richard Hall Fix for file descriptor leak in redirection Steve Haslam Lots of stuff, including @@ -154,7 +155,7 @@ Christian Kellner Patch for LDAP dereferencing Alex Kiernan Patch for libradius Diagnosis of milliwait clock-backwards bug Tom Kistner SPA server code - Writing and maintaining the content scanning + Writing and maintaining the content scanning extension (exiscan) Friso Kuipers Patch for GDBM problem Chris Liddiard Fix for bug in exiqsumm @@ -174,9 +175,9 @@ Marc Merlin Many suggestions and patches for callouts and SMTP error message features Andreas Metzler Patch for message_id_header_domain Suggested patch for multi-config files in scripts bug -Alex Miller Suggested readline() patch +Alex Miller Suggested readline() patch Patch for LDAP_RES_SEARCH_REFERENCE handling - Support for the DrWeb content scanner + Support for the DrWeb content scanner Andreas Mueller Patch for logging uncompleted SMTP transactions Pete Naylor Patch for LDAP TCP connect timeout setting Marcin Owsiany Diagnosis of a tricky timeout failure bug diff --git a/src/src/EDITME b/src/src/EDITME index 60774cf49..72f797bb3 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -1,4 +1,4 @@ -# $Cambridge: exim/src/src/EDITME,v 1.8 2005/02/17 11:58:25 ph10 Exp $ +# $Cambridge: exim/src/src/EDITME,v 1.9 2005/03/22 14:11:54 ph10 Exp $ ################################################## # The Exim mail transport agent # @@ -689,6 +689,15 @@ ZCAT_COMMAND=/usr/bin/zcat # EXIM_PERL=perl.o +#------------------------------------------------------------------------------ +# Support for dynamically-loaded string expansion functions via ${dlfunc. If +# you are using gcc the dynamically-loaded object must be compiled with the +# -shared option, and you will need to add -export-dynamic to EXTRALIBS so +# that the local_scan API is made available by the linker. + +# EXPAND_DLFUNC=yes + + #------------------------------------------------------------------------------ # Exim has support for PAM (Pluggable Authentication Modules), a facility # which is available in the latest releases of Solaris and in some GNU/Linux diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults index ea63c888f..2825f98c1 100644 --- a/src/src/config.h.defaults +++ b/src/src/config.h.defaults @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/config.h.defaults,v 1.5 2005/03/08 15:32:02 tom Exp $ */ +/* $Cambridge: exim/src/src/config.h.defaults,v 1.6 2005/03/22 14:11:54 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -42,11 +42,10 @@ in config.h unless some value is defined in Local/Makefile. */ #define EXIMDB_LOCK_TIMEOUT 60 #define EXIMDB_LOCKFILE_MODE 0640 #define EXIMDB_MODE 0640 - #define EXIM_PERL - /* Both uid and gid are triggered by this */ #define EXIM_UID +#define EXPAND_DLFUNC #define FIXED_NEVER_USERS "root" diff --git a/src/src/exim.c b/src/src/exim.c index 14cd03228..ffe596d15 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/exim.c,v 1.16 2005/03/15 14:09:12 ph10 Exp $ */ +/* $Cambridge: exim/src/src/exim.c,v 1.17 2005/03/22 14:11:54 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -829,6 +829,9 @@ fprintf(f, "Support for:"); #ifdef EXIM_PERL fprintf(f, " Perl"); #endif +#ifdef EXPAND_DLFUNC + fprintf(f, " Expand_dlfunc"); +#endif #ifdef USE_TCP_WRAPPERS fprintf(f, " TCPwrappers"); #endif diff --git a/src/src/exim.h b/src/src/exim.h index 42f7980c2..b28edb79b 100644 --- a/src/src/exim.h +++ b/src/src/exim.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/exim.h,v 1.9 2005/03/15 14:09:12 ph10 Exp $ */ +/* $Cambridge: exim/src/src/exim.h,v 1.10 2005/03/22 14:11:54 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -60,7 +60,7 @@ making unique names. */ /* Unix includes */ #include -#if defined(__svr4__) && defined(__sparc) && ! defined(__EXTENSIONS__) +#if defined(__svr4__) && defined(__sparc) && ! defined(__EXTENSIONS__) #define __EXTENSIONS__ /* so that SunOS 5 gets NGROUPS_MAX */ #include #undef __EXTENSIONS__ @@ -207,7 +207,7 @@ or a macro with entries f_frsize and f_bsize. */ #endif -#ifndef SIOCGIFCONF /* HACK for SunOS 5 */ +#ifndef SIOCGIFCONF /* HACK for SunOS 5 */ #include #endif @@ -414,7 +414,7 @@ requires various things that are set therein. */ #include #endif -#ifdef USE_READLINE +#if defined(USE_READLINE) || defined(EXPAND_DLFUNC) #include #endif diff --git a/src/src/expand.c b/src/src/expand.c index 6e7d3550f..d27530bd7 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/expand.c,v 1.16 2005/03/09 08:27:51 tom Exp $ */ +/* $Cambridge: exim/src/src/expand.c,v 1.17 2005/03/22 14:11:54 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -48,6 +48,7 @@ static uschar *expand_string_internal(uschar *, BOOL, uschar **, BOOL); alphabetical order. */ static uschar *item_table[] = { + US"dlfunc", US"extract", US"hash", US"hmac", @@ -55,9 +56,7 @@ static uschar *item_table[] = { US"length", US"lookup", US"nhash", - #ifdef EXIM_PERL - US"perl", - #endif + US"perl", US"readfile", US"readsocket", US"run", @@ -66,6 +65,7 @@ static uschar *item_table[] = { US"tr" }; enum { + EITEM_DLFUNC, EITEM_EXTRACT, EITEM_HASH, EITEM_HMAC, @@ -73,9 +73,7 @@ enum { EITEM_LENGTH, EITEM_LOOKUP, EITEM_NHASH, - #ifdef EXIM_PERL - EITEM_PERL, - #endif + EITEM_PERL, EITEM_READFILE, EITEM_READSOCK, EITEM_RUN, @@ -3072,10 +3070,15 @@ while (*s != 0) or ${perl{sub}{arg1}{arg2}} or up to a maximum of EXIM_PERL_MAX_ARGS arguments (defined below). */ - #ifdef EXIM_PERL #define EXIM_PERL_MAX_ARGS 8 case EITEM_PERL: + #ifndef EXIM_PERL + expand_string_message = US"\"${perl\" encountered, but this facility " + "is not included in this binary"; + goto EXPAND_FAILED; + + #else /* EXIM_PERL */ { uschar *sub_arg[EXIM_PERL_MAX_ARGS + 2]; uschar *new_yield; @@ -3847,6 +3850,106 @@ while (*s != 0) continue; } + + + /* If ${dlfunc support is configured, handle calling dynamically-loaded + functions, unless locked out at this time. Syntax is ${dlfunc{file}{func}} + or ${dlfunc{file}{func}{arg}} or ${dlfunc{file}{func}{arg1}{arg2}} or up to + a maximum of EXPAND_DLFUNC_MAX_ARGS arguments (defined below). */ + + #define EXPAND_DLFUNC_MAX_ARGS 8 + + case EITEM_DLFUNC: + #ifndef EXPAND_DLFUNC + expand_string_message = US"\"${dlfunc\" encountered, but this facility " + "is not included in this binary"; + goto EXPAND_FAILED; + + #else /* EXPAND_DLFUNC */ + { + tree_node *t; + exim_dlfunc_t *func; + uschar *result; + int status, argc; + uschar *argv[EXPAND_DLFUNC_MAX_ARGS + 3]; + + if ((expand_forbid & RDO_DLFUNC) != 0) + { + expand_string_message = + US"dynamically-loaded functions are not permitted"; + goto EXPAND_FAILED; + } + + switch(read_subs(argv, EXPAND_DLFUNC_MAX_ARGS + 2, 2, &s, skipping, + TRUE, US"dlfunc")) + { + case 1: goto EXPAND_FAILED_CURLY; + case 2: + case 3: goto EXPAND_FAILED; + } + + /* If skipping, we don't actually do anything */ + + if (skipping) continue; + + /* Look up the dynamically loaded object handle in the tree. If it isn't + found, dlopen() the file and put the handle in the tree for next time. */ + + t = tree_search(dlobj_anchor, argv[0]); + if (t == NULL) + { + void *handle = dlopen(CS argv[0], RTLD_LAZY); + if (handle == NULL) + { + expand_string_message = string_sprintf("dlopen \"%s\" failed: %s", + argv[0], dlerror()); + log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message); + goto EXPAND_FAILED; + } + t = store_get_perm(sizeof(tree_node) + Ustrlen(argv[0])); + Ustrcpy(t->name, argv[0]); + t->data.ptr = handle; + (void)tree_insertnode(&dlobj_anchor, t); + } + + /* Having obtained the dynamically loaded object handle, look up the + function pointer. */ + + func = (exim_dlfunc_t *)dlsym(t->data.ptr, CS argv[1]); + if (func == NULL) + { + expand_string_message = string_sprintf("dlsym \"%s\" in \"%s\" failed: " + "%s", argv[1], argv[0], dlerror()); + log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message); + goto EXPAND_FAILED; + } + + /* Call the function and work out what to do with the result. If it + returns OK, we have a replacement string; if it returns DEFER then + expansion has failed in a non-forced manner; if it returns FAIL then + failure was forced; if it returns ERROR or any other value there's a + problem, so panic slightly. */ + + result = NULL; + for (argc = 0; argv[argc] != NULL; argc++); + status = func(&result, argc - 2, &argv[2]); + if(status == OK) + { + if (result == NULL) result = US""; + yield = string_cat(yield, &size, &ptr, result, Ustrlen(result)); + continue; + } + else + { + expand_string_message = result == NULL ? US"(no message)" : result; + if(status == FAIL_FORCED) expand_string_forcedfail = TRUE; + else if(status != FAIL) + log_write(0, LOG_MAIN|LOG_PANIC, "dlfunc{%s}{%s} failed (%d): %s", + argv[0], argv[1], status, expand_string_message); + goto EXPAND_FAILED; + } + } + #endif /* EXPAND_DLFUNC */ } /* Control reaches here if the name is not recognized as one of the more diff --git a/src/src/globals.c b/src/src/globals.c index fdccc0b98..2324e4072 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.c,v 1.19 2005/03/08 15:32:02 tom Exp $ */ +/* $Cambridge: exim/src/src/globals.c,v 1.20 2005/03/22 14:11:54 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -62,6 +62,10 @@ BOOL opt_perl_at_start = FALSE; BOOL opt_perl_started = FALSE; #endif +#ifdef EXPAND_DLFUNC +tree_node *dlobj_anchor = NULL; +#endif + #ifdef LOOKUP_IBASE uschar *ibase_servers = NULL; #endif diff --git a/src/src/globals.h b/src/src/globals.h index 2bb61c145..404838126 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.h,v 1.12 2005/03/08 15:32:02 tom Exp $ */ +/* $Cambridge: exim/src/src/globals.h,v 1.13 2005/03/22 14:11:54 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -26,6 +26,10 @@ extern BOOL opt_perl_at_start; /* Start Perl interpreter at start */ extern BOOL opt_perl_started; /* Set once interpreter started */ #endif +#ifdef EXPAND_DLFUNC +extern tree_node *dlobj_anchor; /* Tree of dynamically-loaded objects */ +#endif + #ifdef LOOKUP_IBASE extern uschar *ibase_servers; #endif diff --git a/src/src/local_scan.h b/src/src/local_scan.h index e612ccd84..fdc73bed5 100644 --- a/src/src/local_scan.h +++ b/src/src/local_scan.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/local_scan.h,v 1.3 2005/01/04 10:00:42 ph10 Exp $ */ +/* $Cambridge: exim/src/src/local_scan.h,v 1.4 2005/03/22 14:11:54 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -9,7 +9,9 @@ /* This file is the header that is the only Exim header to be included in the source for the local_scan.c() function. It contains definitions that are made -available for use in that function, and which are documented. */ +available for use in that function, and which are documented. + +This API is also used for functions called by the ${dlfunc expansion item. */ /* Some basic types that make some things easier, and the store functions. */ @@ -34,13 +36,27 @@ enum { }; -/* Return codes from the support functions lss_match_xxx(). */ +/* Functions called by ${dlfunc{file}{func}{arg}...} return one of the five +status codes defined immediately below. The function's first argument is either +the result of expansion, or the error message in case of failure. The second +and third arguments are standard argument count and vector, comprising the +{arg} values specified in the expansion item. */ + +typedef int exim_dlfunc_t(uschar **yield, int argc, uschar *argv[]); + + +/* Return codes from the support functions lss_match_xxx(). These are also the +codes that dynamically-loaded ${dlfunc functions must return. */ #define OK 0 /* Successful match */ #define DEFER 1 /* Defer - some problem */ #define FAIL 2 /* Matching failed */ #define ERROR 3 /* Internal or config error */ +/* Extra return code for ${dlfunc functions */ + +#define FAIL_FORCED 4 /* "Forced" failure */ + /* Available logging destinations */ diff --git a/src/src/macros.h b/src/src/macros.h index d69da22f7..86bb84f12 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/macros.h,v 1.10 2005/03/10 08:56:03 tom Exp $ */ +/* $Cambridge: exim/src/src/macros.h,v 1.11 2005/03/22 14:11:54 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -237,27 +237,29 @@ enum { apply to all of them). Some other functions also use these convenient values, and some additional values are used only by non-driver functions. -OK, FAIL, DEFER, and ERROR are also declared in local_scan.h for use in the -local_scan() function. Do not change them unilaterally. */ +OK, FAIL, DEFER, ERROR, and FAIL_FORCED are also declared in local_scan.h for +use in the local_scan() function and in ${dlfunc loaded functions. Do not +change them unilaterally. */ #define OK 0 /* Successful match */ #define DEFER 1 /* Defer - some problem */ #define FAIL 2 /* Matching failed */ #define ERROR 3 /* Internal or config error */ +#define FAIL_FORCED 4 /* "Forced" failure */ /***********/ -#define DECLINE 4 /* Declined to handle the address, pass to next +#define DECLINE 5 /* Declined to handle the address, pass to next router unless no_more is set */ -#define PASS 5 /* Pass to next driver, or to pass_router, +#define PASS 6 /* Pass to next driver, or to pass_router, even if no_more is set */ -#define DISCARD 6 /* Address routed to :blackhole: or "seen finish" */ -#define SKIP 7 /* Skip this router (used in route_address only) */ -#define REROUTED 8 /* Address was changed and child created*/ -#define PANIC 9 /* Hard failed with internal error */ -#define BAD64 10 /* Bad base64 data (auth) */ -#define UNEXPECTED 11 /* Unexpected initial auth data */ -#define CANCELLED 12 /* Authentication cancelled */ -#define FAIL_SEND 13 /* send() failed in authenticator */ -#define FAIL_DROP 14 /* Fail and drop connection (used in ACL) */ +#define DISCARD 7 /* Address routed to :blackhole: or "seen finish" */ +#define SKIP 8 /* Skip this router (used in route_address only) */ +#define REROUTED 9 /* Address was changed and child created*/ +#define PANIC 10 /* Hard failed with internal error */ +#define BAD64 11 /* Bad base64 data (auth) */ +#define UNEXPECTED 12 /* Unexpected initial auth data */ +#define CANCELLED 13 /* Authentication cancelled */ +#define FAIL_SEND 14 /* send() failed in authenticator */ +#define FAIL_DROP 15 /* Fail and drop connection (used in ACL) */ /* Returns from the deliver_message() function */ @@ -489,15 +491,16 @@ router, which were chosen to represent the standard situation for users' #define RDO_READFILE 0x00001000 /* Forbid "readfile" in exp in filter */ #define RDO_READSOCK 0x00002000 /* Forbid "readsocket" in exp in filter */ #define RDO_RUN 0x00004000 /* Forbid "run" in expansion in filter */ -#define RDO_REALLOG 0x00008000 /* Really do log (not testing/verifying) */ -#define RDO_REWRITE 0x00010000 /* Rewrite generated addresses */ -#define RDO_EXIM_FILTER 0x00020000 /* Forbid Exim filters */ -#define RDO_SIEVE_FILTER 0x00040000 /* Forbid Sieve filters */ +#define RDO_DLFUNC 0x00008000 /* Forbid "dlfunc" in expansion in filter */ +#define RDO_REALLOG 0x00010000 /* Really do log (not testing/verifying) */ +#define RDO_REWRITE 0x00020000 /* Rewrite generated addresses */ +#define RDO_EXIM_FILTER 0x00040000 /* Forbid Exim filters */ +#define RDO_SIEVE_FILTER 0x00080000 /* Forbid Sieve filters */ /* This is the set that apply to expansions in filters */ #define RDO_FILTER_EXPANSIONS \ - (RDO_EXISTS|RDO_LOOKUP|RDO_PERL|RDO_READFILE|RDO_READSOCK|RDO_RUN) + (RDO_EXISTS|RDO_LOOKUP|RDO_PERL|RDO_READFILE|RDO_READSOCK|RDO_RUN|RDO_DLFUNC) /* As well as the RDO bits themselves, we need the bit numbers in order to access (most of) the individual bits as separate options. This could be @@ -505,7 +508,7 @@ automated, but I haven't bothered. Keep this list in step with the above! */ enum { RDON_BLACKHOLE, RDON_DEFER, RDON_EACCES, RDON_ENOTDIR, RDON_EXISTS, RDON_FAIL, RDON_FILTER, RDON_FREEZE, RDON_INCLUDE, RDON_LOG, RDON_LOOKUP, - RDON_PERL, RDON_READFILE, RDON_READSOCK, RDON_RUN, RDON_REALLOG, + RDON_PERL, RDON_READFILE, RDON_READSOCK, RDON_RUN, RDON_DLFUNC, RDON_REALLOG, RDON_REWRITE, RDON_EXIM_FILTER, RDON_SIEVE_FILTER }; /* Results of filter or forward file processing. Some are only from a filter; diff --git a/src/src/routers/redirect.c b/src/src/routers/redirect.c index 461fc5d92..65b5e4099 100644 --- a/src/src/routers/redirect.c +++ b/src/src/routers/redirect.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/routers/redirect.c,v 1.6 2005/03/15 11:37:21 ph10 Exp $ */ +/* $Cambridge: exim/src/src/routers/redirect.c,v 1.7 2005/03/22 14:11:55 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -45,6 +45,10 @@ optionlist redirect_router_options[] = { (void *)offsetof(redirect_router_options_block, bit_options) }, { "forbid_file", opt_bool, (void *)offsetof(redirect_router_options_block, forbid_file) }, + #ifdef EXPAND_DLFUNC + { "forbid_filter_dlfunc", opt_bit | (RDON_DLFUNC << 16), + (void *)offsetof(redirect_router_options_block, bit_options) }, + #endif { "forbid_filter_existstest", opt_bit | (RDON_EXISTS << 16), (void *)offsetof(redirect_router_options_block, bit_options) }, { "forbid_filter_logwrite",opt_bit | (RDON_LOG << 16),