1let
2 dbDomain = "example.org";
3 dbSuffix = "dc=example,dc=org";
4
5 ldapRootUser = "admin";
6 ldapRootPassword = "foobar";
7
8 testUser = "alice";
9 testPassword = "foobar";
10 testNewPassword = "barfoo";
11in
12import ./make-test-python.nix ({ pkgs, ... }: {
13 name = "sssd-ldap";
14
15 meta = with pkgs.lib.maintainers; {
16 maintainers = [ bbigras s1341 ];
17 };
18
19 nodes.machine = { pkgs, ... }: {
20 security.pam.services.systemd-user.makeHomeDir = true;
21 environment.etc."cert.pem".text = builtins.readFile ./common/acme/server/acme.test.cert.pem;
22 environment.etc."key.pem".text = builtins.readFile ./common/acme/server/acme.test.key.pem;
23 services.openldap = {
24 enable = true;
25 urlList = [ "ldap:///" "ldaps:///" ];
26 settings = {
27 attrs = {
28 olcTLSCACertificateFile = "/etc/cert.pem";
29 olcTLSCertificateFile = "/etc/cert.pem";
30 olcTLSCertificateKeyFile = "/etc/key.pem";
31 olcTLSCipherSuite = "HIGH:MEDIUM:+3DES:+RC4:+aNULL";
32 olcTLSCRLCheck = "none";
33 olcTLSVerifyClient = "never";
34 olcTLSProtocolMin = "3.1";
35 };
36 children = {
37 "cn=schema".includes = [
38 "${pkgs.openldap}/etc/schema/core.ldif"
39 "${pkgs.openldap}/etc/schema/cosine.ldif"
40 "${pkgs.openldap}/etc/schema/inetorgperson.ldif"
41 "${pkgs.openldap}/etc/schema/nis.ldif"
42 ];
43 "olcDatabase={1}mdb" = {
44 attrs = {
45 objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ];
46 olcDatabase = "{1}mdb";
47 olcDbDirectory = "/var/lib/openldap/db";
48 olcSuffix = dbSuffix;
49 olcRootDN = "cn=${ldapRootUser},${dbSuffix}";
50 olcRootPW = ldapRootPassword;
51 olcAccess = [
52 /*
53 custom access rules for userPassword attributes
54 */
55 ''
56 {0}to attrs=userPassword
57 by self write
58 by anonymous auth
59 by * none''
60
61 /*
62 allow read on anything else
63 */
64 ''
65 {1}to *
66 by * read''
67 ];
68 };
69 };
70 };
71 };
72 declarativeContents = {
73 ${dbSuffix} = ''
74 dn: ${dbSuffix}
75 objectClass: top
76 objectClass: dcObject
77 objectClass: organization
78 o: ${dbDomain}
79
80 dn: ou=posix,${dbSuffix}
81 objectClass: top
82 objectClass: organizationalUnit
83
84 dn: ou=accounts,ou=posix,${dbSuffix}
85 objectClass: top
86 objectClass: organizationalUnit
87
88 dn: uid=${testUser},ou=accounts,ou=posix,${dbSuffix}
89 objectClass: person
90 objectClass: posixAccount
91 userPassword: ${testPassword}
92 homeDirectory: /home/${testUser}
93 uidNumber: 1234
94 gidNumber: 1234
95 cn: ""
96 sn: ""
97 '';
98 };
99 };
100
101 services.sssd = {
102 enable = true;
103 # just for testing purposes, don't put this into the Nix store in production!
104 environmentFile = "${pkgs.writeText "ldap-root" "LDAP_BIND_PW=${ldapRootPassword}"}";
105 config = ''
106 [sssd]
107 config_file_version = 2
108 services = nss, pam, sudo
109 domains = ${dbDomain}
110
111 [domain/${dbDomain}]
112 auth_provider = ldap
113 id_provider = ldap
114 ldap_uri = ldaps://127.0.0.1:636
115 ldap_tls_reqcert = allow
116 ldap_tls_cacert = /etc/cert.pem
117 ldap_search_base = ${dbSuffix}
118 ldap_default_bind_dn = cn=${ldapRootUser},${dbSuffix}
119 ldap_default_authtok_type = password
120 ldap_default_authtok = $LDAP_BIND_PW
121 '';
122 };
123 };
124
125 testScript = ''
126 machine.start()
127 machine.wait_for_unit("openldap.service")
128 machine.wait_for_unit("sssd.service")
129 result = machine.execute("getent passwd ${testUser}")
130 if result[0] == 0:
131 assert "${testUser}" in result[1]
132 else:
133 machine.wait_for_console_text("Backend is online")
134 machine.succeed("getent passwd ${testUser}")
135
136 with subtest("Log in as ${testUser}"):
137 machine.wait_until_tty_matches("1", "login: ")
138 machine.send_chars("${testUser}\n")
139 machine.wait_until_tty_matches("1", "login: ${testUser}")
140 machine.wait_until_succeeds("pgrep login")
141 machine.wait_until_tty_matches("1", "Password: ")
142 machine.send_chars("${testPassword}\n")
143 machine.wait_until_succeeds("pgrep -u ${testUser} bash")
144 machine.send_chars("touch done\n")
145 machine.wait_for_file("/home/${testUser}/done")
146
147 with subtest("Change ${testUser}'s password"):
148 machine.send_chars("passwd\n")
149 machine.wait_until_tty_matches("1", "Current Password: ")
150 machine.send_chars("${testPassword}\n")
151 machine.wait_until_tty_matches("1", "New Password: ")
152 machine.send_chars("${testNewPassword}\n")
153 machine.wait_until_tty_matches("1", "Reenter new Password: ")
154 machine.send_chars("${testNewPassword}\n")
155 machine.wait_until_tty_matches("1", "passwd: password updated successfully")
156
157 with subtest("Log in as ${testUser} with new password in virtual console 2"):
158 machine.send_key("alt-f2")
159 machine.wait_until_succeeds("[ $(fgconsole) = 2 ]")
160 machine.wait_for_unit("getty@tty2.service")
161 machine.wait_until_succeeds("pgrep -f 'agetty.*tty2'")
162
163 machine.wait_until_tty_matches("2", "login: ")
164 machine.send_chars("${testUser}\n")
165 machine.wait_until_tty_matches("2", "login: ${testUser}")
166 machine.wait_until_succeeds("pgrep login")
167 machine.wait_until_tty_matches("2", "Password: ")
168 machine.send_chars("${testNewPassword}\n")
169 machine.wait_until_succeeds("pgrep -u ${testUser} bash")
170 machine.send_chars("touch done2\n")
171 machine.wait_for_file("/home/${testUser}/done2")
172 '';
173})