From 96e1245c1aad58dff560f929fd90972933a65341 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 22 Jul 2024 20:28:12 +0100 Subject: [PATCH] Move control data for sieve into struct --- src/src/deliver.c | 5 +-- src/src/filtertest.c | 2 +- src/src/functions.h | 9 +++-- src/src/rda.c | 45 ++++++++++--------------- src/src/routers/queryprogram.c | 5 +-- src/src/routers/redirect.c | 60 ++++++++++------------------------ src/src/routers/redirect.h | 5 ++- src/src/sieve.c | 31 +++++++++--------- src/src/structs.h | 9 +++++ 9 files changed, 70 insertions(+), 101 deletions(-) diff --git a/src/src/deliver.c b/src/src/deliver.c index 8aeedc755..64a53c7ba 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -7002,10 +7002,7 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) RDO_REALLOG | RDO_REWRITE, NULL, /* No :include: restriction (not used in filter) */ - NULL, /* No sieve vacation directory (not sieve!) */ - NULL, /* No sieve enotify mailto owner (not sieve!) */ - NULL, /* No sieve user address (not sieve!) */ - NULL, /* No sieve subaddress (not sieve!) */ + NULL, /* No sieve info (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 60a853dcf..a58fe5e82 100644 --- a/src/src/filtertest.c +++ b/src/src/filtertest.c @@ -273,7 +273,7 @@ if (is_system) else { yield = filter_type == FILTER_SIEVE - ? sieve_interpret(filebuf, RDO_REWRITE, NULL, NULL, NULL, NULL, &generated, &error) + ? sieve_interpret(filebuf, RDO_REWRITE, NULL, &generated, &error) : filter_interpret(filebuf, RDO_REWRITE, &generated, &error); } diff --git a/src/src/functions.h b/src/src/functions.h index 21214d15b..4bd6ff51b 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -420,9 +420,9 @@ extern void queue_run(qrunner *, const uschar *, const uschar *, BOOL); extern int random_number(int); extern const uschar *rc_to_string(int); -extern int rda_interpret(redirect_block *, int, const uschar *, const uschar *, - const uschar *, const uschar *, const uschar *, const ugid_block *, address_item **, - uschar **, error_block **, int *, const uschar *); +extern int rda_interpret(redirect_block *, int, const uschar *, + const sieve_block *, const ugid_block *, address_item **, + uschar **, error_block **, int *, const uschar *); extern int rda_is_filter(const uschar *); extern BOOL readconf_depends(driver_instance *, uschar *); extern void readconf_driver_init(uschar *, driver_instance **, @@ -504,8 +504,7 @@ extern void set_process_info(const char *, ...) PRINTF_FUNCTION(1,2); extern void sha1_end(hctx *, const uschar *, int, uschar *); extern void sha1_mid(hctx *, const uschar *); extern void sha1_start(hctx *); -extern int sieve_interpret(const uschar *, int, const uschar *, - const uschar *, const uschar *, const uschar *, +extern int sieve_interpret(const uschar *, int, const sieve_block *, address_item **, uschar **); extern void sigalrm_handler(int); extern void single_queue_run(qrunner *, const uschar *, const uschar *); diff --git a/src/src/rda.c b/src/src/rda.c index 776805ca4..8289ab084 100644 --- a/src/src/rda.c +++ b/src/src/rda.c @@ -322,10 +322,7 @@ Arguments: rdata the redirection block options the options bits include_directory restrain to this directory - sieve_vacation_directory passed to sieve_interpret - sieve_enotify_mailto_owner passed to sieve_interpret - sieve_useraddress passed to sieve_interpret - sieve_subaddress passed to sieve_interpret + sieve passed to sieve_interpret generated where to hang generated addresses error for error messages eblockp for details of skipped syntax errors @@ -341,9 +338,8 @@ Returns: a suitable return for rda_interpret() static int rda_extract(const redirect_block * rdata, int options, - const uschar * include_directory, const uschar * sieve_vacation_directory, - const uschar * sieve_enotify_mailto_owner, const uschar * sieve_useraddress, - const uschar * sieve_subaddress, address_item ** generated, uschar ** error, + const uschar * include_directory, const sieve_block * sieve, + address_item ** generated, uschar ** error, error_block ** eblockp, int * filtertype) { const uschar * data; @@ -387,7 +383,7 @@ if (*filtertype != FILTER_FORWARD) if (*filtertype == FILTER_EXIM) { - if ((options & RDO_EXIM_FILTER) != 0) + if (options & RDO_EXIM_FILTER) { *error = US"Exim filtering not enabled"; return FF_ERROR; @@ -401,9 +397,7 @@ if (*filtertype != FILTER_FORWARD) *error = US"Sieve filtering not enabled"; return FF_ERROR; } - frc = sieve_interpret(data, options, sieve_vacation_directory, - sieve_enotify_mailto_owner, sieve_useraddress, sieve_subaddress, - generated, error); + frc = sieve_interpret(data, options, sieve, generated, error); } expand_forbid = old_expand_forbid; @@ -513,10 +507,7 @@ Arguments: options options to pass to the extraction functions, plus ENOTDIR and EACCES handling bits include_directory restrain :include: to this directory - sieve_vacation_directory directory passed to sieve_interpret - sieve_enotify_mailto_owner passed to sieve_interpret - sieve_useraddress passed to sieve_interpret - sieve_subaddress passed to sieve_interpret + sieve 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 @@ -543,9 +534,8 @@ Returns: values from extraction function, or FF_NONEXIST: int rda_interpret(redirect_block * rdata, int options, - const uschar * include_directory, const uschar * sieve_vacation_directory, - const uschar * sieve_enotify_mailto_owner, const uschar * sieve_useraddress, - const uschar * sieve_subaddress, const ugid_block * ugid, address_item ** generated, + const uschar * include_directory, const sieve_block * sieve, + const ugid_block * ugid, address_item ** generated, uschar ** error, error_block ** eblockp, int * filtertype, const uschar * rname) { int fd, rc, pfd[2]; @@ -584,13 +574,13 @@ with #Exim filter or #Sieve filter, and does not contain :include:, do all the work in this process. Note that for a system filter, we always have a file, so the work is done in this process only if no user is supplied. */ -if (!ugid->uid_set || /* Either there's no uid, or */ - (!rdata->isfile && /* We've got the data, and */ - rda_is_filter(data) == FILTER_FORWARD && /* It's not a filter script, */ - Ustrstr(data, ":include:") == NULL)) /* and there's no :include: */ - return rda_extract(rdata, options, include_directory, - sieve_vacation_directory, sieve_enotify_mailto_owner, sieve_useraddress, - sieve_subaddress, generated, error, eblockp, filtertype); +if ( !ugid->uid_set /* Either there's no uid, or */ + || ( !rdata->isfile /* We've got the data, and */ + && rda_is_filter(data) == FILTER_FORWARD /* It's not a filter script, */ + && Ustrstr(data, ":include:") == NULL /* and there's no :include: */ + ) ) + return rda_extract(rdata, options, include_directory, sieve, + generated, error, eblockp, filtertype); /* We need to run the processing code in a sub-process. However, if we can determine the non-existence of a file first, we can decline without having to @@ -642,9 +632,8 @@ if ((pid = exim_fork(US"router-interpret")) == 0) /* Now do the business */ - yield = rda_extract(rdata, options, include_directory, - sieve_vacation_directory, sieve_enotify_mailto_owner, sieve_useraddress, - sieve_subaddress, generated, error, eblockp, filtertype); + yield = rda_extract(rdata, options, include_directory, sieve, + 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 267a8ec5f..235d0e769 100644 --- a/src/src/routers/queryprogram.c +++ b/src/src/routers/queryprogram.c @@ -388,10 +388,7 @@ if (strcmpic(rword, US"REDIRECT") == 0) RDO_INCLUDE | /* forbid :include: */ RDO_REWRITE, /* rewrite generated addresses */ NULL, /* :include: directory not relevant */ - NULL, /* sieve vacation directory not relevant */ - NULL, /* sieve enotify mailto owner not relevant */ - NULL, /* sieve useraddress not relevant */ - NULL, /* sieve subaddress not relevant */ + NULL, /* sieve info 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 e1ee8bc33..08b7726b7 100644 --- a/src/src/routers/redirect.c +++ b/src/src/routers/redirect.c @@ -92,8 +92,8 @@ optionlist redirect_router_options[] = { LOFF(bit_options) }, { "sieve_enotify_mailto_owner", opt_stringptr, LOFF(sieve_enotify_mailto_owner) }, - { "sieve_subaddress", opt_stringptr, LOFF(sieve_subaddress) }, - { "sieve_useraddress", opt_stringptr, LOFF(sieve_useraddress) }, + { "sieve_subaddress", opt_stringptr, LOFF(sieve_subaddress) }, + { "sieve_useraddress", opt_stringptr, LOFF(sieve_useraddress) }, { "sieve_vacation_directory", opt_stringptr, LOFF(sieve_vacation_directory) }, { "skip_syntax_errors", opt_bool, LOFF(skip_syntax_errors) }, { "syntax_errors_text", opt_stringptr, LOFF(syntax_errors_text) }, @@ -121,43 +121,14 @@ int redirect_router_entry(router_instance *rblock, address_item *addr, -/* Default private options block for the redirect router. */ +/* Default private options block for the redirect router. +Unlisted elements are 0/NULL/FALSE */ redirect_router_options_block redirect_router_option_defaults = { - NULL, /* directory_transport */ - NULL, /* file_transport */ - NULL, /* pipe_transport */ - NULL, /* reply_transport */ - NULL, /* data */ - NULL, /* directory_transport_name */ - NULL, /* file */ - NULL, /* file_dir */ - NULL, /* file_transport_name */ - NULL, /* include_directory */ - NULL, /* pipe_transport_name */ - NULL, /* reply_transport_name */ - NULL, /* sieve_subaddress */ - NULL, /* sieve_useraddress */ - NULL, /* sieve_vacation_directory */ - NULL, /* sieve_enotify_mailto_owner */ - NULL, /* syntax_errors_text */ - NULL, /* syntax_errors_to */ - NULL, /* qualify_domain */ - NULL, /* owners */ - NULL, /* owngroups */ - 022, /* modemask */ - RDO_REWRITE | RDO_PREPEND_HOME, /* bit_options */ - FALSE, /* check_ancestor */ - TRUE_UNSET, /* check_owner */ - TRUE_UNSET, /* check_group */ - FALSE, /* forbid_file */ - FALSE, /* forbid_filter_reply */ - FALSE, /* forbid_pipe */ - FALSE, /* forbid_smtp_code */ - FALSE, /* hide_child_in_errmsg */ - FALSE, /* one_time */ - FALSE, /* qualify_preserve_domain */ - FALSE /* skip_syntax_errors */ + .modemask = 022, + .bit_options = RDO_REWRITE | RDO_PREPEND_HOME, + .check_owner = TRUE_UNSET, + .check_group = TRUE_UNSET, }; @@ -515,6 +486,7 @@ address_item_propagated addr_prop; error_block *eblock = NULL; ugid_block ugid; redirect_block redirect; +sieve_block sieve; int filtertype = FILTER_UNSET; int yield = OK; int options = ob->bit_options; @@ -594,11 +566,15 @@ redirect.pw = pw; redirect.string = (redirect.isfile = (ob->file != NULL)) ? ob->file : ob->data; -frc = rda_interpret(&redirect, options, ob->include_directory, - ob->sieve_vacation_directory, ob->sieve_enotify_mailto_owner, - 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)); +sieve.vacation_dir = ob->sieve_vacation_directory; +sieve.enotify_mailto_owner = ob->sieve_enotify_mailto_owner; +sieve.useraddress = ob->sieve_useraddress; +sieve.subaddress = ob->sieve_subaddress; + +frc = rda_interpret(&redirect, options, ob->include_directory, &sieve, &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 8aeb892cb..86c24d80c 100644 --- a/src/src/routers/redirect.h +++ b/src/src/routers/redirect.h @@ -25,10 +25,13 @@ typedef struct { uschar *include_directory; uschar *pipe_transport_name; uschar *reply_transport_name; + + uschar *sieve_enotify_mailto_owner; + uschar *sieve_inbox; uschar *sieve_subaddress; uschar *sieve_useraddress; uschar *sieve_vacation_directory; - uschar *sieve_enotify_mailto_owner; + uschar *syntax_errors_text; uschar *syntax_errors_to; uschar *qualify_domain; diff --git a/src/src/sieve.c b/src/src/sieve.c index 798dac827..db37f44fa 100644 --- a/src/src/sieve.c +++ b/src/src/sieve.c @@ -3508,10 +3508,11 @@ Arguments: filter points to the entire file, read into store as a single string options controls whether various special things are allowed, and requests special actions (not currently used) - vacation_directory where to store vacation "once" files - enotify_mailto_owner owner of mailto notifications - useraddress string expression for :user part of address - subaddress string expression for :subaddress part of address + sieve + vacation_directory where to store vacation "once" files + enotify_mailto_owner owner of mailto notifications + 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 @@ -3524,9 +3525,7 @@ Returns: FF_DELIVERED success, a significant action was taken */ int -sieve_interpret(const uschar * filter, int options, - const uschar * vacation_directory, const uschar * enotify_mailto_owner, - const uschar * useraddress, const uschar * subaddress, +sieve_interpret(const uschar * filter, int options, const sieve_block * sb, address_item ** generated, uschar ** error) { struct Sieve sieve; @@ -3537,29 +3536,29 @@ DEBUG(D_route) debug_printf_indent("Sieve: start of processing\n"); expand_level++; sieve.filter = filter; -if (!vacation_directory) +if (!sb || !sb->vacation_dir) sieve.vacation_directory = NULL; -else if (!(sieve.vacation_directory = expand_cstring(vacation_directory))) +else if (!(sieve.vacation_directory = expand_cstring(sb->vacation_dir))) { *error = string_sprintf("failed to expand \"%s\" " - "(sieve_vacation_directory): %s", vacation_directory, + "(sieve_vacation_directory): %s", sb->vacation_dir, expand_string_message); return FF_ERROR; } -if (!enotify_mailto_owner) +if (!sb || !sb->enotify_mailto_owner) sieve.enotify_mailto_owner = NULL; -else if (!(sieve.enotify_mailto_owner = expand_cstring(enotify_mailto_owner))) +else if (!(sieve.enotify_mailto_owner = expand_cstring(sb->enotify_mailto_owner))) { *error = string_sprintf("failed to expand \"%s\" " - "(sieve_enotify_mailto_owner): %s", enotify_mailto_owner, + "(sieve_enotify_mailto_owner): %s", sb->enotify_mailto_owner, expand_string_message); return FF_ERROR; } -sieve.useraddress = useraddress - ? useraddress : CUS "$local_part_prefix$local_part$local_part_suffix"; -sieve.subaddress = subaddress; +sieve.useraddress = sb && sb->useraddress + ? sb->useraddress : CUS "$local_part_prefix$local_part$local_part_suffix"; +sieve.subaddress = sb ? sb->subaddress : NULL; #ifdef COMPILE_SYNTAX_CHECKER if (parse_start(&sieve, 0, generated) == 1) diff --git a/src/src/structs.h b/src/src/structs.h index 3c85f6ae5..c11a5c6b1 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -893,6 +893,15 @@ typedef struct redirect_block { BOOL check_group; /* TRUE, FALSE, or TRUE_UNSET */ } redirect_block; +/* Sieve control data */ + +typedef struct sieve_block { + const uschar * vacation_dir; + const uschar * enotify_mailto_owner; + const uschar * useraddress; + const uschar * subaddress; +} sieve_block; + /* Structure for passing arguments to check_host() */ typedef struct check_host_block { -- 2.30.2