let dbDomain = "example.org"; dbSuffix = "dc=example,dc=org"; ldapRootUser = "admin"; ldapRootPassword = "foobar"; testUser = "alice"; testPassword = "foobar"; testNewPassword = "barfoo"; in import ./make-test-python.nix ({ pkgs, ... }: { name = "sssd-ldap"; meta = with pkgs.lib.maintainers; { maintainers = [ bbigras s1341 ]; }; nodes.machine = { pkgs, ... }: { security.pam.services.systemd-user.makeHomeDir = true; environment.etc."cert.pem".text = builtins.readFile ./common/acme/server/acme.test.cert.pem; environment.etc."key.pem".text = builtins.readFile ./common/acme/server/acme.test.key.pem; services.openldap = { enable = true; urlList = [ "ldap:///" "ldaps:///" ]; settings = { attrs = { olcTLSCACertificateFile = "/etc/cert.pem"; olcTLSCertificateFile = "/etc/cert.pem"; olcTLSCertificateKeyFile = "/etc/key.pem"; olcTLSCipherSuite = "HIGH:MEDIUM:+3DES:+RC4:+aNULL"; olcTLSCRLCheck = "none"; olcTLSVerifyClient = "never"; olcTLSProtocolMin = "3.1"; }; children = { "cn=schema".includes = [ "${pkgs.openldap}/etc/schema/core.ldif" "${pkgs.openldap}/etc/schema/cosine.ldif" "${pkgs.openldap}/etc/schema/inetorgperson.ldif" "${pkgs.openldap}/etc/schema/nis.ldif" ]; "olcDatabase={1}mdb" = { attrs = { objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ]; olcDatabase = "{1}mdb"; olcDbDirectory = "/var/lib/openldap/db"; olcSuffix = dbSuffix; olcRootDN = "cn=${ldapRootUser},${dbSuffix}"; olcRootPW = ldapRootPassword; olcAccess = [ /* custom access rules for userPassword attributes */ '' {0}to attrs=userPassword by self write by anonymous auth by * none'' /* allow read on anything else */ '' {1}to * by * read'' ]; }; }; }; }; declarativeContents = { ${dbSuffix} = '' dn: ${dbSuffix} objectClass: top objectClass: dcObject objectClass: organization o: ${dbDomain} dn: ou=posix,${dbSuffix} objectClass: top objectClass: organizationalUnit dn: ou=accounts,ou=posix,${dbSuffix} objectClass: top objectClass: organizationalUnit dn: uid=${testUser},ou=accounts,ou=posix,${dbSuffix} objectClass: person objectClass: posixAccount userPassword: ${testPassword} homeDirectory: /home/${testUser} uidNumber: 1234 gidNumber: 1234 cn: "" sn: "" ''; }; }; services.sssd = { enable = true; # just for testing purposes, don't put this into the Nix store in production! environmentFile = "${pkgs.writeText "ldap-root" "LDAP_BIND_PW=${ldapRootPassword}"}"; config = '' [sssd] config_file_version = 2 services = nss, pam, sudo domains = ${dbDomain} [domain/${dbDomain}] auth_provider = ldap id_provider = ldap ldap_uri = ldaps://127.0.0.1:636 ldap_tls_reqcert = allow ldap_tls_cacert = /etc/cert.pem ldap_search_base = ${dbSuffix} ldap_default_bind_dn = cn=${ldapRootUser},${dbSuffix} ldap_default_authtok_type = password ldap_default_authtok = $LDAP_BIND_PW ''; }; }; testScript = '' machine.start() machine.wait_for_unit("openldap.service") machine.wait_for_unit("sssd.service") result = machine.execute("getent passwd ${testUser}") if result[0] == 0: assert "${testUser}" in result[1] else: machine.wait_for_console_text("Backend is online") machine.succeed("getent passwd ${testUser}") with subtest("Log in as ${testUser}"): machine.wait_until_tty_matches("1", "login: ") machine.send_chars("${testUser}\n") machine.wait_until_tty_matches("1", "login: ${testUser}") machine.wait_until_succeeds("pgrep login") machine.wait_until_tty_matches("1", "Password: ") machine.send_chars("${testPassword}\n") machine.wait_until_succeeds("pgrep -u ${testUser} bash") machine.send_chars("touch done\n") machine.wait_for_file("/home/${testUser}/done") with subtest("Change ${testUser}'s password"): machine.send_chars("passwd\n") machine.wait_until_tty_matches("1", "Current Password: ") machine.send_chars("${testPassword}\n") machine.wait_until_tty_matches("1", "New Password: ") machine.send_chars("${testNewPassword}\n") machine.wait_until_tty_matches("1", "Reenter new Password: ") machine.send_chars("${testNewPassword}\n") machine.wait_until_tty_matches("1", "passwd: password updated successfully") with subtest("Log in as ${testUser} with new password in virtual console 2"): machine.send_key("alt-f2") machine.wait_until_succeeds("[ $(fgconsole) = 2 ]") machine.wait_for_unit("getty@tty2.service") machine.wait_until_succeeds("pgrep -f 'agetty.*tty2'") machine.wait_until_tty_matches("2", "login: ") machine.send_chars("${testUser}\n") machine.wait_until_tty_matches("2", "login: ${testUser}") machine.wait_until_succeeds("pgrep login") machine.wait_until_tty_matches("2", "Password: ") machine.send_chars("${testNewPassword}\n") machine.wait_until_succeeds("pgrep -u ${testUser} bash") machine.send_chars("touch done2\n") machine.wait_for_file("/home/${testUser}/done2") ''; })