I can't seem to find documentation that shows how to set up 2 LDAP passdb blocks. I can get each of them working properly, but only the second of the two works at any given time. I can't figure out the syntax needed to get both to work, even though I've been all over the Dovecot 2.4x official documentation. The docs seem to suggest settings that the server rejects.
Anyone have any experience doing this, or know the correct syntax? Thanks in advance!
passdb ldap { # works when standalone; fails when combined with 2nd block below #passdb_name = ldap1 #driver = ldap ldap_version = 3 bind = yes bind_userdn = %{user|username} ldap_auth_dn = cn=dovecot,ou=apps,dc=example,dc=com ldap_auth_dn_password = D0vec0t ldap_base = ou=apps,dc=foscore,dc=com ldap_uris = ldapi://%2Frun%2Fldapi filter = (&(objectClass=applicationProcess)(cn=%{user})) passdb_ldap_bind = yes passdb_ldap_bind_userdn = cn=%{user},ou=apps,dc=example,dc=com result_success = return-ok } passdb ldap { #driver = ldap #name = ldap_users ldap_version = 3 bind = yes bind_userdn = %{user|username} ldap_auth_dn = cn=dovecot,ou=apps,dc=example,dc=com ldap_auth_dn_password = D0vec0t ldap_base = ou=people,dc=example,dc=com ldap_uris = ldapi://%2Frun%2Fldapi filter = (&(objectClass=posixAccount)(uid=%{user|username})(memberOf=cn=mail,ou=%{user|domain},ou=groups,dc=example,dc=com)) passdb_ldap_bind = yes passdb_ldap_bind_userdn = uid=%{user|username},ou=people,dc=example,dc=com result_success = return-ok }
On 02/06/2026 16:21 EEST Tom via dovecot <dovecot@dovecot.org> wrote:
I can't seem to find documentation that shows how to set up 2 LDAP passdb blocks. I can get each of them working properly, but only the second of the two works at any given time. I can't figure out the syntax needed to get both to work, even though I've been all over the Dovecot 2.4x official documentation. The docs seem to suggest settings that the server rejects.
Anyone have any experience doing this, or know the correct syntax? Thanks in advance!
you can share settings like this
ldap_auth_dn = cn=dovecot,ou=apps,dc=example,dc=com ldap_auth_dn_password = D0vec0t ldap_uris = ldapi://%2Frun%2Fldapi ldap_version = 3 ldap_bind = yes
passdb ldab-1 { driver = ldap ldap_bind_userdn = cn=%{user},ou=apps,dc=example,dc=com ldap_filter = (&(objectClass=applicationProcess)(cn=%{user})) }
passdb ldap-2 { driver = ldap ldap_bind_userdn = cn=%{user},ou=apps,dc=example,dc=com ldap_filter = (&(objectClass=posixAccount)(uid=%{user|username})(memberOf=cn=mail,ou=%{user|domain},ou=groups,dc=example,dc=com)) }
Aki
On 02/06/2026 16:33 EEST Aki Tuomi via dovecot <dovecot@dovecot.org> wrote:
On 02/06/2026 16:21 EEST Tom via dovecot <dovecot@dovecot.org> wrote:
I can't seem to find documentation that shows how to set up 2 LDAP passdb blocks. I can get each of them working properly, but only the second of the two works at any given time. I can't figure out the syntax needed to get both to work, even though I've been all over the Dovecot 2.4x official documentation. The docs seem to suggest settings that the server rejects.
Anyone have any experience doing this, or know the correct syntax? Thanks in advance!
you can share settings like this
ldap_auth_dn = cn=dovecot,ou=apps,dc=example,dc=com ldap_auth_dn_password = D0vec0t ldap_uris = ldapi://%2Frun%2Fldapi ldap_version = 3 ldap_bind = yes
passdb ldab-1 { driver = ldap ldap_bind_userdn = cn=%{user},ou=apps,dc=example,dc=com ldap_filter = (&(objectClass=applicationProcess)(cn=%{user})) }
passdb ldap-2 { driver = ldap ldap_bind_userdn = cn=%{user},ou=apps,dc=example,dc=com ldap_filter = (&(objectClass=posixAccount)(uid=%{user|username})(memberOf=cn=mail,ou=%{user|domain},ou=groups,dc=example,dc=com)) }
Aki
Sorry, small mistake
ldap_bind = yes => passdb_ldap_bind = yes
Aki
On 2026-06-02 09:36, Aki Tuomi via dovecot wrote:
I can't seem to find documentation that shows how to set up 2 LDAP passdb blocks. I can get each of them working properly, but only the second of the two works at any given time. I can't figure out the syntax needed to get both to work, even though I've been all over the Dovecot 2.4x official documentation. The docs seem to suggest settings that the server rejects.
Anyone have any experience doing this, or know the correct syntax? Thanks in advance!
you can share settings like this
ldap_auth_dn = cn=dovecot,ou=apps,dc=example,dc=com ldap_auth_dn_password = D0vec0t ldap_uris = ldapi://%2Frun%2Fldapi ldap_version = 3 ldap_bind = yes
passdb ldab-1 { driver = ldap ldap_bind_userdn = cn=%{user},ou=apps,dc=example,dc=com ldap_filter = (&(objectClass=applicationProcess)(cn=%{user})) }
passdb ldap-2 { driver = ldap ldap_bind_userdn = cn=%{user},ou=apps,dc=example,dc=com ldap_filter = (&(objectClass=posixAccount)(uid=%{user|username})(memberOf=cn=mail,ou=%{user|domain},ou=groups,dc=example,dc=com)) }
Aki
Sorry, small mistake
ldap_bind = yes => passdb_ldap_bind = yes
Thanks for your replies.
2026.06.02 13:52:40 auth(example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>: Debug: sasl(plain): Set authid 'example@example.net' 2026.06.02 13:52:40 auth(example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>: Debug: sasl(plain): Performing plain passdb verification 2026.06.02 13:52:40 auth(example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>: Debug: ldap-1: Performing passdb lookup 2026.06.02 13:52:40 auth(example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>: Debug: ldap-1: Finished passdb lookup 2026.06.02 13:52:40 auth(example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>: Debug: ldap-2: Performing passdb lookup 2026.06.02 13:52:40 auth(example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>: Debug: ldap-2: Finished passdb lookup 2026.06.02 13:52:43 auth(example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>: Debug: sasl(plain): Finished plain passdb verification (status=internal-failure) 2026.06.02 13:52:43 auth(example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>: Debug: sasl(plain): Interaction failed (internal failure) 2026.06.02 13:52:43 auth(example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>: Debug: Auth request finished 2026.06.02 13:52:43 auth(example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>: Debug: immediate auth failure due to internal failure
Not getting either one to work. This is with full debugging on. It looks like the internal error happens instantly, no attempt to contact the directory.
Can you send doveconf -n
Aki
On 02/06/2026 21:10 EEST Tom via dovecot <[1]dovecot@dovecot.org> wrote:
On 2026-06-02 09:36, Aki Tuomi via dovecot wrote:
>>> I can't seem to find documentation that shows how to set up 2 LDAP
passdb blocks. I can get each of them working properly, but only the
second of the two works at any given time. I can't figure out the syntax
needed to get both to work, even though I've been all over the Dovecot
2.4x official documentation. The docs seem to suggest settings that the
server rejects.
>>>
>>> Anyone have any experience doing this, or know the correct syntax?
Thanks in advance!
>>
>> # you can share settings like this
>> ldap_auth_dn = cn=dovecot,ou=apps,dc=example,dc=com
>> ldap_auth_dn_password = D0vec0t
>> ldap_uris = ldapi://%2Frun%2Fldapi
>> ldap_version = 3
>> ldap_bind = yes
>>
>> passdb ldab-1 {
>> driver = ldap
>> ldap_bind_userdn = cn=%{user},ou=apps,dc=example,dc=com
>> ldap_filter = (&(objectClass=applicationProcess)(cn=%{user}))
>> }
>>
>> passdb ldap-2 {
>> driver = ldap
>> ldap_bind_userdn = cn=%{user},ou=apps,dc=example,dc=com
>> ldap_filter =
(&(objectClass=posixAccount)(uid=%{user|username})(memberOf=cn=mail,ou=%{user|domain},ou=groups,dc=example,dc=com))
>> }
>>
>> Aki
Sorry, small mistake
ldap_bind = yes => passdb_ldap_bind = yes
Thanks for your replies.
2026.06.02 13:52:40
auth([2]example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>:
Debug: sasl(plain): Set authid [3]'example@example.net'
2026.06.02 13:52:40
auth([4]example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>:
Debug: sasl(plain): Performing plain passdb verification
2026.06.02 13:52:40
auth([5]example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>:
Debug: ldap-1: Performing passdb lookup
2026.06.02 13:52:40
auth([6]example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>:
Debug: ldap-1: Finished passdb lookup
2026.06.02 13:52:40
auth([7]example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>:
Debug: ldap-2: Performing passdb lookup
2026.06.02 13:52:40
auth([8]example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>:
Debug: ldap-2: Finished passdb lookup
2026.06.02 13:52:43
auth([9]example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>:
Debug: sasl(plain): Finished plain passdb verification
(status=internal-failure)
2026.06.02 13:52:43
auth([10]example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>:
Debug: sasl(plain): Interaction failed (internal failure)
2026.06.02 13:52:43
auth([11]example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>:
Debug: Auth request finished
2026.06.02 13:52:43
auth([12]example@example.net,10.0.0.99,sasl:plain)<qgg2+khTlLgKAABj>:
Debug: immediate auth failure due to internal failure
Not getting either one to work. This is with full debugging on. It looks
like the internal error happens instantly, no attempt to contact the
directory.
_______________________________________________
dovecot mailing list -- [13]dovecot@dovecot.org
To unsubscribe send an email to [14]dovecot-leave@dovecot.org
References
Visible links
- mailto:dovecot@dovecot.org
- mailto:example@example.net
- mailto:'example@example.net
- mailto:example@example.net
- mailto:example@example.net
- mailto:example@example.net
- mailto:example@example.net
- mailto:example@example.net
- mailto:example@example.net
- mailto:example@example.net
- mailto:example@example.net
- mailto:example@example.net
- mailto:dovecot@dovecot.org
- mailto:dovecot-leave@dovecot.org
On 2026-06-02 15:08, Aki Tuomi wrote:
Can you send doveconf -n
2.4.4 (8b687aa65c): /etc/dovecot/dovecot.conf
Pigeonhole version 2.4.4 (3beb331a)
OS: Linux 7.0.10-200.fc44.x86_64 x86_64 Fedora release 44 (Forty Four) btrfs
Hostname: fox.example.com
dovecot_config_version = 2.4.3 auth_debug = yes auth_debug_passwords = yes auth_verbose = yes debug_log_path = /var/log/dovecot/dovecot-debug.log dovecot_storage_version = 2.4.3 first_valid_uid = 1000 hostname = mail.example.com info_log_path = /var/log/dovecot/dovecot.log ldap_auth_dn = cn=dovecot,ou=apps,dc=example,dc=com ldap_auth_dn_password = # hidden, use -P to show it ldap_uris = ldapi://%2Frun%2Fldapi log_debug = category=auth log_path = /var/log/dovecot/dovecot-errors.log log_timestamp = "%Y.%m.%d %H:%M:%S " mail_debug = yes mail_driver = maildir mail_home = /home/%{user|username} mail_path = /home/%{user|username}/Maildir/%{user|domain} protocols { imap = yes lmtp = yes sieve = yes } sieve_global_extensions { vnd.dovecot.debug = yes vnd.dovecot.environment = yes vnd.dovecot.pipe = yes } sieve_pipe_bin_dir = /var/lib/dovecot/sieve sieve_plugins { sieve_imapsieve = yes sieve_extprograms = yes } sieve_user_log_path = ~/.sieve/log ssl = required ssl_cipher_list = PROFILE=SYSTEM ssl_server { cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem } namespace inbox { inbox = yes mailbox Junk { auto = subscribe special_use = "\\Junk" } mailbox Spam { auto = create special_use = "\\Junk" } } service imap-login { process_limit = 200 } service auth { auth_mechanisms = plain login cram-md5 auth_verbose = yes auth_verbose_passwords = yes inet_listener auth { port = 2003 ssl = yes } } service lmtp { executable = lmtp -L inet_listener lmtp { port = 240 ssl = yes } unix_listener /var/spool/postfix/private/dovecot-lmtp { group = postfix mode = 0600 user = postfix } } protocol lmtp { info_log_path = /var/log/dovecot/dovecot-lmtp.log log_path = /var/log/dovecot/dovecot-lmtp-errors.log mail_plugins { sieve = yes } } passdb ldap-1 { driver = ldap ldap_filter = (&(objectClass=posixAccount)(uid=%{user|username})(memberOf=cn=mail,ou=%{user|domain},ou=groups,dc=example,dc=com)) result_success = return-ok passdb_ldap { bind_userdn = cn=%{user},ou=apps,dc=example,dc=com } } passdb ldap-2 { driver = ldap ldap_filter = (&(objectClass=applicationProcess)(cn=%{user})) result_success = return-ok passdb_ldap { bind_userdn = uid=%{user|username},ou=people,dc=example,dc=com } } userdb ldap { ldap_auth_dn = cn=dovecot,ou=apps,dc=example,dc=com ldap_auth_dn_password = # hidden, use -P to show it ldap_base = ou=people,dc=example,dc=com ldap_uris = ldapi://%2Frun%2Fldapi ldap_version = 3 fields { gid = %{ldap:gidNumber} home = %{ldap:homeDirectory} mail = %{ldap:homeDirectory}/Maildir/%{user|domain} uid = %{ldap:uidNumber} } filter = (&(objectClass=posixAccount)(uid=%{user|username})(memberOf=cn=mail,ou=%{user|domain},ou=groups,dc=example,dc=com)) } protocol imap { mail_plugins { imap_sieve = yes } } mailbox Spam { sieve_script report-spam { cause = copy path = /etc/dovecot/sieve/report-spam.sieve type = before } } imapsieve_from Spam { sieve_script report-ham { cause = copy path = /etc/dovecot/sieve/report-ham.sieve type = before } } sieve_script personal { active_path = ~/.sieve/dovecot.sieve path = ~/.sieve type = personal } sieve_script default { driver = file name = default path = /var/lib/dovecot/sieve/default.sieve type = default } protocol sieve { sieve_global_extensions = vnd.dovecot.pipe sieve_plugins { sieve_imapsieve = yes sieve_extprograms = yes } } imapsieve_from Junk { sieve_script learn-ham { cause = COPY APPEND path = /var/lib/dovecot/sieve/learn-ham.sieve type = before } } mailbox Junk { sieve_script learn-spam { cause = COPY path = /var/lib/dovecot/sieve/learn-spam.sieve type = before } }
On 03/06/2026 17:57 EEST Tom via dovecot <dovecot@dovecot.org> wrote:
On 2026-06-02 15:08, Aki Tuomi wrote:
Can you send doveconf -n
Hi!
Small optimization:
userdb ldap { ldap_base = ou=people,dc=example,dc=com fields { gid = %{ldap:gidNumber} home = %{ldap:homeDirectory} mail = %{ldap:homeDirectory}/Maildir/%{user|domain} uid = %{ldap:uidNumber} } filter = (&(objectClass=posixAccount)(uid=%{user|username})(memberOf=cn=mail,ou=%{user|domain},ou=groups,dc=example,dc=com)) }
Also I think the problem happens on LDAP connection. Can you set ldap_debug_level=9?
Aki
On 2026-06-03 12:49, Aki Tuomi via dovecot wrote:
Small optimization: userdb ldap { ldap_base = ou=people,dc=example,dc=com fields { gid = %{ldap:gidNumber} home = %{ldap:homeDirectory} mail = %{ldap:homeDirectory}/Maildir/%{user|domain} uid = %{ldap:uidNumber} } filter = (&(objectClass=posixAccount)(uid=%{user|username})(memberOf=cn=mail,ou=%{user|domain},ou=groups,dc=example,dc=com)) }
Unfortunately that broke things.
Also I think the problem happens on LDAP connection. Can you set ldap_debug_level=9?
That was already maxed out, but yes, very useful. I love it when services have the ability to turn logging up to extremely detailed levels.
Anyway, I managed to solve the issue. Here's what I have:
ldap_auth_dn = cn=dovecot,ou=apps,dc=example,dc=com ldap_auth_dn_password = D0vec0t ldap_uris = ldapi://%2Frun%2Fldapi ldap_version = 3 passdb_ldap_bind = yes
passdb ldap-1 { driver = ldap ldap_base = ou=apps,dc=example,dc=com ldap_filter = (&(objectClass=posixAccount)(uid=%{user|username})(memberOf=cn=mail,ou=%{user|domain},ou=groups,dc=example,dc=com)) passdb_ldap_bind_userdn = cn=%{user},ou=apps,dc=example,dc=com result_success = return-ok } passdb ldap-2 { driver = ldap ldap_base = ou=people,dc=example,dc=com ldap_filter = (&(objectClass=applicationProcess)(cn=%{user})) passdb_ldap_bind_userdn = uid=%{user|username},ou=people,dc=example,dc=com result_success = return-ok }
The difference was ldap_base turned out to be a requirement.
This is valuable information IMO because the 2.4x documentation is extensive but lacking examples sometimes.
participants (2)
-
Aki Tuomi
-
Tom