1import ./make-test-python.nix ({ pkgs, ... }:
2let
3 # build a getent that itself doesn't see anything in /etc/hosts and
4 # /etc/nsswitch.conf, by using libredirect to steer its own requests to
5 # /dev/null.
6 # This means is /has/ to go via nscd to actuallly resolve any of the
7 # additionally configured hosts.
8 getent' = pkgs.writeScript "getent-without-etc-hosts" ''
9 export NIX_REDIRECTS=/etc/hosts=/dev/null:/etc/nsswitch.conf=/dev/null
10 export LD_PRELOAD=${pkgs.libredirect}/lib/libredirect.so
11 exec getent $@
12 '';
13in
14{
15 name = "nscd";
16
17 nodes.machine = { pkgs, ... }: {
18 imports = [ common/user-account.nix ];
19 networking.extraHosts = ''
20 2001:db8::1 somehost.test
21 192.0.2.1 somehost.test
22 '';
23
24 systemd.services.sockdump = {
25 wantedBy = [ "multi-user.target" ];
26 path = [
27 # necessary for bcc to unpack kernel headers and invoke modprobe
28 pkgs.gnutar
29 pkgs.xz.bin
30 pkgs.kmod
31 ];
32 environment.PYTHONUNBUFFERED = "1";
33
34 serviceConfig = {
35 ExecStart = "${pkgs.sockdump}/bin/sockdump /var/run/nscd/socket";
36 Restart = "on-failure";
37 RestartSec = "1";
38 Type = "simple";
39 };
40 };
41
42 specialisation = {
43 withGlibcNscd.configuration = { ... }: {
44 services.nscd.enableNsncd = false;
45 };
46 withUnscd.configuration = { ... }: {
47 services.nscd.enableNsncd = false;
48 services.nscd.package = pkgs.unscd;
49 };
50 };
51 };
52
53 testScript = { nodes, ... }:
54 let
55 specialisations = "${nodes.machine.system.build.toplevel}/specialisation";
56 in
57 ''
58 # Regression test for https://github.com/NixOS/nixpkgs/issues/50273
59 def test_dynamic_user():
60 with subtest("DynamicUser actually allocates a user"):
61 assert "iamatest" in machine.succeed(
62 "systemd-run --pty --property=Type=oneshot --property=DynamicUser=yes --property=User=iamatest whoami"
63 )
64
65 # Test resolution of somehost.test with getent', to make sure we go via
66 # nscd protocol
67 def test_host_lookups():
68 with subtest("host lookups via nscd protocol"):
69 # ahosts
70 output = machine.succeed("${getent'} ahosts somehost.test")
71 assert "192.0.2.1" in output
72 assert "2001:db8::1" in output
73
74 # ahostsv4
75 output = machine.succeed("${getent'} ahostsv4 somehost.test")
76 assert "192.0.2.1" in output
77 assert "2001:db8::1" not in output
78
79 # ahostsv6
80 output = machine.succeed("${getent'} ahostsv6 somehost.test")
81 assert "192.0.2.1" not in output
82 assert "2001:db8::1" in output
83
84 # reverse lookups (hosts)
85 assert "somehost.test" in machine.succeed("${getent'} hosts 2001:db8::1")
86 assert "somehost.test" in machine.succeed("${getent'} hosts 192.0.2.1")
87
88
89 # Test host resolution via nss modules works
90 # We rely on nss-myhostname in this case, which resolves *.localhost and
91 # _gateway.
92 # We don't need to use getent' here, as non-glibc nss modules can only be
93 # discovered via nscd.
94 def test_nss_myhostname():
95 with subtest("nss-myhostname provides hostnames (ahosts)"):
96 # ahosts
97 output = machine.succeed("getent ahosts foobar.localhost")
98 assert "::1" in output
99 assert "127.0.0.1" in output
100
101 # ahostsv4
102 output = machine.succeed("getent ahostsv4 foobar.localhost")
103 assert "::1" not in output
104 assert "127.0.0.1" in output
105
106 # ahostsv6
107 output = machine.succeed("getent ahostsv6 foobar.localhost")
108 assert "::1" in output
109 assert "127.0.0.1" not in output
110
111 start_all()
112 machine.wait_for_unit("default.target")
113
114 # give sockdump some time to finish attaching.
115 machine.sleep(5)
116
117 # Test all tests with glibc-nscd.
118 test_dynamic_user()
119 test_host_lookups()
120 test_nss_myhostname()
121
122 with subtest("glibc-nscd"):
123 machine.succeed('${specialisations}/withGlibcNscd/bin/switch-to-configuration test')
124 machine.wait_for_unit("default.target")
125
126 test_dynamic_user()
127 test_host_lookups()
128 test_nss_myhostname()
129
130 with subtest("unscd"):
131 machine.succeed('${specialisations}/withUnscd/bin/switch-to-configuration test')
132 machine.wait_for_unit("default.target")
133
134 # known to fail, unscd doesn't load external NSS modules
135 # test_dynamic_user()
136
137 test_host_lookups()
138
139 # known to fail, unscd doesn't load external NSS modules
140 # test_nss_myhostname()
141 '';
142})