ldap: make uid the default account name

I fail to understand how mail became the uidAttribute way back when LDAP
support was introduced, but it was unintentional and clearly a mistake.

The uid attribute is the standard system login name per RFC4519 2.39 and
what we default to going forward.
This commit is contained in:
Martin Weinelt
2026-03-12 02:33:06 +01:00
parent a87d01ea79
commit 762f553643
4 changed files with 36 additions and 21 deletions
+13 -5
View File
@@ -445,8 +445,11 @@ in
dovecot = {
userFilter = mkOption {
type = types.str;
default = "mail=%{user}";
example = "(&(objectClass=inetOrgPerson)(mail=%{user}))";
default = with cfg.ldap.attributes; "(|(${mail}=%{user})(${username}=%{user}))";
defaultText = literalExpression ''
with config.mailserver.ldap.attributes; "(|(''${mail}=%{user})(''${username}=%{user}))";
'';
example = "(|(mail=%{user})(uid=%{user}))";
description = ''
LDAP filter used for LMTP delivery from Postfix and post-login
information construction, like the home directory.
@@ -459,8 +462,13 @@ in
passFilter = mkOption {
type = types.nullOr types.str;
default = "mail=%{user}";
example = "(&(objectClass=inetOrgPerson)(mail=%{user}))";
default = with cfg.ldap.attributes; "${username}=%{user}";
defaultText = lib.literalExpression ''
with config.mailserver.ldap.attributes; "''${username}=%{user}";
'';
example =
with cfg.ldap.attributes;
"(&(memberOf=cn=mail_users,ou=groups,dc=example,dc=com)(${username}=%{user}))";
description = ''
LDAP filter used to restrict which users are eligible to
authenticate against Dovecot.
@@ -479,7 +487,7 @@ in
defaultText = lib.literalExpression ''
with config.mailserver.ldap.attributes; "''${mail}=%s";
'';
example = "(&(objectClass=inetOrgPerson)(mail=%s))";
example = "(mail=%s)";
description = ''
LDAP filter used to search for an account by mail, where `%s` is a
substitute for the address in question.
+5
View File
@@ -22,6 +22,11 @@ NixOS 26.05
established by `agenix`_/`sops-nix`_ that instead rely on encryption. This
option prevents files from leaking in to the Nix store.
See :option:`mailserver.loginAccounts.<name>.passwordFile`.
- The default login username for LDAP users has changed from the ``mail`` to
the ``uid`` attribute. This allows users to login with their account name
rather than their email address, which is more convenient and consistent
with typical LDAP practices. The exact attribute can be customized through
:option:`mailserver.ldap.attributes.username`.
- The following integrations are deprecated and will be removed before the next
release:
+1 -1
View File
@@ -222,7 +222,7 @@ let
ldapSenderLoginMap = pkgs.writeText "ldap-sender-login-map.cf" ''
${commonLdapConfig}
query_filter = ${cfg.ldap.postfix.filter}
result_attribute = ${cfg.ldap.attributes.mail}
result_attribute = ${cfg.ldap.attributes.username}
'';
ldapSenderLoginMapFile = "/run/postfix/ldap-sender-login-map.cf";
appendPwdInSenderLoginMap = appendLdapBindPwd {
+17 -15
View File
@@ -74,7 +74,7 @@ in
dn: cn=alice,ou=users,dc=example
entryUUID: c52f777b-a6e8-4507-80f9-c4de47e8520d
objectClass: inetOrgPerson
cn: alice
uid: alice
sn: Foo
mail: alice@example.com
userPassword: ${alicePassword}
@@ -83,7 +83,6 @@ in
entryUUID: f3b4e8ea-087f-42cc-95f0-cbfd99386092
objectClass: inetOrgPerson
objectClass: posixAccount
cn: bob
uid: bob
uidNumber: 9999
gidNumber: 9999
@@ -161,16 +160,19 @@ in
raise
with subtest("Test postmap lookups"):
test_lookup("postconf virtual_mailbox_maps", "alice@example.com", "alice@example.com")
test_lookup("postconf -P submission/inet/smtpd_sender_login_maps", "alice@example.com", "alice@example.com")
test_lookup("postconf virtual_mailbox_maps", "alice@example.com", "alice")
test_lookup("postconf -P submission/inet/smtpd_sender_login_maps", "alice@example.com", "alice")
test_lookup("postconf virtual_mailbox_maps", "bob@example.com", "bob@example.com")
test_lookup("postconf -P submission/inet/smtpd_sender_login_maps", "bob@example.com", "bob@example.com")
test_lookup("postconf virtual_mailbox_maps", "bob@example.com", "bob")
test_lookup("postconf -P submission/inet/smtpd_sender_login_maps", "bob@example.com", "bob")
with subtest("Test doveadm lookups"):
machine.succeed("doveadm user -u alice@example.com")
machine.succeed("doveadm user -u bob@example.com")
machine.succeed("doveadm user -u alice")
machine.log(machine.succeed("doveadm user -u bob"))
machine.succeed("doveadm user -f uid bob@example.com | grep ${toString nodes.machine.mailserver.vmailUID}")
machine.succeed("doveadm user -f gid bob@example.com | grep ${toString nodes.machine.mailserver.vmailUID}")
@@ -187,16 +189,16 @@ in
"--smtp-port 587",
"--smtp-starttls",
"--smtp-host localhost",
"--smtp-username alice@example.com",
"--smtp-username alice",
"--imap-host localhost",
"--imap-username bob@example.com",
"--imap-username bob",
"--from-addr bob@example.com",
"--to-addr aliceb@example.com",
"--src-password-file <(echo '${alicePassword}')",
"--dst-password-file <(echo '${bobPassword}')",
"--ignore-dkim-spf"
]))
machine.succeed("journalctl -u postfix | grep -q 'Sender address rejected: not owned by user alice@example.com'")
machine.succeed("journalctl -u postfix | grep -q 'Sender address rejected: not owned by user alice'")
with subtest("Test mail delivery via implicit TLS"):
machine.succeed(" ".join([
@@ -204,9 +206,9 @@ in
"--smtp-port 465",
"--smtp-ssl",
"--smtp-host localhost",
"--smtp-username alice@example.com",
"--smtp-username alice",
"--imap-host localhost",
"--imap-username bob@example.com",
"--imap-username bob",
"--from-addr alice@example.com",
"--to-addr bob@example.com",
"--src-password-file <(echo '${alicePassword}')",
@@ -220,9 +222,9 @@ in
"--smtp-port 587",
"--smtp-starttls",
"--smtp-host localhost",
"--smtp-username alice@example.com",
"--smtp-username alice",
"--imap-host localhost",
"--imap-username bob@example.com",
"--imap-username bob",
"--from-addr alice@example.com",
"--to-addr bob_fw@example.com",
"--src-password-file <(echo '${alicePassword}')",
@@ -236,7 +238,7 @@ in
"--smtp-port 465",
"--smtp-ssl",
"--smtp-host localhost",
"--smtp-username bob@example.com",
"--smtp-username bob",
"--imap-host localhost",
"--imap-username alice@example.com",
"--from-addr bob_fw@example.com",
@@ -245,7 +247,7 @@ in
"--dst-password-file <(echo '${alicePassword}')",
"--ignore-dkim-spf"
]))
machine.succeed("journalctl -u postfix | grep -q 'Sender address rejected: not owned by user bob@example.com'")
machine.succeed("journalctl -u postfix | grep -q 'Sender address rejected: not owned by user bob'")
'';
}