[exim] Trapping string expansion failures

Top Page
Delete this message
Reply to this message
Author: Ben Allen
Date:  
To: exim-users
Subject: [exim] Trapping string expansion failures
Hi everyone,

I'm trying to set up exim as a gateway, checking for valid email addresses
with lookups against an Exchange/AD LDAP server. This works fine provided the
LDAP server is up and running.

What I would like to have is a failover list in case the connection to the AD
box dies (or Windows has a "problem/feature" ;-) ). At the moment I've got
three routers as follows (simplified as I'm not asking about the syntax
particularly):

#Is this outgoing mail?
external:
driver = manualroute
domains = ! +local_domains
transport = remote_smtp
no_more

#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}

#Not exchange, do something else.
.
.
.

The above works fine as long as the LDAP query connects properly. If the LDAP
query fails though (e.g. if the AD box is dead) then the address_data
expansion fails and AD_rewrite router returns a 'fail defer' so verification
fails and I send a 4xx defer to the client).

What I want to be able to do is trap the expansion error somehow and have
AD_rewrite decline the address. That way it will move onto static_rewrite.

I've searched around and can't find anything that hints at how to do this.
It's been asked before
(http://lists.exim.org/lurker/message/20050324.134621.f3e609b4.en.html) but
never got a reply.

I've also tried setting address_data via an acl variable and using that in the
router. e.g.:

acl_smtp_rcpt:
    warn    set acl_m_currentaddr = LDAP_LOOKUP


    require  verify = recipient
.
.
.


begin routers
.
.

AD_Rewrite:
  driver = redirect
  domains = +exchange_domains      
  address_data = $acl_m_currentaddr
  data = ${filter{$address_data}} #
.
.
.


Doing it this way works fine for verification, (the correct address_data is
used when the verify is performed),but it breaks if there's multiple
recipients once it gets to the routing step. I end up with everything being
delivered to the final verified recipient. Looking through the docs, it seems
that address_data is supposed set on a per recipient basis, but only during
routing and delivery. I can't seem to set it during Verify and have it stick.

So the problem boils down to either trapping a hard fail from an ldap lookup
and having the router decline as opposed to defer, or finding a way to store
per recipient data during an ACL to be used in routing and delivery.

Assuming what I want isn't possible, I could do two things. First off, just
set the max_recipients to 1 to avoid the address_data overwrite problem above.
That'd put a lot of extra strain on the server and network connection though.
I could also just run an acl to check LDAP connectivity early on and then use
the result in the router's condition to assume it's going to connect. Neither
of these seems like a clean way of doing things.

I welcome any other ideas anyone has, and if I've missed something obvious
please let me know.

Cheers

Ben

p.s. Apologies for a possible double post. I was relaying through gmail which
insists on rewriting stuff. It should be clean now.(I need to get an ISP
that'll allow port 25 out :-) )