chore: first attempt at solving the LDAP issues

Signed-off-by: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com>
This commit is contained in:
Georg Lauterbach 2026-04-04 17:44:38 +02:00
parent 7ff725f615
commit e797692a3d
No known key found for this signature in database
3 changed files with 42 additions and 20 deletions

View File

@ -4,18 +4,36 @@
# This prevents unnecessary auth failure logs triggering Fail2Ban when
# additional passdb are enabled (OAuth2).
passdb {
driver = ldap
mechanisms = plain login
# Replaced by ldap.sh
ldap_uris = REPLACED
ldap_base = REPLACED
ldap_auth_dn = REPLACED
ldap_auth_dn_password = REPLACED
# Path for LDAP configuration file, see example-config/dovecot-ldap.conf.ext
args = /etc/dovecot/dovecot-ldap.conf.ext
passdb ldap {
driver = ldap
user_filter = (&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))
fields {
default_pass_scheme = SSHA
tls = no
ldap_version = 3
pass_attrs = uniqueIdentifier=user,userPassword=password
user_attrs = mailHomeDirectory=home,mailUidNumber=uid,mailGidNumber=gid,mailStorageDirectory=mail
auth_bind = no
}
}
userdb {
userdb ldap {
driver = ldap
args = /etc/dovecot/dovecot-ldap.conf.ext
pass_filter = (&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))
# Default fields can be used to specify defaults that LDAP may override
#default_fields = home=/home/virtual/%u
fields {
default_pass_scheme = SSHA
tls = no
ldap_version = 3
pass_attrs = uniqueIdentifier=user,userPassword=password
user_attrs = mailHomeDirectory=home,mailUidNumber=uid,mailGidNumber=gid,mailStorageDirectory=mail
auth_bind = no
}
}

View File

@ -35,10 +35,10 @@ function _setup_ldap() {
declare -A DOVECOT_LDAP_MAPPING
DOVECOT_LDAP_MAPPING['DOVECOT_BASE']="${DOVECOT_BASE:="${LDAP_SEARCH_BASE}"}"
DOVECOT_LDAP_MAPPING['DOVECOT_DN']="${DOVECOT_DN:="${LDAP_BIND_DN}"}"
DOVECOT_LDAP_MAPPING['DOVECOT_DNPASS']="${DOVECOT_DNPASS:="${LDAP_BIND_PW}"}"
DOVECOT_LDAP_MAPPING['DOVECOT_URIS']="${DOVECOT_URIS:="${LDAP_SERVER_HOST}"}"
DOVECOT_LDAP_MAPPING['DOVECOT_LDAP_URIS']="${DOVECOT_URIS:="${LDAP_SERVER_HOST}"}"
DOVECOT_LDAP_MAPPING['DOVECOT_LDAP_BASE']="${DOVECOT_BASE:="${LDAP_SEARCH_BASE}"}"
DOVECOT_LDAP_MAPPING['DOVECOT_LDAP_AUTH_DN']="${DOVECOT_DN:="${LDAP_BIND_DN}"}"
DOVECOT_LDAP_MAPPING['DOVECOT_LDAP_AUTH_DN_PASSWORD']="${DOVECOT_DNPASS:="${LDAP_BIND_PW}"}"
# Default DOVECOT_PASS_FILTER to the same value as DOVECOT_USER_FILTER
DOVECOT_LDAP_MAPPING['DOVECOT_PASS_FILTER']="${DOVECOT_PASS_FILTER:="${DOVECOT_USER_FILTER}"}"
@ -47,7 +47,11 @@ function _setup_ldap() {
export "${VAR}=${DOVECOT_LDAP_MAPPING[${VAR}]}"
done
_replace_by_env_in_file 'DOVECOT_' '/etc/dovecot/dovecot-ldap.conf.ext'
_replace_by_env_in_file 'DOVECOT_' /etc/dovecot/conf.d/auth-ldap.conf.ext
sed -i -E \
-e 's|user_filter| filter|' \
-e 's|pass_filter| filter|' \
/etc/dovecot/conf.d/auth-ldap.conf.ext
_log 'trace' 'Enabling Dovecot LDAP authentication'

View File

@ -81,14 +81,14 @@ function setup_file() {
# As the `userID` is not a mail address, we ensure any domain-part is ignored, as a login name is not
# required to match the mail accounts actual `mail` attribute (nor the local-part), they are distinct.
# TODO: Docs should better cover this difference, as it does confuse some users of DMS (and past contributors to our tests..).
local SASLAUTHD_QUERY='(&(userID=%U)(mailEnabled=TRUE))'
local SASLAUTHD_QUERY='(&(userID=%{user | username})(mailEnabled=TRUE))'
# Dovecot is configured to lookup a user account by their login name (`userID` in this case, but it could be any attribute like `mail`).
# Dovecot syntax token `%n` is the local-part of the full email address supplied as the login name. There must be a unique match on `userID` (which there will be as each account is configured via LDIF to use it in their DN)
# Dovecot syntax token `%{user | username}` is the local-part of the full email address supplied as the login name. There must be a unique match on `userID` (which there will be as each account is configured via LDIF to use it in their DN)
# NOTE: We already have a constraint on the LDAP tree to search (`LDAP_SEARCH_BASE`), if all objects in that subtree use `PostfixBookMailAccount` class then there is no benefit in the extra constraint.
# TODO: For tests, that additional constraint is meaningless. We can detail it in our docs instead and just use `userID=%n`.
local DOVECOT_QUERY_PASS='(&(userID=%n)(objectClass=PostfixBookMailAccount))'
local DOVECOT_QUERY_USER='(&(userID=%n)(objectClass=PostfixBookMailAccount))'
# TODO: For tests, that additional constraint is meaningless. We can detail it in our docs instead and just use `userID=%{user | username}`.
local DOVECOT_QUERY_PASS='(&(userID=%{user | username})(objectClass=PostfixBookMailAccount))'
local DOVECOT_QUERY_USER='(&(userID=%{user | username})(objectClass=PostfixBookMailAccount))'
local ENV_LDAP_CONFIG=(
--env ACCOUNT_PROVISIONER=LDAP
@ -168,8 +168,8 @@ function setup_file() {
# Set default implicit container fallback for helpers:
export CONTAINER_NAME=${CONTAINER1_NAME}
}
export CONTAINER_NAME=${CONTAINER1_NAME}
function teardown_file() {
docker rm -f "${CONTAINER1_NAME}" "${CONTAINER2_NAME}"