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