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