xref: /aosp_15_r20/external/libcap/progs/old/setpcaps.c (revision 2810ac1b38eead2603277920c78344c84ddf3aff)
1*2810ac1bSKiyoung Kim /*
2*2810ac1bSKiyoung Kim  * Copyright (c) 1997-8 Andrew G. Morgan  <[email protected]>
3*2810ac1bSKiyoung Kim  *
4*2810ac1bSKiyoung Kim  * This sets the capabilities of a given process.
5*2810ac1bSKiyoung Kim  */
6*2810ac1bSKiyoung Kim 
7*2810ac1bSKiyoung Kim #include <sys/types.h>
8*2810ac1bSKiyoung Kim #include <errno.h>
9*2810ac1bSKiyoung Kim #include <stdio.h>
10*2810ac1bSKiyoung Kim #include <string.h>
11*2810ac1bSKiyoung Kim #include <stdlib.h>
12*2810ac1bSKiyoung Kim #undef _POSIX_SOURCE
13*2810ac1bSKiyoung Kim #include <sys/capability.h>
14*2810ac1bSKiyoung Kim #include <unistd.h>
15*2810ac1bSKiyoung Kim 
usage(void)16*2810ac1bSKiyoung Kim static void usage(void)
17*2810ac1bSKiyoung Kim {
18*2810ac1bSKiyoung Kim     fprintf(stderr,
19*2810ac1bSKiyoung Kim "usage: setcap [-q] (-|<caps>) <pid> [ ... (-|<capsN>) <pid> ]\n\n"
20*2810ac1bSKiyoung Kim "  This program can be used to set the process capabilities of running\n"
21*2810ac1bSKiyoung Kim "  processes.  In order to work, it needs to be executing with CAP_SETPCAP\n"
22*2810ac1bSKiyoung Kim "  raised, and the only capabilities that this program can bestow on others\n"
23*2810ac1bSKiyoung Kim "  are a subset of its effective set.  This program is mostly intended as an\n"
24*2810ac1bSKiyoung Kim "  example -- a safe use of CAP_SETPCAP has yet to be demonstrated!\n\n"
25*2810ac1bSKiyoung Kim "[Copyright (c) 1997-8 Andrew G. Morgan  <[email protected]>]\n"
26*2810ac1bSKiyoung Kim 	);
27*2810ac1bSKiyoung Kim     exit(1);
28*2810ac1bSKiyoung Kim }
29*2810ac1bSKiyoung Kim 
30*2810ac1bSKiyoung Kim #define MAXCAP  2048
31*2810ac1bSKiyoung Kim 
read_caps(int quiet,const char * filename,char * buffer)32*2810ac1bSKiyoung Kim static int read_caps(int quiet, const char *filename, char *buffer)
33*2810ac1bSKiyoung Kim {
34*2810ac1bSKiyoung Kim     int i=MAXCAP;
35*2810ac1bSKiyoung Kim 
36*2810ac1bSKiyoung Kim     if (!quiet) {
37*2810ac1bSKiyoung Kim 	fprintf(stderr,	"Please enter caps for file [empty line to end]:\n");
38*2810ac1bSKiyoung Kim     }
39*2810ac1bSKiyoung Kim     while (i > 0) {
40*2810ac1bSKiyoung Kim 	int j = read(STDIN_FILENO, buffer, i);
41*2810ac1bSKiyoung Kim 
42*2810ac1bSKiyoung Kim 	if (j < 0) {
43*2810ac1bSKiyoung Kim 	    fprintf(stderr, "\n[Error - aborting]\n");
44*2810ac1bSKiyoung Kim 	    exit(1);
45*2810ac1bSKiyoung Kim 	}
46*2810ac1bSKiyoung Kim 
47*2810ac1bSKiyoung Kim 	if (j==0 || buffer[0] == '\n') {
48*2810ac1bSKiyoung Kim 	    /* we're done */
49*2810ac1bSKiyoung Kim 	    break;
50*2810ac1bSKiyoung Kim 	}
51*2810ac1bSKiyoung Kim 
52*2810ac1bSKiyoung Kim 	/* move on... */
53*2810ac1bSKiyoung Kim 
54*2810ac1bSKiyoung Kim 	i -= j;
55*2810ac1bSKiyoung Kim 	buffer += j;
56*2810ac1bSKiyoung Kim     }
57*2810ac1bSKiyoung Kim 
58*2810ac1bSKiyoung Kim     /* <NUL> terminate */
59*2810ac1bSKiyoung Kim     buffer[0] = '\0';
60*2810ac1bSKiyoung Kim 
61*2810ac1bSKiyoung Kim     return (i < MAXCAP ? 0:-1);
62*2810ac1bSKiyoung Kim }
63*2810ac1bSKiyoung Kim 
main(int argc,char ** argv)64*2810ac1bSKiyoung Kim int main(int argc, char **argv)
65*2810ac1bSKiyoung Kim {
66*2810ac1bSKiyoung Kim     char buffer[MAXCAP+1];
67*2810ac1bSKiyoung Kim     int retval, quiet=0;
68*2810ac1bSKiyoung Kim     cap_t cap_d;
69*2810ac1bSKiyoung Kim 
70*2810ac1bSKiyoung Kim     if (argc < 3) {
71*2810ac1bSKiyoung Kim 	usage();
72*2810ac1bSKiyoung Kim     }
73*2810ac1bSKiyoung Kim 
74*2810ac1bSKiyoung Kim     while (--argc > 0) {
75*2810ac1bSKiyoung Kim 	const char *text;
76*2810ac1bSKiyoung Kim 	pid_t pid;
77*2810ac1bSKiyoung Kim 
78*2810ac1bSKiyoung Kim 	if (!strcmp(*++argv,"-q")) {
79*2810ac1bSKiyoung Kim 	    quiet = 1;
80*2810ac1bSKiyoung Kim 	    continue;
81*2810ac1bSKiyoung Kim 	}
82*2810ac1bSKiyoung Kim 	if (!strcmp(*argv,"-")) {
83*2810ac1bSKiyoung Kim 	    retval = read_caps(quiet, *argv, buffer);
84*2810ac1bSKiyoung Kim 	    if (retval)
85*2810ac1bSKiyoung Kim 		usage();
86*2810ac1bSKiyoung Kim 	    text = buffer;
87*2810ac1bSKiyoung Kim 	} else
88*2810ac1bSKiyoung Kim 	    text = *argv;
89*2810ac1bSKiyoung Kim 
90*2810ac1bSKiyoung Kim 	cap_d = cap_from_text(text);
91*2810ac1bSKiyoung Kim 	if (cap_d == NULL) {
92*2810ac1bSKiyoung Kim 	    perror("fatal error");
93*2810ac1bSKiyoung Kim 	    usage();
94*2810ac1bSKiyoung Kim 	}
95*2810ac1bSKiyoung Kim #ifndef DEBUG
96*2810ac1bSKiyoung Kim 	{
97*2810ac1bSKiyoung Kim 	    ssize_t length;
98*2810ac1bSKiyoung Kim 	    char *result;
99*2810ac1bSKiyoung Kim 
100*2810ac1bSKiyoung Kim 	    result = cap_to_text(cap_d, &length);
101*2810ac1bSKiyoung Kim 	    fprintf(stderr, "[caps set to:\n%s\n]\n", result);
102*2810ac1bSKiyoung Kim 	    cap_free(result);
103*2810ac1bSKiyoung Kim 	    result = NULL;
104*2810ac1bSKiyoung Kim 	}
105*2810ac1bSKiyoung Kim #endif
106*2810ac1bSKiyoung Kim 
107*2810ac1bSKiyoung Kim 	if (--argc <= 0)
108*2810ac1bSKiyoung Kim 	    usage();
109*2810ac1bSKiyoung Kim 
110*2810ac1bSKiyoung Kim 	pid = atoi(*++argv);
111*2810ac1bSKiyoung Kim 	retval = capsetp(pid, cap_d);
112*2810ac1bSKiyoung Kim 
113*2810ac1bSKiyoung Kim 	if (retval != 0) {
114*2810ac1bSKiyoung Kim 	    fprintf(stderr, "Failed to set cap's on process `%d': (%s)\n",
115*2810ac1bSKiyoung Kim 		    pid, strerror(errno));
116*2810ac1bSKiyoung Kim 	    usage();
117*2810ac1bSKiyoung Kim 	}
118*2810ac1bSKiyoung Kim #ifndef DEBUG
119*2810ac1bSKiyoung Kim 	fprintf(stderr, "[caps set on %d]\n", pid);
120*2810ac1bSKiyoung Kim #endif
121*2810ac1bSKiyoung Kim     }
122*2810ac1bSKiyoung Kim 
123*2810ac1bSKiyoung Kim     return 0;
124*2810ac1bSKiyoung Kim }
125