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