On Tue, 2003-12-16 at 09:49 +0000, Philip Hazel wrote:
> On Mon, 15 Dec 2003, David Woodhouse wrote:
>
> > The following routers use it to implement a virtual domain. You could of
> > course omit the first and just make sure you have postmaster in all the
> > zones you use this way...
>
> I've saved this to put in the config samples / FAQ when I next update them.
There was a bug in the handling of '@domain' TXT records, which I use as
wildcards for some virtual domains, to redirect all localparts without
their own TXT record to a single host which handles the majority of that
domain. In the case where the local part started with numbers, the
expansion of the outermost ${sg...} in the dns_virtual_domains router we
getting confused, because it expanded $local_part before attempting to
expand $1.
This is the new version with one extra backslash to cause the expansion
of $local_part to happen in the same pass as the expansion of $1, and
hence not cause this breakage.
domainlist dns_virtual_domains = lsearch;CONFDIR/dns-virtual-domains
<...>
virtual_postmaster:
driver = redirect
domains = +dns_virtual_domains
local_parts = postmaster:root:abuse:mailer-daemon
data = postmaster@$primary_hostname
# For virtual domains, look up the target in DNS and rewrite...
dns_virtual_domains:
driver = redirect
domains = +dns_virtual_domains
check_ancestor
repeat_use
one_time
allow_defer
allow_fail
forbid_file
forbid_pipe
retry_use_local_part
qualify_preserve_domain
# Stash the lookup domain root for use in the next router.
address_data = ${lookup{$domain}lsearch{CONFDIR/dns-virtual-domains}}
# The lookup failure won't distinguish between absent record, absent
# domain, or other temporary failures. So we make this router just
# give up, and sort out the various failure modes later.
# The ${sg...} bits turn multiple TXT records (which Exim gives us
# separated by \n) into a comma-separated list, and also rewrite
# any element of that list of the form '@domain' (i.e. without a
# local part) to $local_part@domain, using the original local part
# from the address being routed, at the newly-provided domain.
# Addresses containing _only_ a localpart are qualified at the
# same domain as is being looked up, by qualify_preserve_domain
# above.
data = ${sg{\
${sg{\
${lookup dnsdb{txt=$local_part.$address_data}{$value}fail}\
}{\n}{,}}\
}{(,|^)[ ]*@}{\$1\$local_part@}}
dns_virtual_failed:
driver = redirect
domains = +dns_virtual_domains
allow_fail
allow_defer
data = ${lookup dnsdb{ns=$address_data}\
# If NS lookup succeeded, the domain exists and we can find it.
# Therefore, the above lookup failure meant that the user
# just doesn't exist. Fail appropriately:
{:fail:Unknown user at virtual domain}\
# NS lookup failed. This means there's a DNS problem -- so we
# shouldn't fail the delivery; let the following routers handle
# it... Note "fail" not "{:fail:}". It means 'pass'. :)
fail}
# We have DNS problems. If we're actually _delivering_, then try to
# deliver to a higher-priority MX if one exists. Otherwise, we defer and
# let it stay on the queue until the problem is fixed.
# You may prefer to freeze or bounce in this situation; I don't.
dns_virtual_relay:
driver = dnslookup
domains = +dns_virtual_domains
transport = remote_smtp
self = defer
no_verify
no_more
# On the other hand, if there's a DNS problem and we're only _verifying_,
# as we do when accepting incoming mail, then accept it for now and
# it'll get queued for when the DNS works again.
dns_virtual_verify_fallback:
driver = accept
domains = +dns_virtual_domains
verify_only
no_more
--
dwmw2