my system is set up like this.

smtp --> postfix --> dovecot (via LMTP) --> mailbox

The tricky part is that authentication is against LDAP.

A typical LDAP entry looks like this:

CN=Jon Doe

What now happens is that postfix is pushing the mail to dovecot. Dovecot is performing an userdb lookup but based on the destination email address that is "jonny@example.com".

So LDAP looks for (uid=%u) which then is (uid=jonny@example.com).

Postfix is sending this via the virtual stack so the virtual part is set up like this:

virtual_alias_maps = ldap:/etc/postfix/ldap/ldap-aliases.cf
virtual_gid_maps = static:5000
virtual_mailbox_base = /
virtual_mailbox_domains = ldap:/etc/postfix/ldap/virtual_domains.cf

virtual_mailbox_maps = ldap:/etc/postfix/ldap/ldap-accounts.cf
virtual_minimum_uid = 5000
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_uid_maps = static:5000

What I expected is that postfix is using the virtual_mailbox_maps to lookup the user and pass that user to the LMTP so dovecot can do a userdb lookup. Since postfix does not know how to do it and i don't find a virtual_map* parameter that could do it, I don't know what the correct procedure would be.

Should postfix lookup the user via LDAP and send it to LMTP? Or should LMTP do a lookup on base of the recipient email address?

EDIT: I should add that the IMAP part of dovecot works fine when i connect with a mail client to receive the mail. It correctly looks up everything based on my login name which is uid. This of course is possible since when I login to IMAP I pass my uid so its easy to use it for dovecot.

I somehow have to tell dovecot to do it differently when postfix is using it...


hosts = localhost
dn = cn=linagent,ou=people,dc=example,dc=org
dnpass = SECRET
tls = no
auth_bind = yes
base = dc=example,dc=org
deref = never
scope = subtree
user_attrs = \
  =home=%{ldap:homeDirectory}, \
  =uid=5000, \
  =gid=5000, \
user_filter = (&(objectClass=inetOrgPerson)(uid=%u))
pass_attrs = uid=user,userPassword=password
pass_filter = (&(objectClass=inetOrgPerson)(uid=%u))
  • On your last question, I believe only Dovecot should do the LDAP lookup and then send to Postfix whether or not the user exists, as per this document: wiki2.dovecot.org/HowTo/PostfixDovecotLMTP. For your main question, I don't know the answer (yet). – Tommiie Sep 6 '18 at 8:50
  • see my own answer, i don't know it this is the most elegant style though. – tuxmania Sep 6 '18 at 9:20

I don't know if this is supposed to be like that but I changed the ldap configuration in dovecot like this:

user_filter = (&(objectClass=inetOrgPerson)(|(uid=%u)(mail=%u)))
pass_filter = (&(objectClass=inetOrgPerson)(|(uid=%u)(mail=%u)))

The part where uid=%u I need for authentication from a mail client because the mail client is logging in via UID (username).

The part where mail=%u I need for LMTP receiving from postfix and postfix just knows the recipient mail.

Since uid never is a mail address I guess this solution will work and not creating any conflicts. It also makes sense to me but I wonder why Courier could handle it more elegantly.

I will not resolve the question though since I think it is not the designed way.


Souldn't you use the %n variable instead of %u?
Check this : https://wiki.dovecot.org/Variables

And this is an extract of https://wiki2.dovecot.org/AuthDatabase/LDAP/Userdb

Variables and domains

User names and domains may be distinguished using the Variables %n and %d. They split the previous username at the "@" character. The previous username is:
- For LMTP, it will be user@hostname, where hostname depends on e.g. the Postfix configuration. - For IMAP, it will be whatever the password database has designated as the username. If the (LDAP) password database has "user_attrs = =user=%n", then the domain part of the login name will be stripped by the password database. The UserDB will not see any domain part, i.e. %n and %u are the same thing for the UserDB.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.