OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
Questions on how postfix does it's LDAP lookups.

From: Adrian Buxton (buxtonagmail.com)
Date: Mon May 09 2005 - 01:08:14 CDT


Hi all,

I've got a couple of questions about the way postfix does it's LDAP
lookups. I'm running Postfix 2.0.18-20040209 on OpenBSD with the
following lookups in LDAP:

virtual_alias_domains
virtual_alias_maps
virtual_mailbox_domains
virtual_mailbox_maps

I've also included a copy of postconf -n at the end of this message.

The results all appear to be fine and as I'd expect. What is unusual
is the number and type of queries postfix is performing.

I'm using an OpenLDAP directory server and have enabled debugging on
the queries so I can see what information postfix is requesting. I
manually connected from another system and typed in a few SMTP
commands with the following results (note: debug output pre-pended
with '>')

mail from:sendergmail.com
>conn=3 fd=12 ACCEPT from IP=192.168.15.12:18378 (IP=0.0.0.0:389)
>conn=3 op=0 BIND dn="cn=Manager,dc=mytestdomain,dc=com" method=128
>conn=3 op=0 BIND dn="cn=Manager,dc=mytestdomain,dc=com" mech=SIMPLE ssf=0
>conn=3 op=0 RESULT tag=97 err=0 text=
>conn=3 op=1 SRCH base="dc=mytestdomain,dc=com" scope=2
filter="(&(objectClass=virtualAliasDomain)(dc=gmail.com))"
>conn=3 op=1 SRCH attr=dc
><= bdb_equality_candidates: (dc) index_param failed (18)
>conn=3 op=1 SEARCH RESULT tag=101 err=0 nentries=0 text=
>conn=3 op=2 SRCH base="dc=mytestdomain,dc=com" scope=2
filter="(&(objectClass=virtualMailboxDomain)(dc=gmail.com))"
>conn=3 op=2 SRCH attr=dc
><= bdb_equality_candidates: (dc) index_param failed (18)
>conn=3 op=2 SEARCH RESULT tag=101 err=0 nentries=0 text=

Postfix is checking to see if the sender's domain is in the
virtual_mailbox_domains table, or the virtual_alias_domains table. Why
does Postfix do this when those tables are applicable to recipients
only? I can't see why this setup would cause any LDAP query to be
fired off at this stage of the SMTP conversation…

rcpt to:lanwheeloftime.com.au
>conn=4 op=4 SRCH base="dc=mytestdomain,dc=com" scope=2
filter="(&(|(mail=sendergmail.com)(mailAlias=sendergmail.com))(objectClass=efMailUser))"
>conn=4 op=4 SRCH attr=mail
><= bdb_equality_candidates: (mail) index_param failed (18)
><= bdb_equality_candidates: (mailAlias) index_param failed (18)
>conn=4 op=4 SEARCH RESULT tag=101 err=0 nentries=0 text=
>conn=4 op=5 SRCH base="dc=mytestdomain,dc=com" scope=2
filter="(&(|(mail=gmail.com)(mailAlias=gmail.com))(objectClass=efMailUser))"
>conn=4 op=5 SRCH attr=mail
><= bdb_equality_candidates: (mail) index_param failed (18)
><= bdb_equality_candidates: (mailAlias) index_param failed (18)
>conn=4 op=5 SEARCH RESULT tag=101 err=0 nentries=0 text=

In the preceding text you can see that Postfix is querying LDAP
because I issued an rcpt to command. The bizarre thing is that postfix
is querying the virtual_alias_maps LDAP data to see if the sender
address or sender domain have entries. The virtual_alias_maps are
recipient only, so this looks like a redundant query.

>conn=4 op=6 SRCH base="dc=mytestdomain,dc=com" scope=2
filter="(&(|(mail=lanwheeloftime.com.au)(mailAlias=lanwheeloftime.com.au))(objectClass=efMailUser))"
>conn=4 op=6 SRCH attr=mail
><= bdb_equality_candidates: (mail) index_param failed (18)
><= bdb_equality_candidates: (mailAlias) index_param failed (18)
>conn=4 op=6 ENTRY dn="cn=lan,dc=wheeloftime.com.au,ou=virtual alias
domains,ou=mail stuff,dc=mytestdomain,dc=com"
>conn=4 op=6 SEARCH RESULT tag=101 err=0 nentries=1 text=

Here you can see a successful match as intended. The Postfix server
checks the LDAP directory for a virtual_alias_map entry for
lanwheeloftime.com.au. It returns another email address
(adrianmytestdomain.com) However....

>conn=5 op=3 SRCH base="dc=mytestdomain,dc=com" scope=2
filter="(&(|(mail=lanwheeloftime.com.au)(mailAlias=lanwheeloftime.com.au))(objectClass=efMailUser))"
>conn=5 op=3 SRCH attr=mail
><= bdb_equality_candidates: (mail) index_param failed (18)
><= bdb_equality_candidates: (mailAlias) index_param failed (18)
>conn=5 op=3 ENTRY dn="cn=lan,dc=wheeloftime.com.au,ou=virtual alias
domains,ou=mail stuff,dc=mytestdomain,dc=com"
>conn=5 op=3 SEARCH RESULT tag=101 err=0 nentries=1 text=

...The exact same query is resubmitted. The parameters for the search
are identical and the same result is returned. Any ideas why?
Shouldn't there be one query rather than two?

Also, I've noticed that you cannot use virutal_mailbox_maps to submit
mail to more than one maildir. i.e. you cannot do this:

bobstuff.com stuff.com/bob/, stuff.com/meme/

It just goes into a directory called "stuff.com/bob/,
stuff.com/meme/". Is there any way to make that actually work? I've
had to put in a dodgy work around using the virtual_alias_maps in
order to actually make it all behave. What work around?

Well in order to get a catch all on a domain that must be delivered to
multiple maildirs, you need to specify the catchall in
virtual_alias_maps. If you specify a catchall in virtual_alias_maps,
all mail then goes to the catchall - sounds logical. However if want
to get mail delivered to a catchall and to have other mail for the
same domain go to a different user, then you need to add an additional
entry in virtual_alias_maps fiel pointing back to the same user as
you specify. E.G.
 
bobstuff.com bobstuff.com
memestuff.com memestuff.com
rogerstuff.com roger421gmail.com
stuff.com bobstuff.com, memestuff.com, otherusergmail.com

..then in virtual_mailbox_maps you can point bobstuff.com to his
maildir, and meme to her maildir and they both receive the mail they
are intended to receive. If the first line is omitted, then meme will
receive mail destined to bob also. If the second line is omitted then
meme's mail is also delivered to bob's maildir.

All because you can't have mupltiple maildir's specified!!!

If anyone knows another way to implement that I'd be interested also.
Remember that it you must be able to deliver a catch all to multiple
maildir's, and ideally be able to send a copy to any non local user
(eg. otherusergmail).

Thanks,
Adrian.

postconf -n output
--------------------------
command_directory = /usr/local/sbin
config_directory = /etc/postfix
daemon_directory = /usr/local/libexec/postfix
debug_peer_level = 2
mail_owner = _postfix
mailq_path = /usr/local/sbin/mailq
manpage_directory = /usr/local/man
newaliases_path = /usr/bin/newaliases
queue_directory = /var/spool/postfix
readme_directory = /usr/local/share/doc/postfix/readme
sample_directory = /etc/postfix
sendmail_path = /usr/local/sbin/sendmail
setgid_group = _postdrop
smtpd_sender_restrictions = reject_unknown_sender_domain
unknown_local_recipient_reject_code = 450
virtual_alias_domains = voyager.testdomain.com.au,ldap:ldapVirtualAliasDomains
virtual_alias_maps = hash:/etc/postfix/virtual,ldap:ldapVirtualAliasMaps2
virtual_gid_maps = static:5000
virtual_mailbox_base = /var/vmailhosts
virtual_mailbox_domains = stuff.com.au,ldap:ldapVirtualMailboxDomains
virtual_mailbox_maps = hash:/etc/postfix/vmailbox,ldap:ldapVirtualMailbox
virtual_minimum_uid = 100
virtual_uid_maps = static:5000