]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/regression/capsicum/libcasper/pwd.c
Add simple support for CloudABI processes to kdump(1).
[FreeBSD/FreeBSD.git] / tools / regression / capsicum / libcasper / pwd.c
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 }