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