aboutsummaryrefslogtreecommitdiff
path: root/util-linux/setpriv.c
diff options
context:
space:
mode:
Diffstat (limited to 'util-linux/setpriv.c')
-rw-r--r--util-linux/setpriv.c152
1 files changed, 18 insertions, 134 deletions
diff --git a/util-linux/setpriv.c b/util-linux/setpriv.c
index 0f85428ab..12ab1bd66 100644
--- a/util-linux/setpriv.c
+++ b/util-linux/setpriv.c
@@ -5,7 +5,6 @@
5 * Copyright (C) 2017 by <assafgordon@gmail.com> 5 * Copyright (C) 2017 by <assafgordon@gmail.com>
6 * 6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8 *
9 */ 8 */
10//config:config SETPRIV 9//config:config SETPRIV
11//config: bool "setpriv (3.4 kb)" 10//config: bool "setpriv (3.4 kb)"
@@ -125,96 +124,10 @@ enum {
125}; 124};
126 125
127#if ENABLE_FEATURE_SETPRIV_CAPABILITIES 126#if ENABLE_FEATURE_SETPRIV_CAPABILITIES
128struct caps { 127DEFINE_STRUCT_CAPS;
129 struct __user_cap_header_struct header;
130 cap_user_data_t data;
131 int u32s;
132};
133
134# if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES
135static const char *const capabilities[] = {
136 "chown",
137 "dac_override",
138 "dac_read_search",
139 "fowner",
140 "fsetid",
141 "kill",
142 "setgid",
143 "setuid",
144 "setpcap",
145 "linux_immutable",
146 "net_bind_service",
147 "net_broadcast",
148 "net_admin",
149 "net_raw",
150 "ipc_lock",
151 "ipc_owner",
152 "sys_module",
153 "sys_rawio",
154 "sys_chroot",
155 "sys_ptrace",
156 "sys_pacct",
157 "sys_admin",
158 "sys_boot",
159 "sys_nice",
160 "sys_resource",
161 "sys_time",
162 "sys_tty_config",
163 "mknod",
164 "lease",
165 "audit_write",
166 "audit_control",
167 "setfcap",
168 "mac_override",
169 "mac_admin",
170 "syslog",
171 "wake_alarm",
172 "block_suspend",
173 "audit_read",
174};
175# endif /* FEATURE_SETPRIV_CAPABILITY_NAMES */
176 128
177static void getcaps(struct caps *caps) 129static unsigned parse_cap(const char *cap)
178{ 130{
179 static const uint8_t versions[] = {
180 _LINUX_CAPABILITY_U32S_3, /* = 2 (fits into byte) */
181 _LINUX_CAPABILITY_U32S_2, /* = 2 */
182 _LINUX_CAPABILITY_U32S_1, /* = 1 */
183 };
184 int i;
185
186 caps->header.pid = 0;
187 for (i = 0; i < ARRAY_SIZE(versions); i++) {
188 caps->header.version = versions[i];
189 if (capget(&caps->header, NULL) == 0)
190 goto got_it;
191 }
192 bb_simple_perror_msg_and_die("capget");
193 got_it:
194
195 switch (caps->header.version) {
196 case _LINUX_CAPABILITY_VERSION_1:
197 caps->u32s = _LINUX_CAPABILITY_U32S_1;
198 break;
199 case _LINUX_CAPABILITY_VERSION_2:
200 caps->u32s = _LINUX_CAPABILITY_U32S_2;
201 break;
202 case _LINUX_CAPABILITY_VERSION_3:
203 caps->u32s = _LINUX_CAPABILITY_U32S_3;
204 break;
205 default:
206 bb_error_msg_and_die("unsupported capability version");
207 }
208
209 caps->data = xmalloc(sizeof(caps->data[0]) * caps->u32s);
210 if (capget(&caps->header, caps->data) < 0)
211 bb_simple_perror_msg_and_die("capget");
212}
213
214static void parse_cap(unsigned long *index, const char *cap)
215{
216 unsigned long i;
217
218 switch (cap[0]) { 131 switch (cap[0]) {
219 case '-': 132 case '-':
220 break; 133 break;
@@ -226,26 +139,7 @@ static void parse_cap(unsigned long *index, const char *cap)
226 } 139 }
227 140
228 cap++; 141 cap++;
229 if ((sscanf(cap, "cap_%lu", &i)) == 1) { 142 return cap_name_to_number(cap);
230 if (!cap_valid(i))
231 bb_error_msg_and_die("unsupported capability '%s'", cap);
232 *index = i;
233 return;
234 }
235
236# if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES
237 for (i = 0; i < ARRAY_SIZE(capabilities); i++) {
238 if (strcmp(capabilities[i], cap) != 0)
239 continue;
240
241 if (!cap_valid(i))
242 bb_error_msg_and_die("unsupported capability '%s'", cap);
243 *index = i;
244 return;
245 }
246# endif
247
248 bb_error_msg_and_die("unknown capability '%s'", cap);
249} 143}
250 144
251static void set_inh_caps(char *capstring) 145static void set_inh_caps(char *capstring)
@@ -256,11 +150,11 @@ static void set_inh_caps(char *capstring)
256 150
257 capstring = strtok(capstring, ","); 151 capstring = strtok(capstring, ",");
258 while (capstring) { 152 while (capstring) {
259 unsigned long cap; 153 unsigned cap;
260 154
261 parse_cap(&cap, capstring); 155 cap = parse_cap(capstring);
262 if (CAP_TO_INDEX(cap) >= caps.u32s) 156 if (CAP_TO_INDEX(cap) >= caps.u32s)
263 bb_error_msg_and_die("invalid capability cap"); 157 bb_error_msg_and_die("invalid capability '%s'", capstring);
264 158
265 if (capstring[0] == '+') 159 if (capstring[0] == '+')
266 caps.data[CAP_TO_INDEX(cap)].inheritable |= CAP_TO_MASK(cap); 160 caps.data[CAP_TO_INDEX(cap)].inheritable |= CAP_TO_MASK(cap);
@@ -269,11 +163,8 @@ static void set_inh_caps(char *capstring)
269 capstring = strtok(NULL, ","); 163 capstring = strtok(NULL, ",");
270 } 164 }
271 165
272 if ((capset(&caps.header, caps.data)) < 0) 166 if (capset(&caps.header, caps.data) != 0)
273 bb_perror_msg_and_die("capset"); 167 bb_perror_msg_and_die("capset");
274
275 if (ENABLE_FEATURE_CLEAN_UP)
276 free(caps.data);
277} 168}
278 169
279static void set_ambient_caps(char *string) 170static void set_ambient_caps(char *string)
@@ -282,9 +173,9 @@ static void set_ambient_caps(char *string)
282 173
283 cap = strtok(string, ","); 174 cap = strtok(string, ",");
284 while (cap) { 175 while (cap) {
285 unsigned long index; 176 unsigned index;
286 177
287 parse_cap(&index, cap); 178 index = parse_cap(cap);
288 if (cap[0] == '+') { 179 if (cap[0] == '+') {
289 if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, index, 0, 0) < 0) 180 if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, index, 0, 0) < 0)
290 bb_perror_msg("cap_ambient_raise"); 181 bb_perror_msg("cap_ambient_raise");
@@ -298,16 +189,7 @@ static void set_ambient_caps(char *string)
298#endif /* FEATURE_SETPRIV_CAPABILITIES */ 189#endif /* FEATURE_SETPRIV_CAPABILITIES */
299 190
300#if ENABLE_FEATURE_SETPRIV_DUMP 191#if ENABLE_FEATURE_SETPRIV_DUMP
301# if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES 192# if !ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES
302static void printf_cap(const char *pfx, unsigned cap_no)
303{
304 if (cap_no < ARRAY_SIZE(capabilities)) {
305 printf("%s%s", pfx, capabilities[cap_no]);
306 return;
307 }
308 printf("%scap_%u", pfx, cap_no);
309}
310# else
311# define printf_cap(pfx, cap_no) printf("%scap_%u", (pfx), (cap_no)) 193# define printf_cap(pfx, cap_no) printf("%scap_%u", (pfx), (cap_no))
312# endif 194# endif
313 195
@@ -396,10 +278,9 @@ static int dump(void)
396 bb_putchar('\n'); 278 bb_putchar('\n');
397# endif 279# endif
398 280
399 if (ENABLE_FEATURE_CLEAN_UP) { 281 if (ENABLE_FEATURE_CLEAN_UP)
400 IF_FEATURE_SETPRIV_CAPABILITIES(free(caps.data);)
401 free(gids); 282 free(gids);
402 } 283
403 return EXIT_SUCCESS; 284 return EXIT_SUCCESS;
404} 285}
405#endif /* FEATURE_SETPRIV_DUMP */ 286#endif /* FEATURE_SETPRIV_DUMP */
@@ -421,9 +302,12 @@ int setpriv_main(int argc UNUSED_PARAM, char **argv)
421 int opts; 302 int opts;
422 IF_FEATURE_SETPRIV_CAPABILITIES(char *inh_caps, *ambient_caps;) 303 IF_FEATURE_SETPRIV_CAPABILITIES(char *inh_caps, *ambient_caps;)
423 304
424 applet_long_options = setpriv_longopts; 305 opts = getopt32long(argv, "+"
425 opts = getopt32(argv, "+"IF_FEATURE_SETPRIV_DUMP("d") 306 IF_FEATURE_SETPRIV_DUMP("d")
426 IF_FEATURE_SETPRIV_CAPABILITIES("\xfe:\xfd:", &inh_caps, &ambient_caps)); 307 IF_FEATURE_SETPRIV_CAPABILITIES("\xfe:\xfd:"),
308 setpriv_longopts
309 IF_FEATURE_SETPRIV_CAPABILITIES(, &inh_caps, &ambient_caps)
310 );
427 argv += optind; 311 argv += optind;
428 312
429#if ENABLE_FEATURE_SETPRIV_DUMP 313#if ENABLE_FEATURE_SETPRIV_DUMP