Re: [exim] How to rewrite ${filter ...} expressions for olde…

Top Page
Delete this message
Reply to this message
Author: Michael Lampe
Date:  
To: exim-users
Subject: Re: [exim] How to rewrite ${filter ...} expressions for older exims?
Ben Allen wrote:
> On Monday 13 December 2010 21:58:10 Michael Lampe wrote:
>> The whole thing is this:
>>
>> -----
>>
>> # LDAP Router
>>
>> LDAP_USER="uid=mail,ou=System-User,dc=localhost"
>> LDAP_PASS=xxxxxxxxxxxxxxxxxxxx
>> LDAP_URL=ldapi://${quote_ldap_dn:/var/run/ldapi}
>> LDAP_LOCALPART_ATT=mailLocalAddress
>> LDAP_MAIL_GROUP=E-Mail
>> LDAP_UID_QUERY=${lookup ldapm {user=LDAP_USER pass=LDAP_PASS \
>> LDAP_URL/ou=People,dc=localhost?uid?sub?(LDAP_LOCALPART_ATT=${quote_ldap_dn
>> :$local_part})}}
>> LDAP_GROUP_QUERY=${lookup ldapm {user=LDAP_USER
>>   pass=LDAP_PASS \
>>           LDAP_URL/cn=LDAP_MAIL_GROUP,ou=Groups,dc=localhost?cn?base?\
>>                   (uniqueMember=uid=$item,ou=People,dc=localhost)}}

>>
>> ldap_user:
>>     debug_print = "R: ldap_user for $local_part@$domain"
>>     driver = accept
>>     domains = +local_domains
>>     local_parts = ! root
>>     local_part_suffix = +*
>>     local_part_suffix_optional
>>     address_data = ${filter {<\n
>> LDAP_UID_QUERY}{eq{LDAP_GROUP_QUERY}{LDAP_MAIL_GROUP}}}
>>     condition = ${if>{${strlen:${filter {<\n
>> LDAP_UID_QUERY}{eq{LDAP_GROUP_QUERY}{LDAP_MAIL_GROUP}}}} }{0}}
>>     transport = pipe_delivery_cyrus
>>     cannot_route_message = ldap_user: mail address $local_part does not
>>   exist

>
> Right then (apologies if you know this already):
>    - Based on what you've shown above LDAP_UID_QUERY looks up the uid(s) of
> user(s) who's addresses match the current $local_part.
>    -The filter then basically checks if these uids are members of the "E-mail"
> group.

>
> There's a couple if strange things (someone correct me if I'm wrong about
> anything):
>    - LDAP_GROUP_QUERY uses ldapm (multiple matches separated by newlines).
> However, if there are in fact multiple matches (a uid is a member of more than
> one group), then the filter's eq{}{} will fail to match and membership of "E-
> mail" won't get the mail delivered. That leads me to think that there's only
> one possible group in the ldap database, the E-mail group, making it (at least
> partly) redundant (it could still be used to 'enable' or 'disable' a user's
> address.


A users record looks like this:

---
dn: uid=mlampe,ou=People,dc=localhost
objectClass: hordePerson
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: simpleSecurityObject
objectClass: inetLocalMailRecipient
objectClass: top
cn: Michael Lampe
sn: Lampe
uid: mlampe
mailLocalAddress: Michael.Lampe
mailLocalAddress: mlampe
mailLocalAddress: lampe
telephoneNumber: 544943
roomNumber: 207
structuralObjectClass: inetOrgPerson
entryUUID: d0701624-a71a-102c-8ccd-c322842970cf
creatorsName: cn=Manager,dc=localhost
createTimestamp: 20080425135405Z
userPassword:: xxxxxxxxxxxxxxxxx
mail: Michael.Lampe@???
---

And then there's an an E-Mail group record:

---
dn: cn=E-Mail,ou=Groups,dc=localhost
objectClass: groupOfUniqueNames
objectClass: top
uniqueMember: cn=manager,dc=localhost
uniqueMember: uid=mail,ou=System-User,dc=localhost
uniqueMember: uid=administrator,ou=People,dc=localhost
uniqueMember: uid=mlampe,ou=people,dc=localhost
...
cn: E-Mail
structuralObjectClass: groupOfUniqueNames
entryUUID: 544cb920-a71b-102c-8ce0-c322842970cf
creatorsName: cn=Manager,dc=localhost
createTimestamp: 20080425135747Z
entryCSN: 20100802085805Z#000001#00#000000
modifiersName: cn=Manager,dc=localhost
modifyTimestamp: 20100802085805Z
---

If I understand correctly, it works like this:

Someone sends me a mail with address 'lampe@gcsc...' (Three local parts
are possible). From this address 'mlampe' is derived as my uid. Then
it's checked that I am listed in the E-Mail group. Finally the mail is
handed over to cyrus to put it in the 'mlampe' mailbox.

>    - Since this is an accept router, and the transport is called
> "pipe_delivery_cyrus" I'm guessing the transport uses the cyrus 'deliver'
> command through a pipe. I'd like to take a look at it, since my guess is that
> it uses $address_data to choose mailbox(es) to deliver to.


---
pipe_delivery_cyrus:
       debug_print = "T: pipe_delivery_cyrus for $local_part@$domain to 
${tr{$address_data}{\n}{ }}"
       driver = pipe
       use_shell
       command = /bin/sh -c "/usr/lib/cyrus-imapd/deliver -m 
${substr_1:$local_part_suffix} -- ${tr{$address_data}{\n}{ }}"
       user = cyrus
       group = mail
       return_output
       log_output
       message_prefix =
       message_suffix =
---


> Finally, don't assume that the way the configuration is at the moment is the
> correct way to do things (it may appear to be working, but just give it a
> while, I guarantee that bugs will appear).


At least, this way it is working for years now ...

> If you can give us the details that
> Bill asked about, I'm sure we'll have some ideas.


Please have some. :)

I'm still rather clueless here and only fixed the remote root hole by
applying a patch on top of the old sources which were still lying around.

Thanks,
Michael