xref: /freebsd/lib/libcasper/services/cap_pwd/tests/pwd_test.c (revision a64729f5077d77e13b9497cb33ecb3c82e606ee8)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2013 The FreeBSD Foundation
5  *
6  * This software was developed by Pawel Jakub Dawidek under sponsorship from
7  * the FreeBSD Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/capsicum.h>
32 #include <sys/nv.h>
33 
34 #include <assert.h>
35 #include <err.h>
36 #include <errno.h>
37 #include <pwd.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 
43 #include <libcasper.h>
44 
45 #include <casper/cap_pwd.h>
46 
47 static int ntest = 1;
48 
49 #define CHECK(expr)     do {						\
50 	if ((expr))							\
51 		printf("ok %d # %s:%u\n", ntest, __FILE__, __LINE__);	\
52 	else								\
53 		printf("not ok %d # %s:%u\n", ntest, __FILE__, __LINE__); \
54 	fflush(stdout);							\
55 	ntest++;							\
56 } while (0)
57 #define CHECKX(expr)     do {						\
58 	if ((expr)) {							\
59 		printf("ok %d # %s:%u\n", ntest, __FILE__, __LINE__);	\
60 	} else {							\
61 		printf("not ok %d # %s:%u\n", ntest, __FILE__, __LINE__); \
62 		exit(1);						\
63 	}								\
64 	fflush(stdout);							\
65 	ntest++;							\
66 } while (0)
67 
68 #define	UID_ROOT	0
69 #define	UID_OPERATOR	2
70 
71 #define	GETPWENT0	0x0001
72 #define	GETPWENT1	0x0002
73 #define	GETPWENT2	0x0004
74 #define	GETPWENT	(GETPWENT0 | GETPWENT1 | GETPWENT2)
75 #define	GETPWENT_R0	0x0008
76 #define	GETPWENT_R1	0x0010
77 #define	GETPWENT_R2	0x0020
78 #define	GETPWENT_R	(GETPWENT_R0 | GETPWENT_R1 | GETPWENT_R2)
79 #define	GETPWNAM	0x0040
80 #define	GETPWNAM_R	0x0080
81 #define	GETPWUID	0x0100
82 #define	GETPWUID_R	0x0200
83 
84 static bool
85 passwd_compare(const struct passwd *pwd0, const struct passwd *pwd1)
86 {
87 
88 	if (pwd0 == NULL && pwd1 == NULL)
89 		return (true);
90 	if (pwd0 == NULL || pwd1 == NULL)
91 		return (false);
92 
93 	if (strcmp(pwd0->pw_name, pwd1->pw_name) != 0)
94 		return (false);
95 
96 	if (pwd0->pw_passwd != NULL || pwd1->pw_passwd != NULL) {
97 		if (pwd0->pw_passwd == NULL || pwd1->pw_passwd == NULL)
98 			return (false);
99 		if (strcmp(pwd0->pw_passwd, pwd1->pw_passwd) != 0)
100 			return (false);
101 	}
102 
103 	if (pwd0->pw_uid != pwd1->pw_uid)
104 		return (false);
105 
106 	if (pwd0->pw_gid != pwd1->pw_gid)
107 		return (false);
108 
109 	if (pwd0->pw_change != pwd1->pw_change)
110 		return (false);
111 
112 	if (pwd0->pw_class != NULL || pwd1->pw_class != NULL) {
113 		if (pwd0->pw_class == NULL || pwd1->pw_class == NULL)
114 			return (false);
115 		if (strcmp(pwd0->pw_class, pwd1->pw_class) != 0)
116 			return (false);
117 	}
118 
119 	if (pwd0->pw_gecos != NULL || pwd1->pw_gecos != NULL) {
120 		if (pwd0->pw_gecos == NULL || pwd1->pw_gecos == NULL)
121 			return (false);
122 		if (strcmp(pwd0->pw_gecos, pwd1->pw_gecos) != 0)
123 			return (false);
124 	}
125 
126 	if (pwd0->pw_dir != NULL || pwd1->pw_dir != NULL) {
127 		if (pwd0->pw_dir == NULL || pwd1->pw_dir == NULL)
128 			return (false);
129 		if (strcmp(pwd0->pw_dir, pwd1->pw_dir) != 0)
130 			return (false);
131 	}
132 
133 	if (pwd0->pw_shell != NULL || pwd1->pw_shell != NULL) {
134 		if (pwd0->pw_shell == NULL || pwd1->pw_shell == NULL)
135 			return (false);
136 		if (strcmp(pwd0->pw_shell, pwd1->pw_shell) != 0)
137 			return (false);
138 	}
139 
140 	if (pwd0->pw_expire != pwd1->pw_expire)
141 		return (false);
142 
143 	if (pwd0->pw_fields != pwd1->pw_fields)
144 		return (false);
145 
146 	return (true);
147 }
148 
149 static unsigned int
150 runtest_cmds(cap_channel_t *cappwd)
151 {
152 	char bufs[1024], bufc[1024];
153 	unsigned int result;
154 	struct passwd *pwds, *pwdc;
155 	struct passwd sts, stc;
156 
157 	result = 0;
158 
159 	setpwent();
160 	cap_setpwent(cappwd);
161 
162 	pwds = getpwent();
163 	pwdc = cap_getpwent(cappwd);
164 	if (passwd_compare(pwds, pwdc)) {
165 		result |= GETPWENT0;
166 		pwds = getpwent();
167 		pwdc = cap_getpwent(cappwd);
168 		if (passwd_compare(pwds, pwdc))
169 			result |= GETPWENT1;
170 	}
171 
172 	getpwent_r(&sts, bufs, sizeof(bufs), &pwds);
173 	cap_getpwent_r(cappwd, &stc, bufc, sizeof(bufc), &pwdc);
174 	if (passwd_compare(pwds, pwdc)) {
175 		result |= GETPWENT_R0;
176 		getpwent_r(&sts, bufs, sizeof(bufs), &pwds);
177 		cap_getpwent_r(cappwd, &stc, bufc, sizeof(bufc), &pwdc);
178 		if (passwd_compare(pwds, pwdc))
179 			result |= GETPWENT_R1;
180 	}
181 
182 	setpwent();
183 	cap_setpwent(cappwd);
184 
185 	getpwent_r(&sts, bufs, sizeof(bufs), &pwds);
186 	cap_getpwent_r(cappwd, &stc, bufc, sizeof(bufc), &pwdc);
187 	if (passwd_compare(pwds, pwdc))
188 		result |= GETPWENT_R2;
189 
190 	pwds = getpwent();
191 	pwdc = cap_getpwent(cappwd);
192 	if (passwd_compare(pwds, pwdc))
193 		result |= GETPWENT2;
194 
195 	pwds = getpwnam("root");
196 	pwdc = cap_getpwnam(cappwd, "root");
197 	if (passwd_compare(pwds, pwdc)) {
198 		pwds = getpwnam("operator");
199 		pwdc = cap_getpwnam(cappwd, "operator");
200 		if (passwd_compare(pwds, pwdc))
201 			result |= GETPWNAM;
202 	}
203 
204 	getpwnam_r("root", &sts, bufs, sizeof(bufs), &pwds);
205 	cap_getpwnam_r(cappwd, "root", &stc, bufc, sizeof(bufc), &pwdc);
206 	if (passwd_compare(pwds, pwdc)) {
207 		getpwnam_r("operator", &sts, bufs, sizeof(bufs), &pwds);
208 		cap_getpwnam_r(cappwd, "operator", &stc, bufc, sizeof(bufc),
209 		    &pwdc);
210 		if (passwd_compare(pwds, pwdc))
211 			result |= GETPWNAM_R;
212 	}
213 
214 	pwds = getpwuid(UID_ROOT);
215 	pwdc = cap_getpwuid(cappwd, UID_ROOT);
216 	if (passwd_compare(pwds, pwdc)) {
217 		pwds = getpwuid(UID_OPERATOR);
218 		pwdc = cap_getpwuid(cappwd, UID_OPERATOR);
219 		if (passwd_compare(pwds, pwdc))
220 			result |= GETPWUID;
221 	}
222 
223 	getpwuid_r(UID_ROOT, &sts, bufs, sizeof(bufs), &pwds);
224 	cap_getpwuid_r(cappwd, UID_ROOT, &stc, bufc, sizeof(bufc), &pwdc);
225 	if (passwd_compare(pwds, pwdc)) {
226 		getpwuid_r(UID_OPERATOR, &sts, bufs, sizeof(bufs), &pwds);
227 		cap_getpwuid_r(cappwd, UID_OPERATOR, &stc, bufc, sizeof(bufc),
228 		    &pwdc);
229 		if (passwd_compare(pwds, pwdc))
230 			result |= GETPWUID_R;
231 	}
232 
233 	return (result);
234 }
235 
236 static void
237 test_cmds(cap_channel_t *origcappwd)
238 {
239 	cap_channel_t *cappwd;
240 	const char *cmds[7], *fields[10], *names[6];
241 	uid_t uids[5];
242 
243 	fields[0] = "pw_name";
244 	fields[1] = "pw_passwd";
245 	fields[2] = "pw_uid";
246 	fields[3] = "pw_gid";
247 	fields[4] = "pw_change";
248 	fields[5] = "pw_class";
249 	fields[6] = "pw_gecos";
250 	fields[7] = "pw_dir";
251 	fields[8] = "pw_shell";
252 	fields[9] = "pw_expire";
253 
254 	names[0] = "root";
255 	names[1] = "toor";
256 	names[2] = "daemon";
257 	names[3] = "operator";
258 	names[4] = "bin";
259 	names[5] = "kmem";
260 
261 	uids[0] = 0;
262 	uids[1] = 1;
263 	uids[2] = 2;
264 	uids[3] = 3;
265 	uids[4] = 5;
266 
267 	/*
268 	 * Allow:
269 	 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r,
270 	 *       getpwuid, getpwuid_r
271 	 * users:
272 	 *     names: root, toor, daemon, operator, bin, kmem
273 	 *     uids:
274 	 */
275 	cappwd = cap_clone(origcappwd);
276 	CHECK(cappwd != NULL);
277 
278 	cmds[0] = "setpwent";
279 	cmds[1] = "getpwent";
280 	cmds[2] = "getpwent_r";
281 	cmds[3] = "getpwnam";
282 	cmds[4] = "getpwnam_r";
283 	cmds[5] = "getpwuid";
284 	cmds[6] = "getpwuid_r";
285 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == 0);
286 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
287 	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);
288 
289 	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
290 	    GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));
291 
292 	cap_close(cappwd);
293 
294 	/*
295 	 * Allow:
296 	 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r,
297 	 *       getpwuid, getpwuid_r
298 	 * users:
299 	 *     names:
300 	 *     uids: 0, 1, 2, 3, 5
301 	 */
302 	cappwd = cap_clone(origcappwd);
303 	CHECK(cappwd != NULL);
304 
305 	cmds[0] = "setpwent";
306 	cmds[1] = "getpwent";
307 	cmds[2] = "getpwent_r";
308 	cmds[3] = "getpwnam";
309 	cmds[4] = "getpwnam_r";
310 	cmds[5] = "getpwuid";
311 	cmds[6] = "getpwuid_r";
312 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == 0);
313 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
314 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);
315 
316 	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
317 	    GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));
318 
319 	cap_close(cappwd);
320 
321 	/*
322 	 * Allow:
323 	 * cmds: getpwent, getpwent_r, getpwnam, getpwnam_r,
324 	 *       getpwuid, getpwuid_r
325 	 * users:
326 	 *     names: root, toor, daemon, operator, bin, kmem
327 	 *     uids:
328 	 * Disallow:
329 	 * cmds: setpwent
330 	 * users:
331 	 */
332 	cappwd = cap_clone(origcappwd);
333 	CHECK(cappwd != NULL);
334 
335 	cap_setpwent(cappwd);
336 
337 	cmds[0] = "getpwent";
338 	cmds[1] = "getpwent_r";
339 	cmds[2] = "getpwnam";
340 	cmds[3] = "getpwnam_r";
341 	cmds[4] = "getpwuid";
342 	cmds[5] = "getpwuid_r";
343 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
344 	cmds[0] = "setpwent";
345 	cmds[1] = "getpwent";
346 	cmds[2] = "getpwent_r";
347 	cmds[3] = "getpwnam";
348 	cmds[4] = "getpwnam_r";
349 	cmds[5] = "getpwuid";
350 	cmds[6] = "getpwuid_r";
351 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
352 	cmds[0] = "setpwent";
353 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
354 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
355 	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);
356 
357 	CHECK(runtest_cmds(cappwd) == (GETPWENT0 | GETPWENT1 | GETPWENT_R0 |
358 	    GETPWENT_R1 | GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));
359 
360 	cap_close(cappwd);
361 
362 	/*
363 	 * Allow:
364 	 * cmds: getpwent, getpwent_r, getpwnam, getpwnam_r,
365 	 *       getpwuid, getpwuid_r
366 	 * users:
367 	 *     names:
368 	 *     uids: 0, 1, 2, 3, 5
369 	 * Disallow:
370 	 * cmds: setpwent
371 	 * users:
372 	 */
373 	cappwd = cap_clone(origcappwd);
374 	CHECK(cappwd != NULL);
375 
376 	cap_setpwent(cappwd);
377 
378 	cmds[0] = "getpwent";
379 	cmds[1] = "getpwent_r";
380 	cmds[2] = "getpwnam";
381 	cmds[3] = "getpwnam_r";
382 	cmds[4] = "getpwuid";
383 	cmds[5] = "getpwuid_r";
384 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
385 	cmds[0] = "setpwent";
386 	cmds[1] = "getpwent";
387 	cmds[2] = "getpwent_r";
388 	cmds[3] = "getpwnam";
389 	cmds[4] = "getpwnam_r";
390 	cmds[5] = "getpwuid";
391 	cmds[6] = "getpwuid_r";
392 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
393 	cmds[0] = "setpwent";
394 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
395 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
396 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);
397 
398 	CHECK(runtest_cmds(cappwd) == (GETPWENT0 | GETPWENT1 | GETPWENT_R0 |
399 	    GETPWENT_R1 | GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));
400 
401 	cap_close(cappwd);
402 
403 	/*
404 	 * Allow:
405 	 * cmds: setpwent, getpwent_r, getpwnam, getpwnam_r,
406 	 *       getpwuid, getpwuid_r
407 	 * users:
408 	 *     names: root, toor, daemon, operator, bin, kmem
409 	 *     uids:
410 	 * Disallow:
411 	 * cmds: getpwent
412 	 * users:
413 	 */
414 	cappwd = cap_clone(origcappwd);
415 	CHECK(cappwd != NULL);
416 
417 	cmds[0] = "setpwent";
418 	cmds[1] = "getpwent_r";
419 	cmds[2] = "getpwnam";
420 	cmds[3] = "getpwnam_r";
421 	cmds[4] = "getpwuid";
422 	cmds[5] = "getpwuid_r";
423 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
424 	cmds[0] = "setpwent";
425 	cmds[1] = "getpwent";
426 	cmds[2] = "getpwent_r";
427 	cmds[3] = "getpwnam";
428 	cmds[4] = "getpwnam_r";
429 	cmds[5] = "getpwuid";
430 	cmds[6] = "getpwuid_r";
431 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
432 	cmds[0] = "getpwent";
433 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
434 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
435 	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);
436 
437 	CHECK(runtest_cmds(cappwd) == (GETPWENT_R2 |
438 	    GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));
439 
440 	cap_close(cappwd);
441 
442 	/*
443 	 * Allow:
444 	 * cmds: setpwent, getpwent_r, getpwnam, getpwnam_r,
445 	 *       getpwuid, getpwuid_r
446 	 * users:
447 	 *     names:
448 	 *     uids: 0, 1, 2, 3, 5
449 	 * Disallow:
450 	 * cmds: getpwent
451 	 * users:
452 	 */
453 	cappwd = cap_clone(origcappwd);
454 	CHECK(cappwd != NULL);
455 
456 	cmds[0] = "setpwent";
457 	cmds[1] = "getpwent_r";
458 	cmds[2] = "getpwnam";
459 	cmds[3] = "getpwnam_r";
460 	cmds[4] = "getpwuid";
461 	cmds[5] = "getpwuid_r";
462 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
463 	cmds[0] = "setpwent";
464 	cmds[1] = "getpwent";
465 	cmds[2] = "getpwent_r";
466 	cmds[3] = "getpwnam";
467 	cmds[4] = "getpwnam_r";
468 	cmds[5] = "getpwuid";
469 	cmds[6] = "getpwuid_r";
470 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
471 	cmds[0] = "getpwent";
472 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
473 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
474 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);
475 
476 	CHECK(runtest_cmds(cappwd) == (GETPWENT_R2 |
477 	    GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));
478 
479 	cap_close(cappwd);
480 
481 	/*
482 	 * Allow:
483 	 * cmds: setpwent, getpwent, getpwnam, getpwnam_r,
484 	 *       getpwuid, getpwuid_r
485 	 * users:
486 	 *     names: root, toor, daemon, operator, bin, kmem
487 	 *     uids:
488 	 * Disallow:
489 	 * cmds: getpwent_r
490 	 * users:
491 	 */
492 	cappwd = cap_clone(origcappwd);
493 	CHECK(cappwd != NULL);
494 
495 	cmds[0] = "setpwent";
496 	cmds[1] = "getpwent";
497 	cmds[2] = "getpwnam";
498 	cmds[3] = "getpwnam_r";
499 	cmds[4] = "getpwuid";
500 	cmds[5] = "getpwuid_r";
501 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
502 	cmds[0] = "setpwent";
503 	cmds[1] = "getpwent";
504 	cmds[2] = "getpwent_r";
505 	cmds[3] = "getpwnam";
506 	cmds[4] = "getpwnam_r";
507 	cmds[5] = "getpwuid";
508 	cmds[6] = "getpwuid_r";
509 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
510 	cmds[0] = "getpwent_r";
511 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
512 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
513 	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);
514 
515 	CHECK(runtest_cmds(cappwd) == (GETPWENT0 | GETPWENT1 |
516 	    GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));
517 
518 	cap_close(cappwd);
519 
520 	/*
521 	 * Allow:
522 	 * cmds: setpwent, getpwent, getpwnam, getpwnam_r,
523 	 *       getpwuid, getpwuid_r
524 	 * users:
525 	 *     names:
526 	 *     uids: 0, 1, 2, 3, 5
527 	 * Disallow:
528 	 * cmds: getpwent_r
529 	 * users:
530 	 */
531 	cappwd = cap_clone(origcappwd);
532 	CHECK(cappwd != NULL);
533 
534 	cmds[0] = "setpwent";
535 	cmds[1] = "getpwent";
536 	cmds[2] = "getpwnam";
537 	cmds[3] = "getpwnam_r";
538 	cmds[4] = "getpwuid";
539 	cmds[5] = "getpwuid_r";
540 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
541 	cmds[0] = "setpwent";
542 	cmds[1] = "getpwent";
543 	cmds[2] = "getpwent_r";
544 	cmds[3] = "getpwnam";
545 	cmds[4] = "getpwnam_r";
546 	cmds[5] = "getpwuid";
547 	cmds[6] = "getpwuid_r";
548 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
549 	cmds[0] = "getpwent_r";
550 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
551 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
552 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);
553 
554 	CHECK(runtest_cmds(cappwd) == (GETPWENT0 | GETPWENT1 |
555 	    GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));
556 
557 	cap_close(cappwd);
558 
559 	/*
560 	 * Allow:
561 	 * cmds: setpwent, getpwent, getpwent_r, getpwnam_r,
562 	 *       getpwuid, getpwuid_r
563 	 * users:
564 	 *     names: root, toor, daemon, operator, bin, kmem
565 	 *     uids:
566 	 * Disallow:
567 	 * cmds: getpwnam
568 	 * users:
569 	 */
570 	cappwd = cap_clone(origcappwd);
571 	CHECK(cappwd != NULL);
572 
573 	cmds[0] = "setpwent";
574 	cmds[1] = "getpwent";
575 	cmds[2] = "getpwent_r";
576 	cmds[3] = "getpwnam_r";
577 	cmds[4] = "getpwuid";
578 	cmds[5] = "getpwuid_r";
579 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
580 	cmds[0] = "setpwent";
581 	cmds[1] = "getpwent";
582 	cmds[2] = "getpwent_r";
583 	cmds[3] = "getpwnam";
584 	cmds[4] = "getpwnam_r";
585 	cmds[5] = "getpwuid";
586 	cmds[6] = "getpwuid_r";
587 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
588 	cmds[0] = "getpwnam";
589 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
590 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
591 	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);
592 
593 	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
594 	    GETPWNAM_R | GETPWUID | GETPWUID_R));
595 
596 	cap_close(cappwd);
597 
598 	/*
599 	 * Allow:
600 	 * cmds: setpwent, getpwent, getpwent_r, getpwnam_r,
601 	 *       getpwuid, getpwuid_r
602 	 * users:
603 	 *     names:
604 	 *     uids: 0, 1, 2, 3, 5
605 	 * Disallow:
606 	 * cmds: getpwnam
607 	 * users:
608 	 */
609 	cappwd = cap_clone(origcappwd);
610 	CHECK(cappwd != NULL);
611 
612 	cmds[0] = "setpwent";
613 	cmds[1] = "getpwent";
614 	cmds[2] = "getpwent_r";
615 	cmds[3] = "getpwnam_r";
616 	cmds[4] = "getpwuid";
617 	cmds[5] = "getpwuid_r";
618 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
619 	cmds[0] = "setpwent";
620 	cmds[1] = "getpwent";
621 	cmds[2] = "getpwent_r";
622 	cmds[3] = "getpwnam";
623 	cmds[4] = "getpwnam_r";
624 	cmds[5] = "getpwuid";
625 	cmds[6] = "getpwuid_r";
626 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
627 	cmds[0] = "getpwnam";
628 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
629 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
630 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);
631 
632 	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
633 	    GETPWNAM_R | GETPWUID | GETPWUID_R));
634 
635 	cap_close(cappwd);
636 
637 	/*
638 	 * Allow:
639 	 * cmds: setpwent, getpwent, getpwent_r, getpwnam,
640 	 *       getpwuid, getpwuid_r
641 	 * users:
642 	 *     names: root, toor, daemon, operator, bin, kmem
643 	 *     uids:
644 	 * Disallow:
645 	 * cmds: getpwnam_r
646 	 * users:
647 	 */
648 	cappwd = cap_clone(origcappwd);
649 	CHECK(cappwd != NULL);
650 
651 	cmds[0] = "setpwent";
652 	cmds[1] = "getpwent";
653 	cmds[2] = "getpwent_r";
654 	cmds[3] = "getpwnam";
655 	cmds[4] = "getpwuid";
656 	cmds[5] = "getpwuid_r";
657 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
658 	cmds[0] = "setpwent";
659 	cmds[1] = "getpwent";
660 	cmds[2] = "getpwent_r";
661 	cmds[3] = "getpwnam";
662 	cmds[4] = "getpwnam_r";
663 	cmds[5] = "getpwuid";
664 	cmds[6] = "getpwuid_r";
665 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
666 	cmds[0] = "getpwnam_r";
667 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
668 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
669 	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);
670 
671 	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
672 	    GETPWNAM | GETPWUID | GETPWUID_R));
673 
674 	cap_close(cappwd);
675 
676 	/*
677 	 * Allow:
678 	 * cmds: setpwent, getpwent, getpwent_r, getpwnam,
679 	 *       getpwuid, getpwuid_r
680 	 * users:
681 	 *     names:
682 	 *     uids: 0, 1, 2, 3, 5
683 	 * Disallow:
684 	 * cmds: getpwnam_r
685 	 * users:
686 	 */
687 	cappwd = cap_clone(origcappwd);
688 	CHECK(cappwd != NULL);
689 
690 	cmds[0] = "setpwent";
691 	cmds[1] = "getpwent";
692 	cmds[2] = "getpwent_r";
693 	cmds[3] = "getpwnam";
694 	cmds[4] = "getpwuid";
695 	cmds[5] = "getpwuid_r";
696 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
697 	cmds[0] = "setpwent";
698 	cmds[1] = "getpwent";
699 	cmds[2] = "getpwent_r";
700 	cmds[3] = "getpwnam";
701 	cmds[4] = "getpwnam_r";
702 	cmds[5] = "getpwuid";
703 	cmds[6] = "getpwuid_r";
704 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
705 	cmds[0] = "getpwnam_r";
706 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
707 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
708 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);
709 
710 	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
711 	    GETPWNAM | GETPWUID | GETPWUID_R));
712 
713 	cap_close(cappwd);
714 
715 	/*
716 	 * Allow:
717 	 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r,
718 	 *       getpwuid_r
719 	 * users:
720 	 *     names: root, toor, daemon, operator, bin, kmem
721 	 *     uids:
722 	 * Disallow:
723 	 * cmds: getpwuid
724 	 * users:
725 	 */
726 	cappwd = cap_clone(origcappwd);
727 	CHECK(cappwd != NULL);
728 
729 	cmds[0] = "setpwent";
730 	cmds[1] = "getpwent";
731 	cmds[2] = "getpwent_r";
732 	cmds[3] = "getpwnam";
733 	cmds[4] = "getpwnam_r";
734 	cmds[5] = "getpwuid_r";
735 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
736 	cmds[0] = "setpwent";
737 	cmds[1] = "getpwent";
738 	cmds[2] = "getpwent_r";
739 	cmds[3] = "getpwnam";
740 	cmds[4] = "getpwnam_r";
741 	cmds[5] = "getpwuid";
742 	cmds[6] = "getpwuid_r";
743 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
744 	cmds[0] = "getpwuid";
745 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
746 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
747 	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);
748 
749 	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
750 	    GETPWNAM | GETPWNAM_R | GETPWUID_R));
751 
752 	cap_close(cappwd);
753 
754 	/*
755 	 * Allow:
756 	 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r,
757 	 *       getpwuid_r
758 	 * users:
759 	 *     names:
760 	 *     uids: 0, 1, 2, 3, 5
761 	 * Disallow:
762 	 * cmds: getpwuid
763 	 * users:
764 	 */
765 	cappwd = cap_clone(origcappwd);
766 	CHECK(cappwd != NULL);
767 
768 	cmds[0] = "setpwent";
769 	cmds[1] = "getpwent";
770 	cmds[2] = "getpwent_r";
771 	cmds[3] = "getpwnam";
772 	cmds[4] = "getpwnam_r";
773 	cmds[5] = "getpwuid_r";
774 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
775 	cmds[0] = "setpwent";
776 	cmds[1] = "getpwent";
777 	cmds[2] = "getpwent_r";
778 	cmds[3] = "getpwnam";
779 	cmds[4] = "getpwnam_r";
780 	cmds[5] = "getpwuid";
781 	cmds[6] = "getpwuid_r";
782 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
783 	cmds[0] = "getpwuid";
784 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
785 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
786 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);
787 
788 	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
789 	    GETPWNAM | GETPWNAM_R | GETPWUID_R));
790 
791 	cap_close(cappwd);
792 
793 	/*
794 	 * Allow:
795 	 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r,
796 	 *       getpwuid
797 	 * users:
798 	 *     names: root, toor, daemon, operator, bin, kmem
799 	 *     uids:
800 	 * Disallow:
801 	 * cmds: getpwuid_r
802 	 * users:
803 	 */
804 	cappwd = cap_clone(origcappwd);
805 	CHECK(cappwd != NULL);
806 
807 	cmds[0] = "setpwent";
808 	cmds[1] = "getpwent";
809 	cmds[2] = "getpwent_r";
810 	cmds[3] = "getpwnam";
811 	cmds[4] = "getpwnam_r";
812 	cmds[5] = "getpwuid";
813 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
814 	cmds[0] = "setpwent";
815 	cmds[1] = "getpwent";
816 	cmds[2] = "getpwent_r";
817 	cmds[3] = "getpwnam";
818 	cmds[4] = "getpwnam_r";
819 	cmds[5] = "getpwuid";
820 	cmds[6] = "getpwuid_r";
821 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
822 	cmds[0] = "getpwuid_r";
823 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
824 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
825 	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);
826 
827 	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
828 	    GETPWNAM | GETPWNAM_R | GETPWUID));
829 
830 	cap_close(cappwd);
831 
832 	/*
833 	 * Allow:
834 	 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r,
835 	 *       getpwuid
836 	 * users:
837 	 *     names:
838 	 *     uids: 0, 1, 2, 3, 5
839 	 * Disallow:
840 	 * cmds: getpwuid_r
841 	 * users:
842 	 */
843 	cappwd = cap_clone(origcappwd);
844 	CHECK(cappwd != NULL);
845 
846 	cmds[0] = "setpwent";
847 	cmds[1] = "getpwent";
848 	cmds[2] = "getpwent_r";
849 	cmds[3] = "getpwnam";
850 	cmds[4] = "getpwnam_r";
851 	cmds[5] = "getpwuid";
852 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
853 	cmds[0] = "setpwent";
854 	cmds[1] = "getpwent";
855 	cmds[2] = "getpwent_r";
856 	cmds[3] = "getpwnam";
857 	cmds[4] = "getpwnam_r";
858 	cmds[5] = "getpwuid";
859 	cmds[6] = "getpwuid_r";
860 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
861 	cmds[0] = "getpwuid_r";
862 	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
863 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
864 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);
865 
866 	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
867 	    GETPWNAM | GETPWNAM_R | GETPWUID));
868 
869 	cap_close(cappwd);
870 }
871 
872 #define	PW_NAME		_PWF_NAME
873 #define	PW_PASSWD	_PWF_PASSWD
874 #define	PW_UID		_PWF_UID
875 #define	PW_GID		_PWF_GID
876 #define	PW_CHANGE	_PWF_CHANGE
877 #define	PW_CLASS	_PWF_CLASS
878 #define	PW_GECOS	_PWF_GECOS
879 #define	PW_DIR		_PWF_DIR
880 #define	PW_SHELL	_PWF_SHELL
881 #define	PW_EXPIRE	_PWF_EXPIRE
882 
883 static unsigned int
884 passwd_fields(const struct passwd *pwd)
885 {
886 	unsigned int result;
887 
888 	result = 0;
889 
890 	if (pwd->pw_name != NULL && pwd->pw_name[0] != '\0')
891 		result |= PW_NAME;
892 //	else
893 //		printf("No pw_name\n");
894 
895 	if (pwd->pw_passwd != NULL && pwd->pw_passwd[0] != '\0')
896 		result |= PW_PASSWD;
897 	else if ((pwd->pw_fields & _PWF_PASSWD) != 0)
898 		result |= PW_PASSWD;
899 //	else
900 //		printf("No pw_passwd\n");
901 
902 	if (pwd->pw_uid != (uid_t)-1)
903 		result |= PW_UID;
904 //	else
905 //		printf("No pw_uid\n");
906 
907 	if (pwd->pw_gid != (gid_t)-1)
908 		result |= PW_GID;
909 //	else
910 //		printf("No pw_gid\n");
911 
912 	if (pwd->pw_change != 0 || (pwd->pw_fields & _PWF_CHANGE) != 0)
913 		result |= PW_CHANGE;
914 //	else
915 //		printf("No pw_change\n");
916 
917 	if (pwd->pw_class != NULL && pwd->pw_class[0] != '\0')
918 		result |= PW_CLASS;
919 	else if ((pwd->pw_fields & _PWF_CLASS) != 0)
920 		result |= PW_CLASS;
921 //	else
922 //		printf("No pw_class\n");
923 
924 	if (pwd->pw_gecos != NULL && pwd->pw_gecos[0] != '\0')
925 		result |= PW_GECOS;
926 	else if ((pwd->pw_fields & _PWF_GECOS) != 0)
927 		result |= PW_GECOS;
928 //	else
929 //		printf("No pw_gecos\n");
930 
931 	if (pwd->pw_dir != NULL && pwd->pw_dir[0] != '\0')
932 		result |= PW_DIR;
933 	else if ((pwd->pw_fields & _PWF_DIR) != 0)
934 		result |= PW_DIR;
935 //	else
936 //		printf("No pw_dir\n");
937 
938 	if (pwd->pw_shell != NULL && pwd->pw_shell[0] != '\0')
939 		result |= PW_SHELL;
940 	else if ((pwd->pw_fields & _PWF_SHELL) != 0)
941 		result |= PW_SHELL;
942 //	else
943 //		printf("No pw_shell\n");
944 
945 	if (pwd->pw_expire != 0 || (pwd->pw_fields & _PWF_EXPIRE) != 0)
946 		result |= PW_EXPIRE;
947 //	else
948 //		printf("No pw_expire\n");
949 
950 if (false && pwd->pw_fields != (int)result) {
951 printf("fields=0x%x != result=0x%x\n", (const unsigned int)pwd->pw_fields, result);
952 printf("           fields result\n");
953 printf("PW_NAME    %d      %d\n", (pwd->pw_fields & PW_NAME) != 0, (result & PW_NAME) != 0);
954 printf("PW_PASSWD  %d      %d\n", (pwd->pw_fields & PW_PASSWD) != 0, (result & PW_PASSWD) != 0);
955 printf("PW_UID     %d      %d\n", (pwd->pw_fields & PW_UID) != 0, (result & PW_UID) != 0);
956 printf("PW_GID     %d      %d\n", (pwd->pw_fields & PW_GID) != 0, (result & PW_GID) != 0);
957 printf("PW_CHANGE  %d      %d\n", (pwd->pw_fields & PW_CHANGE) != 0, (result & PW_CHANGE) != 0);
958 printf("PW_CLASS   %d      %d\n", (pwd->pw_fields & PW_CLASS) != 0, (result & PW_CLASS) != 0);
959 printf("PW_GECOS   %d      %d\n", (pwd->pw_fields & PW_GECOS) != 0, (result & PW_GECOS) != 0);
960 printf("PW_DIR     %d      %d\n", (pwd->pw_fields & PW_DIR) != 0, (result & PW_DIR) != 0);
961 printf("PW_SHELL   %d      %d\n", (pwd->pw_fields & PW_SHELL) != 0, (result & PW_SHELL) != 0);
962 printf("PW_EXPIRE  %d      %d\n", (pwd->pw_fields & PW_EXPIRE) != 0, (result & PW_EXPIRE) != 0);
963 }
964 
965 //printf("result=0x%x\n", result);
966 	return (result);
967 }
968 
969 static bool
970 runtest_fields(cap_channel_t *cappwd, unsigned int expected)
971 {
972 	char buf[1024];
973 	struct passwd *pwd;
974 	struct passwd st;
975 
976 //printf("expected=0x%x\n", expected);
977 	cap_setpwent(cappwd);
978 	pwd = cap_getpwent(cappwd);
979 	if ((passwd_fields(pwd) & ~expected) != 0)
980 		return (false);
981 
982 	cap_setpwent(cappwd);
983 	cap_getpwent_r(cappwd, &st, buf, sizeof(buf), &pwd);
984 	if ((passwd_fields(pwd) & ~expected) != 0)
985 		return (false);
986 
987 	pwd = cap_getpwnam(cappwd, "root");
988 	if ((passwd_fields(pwd) & ~expected) != 0)
989 		return (false);
990 
991 	cap_getpwnam_r(cappwd, "root", &st, buf, sizeof(buf), &pwd);
992 	if ((passwd_fields(pwd) & ~expected) != 0)
993 		return (false);
994 
995 	pwd = cap_getpwuid(cappwd, UID_ROOT);
996 	if ((passwd_fields(pwd) & ~expected) != 0)
997 		return (false);
998 
999 	cap_getpwuid_r(cappwd, UID_ROOT, &st, buf, sizeof(buf), &pwd);
1000 	if ((passwd_fields(pwd) & ~expected) != 0)
1001 		return (false);
1002 
1003 	return (true);
1004 }
1005 
1006 static void
1007 test_fields(cap_channel_t *origcappwd)
1008 {
1009 	cap_channel_t *cappwd;
1010 	const char *fields[10];
1011 
1012 	/* No limits. */
1013 
1014 	CHECK(runtest_fields(origcappwd, PW_NAME | PW_PASSWD | PW_UID |
1015 	    PW_GID | PW_CHANGE | PW_CLASS | PW_GECOS | PW_DIR | PW_SHELL |
1016 	    PW_EXPIRE));
1017 
1018 	/*
1019 	 * Allow:
1020 	 * fields: pw_name, pw_passwd, pw_uid, pw_gid, pw_change, pw_class,
1021 	 *         pw_gecos, pw_dir, pw_shell, pw_expire
1022 	 */
1023 	cappwd = cap_clone(origcappwd);
1024 	CHECK(cappwd != NULL);
1025 
1026 	fields[0] = "pw_name";
1027 	fields[1] = "pw_passwd";
1028 	fields[2] = "pw_uid";
1029 	fields[3] = "pw_gid";
1030 	fields[4] = "pw_change";
1031 	fields[5] = "pw_class";
1032 	fields[6] = "pw_gecos";
1033 	fields[7] = "pw_dir";
1034 	fields[8] = "pw_shell";
1035 	fields[9] = "pw_expire";
1036 	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
1037 
1038 	CHECK(runtest_fields(origcappwd, PW_NAME | PW_PASSWD | PW_UID |
1039 	    PW_GID | PW_CHANGE | PW_CLASS | PW_GECOS | PW_DIR | PW_SHELL |
1040 	    PW_EXPIRE));
1041 
1042 	cap_close(cappwd);
1043 
1044 	/*
1045 	 * Allow:
1046 	 * fields: pw_name, pw_passwd, pw_uid, pw_gid, pw_change
1047 	 */
1048 	cappwd = cap_clone(origcappwd);
1049 	CHECK(cappwd != NULL);
1050 
1051 	fields[0] = "pw_name";
1052 	fields[1] = "pw_passwd";
1053 	fields[2] = "pw_uid";
1054 	fields[3] = "pw_gid";
1055 	fields[4] = "pw_change";
1056 	CHECK(cap_pwd_limit_fields(cappwd, fields, 5) == 0);
1057 	fields[5] = "pw_class";
1058 	CHECK(cap_pwd_limit_fields(cappwd, fields, 6) == -1 &&
1059 	    errno == ENOTCAPABLE);
1060 	fields[0] = "pw_class";
1061 	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 &&
1062 	    errno == ENOTCAPABLE);
1063 
1064 	CHECK(runtest_fields(cappwd, PW_NAME | PW_PASSWD | PW_UID |
1065 	    PW_GID | PW_CHANGE));
1066 
1067 	cap_close(cappwd);
1068 
1069 	/*
1070 	 * Allow:
1071 	 * fields: pw_class, pw_gecos, pw_dir, pw_shell, pw_expire
1072 	 */
1073 	cappwd = cap_clone(origcappwd);
1074 	CHECK(cappwd != NULL);
1075 
1076 	fields[0] = "pw_class";
1077 	fields[1] = "pw_gecos";
1078 	fields[2] = "pw_dir";
1079 	fields[3] = "pw_shell";
1080 	fields[4] = "pw_expire";
1081 	CHECK(cap_pwd_limit_fields(cappwd, fields, 5) == 0);
1082 	fields[5] = "pw_uid";
1083 	CHECK(cap_pwd_limit_fields(cappwd, fields, 6) == -1 &&
1084 	    errno == ENOTCAPABLE);
1085 	fields[0] = "pw_uid";
1086 	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 &&
1087 	    errno == ENOTCAPABLE);
1088 
1089 	CHECK(runtest_fields(cappwd, PW_CLASS | PW_GECOS | PW_DIR |
1090 	    PW_SHELL | PW_EXPIRE));
1091 
1092 	cap_close(cappwd);
1093 
1094 	/*
1095 	 * Allow:
1096 	 * fields: pw_name, pw_uid, pw_change, pw_gecos, pw_shell
1097 	 */
1098 	cappwd = cap_clone(origcappwd);
1099 	CHECK(cappwd != NULL);
1100 
1101 	fields[0] = "pw_name";
1102 	fields[1] = "pw_uid";
1103 	fields[2] = "pw_change";
1104 	fields[3] = "pw_gecos";
1105 	fields[4] = "pw_shell";
1106 	CHECK(cap_pwd_limit_fields(cappwd, fields, 5) == 0);
1107 	fields[5] = "pw_class";
1108 	CHECK(cap_pwd_limit_fields(cappwd, fields, 6) == -1 &&
1109 	    errno == ENOTCAPABLE);
1110 	fields[0] = "pw_class";
1111 	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 &&
1112 	    errno == ENOTCAPABLE);
1113 
1114 	CHECK(runtest_fields(cappwd, PW_NAME | PW_UID | PW_CHANGE |
1115 	    PW_GECOS | PW_SHELL));
1116 
1117 	cap_close(cappwd);
1118 
1119 	/*
1120 	 * Allow:
1121 	 * fields: pw_passwd, pw_gid, pw_class, pw_dir, pw_expire
1122 	 */
1123 	cappwd = cap_clone(origcappwd);
1124 	CHECK(cappwd != NULL);
1125 
1126 	fields[0] = "pw_passwd";
1127 	fields[1] = "pw_gid";
1128 	fields[2] = "pw_class";
1129 	fields[3] = "pw_dir";
1130 	fields[4] = "pw_expire";
1131 	CHECK(cap_pwd_limit_fields(cappwd, fields, 5) == 0);
1132 	fields[5] = "pw_uid";
1133 	CHECK(cap_pwd_limit_fields(cappwd, fields, 6) == -1 &&
1134 	    errno == ENOTCAPABLE);
1135 	fields[0] = "pw_uid";
1136 	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 &&
1137 	    errno == ENOTCAPABLE);
1138 
1139 	CHECK(runtest_fields(cappwd, PW_PASSWD | PW_GID | PW_CLASS |
1140 	    PW_DIR | PW_EXPIRE));
1141 
1142 	cap_close(cappwd);
1143 
1144 	/*
1145 	 * Allow:
1146 	 * fields: pw_uid, pw_class, pw_shell
1147 	 */
1148 	cappwd = cap_clone(origcappwd);
1149 	CHECK(cappwd != NULL);
1150 
1151 	fields[0] = "pw_uid";
1152 	fields[1] = "pw_class";
1153 	fields[2] = "pw_shell";
1154 	CHECK(cap_pwd_limit_fields(cappwd, fields, 3) == 0);
1155 	fields[3] = "pw_change";
1156 	CHECK(cap_pwd_limit_fields(cappwd, fields, 4) == -1 &&
1157 	    errno == ENOTCAPABLE);
1158 	fields[0] = "pw_change";
1159 	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 &&
1160 	    errno == ENOTCAPABLE);
1161 
1162 	CHECK(runtest_fields(cappwd, PW_UID | PW_CLASS | PW_SHELL));
1163 
1164 	cap_close(cappwd);
1165 
1166 	/*
1167 	 * Allow:
1168 	 * fields: pw_change
1169 	 */
1170 	cappwd = cap_clone(origcappwd);
1171 	CHECK(cappwd != NULL);
1172 
1173 	fields[0] = "pw_change";
1174 	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == 0);
1175 	fields[1] = "pw_uid";
1176 	CHECK(cap_pwd_limit_fields(cappwd, fields, 2) == -1 &&
1177 	    errno == ENOTCAPABLE);
1178 	fields[0] = "pw_uid";
1179 	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 &&
1180 	    errno == ENOTCAPABLE);
1181 
1182 	CHECK(runtest_fields(cappwd, PW_CHANGE));
1183 
1184 	cap_close(cappwd);
1185 }
1186 
1187 static bool
1188 runtest_users(cap_channel_t *cappwd, const char **names, const uid_t *uids,
1189     size_t nusers)
1190 {
1191 	char buf[1024];
1192 	struct passwd *pwd;
1193 	struct passwd st;
1194 	unsigned int i, got;
1195 
1196 	cap_setpwent(cappwd);
1197 	got = 0;
1198 	for (;;) {
1199 		pwd = cap_getpwent(cappwd);
1200 		if (pwd == NULL)
1201 			break;
1202 		got++;
1203 		for (i = 0; i < nusers; i++) {
1204 			if (strcmp(names[i], pwd->pw_name) == 0 &&
1205 			    uids[i] == pwd->pw_uid) {
1206 				break;
1207 			}
1208 		}
1209 		if (i == nusers)
1210 			return (false);
1211 	}
1212 	if (got != nusers)
1213 		return (false);
1214 
1215 	cap_setpwent(cappwd);
1216 	got = 0;
1217 	for (;;) {
1218 		cap_getpwent_r(cappwd, &st, buf, sizeof(buf), &pwd);
1219 		if (pwd == NULL)
1220 			break;
1221 		got++;
1222 		for (i = 0; i < nusers; i++) {
1223 			if (strcmp(names[i], pwd->pw_name) == 0 &&
1224 			    uids[i] == pwd->pw_uid) {
1225 				break;
1226 			}
1227 		}
1228 		if (i == nusers)
1229 			return (false);
1230 	}
1231 	if (got != nusers)
1232 		return (false);
1233 
1234 	for (i = 0; i < nusers; i++) {
1235 		pwd = cap_getpwnam(cappwd, names[i]);
1236 		if (pwd == NULL)
1237 			return (false);
1238 	}
1239 
1240 	for (i = 0; i < nusers; i++) {
1241 		cap_getpwnam_r(cappwd, names[i], &st, buf, sizeof(buf), &pwd);
1242 		if (pwd == NULL)
1243 			return (false);
1244 	}
1245 
1246 	for (i = 0; i < nusers; i++) {
1247 		pwd = cap_getpwuid(cappwd, uids[i]);
1248 		if (pwd == NULL)
1249 			return (false);
1250 	}
1251 
1252 	for (i = 0; i < nusers; i++) {
1253 		cap_getpwuid_r(cappwd, uids[i], &st, buf, sizeof(buf), &pwd);
1254 		if (pwd == NULL)
1255 			return (false);
1256 	}
1257 
1258 	return (true);
1259 }
1260 
1261 static void
1262 test_users(cap_channel_t *origcappwd)
1263 {
1264 	cap_channel_t *cappwd;
1265 	const char *names[6];
1266 	uid_t uids[6];
1267 
1268 	/*
1269 	 * Allow:
1270 	 * users:
1271 	 *     names: root, toor, daemon, operator, bin, tty
1272 	 *     uids:
1273 	 */
1274 	cappwd = cap_clone(origcappwd);
1275 	CHECK(cappwd != NULL);
1276 
1277 	names[0] = "root";
1278 	names[1] = "toor";
1279 	names[2] = "daemon";
1280 	names[3] = "operator";
1281 	names[4] = "bin";
1282 	names[5] = "tty";
1283 	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);
1284 	uids[0] = 0;
1285 	uids[1] = 0;
1286 	uids[2] = 1;
1287 	uids[3] = 2;
1288 	uids[4] = 3;
1289 	uids[5] = 4;
1290 
1291 	CHECK(runtest_users(cappwd, names, uids, 6));
1292 
1293 	cap_close(cappwd);
1294 
1295 	/*
1296 	 * Allow:
1297 	 * users:
1298 	 *     names: daemon, operator, bin
1299 	 *     uids:
1300 	 */
1301 	cappwd = cap_clone(origcappwd);
1302 	CHECK(cappwd != NULL);
1303 
1304 	names[0] = "daemon";
1305 	names[1] = "operator";
1306 	names[2] = "bin";
1307 	CHECK(cap_pwd_limit_users(cappwd, names, 3, NULL, 0) == 0);
1308 	names[3] = "tty";
1309 	CHECK(cap_pwd_limit_users(cappwd, names, 4, NULL, 0) == -1 &&
1310 	    errno == ENOTCAPABLE);
1311 	names[0] = "tty";
1312 	CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == -1 &&
1313 	    errno == ENOTCAPABLE);
1314 	names[0] = "daemon";
1315 	uids[0] = 1;
1316 	uids[1] = 2;
1317 	uids[2] = 3;
1318 
1319 	CHECK(runtest_users(cappwd, names, uids, 3));
1320 
1321 	cap_close(cappwd);
1322 
1323 	/*
1324 	 * Allow:
1325 	 * users:
1326 	 *     names: daemon, bin, tty
1327 	 *     uids:
1328 	 */
1329 	cappwd = cap_clone(origcappwd);
1330 	CHECK(cappwd != NULL);
1331 
1332 	names[0] = "daemon";
1333 	names[1] = "bin";
1334 	names[2] = "tty";
1335 	CHECK(cap_pwd_limit_users(cappwd, names, 3, NULL, 0) == 0);
1336 	names[3] = "operator";
1337 	CHECK(cap_pwd_limit_users(cappwd, names, 4, NULL, 0) == -1 &&
1338 	    errno == ENOTCAPABLE);
1339 	names[0] = "operator";
1340 	CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == -1 &&
1341 	    errno == ENOTCAPABLE);
1342 	names[0] = "daemon";
1343 	uids[0] = 1;
1344 	uids[1] = 3;
1345 	uids[2] = 4;
1346 
1347 	CHECK(runtest_users(cappwd, names, uids, 3));
1348 
1349 	cap_close(cappwd);
1350 
1351 	/*
1352 	 * Allow:
1353 	 * users:
1354 	 *     names:
1355 	 *     uids: 1, 2, 3
1356 	 */
1357 	cappwd = cap_clone(origcappwd);
1358 	CHECK(cappwd != NULL);
1359 
1360 	names[0] = "daemon";
1361 	names[1] = "operator";
1362 	names[2] = "bin";
1363 	uids[0] = 1;
1364 	uids[1] = 2;
1365 	uids[2] = 3;
1366 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 3) == 0);
1367 	uids[3] = 4;
1368 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 4) == -1 &&
1369 	    errno == ENOTCAPABLE);
1370 	uids[0] = 4;
1371 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == -1 &&
1372 	    errno == ENOTCAPABLE);
1373 	uids[0] = 1;
1374 
1375 	CHECK(runtest_users(cappwd, names, uids, 3));
1376 
1377 	cap_close(cappwd);
1378 
1379 	/*
1380 	 * Allow:
1381 	 * users:
1382 	 *     names:
1383 	 *     uids: 1, 3, 4
1384 	 */
1385 	cappwd = cap_clone(origcappwd);
1386 	CHECK(cappwd != NULL);
1387 
1388 	names[0] = "daemon";
1389 	names[1] = "bin";
1390 	names[2] = "tty";
1391 	uids[0] = 1;
1392 	uids[1] = 3;
1393 	uids[2] = 4;
1394 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 3) == 0);
1395 	uids[3] = 5;
1396 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 4) == -1 &&
1397 	    errno == ENOTCAPABLE);
1398 	uids[0] = 5;
1399 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == -1 &&
1400 	    errno == ENOTCAPABLE);
1401 	uids[0] = 1;
1402 
1403 	CHECK(runtest_users(cappwd, names, uids, 3));
1404 
1405 	cap_close(cappwd);
1406 
1407 	/*
1408 	 * Allow:
1409 	 * users:
1410 	 *     names: bin
1411 	 *     uids:
1412 	 */
1413 	cappwd = cap_clone(origcappwd);
1414 	CHECK(cappwd != NULL);
1415 
1416 	names[0] = "bin";
1417 	CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == 0);
1418 	names[1] = "operator";
1419 	CHECK(cap_pwd_limit_users(cappwd, names, 2, NULL, 0) == -1 &&
1420 	    errno == ENOTCAPABLE);
1421 	names[0] = "operator";
1422 	CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == -1 &&
1423 	    errno == ENOTCAPABLE);
1424 	names[0] = "bin";
1425 	uids[0] = 3;
1426 
1427 	CHECK(runtest_users(cappwd, names, uids, 1));
1428 
1429 	cap_close(cappwd);
1430 
1431 	/*
1432 	 * Allow:
1433 	 * users:
1434 	 *     names: daemon, tty
1435 	 *     uids:
1436 	 */
1437 	cappwd = cap_clone(origcappwd);
1438 	CHECK(cappwd != NULL);
1439 
1440 	names[0] = "daemon";
1441 	names[1] = "tty";
1442 	CHECK(cap_pwd_limit_users(cappwd, names, 2, NULL, 0) == 0);
1443 	names[2] = "operator";
1444 	CHECK(cap_pwd_limit_users(cappwd, names, 3, NULL, 0) == -1 &&
1445 	    errno == ENOTCAPABLE);
1446 	names[0] = "operator";
1447 	CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == -1 &&
1448 	    errno == ENOTCAPABLE);
1449 	names[0] = "daemon";
1450 	uids[0] = 1;
1451 	uids[1] = 4;
1452 
1453 	CHECK(runtest_users(cappwd, names, uids, 2));
1454 
1455 	cap_close(cappwd);
1456 
1457 	/*
1458 	 * Allow:
1459 	 * users:
1460 	 *     names:
1461 	 *     uids: 3
1462 	 */
1463 	cappwd = cap_clone(origcappwd);
1464 	CHECK(cappwd != NULL);
1465 
1466 	names[0] = "bin";
1467 	uids[0] = 3;
1468 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == 0);
1469 	uids[1] = 4;
1470 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 2) == -1 &&
1471 	    errno == ENOTCAPABLE);
1472 	uids[0] = 4;
1473 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == -1 &&
1474 	    errno == ENOTCAPABLE);
1475 	uids[0] = 3;
1476 
1477 	CHECK(runtest_users(cappwd, names, uids, 1));
1478 
1479 	cap_close(cappwd);
1480 
1481 	/*
1482 	 * Allow:
1483 	 * users:
1484 	 *     names:
1485 	 *     uids: 1, 4
1486 	 */
1487 	cappwd = cap_clone(origcappwd);
1488 	CHECK(cappwd != NULL);
1489 
1490 	names[0] = "daemon";
1491 	names[1] = "tty";
1492 	uids[0] = 1;
1493 	uids[1] = 4;
1494 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 2) == 0);
1495 	uids[2] = 3;
1496 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 3) == -1 &&
1497 	    errno == ENOTCAPABLE);
1498 	uids[0] = 3;
1499 	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == -1 &&
1500 	    errno == ENOTCAPABLE);
1501 	uids[0] = 1;
1502 
1503 	CHECK(runtest_users(cappwd, names, uids, 2));
1504 
1505 	cap_close(cappwd);
1506 }
1507 
1508 int
1509 main(void)
1510 {
1511 	cap_channel_t *capcas, *cappwd;
1512 
1513 	printf("1..188\n");
1514 	fflush(stdout);
1515 
1516 	capcas = cap_init();
1517 	CHECKX(capcas != NULL);
1518 
1519 	cappwd = cap_service_open(capcas, "system.pwd");
1520 	CHECKX(cappwd != NULL);
1521 
1522 	cap_close(capcas);
1523 
1524 	/* No limits. */
1525 
1526 	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | GETPWNAM |
1527 	    GETPWNAM_R | GETPWUID | GETPWUID_R));
1528 
1529 	test_cmds(cappwd);
1530 
1531 	test_fields(cappwd);
1532 
1533 	test_users(cappwd);
1534 
1535 	cap_close(cappwd);
1536 
1537 	exit(0);
1538 }
1539