This item inserts &"basic"& header lines. It is described with the &%header%&
expansion item below.
+
+.vitem "&*${acl{*&<&'name'&>&*}{*&<&'string'&>&*}}*&"
+.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
+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,
+the value is an empty string. Otherwise the expansion fails.
+
+
.vitem "&*${dlfunc{*&<&'file'&>&*}{*&<&'function'&>&*}{*&<&'arg'&>&*}&&&
{*&<&'arg'&>&*}...}*&"
.cindex &%dlfunc%&
JH/03 Add expansion operators ${listnamed:name} and ${listcount:string}
+JH/04 Add expansion item ${acl {name}{argument}}
+
Exim version 4.80
-----------------
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.
+
Version 4.80
------------
alphabetical order. */
static uschar *item_table[] = {
+ US"acl",
US"dlfunc",
US"extract",
US"filter",
US"tr" };
enum {
+ EITEM_ACL,
EITEM_DLFUNC,
EITEM_EXTRACT,
EITEM_FILTER,
switch(item_type)
{
+ /* Call an ACL from an expansion. We feed data in via $address_data.
+ 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.
+ */
+
+ case EITEM_ACL:
+ {
+ int rc;
+ uschar *sub[2];
+ uschar *new_yield;
+ uschar *user_msg;
+ uschar *log_msg;
+ switch(read_subs(sub, 2, 1, &s, skipping, TRUE, US"acl"))
+ {
+ case 1: goto EXPAND_FAILED_CURLY;
+ case 2:
+ case 3: goto EXPAND_FAILED;
+ }
+ if (skipping) continue;
+
+ DEBUG(D_expand)
+ debug_printf("expanding: acl: %s arg: %s\n", sub[0], sub[1]?sub[1]:US"<none>");
+
+ deliver_address_data = sub[1];
+ switch(rc = acl_check(ACL_WHERE_EXPANSION, NULL, sub[0], &user_msg, &log_msg))
+ {
+ case OK:
+ if (user_msg)
+ yield = string_cat(yield, &size, &ptr, user_msg, Ustrlen(user_msg));
+ continue;
+ case DEFER:
+ continue;
+ default:
+ expand_string_message = string_sprintf("acl \"%s\" did not accept", sub[0]);
+ goto EXPAND_FAILED;
+ }
+ }
+
/* Handle conditionals - preserve the values of the numerical expansion
variables in case they get changed by a regular expression match in the
condition. If not, they retain their external settings. At the end
goto EXPAND_FAILED;
}
- if (skipping) continue;
list = ((namedlist_block *)(t->data.ptr))->string;
while ((item = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
uschar *acl_not_smtp_mime = NULL;
#endif
uschar *acl_not_smtp_start = NULL;
-
uschar *acl_smtp_auth = NULL;
uschar *acl_smtp_connect = NULL;
uschar *acl_smtp_data = NULL;
US"NOTQUIT",
US"QUIT",
US"STARTTLS",
- US"VRFY"
+ US"VRFY",
+ US"expansion"
};
uschar *acl_wherecodes[] = { US"550", /* RCPT */
US"0", /* NOTQUIT; not relevant */
US"0", /* QUIT; not relevant */
US"550", /* STARTTLS */
- US"252" /* VRFY */
+ US"252", /* VRFY */
+ US"0" /* unknown; not relevant */
};
BOOL active_local_from_check = FALSE;
ACL_WHERE_NOTQUIT,
ACL_WHERE_QUIT,
ACL_WHERE_STARTTLS,
- ACL_WHERE_VRFY
+ ACL_WHERE_VRFY,
+
+ ACL_WHERE_EXPANSION /* Currently used by a ${acl:name} expansion */
};
/* Situations for spool_write_header() */
warn logwrite = Subject is: "$h_subject:"
deny message = reply_address=<$reply_address>
+a_ret:
+ accept message = [$address_data]
+
+a_none:
+ accept
+
+a_deny:
+
# End
# Operators
+acl: ${acl
+acl: ${acl}
+acl: ${acl {a_bad}}
+acl: ${acl {a_ret}}
+acl: ${acl {a_ret}{person@dom.ain}}
+acl: ${acl {a_none}}
+acl: ${acl {a_none}{person@dom.ain}}
+acl: ${acl {a_deny}}
+acl: ${acl {a_deny}{person@dom.ain}}
+acl: ${reduce {1:2:3:4} {} {$value ${acl {a_ret}{$item}}}}
+
addrss: ${address:local-part@dom.ain}
addrss: ${address:Exim Person <local-part@dom.ain> (that's me)}
domain: ${domain:local-part@dom.ain}
>
> # Operators
>
+> Failed: missing or misplaced { or }
+> Failed: missing or misplaced { or }
+> Failed: acl "a_bad" did not accept
+> acl: []
+> acl: [person@dom.ain]
+> acl:
+> acl:
+> Failed: acl "a_deny" did not accept
+> Failed: acl "a_deny" did not accept
+> acl: [1] [2] [3] [4]
+>
> addrss: local-part@dom.ain
> addrss: local-part@dom.ain
> domain: dom.ain