aboutsummaryrefslogtreecommitdiff
path: root/libbb/appletlib.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-05-16 00:01:08 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-05-16 00:01:08 +0200
commit4566e172eb2423bdcec68babde907cd06e8fc997 (patch)
tree697f14694d44908670baa221d20b311c4d7294e0 /libbb/appletlib.c
parente0238f852b7a492581414b5aecb8a438f2fc4c77 (diff)
downloadbusybox-w32-4566e172eb2423bdcec68babde907cd06e8fc997.tar.gz
busybox-w32-4566e172eb2423bdcec68babde907cd06e8fc997.tar.bz2
busybox-w32-4566e172eb2423bdcec68babde907cd06e8fc997.zip
simplify parsing of /etc/busybox.conf
function old new delta parse_config_file 799 667 -132 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb/appletlib.c')
-rw-r--r--libbb/appletlib.c75
1 files changed, 30 insertions, 45 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 705829cb0..03f712821 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -236,8 +236,7 @@ IF_FEATURE_SUID(static uid_t ruid;) /* real uid */
236/* applets[] is const, so we have to define this "override" structure */ 236/* applets[] is const, so we have to define this "override" structure */
237static struct BB_suid_config { 237static struct BB_suid_config {
238 int m_applet; 238 int m_applet;
239 uid_t m_uid; 239 struct bb_uidgid_t m_ugid;
240 gid_t m_gid;
241 mode_t m_mode; 240 mode_t m_mode;
242 struct BB_suid_config *m_next; 241 struct BB_suid_config *m_next;
243} *suid_config; 242} *suid_config;
@@ -295,8 +294,6 @@ static const unsigned short mode_mask[] ALIGN2 = {
295 0, S_IXOTH, S_IXOTH, 0 /* other */ 294 0, S_IXOTH, S_IXOTH, 0 /* other */
296}; 295};
297 296
298#define parse_error(x) do { errmsg = x; goto pe_label; } while (0)
299
300static void parse_config_file(void) 297static void parse_config_file(void)
301{ 298{
302 struct BB_suid_config *sct_head; 299 struct BB_suid_config *sct_head;
@@ -312,8 +309,6 @@ static void parse_config_file(void)
312 char buffer[256]; 309 char buffer[256];
313 struct stat st; 310 struct stat st;
314 311
315 assert(!suid_config); /* Should be set to NULL by bss init. */
316
317 ruid = getuid(); 312 ruid = getuid();
318 if (ruid == 0) /* run by root - don't need to even read config file */ 313 if (ruid == 0) /* run by root - don't need to even read config file */
319 return; 314 return;
@@ -322,7 +317,7 @@ static void parse_config_file(void)
322 || !S_ISREG(st.st_mode) /* Not a regular file? */ 317 || !S_ISREG(st.st_mode) /* Not a regular file? */
323 || (st.st_uid != 0) /* Not owned by root? */ 318 || (st.st_uid != 0) /* Not owned by root? */
324 || (st.st_mode & (S_IWGRP | S_IWOTH)) /* Writable by non-root? */ 319 || (st.st_mode & (S_IWGRP | S_IWOTH)) /* Writable by non-root? */
325 || !(f = fopen_for_read(config_file)) /* Cannot open? */ 320 || !(f = fopen_for_read(config_file)) /* Cannot open? */
326 ) { 321 ) {
327 return; 322 return;
328 } 323 }
@@ -335,10 +330,11 @@ static void parse_config_file(void)
335 s = buffer; 330 s = buffer;
336 331
337 if (!fgets(s, sizeof(buffer), f)) { /* Are we done? */ 332 if (!fgets(s, sizeof(buffer), f)) { /* Are we done? */
338// why? 333 // Looks like bloat
339 if (ferror(f)) { /* Make sure it wasn't a read error. */ 334 //if (ferror(f)) { /* Make sure it wasn't a read error. */
340 parse_error("reading"); 335 // errmsg = "reading";
341 } 336 // goto pe_label;
337 //}
342 fclose(f); 338 fclose(f);
343 suid_config = sct_head; /* Success, so set the pointer. */ 339 suid_config = sct_head; /* Success, so set the pointer. */
344 return; 340 return;
@@ -355,7 +351,8 @@ static void parse_config_file(void)
355 * we do err on the side of caution. Besides, the line would be 351 * we do err on the side of caution. Besides, the line would be
356 * too long if it did end with a newline. */ 352 * too long if it did end with a newline. */
357 if (!strchr(s, '\n') && !feof(f)) { 353 if (!strchr(s, '\n') && !feof(f)) {
358 parse_error("line too long"); 354 errmsg = "line too long";
355 goto pe_label;
359 } 356 }
360 357
361 /* Trim leading and trailing whitespace, ignoring comments, and 358 /* Trim leading and trailing whitespace, ignoring comments, and
@@ -376,7 +373,8 @@ static void parse_config_file(void)
376 || e[1] /* Trailing characters? */ 373 || e[1] /* Trailing characters? */
377 || !*(s = get_trimmed_slice(s+1, e)) /* Missing name? */ 374 || !*(s = get_trimmed_slice(s+1, e)) /* Missing name? */
378 ) { 375 ) {
379 parse_error("section header"); 376 errmsg = "section header";
377 goto pe_label;
380 } 378 }
381 /* Right now we only have one section so just check it. 379 /* Right now we only have one section so just check it.
382 * If more sections are added in the future, please don't 380 * If more sections are added in the future, please don't
@@ -406,7 +404,8 @@ static void parse_config_file(void)
406 s = get_trimmed_slice(s, e); 404 s = get_trimmed_slice(s, e);
407 } 405 }
408 if (!e || !*s) { /* Missing '=' or empty key. */ 406 if (!e || !*s) { /* Missing '=' or empty key. */
409 parse_error("keyword"); 407 errmsg = "keyword";
408 goto pe_label;
410 } 409 }
411 410
412 /* Ok, we have an applet name. Process the rhs if this 411 /* Ok, we have an applet name. Process the rhs if this
@@ -419,9 +418,9 @@ static void parse_config_file(void)
419 * The last config line for each applet will be the 418 * The last config line for each applet will be the
420 * one used since we insert at the head of the list. 419 * one used since we insert at the head of the list.
421 * I suppose this could be considered a feature. */ 420 * I suppose this could be considered a feature. */
422 sct = xmalloc(sizeof(struct BB_suid_config)); 421 sct = xzalloc(sizeof(*sct));
423 sct->m_applet = applet_no; 422 sct->m_applet = applet_no;
424 sct->m_mode = 0; 423 /*sct->m_mode = 0;*/
425 sct->m_next = sct_head; 424 sct->m_next = sct_head;
426 sct_head = sct; 425 sct_head = sct;
427 426
@@ -436,7 +435,8 @@ static void parse_config_file(void)
436 const char *q; 435 const char *q;
437 q = strchrnul(mode_chars + 5*i, *e++); 436 q = strchrnul(mode_chars + 5*i, *e++);
438 if (!*q) { 437 if (!*q) {
439 parse_error("mode"); 438 errmsg = "mode";
439 goto pe_label;
440 } 440 }
441 /* Adjust by -i to account for nul. */ 441 /* Adjust by -i to account for nul. */
442 sct->m_mode |= mode_mask[(q - mode_chars) - i]; 442 sct->m_mode |= mode_mask[(q - mode_chars) - i];
@@ -449,29 +449,14 @@ static void parse_config_file(void)
449 /* Note: we require whitespace between the mode and the 449 /* Note: we require whitespace between the mode and the
450 * user/group info. */ 450 * user/group info. */
451 if ((s == e) || !(e = strchr(s, '.'))) { 451 if ((s == e) || !(e = strchr(s, '.'))) {
452 parse_error("<uid>.<gid>"); 452 errmsg = "uid.gid";
453 } 453 goto pe_label;
454 *e++ = '\0';
455
456 /* We can't use get_ug_id here since it would exit()
457 * if a uid or gid was not found. Oh well... */
458 sct->m_uid = bb_strtoul(s, NULL, 10);
459 if (errno) {
460 struct passwd *pwd = getpwnam(s);
461 if (!pwd) {
462 parse_error("user");
463 }
464 sct->m_uid = pwd->pw_uid;
465 } 454 }
466 455
467 sct->m_gid = bb_strtoul(e, NULL, 10); 456 *e++ = ':'; /* get_uidgid doesn't understand user.group */
468 if (errno) { 457 if (get_uidgid(&sct->m_ugid, s, /*allow_numeric:*/ 1) == 0) {
469 struct group *grp; 458 errmsg = "unknown user/group";
470 grp = getgrnam(e); 459 goto pe_label;
471 if (!grp) {
472 parse_error("group");
473 }
474 sct->m_gid = grp->gr_gid;
475 } 460 }
476 } 461 }
477 continue; 462 continue;
@@ -485,14 +470,14 @@ static void parse_config_file(void)
485 * We may want to simply ignore such lines in case they 470 * We may want to simply ignore such lines in case they
486 * are used in some future version of busybox. */ 471 * are used in some future version of busybox. */
487 if (!section) { 472 if (!section) {
488 parse_error("keyword outside section"); 473 errmsg = "keyword outside section";
474 goto pe_label;
489 } 475 }
490 476
491 } /* while (1) */ 477 } /* while (1) */
492 478
493 pe_label: 479 pe_label:
494 fprintf(stderr, "Parse error in %s, line %d: %s\n", 480 bb_error_msg("parse error in %s, line %u: %s", config_file, lc, errmsg);
495 config_file, lc, errmsg);
496 481
497 fclose(f); 482 fclose(f);
498 /* Release any allocated memory before returning. */ 483 /* Release any allocated memory before returning. */
@@ -532,10 +517,10 @@ static void check_suid(int applet_no)
532 goto check_need_suid; 517 goto check_need_suid;
533 found: 518 found:
534 m = sct->m_mode; 519 m = sct->m_mode;
535 if (sct->m_uid == ruid) 520 if (sct->m_ugid.uid == ruid)
536 /* same uid */ 521 /* same uid */
537 m >>= 6; 522 m >>= 6;
538 else if ((sct->m_gid == rgid) || ingroup(ruid, sct->m_gid)) 523 else if ((sct->m_ugid.gid == rgid) || ingroup(ruid, sct->m_ugid.gid))
539 /* same group / in group */ 524 /* same group / in group */
540 m >>= 3; 525 m >>= 3;
541 526
@@ -544,7 +529,7 @@ static void check_suid(int applet_no)
544 529
545 /* _both_ sgid and group_exec have to be set for setegid */ 530 /* _both_ sgid and group_exec have to be set for setegid */
546 if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) 531 if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
547 rgid = sct->m_gid; 532 rgid = sct->m_ugid.gid;
548 /* else (no setegid) we will set egid = rgid */ 533 /* else (no setegid) we will set egid = rgid */
549 534
550 /* We set effective AND saved ids. If saved-id is not set 535 /* We set effective AND saved ids. If saved-id is not set
@@ -555,7 +540,7 @@ static void check_suid(int applet_no)
555 /* do we have to set effective uid? */ 540 /* do we have to set effective uid? */
556 uid = ruid; 541 uid = ruid;
557 if (sct->m_mode & S_ISUID) 542 if (sct->m_mode & S_ISUID)
558 uid = sct->m_uid; 543 uid = sct->m_ugid.uid;
559 /* else (no seteuid) we will set euid = ruid */ 544 /* else (no seteuid) we will set euid = ruid */
560 545
561 if (setresuid(-1, uid, uid)) 546 if (setresuid(-1, uid, uid))