2 * Tests for the NSS cash module
4 * Copyright (C) 2019 Simon Ruderich
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
27 #include "../cash_nss.h"
30 static void test_getpwent(void) {
37 // Test one setpwent/getpwent/endpwent round
39 s = _nss_cash_setpwent(0);
40 assert(s == NSS_STATUS_SUCCESS);
42 // Multiple calls with too small buffer don't advance any internal indices
43 s = _nss_cash_getpwent_r(&p, tmp_small, sizeof(tmp_small), &errnop);
44 assert(s == NSS_STATUS_TRYAGAIN);
45 assert(errnop == ERANGE);
46 s = _nss_cash_getpwent_r(&p, tmp_small, sizeof(tmp_small), &errnop);
47 assert(s == NSS_STATUS_TRYAGAIN);
48 assert(errnop == ERANGE);
49 s = _nss_cash_getpwent_r(&p, tmp_small, sizeof(tmp_small), &errnop);
50 assert(s == NSS_STATUS_TRYAGAIN);
51 assert(errnop == ERANGE);
53 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
54 assert(s == NSS_STATUS_SUCCESS);
55 assert(!strcmp(p.pw_name, "root"));
56 assert(!strcmp(p.pw_passwd, "x"));
57 assert(p.pw_uid == 0);
58 assert(p.pw_gid == 0);
59 assert(!strcmp(p.pw_gecos, "root"));
60 assert(!strcmp(p.pw_dir, "/root"));
61 assert(!strcmp(p.pw_shell, "/bin/bash"));
63 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
64 assert(s == NSS_STATUS_SUCCESS);
65 assert(!strcmp(p.pw_name, "daemon"));
66 for (int i = 0; i < 10; i++) {
67 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
68 assert(s == NSS_STATUS_SUCCESS);
70 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
71 assert(s == NSS_STATUS_SUCCESS);
72 assert(!strcmp(p.pw_name, "www-data"));
73 for (int i = 0; i < 12; i++) {
74 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
75 assert(s == NSS_STATUS_SUCCESS);
77 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
78 assert(s == NSS_STATUS_SUCCESS);
79 assert(!strcmp(p.pw_name, "_rpc"));
80 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
81 assert(s == NSS_STATUS_SUCCESS);
82 assert(!strcmp(p.pw_name, "postfix"));
83 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
84 assert(s == NSS_STATUS_NOTFOUND);
85 assert(errnop == ENOENT);
87 s = _nss_cash_endpwent();
88 assert(s == NSS_STATUS_SUCCESS);
93 s = _nss_cash_setpwent(0);
94 assert(s == NSS_STATUS_SUCCESS);
96 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
97 assert(s == NSS_STATUS_SUCCESS);
98 assert(!strcmp(p.pw_name, "root"));
99 assert(!strcmp(p.pw_passwd, "x"));
100 assert(p.pw_uid == 0);
101 assert(p.pw_gid == 0);
102 assert(!strcmp(p.pw_gecos, "root"));
103 assert(!strcmp(p.pw_dir, "/root"));
104 assert(!strcmp(p.pw_shell, "/bin/bash"));
106 s = _nss_cash_endpwent();
107 assert(s == NSS_STATUS_SUCCESS);
110 // Test proper reset the 2nd
112 s = _nss_cash_setpwent(0);
113 assert(s == NSS_STATUS_SUCCESS);
115 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
116 assert(s == NSS_STATUS_SUCCESS);
117 assert(!strcmp(p.pw_name, "root"));
118 assert(!strcmp(p.pw_passwd, "x"));
119 assert(p.pw_uid == 0);
120 assert(p.pw_gid == 0);
121 assert(!strcmp(p.pw_gecos, "root"));
122 assert(!strcmp(p.pw_dir, "/root"));
123 assert(!strcmp(p.pw_shell, "/bin/bash"));
125 s = _nss_cash_endpwent();
126 assert(s == NSS_STATUS_SUCCESS);
129 // Test many rounds to check for open file leaks
130 for (int i = 0; i < 10000; i++) {
131 s = _nss_cash_setpwent(0);
132 assert(s == NSS_STATUS_SUCCESS);
134 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
135 assert(s == NSS_STATUS_SUCCESS);
136 assert(!strcmp(p.pw_name, "root"));
138 s = _nss_cash_endpwent();
139 assert(s == NSS_STATUS_SUCCESS);
143 // Test with cash file is not present
145 assert(rename("tests/passwd.nsscash", "tests/passwd.nsscash.tmp") == 0);
146 s = _nss_cash_setpwent(0);
147 assert(s == NSS_STATUS_SUCCESS);
148 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
149 assert(s == NSS_STATUS_UNAVAIL);
150 assert(errnop == ENOENT);
151 s = _nss_cash_getpwent_r(&p, tmp, sizeof(tmp), &errnop);
152 assert(s == NSS_STATUS_UNAVAIL);
153 assert(errnop == ENOENT);
154 s = _nss_cash_endpwent();
155 assert(s == NSS_STATUS_SUCCESS);
156 assert(rename("tests/passwd.nsscash.tmp", "tests/passwd.nsscash") == 0);
159 static void test_getpwuid(void) {
166 s = _nss_cash_getpwuid_r(0, &p, tmp_small, sizeof(tmp_small), &errnop);
167 assert(s == NSS_STATUS_TRYAGAIN);
168 assert(errnop == ERANGE);
169 s = _nss_cash_getpwuid_r(42, &p, tmp_small, sizeof(tmp_small), &errnop);
170 assert(s == NSS_STATUS_NOTFOUND); // 42 does not exist
171 assert(errnop == ENOENT);
172 s = _nss_cash_getpwuid_r(65534, &p, tmp_small, sizeof(tmp_small), &errnop);
173 assert(s == NSS_STATUS_TRYAGAIN);
174 assert(errnop == ERANGE);
176 s = _nss_cash_getpwuid_r(0, &p, tmp, sizeof(tmp), &errnop);
177 assert(s == NSS_STATUS_SUCCESS);
178 assert(!strcmp(p.pw_name, "root"));
179 assert(!strcmp(p.pw_passwd, "x"));
180 assert(p.pw_uid == 0);
181 assert(p.pw_gid == 0);
182 assert(!strcmp(p.pw_gecos, "root"));
183 assert(!strcmp(p.pw_dir, "/root"));
184 assert(!strcmp(p.pw_shell, "/bin/bash"));
186 s = _nss_cash_getpwuid_r(1, &p, tmp, sizeof(tmp), &errnop);
187 assert(s == NSS_STATUS_SUCCESS);
188 assert(!strcmp(p.pw_name, "daemon"));
189 assert(!strcmp(p.pw_passwd, "x"));
190 assert(p.pw_uid == 1);
191 assert(p.pw_gid == 1);
192 assert(!strcmp(p.pw_gecos, "daemon"));
193 assert(!strcmp(p.pw_dir, "/usr/sbin"));
194 assert(!strcmp(p.pw_shell, "/usr/sbin/nologin"));
196 s = _nss_cash_getpwuid_r(11, &p, tmp, sizeof(tmp), &errnop);
197 assert(s == NSS_STATUS_NOTFOUND);
198 assert(errnop == ENOENT);
200 s = _nss_cash_getpwuid_r(102, &p, tmp, sizeof(tmp), &errnop);
201 assert(s == NSS_STATUS_SUCCESS);
202 assert(!strcmp(p.pw_name, "systemd-network"));
203 assert(!strcmp(p.pw_passwd, "x"));
204 assert(p.pw_uid == 102);
205 assert(p.pw_gid == 103);
206 assert(!strcmp(p.pw_gecos, "systemd Network Management,,,"));
207 assert(!strcmp(p.pw_dir, "/run/systemd"));
208 assert(!strcmp(p.pw_shell, "/usr/sbin/nologin"));
210 s = _nss_cash_getpwuid_r(107, &p, tmp, sizeof(tmp), &errnop);
211 assert(s == NSS_STATUS_SUCCESS);
212 assert(!strcmp(p.pw_name, "postfix"));
213 assert(!strcmp(p.pw_passwd, "x"));
214 assert(p.pw_uid == 107);
215 assert(p.pw_gid == 114);
216 assert(!strcmp(p.pw_gecos, ""));
217 assert(!strcmp(p.pw_dir, "/var/spool/postfix"));
218 assert(!strcmp(p.pw_shell, "/usr/sbin/nologin"));
220 s = _nss_cash_getpwuid_r(INT_MAX, &p, tmp, sizeof(tmp), &errnop);
221 assert(s == NSS_STATUS_NOTFOUND);
222 assert(errnop == ENOENT);
225 // Test with cash file is not present
227 assert(rename("tests/passwd.nsscash", "tests/passwd.nsscash.tmp") == 0);
228 s = _nss_cash_getpwuid_r(0, &p, tmp, sizeof(tmp), &errnop);
229 assert(s == NSS_STATUS_UNAVAIL);
230 assert(errnop == ENOENT);
231 s = _nss_cash_getpwuid_r(42, &p, tmp, sizeof(tmp), &errnop);
232 assert(s == NSS_STATUS_UNAVAIL);
233 assert(errnop == ENOENT);
234 assert(rename("tests/passwd.nsscash.tmp", "tests/passwd.nsscash") == 0);
237 static void test_getpwnam(void) {
244 s = _nss_cash_getpwnam_r("root", &p, tmp_small, sizeof(tmp_small), &errnop);
245 assert(s == NSS_STATUS_TRYAGAIN);
246 assert(errnop == ERANGE);
247 s = _nss_cash_getpwnam_r("nope", &p, tmp_small, sizeof(tmp_small), &errnop);
248 assert(s == NSS_STATUS_NOTFOUND); // does not exist
249 assert(errnop == ENOENT);
250 s = _nss_cash_getpwnam_r("nobody", &p, tmp_small, sizeof(tmp_small), &errnop);
251 assert(s == NSS_STATUS_TRYAGAIN);
252 assert(errnop == ERANGE);
254 s = _nss_cash_getpwnam_r("root", &p, tmp, sizeof(tmp), &errnop);
255 assert(s == NSS_STATUS_SUCCESS);
256 assert(!strcmp(p.pw_name, "root"));
257 assert(!strcmp(p.pw_passwd, "x"));
258 assert(p.pw_uid == 0);
259 assert(p.pw_gid == 0);
260 assert(!strcmp(p.pw_gecos, "root"));
261 assert(!strcmp(p.pw_dir, "/root"));
262 assert(!strcmp(p.pw_shell, "/bin/bash"));
264 s = _nss_cash_getpwnam_r("daemon", &p, tmp, sizeof(tmp), &errnop);
265 assert(s == NSS_STATUS_SUCCESS);
266 assert(!strcmp(p.pw_name, "daemon"));
267 assert(!strcmp(p.pw_passwd, "x"));
268 assert(p.pw_uid == 1);
269 assert(p.pw_gid == 1);
270 assert(!strcmp(p.pw_gecos, "daemon"));
271 assert(!strcmp(p.pw_dir, "/usr/sbin"));
272 assert(!strcmp(p.pw_shell, "/usr/sbin/nologin"));
274 s = _nss_cash_getpwnam_r("nope2", &p, tmp, sizeof(tmp), &errnop);
275 assert(s == NSS_STATUS_NOTFOUND);
276 assert(errnop == ENOENT);
278 s = _nss_cash_getpwnam_r("systemd-network", &p, tmp, sizeof(tmp), &errnop);
279 assert(s == NSS_STATUS_SUCCESS);
280 assert(!strcmp(p.pw_name, "systemd-network"));
281 assert(!strcmp(p.pw_passwd, "x"));
282 assert(p.pw_uid == 102);
283 assert(p.pw_gid == 103);
284 assert(!strcmp(p.pw_gecos, "systemd Network Management,,,"));
285 assert(!strcmp(p.pw_dir, "/run/systemd"));
286 assert(!strcmp(p.pw_shell, "/usr/sbin/nologin"));
288 s = _nss_cash_getpwnam_r("postfix", &p, tmp, sizeof(tmp), &errnop);
289 assert(s == NSS_STATUS_SUCCESS);
290 assert(!strcmp(p.pw_name, "postfix"));
291 assert(!strcmp(p.pw_passwd, "x"));
292 assert(p.pw_uid == 107);
293 assert(p.pw_gid == 114);
294 assert(!strcmp(p.pw_gecos, ""));
295 assert(!strcmp(p.pw_dir, "/var/spool/postfix"));
296 assert(!strcmp(p.pw_shell, "/usr/sbin/nologin"));
298 s = _nss_cash_getpwnam_r("", &p, tmp, sizeof(tmp), &errnop);
299 assert(s == NSS_STATUS_NOTFOUND);
300 assert(errnop == ENOENT);
303 // Test with cash file is not present
305 assert(rename("tests/passwd.nsscash", "tests/passwd.nsscash.tmp") == 0);
306 s = _nss_cash_getpwnam_r("root", &p, tmp, sizeof(tmp), &errnop);
307 assert(s == NSS_STATUS_UNAVAIL);
308 assert(errnop == ENOENT);
309 s = _nss_cash_getpwnam_r("nope", &p, tmp, sizeof(tmp), &errnop);
310 assert(s == NSS_STATUS_UNAVAIL);
311 assert(errnop == ENOENT);
312 assert(rename("tests/passwd.nsscash.tmp", "tests/passwd.nsscash") == 0);