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
passwd_compare(const struct passwd * pwd0,const struct passwd * pwd1)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
runtest_cmds(cap_channel_t * cappwd)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
test_cmds(cap_channel_t * origcappwd)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
passwd_fields(const struct passwd * pwd)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
runtest_fields(cap_channel_t * cappwd,unsigned int expected)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
test_fields(cap_channel_t * origcappwd)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
runtest_users(cap_channel_t * cappwd,const char ** names,const uid_t * uids,size_t nusers)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
test_users(cap_channel_t * origcappwd)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
main(void)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