Re: [exim] ACL condition

Top Page
Delete this message
Reply to this message
Author: Phil Pennock
Date:  
To: Greg
CC: exim-users
Subject: Re: [exim] ACL condition
On 2012-10-12 at 00:01 -0500, Greg wrote:
> I'm attempting to add a condition within a sender verification ACL that
> will allow my users to have a whitelist(already done) file, the users
> info is stored in acl_m1_home, but I keep getting this error: missing }
> at end of condition inside "or" group.
>
> I have a pastebin of the code at at: http://pastebin.com/EuDmMe9Z


Let's break it out like this (ignoring needed \ at end-of-line):
----------------------------8< cut here >8------------------------------
${if or {

{exists{${acl_m1_home}/.spamd/ip.whitelist}{${if match_ip{$sender_host_address}{iplsearch;$acl_m1_home/.spamd/ip.whitelist}{yes}{no}}}{no}}

{eq{$sender_address_local_part}{postmaster}{yes}{no}}
{eq{$sender_address_local_part}{noreply}{yes}{no}}
{eq{$sender_address_local_part}{no-reply}{yes}{no}}
{eq{$sender_address_local_part}{no-reply}{yes}{no}}
{eq{$sender_address_local_part}{no_reply}{yes}{no}}

}}

----------------------------8< cut here >8------------------------------

That makes it clearer that you're trying to do:
CONDITION_exists{filepath}SOMETHINGELSE
within one condition rule, with the SOMETHINGELSE being a raw string
expansion. And then, again, you have the {yes}{no} for each subsequent
condition. The {yes}{no} and the previous expansion are the later parts
of an IF rule, not part of the condition syntax.

(Also, not seeing why "no-reply" is there twice; you also might want eqi
for case-insensitive).

If I've understood the requirements, then I think that you want:
----------------------------8< cut here >8------------------------------
${if or {\
  {and{\
    {exists{${acl_m1_home}/.spamd/ip.whitelist}}\
    {match_ip{$sender_host_address}{iplsearch;$acl_m1_home/.spamd/ip.whitelist}}\
  }}\
  {eqi{$sender_address_local_part}{postmaster}}\
  {eqi{$sender_address_local_part}{noreply}}\
  {eqi{$sender_address_local_part}{no-reply}}\
  {eqi{$sender_address_local_part}{no_reply}}\
}}
----------------------------8< cut here >8------------------------------


However, note that from Exim 4.77 onwards, the right-hand-side of a
match_<type> is no longer subject to string expansion, because we saw
too many insecure configs because people didn't understand that the
content had to be highly trusted, since it could be any arbitrary
lookup. You can build Exim with EXPAND_LISTMATCH_RHS in Local/Makefile
to get that functionality back.

Instead, I'd write this as three condition rules in the ACL:
----------------------------8< cut here >8------------------------------
condition = ${if exists{${acl_m1_home}/.spamd/ip.whitelist}}
hosts = iplsearch;$acl_m1_home/.spamd/ip.whitelist
!condition = ${if inlisti{$sender_address_local_part}{postmaster:no-reply:no_reply}}
----------------------------8< cut here >8------------------------------

Note that inlisti was added in Exim 4.77, so before that you might
instead use:
----------------------------8< cut here >8------------------------------
!condition = ${if forany{postmaster:no-reply:no_reply}{eqi{$item}{$sender_address_local_part}}}
----------------------------8< cut here >8------------------------------

Great long chained and/or rules in conditions are historically because
Routers only supported one "condition" rule, before Exim 4.73, so for
Routers there was no choice. From Exim 4.73, you can use multiple
condition rules there, so it becomes easier to write rules where mere
mortals can balance the braces without much debugging. For ACLs, you've
always been able to chain together rules as I did above.

Regards,
-Phil