From e4a89c47c2a7d9a9268f36728b4b4f1b028b17b1 Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Wed, 6 Apr 2005 14:40:23 +0000 Subject: [PATCH] Michael Haardt's patch for support for :user and :subaddress in Sieve filters by means of two new redirect router options. --- doc/doc-txt/ChangeLog | 5 ++++- doc/doc-txt/NewStuff | 8 +++++++- src/src/deliver.c | 4 +++- src/src/filtertest.c | 4 ++-- src/src/functions.h | 11 ++++++----- src/src/rda.c | 22 +++++++++++++++------- src/src/routers/queryprogram.c | 4 +++- src/src/routers/redirect.c | 15 +++++++++++---- src/src/routers/redirect.h | 4 +++- src/src/sieve.c | 25 ++++++++++++++----------- 10 files changed, 68 insertions(+), 34 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 2d4044efc..7ac876c15 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.115 2005/04/06 14:09:17 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.116 2005/04/06 14:40:23 ph10 Exp $ Change log file for Exim from version 4.21 ------------------------------------------- @@ -176,6 +176,9 @@ PH/28 Modified OS/os.c-Linux with to make Exim compile on kfreebsd-gnu. (I'm totally confused about the nomenclature these days.) +PH/29 Installed patch from the Sieve maintainer that adds the options + sieve_useraddress and sieve_subaddress to the redirect router. + A note about Exim versions 4.44 and 4.50 diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 4a2739188..16f494bb9 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/NewStuff,v 1.34 2005/04/06 14:03:53 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/NewStuff,v 1.35 2005/04/06 14:40:23 ph10 Exp $ New Features in Exim -------------------- @@ -140,6 +140,12 @@ PH/07 $acl_verify_message is now set immediately after the failure of a Previously, $acl_verify_message was set only while expanding "message" and "log_message" when a very denied access. +PH/08 The redirect router has two new options, sieve_useraddress and + sieve_subaddress. These are passed to a Sieve filter to specify the :user + and :subaddress parts of an address. Both options are unset by default. + However, when a Sieve filter is run, if sieve_useraddress is unset, the + entire original local part (including any prefix or suffix) is used for + :user. An unset subaddress is treated as an empty subaddress. Version 4.50 diff --git a/src/src/deliver.c b/src/src/deliver.c index cc9b8ee0f..ac23a33aa 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/deliver.c,v 1.10 2005/04/05 15:47:50 ph10 Exp $ */ +/* $Cambridge: exim/src/src/deliver.c,v 1.11 2005/04/06 14:40:24 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -4662,6 +4662,8 @@ else if (system_filter != NULL && process_recipients != RECIP_FAIL_TIMEOUT) RDO_REWRITE, NULL, /* No :include: restriction (not used in filter) */ NULL, /* No sieve vacation directory (not sieve!) */ + NULL, /* No sieve user address (not sieve!) */ + NULL, /* No sieve subaddress (not sieve!) */ &ugid, /* uid/gid data */ &addr_new, /* Where to hang generated addresses */ &filter_message, /* Where to put error message */ diff --git a/src/src/filtertest.c b/src/src/filtertest.c index c0a183d6a..107e35e0b 100644 --- a/src/src/filtertest.c +++ b/src/src/filtertest.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/filtertest.c,v 1.4 2005/02/17 11:58:26 ph10 Exp $ */ +/* $Cambridge: exim/src/src/filtertest.c,v 1.5 2005/04/06 14:40:24 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -271,7 +271,7 @@ if (is_system) else { yield = (filter_type == FILTER_SIEVE)? - sieve_interpret(filebuf, RDO_REWRITE, NULL, &generated, &error) + sieve_interpret(filebuf, RDO_REWRITE, NULL, NULL, NULL, &generated, &error) : filter_interpret(filebuf, RDO_REWRITE, &generated, &error); } diff --git a/src/src/functions.h b/src/src/functions.h index 1563a55c3..5fce129a7 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/functions.h,v 1.13 2005/04/04 10:33:49 ph10 Exp $ */ +/* $Cambridge: exim/src/src/functions.h,v 1.14 2005/04/06 14:40:24 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -184,8 +184,9 @@ extern int random_number(int); #ifdef WITH_CONTENT_SCAN extern int recv_line(int, uschar *, int); #endif -extern int rda_interpret(redirect_block *, int, uschar *, uschar *, ugid_block *, - address_item **, uschar **, error_block **, int *, uschar *); +extern int rda_interpret(redirect_block *, int, uschar *, uschar *, + uschar *, uschar *, ugid_block *, address_item **, uschar **, + error_block **, int *, uschar *); extern int rda_is_filter(const uschar *); extern BOOL readconf_depends(driver_instance *, uschar *); extern void readconf_driver_init(uschar *, driver_instance **, @@ -247,8 +248,8 @@ extern void set_process_info(char *, ...); extern void sha1_end(sha1 *, const uschar *, int, uschar *); extern void sha1_mid(sha1 *, const uschar *); extern void sha1_start(sha1 *); -extern int sieve_interpret(uschar *, int, uschar *, address_item **, - uschar **); +extern int sieve_interpret(uschar *, int, uschar *, uschar *, uschar *, + address_item **, uschar **); extern void sigalrm_handler(int); extern void smtp_closedown(uschar *); extern int smtp_connect(host_item *, int, int, uschar *, int, BOOL); diff --git a/src/src/rda.c b/src/src/rda.c index cae283d8c..311f17394 100644 --- a/src/src/rda.c +++ b/src/src/rda.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/rda.c,v 1.4 2005/02/17 11:58:26 ph10 Exp $ */ +/* $Cambridge: exim/src/src/rda.c,v 1.5 2005/04/06 14:40:24 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -333,6 +333,8 @@ Arguments: options the options bits include_directory restrain to this directory sieve_vacation_directory passed to sieve_interpret + sieve_useraddress passed to sieve_interpret + sieve_subaddress passed to sieve_interpret generated where to hang generated addresses error for error messages eblockp for details of skipped syntax errors @@ -348,7 +350,8 @@ Returns: a suitable return for rda_interpret() static int rda_extract(redirect_block *rdata, int options, uschar *include_directory, - uschar *sieve_vacation_directory, address_item **generated, uschar **error, + uschar *sieve_vacation_directory, uschar *sieve_useraddress, + uschar *sieve_subaddress, address_item **generated, uschar **error, error_block **eblockp, int *filtertype) { uschar *data; @@ -407,8 +410,8 @@ if (*filtertype != FILTER_FORWARD) *error = US"Sieve filtering not enabled"; return FF_ERROR; } - frc = sieve_interpret(data, options, sieve_vacation_directory, generated, - error); + frc = sieve_interpret(data, options, sieve_vacation_directory, + sieve_useraddress, sieve_subaddress, generated, error); } expand_forbid = old_expand_forbid; @@ -515,6 +518,8 @@ Arguments: plus ENOTDIR and EACCES handling bits include_directory restrain :include: to this directory sieve_vacation_directory directory passed to sieve_interpret() + sieve_useraddress passed to sieve_interpret + sieve_subaddress passed to sieve_interpret ugid uid/gid to run under - if NULL, no change generated where to hang generated addresses, initially NULL error pointer for error message @@ -541,7 +546,8 @@ Returns: values from extraction function, or FF_NONEXIST: int rda_interpret(redirect_block *rdata, int options, uschar *include_directory, - uschar *sieve_vacation_directory, ugid_block *ugid, address_item **generated, + uschar *sieve_vacation_directory, uschar *sieve_useraddress, + uschar *sieve_subaddress, ugid_block *ugid, address_item **generated, uschar **error, error_block **eblockp, int *filtertype, uschar *rname) { int fd, rc, pfd[2]; @@ -586,7 +592,8 @@ if (!ugid->uid_set || /* Either there's no uid, or */ Ustrstr(data, ":include:") == NULL)) /* and there's no :include: */ { return rda_extract(rdata, options, include_directory, - sieve_vacation_directory, generated, error, eblockp, filtertype); + sieve_vacation_directory, sieve_useraddress, sieve_subaddress, + generated, error, eblockp, filtertype); } /* We need to run the processing code in a sub-process. However, if we can @@ -631,7 +638,8 @@ if ((pid = fork()) == 0) /* Now do the business */ yield = rda_extract(rdata, options, include_directory, - sieve_vacation_directory, generated, error, eblockp, filtertype); + sieve_vacation_directory, sieve_useraddress, sieve_subaddress, generated, + error, eblockp, filtertype); /* Pass back whether it was a filter, and the return code and any overall error text via the pipe. */ diff --git a/src/src/routers/queryprogram.c b/src/src/routers/queryprogram.c index 309695b88..5d7a51fdf 100644 --- a/src/src/routers/queryprogram.c +++ b/src/src/routers/queryprogram.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/routers/queryprogram.c,v 1.2 2005/01/04 10:00:44 ph10 Exp $ */ +/* $Cambridge: exim/src/src/routers/queryprogram.c,v 1.3 2005/04/06 14:40:24 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -356,6 +356,8 @@ if (strcmpic(rword, US"REDIRECT") == 0) RDO_REWRITE, /* rewrite generated addresses */ NULL, /* :include: directory not relevant */ NULL, /* sieve vacation directory not relevant */ + NULL, /* sieve useraddress not relevant */ + NULL, /* sieve subaddress not relevant */ &ugid, /* uid/gid (but not set) */ &generated, /* where to hang the results */ &(addr->message), /* where to put messages */ diff --git a/src/src/routers/redirect.c b/src/src/routers/redirect.c index c0c76322c..0153a4d49 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.8 2005/03/22 15:02:34 ph10 Exp $ */ +/* $Cambridge: exim/src/src/routers/redirect.c,v 1.9 2005/04/06 14:40:24 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -97,6 +97,10 @@ optionlist redirect_router_options[] = { (void *)offsetof(redirect_router_options_block, reply_transport_name) }, { "rewrite", opt_bit | (RDON_REWRITE << 16), (void *)offsetof(redirect_router_options_block, bit_options) }, + { "sieve_subaddress", opt_stringptr, + (void *)offsetof(redirect_router_options_block, sieve_subaddress) }, + { "sieve_useraddress", opt_stringptr, + (void *)offsetof(redirect_router_options_block, sieve_useraddress) }, { "sieve_vacation_directory", opt_stringptr, (void *)offsetof(redirect_router_options_block, sieve_vacation_directory) }, { "skip_syntax_errors", opt_bool, @@ -138,6 +142,8 @@ redirect_router_options_block redirect_router_option_defaults = { NULL, /* include_directory */ NULL, /* pipe_transport_name */ NULL, /* reply_transport_name */ + NULL, /* sieve_subaddress */ + NULL, /* sieve_useraddress */ NULL, /* sieve_vacation_directory */ NULL, /* syntax_errors_text */ NULL, /* syntax_errors_to */ @@ -613,9 +619,10 @@ else } frc = rda_interpret(&redirect, options, ob->include_directory, - ob->sieve_vacation_directory, &ugid, &generated, &(addr->message), - ob->skip_syntax_errors? &eblock : NULL, &filtertype, - string_sprintf("%s router (recipient is %s)", rblock->name, addr->address)); + ob->sieve_vacation_directory, ob->sieve_useraddress, ob->sieve_subaddress, + &ugid, &generated, &(addr->message), ob->skip_syntax_errors? &eblock : NULL, + &filtertype, string_sprintf("%s router (recipient is %s)", rblock->name, + addr->address)); qualify_domain_recipient = save_qualify_domain_recipient; diff --git a/src/src/routers/redirect.h b/src/src/routers/redirect.h index 9fd54ee54..bda2224a8 100644 --- a/src/src/routers/redirect.h +++ b/src/src/routers/redirect.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/routers/redirect.h,v 1.3 2005/01/04 10:00:44 ph10 Exp $ */ +/* $Cambridge: exim/src/src/routers/redirect.h,v 1.4 2005/04/06 14:40:24 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -25,6 +25,8 @@ typedef struct { uschar *include_directory; uschar *pipe_transport_name; uschar *reply_transport_name; + uschar *sieve_subaddress; + uschar *sieve_useraddress; uschar *sieve_vacation_directory; uschar *syntax_errors_text; uschar *syntax_errors_to; diff --git a/src/src/sieve.c b/src/src/sieve.c index abe0d37f3..cc3ad14a2 100644 --- a/src/src/sieve.c +++ b/src/src/sieve.c @@ -1,10 +1,10 @@ -/* $Cambridge: exim/src/src/sieve.c,v 1.8 2005/03/01 10:21:44 ph10 Exp $ */ +/* $Cambridge: exim/src/src/sieve.c,v 1.9 2005/04/06 14:40:24 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) Michael Haardt 2003,2004 */ +/* Copyright (c) Michael Haardt 2003-2005 */ /* See the file NOTICE for conditions of use and distribution. */ /* This code was contributed by Michael Haardt. */ @@ -61,6 +61,8 @@ struct Sieve int vacation_ran; #endif uschar *vacation_directory; + const uschar *subaddress; + const uschar *useraddress; int require_copy; int require_iascii_numeric; }; @@ -1711,10 +1713,8 @@ if (parse_identifier(filter,CUS "address")) case ADDRPART_LOCALPART: part=extracted_addr; part[domain-1]='\0'; break; case ADDRPART_DOMAIN: part=extracted_addr+domain; break; #ifdef SUBADDRESS - case ADDRPART_DETAIL: - part=NULL; + case ADDRPART_DETAIL: part=NULL; break; #endif - break; } *end_addr = saveend; @@ -2019,9 +2019,7 @@ else if (parse_identifier(filter,CUS "envelope")) case ADDRPART_LOCALPART: envelopeExpr=CUS "${local_part:$sender_address}"; break; case ADDRPART_DOMAIN: envelopeExpr=CUS "${domain:$sender_address}"; break; #ifdef SUBADDRESS - case ADDRPART_DETAIL: - envelopeExpr=CUS 0; - break; + case ADDRPART_DETAIL: envelopeExpr=CUS 0; break; #endif } } @@ -2031,8 +2029,8 @@ else if (parse_identifier(filter,CUS "envelope")) { case ADDRPART_ALL: envelopeExpr=CUS "$local_part_prefix$local_part$local_part_suffix@$domain"; break; #ifdef SUBADDRESS - case ADDRPART_USER: envelopeExpr=CUS "$local_part_prefix$local_part"; break; - case ADDRPART_DETAIL: envelopeExpr=CUS "$local_part_suffix"; break; + case ADDRPART_USER: envelopeExpr=filter->useraddress; break; + case ADDRPART_DETAIL: envelopeExpr=filter->subaddress; break; #endif case ADDRPART_LOCALPART: envelopeExpr=CUS "$local_part_prefix$local_part$local_part_suffix"; break; case ADDRPART_DOMAIN: envelopeExpr=CUS "$domain"; break; @@ -2724,6 +2722,8 @@ Arguments: options controls whether various special things are allowed, and requests special actions (not currently used) sieve_vacation_directory where to store vacation "once" files + useraddress string expression for :user part of address + subaddress string expression for :subaddress part of address generated where to hang newly-generated addresses error where to pass back an error text @@ -2737,7 +2737,7 @@ Returns: FF_DELIVERED success, a significant action was taken int sieve_interpret(uschar *filter, int options, uschar *vacation_directory, - address_item **generated, uschar **error) + uschar *useraddress, uschar *subaddress, address_item **generated, uschar **error) { struct Sieve sieve; int r; @@ -2763,6 +2763,9 @@ else } } +sieve.useraddress = useraddress == NULL ? CUS "$local_part_prefix$local_part$local_part_suffix" : useraddress; +sieve.subaddress = subaddress; + #ifdef COMPILE_SYNTAX_CHECKER if (parse_start(&sieve,0,generated)==1) #else -- 2.25.1