diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-07 16:00:07 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-07 16:00:07 +0200 |
| commit | cf5748cc892f78c004359ed321bf72bc8e3772ac (patch) | |
| tree | 0771d776e0244861f22e7ebc00c21253f9740b2d /util-linux | |
| parent | 6842d00cebef368a4ade9c9cd3dc92804b84c88d (diff) | |
| download | busybox-w32-cf5748cc892f78c004359ed321bf72bc8e3772ac.tar.gz busybox-w32-cf5748cc892f78c004359ed321bf72bc8e3772ac.tar.bz2 busybox-w32-cf5748cc892f78c004359ed321bf72bc8e3772ac.zip | |
setpriv: code shrink, and grouping capability code together
function old new delta
static.versions - 3 +3
getcaps 174 149 -25
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'util-linux')
| -rw-r--r-- | util-linux/setpriv.c | 187 |
1 files changed, 91 insertions, 96 deletions
diff --git a/util-linux/setpriv.c b/util-linux/setpriv.c index 8d9c218a3..dc83549ba 100644 --- a/util-linux/setpriv.c +++ b/util-linux/setpriv.c | |||
| @@ -124,7 +124,7 @@ struct caps { | |||
| 124 | int u32s; | 124 | int u32s; |
| 125 | }; | 125 | }; |
| 126 | 126 | ||
| 127 | #if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES | 127 | # if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES |
| 128 | static const char *const capabilities[] = { | 128 | static const char *const capabilities[] = { |
| 129 | "chown", | 129 | "chown", |
| 130 | "dac_override", | 130 | "dac_override", |
| @@ -165,17 +165,14 @@ static const char *const capabilities[] = { | |||
| 165 | "block_suspend", | 165 | "block_suspend", |
| 166 | "audit_read", | 166 | "audit_read", |
| 167 | }; | 167 | }; |
| 168 | #endif /* FEATURE_SETPRIV_CAPABILITY_NAMES */ | 168 | # endif /* FEATURE_SETPRIV_CAPABILITY_NAMES */ |
| 169 | |||
| 170 | #endif /* FEATURE_SETPRIV_CAPABILITIES */ | ||
| 171 | 169 | ||
| 172 | #if ENABLE_FEATURE_SETPRIV_CAPABILITIES | ||
| 173 | static void getcaps(struct caps *caps) | 170 | static void getcaps(struct caps *caps) |
| 174 | { | 171 | { |
| 175 | int versions[] = { | 172 | static const uint8_t versions[] = { |
| 176 | _LINUX_CAPABILITY_U32S_3, | 173 | _LINUX_CAPABILITY_U32S_3, /* = 2 (fits into byte) */ |
| 177 | _LINUX_CAPABILITY_U32S_2, | 174 | _LINUX_CAPABILITY_U32S_2, /* = 2 */ |
| 178 | _LINUX_CAPABILITY_U32S_1, | 175 | _LINUX_CAPABILITY_U32S_1, /* = 1 */ |
| 179 | }; | 176 | }; |
| 180 | int i; | 177 | int i; |
| 181 | 178 | ||
| @@ -206,6 +203,91 @@ static void getcaps(struct caps *caps) | |||
| 206 | if (capget(&caps->header, caps->data) < 0) | 203 | if (capget(&caps->header, caps->data) < 0) |
| 207 | bb_simple_perror_msg_and_die("capget"); | 204 | bb_simple_perror_msg_and_die("capget"); |
| 208 | } | 205 | } |
| 206 | |||
| 207 | static void parse_cap(unsigned long *index, const char *cap) | ||
| 208 | { | ||
| 209 | unsigned long i; | ||
| 210 | |||
| 211 | switch (cap[0]) { | ||
| 212 | case '-': | ||
| 213 | break; | ||
| 214 | case '+': | ||
| 215 | break; | ||
| 216 | default: | ||
| 217 | bb_error_msg_and_die("invalid capability '%s'", cap); | ||
| 218 | break; | ||
| 219 | } | ||
| 220 | |||
| 221 | cap++; | ||
| 222 | if ((sscanf(cap, "cap_%lu", &i)) == 1) { | ||
| 223 | if (!cap_valid(i)) | ||
| 224 | bb_error_msg_and_die("unsupported capability '%s'", cap); | ||
| 225 | *index = i; | ||
| 226 | return; | ||
| 227 | } | ||
| 228 | |||
| 229 | # if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES | ||
| 230 | for (i = 0; i < ARRAY_SIZE(capabilities); i++) { | ||
| 231 | if (strcmp(capabilities[i], cap) != 0) | ||
| 232 | continue; | ||
| 233 | |||
| 234 | if (!cap_valid(i)) | ||
| 235 | bb_error_msg_and_die("unsupported capability '%s'", cap); | ||
| 236 | *index = i; | ||
| 237 | return; | ||
| 238 | } | ||
| 239 | # endif | ||
| 240 | |||
| 241 | bb_error_msg_and_die("unknown capability '%s'", cap); | ||
| 242 | } | ||
| 243 | |||
| 244 | static void set_inh_caps(char *capstring) | ||
| 245 | { | ||
| 246 | struct caps caps; | ||
| 247 | |||
| 248 | getcaps(&caps); | ||
| 249 | |||
| 250 | capstring = strtok(capstring, ","); | ||
| 251 | while (capstring) { | ||
| 252 | unsigned long cap; | ||
| 253 | |||
| 254 | parse_cap(&cap, capstring); | ||
| 255 | if (CAP_TO_INDEX(cap) >= caps.u32s) | ||
| 256 | bb_error_msg_and_die("invalid capability cap"); | ||
| 257 | |||
| 258 | if (capstring[0] == '+') | ||
| 259 | caps.data[CAP_TO_INDEX(cap)].inheritable |= CAP_TO_MASK(cap); | ||
| 260 | else | ||
| 261 | caps.data[CAP_TO_INDEX(cap)].inheritable &= ~CAP_TO_MASK(cap); | ||
| 262 | capstring = strtok(NULL, ","); | ||
| 263 | } | ||
| 264 | |||
| 265 | if ((capset(&caps.header, caps.data)) < 0) | ||
| 266 | bb_perror_msg_and_die("capset"); | ||
| 267 | |||
| 268 | if (ENABLE_FEATURE_CLEAN_UP) | ||
| 269 | free(caps.data); | ||
| 270 | } | ||
| 271 | |||
| 272 | static void set_ambient_caps(char *string) | ||
| 273 | { | ||
| 274 | char *cap; | ||
| 275 | |||
| 276 | cap = strtok(string, ","); | ||
| 277 | while (cap) { | ||
| 278 | unsigned long index; | ||
| 279 | |||
| 280 | parse_cap(&index, cap); | ||
| 281 | if (cap[0] == '+') { | ||
| 282 | if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, index, 0, 0) < 0) | ||
| 283 | bb_perror_msg("cap_ambient_raise"); | ||
| 284 | } else { | ||
| 285 | if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, index, 0, 0) < 0) | ||
| 286 | bb_perror_msg("cap_ambient_lower"); | ||
| 287 | } | ||
| 288 | cap = strtok(NULL, ","); | ||
| 289 | } | ||
| 290 | } | ||
| 209 | #endif /* FEATURE_SETPRIV_CAPABILITIES */ | 291 | #endif /* FEATURE_SETPRIV_CAPABILITIES */ |
| 210 | 292 | ||
| 211 | #if ENABLE_FEATURE_SETPRIV_DUMP | 293 | #if ENABLE_FEATURE_SETPRIV_DUMP |
| @@ -317,93 +399,6 @@ static int dump(void) | |||
| 317 | } | 399 | } |
| 318 | #endif /* FEATURE_SETPRIV_DUMP */ | 400 | #endif /* FEATURE_SETPRIV_DUMP */ |
| 319 | 401 | ||
| 320 | #if ENABLE_FEATURE_SETPRIV_CAPABILITIES | ||
| 321 | static void parse_cap(unsigned long *index, const char *cap) | ||
| 322 | { | ||
| 323 | unsigned long i; | ||
| 324 | |||
| 325 | switch (cap[0]) { | ||
| 326 | case '-': | ||
| 327 | break; | ||
| 328 | case '+': | ||
| 329 | break; | ||
| 330 | default: | ||
| 331 | bb_error_msg_and_die("invalid capability '%s'", cap); | ||
| 332 | break; | ||
| 333 | } | ||
| 334 | |||
| 335 | cap++; | ||
| 336 | if ((sscanf(cap, "cap_%lu", &i)) == 1) { | ||
| 337 | if (!cap_valid(i)) | ||
| 338 | bb_error_msg_and_die("unsupported capability '%s'", cap); | ||
| 339 | *index = i; | ||
| 340 | return; | ||
| 341 | } | ||
| 342 | |||
| 343 | # if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES | ||
| 344 | for (i = 0; i < ARRAY_SIZE(capabilities); i++) { | ||
| 345 | if (strcmp(capabilities[i], cap) != 0) | ||
| 346 | continue; | ||
| 347 | |||
| 348 | if (!cap_valid(i)) | ||
| 349 | bb_error_msg_and_die("unsupported capability '%s'", cap); | ||
| 350 | *index = i; | ||
| 351 | return; | ||
| 352 | } | ||
| 353 | # endif | ||
| 354 | |||
| 355 | bb_error_msg_and_die("unknown capability '%s'", cap); | ||
| 356 | } | ||
| 357 | |||
| 358 | static void set_inh_caps(char *capstring) | ||
| 359 | { | ||
| 360 | struct caps caps; | ||
| 361 | |||
| 362 | getcaps(&caps); | ||
| 363 | |||
| 364 | capstring = strtok(capstring, ","); | ||
| 365 | while (capstring) { | ||
| 366 | unsigned long cap; | ||
| 367 | |||
| 368 | parse_cap(&cap, capstring); | ||
| 369 | if (CAP_TO_INDEX(cap) >= caps.u32s) | ||
| 370 | bb_error_msg_and_die("invalid capability cap"); | ||
| 371 | |||
| 372 | if (capstring[0] == '+') | ||
| 373 | caps.data[CAP_TO_INDEX(cap)].inheritable |= CAP_TO_MASK(cap); | ||
| 374 | else | ||
| 375 | caps.data[CAP_TO_INDEX(cap)].inheritable &= ~CAP_TO_MASK(cap); | ||
| 376 | capstring = strtok(NULL, ","); | ||
| 377 | } | ||
| 378 | |||
| 379 | if ((capset(&caps.header, caps.data)) < 0) | ||
| 380 | bb_perror_msg_and_die("capset"); | ||
| 381 | |||
| 382 | if (ENABLE_FEATURE_CLEAN_UP) | ||
| 383 | free(caps.data); | ||
| 384 | } | ||
| 385 | |||
| 386 | static void set_ambient_caps(char *string) | ||
| 387 | { | ||
| 388 | char *cap; | ||
| 389 | |||
| 390 | cap = strtok(string, ","); | ||
| 391 | while (cap) { | ||
| 392 | unsigned long index; | ||
| 393 | |||
| 394 | parse_cap(&index, cap); | ||
| 395 | if (cap[0] == '+') { | ||
| 396 | if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, index, 0, 0) < 0) | ||
| 397 | bb_perror_msg("cap_ambient_raise"); | ||
| 398 | } else { | ||
| 399 | if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, index, 0, 0) < 0) | ||
| 400 | bb_perror_msg("cap_ambient_lower"); | ||
| 401 | } | ||
| 402 | cap = strtok(NULL, ","); | ||
| 403 | } | ||
| 404 | } | ||
| 405 | #endif /* FEATURE_SETPRIV_CAPABILITIES */ | ||
| 406 | |||
| 407 | int setpriv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 402 | int setpriv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 408 | int setpriv_main(int argc UNUSED_PARAM, char **argv) | 403 | int setpriv_main(int argc UNUSED_PARAM, char **argv) |
| 409 | { | 404 | { |
