nix: move to flake.nix
[sourcephile-nix.git] / nixos / modules / services / databases / openldap.nix
index a27039c0bfdbb3e9855b39a1c78330112e1f643e..bc7a2ecc843d463d6456eaf95d3869898bc6a5eb 100644 (file)
 { pkgs, lib, config, ... }:
-let inherit (builtins) baseNameOf readFile;
-    inherit (lib) types;
-    inherit (pkgs.lib) unlinesAttrs;
-    inherit (config.services) openldap;
-    inherit (config.users) ldap;
-    # FIXME: readFIle ?
-    copyFile = file: pkgs.writeText (baseNameOf file) (readFile file);
+let
+  inherit (builtins) baseNameOf readFile;
+  inherit (lib) types;
+  inherit (config.services) openldap;
+  inherit (config.users) ldap;
+  unlines = lib.concatStringsSep "\n";
+  unlinesAttrs = f: as: unlines (lib.mapAttrsToList f as);
 in
 {
 options = {
-  services.openldap.domainSuffix = lib.mkOption {
-    type        = types.str;
-    default     = "dc=${lib.concatStringsSep ",dc=" (lib.splitString "." config.networking.domain)}";
-    description = ''LDAP suffix for config.networking.domain.'';
-  };
-  services.openldap.initConfig = lib.mkOption {
-    type = types.lines;
-    description = "The databases' initial config in LDIF.";
-    apply = lines: pkgs.writeText "cn=config.ldif.nix"
-      (lines + "\n" + unlinesAttrs (olcSuffix: {conf, olcDbDirectory, ...}:
-        "include: file://" + pkgs.writeText "config.ldif" (conf + ''
-          olcSuffix: ${olcSuffix}
-          olcDbDirectory: ${olcDbDirectory}
-        '')
-      ) openldap.databases);
-    default = ''
-      dn: cn=config
-      objectClass: olcGlobal
-      #olcPidFile: /run/slapd/slapd.pid
-      # List of arguments that were passed to the server
-      #olcArgsFile: /run/slapd/slapd.args
-      # Read slapd-config(5) for possible values
-      olcLogLevel: none
-      # The tool-threads parameter sets the actual amount of CPU's
-      # that is used for indexing.
-      olcToolThreads: 1
+services.openldap.cnConfig = lib.mkOption {
+  type = types.lines;
+  description = "The cn=config in LDIF";
+  apply = lines: pkgs.writeText "cn=config.ldif"
+    (lines + "\n" + unlinesAttrs (olcSuffix: {conf, olcDbDirectory, ...}:
+      "include: file://" + pkgs.writeText "config.ldif" (conf + ''
+        olcSuffix: ${olcSuffix}
+        olcDbDirectory: ${olcDbDirectory}
+      '')
+    ) openldap.databases);
+  default = ''
+    dn: cn=config
+    objectClass: olcGlobal
+    olcLogLevel: none
+    olcToolThreads: 1
 
-      dn: olcDatabase={-1}frontend,cn=config
-      objectClass: olcDatabaseConfig
-      objectClass: olcFrontendConfig
-      # The maximum number of entries that is returned for a search operation
-      olcSizeLimit: 500
-      # Allow unlimited access to local connection from the local root user
-      olcAccess: 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
-      olcAccess: to dn.exact=""
-        by * read
-      olcAccess: to dn.base="cn=Subschema"
-        by * read
+    dn: cn={0}module,cn=config
+    objectClass: olcModuleList
+    olcModulePath: ${pkgs.openldap}/lib/modules
+    #olcModuleLoad: pw-sha2
+    #olcModuleLoad: pw-pbkdf2
+    olcModuleLoad: back_mdb
 
-      dn: olcDatabase=config,cn=config
-      objectClass: olcDatabaseConfig
-      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
+    dn: olcDatabase={-1}frontend,cn=config
+    objectClass: olcDatabaseConfig
+    objectClass: olcFrontendConfig
+    olcSizeLimit: 500
+    # Allow unlimited access to local connection from the local root user
+    olcAccess: 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
+    olcAccess: to dn.exact=""
+      by * read
+    olcAccess: 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}
 
-      dn: cn=schema,cn=config
-      objectClass: olcSchemaConfig
+    dn: olcDatabase={0}config,cn=config
+    objectClass: olcDatabaseConfig
+    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
 
-      include: file://${pkgs.openldap}/etc/schema/core.ldif
-      include: file://${pkgs.openldap}/etc/schema/cosine.ldif
-      include: file://${pkgs.openldap}/etc/schema/nis.ldif
-      include: file://${pkgs.openldap}/etc/schema/inetorgperson.ldif
-      include: file://${copyFile openldap/schema/postfix-book.ldif}
+    dn: cn=schema,cn=config
+    objectClass: olcSchemaConfig
 
-      dn: cn=module{0},cn=config
-      objectClass: olcModuleList
-      # Where the dynamically loaded modules are stored
-      #olcModulePath: /usr/lib/ldap
-      olcModuleLoad: back_mdb
-    '';
-  };
-  services.openldap.databases = lib.mkOption {
-    default = {};
-    type = types.attrsOf (types.submodule ({name, options, config, ...}: {
-      options = {
-        conf = lib.mkOption {
-          type = types.lines;
-          description = "The database's config in LDIF.";
-        };
-        data = lib.mkOption {
-          type = types.lines;
-          description = "The database's data in LDIF.";
-        };
-        olcDbDirectory = lib.mkOption {
-          type = types.str;
-          description = "The directory where the database is stored.";
-          default = "${openldap.dataDir}/${name}";
-        };
-        resetData = lib.mkOption {
-          type = types.bool;
-          description = "Whether to reset the data at each start of the slapd service.";
-          default = false;
-        };
+    include: file://${pkgs.openldap}/etc/schema/core.ldif
+    include: file://${pkgs.openldap}/etc/schema/cosine.ldif
+    include: file://${pkgs.openldap}/etc/schema/nis.ldif
+    include: file://${pkgs.openldap}/etc/schema/inetorgperson.ldif
+  '';
+};
+services.openldap.databases = lib.mkOption {
+  default = {};
+  type = types.attrsOf (types.submodule ({name, options, config, ...}: {
+    options = {
+      conf = lib.mkOption {
+        type = types.lines;
+        description = "The database's config in LDIF.";
+      };
+      data = lib.mkOption {
+        type = types.nullOr types.lines;
+        description = "The database's data in LDIF.";
       };
-    }));
-  };
+      olcDbDirectory = lib.mkOption {
+        type = types.str;
+        description = "The directory where the database is stored.";
+        default = "${openldap.dataDir}/${name}";
+      };
+    };
+  }));
+};
 };
-config = {
-  systemd.services.openldap = {
-    preStart = ''
-        set -e
-        # NOTE: slapd's config is always re-initialized.
-        rm -rf "${openldap.configDir}"/cn=config \
-               "${openldap.configDir}"/cn=config.ldif
-        install -D -d -m 0700 -o "${openldap.user}" -g "${openldap.group}" "${openldap.configDir}"
-        # NOTE: olcDbDirectory must be created before adding the config.
-        '' +
-        unlinesAttrs (olcSuffix: {data, olcDbDirectory, resetData, ...}:
-          lib.optionalString resetData ''
-            rm -rf "${olcDbDirectory}"
-          '' + ''
-          install -D -d -m 0700 -o "${openldap.user}" -g "${openldap.group}" "${olcDbDirectory}"
-          '') openldap.databases
-        + ''
-        # NOTE: slapd is supposed to have been stopped by systemd
-        # before entering this preStart,
-        # hence slap* commands can safely be used.
-        #
-        # NOTE: slapadd(8):
-        # To populate the config database slapd-config(5),
-        # use -n 0 as it is always the first database.
-        # It must physically exist on the filesystem prior to this, however.
-        umask 0077
-        ${pkgs.openldap}/bin/slapadd -n 0 \
-         -F "${openldap.configDir}" \
-         -l ${openldap.initConfig}
-        chown -R "${openldap.user}:${openldap.group}" "${openldap.configDir}"
-      '' +
-      unlinesAttrs (olcSuffix: {data, olcDbDirectory, resetData, ...}:
-        lib.optionalString resetData ''
-          ${pkgs.openldap}/bin/slapadd \
-           -F "${openldap.configDir}" \
-           -l ${pkgs.writeText "data.ldif" data}
-        '' + ''
-        test ! -e "${olcDbDirectory}" ||
-        chown -R "${openldap.user}:${openldap.group}" "${olcDbDirectory}"
-      '') openldap.databases;
-  };
+config = lib.mkIf openldap.enable {
+systemd.services.openldap.preStart =
+  # olcDbDirectory must be created before adding the config.
+  ''
+  set -e
+  install -D -d -m 0700 -o "${openldap.user}" -g "${openldap.group}" "${openldap.configDir}"
+  '' +
+  unlinesAttrs (olcSuffix: {data, olcDbDirectory, ...}: lib.optionalString (data != null) ''
+    rm -rf "${olcDbDirectory}"
+    install -D -d -m 0700 -o "${openldap.user}" -g "${openldap.group}" "${olcDbDirectory}"
+  '') openldap.databases
+  # slapd is supposed to have been stopped by systemd
+  # before entering this preStart,
+  # hence slap* commands can safely be used.
+  #
+  # slapadd(8):
+  # To populate the config database slapd-config(5),
+  # use -n 0 as it is always the first database.
+  # It must physically exist on the filesystem prior to this, however.
+  + ''
+  umask 0077
+  rm -rf "${openldap.configDir}"/cn=config \
+         "${openldap.configDir}"/cn=config.ldif
+  ${pkgs.openldap}/bin/slapadd -n 0 \
+   -F "${openldap.configDir}" \
+   -l ${openldap.cnConfig}
+  chown -R "${openldap.user}:${openldap.group}" "${openldap.configDir}"
+  '' +
+  unlinesAttrs (olcSuffix: {data, olcDbDirectory, ...}: lib.optionalString (data != null) ''
+    ${pkgs.openldap}/bin/slapadd \
+     -F "${openldap.configDir}" \
+     -b ${olcSuffix} \
+     -l ${pkgs.writeText "data.ldif" data}
+    '' + ''
+    test ! -e "${olcDbDirectory}" ||
+    chown -R "${openldap.user}:${openldap.group}" "${olcDbDirectory}"
+  '') openldap.databases;
 };
 }