[exim] Best practice to wrap one's head around quoting?

Top Page
Delete this message
Reply to this message
Author: Tim Landscheidt
Date:  
To: exim-users
Subject: [exim] Best practice to wrap one's head around quoting?
Hi,

I want to replace a redirect router in our configuration
that uses a shell script for an LDAP look-up with a direct
LDAP look-up by exim (4.76/Ubuntu Trusty). The (working)
section reads
(cf. https://gerrit.wikimedia.org/r/#/c/237871/1/modules/toollabs/templates/mail-relay.exim4.conf.erb
for the complete configuration):

| [...]


| # Forward mail to <user>@ to the mail address set in LDAP (wikitech preference)


| user_forward:
|   driver = redirect
|   caseful_local_part
|   check_local_user
|   expn = false
|   check_ancestor
|   modemask = 002
|   data = ${lookup ldap \
|          {user=LDAPUSER pass=LDAPPASS ldap://ldap-eqiad.wikimedia.org/uid=${quote_ldap:$local_part},ou=people,dc=wikimedia,dc=org?mail}{$value}fail}


| [...]


("modemask" is probably copy & paste cruft.) Reading the
exim documentation on quoting reminded me of m4's power and
scariness :-), and as the LDAP "mail" attribute is user in-
put in our setup, a) I want to make sure that this does not
open up any holes. My understanding is that a redirect
router without "allow_filter" treats data returned by
"${lookup}" as if it was given as recipient address(es) in
the first place, i. e. this can never be used to achieve
something "more". Is that correct? Second, does
"${quote_ldap:$local_part}" everything that it needs to do?
In our case, (currently) "check_local_user" will guarantee
that "$local_part" will match "/^[a-z][.a-z0-9_-]*$/i", but
if the look-up depends on that assertion I'd need to docu-
ment it at least.

b) I'm looking for more general "best practices" regarding
quoting. The exim documentation on string expansions (like
m4) goes to great lengths to describe for example what char-
acters get quoted by "${quote}", but doesn't provide a men-
tal model on when to use which operator. In another router
in our configuration, I have a look-up (yes, if there were
reverse memberOf/isMemberOf attributes in our LDAP server,
that would be nice, but there aren't any at the moment):

|   data = ${sg{${lookup ldap \
|          {user=LDAPUSER pass=LDAPPASS ldap://ldap-eqiad.wikimedia.org/cn=INSTANCEPROJECT.${quote_ldap:$local_part},ou=servicegroups,dc=wikimedia,dc=org?member}{$value}fail}}{uid=(.*?),ou=people,(ou=servicegroups,)?dc=wikimedia,dc=org}{\$1}}


Again, that works, but I would much prefer something that
says: "For each attribute, apply this regular expression and
make the result a list of all matches". I've looked at
"${map}", but I'm unclear if and where I should throw in
some "${quote}" operators. Are there recommended examples
for processing the results of look-ups?

TIA,
Tim