diff --git a/default.nix b/default.nix index 9be324e..995de30 100644 --- a/default.nix +++ b/default.nix @@ -483,13 +483,21 @@ in }; password = mkOption { - type = types.str; - default = "userPassword"; - example = "unix_password"; + type = types.nullOr types.str; + default = null; + example = "userPassword"; description = '' The LDAP attribute referencing the account password used to login with. + The account passwords stored in LDAP must be hashed with a supported + [Password Scheme] in order for Dovecot to understand them. + Typically the `userPassword` attribute which is part of the `inetOrgPerson` schema. + + If `null`, [Authentication Binds] will be used instead. + + [Password Scheme]: https://doc.dovecot.org/2.4.4/core/config/auth/schemes.html + [Authentication Binds]: https://doc.dovecot.org/2.4.4/core/config/auth/databases/ldap.html#authentication-binds ''; }; diff --git a/mail-server/dovecot.nix b/mail-server/dovecot.nix index 7c4f439..dc51c61 100644 --- a/mail-server/dovecot.nix +++ b/mail-server/dovecot.nix @@ -437,8 +437,9 @@ in "passdb ldap" = { driver = "ldap"; filter = cfg.ldap.dovecot.passFilter; + bind = cfg.ldap.attributes.password == null; fields = { - password = "%{ldap:${cfg.ldap.attributes.password}}"; + password = mkIf (cfg.ldap.attributes.password != null) "%{ldap:${cfg.ldap.attributes.password}}"; }; ldap_connection_group = "ldap-passdb-conn"; }; diff --git a/tests/ldap.nix b/tests/ldap.nix index 7a771ad..4425b53 100644 --- a/tests/ldap.nix +++ b/tests/ldap.nix @@ -25,7 +25,7 @@ in nodes = { machine = - { pkgs, ... }: + { pkgs, lib, ... }: { imports = [ ../default.nix @@ -166,12 +166,51 @@ in }; base = "ou=users,dc=example"; scope = "sub"; + attributes = { + # disable auth bind + password = "userPassword"; + }; }; forwards = { "bob_fw@example.com" = "bob@example.com"; }; }; + + specialisation.auth_bind = { + inheritParentConfig = true; + configuration = { + mailserver = { + ldap = { + attributes = { + # enable auth bind + password = lib.mkForce null; + }; + }; + }; + + services.openldap.settings.children = { + "olcDatabase={1}mdb" = { + attrs = { + olcAccess = [ + # disallow access to userPassword + '' + to * attrs=userPassword + by anonymous auth + by * none + '' + + # default policy (same as if we would specify none as all) + '' + to * + by * read + '' + ]; + }; + }; + }; + }; + }; }; }; testScript = @@ -331,5 +370,10 @@ in "--dst-password-file <(echo '${malloryPassword}')", "--ignore-dkim-spf" ])) + + with subtest("LDAP Authentication Binds"): + machine.succeed("/run/booted-system/specialisation/auth_bind/bin/switch-to-configuration test") + machine.wait_for_unit("openldap.service") + machine.succeed("doveadm auth test alice '${alicePassword}'") ''; }