xref: /aosp_15_r20/external/libcap-ng/utils/captest.c (revision 8dd5e09d5faf27a871e8654ddaa2d2af7c696578)
1*8dd5e09dSSadaf Ebrahimi /*
2*8dd5e09dSSadaf Ebrahimi  * captest.c - A program that demonstrates and outputs capabilities
3*8dd5e09dSSadaf Ebrahimi  * Copyright (c) 2009, 2013, 2020 Red Hat Inc.
4*8dd5e09dSSadaf Ebrahimi  * All Rights Reserved.
5*8dd5e09dSSadaf Ebrahimi  *
6*8dd5e09dSSadaf Ebrahimi  * This software may be freely redistributed and/or modified under the
7*8dd5e09dSSadaf Ebrahimi  * terms of the GNU General Public License as published by the Free
8*8dd5e09dSSadaf Ebrahimi  * Software Foundation; either version 2, or (at your option) any
9*8dd5e09dSSadaf Ebrahimi  * later version.
10*8dd5e09dSSadaf Ebrahimi  *
11*8dd5e09dSSadaf Ebrahimi  * This program is distributed in the hope that it will be useful,
12*8dd5e09dSSadaf Ebrahimi  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*8dd5e09dSSadaf Ebrahimi  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*8dd5e09dSSadaf Ebrahimi  * GNU General Public License for more details.
15*8dd5e09dSSadaf Ebrahimi  *
16*8dd5e09dSSadaf Ebrahimi  * You should have received a copy of the GNU General Public License
17*8dd5e09dSSadaf Ebrahimi  * along with this program; see the file COPYING. If not, write to the
18*8dd5e09dSSadaf Ebrahimi  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
19*8dd5e09dSSadaf Ebrahimi  * Boston, MA 02110-1335, USA.
20*8dd5e09dSSadaf Ebrahimi  *
21*8dd5e09dSSadaf Ebrahimi  * Authors:
22*8dd5e09dSSadaf Ebrahimi  *   Steve Grubb <[email protected]>
23*8dd5e09dSSadaf Ebrahimi  *
24*8dd5e09dSSadaf Ebrahimi  */
25*8dd5e09dSSadaf Ebrahimi #include "config.h"
26*8dd5e09dSSadaf Ebrahimi #include <unistd.h>
27*8dd5e09dSSadaf Ebrahimi #include <stdio.h>
28*8dd5e09dSSadaf Ebrahimi #include <fcntl.h>
29*8dd5e09dSSadaf Ebrahimi #include <stdlib.h>
30*8dd5e09dSSadaf Ebrahimi #include <string.h>
31*8dd5e09dSSadaf Ebrahimi #include <errno.h>
32*8dd5e09dSSadaf Ebrahimi #include <cap-ng.h>
33*8dd5e09dSSadaf Ebrahimi #include <sys/prctl.h>
34*8dd5e09dSSadaf Ebrahimi #ifdef HAVE_LINUX_SECUREBITS_H
35*8dd5e09dSSadaf Ebrahimi #include <linux/securebits.h>
36*8dd5e09dSSadaf Ebrahimi #endif
37*8dd5e09dSSadaf Ebrahimi 
38*8dd5e09dSSadaf Ebrahimi /* children can't get caps back */
39*8dd5e09dSSadaf Ebrahimi #ifndef SECURE_NOROOT
40*8dd5e09dSSadaf Ebrahimi #define SECURE_NOROOT                   0
41*8dd5e09dSSadaf Ebrahimi #endif
42*8dd5e09dSSadaf Ebrahimi #ifndef SECURE_NOROOT_LOCKED
43*8dd5e09dSSadaf Ebrahimi #define SECURE_NOROOT_LOCKED            1  /* make bit-0 immutable */
44*8dd5e09dSSadaf Ebrahimi #endif
45*8dd5e09dSSadaf Ebrahimi /* Setuid apps run by uid 0 don't get caps back */
46*8dd5e09dSSadaf Ebrahimi #ifndef SECURE_NO_SETUID_FIXUP
47*8dd5e09dSSadaf Ebrahimi #define SECURE_NO_SETUID_FIXUP          2
48*8dd5e09dSSadaf Ebrahimi #endif
49*8dd5e09dSSadaf Ebrahimi #ifndef SECURE_NO_SETUID_FIXUP_LOCKED
50*8dd5e09dSSadaf Ebrahimi #define SECURE_NO_SETUID_FIXUP_LOCKED   3  /* make bit-2 immutable */
51*8dd5e09dSSadaf Ebrahimi #endif
52*8dd5e09dSSadaf Ebrahimi 
53*8dd5e09dSSadaf Ebrahimi static int text = 0, no_child = 0, lock = 0, ambient = 0;
54*8dd5e09dSSadaf Ebrahimi 
report(void)55*8dd5e09dSSadaf Ebrahimi static void report(void)
56*8dd5e09dSSadaf Ebrahimi {
57*8dd5e09dSSadaf Ebrahimi 	int rc, escalated = 0, need_comma = 0;
58*8dd5e09dSSadaf Ebrahimi 	uid_t uid, euid, suid;
59*8dd5e09dSSadaf Ebrahimi 	gid_t gid, egid, sgid;
60*8dd5e09dSSadaf Ebrahimi 
61*8dd5e09dSSadaf Ebrahimi 	// Refresh what we have for capabilities
62*8dd5e09dSSadaf Ebrahimi 	if (capng_get_caps_process()) {
63*8dd5e09dSSadaf Ebrahimi 		printf("Error getting capabilities\n");
64*8dd5e09dSSadaf Ebrahimi 		exit(1);
65*8dd5e09dSSadaf Ebrahimi 	}
66*8dd5e09dSSadaf Ebrahimi 
67*8dd5e09dSSadaf Ebrahimi 	// Check user credentials
68*8dd5e09dSSadaf Ebrahimi 	getresuid(&uid, &euid, &suid);
69*8dd5e09dSSadaf Ebrahimi 	getresgid(&gid, &egid, &sgid);
70*8dd5e09dSSadaf Ebrahimi 	if (no_child) {
71*8dd5e09dSSadaf Ebrahimi 		if ((uid != euid && uid != 0) ||
72*8dd5e09dSSadaf Ebrahimi 					capng_have_capability(CAPNG_EFFECTIVE,
73*8dd5e09dSSadaf Ebrahimi 						 CAP_SETUID)) {
74*8dd5e09dSSadaf Ebrahimi 			printf("Attempting to regain root...");
75*8dd5e09dSSadaf Ebrahimi 			setuid(0);
76*8dd5e09dSSadaf Ebrahimi 			getresuid(&uid, &euid, &suid);
77*8dd5e09dSSadaf Ebrahimi 			if (uid == 0) {
78*8dd5e09dSSadaf Ebrahimi 				printf("SUCCESS - PRIVILEGE ESCALATION POSSIBLE\n");
79*8dd5e09dSSadaf Ebrahimi 				setgid(0);
80*8dd5e09dSSadaf Ebrahimi 				getresgid(&gid, &egid, &sgid);
81*8dd5e09dSSadaf Ebrahimi 				escalated = 1;
82*8dd5e09dSSadaf Ebrahimi 			} else
83*8dd5e09dSSadaf Ebrahimi 				printf("FAILED\n");
84*8dd5e09dSSadaf Ebrahimi 		}
85*8dd5e09dSSadaf Ebrahimi 		printf("Child ");
86*8dd5e09dSSadaf Ebrahimi 	}
87*8dd5e09dSSadaf Ebrahimi 	printf("User  credentials uid:%u euid:%u suid:%u\n", uid, euid, suid);
88*8dd5e09dSSadaf Ebrahimi 	if (no_child)
89*8dd5e09dSSadaf Ebrahimi 		printf("Child ");
90*8dd5e09dSSadaf Ebrahimi 	printf("Group credentials gid:%u egid:%u sgid:%u\n", gid, egid, sgid);
91*8dd5e09dSSadaf Ebrahimi 	if (uid != euid || gid != egid)
92*8dd5e09dSSadaf Ebrahimi 		printf("Note: app has mismatching credentials!!\n");
93*8dd5e09dSSadaf Ebrahimi 
94*8dd5e09dSSadaf Ebrahimi 	// Check capabilities
95*8dd5e09dSSadaf Ebrahimi 	if (text) {
96*8dd5e09dSSadaf Ebrahimi 		if (capng_have_capabilities(CAPNG_SELECT_CAPS) == CAPNG_NONE) {
97*8dd5e09dSSadaf Ebrahimi 			if (no_child)
98*8dd5e09dSSadaf Ebrahimi 				printf("Child capabilities: none\n");
99*8dd5e09dSSadaf Ebrahimi 			else
100*8dd5e09dSSadaf Ebrahimi 				printf("Current capabilities: none\n");
101*8dd5e09dSSadaf Ebrahimi 		} else {
102*8dd5e09dSSadaf Ebrahimi 			if (no_child)
103*8dd5e09dSSadaf Ebrahimi 				printf("Child ");
104*8dd5e09dSSadaf Ebrahimi 			printf("Effective: ");
105*8dd5e09dSSadaf Ebrahimi 			capng_print_caps_text(CAPNG_PRINT_STDOUT,
106*8dd5e09dSSadaf Ebrahimi 					CAPNG_EFFECTIVE);
107*8dd5e09dSSadaf Ebrahimi 			printf("\n");
108*8dd5e09dSSadaf Ebrahimi 			if (no_child)
109*8dd5e09dSSadaf Ebrahimi 				printf("Child ");
110*8dd5e09dSSadaf Ebrahimi 			printf("Permitted: ");
111*8dd5e09dSSadaf Ebrahimi 			capng_print_caps_text(CAPNG_PRINT_STDOUT,
112*8dd5e09dSSadaf Ebrahimi 					CAPNG_PERMITTED);
113*8dd5e09dSSadaf Ebrahimi 			printf("\n");
114*8dd5e09dSSadaf Ebrahimi 			if (no_child)
115*8dd5e09dSSadaf Ebrahimi 				printf("Child ");
116*8dd5e09dSSadaf Ebrahimi 			printf("Inheritable: ");
117*8dd5e09dSSadaf Ebrahimi 			capng_print_caps_text(CAPNG_PRINT_STDOUT,
118*8dd5e09dSSadaf Ebrahimi 					CAPNG_INHERITABLE);
119*8dd5e09dSSadaf Ebrahimi 			printf("\n");
120*8dd5e09dSSadaf Ebrahimi 			if (no_child)
121*8dd5e09dSSadaf Ebrahimi 				printf("Child ");
122*8dd5e09dSSadaf Ebrahimi 			printf("Bounding Set: ");
123*8dd5e09dSSadaf Ebrahimi 			capng_print_caps_text(CAPNG_PRINT_STDOUT,
124*8dd5e09dSSadaf Ebrahimi 					CAPNG_BOUNDING_SET);
125*8dd5e09dSSadaf Ebrahimi 			printf("\n");
126*8dd5e09dSSadaf Ebrahimi 			if (no_child)
127*8dd5e09dSSadaf Ebrahimi 				printf("Child ");
128*8dd5e09dSSadaf Ebrahimi 			printf("Ambient: ");
129*8dd5e09dSSadaf Ebrahimi 			capng_print_caps_text(CAPNG_PRINT_STDOUT,
130*8dd5e09dSSadaf Ebrahimi 					CAPNG_AMBIENT);
131*8dd5e09dSSadaf Ebrahimi 			printf("\n");
132*8dd5e09dSSadaf Ebrahimi 		}
133*8dd5e09dSSadaf Ebrahimi 	} else {
134*8dd5e09dSSadaf Ebrahimi 		if (capng_have_capabilities(CAPNG_SELECT_CAPS) == CAPNG_NONE) {
135*8dd5e09dSSadaf Ebrahimi 			if (no_child)
136*8dd5e09dSSadaf Ebrahimi 				printf("Child capabilities: none\n");
137*8dd5e09dSSadaf Ebrahimi 			else
138*8dd5e09dSSadaf Ebrahimi 				printf("Current capabilities: none\n");
139*8dd5e09dSSadaf Ebrahimi 		} else {
140*8dd5e09dSSadaf Ebrahimi 			if (no_child)
141*8dd5e09dSSadaf Ebrahimi 				printf("Child capabilities:\n");
142*8dd5e09dSSadaf Ebrahimi 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
143*8dd5e09dSSadaf Ebrahimi 					CAPNG_SELECT_ALL);
144*8dd5e09dSSadaf Ebrahimi 		}
145*8dd5e09dSSadaf Ebrahimi 	}
146*8dd5e09dSSadaf Ebrahimi 
147*8dd5e09dSSadaf Ebrahimi 	// Now check securebits flags
148*8dd5e09dSSadaf Ebrahimi #ifdef PR_SET_SECUREBITS
149*8dd5e09dSSadaf Ebrahimi 	if (no_child)
150*8dd5e09dSSadaf Ebrahimi 		printf("Child ");
151*8dd5e09dSSadaf Ebrahimi 	printf("securebits flags: ");
152*8dd5e09dSSadaf Ebrahimi 	rc = prctl(PR_GET_SECUREBITS, 1 << SECURE_NOROOT);
153*8dd5e09dSSadaf Ebrahimi 	if (rc & (1 << SECURE_NOROOT)) {
154*8dd5e09dSSadaf Ebrahimi 		printf("NOROOT");
155*8dd5e09dSSadaf Ebrahimi 		need_comma = 1;
156*8dd5e09dSSadaf Ebrahimi 	}
157*8dd5e09dSSadaf Ebrahimi 	rc = prctl(PR_GET_SECUREBITS, 1 << SECURE_NOROOT_LOCKED);
158*8dd5e09dSSadaf Ebrahimi 	if (rc & (1 << SECURE_NOROOT_LOCKED)) {
159*8dd5e09dSSadaf Ebrahimi 		if (need_comma)
160*8dd5e09dSSadaf Ebrahimi 			printf(", ");
161*8dd5e09dSSadaf Ebrahimi 		printf("NOROOT_LOCKED");
162*8dd5e09dSSadaf Ebrahimi 		need_comma = 1;
163*8dd5e09dSSadaf Ebrahimi 	}
164*8dd5e09dSSadaf Ebrahimi 	rc = prctl(PR_GET_SECUREBITS, 1 << SECURE_NO_SETUID_FIXUP);
165*8dd5e09dSSadaf Ebrahimi 	if (rc & (1 << SECURE_NO_SETUID_FIXUP)) {
166*8dd5e09dSSadaf Ebrahimi 		if (need_comma)
167*8dd5e09dSSadaf Ebrahimi 			printf(", ");
168*8dd5e09dSSadaf Ebrahimi 		printf("NO_SETUID_FIXUP");
169*8dd5e09dSSadaf Ebrahimi 		need_comma = 1;
170*8dd5e09dSSadaf Ebrahimi 	}
171*8dd5e09dSSadaf Ebrahimi 	rc = prctl(PR_GET_SECUREBITS, 1 << SECURE_NO_SETUID_FIXUP_LOCKED);
172*8dd5e09dSSadaf Ebrahimi 	if (rc & (1 << SECURE_NO_SETUID_FIXUP_LOCKED)) {
173*8dd5e09dSSadaf Ebrahimi 		if (need_comma)
174*8dd5e09dSSadaf Ebrahimi 			printf(", ");
175*8dd5e09dSSadaf Ebrahimi 		printf("NO_SETUID_FIXUP_LOCKED");
176*8dd5e09dSSadaf Ebrahimi 		need_comma = 1;
177*8dd5e09dSSadaf Ebrahimi 	}
178*8dd5e09dSSadaf Ebrahimi 	if (need_comma == 0)
179*8dd5e09dSSadaf Ebrahimi 		printf("none");
180*8dd5e09dSSadaf Ebrahimi 	printf("\n");
181*8dd5e09dSSadaf Ebrahimi #endif
182*8dd5e09dSSadaf Ebrahimi 	// Now do child process checks
183*8dd5e09dSSadaf Ebrahimi 	if (no_child == 0 || escalated) {
184*8dd5e09dSSadaf Ebrahimi 		printf("Attempting direct access to shadow...");
185*8dd5e09dSSadaf Ebrahimi 		if (access("/etc/shadow", R_OK) == 0)
186*8dd5e09dSSadaf Ebrahimi 			printf("SUCCESS\n");
187*8dd5e09dSSadaf Ebrahimi 		else
188*8dd5e09dSSadaf Ebrahimi 			printf("FAILED (%s)\n", strerror(errno));
189*8dd5e09dSSadaf Ebrahimi 	}
190*8dd5e09dSSadaf Ebrahimi 	if (no_child == 0) {
191*8dd5e09dSSadaf Ebrahimi 		printf("Attempting to access shadow by child process...");
192*8dd5e09dSSadaf Ebrahimi 		rc = system("cat /etc/shadow > /dev/null 2>&1");
193*8dd5e09dSSadaf Ebrahimi 		if (rc == 0)
194*8dd5e09dSSadaf Ebrahimi 			printf("SUCCESS\n");
195*8dd5e09dSSadaf Ebrahimi 		else
196*8dd5e09dSSadaf Ebrahimi 			printf("FAILED\n");
197*8dd5e09dSSadaf Ebrahimi 		if (text)
198*8dd5e09dSSadaf Ebrahimi 			system("/usr/bin/captest --no-child --text");
199*8dd5e09dSSadaf Ebrahimi 		else
200*8dd5e09dSSadaf Ebrahimi 			system("/usr/bin/captest --no-child");
201*8dd5e09dSSadaf Ebrahimi 	}
202*8dd5e09dSSadaf Ebrahimi }
203*8dd5e09dSSadaf Ebrahimi 
usage(void)204*8dd5e09dSSadaf Ebrahimi static void usage(void)
205*8dd5e09dSSadaf Ebrahimi {
206*8dd5e09dSSadaf Ebrahimi 	printf("usage: captest [ --ambient | --drop-all | --drop-caps | --id | --init-grp ] [ --lock ] [ --text ]\n");
207*8dd5e09dSSadaf Ebrahimi }
208*8dd5e09dSSadaf Ebrahimi 
main(int argc,char * argv[])209*8dd5e09dSSadaf Ebrahimi int main(int argc, char *argv[])
210*8dd5e09dSSadaf Ebrahimi {
211*8dd5e09dSSadaf Ebrahimi 	int which = 0, i;
212*8dd5e09dSSadaf Ebrahimi 
213*8dd5e09dSSadaf Ebrahimi 	for (i = 1; i < argc; i++) {
214*8dd5e09dSSadaf Ebrahimi 		if (strcmp(argv[i], "--text") == 0)
215*8dd5e09dSSadaf Ebrahimi 			text = 1;
216*8dd5e09dSSadaf Ebrahimi 		else if (strcmp(argv[i], "--no-child") == 0)
217*8dd5e09dSSadaf Ebrahimi 			no_child = 1;
218*8dd5e09dSSadaf Ebrahimi 		else if (strcmp(argv[i], "--lock") == 0)
219*8dd5e09dSSadaf Ebrahimi 			lock = 1;
220*8dd5e09dSSadaf Ebrahimi 		else if (strcmp(argv[i], "--drop-all") == 0)
221*8dd5e09dSSadaf Ebrahimi 			which = 1;
222*8dd5e09dSSadaf Ebrahimi 		else if (strcmp(argv[i], "--drop-caps") == 0)
223*8dd5e09dSSadaf Ebrahimi 			which = 2;
224*8dd5e09dSSadaf Ebrahimi 		else if (strcmp(argv[i], "--id") == 0)
225*8dd5e09dSSadaf Ebrahimi 			which = 3;
226*8dd5e09dSSadaf Ebrahimi 		else if (strcmp(argv[i], "--init-grp") == 0)
227*8dd5e09dSSadaf Ebrahimi 			which = 4;
228*8dd5e09dSSadaf Ebrahimi 		else if (strcmp(argv[i], "--ambient") == 0)
229*8dd5e09dSSadaf Ebrahimi 			ambient = 1;
230*8dd5e09dSSadaf Ebrahimi 		else {
231*8dd5e09dSSadaf Ebrahimi 			usage();
232*8dd5e09dSSadaf Ebrahimi 			return 0;
233*8dd5e09dSSadaf Ebrahimi 		}
234*8dd5e09dSSadaf Ebrahimi 	}
235*8dd5e09dSSadaf Ebrahimi 	switch (which)
236*8dd5e09dSSadaf Ebrahimi 	{
237*8dd5e09dSSadaf Ebrahimi 		case 1:
238*8dd5e09dSSadaf Ebrahimi 			capng_clear(CAPNG_SELECT_ALL);
239*8dd5e09dSSadaf Ebrahimi 			if (lock) {
240*8dd5e09dSSadaf Ebrahimi 				if (capng_lock()) {
241*8dd5e09dSSadaf Ebrahimi 					fprintf(stderr, "capng_lock failed\n");
242*8dd5e09dSSadaf Ebrahimi 					return 1;
243*8dd5e09dSSadaf Ebrahimi 				}
244*8dd5e09dSSadaf Ebrahimi 			}
245*8dd5e09dSSadaf Ebrahimi 			if (capng_apply(CAPNG_SELECT_ALL)) {
246*8dd5e09dSSadaf Ebrahimi 				fprintf(stderr, "capng_apply failed\n");
247*8dd5e09dSSadaf Ebrahimi 				return 1;
248*8dd5e09dSSadaf Ebrahimi 			}
249*8dd5e09dSSadaf Ebrahimi 			report();
250*8dd5e09dSSadaf Ebrahimi 			break;
251*8dd5e09dSSadaf Ebrahimi 		case 2:
252*8dd5e09dSSadaf Ebrahimi 			capng_clear(CAPNG_SELECT_CAPS);
253*8dd5e09dSSadaf Ebrahimi 			if (ambient)
254*8dd5e09dSSadaf Ebrahimi 				capng_update(CAPNG_ADD, CAPNG_AMBIENT,
255*8dd5e09dSSadaf Ebrahimi 					     CAP_CHOWN);
256*8dd5e09dSSadaf Ebrahimi 			if (lock) {
257*8dd5e09dSSadaf Ebrahimi 				if (capng_lock()) {
258*8dd5e09dSSadaf Ebrahimi 					fprintf(stderr, "capng_lock failed\n");
259*8dd5e09dSSadaf Ebrahimi 					return 1;
260*8dd5e09dSSadaf Ebrahimi 				}
261*8dd5e09dSSadaf Ebrahimi 			}
262*8dd5e09dSSadaf Ebrahimi 			if (ambient) {
263*8dd5e09dSSadaf Ebrahimi 				if (capng_apply(
264*8dd5e09dSSadaf Ebrahimi 				  CAPNG_SELECT_CAPS|CAPNG_SELECT_AMBIENT)) {
265*8dd5e09dSSadaf Ebrahimi 				  fprintf(stderr, "capng_apply failed\n");
266*8dd5e09dSSadaf Ebrahimi 				  return 1;
267*8dd5e09dSSadaf Ebrahimi 				}
268*8dd5e09dSSadaf Ebrahimi 			} else {
269*8dd5e09dSSadaf Ebrahimi 				if (capng_apply(CAPNG_SELECT_CAPS)) {
270*8dd5e09dSSadaf Ebrahimi 					fprintf(stderr, "capng_apply failed\n");
271*8dd5e09dSSadaf Ebrahimi 					return 1;
272*8dd5e09dSSadaf Ebrahimi 				}
273*8dd5e09dSSadaf Ebrahimi 			}
274*8dd5e09dSSadaf Ebrahimi 			report();
275*8dd5e09dSSadaf Ebrahimi 			break;
276*8dd5e09dSSadaf Ebrahimi 		case 3:
277*8dd5e09dSSadaf Ebrahimi 		case 4: {
278*8dd5e09dSSadaf Ebrahimi 			int rc;
279*8dd5e09dSSadaf Ebrahimi 
280*8dd5e09dSSadaf Ebrahimi 			capng_clear(CAPNG_SELECT_BOTH);
281*8dd5e09dSSadaf Ebrahimi 			capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
282*8dd5e09dSSadaf Ebrahimi 					CAP_CHOWN);
283*8dd5e09dSSadaf Ebrahimi 			if (ambient)
284*8dd5e09dSSadaf Ebrahimi 				capng_update(CAPNG_ADD,
285*8dd5e09dSSadaf Ebrahimi 					     CAPNG_INHERITABLE|CAPNG_AMBIENT,
286*8dd5e09dSSadaf Ebrahimi 					     CAP_CHOWN);
287*8dd5e09dSSadaf Ebrahimi 			if (which == 4)
288*8dd5e09dSSadaf Ebrahimi 				rc = capng_change_id(99, 99,
289*8dd5e09dSSadaf Ebrahimi 				CAPNG_INIT_SUPP_GRP | CAPNG_CLEAR_BOUNDING);
290*8dd5e09dSSadaf Ebrahimi 			else
291*8dd5e09dSSadaf Ebrahimi 				rc = capng_change_id(99, 99,
292*8dd5e09dSSadaf Ebrahimi 				CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING);
293*8dd5e09dSSadaf Ebrahimi 			if (rc < 0) {
294*8dd5e09dSSadaf Ebrahimi 				printf("Error changing uid: %d\n", rc);
295*8dd5e09dSSadaf Ebrahimi 				capng_print_caps_text(CAPNG_PRINT_STDOUT,
296*8dd5e09dSSadaf Ebrahimi 					CAPNG_EFFECTIVE);
297*8dd5e09dSSadaf Ebrahimi 				printf("\n");
298*8dd5e09dSSadaf Ebrahimi 				return 1;
299*8dd5e09dSSadaf Ebrahimi 			}
300*8dd5e09dSSadaf Ebrahimi 			printf("Keeping CAP_CHOWN to show capabilities across uid change.\n");
301*8dd5e09dSSadaf Ebrahimi 			report();
302*8dd5e09dSSadaf Ebrahimi 			} break;
303*8dd5e09dSSadaf Ebrahimi 		case 0:
304*8dd5e09dSSadaf Ebrahimi 			if (lock) {
305*8dd5e09dSSadaf Ebrahimi 				if (capng_lock()) {
306*8dd5e09dSSadaf Ebrahimi 					fprintf(stderr, "capng_lock failed\n");
307*8dd5e09dSSadaf Ebrahimi 					return 1;
308*8dd5e09dSSadaf Ebrahimi 				}
309*8dd5e09dSSadaf Ebrahimi 			}
310*8dd5e09dSSadaf Ebrahimi 			report();
311*8dd5e09dSSadaf Ebrahimi 			break;
312*8dd5e09dSSadaf Ebrahimi 	}
313*8dd5e09dSSadaf Ebrahimi 	return 0;
314*8dd5e09dSSadaf Ebrahimi }
315*8dd5e09dSSadaf Ebrahimi 
316