Re: [exim] Exclude recipient from wildcard

Top Page
Delete this message
Reply to this message
Author: Peter Thomassen
Date:  
To: exim-users
Subject: Re: [exim] Exclude recipient from wildcard
Phil Pennock wrote:
> On 2007-09-21 at 00:01 +0200, Peter Thomassen wrote:
>> The question now is: How do I define a "catch-rest" wildcard that does
>> not affect any recipients that are processed otherwise?
>
> Since that's what lsearch* is supposed to be, something else is
> happening in your configuration.


The output of `exim -bt postmaster` shows that Exim recursively tries to
lookup for an alias (have a look at the "comments" I put in) and finally
finds *:peter, regardless of the fact that root is a Linux user account and
not an alias:

# exim -bt postmaster
R: system_aliases for postmaster@???
R: system_aliases for root@???
R: long_aliases for root@???
R: system_aliases for peter@???
R: long_aliases for peter@???
R: system_aliases for peter@???
R: userforward for peter@???
R: procmail for peter@???
R: maildrop for peter@???
R: local_user for peter@???
peter@???
    <-- peter@???                       # This is *:peter
    <-- root@???                        # This is postmaster:root
    <-- postmaster@???
  router = local_user, transport = maildir_home


> You'll need to post the Routers section of your config file


I'm using the Debian package, so it may look a bit complicated ... (I
skipped routers disabled by .ifdef stanzas)

begin routers

hubbed_hosts:
  debug_print = "R: hubbed_hosts for $domain"
  driver = manualroute
  domains = "${if exists{CONFDIR/hubbed_hosts}\
                   {partial-lsearch;CONFDIR/hubbed_hosts}\
              fail}"
  same_domain_copy_routing = yes
  route_data = ${lookup{$domain}partial-lsearch{CONFDIR/hubbed_hosts}}
  transport = remote_smtp


dnslookup_relay_to_domains:
debug_print = "R: dnslookup_relay_to_domains for $local_part@$domain"
driver = dnslookup
domains = ! +local_domains : +relay_to_domains
transport = remote_smtp
same_domain_copy_routing = yes
no_more

dnslookup:
  debug_print = "R: dnslookup for $local_part@$domain"
  driver = dnslookup
  domains = ! +local_domains
  transport = remote_smtp
  same_domain_copy_routing = yes
  ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 : 192.168.0.0/16 :\
                        172.16.0.0/12 : 10.0.0.0/8 : 169.254.0.0/16 :\
                        255.255.255.255
  no_more


real_local:
debug_print = "R: real_local for $local_part@$domain"
driver = accept
domains = +local_domains
local_part_prefix = real-
check_local_user
transport = LOCAL_DELIVERY

system_aliases:
debug_print = "R: system_aliases for $local_part@$domain"
driver = redirect
domains = +local_domains
allow_fail
allow_defer
data = ${lookup{$local_part}lsearch{/etc/aliases}}
.ifdef SYSTEM_ALIASES_USER
user = SYSTEM_ALIASES_USER
.endif
.ifdef SYSTEM_ALIASES_GROUP
group = SYSTEM_ALIASES_GROUP
.endif
.ifdef SYSTEM_ALIASES_FILE_TRANSPORT
file_transport = SYSTEM_ALIASES_FILE_TRANSPORT
.endif
.ifdef SYSTEM_ALIASES_PIPE_TRANSPORT
pipe_transport = SYSTEM_ALIASES_PIPE_TRANSPORT
.endif
.ifdef SYSTEM_ALIASES_DIRECTORY_TRANSPORT
directory_transport = SYSTEM_ALIASES_DIRECTORY_TRANSPORT
.endif

long_aliases:
debug_print = "R: long_aliases for $local_part@$domain"
driver = redirect
domains = +local_domains
allow_fail
allow_defer
data = ${lookup{$local_part@$domain}lsearch*@{CONFDIR/aliases}}
file_transport = address_file

userforward:
  debug_print = "R: userforward for $local_part@$domain"
  driver = redirect
  domains = +local_domains
  check_local_user
  file = $home/.forward
  require_files = $local_part:$home/.forward
  no_verify
  no_expn
  check_ancestor
  allow_filter
  forbid_smtp_code = true
  directory_transport = address_directory
  file_transport = address_file
  pipe_transport = address_pipe
  reply_transport = address_reply
  skip_syntax_errors
  syntax_errors_to = real-$local_part@$domain
  syntax_errors_text = \
    This is an automatically generated message. An error has\n\
    been found in your .forward file. Details of the error are\n\
    reported below. While this error persists, you will receive\n\
    a copy of this message for every message that is addressed\n\
    to you. If your .forward file is a filter file, or if it is\n\
    a non-filter file containing no valid forwarding addresses,\n\
    a copy of each incoming message will be put in your normal\n\
    mailbox. If a non-filter file contains at least one valid\n\
    forwarding address, forwarding to the valid addresses will\n\
    happen, and those will be the only deliveries that occur.


procmail:
  debug_print = "R: procmail for $local_part@$domain"
  driver = accept
  domains = +local_domains
  check_local_user
  transport = procmail_pipe
  require_files = ${local_part}:\
                  ${if exists{/etc/procmailrc}\
                    {/etc/procmailrc}{${home}/.procmailrc}}:\
                  +/usr/bin/procmail
  no_verify
  no_expn


maildrop:
debug_print = "R: maildrop for $local_part@$domain"
driver = accept
domains = +local_domains
check_local_user
transport = maildrop_pipe
require_files = ${local_part}:${home}/.mailfilter:+/usr/bin/maildrop
no_verify
no_expn

local_user:
debug_print = "R: local_user for $local_part@$domain"
driver = accept
domains = +local_domains
check_local_user
local_parts = ! root
transport = LOCAL_DELIVERY
cannot_route_message = Unknown user

mail4root:
debug_print = "R: mail4root for $local_part@$domain"
driver = redirect
domains = +local_domains
data = /var/mail/mail
file_transport = address_file
local_parts = root
user = mail
group = mail

> and
> preferably also the output of "exim -d+route+lookup -bt root".


# exim -d+route+lookup -bt root
Exim version 4.63 uid=0 gid=0 pid=25892 D=fbb95cfd
Berkeley DB: Sleepycat Software: Berkeley DB 4.3.29: (September 6, 2005)
Support for: crypteq iconv() IPv6 PAM Perl GnuTLS move_frozen_messages
Content_Scanning Old_Demime
Lookups: lsearch wildlsearch nwildlsearch iplsearch cdb dbm dbmnz dnsdb
dsearch ldap ldapdn ldapm mysql nis nis0 passwd pgsql sqlite
Authenticators: cram_md5 cyrus_sasl plaintext spa
Routers: accept dnslookup ipliteral iplookup manualroute queryprogram
redirect
Transports: appendfile/maildir/mailstore/mbx autoreply lmtp pipe smtp
Fixed never_users: 0
Size of off_t: 8
changed uid/gid: forcing real = effective
uid=0 gid=0 pid=25892
auxiliary group list: <none>
seeking password data for user "uucp": cache not available
getpwnam() succeeded uid=10 gid=10
configuration file is /var/lib/exim4/config.autogenerated
log selectors = 00000ffc 00189001
trusted user
admin user
seeking password data for user "mail": cache not available
getpwnam() succeeded uid=8 gid=8
user name "root" extracted from gecos field "root"
originator: uid=0 gid=0 login=root name=root
sender address = root@???
Address testing: uid=0 gid=108 euid=0 egid=108
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Testing root@???
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Considering root@???
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

routing root@???
--------> hubbed_hosts router <--------
local_part=root domain=example.tld
checking domains
expansion of "${if exists{/etc/exim4/hubbed_hosts
{partial-lsearch;/etc/exim4/hubbed_hosts}fail}" forced failure: assume not
in this list
hubbed_hosts router skipped: domains mismatch
--------> dnslookup_relay_to_domains router <--------
local_part=root domain=example.tld
checking domains
example.tld in "@:localhost:@:lsearch:/etc/exim4/local_domains"? yes
(matched "@")
example.tld in "! +local_domains : +relay_to_domains"? no (matched "!
+local_domains")
dnslookup_relay_to_domains router skipped: domains mismatch
--------> dnslookup router <--------
local_part=root domain=example.tld
checking domains
cached yes match for +local_domains
cached lookup data = NULL
example.tld in "! +local_domains"? no (matched "! +local_domains" - cached)
dnslookup router skipped: domains mismatch
--------> real_local router <--------
local_part=root domain=example.tld
real_local router skipped: prefix mismatch
--------> system_aliases router <--------
local_part=root domain=example.tld
checking domains
cached yes match for +local_domains
cached lookup data = NULL
example.tld in "+local_domains"? yes (matched "+local_domains" - cached)
R: system_aliases for root@???
calling system_aliases router
rda_interpret (string): ${lookup{$local_part}lsearch{/etc/aliases}}
search_open: lsearch "/etc/aliases"
search_find: file="/etc/aliases"
key="root" partial=-1 affix=NULL starflags=0
LRU list:
:/etc/aliases
End
internal_search_find: file="/etc/aliases"
type=lsearch key="root"
file lookup required for root
in /etc/aliases
lookup failed
expanded:
file is not a filter file
parse_forward_list:
system_aliases router declined for root@???
--------> long_aliases router <--------
local_part=root domain=example.tld
checking domains
cached yes match for +local_domains
cached lookup data = NULL
example.tld in "+local_domains"? yes (matched "+local_domains" - cached)
R: long_aliases for root@???
calling long_aliases router
rda_interpret (string):
${lookup{$local_part@$domain}lsearch*@{/etc/exim4/aliases}}
search_open: lsearch "/etc/exim4/aliases"
search_find: file="/etc/exim4/aliases"
key="root@???" partial=-1 affix=NULL starflags=2
LRU list:
:/etc/exim4/aliases
:/etc/aliases
End
internal_search_find: file="/etc/exim4/aliases"
type=lsearch key="root@???"
file lookup required for root@???
in /etc/exim4/aliases
lookup failed
trying default match *@example.tld
internal_search_find: file="/etc/exim4/aliases"
type=lsearch key="*@example.tld"
file lookup required for *@example.tld
in /etc/exim4/aliases
lookup failed
trying to match *
internal_search_find: file="/etc/exim4/aliases"
type=lsearch key="*"
file lookup required for *
in /etc/exim4/aliases
lookup yielded: info
expanded: info
file is not a filter file
parse_forward_list: info
extract item: info
long_aliases router generated peter@???
errors_to=NULL transport=NULL
uid=unset gid=unset home=NULL
routed by long_aliases router
envelope to: root@???
transport: <none>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Considering peter@???
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

routing peter@???
--------> hubbed_hosts router <--------
local_part=info domain=example.tld
checking domains
expansion of "${if exists{/etc/exim4/hubbed_hosts
{partial-lsearch;/etc/exim4/hubbed_hosts}fail}" forced failure: assume not
in this list
hubbed_hosts router skipped: domains mismatch
--------> dnslookup_relay_to_domains router <--------
local_part=info domain=example.tld
checking domains
example.tld in "@:localhost:@:lsearch:/etc/exim4/local_domains"? yes
(matched "@")
example.tld in "! +local_domains : +relay_to_domains"? no (matched "!
+local_domains")
dnslookup_relay_to_domains router skipped: domains mismatch
--------> dnslookup router <--------
local_part=info domain=example.tld
checking domains
cached yes match for +local_domains
cached lookup data = NULL
example.tld in "! +local_domains"? no (matched "! +local_domains" - cached)
dnslookup router skipped: domains mismatch
--------> real_local router <--------
local_part=info domain=example.tld
real_local router skipped: prefix mismatch
--------> system_aliases router <--------
local_part=info domain=example.tld
checking domains
cached yes match for +local_domains
cached lookup data = NULL
example.tld in "+local_domains"? yes (matched "+local_domains" - cached)
R: system_aliases for peter@???
calling system_aliases router
rda_interpret (string): ${lookup{$local_part}lsearch{/etc/aliases}}
search_open: lsearch "/etc/aliases"
cached open
search_find: file="/etc/aliases"
key="info" partial=-1 affix=NULL starflags=0
LRU list:
:/etc/aliases
:/etc/exim4/aliases
End
internal_search_find: file="/etc/aliases"
type=lsearch key="info"
file lookup required for info
in /etc/aliases
lookup failed
expanded:
file is not a filter file
parse_forward_list:
system_aliases router declined for peter@???
--------> long_aliases router <--------
local_part=info domain=example.tld
checking domains
cached yes match for +local_domains
cached lookup data = NULL
example.tld in "+local_domains"? yes (matched "+local_domains" - cached)
R: long_aliases for peter@???
calling long_aliases router
rda_interpret (string):
${lookup{$local_part@$domain}lsearch*@{/etc/exim4/aliases}}
search_open: lsearch "/etc/exim4/aliases"
cached open
search_find: file="/etc/exim4/aliases"
key="peter@???" partial=-1 affix=NULL starflags=2
LRU list:
:/etc/exim4/aliases
:/etc/aliases
End
internal_search_find: file="/etc/exim4/aliases"
type=lsearch key="peter@???"
file lookup required for peter@???
in /etc/exim4/aliases
lookup failed
trying default match *@example.tld
internal_search_find: file="/etc/exim4/aliases"
type=lsearch key="*@example.tld"
cached data used for lookup of *@example.tld
in /etc/exim4/aliases
lookup failed
trying to match *
internal_search_find: file="/etc/exim4/aliases"
type=lsearch key="*"
cached data used for lookup of *
in /etc/exim4/aliases
lookup yielded: info
expanded: info
file is not a filter file
parse_forward_list: info
extract item: info
long_aliases router generated peter@???
errors_to=NULL transport=NULL
uid=unset gid=unset home=NULL
routed by long_aliases router
envelope to: peter@???
transport: <none>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Considering peter@???
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

routing peter@???
--------> hubbed_hosts router <--------
local_part=info domain=example.tld
checking domains
expansion of "${if exists{/etc/exim4/hubbed_hosts
{partial-lsearch;/etc/exim4/hubbed_hosts}fail}" forced failure: assume not
in this list
hubbed_hosts router skipped: domains mismatch
--------> dnslookup_relay_to_domains router <--------
local_part=info domain=example.tld
checking domains
example.tld in "@:localhost:@:lsearch:/etc/exim4/local_domains"? yes
(matched "@")
example.tld in "! +local_domains : +relay_to_domains"? no (matched "!
+local_domains")
dnslookup_relay_to_domains router skipped: domains mismatch
--------> dnslookup router <--------
local_part=info domain=example.tld
checking domains
cached yes match for +local_domains
cached lookup data = NULL
example.tld in "! +local_domains"? no (matched "! +local_domains" - cached)
dnslookup router skipped: domains mismatch
--------> real_local router <--------
local_part=info domain=example.tld
real_local router skipped: prefix mismatch
--------> system_aliases router <--------
local_part=info domain=example.tld
checking domains
cached yes match for +local_domains
cached lookup data = NULL
example.tld in "+local_domains"? yes (matched "+local_domains" - cached)
R: system_aliases for peter@???
calling system_aliases router
rda_interpret (string): ${lookup{$local_part}lsearch{/etc/aliases}}
search_open: lsearch "/etc/aliases"
  cached open
search_find: file="/etc/aliases"
  key="info" partial=-1 affix=NULL starflags=0
LRU list:
  :/etc/aliases
  :/etc/exim4/aliases
  End
internal_search_find: file="/etc/aliases"
  type=lsearch key="info"
cached data used for lookup of info
  in /etc/aliases
lookup failed
expanded:
file is not a filter file
parse_forward_list:
system_aliases router declined for peter@???
--------> long_aliases router <--------
long_aliases router skipped: previously routed peter@???
--------> userforward router <--------
local_part=info domain=example.tld
checking domains
cached yes match for +local_domains
cached lookup data = NULL
example.tld in "+local_domains"? yes (matched "+local_domains" - cached)
checking for local user
seeking password data for user "info": cache not available
getpwnam() succeeded uid=1002 gid=65534
R: userforward for peter@???
checking require_files
seeking password data for user "info": using cached result
getpwnam() succeeded uid=1002 gid=65534
check subsequent files for access by info
file check: $home/.forward
expanded file: /home/info/.forward
stat() yielded -1
errno = 2
userforward router skipped: file check
--------> procmail router <--------
local_part=info domain=example.tld
checking domains
cached yes match for +local_domains
cached lookup data = NULL
example.tld in "+local_domains"? yes (matched "+local_domains" - cached)
checking for local user
seeking password data for user "info": using cached result
getpwnam() succeeded uid=1002 gid=65534
R: procmail for peter@???
checking require_files
seeking password data for user "info": using cached result
getpwnam() succeeded uid=1002 gid=65534
check subsequent files for access by info
file check: ${if exists{/etc/procmailrc}{/etc/procmailrc
{${home}/.procmailrc}}
expanded file: /home/info/.procmailrc
stat() yielded -1
errno = 2
procmail router skipped: file check
--------> maildrop router <--------
local_part=info domain=example.tld
checking domains
cached yes match for +local_domains
cached lookup data = NULL
example.tld in "+local_domains"? yes (matched "+local_domains" - cached)
checking for local user
seeking password data for user "info": using cached result
getpwnam() succeeded uid=1002 gid=65534
R: maildrop for peter@???
checking require_files
seeking password data for user "info": using cached result
getpwnam() succeeded uid=1002 gid=65534
check subsequent files for access by info
file check: ${home}/.mailfilter
expanded file: /home/info/.mailfilter
stat() yielded -1
errno = 2
maildrop router skipped: file check
--------> local_user router <--------
local_part=info domain=example.tld
checking domains
cached yes match for +local_domains
cached lookup data = NULL
example.tld in "+local_domains"? yes (matched "+local_domains" - cached)
checking local_parts
info in "! root"? yes (end of list)
checking for local user
seeking password data for user "info": using cached result
getpwnam() succeeded uid=1002 gid=65534
R: local_user for peter@???
calling local_user router
local_user router called for peter@???
  domain = example.tld
set transport maildir_home
queued for maildir_home transport: local_part = info
domain = example.tld
  errors_to=NULL
  domain_data=NULL localpart_data=NULL
routed by local_user router
  envelope to: peter@???
  transport: maildir_home
peter@???
    <-- peter@???
    <-- root@???
  router = local_user, transport = maildir_home
search_tidyup called

>>>>>>>>>>>>>>>> Exim pid=25892 terminating with rc=0 >>>>>>>>>>>>>>>>


Thanks for your help, Phil!
Peter