From ddaf34e7b7fe02cbbb99a6bf515eb4298d6b2d4b Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 6 Aug 2023 14:50:36 +0100 Subject: [PATCH] New $recipients_list. Bug 2726 --- doc/doc-docbook/spec.xfpt | 25 ++++++++++++++++++------- doc/doc-txt/NewStuff | 2 ++ src/src/expand.c | 26 ++++++++++++++++++++++++-- test/confs/0636 | 23 +++++++++++++++++++++++ test/log/0636 | 3 +++ test/scripts/0000-Basic/0636 | 12 ++++++++++++ 6 files changed, 82 insertions(+), 9 deletions(-) create mode 100644 test/confs/0636 create mode 100644 test/log/0636 create mode 100644 test/scripts/0000-Basic/0636 diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index f35ebf675..cf670ba07 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -11802,10 +11802,11 @@ all items in the list, the overall condition is true. .endlist Note that negation of &*forany*& means that the condition must be false for all items for the overall condition to succeed, and negation of &*forall*& means -that the condition must be false for at least one item. In this example, the -list separator is changed to a comma: +that the condition must be false for at least one item. + +Example: .code -${if forany{<, $recipients}{match{$item}{^user3@}}{yes}{no}} +${if forany{$recipients_list}{match{$item}{^user3@}}{yes}{no}} .endd The value of &$item$& is saved and restored while &%forany%& or &%forall%& is being processed, to enable these expansion items to be nested. @@ -13404,10 +13405,20 @@ The main use of this variable is expected to be to distinguish between rejections of MAIL and rejections of RCPT. .tvar &$recipients$& -This variable contains a list of envelope recipients for a message. A comma and -a space separate the addresses in the replacement text. However, the variable -is not generally available, to prevent exposure of Bcc recipients in -unprivileged users' filter files. You can use &$recipients$& only in these +.new +.tvar &$recipients_list$& +These variables both contain the envelope recipients for a message. + +The first uses a comma and a space separate the addresses in the replacement text. +&*Note*&: an address can legitimately contain a comma; +this variable is not intended for further processing. + +The second is a proper Exim list; colon-separated. +.wen + +However, the variables +are not generally available, to prevent exposure of Bcc recipients in +unprivileged users' filter files. You can use either of them only in these cases: .olist diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 991bcf741..3c96da6f8 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -33,6 +33,8 @@ Version 4.97 12. The ACL remove_header modifier can take a pattern. + 13. Variable $recipients_list, a properly-quoted exim list. + Version 4.96 ------------ diff --git a/src/src/expand.c b/src/src/expand.c index 259d463a4..ca954ebc2 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -475,6 +475,7 @@ typedef struct { typedef uschar * stringptr_fn_t(void); static uschar * fn_recipients(void); +static uschar * fn_recipients_list(void); static uschar * fn_queue_size(void); /* This table must be kept in alphabetical order. */ @@ -694,6 +695,7 @@ static var_entry var_table[] = { { "recipient_verify_failure",vtype_stringptr,&recipient_verify_failure }, { "recipients", vtype_string_func, (void *) &fn_recipients }, { "recipients_count", vtype_int, &recipients_count }, + { "recipients_list", vtype_string_func, (void *) &fn_recipients_list }, { "regex_cachesize", vtype_int, ®ex_cachesize },/* undocumented; devel observability */ #ifdef WITH_CONTENT_SCAN { "regex_match_string", vtype_stringptr, ®ex_match_string }, @@ -839,6 +841,7 @@ uschar * fn_arc_domains(void) {return NULL;} uschar * fn_hdrs_added(void) {return NULL;} uschar * fn_queue_size(void) {return NULL;} uschar * fn_recipients(void) {return NULL;} +uschar * fn_recipients_list(void) {return NULL;} uschar * sender_helo_verified_boolstr(void) {return NULL;} uschar * smtp_cmd_hist(void) {return NULL;} @@ -1800,7 +1803,9 @@ return g; *************************************************/ /* A recipients list is available only during system message filtering, during ACL processing after DATA, and while expanding pipe commands -generated from a system filter, but not elsewhere. */ +generated from a system filter, but not elsewhere. Note that this does +not check for comman in the elements, and uses comma-space as seperator - +so cannot be used as an exim list as-is. */ static uschar * fn_recipients(void) @@ -1815,6 +1820,23 @@ for (int i = 0; i < recipients_count; i++) s = recipients_list[i].address; g = string_append2_listele_n(g, US", ", s, Ustrlen(s)); } +gstring_release_unused(g); +return string_from_gstring(g); +} + +/* Similar, but as a properly-quoted exim list */ + + +static uschar * +fn_recipients_list(void) +{ +gstring * g = NULL; + +if (!f.enable_dollar_recipients) return NULL; + +for (int i = 0; i < recipients_count; i++) + g = string_append_listele(g, ':', recipients_list[i].address); +gstring_release_unused(g); return string_from_gstring(g); } @@ -2119,7 +2141,7 @@ switch (vp->type) case vtype_string_func: { stringptr_fn_t * fn = (stringptr_fn_t *) val; - uschar* s = fn(); + uschar * s = fn(); return s ? s : US""; } diff --git a/test/confs/0636 b/test/confs/0636 new file mode 100644 index 000000000..b80722525 --- /dev/null +++ b/test/confs/0636 @@ -0,0 +1,23 @@ +# Exim test configuration 0636 + +.include DIR/aux-var/std_conf_prefix + + +# ----- Main settings ----- + +domainlist local_domains = @ + +acl_smtp_rcpt = accept +acl_smtp_data = check_data +queue_only + + +# ----- ACL ----- + +begin acl + +check_data: + accept logwrite = \$recipients: "$recipients" + logwrite = \$recipients_list: "$recipients_list" + +# End diff --git a/test/log/0636 b/test/log/0636 new file mode 100644 index 000000000..e52cd68d2 --- /dev/null +++ b/test/log/0636 @@ -0,0 +1,3 @@ +1999-03-02 09:44:33 10HmaX-000000005vi-0000 $recipients: "a@test.ex, b@test.ex" +1999-03-02 09:44:33 10HmaX-000000005vi-0000 $recipients_list: "a@test.ex:b@test.ex" +1999-03-02 09:44:33 10HmaX-000000005vi-0000 <= CALLER@the.local.host.name U=CALLER P=local-smtp S=sss diff --git a/test/scripts/0000-Basic/0636 b/test/scripts/0000-Basic/0636 new file mode 100644 index 000000000..8a1f7f293 --- /dev/null +++ b/test/scripts/0000-Basic/0636 @@ -0,0 +1,12 @@ +# $recipients_list +exim -bs +helo test +mail from:someone@some.domain +rcpt to: +rcpt to: +data +. +quit +**** +no_msglog_check +no_stdout_check -- 2.30.2