Use custom variables for ACL args, up to nine. Add an arg-count variable.
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 12 Jun 2012 21:50:52 +0000 (22:50 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 12 Jun 2012 21:50:52 +0000 (22:50 +0100)
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/expand.c
src/src/globals.c
src/src/globals.h
test/confs/0002
test/scripts/0000-Basic/0002
test/stdout/0002

index cde80a1..29aacf6 100644 (file)
@@ -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
-&<<CHAPACL>>&) 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 &<<CHAPACL>>&) 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,
index 4a22159..504c3f5 100644 (file)
@@ -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
 -----------------
index b13a5a0..3c5c491 100644 (file)
@@ -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
 ------------
index 16d5d74..913a808 100644 (file)
@@ -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"<none>");
+        debug_printf("expanding: acl: %s  arg: %s%s\n",
+         sub[0],
+         acl_narg>0 ? sub[1]   : US"<none>",
+         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:
index 3ad38d3..b6db925 100644 (file)
@@ -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
index e910dbe..639d88f 100644 (file)
@@ -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 */
index 317c4a2..df65e2c 100644 (file)
@@ -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
index d567f84..62a0a1f 100644 (file)
@@ -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}}
index 377fe02..edf18d1 100644 (file)
 > 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