From 525239c16e35d7bf893e0e2232f4c4c4a7c75447 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 12 Jun 2012 22:50:52 +0100 Subject: [PATCH] Use custom variables for ACL args, up to nine. Add an arg-count variable. --- doc/doc-docbook/spec.xfpt | 12 +++++++----- doc/doc-txt/ChangeLog | 2 +- doc/doc-txt/NewStuff | 7 ++++--- src/src/expand.c | 28 +++++++++++++++++++++++----- src/src/globals.c | 3 +++ src/src/globals.h | 2 ++ test/confs/0002 | 2 +- test/scripts/0000-Basic/0002 | 2 ++ test/stdout/0002 | 8 +++++--- 9 files changed, 48 insertions(+), 18 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index cde80a17c..29aacf61c 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -8759,13 +8759,15 @@ This item inserts &"basic"& header lines. It is described with the &%header%& expansion item below. -.vitem "&*${acl{*&<&'name'&>&*}{*&<&'string'&>&*}}*&" +.vitem "&*${acl{*&<&'name'&>&*}{*&<&'arg'&>&*}...}*&" .cindex "expansion" "calling an acl" .cindex "&%acl%&" "call from expansion" -The name and <&'string'&> are first expanded separately. The expanded -<&'string'&> is assigned to the &$address_data$& variable. If {<&'string'&>} -is omitted, &$address_data$& is made empty. The named ACL (see chapter -&<>&) is called and may use &$address_data$&. If the ACL sets +The name and zero to nine argument strings are first expanded separately. The expanded +arguments are assigned to the variables &$acl_arg1$& to &$acl_arg9$& in order. +Any used are made empty. The variable &$acl_narg$& is set to the number of +arguments. The named ACL (see chapter &<>&) is called +and may use the variables; if another acl expansion is used the values +are overwritten. If the ACL sets a value using a "message =" modifier and returns accept, the value becomes the result of the expansion. If no message was set but the ACL returned accept, or if the ACL returned defer, diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 4a2215956..504c3f551 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -44,7 +44,7 @@ NM/01 Bugzilla 1197 - Spec typo JH/03 Add expansion operators ${listnamed:name} and ${listcount:string} -JH/04 Add expansion item ${acl {name}{argument}} +JH/04 Add expansion item ${acl {name}{arg}...} Exim version 4.80 ----------------- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index b13a5a0f2..3c5c4913b 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -87,9 +87,10 @@ Version 4.81 8. New expansion operators ${listnamed:name} to get the content of a named list and ${listcount:string} to count the items in a list. - 9. New expansion item ${acl {name}{argument}} to call an ACL. The argument can - be accessed by the ACL in $address_data. The expansion result is set by - a "message =" modifier and an "accept" return from the ACL. + 9. New expansion item ${acl {name}{arg}...} to call an ACL. The argument can + be accessed by the ACL in $acl_arg1 to $acl_arg9. $acl_narg will be the + number of arguments. The expansion result is set by a "message =" modifier + and an "accept" return from the ACL. Version 4.80 ------------ diff --git a/src/src/expand.c b/src/src/expand.c index 16d5d74ab..913a808b8 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -392,6 +392,16 @@ enum { static var_entry var_table[] = { /* WARNING: Do not invent variables whose names start acl_c or acl_m because they will be confused with user-creatable ACL variables. */ + { "acl_arg1", vtype_stringptr, &acl_arg[0] }, + { "acl_arg2", vtype_stringptr, &acl_arg[1] }, + { "acl_arg3", vtype_stringptr, &acl_arg[2] }, + { "acl_arg4", vtype_stringptr, &acl_arg[3] }, + { "acl_arg5", vtype_stringptr, &acl_arg[4] }, + { "acl_arg6", vtype_stringptr, &acl_arg[5] }, + { "acl_arg7", vtype_stringptr, &acl_arg[6] }, + { "acl_arg8", vtype_stringptr, &acl_arg[7] }, + { "acl_arg9", vtype_stringptr, &acl_arg[8] }, + { "acl_narg", vtype_int, &acl_narg }, { "acl_verify_message", vtype_stringptr, &acl_verify_message }, { "address_data", vtype_stringptr, &deliver_address_data }, { "address_file", vtype_stringptr, &address_file }, @@ -3643,7 +3653,7 @@ while (*s != 0) switch(item_type) { - /* Call an ACL from an expansion. We feed data in via $address_data. + /* Call an ACL from an expansion. We feed data in via $acl_arg1 - $acl_arg9. If the ACL returns acceptance we return content set by "message =" There is currently no limit on recursion; this would have us call acl_check_internal() directly and get a current level from somewhere. @@ -3652,11 +3662,11 @@ while (*s != 0) case EITEM_ACL: { int rc; - uschar *sub[2]; + uschar *sub[10]; /* name + arg1-arg9, must match number of acl_arg[] */ uschar *new_yield; uschar *user_msg; uschar *log_msg; - switch(read_subs(sub, 2, 1, &s, skipping, TRUE, US"acl")) + switch(read_subs(sub, 10, 1, &s, skipping, TRUE, US"acl")) { case 1: goto EXPAND_FAILED_CURLY; case 2: @@ -3664,10 +3674,18 @@ while (*s != 0) } if (skipping) continue; + for (rc = 1; rc < sizeof(sub)/sizeof(*sub) && sub[rc]; rc++) + acl_arg[rc-1] = sub[rc]; + acl_narg = rc-1; + while (rc < sizeof(sub)/sizeof(*sub)) + acl_arg[rc++ - 1] = NULL; + DEBUG(D_expand) - debug_printf("expanding: acl: %s arg: %s\n", sub[0], sub[1]?sub[1]:US""); + debug_printf("expanding: acl: %s arg: %s%s\n", + sub[0], + acl_narg>0 ? sub[1] : US"", + acl_narg>1 ? " +more" : ""); - deliver_address_data = sub[1]; switch(rc = acl_check(ACL_WHERE_EXPANSION, NULL, sub[0], &user_msg, &log_msg)) { case OK: diff --git a/src/src/globals.c b/src/src/globals.c index 3ad38d39d..b6db9251d 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -186,6 +186,9 @@ int address_expansions_count = sizeof(address_expansions)/sizeof(uschar **); header_line *acl_added_headers = NULL; tree_node *acl_anchor = NULL; +uschar *acl_arg[9] = {NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL}; +int acl_narg = 0; uschar *acl_not_smtp = NULL; #ifdef WITH_CONTENT_SCAN diff --git a/src/src/globals.h b/src/src/globals.h index e910dbe1b..639d88f31 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -134,6 +134,8 @@ extern uschar **address_expansions[ADDRESS_EXPANSIONS_COUNT]; extern BOOL accept_8bitmime; /* Allow *BITMIME incoming */ extern header_line *acl_added_headers; /* Headers added by an ACL */ extern tree_node *acl_anchor; /* Tree of named ACLs */ +extern uschar *acl_arg[9]; /* Argument to ACL call */ +extern int acl_narg; /* Number of arguments to ACL call */ extern uschar *acl_not_smtp; /* ACL run for non-SMTP messages */ #ifdef WITH_CONTENT_SCAN extern uschar *acl_not_smtp_mime; /* For MIME parts of ditto */ diff --git a/test/confs/0002 b/test/confs/0002 index 317c4a27d..df65e2c30 100644 --- a/test/confs/0002 +++ b/test/confs/0002 @@ -45,7 +45,7 @@ check_data: deny message = reply_address=<$reply_address> a_ret: - accept message = [$address_data] + accept message = ($acl_narg) [$acl_arg1] [$acl_arg2] a_none: accept diff --git a/test/scripts/0000-Basic/0002 b/test/scripts/0000-Basic/0002 index d567f8486..62a0a1f56 100644 --- a/test/scripts/0000-Basic/0002 +++ b/test/scripts/0000-Basic/0002 @@ -91,6 +91,8 @@ acl: ${acl} acl: ${acl {a_bad}} acl: ${acl {a_ret}} acl: ${acl {a_ret}{person@dom.ain}} +acl: ${acl {a_ret}{firstarg}{secondarg}} +acl: ${acl {a_ret}{arg with spaces}} acl: ${acl {a_none}} acl: ${acl {a_none}{person@dom.ain}} acl: ${acl {a_deny}} diff --git a/test/stdout/0002 b/test/stdout/0002 index 377fe02cd..edf18d18c 100644 --- a/test/stdout/0002 +++ b/test/stdout/0002 @@ -81,13 +81,15 @@ > Failed: missing or misplaced { or } > Failed: missing or misplaced { or } > Failed: acl "a_bad" did not accept -> acl: [] -> acl: [person@dom.ain] +> acl: (0) [] [] +> acl: (1) [person@dom.ain] [] +> acl: (2) [firstarg] [secondarg] +> acl: (1) [arg with spaces] [] > acl: > acl: > Failed: acl "a_deny" did not accept > Failed: acl "a_deny" did not accept -> acl: [1] [2] [3] [4] +> acl: (1) [1] [] (1) [2] [] (1) [3] [] (1) [4] [] > > addrss: local-part@dom.ain > addrss: local-part@dom.ain -- 2.30.2