ldap: migrate to UUID based Dovecot home directories

The LDAP support was not in a good shape when it was merged. This is a
breaking change and course correction to apply best practices going
forward.

This fixes various issues experienced with the Dovecot LDAP home
directory.

The gravest issue is that the `homeDirectory` attribute from
the `posixAccount` schema would overwrite the Dovecot home directory and
cause permission errors. This was possible because we defined the home
variable in `default_fields` that is inherently mutable and just a preset
if no other value gets transmitted from LDAP. This did not surface in
tests, because our LDAP schema was too minimal compared to a common
production dataset.

The most annoying issue and the actual breaking change is that we now
default to UUID based home directories. Every entry in an IDM that
supports LDAP comes with a unique identifier that does not change upon
account name changes. We want those to enable simple account name
migrations that don't require any manual data migration.

To migrate existing dovecot home directories a migration script is
included, which will be backported to the 25.11 release, so the migration
can already be started from the previous release version.
This commit is contained in:
Martin Weinelt
2026-03-12 03:18:48 +01:00
parent fa0d5c9694
commit 091eda1ed2
3 changed files with 37 additions and 21 deletions
+8 -9
View File
@@ -61,6 +61,7 @@ let
postfixCfg = config.services.postfix;
ldapUuidAttribute = cfg.ldap.attributes.uuid;
ldapConfig = pkgs.writeTextFile {
name = "dovecot-ldap.conf.ext.template";
text = ''
@@ -76,9 +77,12 @@ let
auth_bind = yes
base = ${cfg.ldap.searchBase}
scope = ${mkLdapSearchScope cfg.ldap.searchScope}
${lib.optionalString (cfg.ldap.dovecot.userAttrs != null) ''
user_attrs = ${cfg.ldap.dovecot.userAttrs}
''}
user_attrs = \
${ldapUuidAttribute}=${ldapUuidAttribute}, \
=home=/var/vmail/ldap/%{ldap:${ldapUuidAttribute}}, \
=mail=maildir:~/mail${maildirLayoutAppendix}${maildirUTF8FolderNames}${
lib.optionalString (cfg.indexDir != null) ":INDEX=${cfg.indexDir}/ldap/%{ldap:${ldapUuidAttribute}}"
}
user_filter = ${cfg.ldap.dovecot.userFilter}
${lib.optionalString (cfg.ldap.dovecot.passAttrs != "") ''
pass_attrs = ${cfg.ldap.dovecot.passAttrs}
@@ -444,13 +448,8 @@ in
driver = ldap
args = ${ldapConfFile}
default_fields = \
home=${cfg.mailDirectory}/ldap/%{user} \
uid=${toString cfg.vmailUID} \
gid=${toString cfg.vmailUID} \
mail=maildir:~/mail${maildirLayoutAppendix}${maildirUTF8FolderNames}${
lib.optionalString (cfg.indexDir != null) ":INDEX=${cfg.indexDir}/ldap/%{user}"
}
gid=${toString cfg.vmailUID}
}
''}