{ pkgs, lib, config, host, ... }: let inherit (builtins) baseNameOf readFile; inherit (lib) types; inherit (pkgs.lib) unlinesAttrs; inherit (config) networking; inherit (config.services) openldap; inherit (config.users) ldap; domainSuffix = "dc=" + lib.concatStringsSep ",dc=" (lib.splitString "." networking.domain); in { imports = [ openldap/sourcephile.fr.nix openldap/autogeree.net.nix ]; users.ldap = { enable = false; # FIXME: reset to ldapi:/// once https://nixpk.gs/pr-tracker.html?pr=179597 is included #server = "ldapi:///"; server = "ldapi://%2Frun%2Fslapd%2Fsock"; base = "ou=posix,${domainSuffix}"; bind = { #distinguishedName = "cn=admin,${domainSuffix}"; }; daemon = { enable = false; extraConfig = '' log syslog info sasl_mech EXTERNAL # NOTE: nslcd cannot use SASL to bind to rootpwmoddn # which is the DN used by nslcd when passwd is run by root # to change the userPassword of an LDAP user. # SEE: https://www.reddit.com/r/linuxadmin/comments/53sxpl/how_do_i_configure_nslcd_to_use_a_sasl_external/d7w9awd/ # Thus, use: ldappasswd -H ldapi:// -Y EXTERNAL uid=$user,ou=accounts,ou=posix,dc=sourcephile,dc=fr ''; }; }; services.openldap = { enable = true; #dataDir = "/var/db/ldap"; #configDir = "/var/db/slapd"; # FIXME: reset to ldapi:/// #urlList = [ "ldapi:///" ]; # UNIX socket urlList = [ "ldapi://%%2Frun%%2Fslapd%%2Fsock" ]; # UNIX socket # sudo ldapsearch -LLL -H ldapi:// -D cn=admin,cn=config -Y EXTERNAL -b "" -s base supportedControl settings = { attrs = { objectClass = "olcGlobal"; olcLogLevel = [ "stats" ]; # The tool-threads parameter sets the actual amount of CPU's # that is used for indexing. olcToolThreads = toString host.CPUs; }; children = { "cn=schema".includes = [ "${pkgs.openldap}/etc/schema/core.ldif" "${pkgs.openldap}/etc/schema/cosine.ldif" "${pkgs.openldap}/etc/schema/nis.ldif" "${pkgs.openldap}/etc/schema/inetorgperson.ldif" "${openldap/schema/postfix-book.ldif}" ]; # The first database is the special frontend database # whose settings are applied globally to all the other databases. # Beware that cn={0}module,cn=config must appear before # for enabling password schemes provided by the modules in olcPasswordHash. # ldapsearch -LLL -H ldapi:// -D cn=admin,cn=config -Y EXTERNAL -b 'olcDatabase={-1}frontend,cn=config' -s sub '*' "olcDatabase={-1}frontend".attrs = { objectClass = [ "olcDatabaseConfig" "olcFrontendConfig" ]; olcDatabase = "{-1}frontend"; # The maximum number of entries that is returned for a search operation olcSizeLimit = "500"; olcAccess = [ # Allow unlimited access to local connection from the local root user ''to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break '' # Allow unauthenticated read access for schema and base DN autodiscovery ''to dn.exact="" by * read '' ''to dn.base="cn=Subschema" by * read '' ]; # Hash algorithm to be used by LDAP Password Modify Extended Operation or the ppolicy overlay #olcPasswordHash = "{PBKDF2-SHA256}"; olcPasswordHash = "{SSHA}"; }; "cn={0}module".attrs = { objectClass = [ "olcModuleList" ]; olcModulePath = "${pkgs.openldap}/lib/modules"; #olcModuleLoad = "pw-sha2"; #olcModuleLoad = "pw-pbkdf2"; olcModuleLoad = "back_mdb"; }; "olcDatabase={0}config".attrs = { objectClass = "olcDatabaseConfig"; olcDatabase = "{0}config"; olcRootDN = "cn=admin,cn=config"; # Access to cn=config, system root can be manager # with SASL mechanism (-Y EXTERNAL) over unix socket (-H ldapi://) olcAccess = [ ''to * by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by * break '' ]; }; }; }; /* cnConfig = '' dn: cn=schema,cn=config objectClass: olcSchemaConfig dn: olcBackend=mdb,cn=config objectClass: olcBackendConfig ''; */ }; }