1296047Soshogbo/*-
2296047Soshogbo * Copyright (c) 2013 The FreeBSD Foundation
3296047Soshogbo * All rights reserved.
4296047Soshogbo *
5296047Soshogbo * This software was developed by Pawel Jakub Dawidek under sponsorship from
6296047Soshogbo * the FreeBSD Foundation.
7296047Soshogbo *
8296047Soshogbo * Redistribution and use in source and binary forms, with or without
9296047Soshogbo * modification, are permitted provided that the following conditions
10296047Soshogbo * are met:
11296047Soshogbo * 1. Redistributions of source code must retain the above copyright
12296047Soshogbo *    notice, this list of conditions and the following disclaimer.
13296047Soshogbo * 2. Redistributions in binary form must reproduce the above copyright
14296047Soshogbo *    notice, this list of conditions and the following disclaimer in the
15296047Soshogbo *    documentation and/or other materials provided with the distribution.
16296047Soshogbo *
17296047Soshogbo * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18296047Soshogbo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19296047Soshogbo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20296047Soshogbo * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21296047Soshogbo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22296047Soshogbo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23296047Soshogbo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24296047Soshogbo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25296047Soshogbo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26296047Soshogbo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27296047Soshogbo * SUCH DAMAGE.
28296047Soshogbo */
29296047Soshogbo
30296047Soshogbo#include <sys/cdefs.h>
31296047Soshogbo__FBSDID("$FreeBSD: stable/11/lib/libcasper/services/cap_grp/tests/grp_test.c 322715 2017-08-20 06:07:40Z ngie $");
32296047Soshogbo
33296047Soshogbo#include <sys/capsicum.h>
34296047Soshogbo
35296047Soshogbo#include <assert.h>
36296047Soshogbo#include <err.h>
37296047Soshogbo#include <errno.h>
38296047Soshogbo#include <grp.h>
39296047Soshogbo#include <stdio.h>
40296047Soshogbo#include <stdlib.h>
41296047Soshogbo#include <string.h>
42296047Soshogbo#include <unistd.h>
43296047Soshogbo
44296047Soshogbo#include <libcasper.h>
45296047Soshogbo
46296047Soshogbo#include <casper/cap_grp.h>
47296047Soshogbo
48296047Soshogbostatic int ntest = 1;
49296047Soshogbo
50296047Soshogbo#define CHECK(expr)     do {						\
51296047Soshogbo	if ((expr))							\
52296047Soshogbo		printf("ok %d %s:%u\n", ntest, __FILE__, __LINE__);	\
53296047Soshogbo	else								\
54296047Soshogbo		printf("not ok %d %s:%u\n", ntest, __FILE__, __LINE__);	\
55322715Sngie	fflush(stdout);							\
56296047Soshogbo	ntest++;							\
57296047Soshogbo} while (0)
58296047Soshogbo#define CHECKX(expr)     do {						\
59296047Soshogbo	if ((expr)) {							\
60296047Soshogbo		printf("ok %d %s:%u\n", ntest, __FILE__, __LINE__);	\
61296047Soshogbo	} else {							\
62296047Soshogbo		printf("not ok %d %s:%u\n", ntest, __FILE__, __LINE__);	\
63296047Soshogbo		exit(1);						\
64296047Soshogbo	}								\
65322715Sngie	fflush(stdout);							\
66296047Soshogbo	ntest++;							\
67296047Soshogbo} while (0)
68296047Soshogbo
69296047Soshogbo#define	GID_WHEEL	0
70296047Soshogbo#define	GID_OPERATOR	5
71296047Soshogbo
72296047Soshogbo#define	GETGRENT0	0x0001
73296047Soshogbo#define	GETGRENT1	0x0002
74296047Soshogbo#define	GETGRENT2	0x0004
75296047Soshogbo#define	GETGRENT	(GETGRENT0 | GETGRENT1 | GETGRENT2)
76296047Soshogbo#define	GETGRENT_R0	0x0008
77296047Soshogbo#define	GETGRENT_R1	0x0010
78296047Soshogbo#define	GETGRENT_R2	0x0020
79296047Soshogbo#define	GETGRENT_R	(GETGRENT_R0 | GETGRENT_R1 | GETGRENT_R2)
80296047Soshogbo#define	GETGRNAM	0x0040
81296047Soshogbo#define	GETGRNAM_R	0x0080
82296047Soshogbo#define	GETGRGID	0x0100
83296047Soshogbo#define	GETGRGID_R	0x0200
84296047Soshogbo#define	SETGRENT	0x0400
85296047Soshogbo
86296047Soshogbostatic bool
87296047Soshogbogroup_mem_compare(char **mem0, char **mem1)
88296047Soshogbo{
89296047Soshogbo	int i0, i1;
90296047Soshogbo
91296047Soshogbo	if (mem0 == NULL && mem1 == NULL)
92296047Soshogbo		return (true);
93296047Soshogbo	if (mem0 == NULL || mem1 == NULL)
94296047Soshogbo		return (false);
95296047Soshogbo
96296047Soshogbo	for (i0 = 0; mem0[i0] != NULL; i0++) {
97296047Soshogbo		for (i1 = 0; mem1[i1] != NULL; i1++) {
98296047Soshogbo			if (strcmp(mem0[i0], mem1[i1]) == 0)
99296047Soshogbo				break;
100296047Soshogbo		}
101296047Soshogbo		if (mem1[i1] == NULL)
102296047Soshogbo			return (false);
103296047Soshogbo	}
104296047Soshogbo
105296047Soshogbo	return (true);
106296047Soshogbo}
107296047Soshogbo
108296047Soshogbostatic bool
109296047Soshogbogroup_compare(const struct group *grp0, const struct group *grp1)
110296047Soshogbo{
111296047Soshogbo
112296047Soshogbo	if (grp0 == NULL && grp1 == NULL)
113296047Soshogbo		return (true);
114296047Soshogbo	if (grp0 == NULL || grp1 == NULL)
115296047Soshogbo		return (false);
116296047Soshogbo
117296047Soshogbo	if (strcmp(grp0->gr_name, grp1->gr_name) != 0)
118296047Soshogbo		return (false);
119296047Soshogbo
120296047Soshogbo	if (grp0->gr_passwd != NULL || grp1->gr_passwd != NULL) {
121296047Soshogbo		if (grp0->gr_passwd == NULL || grp1->gr_passwd == NULL)
122296047Soshogbo			return (false);
123296047Soshogbo		if (strcmp(grp0->gr_passwd, grp1->gr_passwd) != 0)
124296047Soshogbo			return (false);
125296047Soshogbo	}
126296047Soshogbo
127296047Soshogbo	if (grp0->gr_gid != grp1->gr_gid)
128296047Soshogbo		return (false);
129296047Soshogbo
130296047Soshogbo	if (!group_mem_compare(grp0->gr_mem, grp1->gr_mem))
131296047Soshogbo		return (false);
132296047Soshogbo
133296047Soshogbo	return (true);
134296047Soshogbo}
135296047Soshogbo
136296047Soshogbostatic unsigned int
137296047Soshogboruntest_cmds(cap_channel_t *capgrp)
138296047Soshogbo{
139296047Soshogbo	char bufs[1024], bufc[1024];
140296047Soshogbo	unsigned int result;
141296047Soshogbo	struct group *grps, *grpc;
142296047Soshogbo	struct group sts, stc;
143296047Soshogbo
144296047Soshogbo	result = 0;
145296047Soshogbo
146296047Soshogbo	(void)setgrent();
147296047Soshogbo	if (cap_setgrent(capgrp) == 1)
148296047Soshogbo		result |= SETGRENT;
149296047Soshogbo
150296047Soshogbo	grps = getgrent();
151296047Soshogbo	grpc = cap_getgrent(capgrp);
152296047Soshogbo	if (group_compare(grps, grpc)) {
153296047Soshogbo		result |= GETGRENT0;
154296047Soshogbo		grps = getgrent();
155296047Soshogbo		grpc = cap_getgrent(capgrp);
156296047Soshogbo		if (group_compare(grps, grpc))
157296047Soshogbo			result |= GETGRENT1;
158296047Soshogbo	}
159296047Soshogbo
160296047Soshogbo	getgrent_r(&sts, bufs, sizeof(bufs), &grps);
161296047Soshogbo	cap_getgrent_r(capgrp, &stc, bufc, sizeof(bufc), &grpc);
162296047Soshogbo	if (group_compare(grps, grpc)) {
163296047Soshogbo		result |= GETGRENT_R0;
164296047Soshogbo		getgrent_r(&sts, bufs, sizeof(bufs), &grps);
165296047Soshogbo		cap_getgrent_r(capgrp, &stc, bufc, sizeof(bufc), &grpc);
166296047Soshogbo		if (group_compare(grps, grpc))
167296047Soshogbo			result |= GETGRENT_R1;
168296047Soshogbo	}
169296047Soshogbo
170296047Soshogbo	(void)setgrent();
171296047Soshogbo	if (cap_setgrent(capgrp) == 1)
172296047Soshogbo		result |= SETGRENT;
173296047Soshogbo
174296047Soshogbo	getgrent_r(&sts, bufs, sizeof(bufs), &grps);
175296047Soshogbo	cap_getgrent_r(capgrp, &stc, bufc, sizeof(bufc), &grpc);
176296047Soshogbo	if (group_compare(grps, grpc))
177296047Soshogbo		result |= GETGRENT_R2;
178296047Soshogbo
179296047Soshogbo	grps = getgrent();
180296047Soshogbo	grpc = cap_getgrent(capgrp);
181296047Soshogbo	if (group_compare(grps, grpc))
182296047Soshogbo		result |= GETGRENT2;
183296047Soshogbo
184296047Soshogbo	grps = getgrnam("wheel");
185296047Soshogbo	grpc = cap_getgrnam(capgrp, "wheel");
186296047Soshogbo	if (group_compare(grps, grpc)) {
187296047Soshogbo		grps = getgrnam("operator");
188296047Soshogbo		grpc = cap_getgrnam(capgrp, "operator");
189296047Soshogbo		if (group_compare(grps, grpc))
190296047Soshogbo			result |= GETGRNAM;
191296047Soshogbo	}
192296047Soshogbo
193296047Soshogbo	getgrnam_r("wheel", &sts, bufs, sizeof(bufs), &grps);
194296047Soshogbo	cap_getgrnam_r(capgrp, "wheel", &stc, bufc, sizeof(bufc), &grpc);
195296047Soshogbo	if (group_compare(grps, grpc)) {
196296047Soshogbo		getgrnam_r("operator", &sts, bufs, sizeof(bufs), &grps);
197296047Soshogbo		cap_getgrnam_r(capgrp, "operator", &stc, bufc, sizeof(bufc),
198296047Soshogbo		    &grpc);
199296047Soshogbo		if (group_compare(grps, grpc))
200296047Soshogbo			result |= GETGRNAM_R;
201296047Soshogbo	}
202296047Soshogbo
203296047Soshogbo	grps = getgrgid(GID_WHEEL);
204296047Soshogbo	grpc = cap_getgrgid(capgrp, GID_WHEEL);
205296047Soshogbo	if (group_compare(grps, grpc)) {
206296047Soshogbo		grps = getgrgid(GID_OPERATOR);
207296047Soshogbo		grpc = cap_getgrgid(capgrp, GID_OPERATOR);
208296047Soshogbo		if (group_compare(grps, grpc))
209296047Soshogbo			result |= GETGRGID;
210296047Soshogbo	}
211296047Soshogbo
212296047Soshogbo	getgrgid_r(GID_WHEEL, &sts, bufs, sizeof(bufs), &grps);
213296047Soshogbo	cap_getgrgid_r(capgrp, GID_WHEEL, &stc, bufc, sizeof(bufc), &grpc);
214296047Soshogbo	if (group_compare(grps, grpc)) {
215296047Soshogbo		getgrgid_r(GID_OPERATOR, &sts, bufs, sizeof(bufs), &grps);
216296047Soshogbo		cap_getgrgid_r(capgrp, GID_OPERATOR, &stc, bufc, sizeof(bufc),
217296047Soshogbo		    &grpc);
218296047Soshogbo		if (group_compare(grps, grpc))
219296047Soshogbo			result |= GETGRGID_R;
220296047Soshogbo	}
221296047Soshogbo
222296047Soshogbo	return (result);
223296047Soshogbo}
224296047Soshogbo
225296047Soshogbostatic void
226296047Soshogbotest_cmds(cap_channel_t *origcapgrp)
227296047Soshogbo{
228296047Soshogbo	cap_channel_t *capgrp;
229296047Soshogbo	const char *cmds[7], *fields[4], *names[5];
230296047Soshogbo	gid_t gids[5];
231296047Soshogbo
232296047Soshogbo	fields[0] = "gr_name";
233296047Soshogbo	fields[1] = "gr_passwd";
234296047Soshogbo	fields[2] = "gr_gid";
235296047Soshogbo	fields[3] = "gr_mem";
236296047Soshogbo
237296047Soshogbo	names[0] = "wheel";
238296047Soshogbo	names[1] = "daemon";
239296047Soshogbo	names[2] = "kmem";
240296047Soshogbo	names[3] = "sys";
241296047Soshogbo	names[4] = "operator";
242296047Soshogbo
243296047Soshogbo	gids[0] = 0;
244296047Soshogbo	gids[1] = 1;
245296047Soshogbo	gids[2] = 2;
246296047Soshogbo	gids[3] = 3;
247296047Soshogbo	gids[4] = 5;
248296047Soshogbo
249296047Soshogbo	/*
250296047Soshogbo	 * Allow:
251296047Soshogbo	 * cmds: setgrent, getgrent, getgrent_r, getgrnam, getgrnam_r,
252296047Soshogbo	 *       getgrgid, getgrgid_r
253296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
254296047Soshogbo	 * groups:
255296047Soshogbo	 *     names: wheel, daemon, kmem, sys, operator
256296047Soshogbo	 *     gids:
257296047Soshogbo	 */
258296047Soshogbo	capgrp = cap_clone(origcapgrp);
259296047Soshogbo	CHECK(capgrp != NULL);
260296047Soshogbo
261296047Soshogbo	cmds[0] = "setgrent";
262296047Soshogbo	cmds[1] = "getgrent";
263296047Soshogbo	cmds[2] = "getgrent_r";
264296047Soshogbo	cmds[3] = "getgrnam";
265296047Soshogbo	cmds[4] = "getgrnam_r";
266296047Soshogbo	cmds[5] = "getgrgid";
267296047Soshogbo	cmds[6] = "getgrgid_r";
268296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == 0);
269296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == 0);
270296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 5, NULL, 0) == 0);
271296047Soshogbo
272296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT | GETGRENT_R |
273296047Soshogbo	    GETGRNAM | GETGRNAM_R | GETGRGID | GETGRGID_R));
274296047Soshogbo
275296047Soshogbo	cap_close(capgrp);
276296047Soshogbo
277296047Soshogbo	/*
278296047Soshogbo	 * Allow:
279296047Soshogbo	 * cmds: setgrent, getgrent, getgrent_r, getgrnam, getgrnam_r,
280296047Soshogbo	 *       getgrgid, getgrgid_r
281296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
282296047Soshogbo	 * groups:
283296047Soshogbo	 *     names:
284296047Soshogbo	 *     gids: 0, 1, 2, 3, 5
285296047Soshogbo	 */
286296047Soshogbo	capgrp = cap_clone(origcapgrp);
287296047Soshogbo	CHECK(capgrp != NULL);
288296047Soshogbo
289296047Soshogbo	cmds[0] = "setgrent";
290296047Soshogbo	cmds[1] = "getgrent";
291296047Soshogbo	cmds[2] = "getgrent_r";
292296047Soshogbo	cmds[3] = "getgrnam";
293296047Soshogbo	cmds[4] = "getgrnam_r";
294296047Soshogbo	cmds[5] = "getgrgid";
295296047Soshogbo	cmds[6] = "getgrgid_r";
296296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == 0);
297296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == 0);
298296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 5) == 0);
299296047Soshogbo
300296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT | GETGRENT_R |
301296047Soshogbo	    GETGRNAM | GETGRNAM_R | GETGRGID | GETGRGID_R));
302296047Soshogbo
303296047Soshogbo	cap_close(capgrp);
304296047Soshogbo
305296047Soshogbo	/*
306296047Soshogbo	 * Allow:
307296047Soshogbo	 * cmds: getgrent, getgrent_r, getgrnam, getgrnam_r,
308296047Soshogbo	 *       getgrgid, getgrgid_r
309296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
310296047Soshogbo	 * groups:
311296047Soshogbo	 *     names: wheel, daemon, kmem, sys, operator
312296047Soshogbo	 *     gids:
313296047Soshogbo	 * Disallow:
314296047Soshogbo	 * cmds: setgrent
315296047Soshogbo	 * fields:
316296047Soshogbo	 * groups:
317296047Soshogbo	 */
318296047Soshogbo	capgrp = cap_clone(origcapgrp);
319296047Soshogbo	CHECK(capgrp != NULL);
320296047Soshogbo
321296047Soshogbo	cmds[0] = "getgrent";
322296047Soshogbo	cmds[1] = "getgrent_r";
323296047Soshogbo	cmds[2] = "getgrnam";
324296047Soshogbo	cmds[3] = "getgrnam_r";
325296047Soshogbo	cmds[4] = "getgrgid";
326296047Soshogbo	cmds[5] = "getgrgid_r";
327296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
328296047Soshogbo	cmds[0] = "setgrent";
329296047Soshogbo	cmds[1] = "getgrent";
330296047Soshogbo	cmds[2] = "getgrent_r";
331296047Soshogbo	cmds[3] = "getgrnam";
332296047Soshogbo	cmds[4] = "getgrnam_r";
333296047Soshogbo	cmds[5] = "getgrgid";
334296047Soshogbo	cmds[6] = "getgrgid_r";
335296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
336296047Soshogbo	cmds[0] = "setgrent";
337296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
338296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 5, NULL, 0) == 0);
339296047Soshogbo
340296047Soshogbo	CHECK(runtest_cmds(capgrp) == (GETGRENT0 | GETGRENT1 | GETGRENT_R0 |
341296047Soshogbo	    GETGRENT_R1 | GETGRNAM | GETGRNAM_R | GETGRGID | GETGRGID_R));
342296047Soshogbo
343296047Soshogbo	cap_close(capgrp);
344296047Soshogbo
345296047Soshogbo	/*
346296047Soshogbo	 * Allow:
347296047Soshogbo	 * cmds: getgrent, getgrent_r, getgrnam, getgrnam_r,
348296047Soshogbo	 *       getgrgid, getgrgid_r
349296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
350296047Soshogbo	 * groups:
351296047Soshogbo	 *     names:
352296047Soshogbo	 *     gids: 0, 1, 2, 3, 5
353296047Soshogbo	 * Disallow:
354296047Soshogbo	 * cmds: setgrent
355296047Soshogbo	 * fields:
356296047Soshogbo	 * groups:
357296047Soshogbo	 */
358296047Soshogbo	capgrp = cap_clone(origcapgrp);
359296047Soshogbo	CHECK(capgrp != NULL);
360296047Soshogbo
361296047Soshogbo	cmds[0] = "getgrent";
362296047Soshogbo	cmds[1] = "getgrent_r";
363296047Soshogbo	cmds[2] = "getgrnam";
364296047Soshogbo	cmds[3] = "getgrnam_r";
365296047Soshogbo	cmds[4] = "getgrgid";
366296047Soshogbo	cmds[5] = "getgrgid_r";
367296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
368296047Soshogbo	cmds[0] = "setgrent";
369296047Soshogbo	cmds[1] = "getgrent";
370296047Soshogbo	cmds[2] = "getgrent_r";
371296047Soshogbo	cmds[3] = "getgrnam";
372296047Soshogbo	cmds[4] = "getgrnam_r";
373296047Soshogbo	cmds[5] = "getgrgid";
374296047Soshogbo	cmds[6] = "getgrgid_r";
375296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
376296047Soshogbo	cmds[0] = "setgrent";
377296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
378296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 5) == 0);
379296047Soshogbo
380296047Soshogbo	CHECK(runtest_cmds(capgrp) == (GETGRENT0 | GETGRENT1 | GETGRENT_R0 |
381296047Soshogbo	    GETGRENT_R1 | GETGRNAM | GETGRNAM_R | GETGRGID | GETGRGID_R));
382296047Soshogbo
383296047Soshogbo	cap_close(capgrp);
384296047Soshogbo
385296047Soshogbo	/*
386296047Soshogbo	 * Allow:
387296047Soshogbo	 * cmds: setgrent, getgrent_r, getgrnam, getgrnam_r,
388296047Soshogbo	 *       getgrgid, getgrgid_r
389296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
390296047Soshogbo	 * groups:
391296047Soshogbo	 *     names: wheel, daemon, kmem, sys, operator
392296047Soshogbo	 *     gids:
393296047Soshogbo	 * Disallow:
394296047Soshogbo	 * cmds: getgrent
395296047Soshogbo	 * fields:
396296047Soshogbo	 * groups:
397296047Soshogbo	 */
398296047Soshogbo	capgrp = cap_clone(origcapgrp);
399296047Soshogbo	CHECK(capgrp != NULL);
400296047Soshogbo
401296047Soshogbo	cmds[0] = "setgrent";
402296047Soshogbo	cmds[1] = "getgrent_r";
403296047Soshogbo	cmds[2] = "getgrnam";
404296047Soshogbo	cmds[3] = "getgrnam_r";
405296047Soshogbo	cmds[4] = "getgrgid";
406296047Soshogbo	cmds[5] = "getgrgid_r";
407296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
408296047Soshogbo	cmds[0] = "setgrent";
409296047Soshogbo	cmds[1] = "getgrent";
410296047Soshogbo	cmds[2] = "getgrent_r";
411296047Soshogbo	cmds[3] = "getgrnam";
412296047Soshogbo	cmds[4] = "getgrnam_r";
413296047Soshogbo	cmds[5] = "getgrgid";
414296047Soshogbo	cmds[6] = "getgrgid_r";
415296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
416296047Soshogbo	cmds[0] = "getgrent";
417296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
418296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == 0);
419296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 5, NULL, 0) == 0);
420296047Soshogbo
421296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT_R2 |
422296047Soshogbo	    GETGRNAM | GETGRNAM_R | GETGRGID | GETGRGID_R));
423296047Soshogbo
424296047Soshogbo	cap_close(capgrp);
425296047Soshogbo
426296047Soshogbo	/*
427296047Soshogbo	 * Allow:
428296047Soshogbo	 * cmds: setgrent, getgrent_r, getgrnam, getgrnam_r,
429296047Soshogbo	 *       getgrgid, getgrgid_r
430296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
431296047Soshogbo	 * groups:
432296047Soshogbo	 *     names:
433296047Soshogbo	 *     gids: 0, 1, 2, 3, 5
434296047Soshogbo	 * Disallow:
435296047Soshogbo	 * cmds: getgrent
436296047Soshogbo	 * fields:
437296047Soshogbo	 * groups:
438296047Soshogbo	 */
439296047Soshogbo	capgrp = cap_clone(origcapgrp);
440296047Soshogbo	CHECK(capgrp != NULL);
441296047Soshogbo
442296047Soshogbo	cmds[0] = "setgrent";
443296047Soshogbo	cmds[1] = "getgrent_r";
444296047Soshogbo	cmds[2] = "getgrnam";
445296047Soshogbo	cmds[3] = "getgrnam_r";
446296047Soshogbo	cmds[4] = "getgrgid";
447296047Soshogbo	cmds[5] = "getgrgid_r";
448296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
449296047Soshogbo	cmds[0] = "setgrent";
450296047Soshogbo	cmds[1] = "getgrent";
451296047Soshogbo	cmds[2] = "getgrent_r";
452296047Soshogbo	cmds[3] = "getgrnam";
453296047Soshogbo	cmds[4] = "getgrnam_r";
454296047Soshogbo	cmds[5] = "getgrgid";
455296047Soshogbo	cmds[6] = "getgrgid_r";
456296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
457296047Soshogbo	cmds[0] = "getgrent";
458296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
459296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == 0);
460296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 5) == 0);
461296047Soshogbo
462296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT_R2 |
463296047Soshogbo	    GETGRNAM | GETGRNAM_R | GETGRGID | GETGRGID_R));
464296047Soshogbo
465296047Soshogbo	cap_close(capgrp);
466296047Soshogbo
467296047Soshogbo	/*
468296047Soshogbo	 * Allow:
469296047Soshogbo	 * cmds: setgrent, getgrent, getgrnam, getgrnam_r,
470296047Soshogbo	 *       getgrgid, getgrgid_r
471296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
472296047Soshogbo	 * groups:
473296047Soshogbo	 *     names: wheel, daemon, kmem, sys, operator
474296047Soshogbo	 *     gids:
475296047Soshogbo	 * Disallow:
476296047Soshogbo	 * cmds: getgrent_r
477296047Soshogbo	 * fields:
478296047Soshogbo	 * groups:
479296047Soshogbo	 */
480296047Soshogbo	capgrp = cap_clone(origcapgrp);
481296047Soshogbo	CHECK(capgrp != NULL);
482296047Soshogbo
483296047Soshogbo	cmds[0] = "setgrent";
484296047Soshogbo	cmds[1] = "getgrent";
485296047Soshogbo	cmds[2] = "getgrnam";
486296047Soshogbo	cmds[3] = "getgrnam_r";
487296047Soshogbo	cmds[4] = "getgrgid";
488296047Soshogbo	cmds[5] = "getgrgid_r";
489296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
490296047Soshogbo	cmds[0] = "setgrent";
491296047Soshogbo	cmds[1] = "getgrent";
492296047Soshogbo	cmds[2] = "getgrent_r";
493296047Soshogbo	cmds[3] = "getgrnam";
494296047Soshogbo	cmds[4] = "getgrnam_r";
495296047Soshogbo	cmds[5] = "getgrgid";
496296047Soshogbo	cmds[6] = "getgrgid_r";
497296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
498296047Soshogbo	cmds[0] = "getgrent_r";
499296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
500296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 5, NULL, 0) == 0);
501296047Soshogbo
502296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT0 | GETGRENT1 |
503296047Soshogbo	    GETGRNAM | GETGRNAM_R | GETGRGID | GETGRGID_R));
504296047Soshogbo
505296047Soshogbo	cap_close(capgrp);
506296047Soshogbo
507296047Soshogbo	/*
508296047Soshogbo	 * Allow:
509296047Soshogbo	 * cmds: setgrent, getgrent, getgrnam, getgrnam_r,
510296047Soshogbo	 *       getgrgid, getgrgid_r
511296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
512296047Soshogbo	 * groups:
513296047Soshogbo	 *     names:
514296047Soshogbo	 *     gids: 0, 1, 2, 3, 5
515296047Soshogbo	 * Disallow:
516296047Soshogbo	 * cmds: getgrent_r
517296047Soshogbo	 * fields:
518296047Soshogbo	 * groups:
519296047Soshogbo	 */
520296047Soshogbo	capgrp = cap_clone(origcapgrp);
521296047Soshogbo	CHECK(capgrp != NULL);
522296047Soshogbo
523296047Soshogbo	cmds[0] = "setgrent";
524296047Soshogbo	cmds[1] = "getgrent";
525296047Soshogbo	cmds[2] = "getgrnam";
526296047Soshogbo	cmds[3] = "getgrnam_r";
527296047Soshogbo	cmds[4] = "getgrgid";
528296047Soshogbo	cmds[5] = "getgrgid_r";
529296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
530296047Soshogbo	cmds[0] = "setgrent";
531296047Soshogbo	cmds[1] = "getgrent";
532296047Soshogbo	cmds[2] = "getgrent_r";
533296047Soshogbo	cmds[3] = "getgrnam";
534296047Soshogbo	cmds[4] = "getgrnam_r";
535296047Soshogbo	cmds[5] = "getgrgid";
536296047Soshogbo	cmds[6] = "getgrgid_r";
537296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
538296047Soshogbo	cmds[0] = "getgrent_r";
539296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
540296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 5) == 0);
541296047Soshogbo
542296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT0 | GETGRENT1 |
543296047Soshogbo	    GETGRNAM | GETGRNAM_R | GETGRGID | GETGRGID_R));
544296047Soshogbo
545296047Soshogbo	cap_close(capgrp);
546296047Soshogbo
547296047Soshogbo	/*
548296047Soshogbo	 * Allow:
549296047Soshogbo	 * cmds: setgrent, getgrent, getgrent_r, getgrnam_r,
550296047Soshogbo	 *       getgrgid, getgrgid_r
551296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
552296047Soshogbo	 * groups:
553296047Soshogbo	 *     names: wheel, daemon, kmem, sys, operator
554296047Soshogbo	 *     gids:
555296047Soshogbo	 * Disallow:
556296047Soshogbo	 * cmds: getgrnam
557296047Soshogbo	 * fields:
558296047Soshogbo	 * groups:
559296047Soshogbo	 */
560296047Soshogbo	capgrp = cap_clone(origcapgrp);
561296047Soshogbo	CHECK(capgrp != NULL);
562296047Soshogbo
563296047Soshogbo	cmds[0] = "setgrent";
564296047Soshogbo	cmds[1] = "getgrent";
565296047Soshogbo	cmds[2] = "getgrent_r";
566296047Soshogbo	cmds[3] = "getgrnam_r";
567296047Soshogbo	cmds[4] = "getgrgid";
568296047Soshogbo	cmds[5] = "getgrgid_r";
569296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
570296047Soshogbo	cmds[0] = "setgrent";
571296047Soshogbo	cmds[1] = "getgrent";
572296047Soshogbo	cmds[2] = "getgrent_r";
573296047Soshogbo	cmds[3] = "getgrnam";
574296047Soshogbo	cmds[4] = "getgrnam_r";
575296047Soshogbo	cmds[5] = "getgrgid";
576296047Soshogbo	cmds[6] = "getgrgid_r";
577296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
578296047Soshogbo	cmds[0] = "getgrnam";
579296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
580296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == 0);
581296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 5, NULL, 0) == 0);
582296047Soshogbo
583296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT | GETGRENT_R |
584296047Soshogbo	    GETGRNAM_R | GETGRGID | GETGRGID_R));
585296047Soshogbo
586296047Soshogbo	cap_close(capgrp);
587296047Soshogbo
588296047Soshogbo	/*
589296047Soshogbo	 * Allow:
590296047Soshogbo	 * cmds: setgrent, getgrent, getgrent_r, getgrnam_r,
591296047Soshogbo	 *       getgrgid, getgrgid_r
592296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
593296047Soshogbo	 * groups:
594296047Soshogbo	 *     names:
595296047Soshogbo	 *     gids: 0, 1, 2, 3, 5
596296047Soshogbo	 * Disallow:
597296047Soshogbo	 * cmds: getgrnam
598296047Soshogbo	 * fields:
599296047Soshogbo	 * groups:
600296047Soshogbo	 */
601296047Soshogbo	capgrp = cap_clone(origcapgrp);
602296047Soshogbo	CHECK(capgrp != NULL);
603296047Soshogbo
604296047Soshogbo	cmds[0] = "setgrent";
605296047Soshogbo	cmds[1] = "getgrent";
606296047Soshogbo	cmds[2] = "getgrent_r";
607296047Soshogbo	cmds[3] = "getgrnam_r";
608296047Soshogbo	cmds[4] = "getgrgid";
609296047Soshogbo	cmds[5] = "getgrgid_r";
610296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
611296047Soshogbo	cmds[0] = "setgrent";
612296047Soshogbo	cmds[1] = "getgrent";
613296047Soshogbo	cmds[2] = "getgrent_r";
614296047Soshogbo	cmds[3] = "getgrnam";
615296047Soshogbo	cmds[4] = "getgrnam_r";
616296047Soshogbo	cmds[5] = "getgrgid";
617296047Soshogbo	cmds[6] = "getgrgid_r";
618296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
619296047Soshogbo	cmds[0] = "getgrnam";
620296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
621296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == 0);
622296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 5) == 0);
623296047Soshogbo
624296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT | GETGRENT_R |
625296047Soshogbo	    GETGRNAM_R | GETGRGID | GETGRGID_R));
626296047Soshogbo
627296047Soshogbo	cap_close(capgrp);
628296047Soshogbo
629296047Soshogbo	/*
630296047Soshogbo	 * Allow:
631296047Soshogbo	 * cmds: setgrent, getgrent, getgrent_r, getgrnam,
632296047Soshogbo	 *       getgrgid, getgrgid_r
633296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
634296047Soshogbo	 * groups:
635296047Soshogbo	 *     names: wheel, daemon, kmem, sys, operator
636296047Soshogbo	 *     gids:
637296047Soshogbo	 * Disallow:
638296047Soshogbo	 * cmds: getgrnam_r
639296047Soshogbo	 * fields:
640296047Soshogbo	 * groups:
641296047Soshogbo	 */
642296047Soshogbo	capgrp = cap_clone(origcapgrp);
643296047Soshogbo	CHECK(capgrp != NULL);
644296047Soshogbo
645296047Soshogbo	cmds[0] = "setgrent";
646296047Soshogbo	cmds[1] = "getgrent";
647296047Soshogbo	cmds[2] = "getgrent_r";
648296047Soshogbo	cmds[3] = "getgrnam";
649296047Soshogbo	cmds[4] = "getgrgid";
650296047Soshogbo	cmds[5] = "getgrgid_r";
651296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
652296047Soshogbo	cmds[0] = "setgrent";
653296047Soshogbo	cmds[1] = "getgrent";
654296047Soshogbo	cmds[2] = "getgrent_r";
655296047Soshogbo	cmds[3] = "getgrnam";
656296047Soshogbo	cmds[4] = "getgrnam_r";
657296047Soshogbo	cmds[5] = "getgrgid";
658296047Soshogbo	cmds[6] = "getgrgid_r";
659296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
660296047Soshogbo	cmds[0] = "getgrnam_r";
661296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
662296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 5, NULL, 0) == 0);
663296047Soshogbo
664296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT | GETGRENT_R |
665296047Soshogbo	    GETGRNAM | GETGRGID | GETGRGID_R));
666296047Soshogbo
667296047Soshogbo	cap_close(capgrp);
668296047Soshogbo
669296047Soshogbo	/*
670296047Soshogbo	 * Allow:
671296047Soshogbo	 * cmds: setgrent, getgrent, getgrent_r, getgrnam,
672296047Soshogbo	 *       getgrgid, getgrgid_r
673296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
674296047Soshogbo	 * groups:
675296047Soshogbo	 *     names:
676296047Soshogbo	 *     gids: 0, 1, 2, 3, 5
677296047Soshogbo	 * Disallow:
678296047Soshogbo	 * cmds: getgrnam_r
679296047Soshogbo	 * fields:
680296047Soshogbo	 * groups:
681296047Soshogbo	 */
682296047Soshogbo	capgrp = cap_clone(origcapgrp);
683296047Soshogbo	CHECK(capgrp != NULL);
684296047Soshogbo
685296047Soshogbo	cmds[0] = "setgrent";
686296047Soshogbo	cmds[1] = "getgrent";
687296047Soshogbo	cmds[2] = "getgrent_r";
688296047Soshogbo	cmds[3] = "getgrnam";
689296047Soshogbo	cmds[4] = "getgrgid";
690296047Soshogbo	cmds[5] = "getgrgid_r";
691296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
692296047Soshogbo	cmds[0] = "setgrent";
693296047Soshogbo	cmds[1] = "getgrent";
694296047Soshogbo	cmds[2] = "getgrent_r";
695296047Soshogbo	cmds[3] = "getgrnam";
696296047Soshogbo	cmds[4] = "getgrnam_r";
697296047Soshogbo	cmds[5] = "getgrgid";
698296047Soshogbo	cmds[6] = "getgrgid_r";
699296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
700296047Soshogbo	cmds[0] = "getgrnam_r";
701296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
702296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 5) == 0);
703296047Soshogbo
704296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT | GETGRENT_R |
705296047Soshogbo	    GETGRNAM | GETGRGID | GETGRGID_R));
706296047Soshogbo
707296047Soshogbo	cap_close(capgrp);
708296047Soshogbo
709296047Soshogbo	/*
710296047Soshogbo	 * Allow:
711296047Soshogbo	 * cmds: setgrent, getgrent, getgrent_r, getgrnam, getgrnam_r,
712296047Soshogbo	 *       getgrgid_r
713296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
714296047Soshogbo	 * groups:
715296047Soshogbo	 *     names: wheel, daemon, kmem, sys, operator
716296047Soshogbo	 *     gids:
717296047Soshogbo	 * Disallow:
718296047Soshogbo	 * cmds: getgrgid
719296047Soshogbo	 * fields:
720296047Soshogbo	 * groups:
721296047Soshogbo	 */
722296047Soshogbo	capgrp = cap_clone(origcapgrp);
723296047Soshogbo	CHECK(capgrp != NULL);
724296047Soshogbo
725296047Soshogbo	cmds[0] = "setgrent";
726296047Soshogbo	cmds[1] = "getgrent";
727296047Soshogbo	cmds[2] = "getgrent_r";
728296047Soshogbo	cmds[3] = "getgrnam";
729296047Soshogbo	cmds[4] = "getgrnam_r";
730296047Soshogbo	cmds[5] = "getgrgid_r";
731296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
732296047Soshogbo	cmds[0] = "setgrent";
733296047Soshogbo	cmds[1] = "getgrent";
734296047Soshogbo	cmds[2] = "getgrent_r";
735296047Soshogbo	cmds[3] = "getgrnam";
736296047Soshogbo	cmds[4] = "getgrnam_r";
737296047Soshogbo	cmds[5] = "getgrgid";
738296047Soshogbo	cmds[6] = "getgrgid_r";
739296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
740296047Soshogbo	cmds[0] = "getgrgid";
741296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
742296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == 0);
743296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 5, NULL, 0) == 0);
744296047Soshogbo
745296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT | GETGRENT_R |
746296047Soshogbo	    GETGRNAM | GETGRNAM_R | GETGRGID_R));
747296047Soshogbo
748296047Soshogbo	cap_close(capgrp);
749296047Soshogbo
750296047Soshogbo	/*
751296047Soshogbo	 * Allow:
752296047Soshogbo	 * cmds: setgrent, getgrent, getgrent_r, getgrnam, getgrnam_r,
753296047Soshogbo	 *       getgrgid_r
754296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
755296047Soshogbo	 * groups:
756296047Soshogbo	 *     names:
757296047Soshogbo	 *     gids: 0, 1, 2, 3, 5
758296047Soshogbo	 * Disallow:
759296047Soshogbo	 * cmds: getgrgid
760296047Soshogbo	 * fields:
761296047Soshogbo	 * groups:
762296047Soshogbo	 */
763296047Soshogbo	capgrp = cap_clone(origcapgrp);
764296047Soshogbo	CHECK(capgrp != NULL);
765296047Soshogbo
766296047Soshogbo	cmds[0] = "setgrent";
767296047Soshogbo	cmds[1] = "getgrent";
768296047Soshogbo	cmds[2] = "getgrent_r";
769296047Soshogbo	cmds[3] = "getgrnam";
770296047Soshogbo	cmds[4] = "getgrnam_r";
771296047Soshogbo	cmds[5] = "getgrgid_r";
772296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
773296047Soshogbo	cmds[0] = "setgrent";
774296047Soshogbo	cmds[1] = "getgrent";
775296047Soshogbo	cmds[2] = "getgrent_r";
776296047Soshogbo	cmds[3] = "getgrnam";
777296047Soshogbo	cmds[4] = "getgrnam_r";
778296047Soshogbo	cmds[5] = "getgrgid";
779296047Soshogbo	cmds[6] = "getgrgid_r";
780296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
781296047Soshogbo	cmds[0] = "getgrgid";
782296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
783296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == 0);
784296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 5) == 0);
785296047Soshogbo
786296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT | GETGRENT_R |
787296047Soshogbo	    GETGRNAM | GETGRNAM_R | GETGRGID_R));
788296047Soshogbo
789296047Soshogbo	cap_close(capgrp);
790296047Soshogbo
791296047Soshogbo	/*
792296047Soshogbo	 * Allow:
793296047Soshogbo	 * cmds: setgrent, getgrent, getgrent_r, getgrnam, getgrnam_r,
794296047Soshogbo	 *       getgrgid
795296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
796296047Soshogbo	 * groups:
797296047Soshogbo	 *     names: wheel, daemon, kmem, sys, operator
798296047Soshogbo	 *     gids:
799296047Soshogbo	 * Disallow:
800296047Soshogbo	 * cmds: getgrgid_r
801296047Soshogbo	 * fields:
802296047Soshogbo	 * groups:
803296047Soshogbo	 */
804296047Soshogbo	capgrp = cap_clone(origcapgrp);
805296047Soshogbo	CHECK(capgrp != NULL);
806296047Soshogbo
807296047Soshogbo	cmds[0] = "setgrent";
808296047Soshogbo	cmds[1] = "getgrent";
809296047Soshogbo	cmds[2] = "getgrent_r";
810296047Soshogbo	cmds[3] = "getgrnam";
811296047Soshogbo	cmds[4] = "getgrnam_r";
812296047Soshogbo	cmds[5] = "getgrgid";
813296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
814296047Soshogbo	cmds[0] = "setgrent";
815296047Soshogbo	cmds[1] = "getgrent";
816296047Soshogbo	cmds[2] = "getgrent_r";
817296047Soshogbo	cmds[3] = "getgrnam";
818296047Soshogbo	cmds[4] = "getgrnam_r";
819296047Soshogbo	cmds[5] = "getgrgid";
820296047Soshogbo	cmds[6] = "getgrgid_r";
821296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
822296047Soshogbo	cmds[0] = "getgrgid_r";
823296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
824296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 5, NULL, 0) == 0);
825296047Soshogbo
826296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT | GETGRENT_R |
827296047Soshogbo	    GETGRNAM | GETGRNAM_R | GETGRGID));
828296047Soshogbo
829296047Soshogbo	cap_close(capgrp);
830296047Soshogbo
831296047Soshogbo	/*
832296047Soshogbo	 * Allow:
833296047Soshogbo	 * cmds: setgrent, getgrent, getgrent_r, getgrnam, getgrnam_r,
834296047Soshogbo	 *       getgrgid
835296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
836296047Soshogbo	 * groups:
837296047Soshogbo	 *     names:
838296047Soshogbo	 *     gids: 0, 1, 2, 3, 5
839296047Soshogbo	 * Disallow:
840296047Soshogbo	 * cmds: getgrgid_r
841296047Soshogbo	 * fields:
842296047Soshogbo	 * groups:
843296047Soshogbo	 */
844296047Soshogbo	capgrp = cap_clone(origcapgrp);
845296047Soshogbo	CHECK(capgrp != NULL);
846296047Soshogbo
847296047Soshogbo	cmds[0] = "setgrent";
848296047Soshogbo	cmds[1] = "getgrent";
849296047Soshogbo	cmds[2] = "getgrent_r";
850296047Soshogbo	cmds[3] = "getgrnam";
851296047Soshogbo	cmds[4] = "getgrnam_r";
852296047Soshogbo	cmds[5] = "getgrgid";
853296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 6) == 0);
854296047Soshogbo	cmds[0] = "setgrent";
855296047Soshogbo	cmds[1] = "getgrent";
856296047Soshogbo	cmds[2] = "getgrent_r";
857296047Soshogbo	cmds[3] = "getgrnam";
858296047Soshogbo	cmds[4] = "getgrnam_r";
859296047Soshogbo	cmds[5] = "getgrgid";
860296047Soshogbo	cmds[6] = "getgrgid_r";
861296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 7) == -1 && errno == ENOTCAPABLE);
862296047Soshogbo	cmds[0] = "getgrgid_r";
863296047Soshogbo	CHECK(cap_grp_limit_cmds(capgrp, cmds, 1) == -1 && errno == ENOTCAPABLE);
864296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 5) == 0);
865296047Soshogbo
866296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT | GETGRENT_R |
867296047Soshogbo	    GETGRNAM | GETGRNAM_R | GETGRGID));
868296047Soshogbo
869296047Soshogbo	cap_close(capgrp);
870296047Soshogbo}
871296047Soshogbo
872296047Soshogbo#define	GR_NAME		0x01
873296047Soshogbo#define	GR_PASSWD	0x02
874296047Soshogbo#define	GR_GID		0x04
875296047Soshogbo#define	GR_MEM		0x08
876296047Soshogbo
877296047Soshogbostatic unsigned int
878296047Soshogbogroup_fields(const struct group *grp)
879296047Soshogbo{
880296047Soshogbo	unsigned int result;
881296047Soshogbo
882296047Soshogbo	result = 0;
883296047Soshogbo
884296047Soshogbo	if (grp->gr_name != NULL && grp->gr_name[0] != '\0')
885296047Soshogbo		result |= GR_NAME;
886296047Soshogbo
887296047Soshogbo	if (grp->gr_passwd != NULL && grp->gr_passwd[0] != '\0')
888296047Soshogbo		result |= GR_PASSWD;
889296047Soshogbo
890296047Soshogbo	if (grp->gr_gid != (gid_t)-1)
891296047Soshogbo		result |= GR_GID;
892296047Soshogbo
893296047Soshogbo	if (grp->gr_mem != NULL && grp->gr_mem[0] != NULL)
894296047Soshogbo		result |= GR_MEM;
895296047Soshogbo
896296047Soshogbo	return (result);
897296047Soshogbo}
898296047Soshogbo
899296047Soshogbostatic bool
900296047Soshogboruntest_fields(cap_channel_t *capgrp, unsigned int expected)
901296047Soshogbo{
902296047Soshogbo	char buf[1024];
903296047Soshogbo	struct group *grp;
904296047Soshogbo	struct group st;
905296047Soshogbo
906296047Soshogbo	(void)cap_setgrent(capgrp);
907296047Soshogbo	grp = cap_getgrent(capgrp);
908296047Soshogbo	if (group_fields(grp) != expected)
909296047Soshogbo		return (false);
910296047Soshogbo
911296047Soshogbo	(void)cap_setgrent(capgrp);
912296047Soshogbo	cap_getgrent_r(capgrp, &st, buf, sizeof(buf), &grp);
913296047Soshogbo	if (group_fields(grp) != expected)
914296047Soshogbo		return (false);
915296047Soshogbo
916296047Soshogbo	grp = cap_getgrnam(capgrp, "wheel");
917296047Soshogbo	if (group_fields(grp) != expected)
918296047Soshogbo		return (false);
919296047Soshogbo
920296047Soshogbo	cap_getgrnam_r(capgrp, "wheel", &st, buf, sizeof(buf), &grp);
921296047Soshogbo	if (group_fields(grp) != expected)
922296047Soshogbo		return (false);
923296047Soshogbo
924296047Soshogbo	grp = cap_getgrgid(capgrp, GID_WHEEL);
925296047Soshogbo	if (group_fields(grp) != expected)
926296047Soshogbo		return (false);
927296047Soshogbo
928296047Soshogbo	cap_getgrgid_r(capgrp, GID_WHEEL, &st, buf, sizeof(buf), &grp);
929296047Soshogbo	if (group_fields(grp) != expected)
930296047Soshogbo		return (false);
931296047Soshogbo
932296047Soshogbo	return (true);
933296047Soshogbo}
934296047Soshogbo
935296047Soshogbostatic void
936296047Soshogbotest_fields(cap_channel_t *origcapgrp)
937296047Soshogbo{
938296047Soshogbo	cap_channel_t *capgrp;
939296047Soshogbo	const char *fields[4];
940296047Soshogbo
941296047Soshogbo	/* No limits. */
942296047Soshogbo
943296047Soshogbo	CHECK(runtest_fields(origcapgrp, GR_NAME | GR_PASSWD | GR_GID | GR_MEM));
944296047Soshogbo
945296047Soshogbo	/*
946296047Soshogbo	 * Allow:
947296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid, gr_mem
948296047Soshogbo	 */
949296047Soshogbo	capgrp = cap_clone(origcapgrp);
950296047Soshogbo	CHECK(capgrp != NULL);
951296047Soshogbo
952296047Soshogbo	fields[0] = "gr_name";
953296047Soshogbo	fields[1] = "gr_passwd";
954296047Soshogbo	fields[2] = "gr_gid";
955296047Soshogbo	fields[3] = "gr_mem";
956296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == 0);
957296047Soshogbo
958296047Soshogbo	CHECK(runtest_fields(capgrp, GR_NAME | GR_PASSWD | GR_GID | GR_MEM));
959296047Soshogbo
960296047Soshogbo	cap_close(capgrp);
961296047Soshogbo
962296047Soshogbo	/*
963296047Soshogbo	 * Allow:
964296047Soshogbo	 * fields: gr_passwd, gr_gid, gr_mem
965296047Soshogbo	 */
966296047Soshogbo	capgrp = cap_clone(origcapgrp);
967296047Soshogbo	CHECK(capgrp != NULL);
968296047Soshogbo
969296047Soshogbo	fields[0] = "gr_passwd";
970296047Soshogbo	fields[1] = "gr_gid";
971296047Soshogbo	fields[2] = "gr_mem";
972296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 3) == 0);
973296047Soshogbo	fields[0] = "gr_name";
974296047Soshogbo	fields[1] = "gr_passwd";
975296047Soshogbo	fields[2] = "gr_gid";
976296047Soshogbo	fields[3] = "gr_mem";
977296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == -1 &&
978296047Soshogbo	    errno == ENOTCAPABLE);
979296047Soshogbo
980296047Soshogbo	CHECK(runtest_fields(capgrp, GR_PASSWD | GR_GID | GR_MEM));
981296047Soshogbo
982296047Soshogbo	cap_close(capgrp);
983296047Soshogbo
984296047Soshogbo	/*
985296047Soshogbo	 * Allow:
986296047Soshogbo	 * fields: gr_name, gr_gid, gr_mem
987296047Soshogbo	 */
988296047Soshogbo	capgrp = cap_clone(origcapgrp);
989296047Soshogbo	CHECK(capgrp != NULL);
990296047Soshogbo
991296047Soshogbo	fields[0] = "gr_name";
992296047Soshogbo	fields[1] = "gr_gid";
993296047Soshogbo	fields[2] = "gr_mem";
994296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 3) == 0);
995296047Soshogbo	fields[0] = "gr_name";
996296047Soshogbo	fields[1] = "gr_passwd";
997296047Soshogbo	fields[2] = "gr_gid";
998296047Soshogbo	fields[3] = "gr_mem";
999296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == -1 &&
1000296047Soshogbo	    errno == ENOTCAPABLE);
1001296047Soshogbo	fields[0] = "gr_passwd";
1002296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 1) == -1 &&
1003296047Soshogbo	    errno == ENOTCAPABLE);
1004296047Soshogbo
1005296047Soshogbo	CHECK(runtest_fields(capgrp, GR_NAME | GR_GID | GR_MEM));
1006296047Soshogbo
1007296047Soshogbo	cap_close(capgrp);
1008296047Soshogbo
1009296047Soshogbo	/*
1010296047Soshogbo	 * Allow:
1011296047Soshogbo	 * fields: gr_name, gr_passwd, gr_mem
1012296047Soshogbo	 */
1013296047Soshogbo	capgrp = cap_clone(origcapgrp);
1014296047Soshogbo	CHECK(capgrp != NULL);
1015296047Soshogbo
1016296047Soshogbo	fields[0] = "gr_name";
1017296047Soshogbo	fields[1] = "gr_passwd";
1018296047Soshogbo	fields[2] = "gr_mem";
1019296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 3) == 0);
1020296047Soshogbo	fields[0] = "gr_name";
1021296047Soshogbo	fields[1] = "gr_passwd";
1022296047Soshogbo	fields[2] = "gr_gid";
1023296047Soshogbo	fields[3] = "gr_mem";
1024296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == -1 &&
1025296047Soshogbo	    errno == ENOTCAPABLE);
1026296047Soshogbo	fields[0] = "gr_gid";
1027296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 1) == -1 &&
1028296047Soshogbo	    errno == ENOTCAPABLE);
1029296047Soshogbo
1030296047Soshogbo	CHECK(runtest_fields(capgrp, GR_NAME | GR_PASSWD | GR_MEM));
1031296047Soshogbo
1032296047Soshogbo	cap_close(capgrp);
1033296047Soshogbo
1034296047Soshogbo	/*
1035296047Soshogbo	 * Allow:
1036296047Soshogbo	 * fields: gr_name, gr_passwd, gr_gid
1037296047Soshogbo	 */
1038296047Soshogbo	capgrp = cap_clone(origcapgrp);
1039296047Soshogbo	CHECK(capgrp != NULL);
1040296047Soshogbo
1041296047Soshogbo	fields[0] = "gr_name";
1042296047Soshogbo	fields[1] = "gr_passwd";
1043296047Soshogbo	fields[2] = "gr_gid";
1044296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 3) == 0);
1045296047Soshogbo	fields[0] = "gr_name";
1046296047Soshogbo	fields[1] = "gr_passwd";
1047296047Soshogbo	fields[2] = "gr_gid";
1048296047Soshogbo	fields[3] = "gr_mem";
1049296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == -1 &&
1050296047Soshogbo	    errno == ENOTCAPABLE);
1051296047Soshogbo	fields[0] = "gr_mem";
1052296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 1) == -1 &&
1053296047Soshogbo	    errno == ENOTCAPABLE);
1054296047Soshogbo
1055296047Soshogbo	CHECK(runtest_fields(capgrp, GR_NAME | GR_PASSWD | GR_GID));
1056296047Soshogbo
1057296047Soshogbo	cap_close(capgrp);
1058296047Soshogbo
1059296047Soshogbo	/*
1060296047Soshogbo	 * Allow:
1061296047Soshogbo	 * fields: gr_name, gr_passwd
1062296047Soshogbo	 */
1063296047Soshogbo	capgrp = cap_clone(origcapgrp);
1064296047Soshogbo	CHECK(capgrp != NULL);
1065296047Soshogbo
1066296047Soshogbo	fields[0] = "gr_name";
1067296047Soshogbo	fields[1] = "gr_passwd";
1068296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 2) == 0);
1069296047Soshogbo	fields[0] = "gr_name";
1070296047Soshogbo	fields[1] = "gr_passwd";
1071296047Soshogbo	fields[2] = "gr_gid";
1072296047Soshogbo	fields[3] = "gr_mem";
1073296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == -1 &&
1074296047Soshogbo	    errno == ENOTCAPABLE);
1075296047Soshogbo	fields[0] = "gr_gid";
1076296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 1) == -1 &&
1077296047Soshogbo	    errno == ENOTCAPABLE);
1078296047Soshogbo
1079296047Soshogbo	CHECK(runtest_fields(capgrp, GR_NAME | GR_PASSWD));
1080296047Soshogbo
1081296047Soshogbo	cap_close(capgrp);
1082296047Soshogbo
1083296047Soshogbo	/*
1084296047Soshogbo	 * Allow:
1085296047Soshogbo	 * fields: gr_name, gr_gid
1086296047Soshogbo	 */
1087296047Soshogbo	capgrp = cap_clone(origcapgrp);
1088296047Soshogbo	CHECK(capgrp != NULL);
1089296047Soshogbo
1090296047Soshogbo	fields[0] = "gr_name";
1091296047Soshogbo	fields[1] = "gr_gid";
1092296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 2) == 0);
1093296047Soshogbo	fields[0] = "gr_name";
1094296047Soshogbo	fields[1] = "gr_passwd";
1095296047Soshogbo	fields[2] = "gr_gid";
1096296047Soshogbo	fields[3] = "gr_mem";
1097296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == -1 &&
1098296047Soshogbo	    errno == ENOTCAPABLE);
1099296047Soshogbo	fields[0] = "gr_mem";
1100296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 1) == -1 &&
1101296047Soshogbo	    errno == ENOTCAPABLE);
1102296047Soshogbo
1103296047Soshogbo	CHECK(runtest_fields(capgrp, GR_NAME | GR_GID));
1104296047Soshogbo
1105296047Soshogbo	cap_close(capgrp);
1106296047Soshogbo
1107296047Soshogbo	/*
1108296047Soshogbo	 * Allow:
1109296047Soshogbo	 * fields: gr_name, gr_mem
1110296047Soshogbo	 */
1111296047Soshogbo	capgrp = cap_clone(origcapgrp);
1112296047Soshogbo	CHECK(capgrp != NULL);
1113296047Soshogbo
1114296047Soshogbo	fields[0] = "gr_name";
1115296047Soshogbo	fields[1] = "gr_mem";
1116296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 2) == 0);
1117296047Soshogbo	fields[0] = "gr_name";
1118296047Soshogbo	fields[1] = "gr_passwd";
1119296047Soshogbo	fields[2] = "gr_gid";
1120296047Soshogbo	fields[3] = "gr_mem";
1121296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == -1 &&
1122296047Soshogbo	    errno == ENOTCAPABLE);
1123296047Soshogbo	fields[0] = "gr_passwd";
1124296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 1) == -1 &&
1125296047Soshogbo	    errno == ENOTCAPABLE);
1126296047Soshogbo
1127296047Soshogbo	CHECK(runtest_fields(capgrp, GR_NAME | GR_MEM));
1128296047Soshogbo
1129296047Soshogbo	cap_close(capgrp);
1130296047Soshogbo
1131296047Soshogbo	/*
1132296047Soshogbo	 * Allow:
1133296047Soshogbo	 * fields: gr_passwd, gr_gid
1134296047Soshogbo	 */
1135296047Soshogbo	capgrp = cap_clone(origcapgrp);
1136296047Soshogbo	CHECK(capgrp != NULL);
1137296047Soshogbo
1138296047Soshogbo	fields[0] = "gr_passwd";
1139296047Soshogbo	fields[1] = "gr_gid";
1140296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 2) == 0);
1141296047Soshogbo	fields[0] = "gr_name";
1142296047Soshogbo	fields[1] = "gr_passwd";
1143296047Soshogbo	fields[2] = "gr_gid";
1144296047Soshogbo	fields[3] = "gr_mem";
1145296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == -1 &&
1146296047Soshogbo	    errno == ENOTCAPABLE);
1147296047Soshogbo	fields[0] = "gr_mem";
1148296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 1) == -1 &&
1149296047Soshogbo	    errno == ENOTCAPABLE);
1150296047Soshogbo
1151296047Soshogbo	CHECK(runtest_fields(capgrp, GR_PASSWD | GR_GID));
1152296047Soshogbo
1153296047Soshogbo	cap_close(capgrp);
1154296047Soshogbo
1155296047Soshogbo	/*
1156296047Soshogbo	 * Allow:
1157296047Soshogbo	 * fields: gr_passwd, gr_mem
1158296047Soshogbo	 */
1159296047Soshogbo	capgrp = cap_clone(origcapgrp);
1160296047Soshogbo	CHECK(capgrp != NULL);
1161296047Soshogbo
1162296047Soshogbo	fields[0] = "gr_passwd";
1163296047Soshogbo	fields[1] = "gr_mem";
1164296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 2) == 0);
1165296047Soshogbo	fields[0] = "gr_name";
1166296047Soshogbo	fields[1] = "gr_passwd";
1167296047Soshogbo	fields[2] = "gr_gid";
1168296047Soshogbo	fields[3] = "gr_mem";
1169296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == -1 &&
1170296047Soshogbo	    errno == ENOTCAPABLE);
1171296047Soshogbo	fields[0] = "gr_gid";
1172296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 1) == -1 &&
1173296047Soshogbo	    errno == ENOTCAPABLE);
1174296047Soshogbo
1175296047Soshogbo	CHECK(runtest_fields(capgrp, GR_PASSWD | GR_MEM));
1176296047Soshogbo
1177296047Soshogbo	cap_close(capgrp);
1178296047Soshogbo
1179296047Soshogbo	/*
1180296047Soshogbo	 * Allow:
1181296047Soshogbo	 * fields: gr_gid, gr_mem
1182296047Soshogbo	 */
1183296047Soshogbo	capgrp = cap_clone(origcapgrp);
1184296047Soshogbo	CHECK(capgrp != NULL);
1185296047Soshogbo
1186296047Soshogbo	fields[0] = "gr_gid";
1187296047Soshogbo	fields[1] = "gr_mem";
1188296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 2) == 0);
1189296047Soshogbo	fields[0] = "gr_name";
1190296047Soshogbo	fields[1] = "gr_passwd";
1191296047Soshogbo	fields[2] = "gr_gid";
1192296047Soshogbo	fields[3] = "gr_mem";
1193296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 4) == -1 &&
1194296047Soshogbo	    errno == ENOTCAPABLE);
1195296047Soshogbo	fields[0] = "gr_passwd";
1196296047Soshogbo	CHECK(cap_grp_limit_fields(capgrp, fields, 1) == -1 &&
1197296047Soshogbo	    errno == ENOTCAPABLE);
1198296047Soshogbo
1199296047Soshogbo	CHECK(runtest_fields(capgrp, GR_GID | GR_MEM));
1200296047Soshogbo
1201296047Soshogbo	cap_close(capgrp);
1202296047Soshogbo}
1203296047Soshogbo
1204296047Soshogbostatic bool
1205296047Soshogboruntest_groups(cap_channel_t *capgrp, const char **names, const gid_t *gids,
1206296047Soshogbo    size_t ngroups)
1207296047Soshogbo{
1208296047Soshogbo	char buf[1024];
1209296047Soshogbo	struct group *grp;
1210296047Soshogbo	struct group st;
1211296047Soshogbo	unsigned int i, got;
1212296047Soshogbo
1213296047Soshogbo	(void)cap_setgrent(capgrp);
1214296047Soshogbo	got = 0;
1215296047Soshogbo	for (;;) {
1216296047Soshogbo		grp = cap_getgrent(capgrp);
1217296047Soshogbo		if (grp == NULL)
1218296047Soshogbo			break;
1219296047Soshogbo		got++;
1220296047Soshogbo		for (i = 0; i < ngroups; i++) {
1221296047Soshogbo			if (strcmp(names[i], grp->gr_name) == 0 &&
1222296047Soshogbo			    gids[i] == grp->gr_gid) {
1223296047Soshogbo				break;
1224296047Soshogbo			}
1225296047Soshogbo		}
1226296047Soshogbo		if (i == ngroups)
1227296047Soshogbo			return (false);
1228296047Soshogbo	}
1229296047Soshogbo	if (got != ngroups)
1230296047Soshogbo		return (false);
1231296047Soshogbo
1232296047Soshogbo	(void)cap_setgrent(capgrp);
1233296047Soshogbo	got = 0;
1234296047Soshogbo	for (;;) {
1235296047Soshogbo		cap_getgrent_r(capgrp, &st, buf, sizeof(buf), &grp);
1236296047Soshogbo		if (grp == NULL)
1237296047Soshogbo			break;
1238296047Soshogbo		got++;
1239296047Soshogbo		for (i = 0; i < ngroups; i++) {
1240296047Soshogbo			if (strcmp(names[i], grp->gr_name) == 0 &&
1241296047Soshogbo			    gids[i] == grp->gr_gid) {
1242296047Soshogbo				break;
1243296047Soshogbo			}
1244296047Soshogbo		}
1245296047Soshogbo		if (i == ngroups)
1246296047Soshogbo			return (false);
1247296047Soshogbo	}
1248296047Soshogbo	if (got != ngroups)
1249296047Soshogbo		return (false);
1250296047Soshogbo
1251296047Soshogbo	for (i = 0; i < ngroups; i++) {
1252296047Soshogbo		grp = cap_getgrnam(capgrp, names[i]);
1253296047Soshogbo		if (grp == NULL)
1254296047Soshogbo			return (false);
1255296047Soshogbo	}
1256296047Soshogbo
1257296047Soshogbo	for (i = 0; i < ngroups; i++) {
1258296047Soshogbo		cap_getgrnam_r(capgrp, names[i], &st, buf, sizeof(buf), &grp);
1259296047Soshogbo		if (grp == NULL)
1260296047Soshogbo			return (false);
1261296047Soshogbo	}
1262296047Soshogbo
1263296047Soshogbo	for (i = 0; i < ngroups; i++) {
1264296047Soshogbo		grp = cap_getgrgid(capgrp, gids[i]);
1265296047Soshogbo		if (grp == NULL)
1266296047Soshogbo			return (false);
1267296047Soshogbo	}
1268296047Soshogbo
1269296047Soshogbo	for (i = 0; i < ngroups; i++) {
1270296047Soshogbo		cap_getgrgid_r(capgrp, gids[i], &st, buf, sizeof(buf), &grp);
1271296047Soshogbo		if (grp == NULL)
1272296047Soshogbo			return (false);
1273296047Soshogbo	}
1274296047Soshogbo
1275296047Soshogbo	return (true);
1276296047Soshogbo}
1277296047Soshogbo
1278296047Soshogbostatic void
1279296047Soshogbotest_groups(cap_channel_t *origcapgrp)
1280296047Soshogbo{
1281296047Soshogbo	cap_channel_t *capgrp;
1282296047Soshogbo	const char *names[5];
1283296047Soshogbo	gid_t gids[5];
1284296047Soshogbo
1285296047Soshogbo	/*
1286296047Soshogbo	 * Allow:
1287296047Soshogbo	 * groups:
1288296047Soshogbo	 *     names: wheel, daemon, kmem, sys, tty
1289296047Soshogbo	 *     gids:
1290296047Soshogbo	 */
1291296047Soshogbo	capgrp = cap_clone(origcapgrp);
1292296047Soshogbo	CHECK(capgrp != NULL);
1293296047Soshogbo
1294296047Soshogbo	names[0] = "wheel";
1295296047Soshogbo	names[1] = "daemon";
1296296047Soshogbo	names[2] = "kmem";
1297296047Soshogbo	names[3] = "sys";
1298296047Soshogbo	names[4] = "tty";
1299296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 5, NULL, 0) == 0);
1300296047Soshogbo	gids[0] = 0;
1301296047Soshogbo	gids[1] = 1;
1302296047Soshogbo	gids[2] = 2;
1303296047Soshogbo	gids[3] = 3;
1304296047Soshogbo	gids[4] = 4;
1305296047Soshogbo
1306296047Soshogbo	CHECK(runtest_groups(capgrp, names, gids, 5));
1307296047Soshogbo
1308296047Soshogbo	cap_close(capgrp);
1309296047Soshogbo
1310296047Soshogbo	/*
1311296047Soshogbo	 * Allow:
1312296047Soshogbo	 * groups:
1313296047Soshogbo	 *     names: kmem, sys, tty
1314296047Soshogbo	 *     gids:
1315296047Soshogbo	 */
1316296047Soshogbo	capgrp = cap_clone(origcapgrp);
1317296047Soshogbo	CHECK(capgrp != NULL);
1318296047Soshogbo
1319296047Soshogbo	names[0] = "kmem";
1320296047Soshogbo	names[1] = "sys";
1321296047Soshogbo	names[2] = "tty";
1322296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 3, NULL, 0) == 0);
1323296047Soshogbo	names[3] = "daemon";
1324296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 4, NULL, 0) == -1 &&
1325296047Soshogbo	    errno == ENOTCAPABLE);
1326296047Soshogbo	names[0] = "daemon";
1327296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 1, NULL, 0) == -1 &&
1328296047Soshogbo	    errno == ENOTCAPABLE);
1329296047Soshogbo	names[0] = "kmem";
1330296047Soshogbo	gids[0] = 2;
1331296047Soshogbo	gids[1] = 3;
1332296047Soshogbo	gids[2] = 4;
1333296047Soshogbo
1334296047Soshogbo	CHECK(runtest_groups(capgrp, names, gids, 3));
1335296047Soshogbo
1336296047Soshogbo	cap_close(capgrp);
1337296047Soshogbo
1338296047Soshogbo	/*
1339296047Soshogbo	 * Allow:
1340296047Soshogbo	 * groups:
1341296047Soshogbo	 *     names: wheel, kmem, tty
1342296047Soshogbo	 *     gids:
1343296047Soshogbo	 */
1344296047Soshogbo	capgrp = cap_clone(origcapgrp);
1345296047Soshogbo	CHECK(capgrp != NULL);
1346296047Soshogbo
1347296047Soshogbo	names[0] = "wheel";
1348296047Soshogbo	names[1] = "kmem";
1349296047Soshogbo	names[2] = "tty";
1350296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 3, NULL, 0) == 0);
1351296047Soshogbo	names[3] = "daemon";
1352296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 4, NULL, 0) == -1 &&
1353296047Soshogbo	    errno == ENOTCAPABLE);
1354296047Soshogbo	names[0] = "daemon";
1355296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 1, NULL, 0) == -1 &&
1356296047Soshogbo	    errno == ENOTCAPABLE);
1357296047Soshogbo	names[0] = "wheel";
1358296047Soshogbo	gids[0] = 0;
1359296047Soshogbo	gids[1] = 2;
1360296047Soshogbo	gids[2] = 4;
1361296047Soshogbo
1362296047Soshogbo	CHECK(runtest_groups(capgrp, names, gids, 3));
1363296047Soshogbo
1364296047Soshogbo	cap_close(capgrp);
1365296047Soshogbo
1366296047Soshogbo	/*
1367296047Soshogbo	 * Allow:
1368296047Soshogbo	 * groups:
1369296047Soshogbo	 *     names:
1370296047Soshogbo	 *     gids: 2, 3, 4
1371296047Soshogbo	 */
1372296047Soshogbo	capgrp = cap_clone(origcapgrp);
1373296047Soshogbo	CHECK(capgrp != NULL);
1374296047Soshogbo
1375296047Soshogbo	names[0] = "kmem";
1376296047Soshogbo	names[1] = "sys";
1377296047Soshogbo	names[2] = "tty";
1378296047Soshogbo	gids[0] = 2;
1379296047Soshogbo	gids[1] = 3;
1380296047Soshogbo	gids[2] = 4;
1381296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 3) == 0);
1382296047Soshogbo	gids[3] = 0;
1383296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 4) == -1 &&
1384296047Soshogbo	    errno == ENOTCAPABLE);
1385296047Soshogbo	gids[0] = 0;
1386296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 1) == -1 &&
1387296047Soshogbo	    errno == ENOTCAPABLE);
1388296047Soshogbo	gids[0] = 2;
1389296047Soshogbo
1390296047Soshogbo	CHECK(runtest_groups(capgrp, names, gids, 3));
1391296047Soshogbo
1392296047Soshogbo	cap_close(capgrp);
1393296047Soshogbo
1394296047Soshogbo	/*
1395296047Soshogbo	 * Allow:
1396296047Soshogbo	 * groups:
1397296047Soshogbo	 *     names:
1398296047Soshogbo	 *     gids: 0, 2, 4
1399296047Soshogbo	 */
1400296047Soshogbo	capgrp = cap_clone(origcapgrp);
1401296047Soshogbo	CHECK(capgrp != NULL);
1402296047Soshogbo
1403296047Soshogbo	names[0] = "wheel";
1404296047Soshogbo	names[1] = "kmem";
1405296047Soshogbo	names[2] = "tty";
1406296047Soshogbo	gids[0] = 0;
1407296047Soshogbo	gids[1] = 2;
1408296047Soshogbo	gids[2] = 4;
1409296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 3) == 0);
1410296047Soshogbo	gids[3] = 1;
1411296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 4) == -1 &&
1412296047Soshogbo	    errno == ENOTCAPABLE);
1413296047Soshogbo	gids[0] = 1;
1414296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 1) == -1 &&
1415296047Soshogbo	    errno == ENOTCAPABLE);
1416296047Soshogbo	gids[0] = 0;
1417296047Soshogbo
1418296047Soshogbo	CHECK(runtest_groups(capgrp, names, gids, 3));
1419296047Soshogbo
1420296047Soshogbo	cap_close(capgrp);
1421296047Soshogbo
1422296047Soshogbo	/*
1423296047Soshogbo	 * Allow:
1424296047Soshogbo	 * groups:
1425296047Soshogbo	 *     names: kmem
1426296047Soshogbo	 *     gids:
1427296047Soshogbo	 */
1428296047Soshogbo	capgrp = cap_clone(origcapgrp);
1429296047Soshogbo	CHECK(capgrp != NULL);
1430296047Soshogbo
1431296047Soshogbo	names[0] = "kmem";
1432296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 1, NULL, 0) == 0);
1433296047Soshogbo	names[1] = "daemon";
1434296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 2, NULL, 0) == -1 &&
1435296047Soshogbo	    errno == ENOTCAPABLE);
1436296047Soshogbo	names[0] = "daemon";
1437296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 1, NULL, 0) == -1 &&
1438296047Soshogbo	    errno == ENOTCAPABLE);
1439296047Soshogbo	names[0] = "kmem";
1440296047Soshogbo	gids[0] = 2;
1441296047Soshogbo
1442296047Soshogbo	CHECK(runtest_groups(capgrp, names, gids, 1));
1443296047Soshogbo
1444296047Soshogbo	cap_close(capgrp);
1445296047Soshogbo
1446296047Soshogbo	/*
1447296047Soshogbo	 * Allow:
1448296047Soshogbo	 * groups:
1449296047Soshogbo	 *     names: wheel, tty
1450296047Soshogbo	 *     gids:
1451296047Soshogbo	 */
1452296047Soshogbo	capgrp = cap_clone(origcapgrp);
1453296047Soshogbo	CHECK(capgrp != NULL);
1454296047Soshogbo
1455296047Soshogbo	names[0] = "wheel";
1456296047Soshogbo	names[1] = "tty";
1457296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 2, NULL, 0) == 0);
1458296047Soshogbo	names[2] = "daemon";
1459296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 3, NULL, 0) == -1 &&
1460296047Soshogbo	    errno == ENOTCAPABLE);
1461296047Soshogbo	names[0] = "daemon";
1462296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, names, 1, NULL, 0) == -1 &&
1463296047Soshogbo	    errno == ENOTCAPABLE);
1464296047Soshogbo	names[0] = "wheel";
1465296047Soshogbo	gids[0] = 0;
1466296047Soshogbo	gids[1] = 4;
1467296047Soshogbo
1468296047Soshogbo	CHECK(runtest_groups(capgrp, names, gids, 2));
1469296047Soshogbo
1470296047Soshogbo	cap_close(capgrp);
1471296047Soshogbo
1472296047Soshogbo	/*
1473296047Soshogbo	 * Allow:
1474296047Soshogbo	 * groups:
1475296047Soshogbo	 *     names:
1476296047Soshogbo	 *     gids: 2
1477296047Soshogbo	 */
1478296047Soshogbo	capgrp = cap_clone(origcapgrp);
1479296047Soshogbo	CHECK(capgrp != NULL);
1480296047Soshogbo
1481296047Soshogbo	names[0] = "kmem";
1482296047Soshogbo	gids[0] = 2;
1483296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 1) == 0);
1484296047Soshogbo	gids[1] = 1;
1485296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 2) == -1 &&
1486296047Soshogbo	    errno == ENOTCAPABLE);
1487296047Soshogbo	gids[0] = 1;
1488296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 1) == -1 &&
1489296047Soshogbo	    errno == ENOTCAPABLE);
1490296047Soshogbo	gids[0] = 2;
1491296047Soshogbo
1492296047Soshogbo	CHECK(runtest_groups(capgrp, names, gids, 1));
1493296047Soshogbo
1494296047Soshogbo	cap_close(capgrp);
1495296047Soshogbo
1496296047Soshogbo	/*
1497296047Soshogbo	 * Allow:
1498296047Soshogbo	 * groups:
1499296047Soshogbo	 *     names:
1500296047Soshogbo	 *     gids: 0, 4
1501296047Soshogbo	 */
1502296047Soshogbo	capgrp = cap_clone(origcapgrp);
1503296047Soshogbo	CHECK(capgrp != NULL);
1504296047Soshogbo
1505296047Soshogbo	names[0] = "wheel";
1506296047Soshogbo	names[1] = "tty";
1507296047Soshogbo	gids[0] = 0;
1508296047Soshogbo	gids[1] = 4;
1509296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 2) == 0);
1510296047Soshogbo	gids[2] = 1;
1511296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 3) == -1 &&
1512296047Soshogbo	    errno == ENOTCAPABLE);
1513296047Soshogbo	gids[0] = 1;
1514296047Soshogbo	CHECK(cap_grp_limit_groups(capgrp, NULL, 0, gids, 1) == -1 &&
1515296047Soshogbo	    errno == ENOTCAPABLE);
1516296047Soshogbo	gids[0] = 0;
1517296047Soshogbo
1518296047Soshogbo	CHECK(runtest_groups(capgrp, names, gids, 2));
1519296047Soshogbo
1520296047Soshogbo	cap_close(capgrp);
1521296047Soshogbo}
1522296047Soshogbo
1523296047Soshogboint
1524296047Soshogbomain(void)
1525296047Soshogbo{
1526296047Soshogbo	cap_channel_t *capcas, *capgrp;
1527296047Soshogbo
1528296047Soshogbo	printf("1..199\n");
1529322715Sngie	fflush(stdout);
1530296047Soshogbo
1531296047Soshogbo	capcas = cap_init();
1532296047Soshogbo	CHECKX(capcas != NULL);
1533296047Soshogbo
1534296047Soshogbo	capgrp = cap_service_open(capcas, "system.grp");
1535296047Soshogbo	CHECKX(capgrp != NULL);
1536296047Soshogbo
1537296047Soshogbo	cap_close(capcas);
1538296047Soshogbo
1539296047Soshogbo	/* No limits. */
1540296047Soshogbo
1541296047Soshogbo	CHECK(runtest_cmds(capgrp) == (SETGRENT | GETGRENT | GETGRENT_R |
1542296047Soshogbo	    GETGRNAM | GETGRNAM_R | GETGRGID | GETGRGID_R));
1543296047Soshogbo
1544296047Soshogbo	test_cmds(capgrp);
1545296047Soshogbo
1546296047Soshogbo	test_fields(capgrp);
1547296047Soshogbo
1548296047Soshogbo	test_groups(capgrp);
1549296047Soshogbo
1550296047Soshogbo	cap_close(capgrp);
1551296047Soshogbo
1552296047Soshogbo	exit(0);
1553296047Soshogbo}
1554