]> Git — Sourcephile - sourcephile-nix.git/blob - nixos/modules/services/databases/openldap.nix
openldap: enable SHA2 and PBKDF2 support
[sourcephile-nix.git] / nixos / modules / services / databases / openldap.nix
1 { pkgs, lib, config, ... }:
2 let inherit (builtins) baseNameOf readFile;
3 inherit (lib) types;
4 inherit (pkgs.lib) unlinesAttrs;
5 inherit (config.services) openldap;
6 inherit (config.users) ldap;
7 in
8 {
9 options = {
10 services.openldap.initConfig = lib.mkOption {
11 type = types.lines;
12 description = "The databases' initial config in LDIF.";
13 apply = lines: pkgs.writeText "cn=config.ldif"
14 (lines + "\n" + unlinesAttrs (olcSuffix: {conf, olcDbDirectory, ...}:
15 "include: file://" + pkgs.writeText "config.ldif" (conf + ''
16 olcSuffix: ${olcSuffix}
17 olcDbDirectory: ${olcDbDirectory}
18 '')
19 ) openldap.databases);
20 # sudo ldapsearch -LLL -H ldapi:// -D cn=admin,cn=config -Y EXTERNAL -b "" -s base supportedControl
21 default = ''
22 dn: cn=config
23 objectClass: olcGlobal
24 olcLogLevel: none
25 # The tool-threads parameter sets the actual amount of CPU's
26 # that is used for indexing.
27 olcToolThreads: ${config.nix.maxJobs}
28
29 dn: cn={0}module,cn=config
30 objectClass: olcModuleList
31 olcModulePath: ${pkgs.openldap}/lib/modules
32 olcModuleLoad: pw-sha2
33 olcModuleLoad: pw-pbkdf2
34 olcModuleLoad: back_mdb
35
36 # The first database is the special frontend database
37 # whose settings are applied globally to all the other databases.
38 # Beware that cn={0}module,cn=config must appear before
39 # for enabling password schemes provided by the modules in olcPasswordHash.
40 # ldapsearch -LLL -H ldapi:// -D cn=admin,cn=config -Y EXTERNAL -b 'olcDatabase={-1}frontend,cn=config' -s sub '*'
41 dn: olcDatabase={-1}frontend,cn=config
42 objectClass: olcDatabaseConfig
43 objectClass: olcFrontendConfig
44 # The maximum number of entries that is returned for a search operation
45 olcSizeLimit: 500
46 # Allow unlimited access to local connection from the local root user
47 olcAccess: to *
48 by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
49 by * break
50 # Allow unauthenticated read access for schema and base DN autodiscovery
51 olcAccess: to dn.exact=""
52 by * read
53 olcAccess: to dn.base="cn=Subschema"
54 by * read
55 # Hash algorithm to be used by LDAP Password Modify Extended Operation or the ppolicy overlay
56 olcPasswordHash: {PBKDF2-SHA256}
57
58 dn: olcDatabase={0}config,cn=config
59 objectClass: olcDatabaseConfig
60 olcRootDN: cn=admin,cn=config
61 # Access to cn=config, system root can be manager
62 # with SASL mechanism (-Y EXTERNAL) over unix socket (-H ldapi://)
63 olcAccess: to *
64 by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
65 by * break
66
67 dn: cn=schema,cn=config
68 objectClass: olcSchemaConfig
69
70 include: file://${pkgs.openldap}/etc/schema/core.ldif
71 include: file://${pkgs.openldap}/etc/schema/cosine.ldif
72 include: file://${pkgs.openldap}/etc/schema/nis.ldif
73 include: file://${pkgs.openldap}/etc/schema/inetorgperson.ldif
74 include: file://${openldap/schema/postfix-book.ldif}
75 '';
76 };
77 services.openldap.databases = lib.mkOption {
78 default = {};
79 type = types.attrsOf (types.submodule ({name, options, config, ...}: {
80 options = {
81 conf = lib.mkOption {
82 type = types.lines;
83 description = "The database's config in LDIF.";
84 };
85 data = lib.mkOption {
86 type = types.lines;
87 description = "The database's data in LDIF.";
88 };
89 olcDbDirectory = lib.mkOption {
90 type = types.str;
91 description = "The directory where the database is stored.";
92 default = "${openldap.dataDir}/${name}";
93 };
94 resetData = lib.mkOption {
95 type = types.bool;
96 description = "Whether to reset the data at each start of the slapd service.";
97 default = false;
98 };
99 };
100 }));
101 };
102 };
103 config = lib.mkIf openldap.enable {
104 systemd.services.openldap.preStart = ''
105 set -e
106 # NOTE: slapd's config is always re-initialized.
107 rm -rf "${openldap.configDir}"/cn=config \
108 "${openldap.configDir}"/cn=config.ldif
109 install -D -d -m 0700 -o "${openldap.user}" -g "${openldap.group}" "${openldap.configDir}"
110 # NOTE: olcDbDirectory must be created before adding the config.
111 '' +
112 unlinesAttrs (olcSuffix: {data, olcDbDirectory, resetData, ...}:
113 lib.optionalString resetData ''
114 rm -rf "${olcDbDirectory}"
115 '' + ''
116 install -D -d -m 0700 -o "${openldap.user}" -g "${openldap.group}" "${olcDbDirectory}"
117 '') openldap.databases
118 + ''
119 # NOTE: slapd is supposed to have been stopped by systemd
120 # before entering this preStart,
121 # hence slap* commands can safely be used.
122 #
123 # NOTE: slapadd(8):
124 # To populate the config database slapd-config(5),
125 # use -n 0 as it is always the first database.
126 # It must physically exist on the filesystem prior to this, however.
127 umask 0077
128 ${pkgs.openldap}/bin/slapadd -n 0 \
129 -F "${openldap.configDir}" \
130 -l ${openldap.initConfig}
131 chown -R "${openldap.user}:${openldap.group}" "${openldap.configDir}"
132 '' +
133 unlinesAttrs (olcSuffix: {data, olcDbDirectory, resetData, ...}:
134 lib.optionalString resetData ''
135 ${pkgs.openldap}/bin/slapadd \
136 -F "${openldap.configDir}" \
137 -l ${pkgs.writeText "data.ldif" data}
138 '' + ''
139 test ! -e "${olcDbDirectory}" ||
140 chown -R "${openldap.user}:${openldap.group}" "${olcDbDirectory}"
141 '') openldap.databases;
142 };
143 }