python312Packages.millheater: 0.11.8 -> 0.12.0
[NixPkgs.git] / nixos / tests / shadow.nix
bloba027af7e450b5de5bde58222e7adaf7677705f02
1 let
2   password1 = "foobar";
3   password2 = "helloworld";
4   password3 = "bazqux";
5   password4 = "asdf123";
6   hashed_bcrypt = "$2b$05$8xIEflrk2RxQtcVXbGIxs.Vl0x7dF1/JSv3cyX6JJt0npzkTCWvxK"; # fnord
7   hashed_yeshash = "$y$j9T$d8Z4EAf8P1SvM/aDFbxMS0$VnTXMp/Hnc7QdCBEaLTq5ZFOAFo2/PM0/xEAFuOE88."; # fnord
8   hashed_sha512crypt = "$6$ymzs8WINZ5wGwQcV$VC2S0cQiX8NVukOLymysTPn4v1zJoJp3NGyhnqyv/dAf4NWZsBWYveQcj6gEJr4ZUjRBRjM0Pj1L8TCQ8hUUp0"; # meow
9 in import ./make-test-python.nix ({ pkgs, ... }: {
10   name = "shadow";
11   meta = with pkgs.lib.maintainers; { maintainers = [ nequissimus ]; };
13   nodes.shadow = { pkgs, ... }: {
14     environment.systemPackages = [ pkgs.shadow ];
16     users = {
17       mutableUsers = true;
18       users.emma = {
19         isNormalUser = true;
20         password = password1;
21         shell = pkgs.bash;
22       };
23       users.layla = {
24         isNormalUser = true;
25         password = password2;
26         shell = pkgs.shadow;
27       };
28       users.ash = {
29         isNormalUser = true;
30         password = password4;
31         shell = pkgs.bash;
32       };
33       users.berta = {
34         isNormalUser = true;
35         hashedPasswordFile = (pkgs.writeText "hashed_bcrypt" hashed_bcrypt).outPath;
36         shell = pkgs.bash;
37       };
38       users.yesim = {
39         isNormalUser = true;
40         hashedPassword = hashed_yeshash;
41         shell = pkgs.bash;
42       };
43       users.leo = {
44         isNormalUser = true;
45         initialHashedPassword = "!";
46         hashedPassword = hashed_sha512crypt; # should take precedence over initialHashedPassword
47         shell = pkgs.bash;
48       };
49     };
50   };
52   testScript = ''
53     shadow.wait_for_unit("multi-user.target")
54     shadow.wait_until_succeeds("pgrep -f 'agetty.*tty1'")
56     with subtest("Normal login"):
57         shadow.send_key("alt-f2")
58         shadow.wait_until_succeeds("[ $(fgconsole) = 2 ]")
59         shadow.wait_for_unit("getty@tty2.service")
60         shadow.wait_until_succeeds("pgrep -f 'agetty.*tty2'")
61         shadow.wait_until_tty_matches("2", "login: ")
62         shadow.send_chars("emma\n")
63         shadow.wait_until_tty_matches("2", "login: emma")
64         shadow.wait_until_succeeds("pgrep login")
65         shadow.sleep(2)
66         shadow.send_chars("${password1}\n")
67         shadow.send_chars("whoami > /tmp/1\n")
68         shadow.wait_for_file("/tmp/1")
69         assert "emma" in shadow.succeed("cat /tmp/1")
71     with subtest("Switch user"):
72         shadow.send_chars("su - ash\n")
73         shadow.sleep(2)
74         shadow.send_chars("${password4}\n")
75         shadow.sleep(2)
76         shadow.send_chars("whoami > /tmp/3\n")
77         shadow.wait_for_file("/tmp/3")
78         assert "ash" in shadow.succeed("cat /tmp/3")
80     with subtest("Change password"):
81         shadow.send_key("alt-f3")
82         shadow.wait_until_succeeds("[ $(fgconsole) = 3 ]")
83         shadow.wait_for_unit("getty@tty3.service")
84         shadow.wait_until_succeeds("pgrep -f 'agetty.*tty3'")
85         shadow.wait_until_tty_matches("3", "login: ")
86         shadow.send_chars("emma\n")
87         shadow.wait_until_tty_matches("3", "login: emma")
88         shadow.wait_until_succeeds("pgrep login")
89         shadow.sleep(2)
90         shadow.send_chars("${password1}\n")
91         shadow.send_chars("passwd\n")
92         shadow.sleep(2)
93         shadow.send_chars("${password1}\n")
94         shadow.sleep(2)
95         shadow.send_chars("${password3}\n")
96         shadow.sleep(2)
97         shadow.send_chars("${password3}\n")
98         shadow.sleep(2)
99         shadow.send_key("alt-f4")
100         shadow.wait_until_succeeds("[ $(fgconsole) = 4 ]")
101         shadow.wait_for_unit("getty@tty4.service")
102         shadow.wait_until_succeeds("pgrep -f 'agetty.*tty4'")
103         shadow.wait_until_tty_matches("4", "login: ")
104         shadow.send_chars("emma\n")
105         shadow.wait_until_tty_matches("4", "login: emma")
106         shadow.wait_until_succeeds("pgrep login")
107         shadow.sleep(2)
108         shadow.send_chars("${password1}\n")
109         shadow.wait_until_tty_matches("4", "Login incorrect")
110         shadow.wait_until_tty_matches("4", "login:")
111         shadow.send_chars("emma\n")
112         shadow.wait_until_tty_matches("4", "login: emma")
113         shadow.wait_until_succeeds("pgrep login")
114         shadow.sleep(2)
115         shadow.send_chars("${password3}\n")
116         shadow.send_chars("whoami > /tmp/2\n")
117         shadow.wait_for_file("/tmp/2")
118         assert "emma" in shadow.succeed("cat /tmp/2")
120     with subtest("Groups"):
121         assert "foobar" not in shadow.succeed("groups emma")
122         shadow.succeed("groupadd foobar")
123         shadow.succeed("usermod -a -G foobar emma")
124         assert "foobar" in shadow.succeed("groups emma")
126     with subtest("nologin shell"):
127         shadow.send_key("alt-f5")
128         shadow.wait_until_succeeds("[ $(fgconsole) = 5 ]")
129         shadow.wait_for_unit("getty@tty5.service")
130         shadow.wait_until_succeeds("pgrep -f 'agetty.*tty5'")
131         shadow.wait_until_tty_matches("5", "login: ")
132         shadow.send_chars("layla\n")
133         shadow.wait_until_tty_matches("5", "login: layla")
134         shadow.wait_until_succeeds("pgrep login")
135         shadow.send_chars("${password2}\n")
136         shadow.wait_until_tty_matches("5", "login:")
138     with subtest("check alternate password hashes"):
139         shadow.send_key("alt-f6")
140         shadow.wait_until_succeeds("[ $(fgconsole) = 6 ]")
141         for u in ["berta", "yesim"]:
142             shadow.wait_for_unit("getty@tty6.service")
143             shadow.wait_until_succeeds("pgrep -f 'agetty.*tty6'")
144             shadow.wait_until_tty_matches("6", "login: ")
145             shadow.send_chars(f"{u}\n")
146             shadow.wait_until_tty_matches("6", f"login: {u}")
147             shadow.wait_until_succeeds("pgrep login")
148             shadow.sleep(2)
149             shadow.send_chars("fnord\n")
150             shadow.send_chars(f"whoami > /tmp/{u}\n")
151             shadow.wait_for_file(f"/tmp/{u}")
152             print(shadow.succeed(f"cat /tmp/{u}"))
153             assert u in shadow.succeed(f"cat /tmp/{u}")
154             shadow.send_chars("logout\n")
156     with subtest("Ensure hashedPassword does not get overridden by initialHashedPassword"):
157         shadow.send_key("alt-f6")
158         shadow.wait_until_succeeds("[ $(fgconsole) = 6 ]")
159         shadow.wait_for_unit("getty@tty6.service")
160         shadow.wait_until_succeeds("pgrep -f 'agetty.*tty6'")
161         shadow.wait_until_tty_matches("6", "login: ")
162         shadow.send_chars("leo\n")
163         shadow.wait_until_tty_matches("6", "login: leo")
164         shadow.wait_until_succeeds("pgrep login")
165         shadow.sleep(2)
166         shadow.send_chars("meow\n")
167         shadow.send_chars("whoami > /tmp/leo\n")
168         shadow.wait_for_file("/tmp/leo")
169         assert "leo" in shadow.succeed("cat /tmp/leo")
170         shadow.send_chars("logout\n")
171   '';