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