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