Re: [exim] Trapping string expansion failures

Top Page
Delete this message
Reply to this message
Author: Ben
Date:  
To: exim-users
Subject: Re: [exim] Trapping string expansion failures
On Wednesday, September 22, 2010 09:52:52 am Phil Pennock wrote:
> On 2010-09-21 at 19:48 +0100, Ben Allen wrote:
> > #Okay, must be destined for us. First try live AD lookup
> >
> > AD_rewrite:
> > driver = redirect
> > domains = +exchange_domains
> > address_data = ${lookup ldap{LDAP_SEARCHSPEC}{$value}fail}
> > data = ${filter{$address_data}} #Does a couple of regexes and maps
> >
> > #If the above rewrite failed, check against a 'virtusertable' file
> >
> > static_rewrite:
> > driver = redirect
> > domains = +exchange_domains
> > data = ${lookup in static table}
>
> On the first Router, add a "condition = ..." line which does the same
> LDAP lookup. Note that this will still only do one LDAP lookup because
> of lookup caching. By then saving the result in address_data, the value
> is preserved across the process boundaries (which the caches are not).
>
>  AD_rewrite:
>    driver = redirect
>    domains = +exchange_domains
>    condition = ${lookup ldap{LDAP_SEARCHSPEC}{yes}{no}}
>    address_data = ${lookup ldap{LDAP_SEARCHSPEC}{$value}fail}
>    data = ${filter{$address_data}} #Does a couple of regexes and maps

>
> Regards,
> -Phil



Hi Phil,
Thanks for the reply. Unfortunately that still doesn't work. I still get a 451
when the ldap lookup fails. It simply stops the verify at that point, and
doesn't decline and move onto the next router.

I've knocked together a minimal config to illustrate the problem (the ldap
lookup will obviously always fail 'cause it's nonsense, but I just want to get
it to decline and run 'static_rewrite'):

########################################################
#Test exim.conf
ldap_default_servers = doesnt.exist.com
LDAP_USER_STR = user=fakeuser
LDAP_PASS_STR = pass=fakepassword
LDAP_SEARCH_BASE_STR =dc=doesnt,dc=exist,dc=com

LDAP_SEARCHSPEC =LDAP_USER_STR LDAP_PASS_STR ldap:///LDAP_SEARCH_BASE_STR
FAKE_LDAP_LOOKUP = ldap{LDAP_SEARCHSPEC?mailaddr?sub?\
(mailaddr=$local_part@$domain)}

daemon_smtp_ports = 26
never_users = root
acl_smtp_rcpt = acl_check_rcpt

begin acl

acl_check_rcpt:
accept verify = recipient
accept

begin routers

ldap_rewrite:
driver = redirect
condition = ${lookup FAKE_LDAP_LOOKUP{yes}fail} #or {yes}{no}}
data = ldapuser@???

static_rewrite:
driver = redirect
condition = ${if !eq{$local_part}{ldapuser} {yes}{no}}
data = catchall@???

local_deliver:
driver = accept
transport = local_delivery

begin transports
local_delivery:
driver = appendfile
file = /var/mail/$local_part

###################################################

Tested with a telnet session:

[root@mybox]telnet localhost 26
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
220 cheviot70.ncl.edu.my ESMTP Exim 4.72 Wed, 22 Sep 2010 15:46:03 +0100
HELO test
250 cheviot70.ncl.edu.my Hello test [127.0.0.1]
MAIL FROM:<geoff@???>
250 OK
RCPT TO:<anyone@???>
451 Temporary local problem - please try later


#################

the relevant bit of the debug log has:
 8120 SMTP<< RCPT TO:<anyone@???>
 8120 using ACL "acl_check_rcpt"
 8120 processing "accept"
 8120 check verify = recipient
 8120 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 8120 Verifying anyone@???
 8120 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 8120 Considering anyone@???
 8120 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 8120 routing anyone@???
 8120 --------> ldap_rewrite router <--------
 8120 local_part=anyone domain=test.com
 8120 checking "condition"
 8120 search_open: ldap "NULL"
 8120 search_find: file="NULL"
 8120    key="user=fakeuser pass=fakepassword  
      ldap:///dc=doesnt,dc=exist,dc=com?mailaddr?sub?
      (mailaddr=anyone@???)" partial=-1 affix=NULL starflags=0
 8120 LRU list:
 8120 internal_search_find: file="NULL"
 8120   type=ldap key="user=fakeuser pass=fakepassword 
      ldap:///dc=doesnt,dc=exist,dc=com?mailaddr?sub? 
      (mailaddr=anyone@???)"
 8120 database lookup required for user=fakeuser pass=fakepassword 
      ldap:///dc=doesnt,dc=exist,dc=com?mailaddr?sub?
      (mailaddr=anyone@???)
 8120 LDAP parameters: user=fakeuser pass=fakepassword size=0 time=0 connect=0 
      dereference=0 referrals=on
 8120 perform_ldap_search: ldap URL = 
     "ldap:///dc=doesnt,dc=exist,dc=com?mailaddr?sub?
     (mailaddr=anyone@???)" server=doesnt.exist.com port=0 sizelimit=0 
     timelimit=0 tcplimit=0
 8120 after ldap_url_parse: host=doesnt.exist.com port=0
 8120 ldap_initialize with URL ldap://doesnt.exist.com:389/
 8120 initialized for LDAP (v3) server doesnt.exist.com:389
 8120 LDAP_OPT_X_TLS_TRY set
 8120 binding with user=fakeuser password=fakepassword
 8120 failed to bind the LDAP connection to server doesnt.exist.com:389 - 
      ldap_bind() returned -1
 8120 lookup deferred: failed to bind the LDAP connection to server 
      doesnt.exist.com:389 - ldap_bind() returned -1
 8120 condition check lookup defer
 8120 ----------- end verify ------------
 8120 accept: condition test deferred
 8120 SMTP>> 451 Temporary local problem - please try later
 8120 LOG: MAIN REJECT


#############################################################

I still can't figure out a way to get around this, bar changing the source
code to alter behaviour wrt to lookup failures. But that'd break too many
existing configurations to be realistic. I can't believe I'm the first person
to have wanted this, but I'm stumped as to how to proceed.

One thing I have turned up is that a lookup against a flat file (e.g. ${lookup
lsearch{/etc/exim/mailaliases}{$value}fail} ) will fail (IMHO) properly if the
file doesn't exist. The router declines and moves on. The documentation also
mentions that dnsdb failures behave in a similar fashion. Is it expected
(and/or desired) behaviour for other database lookups to work differently?
MySQL lookups fail/defer in the same way as LDAP does (I just checked).

Thanks everyone for taking the time to look into this. I'm sure there must be
a way around it.

Regards

Ben