]> Git — Sourcephile - sourcephile-nix.git/blob - servers/mermet/openldap/sourcephile.nix
mermet: add dovecot
[sourcephile-nix.git] / servers / mermet / openldap / sourcephile.nix
1 {pkgs, lib, config, ...}:
2 let
3 inherit (builtins) hasAttr;
4 inherit (builtins.extraBuiltins) pass-chomp;
5 inherit (config) networking;
6 inherit (config.services) openldap;
7 inherit (config.users) users groups;
8 inherit (pkgs.lib) unlines;
9 domainSuffix = openldap.domainSuffix;
10 posixAccount =
11 { uid
12 , uidNumber
13 , gidNumber ? uidNumber
14 , cn ? ""
15 , sn ? ""
16 , userPassword ? null # NOTE: doveadm pw -s SSHA -u $user -p $pass
17 , mailAlias ? []
18 , homeDirectory ? ""
19 , loginShell ? "/run/current-system/sw/bin/bash"
20 , mailEnabled ? true
21 , mailForwardingAddress ? []
22 , domain ? networking.domain
23 }: "\n" + lib.concatStringsSep "\n\n" [
24 (unlines ([ ''
25 dn: uid=${uid},ou=accounts,ou=posix,${domainSuffix}
26 objectClass: person
27 objectClass: posixAccount
28 objectClass: shadowAccount
29 objectClass: PostfixBookMailAccount
30 objectClass: PostfixBookMailForward
31 cn: ${cn}
32 sn: ${sn}
33 mail: ${uid}${lib.optionalString (networking.domain != "") "@${networking.domain}"}
34 mailEnabled: ${if mailEnabled then "TRUE" else "FALSE"}
35 #mailGroupMember: ${networking.domainBase}'']
36 ++ [ "uidNumber: ${toString uidNumber}" ]
37 ++ [ "gidNumber: ${toString gidNumber}" ]
38 ++ [ "homeDirectory: ${homeDirectory}" ]
39 ++ lib.optional (loginShell != null) "loginShell: ${loginShell}"
40 ++ lib.optional (userPassword != null) "userPassword: ${userPassword}"
41 ++ map (forward: "mailForwardingAddress: ${forward}") mailForwardingAddress
42 ++ map (alias: "mailAlias: ${alias}@${networking.domain}") mailAlias
43 ++ lib.optional (mailAlias == []) "mailAlias:"
44 # NOTE: required by PostfixBookMailForward
45 ))
46 ''
47 dn: cn=${uid},ou=groups,ou=posix,${domainSuffix}
48 objectClass: top
49 objectClass: posixGroup
50 gidNumber: ${toString gidNumber}
51 memberUid: ${uid}
52 ''
53 ];
54 in
55 {
56 config = lib.mkIf config.users.ldap.enable {
57 services.openldap = {
58 databases = {
59 # echo "$(nixops show-option mermet -d production services.openldap.databases."dc=sourcephile,dc=fr".data)"
60 "${domainSuffix}" = {
61 #
62 #
63 # WARNING: this deletes data.
64 #
65 #
66 resetData = true;
67 conf = ''
68 # sudo ldapsearch -LLL -H ldapi:// -D cn=admin,cn=config -Y EXTERNAL -b 'olcDatabase={1}mdb,cn=config' -s sub
69 dn: olcBackend={1}mdb,cn=config
70 objectClass: olcBackendConfig
71
72 dn: olcDatabase={1}mdb,cn=config
73 objectClass: olcDatabaseConfig
74 objectClass: olcMdbConfig
75 # NOTE: checkpoint the database periodically in case of system failure
76 # and to speed slapd shutdown.
77 olcDbCheckpoint: 512 30
78 # Database max size is 1G
79 olcDbMaxSize: 1073741824
80 olcLastMod: TRUE
81 # NOTE: database superuser. Needed for syncrepl.
82 olcRootDN: cn=admin,${domainSuffix}
83 # NOTE: superuser password, generated with slappasswd -h "{SSHA}" -s "$password"
84 #olcRootPW: {SSHA}COkATGNe7rs/g8vWcYP5rqt4u5sWdMgP
85 #
86 olcDbIndex: objectClass eq
87 olcDbIndex: cn,uid eq
88 olcDbIndex: uidNumber,gidNumber eq
89 olcDbIndex: member,memberUid eq
90 olcDbIndex: mail eq
91 olcDbIndex: mailAlias eq
92 olcDbIndex: mailEnabled eq
93 #
94 olcAccess: to attrs=userPassword
95 by self write
96 by anonymous auth
97 by dn="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
98 by * none
99 olcAccess: to attrs=shadowLastChange
100 by self write
101 by dn="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
102 by * none
103 olcAccess: to dn.sub="ou=posix,${domainSuffix}"
104 by self read
105 by dn="gidNumber=${toString groups.nslcd.gid}+uidNumber=${toString users.nslcd.uid},cn=peercred,cn=external,cn=auth" read
106 ${lib.optionalString (hasAttr "postfix" users) ''by dn="gidNumber=${toString groups.postfix.gid}+uidNumber=${toString users.postfix.uid},cn=peercred,cn=external,cn=auth" read''}
107 by dn="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
108 # NOTE: dovecot/auth runs as root, hence the gidNumber=0+uidNumber=0
109 olcAccess: to *
110 by self read
111 by * none
112 '';
113 data = ''
114 dn: ${domainSuffix}
115 objectClass: top
116 objectClass: dcObject
117 objectClass: organization
118 o: ${networking.domainBase}
119
120 dn: cn=admin,${domainSuffix}
121 objectClass: simpleSecurityObject
122 objectClass: organizationalRole
123 description: ${networking.domainBase} LDAP administrator
124 roleOccupant: ${domainSuffix}
125 userPassword:
126 #userPassword: {SSHA}NONVwwKnKsCBmFxkMqTCFekdu3SJQHc9
127
128 dn: ou=posix,${domainSuffix}
129 objectClass: top
130 objectClass: organizationalUnit
131
132 dn: ou=accounts,ou=posix,${domainSuffix}
133 objectClass: top
134 objectClass: organizationalUnit
135
136 dn: ou=groups,ou=posix,${domainSuffix}
137 objectClass: top
138 objectClass: organizationalUnit
139
140 dn: cn=${networking.domainBase},ou=groups,ou=posix,${domainSuffix}
141 objectClass: top
142 objectClass: posixGroup
143 gidNumber: 20000
144 memberUid: julm
145 memberUid: sevy
146
147 ''
148 + lib.concatMapStrings posixAccount [
149 { uid="julm";
150 uidNumber=users.julm.uid;
151 gidNumber=groups.julm.gid;
152 cn="Julien Moutinho"; sn="julm";
153 mailAlias = ["julien.moutinho"];
154 userPassword = pass-chomp "members/julm/mail/hashedPassword"; }
155 #{ uid="sevy"; uidNumber=10001; cn="Séverine Popek"; sn="sévy";
156 # mailAlias = ["severine.popek" "ouais-ouais"]; }
157 #{ uid="nomail"; uidNumber=10002; mailAlias = ["noalias"]; mailEnabled = false; }
158 #{ uid="post"; domain="friot"; mailForwardingAddress = ["ju@${networking.domain}"]; }
159 #{ uid="host"; mailForwardingAddress = ["ju@${networking.domain}"]; }
160 ];
161 };
162 };
163 };
164 };
165 }