Convert ldap results into a sudoers userspec so we can use the "sudo

-l" output functions in parse.c.
This commit is contained in:
Todd C. Miller
2018-02-09 18:21:01 -07:00
parent 787717755b
commit 4e2402a8e4
5 changed files with 489 additions and 358 deletions

View File

@@ -667,7 +667,7 @@ short *yysslim;
YYSTYPE *yyvs; YYSTYPE *yyvs;
unsigned int yystacksize; unsigned int yystacksize;
int yyparse(void); int yyparse(void);
#line 898 "gram.y" #line 899 "gram.y"
void void
sudoerserror(const char *s) sudoerserror(const char *s)
{ {
@@ -866,12 +866,13 @@ free_members(struct member_list *members)
void void
free_userspec(struct userspec *us) free_userspec(struct userspec *us)
{ {
struct privilege *priv, *next; struct privilege *priv;
free_members(&us->users); free_members(&us->users);
TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, next) { while ((priv = TAILQ_FIRST(&us->privileges)) != NULL) {
struct member_list *runasuserlist = NULL, *runasgrouplist = NULL; struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
struct cmndspec *cs, *cs_next; struct cmndspec *cs;
struct defaults *def;
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
char *role = NULL, *type = NULL; char *role = NULL, *type = NULL;
#endif /* HAVE_SELINUX */ #endif /* HAVE_SELINUX */
@@ -879,8 +880,11 @@ free_userspec(struct userspec *us)
char *privs = NULL, *limitprivs = NULL; char *privs = NULL, *limitprivs = NULL;
#endif /* HAVE_PRIV_SET */ #endif /* HAVE_PRIV_SET */
TAILQ_REMOVE(&us->privileges, priv, entries);
free(priv->ldap_role);
free_members(&priv->hostlist); free_members(&priv->hostlist);
TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, cs_next) { while ((cs = TAILQ_FIRST(&priv->cmndlist)) != NULL) {
TAILQ_REMOVE(&priv->cmndlist, cs, entries);
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
/* Only free the first instance of a role/type. */ /* Only free the first instance of a role/type. */
if (cs->role != role) { if (cs->role != role) {
@@ -917,6 +921,12 @@ free_userspec(struct userspec *us)
free_member(cs->cmnd); free_member(cs->cmnd);
free(cs); free(cs);
} }
while ((def = TAILQ_FIRST(&priv->defaults)) != NULL) {
TAILQ_REMOVE(&priv->defaults, def, entries);
free(def->var);
free(def->val);
free(def);
}
free(priv); free(priv);
} }
rcstr_delref(us->file); rcstr_delref(us->file);
@@ -1000,7 +1010,7 @@ init_options(struct command_options *opts)
opts->limitprivs = NULL; opts->limitprivs = NULL;
#endif #endif
} }
#line 951 "gram.c" #line 961 "gram.c"
/* allocate initial stack or double stack size, up to YYMAXDEPTH */ /* allocate initial stack or double stack size, up to YYMAXDEPTH */
#if defined(__cplusplus) || defined(__STDC__) #if defined(__cplusplus) || defined(__STDC__)
static int yygrowstack(void) static int yygrowstack(void)
@@ -1364,6 +1374,7 @@ case 26:
sudoerserror(N_("unable to allocate memory")); sudoerserror(N_("unable to allocate memory"));
YYERROR; YYERROR;
} }
TAILQ_INIT(&p->defaults);
HLTQ_TO_TAILQ(&p->hostlist, yyvsp[-2].member, entries); HLTQ_TO_TAILQ(&p->hostlist, yyvsp[-2].member, entries);
HLTQ_TO_TAILQ(&p->cmndlist, yyvsp[0].cmndspec, entries); HLTQ_TO_TAILQ(&p->cmndlist, yyvsp[0].cmndspec, entries);
HLTQ_INIT(p, entries); HLTQ_INIT(p, entries);
@@ -1371,21 +1382,21 @@ case 26:
} }
break; break;
case 27: case 27:
#line 293 "gram.y" #line 294 "gram.y"
{ {
yyval.member = yyvsp[0].member; yyval.member = yyvsp[0].member;
yyval.member->negated = false; yyval.member->negated = false;
} }
break; break;
case 28: case 28:
#line 297 "gram.y" #line 298 "gram.y"
{ {
yyval.member = yyvsp[0].member; yyval.member = yyvsp[0].member;
yyval.member->negated = true; yyval.member->negated = true;
} }
break; break;
case 29: case 29:
#line 303 "gram.y" #line 304 "gram.y"
{ {
yyval.member = new_member(yyvsp[0].string, ALIAS); yyval.member = new_member(yyvsp[0].string, ALIAS);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -1395,7 +1406,7 @@ case 29:
} }
break; break;
case 30: case 30:
#line 310 "gram.y" #line 311 "gram.y"
{ {
yyval.member = new_member(NULL, ALL); yyval.member = new_member(NULL, ALL);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -1405,7 +1416,7 @@ case 30:
} }
break; break;
case 31: case 31:
#line 317 "gram.y" #line 318 "gram.y"
{ {
yyval.member = new_member(yyvsp[0].string, NETGROUP); yyval.member = new_member(yyvsp[0].string, NETGROUP);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -1415,7 +1426,7 @@ case 31:
} }
break; break;
case 32: case 32:
#line 324 "gram.y" #line 325 "gram.y"
{ {
yyval.member = new_member(yyvsp[0].string, NTWKADDR); yyval.member = new_member(yyvsp[0].string, NTWKADDR);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -1425,7 +1436,7 @@ case 32:
} }
break; break;
case 33: case 33:
#line 331 "gram.y" #line 332 "gram.y"
{ {
yyval.member = new_member(yyvsp[0].string, WORD); yyval.member = new_member(yyvsp[0].string, WORD);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -1435,7 +1446,7 @@ case 33:
} }
break; break;
case 35: case 35:
#line 341 "gram.y" #line 342 "gram.y"
{ {
struct cmndspec *prev; struct cmndspec *prev;
prev = HLTQ_LAST(yyvsp[-2].cmndspec, cmndspec, entries); prev = HLTQ_LAST(yyvsp[-2].cmndspec, cmndspec, entries);
@@ -1489,7 +1500,7 @@ case 35:
} }
break; break;
case 36: case 36:
#line 394 "gram.y" #line 395 "gram.y"
{ {
struct cmndspec *cs = calloc(1, sizeof(*cs)); struct cmndspec *cs = calloc(1, sizeof(*cs));
if (cs == NULL) { if (cs == NULL) {
@@ -1541,7 +1552,7 @@ case 36:
} }
break; break;
case 37: case 37:
#line 445 "gram.y" #line 446 "gram.y"
{ {
yyval.digest = new_digest(SUDO_DIGEST_SHA224, yyvsp[0].string); yyval.digest = new_digest(SUDO_DIGEST_SHA224, yyvsp[0].string);
if (yyval.digest == NULL) { if (yyval.digest == NULL) {
@@ -1551,7 +1562,7 @@ case 37:
} }
break; break;
case 38: case 38:
#line 452 "gram.y" #line 453 "gram.y"
{ {
yyval.digest = new_digest(SUDO_DIGEST_SHA256, yyvsp[0].string); yyval.digest = new_digest(SUDO_DIGEST_SHA256, yyvsp[0].string);
if (yyval.digest == NULL) { if (yyval.digest == NULL) {
@@ -1561,7 +1572,7 @@ case 38:
} }
break; break;
case 39: case 39:
#line 459 "gram.y" #line 460 "gram.y"
{ {
yyval.digest = new_digest(SUDO_DIGEST_SHA384, yyvsp[0].string); yyval.digest = new_digest(SUDO_DIGEST_SHA384, yyvsp[0].string);
if (yyval.digest == NULL) { if (yyval.digest == NULL) {
@@ -1571,7 +1582,7 @@ case 39:
} }
break; break;
case 40: case 40:
#line 466 "gram.y" #line 467 "gram.y"
{ {
yyval.digest = new_digest(SUDO_DIGEST_SHA512, yyvsp[0].string); yyval.digest = new_digest(SUDO_DIGEST_SHA512, yyvsp[0].string);
if (yyval.digest == NULL) { if (yyval.digest == NULL) {
@@ -1581,13 +1592,13 @@ case 40:
} }
break; break;
case 41: case 41:
#line 475 "gram.y" #line 476 "gram.y"
{ {
yyval.member = yyvsp[0].member; yyval.member = yyvsp[0].member;
} }
break; break;
case 42: case 42:
#line 478 "gram.y" #line 479 "gram.y"
{ {
if (yyvsp[0].member->type != COMMAND) { if (yyvsp[0].member->type != COMMAND) {
sudoerserror(N_("a digest requires a path name")); sudoerserror(N_("a digest requires a path name"));
@@ -1599,75 +1610,75 @@ case 42:
} }
break; break;
case 43: case 43:
#line 489 "gram.y" #line 490 "gram.y"
{ {
yyval.member = yyvsp[0].member; yyval.member = yyvsp[0].member;
yyval.member->negated = false; yyval.member->negated = false;
} }
break; break;
case 44: case 44:
#line 493 "gram.y" #line 494 "gram.y"
{ {
yyval.member = yyvsp[0].member; yyval.member = yyvsp[0].member;
yyval.member->negated = true; yyval.member->negated = true;
} }
break; break;
case 45: case 45:
#line 499 "gram.y" #line 500 "gram.y"
{ {
yyval.string = yyvsp[0].string; yyval.string = yyvsp[0].string;
} }
break; break;
case 46: case 46:
#line 504 "gram.y" #line 505 "gram.y"
{ {
yyval.string = yyvsp[0].string; yyval.string = yyvsp[0].string;
} }
break; break;
case 47: case 47:
#line 508 "gram.y" #line 509 "gram.y"
{ {
yyval.string = yyvsp[0].string; yyval.string = yyvsp[0].string;
} }
break; break;
case 48: case 48:
#line 513 "gram.y" #line 514 "gram.y"
{ {
yyval.string = yyvsp[0].string; yyval.string = yyvsp[0].string;
} }
break; break;
case 49: case 49:
#line 518 "gram.y" #line 519 "gram.y"
{ {
yyval.string = yyvsp[0].string; yyval.string = yyvsp[0].string;
} }
break; break;
case 50: case 50:
#line 523 "gram.y" #line 524 "gram.y"
{ {
yyval.string = yyvsp[0].string; yyval.string = yyvsp[0].string;
} }
break; break;
case 51: case 51:
#line 527 "gram.y" #line 528 "gram.y"
{ {
yyval.string = yyvsp[0].string; yyval.string = yyvsp[0].string;
} }
break; break;
case 52: case 52:
#line 532 "gram.y" #line 533 "gram.y"
{ {
yyval.runas = NULL; yyval.runas = NULL;
} }
break; break;
case 53: case 53:
#line 535 "gram.y" #line 536 "gram.y"
{ {
yyval.runas = yyvsp[-1].runas; yyval.runas = yyvsp[-1].runas;
} }
break; break;
case 54: case 54:
#line 540 "gram.y" #line 541 "gram.y"
{ {
yyval.runas = calloc(1, sizeof(struct runascontainer)); yyval.runas = calloc(1, sizeof(struct runascontainer));
if (yyval.runas != NULL) { if (yyval.runas != NULL) {
@@ -1685,7 +1696,7 @@ case 54:
} }
break; break;
case 55: case 55:
#line 555 "gram.y" #line 556 "gram.y"
{ {
yyval.runas = calloc(1, sizeof(struct runascontainer)); yyval.runas = calloc(1, sizeof(struct runascontainer));
if (yyval.runas == NULL) { if (yyval.runas == NULL) {
@@ -1697,7 +1708,7 @@ case 55:
} }
break; break;
case 56: case 56:
#line 564 "gram.y" #line 565 "gram.y"
{ {
yyval.runas = calloc(1, sizeof(struct runascontainer)); yyval.runas = calloc(1, sizeof(struct runascontainer));
if (yyval.runas == NULL) { if (yyval.runas == NULL) {
@@ -1709,7 +1720,7 @@ case 56:
} }
break; break;
case 57: case 57:
#line 573 "gram.y" #line 574 "gram.y"
{ {
yyval.runas = calloc(1, sizeof(struct runascontainer)); yyval.runas = calloc(1, sizeof(struct runascontainer));
if (yyval.runas == NULL) { if (yyval.runas == NULL) {
@@ -1721,7 +1732,7 @@ case 57:
} }
break; break;
case 58: case 58:
#line 582 "gram.y" #line 583 "gram.y"
{ {
yyval.runas = calloc(1, sizeof(struct runascontainer)); yyval.runas = calloc(1, sizeof(struct runascontainer));
if (yyval.runas != NULL) { if (yyval.runas != NULL) {
@@ -1739,13 +1750,13 @@ case 58:
} }
break; break;
case 59: case 59:
#line 599 "gram.y" #line 600 "gram.y"
{ {
init_options(&yyval.options); init_options(&yyval.options);
} }
break; break;
case 60: case 60:
#line 602 "gram.y" #line 603 "gram.y"
{ {
yyval.options.notbefore = parse_gentime(yyvsp[0].string); yyval.options.notbefore = parse_gentime(yyvsp[0].string);
free(yyvsp[0].string); free(yyvsp[0].string);
@@ -1756,7 +1767,7 @@ case 60:
} }
break; break;
case 61: case 61:
#line 610 "gram.y" #line 611 "gram.y"
{ {
yyval.options.notafter = parse_gentime(yyvsp[0].string); yyval.options.notafter = parse_gentime(yyvsp[0].string);
free(yyvsp[0].string); free(yyvsp[0].string);
@@ -1767,7 +1778,7 @@ case 61:
} }
break; break;
case 62: case 62:
#line 618 "gram.y" #line 619 "gram.y"
{ {
yyval.options.timeout = parse_timeout(yyvsp[0].string); yyval.options.timeout = parse_timeout(yyvsp[0].string);
free(yyvsp[0].string); free(yyvsp[0].string);
@@ -1781,7 +1792,7 @@ case 62:
} }
break; break;
case 63: case 63:
#line 629 "gram.y" #line 630 "gram.y"
{ {
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
free(yyval.options.role); free(yyval.options.role);
@@ -1790,7 +1801,7 @@ case 63:
} }
break; break;
case 64: case 64:
#line 635 "gram.y" #line 636 "gram.y"
{ {
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
free(yyval.options.type); free(yyval.options.type);
@@ -1799,7 +1810,7 @@ case 64:
} }
break; break;
case 65: case 65:
#line 641 "gram.y" #line 642 "gram.y"
{ {
#ifdef HAVE_PRIV_SET #ifdef HAVE_PRIV_SET
free(yyval.options.privs); free(yyval.options.privs);
@@ -1808,7 +1819,7 @@ case 65:
} }
break; break;
case 66: case 66:
#line 647 "gram.y" #line 648 "gram.y"
{ {
#ifdef HAVE_PRIV_SET #ifdef HAVE_PRIV_SET
free(yyval.options.limitprivs); free(yyval.options.limitprivs);
@@ -1817,97 +1828,97 @@ case 66:
} }
break; break;
case 67: case 67:
#line 655 "gram.y" #line 656 "gram.y"
{ {
TAGS_INIT(yyval.tag); TAGS_INIT(yyval.tag);
} }
break; break;
case 68: case 68:
#line 658 "gram.y" #line 659 "gram.y"
{ {
yyval.tag.nopasswd = true; yyval.tag.nopasswd = true;
} }
break; break;
case 69: case 69:
#line 661 "gram.y" #line 662 "gram.y"
{ {
yyval.tag.nopasswd = false; yyval.tag.nopasswd = false;
} }
break; break;
case 70: case 70:
#line 664 "gram.y" #line 665 "gram.y"
{ {
yyval.tag.noexec = true; yyval.tag.noexec = true;
} }
break; break;
case 71: case 71:
#line 667 "gram.y" #line 668 "gram.y"
{ {
yyval.tag.noexec = false; yyval.tag.noexec = false;
} }
break; break;
case 72: case 72:
#line 670 "gram.y" #line 671 "gram.y"
{ {
yyval.tag.setenv = true; yyval.tag.setenv = true;
} }
break; break;
case 73: case 73:
#line 673 "gram.y" #line 674 "gram.y"
{ {
yyval.tag.setenv = false; yyval.tag.setenv = false;
} }
break; break;
case 74: case 74:
#line 676 "gram.y" #line 677 "gram.y"
{ {
yyval.tag.log_input = true; yyval.tag.log_input = true;
} }
break; break;
case 75: case 75:
#line 679 "gram.y" #line 680 "gram.y"
{ {
yyval.tag.log_input = false; yyval.tag.log_input = false;
} }
break; break;
case 76: case 76:
#line 682 "gram.y" #line 683 "gram.y"
{ {
yyval.tag.log_output = true; yyval.tag.log_output = true;
} }
break; break;
case 77: case 77:
#line 685 "gram.y" #line 686 "gram.y"
{ {
yyval.tag.log_output = false; yyval.tag.log_output = false;
} }
break; break;
case 78: case 78:
#line 688 "gram.y" #line 689 "gram.y"
{ {
yyval.tag.follow = true; yyval.tag.follow = true;
} }
break; break;
case 79: case 79:
#line 691 "gram.y" #line 692 "gram.y"
{ {
yyval.tag.follow = false; yyval.tag.follow = false;
} }
break; break;
case 80: case 80:
#line 694 "gram.y" #line 695 "gram.y"
{ {
yyval.tag.send_mail = true; yyval.tag.send_mail = true;
} }
break; break;
case 81: case 81:
#line 697 "gram.y" #line 698 "gram.y"
{ {
yyval.tag.send_mail = false; yyval.tag.send_mail = false;
} }
break; break;
case 82: case 82:
#line 702 "gram.y" #line 703 "gram.y"
{ {
yyval.member = new_member(NULL, ALL); yyval.member = new_member(NULL, ALL);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -1917,7 +1928,7 @@ case 82:
} }
break; break;
case 83: case 83:
#line 709 "gram.y" #line 710 "gram.y"
{ {
yyval.member = new_member(yyvsp[0].string, ALIAS); yyval.member = new_member(yyvsp[0].string, ALIAS);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -1927,7 +1938,7 @@ case 83:
} }
break; break;
case 84: case 84:
#line 716 "gram.y" #line 717 "gram.y"
{ {
struct sudo_command *c = calloc(1, sizeof(*c)); struct sudo_command *c = calloc(1, sizeof(*c));
if (c == NULL) { if (c == NULL) {
@@ -1945,7 +1956,7 @@ case 84:
} }
break; break;
case 87: case 87:
#line 737 "gram.y" #line 738 "gram.y"
{ {
const char *s; const char *s;
s = alias_add(yyvsp[-2].string, HOSTALIAS, sudoers, this_lineno, yyvsp[0].member); s = alias_add(yyvsp[-2].string, HOSTALIAS, sudoers, this_lineno, yyvsp[0].member);
@@ -1956,14 +1967,14 @@ case 87:
} }
break; break;
case 89: case 89:
#line 748 "gram.y" #line 749 "gram.y"
{ {
HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries); HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
yyval.member = yyvsp[-2].member; yyval.member = yyvsp[-2].member;
} }
break; break;
case 92: case 92:
#line 758 "gram.y" #line 759 "gram.y"
{ {
const char *s; const char *s;
s = alias_add(yyvsp[-2].string, CMNDALIAS, sudoers, this_lineno, yyvsp[0].member); s = alias_add(yyvsp[-2].string, CMNDALIAS, sudoers, this_lineno, yyvsp[0].member);
@@ -1974,14 +1985,14 @@ case 92:
} }
break; break;
case 94: case 94:
#line 769 "gram.y" #line 770 "gram.y"
{ {
HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries); HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
yyval.member = yyvsp[-2].member; yyval.member = yyvsp[-2].member;
} }
break; break;
case 97: case 97:
#line 779 "gram.y" #line 780 "gram.y"
{ {
const char *s; const char *s;
s = alias_add(yyvsp[-2].string, RUNASALIAS, sudoers, this_lineno, yyvsp[0].member); s = alias_add(yyvsp[-2].string, RUNASALIAS, sudoers, this_lineno, yyvsp[0].member);
@@ -1992,7 +2003,7 @@ case 97:
} }
break; break;
case 100: case 100:
#line 793 "gram.y" #line 794 "gram.y"
{ {
const char *s; const char *s;
s = alias_add(yyvsp[-2].string, USERALIAS, sudoers, this_lineno, yyvsp[0].member); s = alias_add(yyvsp[-2].string, USERALIAS, sudoers, this_lineno, yyvsp[0].member);
@@ -2003,28 +2014,28 @@ case 100:
} }
break; break;
case 102: case 102:
#line 804 "gram.y" #line 805 "gram.y"
{ {
HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries); HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
yyval.member = yyvsp[-2].member; yyval.member = yyvsp[-2].member;
} }
break; break;
case 103: case 103:
#line 810 "gram.y" #line 811 "gram.y"
{ {
yyval.member = yyvsp[0].member; yyval.member = yyvsp[0].member;
yyval.member->negated = false; yyval.member->negated = false;
} }
break; break;
case 104: case 104:
#line 814 "gram.y" #line 815 "gram.y"
{ {
yyval.member = yyvsp[0].member; yyval.member = yyvsp[0].member;
yyval.member->negated = true; yyval.member->negated = true;
} }
break; break;
case 105: case 105:
#line 820 "gram.y" #line 821 "gram.y"
{ {
yyval.member = new_member(yyvsp[0].string, ALIAS); yyval.member = new_member(yyvsp[0].string, ALIAS);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -2034,7 +2045,7 @@ case 105:
} }
break; break;
case 106: case 106:
#line 827 "gram.y" #line 828 "gram.y"
{ {
yyval.member = new_member(NULL, ALL); yyval.member = new_member(NULL, ALL);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -2044,7 +2055,7 @@ case 106:
} }
break; break;
case 107: case 107:
#line 834 "gram.y" #line 835 "gram.y"
{ {
yyval.member = new_member(yyvsp[0].string, NETGROUP); yyval.member = new_member(yyvsp[0].string, NETGROUP);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -2054,7 +2065,7 @@ case 107:
} }
break; break;
case 108: case 108:
#line 841 "gram.y" #line 842 "gram.y"
{ {
yyval.member = new_member(yyvsp[0].string, USERGROUP); yyval.member = new_member(yyvsp[0].string, USERGROUP);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -2064,7 +2075,7 @@ case 108:
} }
break; break;
case 109: case 109:
#line 848 "gram.y" #line 849 "gram.y"
{ {
yyval.member = new_member(yyvsp[0].string, WORD); yyval.member = new_member(yyvsp[0].string, WORD);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -2074,28 +2085,28 @@ case 109:
} }
break; break;
case 111: case 111:
#line 858 "gram.y" #line 859 "gram.y"
{ {
HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries); HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
yyval.member = yyvsp[-2].member; yyval.member = yyvsp[-2].member;
} }
break; break;
case 112: case 112:
#line 864 "gram.y" #line 865 "gram.y"
{ {
yyval.member = yyvsp[0].member; yyval.member = yyvsp[0].member;
yyval.member->negated = false; yyval.member->negated = false;
} }
break; break;
case 113: case 113:
#line 868 "gram.y" #line 869 "gram.y"
{ {
yyval.member = yyvsp[0].member; yyval.member = yyvsp[0].member;
yyval.member->negated = true; yyval.member->negated = true;
} }
break; break;
case 114: case 114:
#line 874 "gram.y" #line 875 "gram.y"
{ {
yyval.member = new_member(yyvsp[0].string, ALIAS); yyval.member = new_member(yyvsp[0].string, ALIAS);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -2105,7 +2116,7 @@ case 114:
} }
break; break;
case 115: case 115:
#line 881 "gram.y" #line 882 "gram.y"
{ {
yyval.member = new_member(NULL, ALL); yyval.member = new_member(NULL, ALL);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -2115,7 +2126,7 @@ case 115:
} }
break; break;
case 116: case 116:
#line 888 "gram.y" #line 889 "gram.y"
{ {
yyval.member = new_member(yyvsp[0].string, WORD); yyval.member = new_member(yyvsp[0].string, WORD);
if (yyval.member == NULL) { if (yyval.member == NULL) {
@@ -2124,7 +2135,7 @@ case 116:
} }
} }
break; break;
#line 2075 "gram.c" #line 2086 "gram.c"
} }
yyssp -= yym; yyssp -= yym;
yystate = *yyssp; yystate = *yyssp;

View File

@@ -283,6 +283,7 @@ privilege : hostlist '=' cmndspeclist {
sudoerserror(N_("unable to allocate memory")); sudoerserror(N_("unable to allocate memory"));
YYERROR; YYERROR;
} }
TAILQ_INIT(&p->defaults);
HLTQ_TO_TAILQ(&p->hostlist, $1, entries); HLTQ_TO_TAILQ(&p->hostlist, $1, entries);
HLTQ_TO_TAILQ(&p->cmndlist, $3, entries); HLTQ_TO_TAILQ(&p->cmndlist, $3, entries);
HLTQ_INIT(p, entries); HLTQ_INIT(p, entries);
@@ -1093,12 +1094,13 @@ free_members(struct member_list *members)
void void
free_userspec(struct userspec *us) free_userspec(struct userspec *us)
{ {
struct privilege *priv, *next; struct privilege *priv;
free_members(&us->users); free_members(&us->users);
TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, next) { while ((priv = TAILQ_FIRST(&us->privileges)) != NULL) {
struct member_list *runasuserlist = NULL, *runasgrouplist = NULL; struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
struct cmndspec *cs, *cs_next; struct cmndspec *cs;
struct defaults *def;
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
char *role = NULL, *type = NULL; char *role = NULL, *type = NULL;
#endif /* HAVE_SELINUX */ #endif /* HAVE_SELINUX */
@@ -1106,8 +1108,11 @@ free_userspec(struct userspec *us)
char *privs = NULL, *limitprivs = NULL; char *privs = NULL, *limitprivs = NULL;
#endif /* HAVE_PRIV_SET */ #endif /* HAVE_PRIV_SET */
TAILQ_REMOVE(&us->privileges, priv, entries);
free(priv->ldap_role);
free_members(&priv->hostlist); free_members(&priv->hostlist);
TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, cs_next) { while ((cs = TAILQ_FIRST(&priv->cmndlist)) != NULL) {
TAILQ_REMOVE(&priv->cmndlist, cs, entries);
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
/* Only free the first instance of a role/type. */ /* Only free the first instance of a role/type. */
if (cs->role != role) { if (cs->role != role) {
@@ -1144,6 +1149,12 @@ free_userspec(struct userspec *us)
free_member(cs->cmnd); free_member(cs->cmnd);
free(cs); free(cs);
} }
while ((def = TAILQ_FIRST(&priv->defaults)) != NULL) {
TAILQ_REMOVE(&priv->defaults, def, entries);
free(def->var);
free(def->val);
free(def);
}
free(priv); free(priv);
} }
rcstr_delref(us->file); rcstr_delref(us->file);

View File

@@ -59,6 +59,7 @@
#include "sudoers.h" #include "sudoers.h"
#include "parse.h" #include "parse.h"
#include "gram.h"
#include "sudo_lbuf.h" #include "sudo_lbuf.h"
#include "sudo_dso.h" #include "sudo_dso.h"
@@ -2370,13 +2371,10 @@ sudo_ldap_get_first_rdn(LDAP *ld, LDAPMessage *entry)
} }
static void static void
sudo_ldap_print_quoted3(struct sudo_lbuf *lbuf, const char *prefix, const char *str, const char *suffix) sudo_ldap_print_quoted(struct sudo_lbuf *lbuf, const char *str)
{ {
const char *name = str; const char *name = str;
debug_decl(sudo_ldap_print_quoted, SUDOERS_DEBUG_LDAP)
/* Prefix is not quoted. */
if (prefix != NULL)
sudo_lbuf_append(lbuf, "%s", prefix);
/* Do not quote UID/GID, all others get quoted. */ /* Do not quote UID/GID, all others get quoted. */
while (*name == '!') while (*name == '!')
@@ -2392,21 +2390,7 @@ sudo_ldap_print_quoted3(struct sudo_lbuf *lbuf, const char *prefix, const char *
sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", str); sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", str);
} }
/* Suffix is not quoted. */ debug_return;
if (suffix != NULL)
sudo_lbuf_append(lbuf, "%s", suffix);
}
static void
sudo_ldap_print_quoted2(struct sudo_lbuf *lbuf, const char *prefix, const char *str)
{
return sudo_ldap_print_quoted3(lbuf, prefix, str, NULL);
}
static void
sudo_ldap_print_quoted(struct sudo_lbuf *lbuf, const char *str)
{
return sudo_ldap_print_quoted3(lbuf, NULL, str, NULL);
} }
/* /*
@@ -2484,237 +2468,311 @@ sudo_ldap_display_bound_defaults(struct sudo_nss *nss, struct passwd *pw,
} }
/* /*
* Print a record in the short form, ala file sudoers. * Convert an array of struct berval to a member list.
*/ */
static int static struct member_list *
sudo_ldap_display_entry_short(LDAP *ld, LDAPMessage *entry, struct passwd *pw, bv_to_member_list(struct berval **bv)
struct sudo_lbuf *lbuf)
{ {
struct berval **bv, **p; struct member_list *members;
bool no_runas_user = true; struct berval **p;
int count = 0; struct member *m;
debug_decl(sudo_ldap_display_entry_short, SUDOERS_DEBUG_LDAP) debug_decl(bv_to_member_list, SUDOERS_DEBUG_LDAP)
sudo_lbuf_append(lbuf, " ("); if ((members = calloc(1, sizeof(*members))) == NULL)
return NULL;
TAILQ_INIT(members);
/* get the RunAsUser Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoRunAsUser");
if (bv == NULL)
bv = ldap_get_values_len(ld, entry, "sudoRunAs");
if (bv != NULL) {
for (p = bv; *p != NULL; p++) { for (p = bv; *p != NULL; p++) {
sudo_ldap_print_quoted2(lbuf, p != bv ? ", " : "", if ((m = calloc(1, sizeof(*m))) == NULL)
(*p)->bv_val[0] ? (*p)->bv_val : user_name); goto bad;
}
ldap_value_free_len(bv);
no_runas_user = false;
}
/* get the RunAsGroup Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoRunAsGroup");
if (bv != NULL) {
if (no_runas_user) {
/* finish printing sudoRunAs */
sudo_ldap_print_quoted(lbuf, pw->pw_name);
}
sudo_lbuf_append(lbuf, " : ");
for (p = bv; *p != NULL; p++) {
sudo_ldap_print_quoted2(lbuf, p != bv ? ", " : "", (*p)->bv_val);
}
ldap_value_free_len(bv);
} else {
if (no_runas_user) {
/* finish printing sudoRunAs */
sudo_ldap_print_quoted(lbuf, def_runas_default);
}
}
sudo_lbuf_append(lbuf, ") ");
/* Get the sudoNotBefore and sudoNotAfter Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoNotBefore");
if (bv != NULL) {
for (p = bv; *p != NULL; p++) {
sudo_ldap_print_quoted3(lbuf, "NOTBEFORE=", (*p)->bv_val, " ");
}
ldap_value_free_len(bv);
}
bv = ldap_get_values_len(ld, entry, "sudoNotAfter");
if (bv != NULL) {
for (p = bv; *p != NULL; p++) {
sudo_ldap_print_quoted3(lbuf, "NOTAFTER=", (*p)->bv_val, " ");
}
ldap_value_free_len(bv);
}
/* get the Option Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoOption");
if (bv != NULL) {
for (p = bv; *p != NULL; p++) {
char *val = (*p)->bv_val; char *val = (*p)->bv_val;
bool negated = sudo_ldap_is_negated(&val); switch (val[0]) {
if (strcmp(val, "authenticate") == 0) case '\0':
sudo_lbuf_append(lbuf, negated ? "NOPASSWD: " : "PASSWD: "); /* Empty RunAsUser means run as the invoking user. */
else if (strcmp(val, "sudoedit_follow") == 0) m->type = MYSELF;
sudo_lbuf_append(lbuf, negated ? "NOFOLLOW: " : "FOLLOW: "); break;
else if (strcmp(val, "noexec") == 0) case 'A':
sudo_lbuf_append(lbuf, negated ? "EXEC: " : "NOEXEC: "); if (strcmp(val, "ALL") == 0) {
else if (strcmp(val, "setenv") == 0) m->type = ALL;
sudo_lbuf_append(lbuf, negated ? "NOSETENV: " : "SETENV: "); break;
else if (strcmp(val, "mail_all_cmnds") == 0 || strcmp(val, "mail_always") == 0)
sudo_lbuf_append(lbuf, negated ? "NOMAIL: " : "MAIL: ");
else if (!negated && strncmp(val, "command_timeout=", 16) == 0)
sudo_ldap_print_quoted3(lbuf, "TIMEOUT=", val + 16, " ");
#ifdef HAVE_SELINUX
else if (!negated && strncmp(val, "role=", 5) == 0)
sudo_ldap_print_quoted3(lbuf, "ROLE=", val + 5, " ");
else if (!negated && strncmp(val, "type=", 5) == 0)
sudo_ldap_print_quoted3(lbuf, "TYPE=", val + 5, " ");
#endif /* HAVE_SELINUX */
#ifdef HAVE_PRIV_SET
else if (!negated && strncmp(val, "privs=", 6) == 0)
sudo_ldap_print_quoted3(lbuf, "PRIVS=", val + 6, " ");
else if (!negated && strncmp(val, "limitprivs=", 11) == 0)
sudo_ldap_print_quoted3(lbuf, "LIMITPRIVS=", val + 11, " ");
#endif /* HAVE_PRIV_SET */
} }
ldap_value_free_len(bv); /* FALLTHROUGH */
default:
m->type = WORD;
m->name = strdup(val);
if (m->name == NULL) {
free(m);
goto bad;
} }
break;
/* get the Command Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoCommand");
if (bv != NULL) {
for (p = bv; *p != NULL; p++) {
char *args = strpbrk((*p)->bv_val, " \t");
if (args != NULL)
*args++ = '\0';
if (p != bv)
sudo_lbuf_append(lbuf, ", ");
sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED" \t", "%s",
(*p)->bv_val);
if (args != NULL) {
sudo_lbuf_append(lbuf, " ");
sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", args);
} }
count++; TAILQ_INSERT_TAIL(members, m, entries);
} }
ldap_value_free_len(bv); debug_return_ptr(members);
bad:
while ((m = TAILQ_FIRST(members)) != NULL) {
TAILQ_REMOVE(members, m, entries);
free(m->name);
free(m);
} }
sudo_lbuf_append(lbuf, "\n"); free(members);
debug_return_ptr(NULL);
debug_return_int(count);
} }
/* static struct userspec_list *
* Print a record in the long form. ldap2sudoers(LDAP *ld, struct ldap_result *lres)
*/
static int
sudo_ldap_display_entry_long(LDAP *ld, LDAPMessage *entry, struct passwd *pw,
struct sudo_lbuf *lbuf)
{ {
struct userspec_list *ldap_userspecs;
struct cmndspec *cmndspec = NULL;
struct sudo_command *c;
struct privilege *priv;
struct userspec *us;
struct member *m;
struct berval **bv, **p; struct berval **bv, **p;
bool no_runas_user = true; struct berval **cmnd_bv, **cmnd; /* XXX - naming */
char *rdn; char *cn;
int count = 0; unsigned int i;
debug_decl(sudo_ldap_display_entry_long, SUDOERS_DEBUG_LDAP) debug_decl(ldap2sudoers, SUDOERS_DEBUG_LDAP)
/* extract the dn, only show the first rdn */ if ((ldap_userspecs = calloc(1, sizeof(*ldap_userspecs))) == NULL)
rdn = sudo_ldap_get_first_rdn(ld, entry); goto oom;
if (rdn != NULL) TAILQ_INIT(ldap_userspecs);
sudo_lbuf_append(lbuf, _("\nLDAP Role: %s\n"), rdn);
else
sudo_lbuf_append(lbuf, _("\nLDAP Role: UNKNOWN\n"));
if (rdn)
ldap_memfree(rdn);
/* get the RunAsUser Values from the entry */ /* We only have a single userspec */
sudo_lbuf_append(lbuf, " RunAsUsers: "); if ((us = calloc(1, sizeof(*us))) == NULL)
goto oom;
TAILQ_INIT(&us->users);
TAILQ_INIT(&us->privileges);
TAILQ_INSERT_TAIL(ldap_userspecs, us, entries);
/* The user has already matched, use ALL as wildcard. */
if ((m = calloc(1, sizeof(*m))) == NULL)
goto oom;
m->type = ALL;
TAILQ_INSERT_TAIL(&us->users, m, entries);
/* Treat each sudoRole as a separate privilege. */
for (i = 0; i < lres->nentries; i++) {
struct cmndspec *prev_cmndspec = NULL;
LDAPMessage *entry = lres->entries[i].entry;
/* Ignore sudoRole without sudoCommand. */
cmnd_bv = ldap_get_values_len(ld, entry, "sudoCommand");
if (cmnd_bv == NULL)
continue;
if ((priv = calloc(1, sizeof(*priv))) == NULL)
goto oom;
TAILQ_INIT(&priv->hostlist);
TAILQ_INIT(&priv->cmndlist);
TAILQ_INIT(&priv->defaults);
TAILQ_INSERT_TAIL(&us->privileges, priv, entries);
/* Get the entry's dn for long format printing. */
cn = sudo_ldap_get_first_rdn(ld, entry);
priv->ldap_role = strdup(cn ? cn : "UNKNOWN");
if (cn != NULL)
ldap_memfree(cn);
if (priv->ldap_role == NULL)
goto oom;
/* The host has already matched, use ALL as wildcard. */
if ((m = calloc(1, sizeof(*m))) == NULL)
goto oom;
m->type = ALL;
TAILQ_INSERT_TAIL(&priv->hostlist, m, entries);
/* Parse sudoCommands and add to cmndlist. */
for (cmnd = cmnd_bv; *cmnd != NULL; cmnd++) {
char *args;
/* Allocate storage upfront. */
cmndspec = calloc(1, sizeof(*cmndspec));
c = calloc(1, sizeof(*c));
m = calloc(1, sizeof(*m));
if (cmndspec == NULL || c == NULL || m == NULL) {
free(c);
free(m);
goto oom;
}
TAILQ_INSERT_TAIL(&priv->cmndlist, cmndspec, entries);
/* Initialize cmndspec */
TAGS_INIT(cmndspec->tags);
cmndspec->notbefore = UNSPEC;
cmndspec->notafter = UNSPEC;
cmndspec->timeout = UNSPEC;
/* Fill in command. */
if ((args = strpbrk((*cmnd)->bv_val, " \t")) != NULL) {
*args++ = '\0';
if ((c->args = strdup(args)) == NULL) {
free(c);
free(m);
goto oom;
}
}
if ((c->cmnd = strdup((*cmnd)->bv_val)) == NULL) {
free(c->args);
free(c);
free(m);
goto oom;
}
m->type = COMMAND;
m->name = (char *)c;
cmndspec->cmnd = m;
if (prev_cmndspec != NULL) {
/* Inherit values from prior cmndspec */
cmndspec->runasuserlist = prev_cmndspec->runasuserlist;
cmndspec->runasgrouplist = prev_cmndspec->runasgrouplist;
cmndspec->notbefore = prev_cmndspec->notbefore;
cmndspec->notafter = prev_cmndspec->notafter;
cmndspec->tags = prev_cmndspec->tags;
} else {
/* Parse sudoRunAsUser / sudoRunAs */
bv = ldap_get_values_len(ld, entry, "sudoRunAsUser"); bv = ldap_get_values_len(ld, entry, "sudoRunAsUser");
if (bv == NULL) if (bv == NULL)
bv = ldap_get_values_len(ld, entry, "sudoRunAs"); bv = ldap_get_values_len(ld, entry, "sudoRunAs"); /* old style */
if (bv != NULL) { if (bv != NULL) {
for (p = bv; *p != NULL; p++) { cmndspec->runasuserlist = bv_to_member_list(bv);
sudo_lbuf_append(lbuf, "%s%s", p != bv ? ", " : "", (*p)->bv_val); if (cmndspec->runasuserlist == NULL)
} goto oom;
ldap_value_free_len(bv); ldap_value_free_len(bv);
no_runas_user = false; bv = NULL;
} }
/* get the RunAsGroup Values from the entry */ /* Parse sudoRunAsGroup */
bv = ldap_get_values_len(ld, entry, "sudoRunAsGroup"); bv = ldap_get_values_len(ld, entry, "sudoRunAsGroup");
if (bv != NULL) { if (bv != NULL) {
if (no_runas_user) { cmndspec->runasgrouplist = bv_to_member_list(bv);
/* finish printing sudoRunAs */ if (cmndspec->runasgrouplist == NULL)
sudo_lbuf_append(lbuf, "%s", pw->pw_name); goto oom;
}
sudo_lbuf_append(lbuf, "\n RunAsGroups: ");
for (p = bv; *p != NULL; p++) {
sudo_lbuf_append(lbuf, "%s%s", p != bv ? ", " : "", (*p)->bv_val);
}
ldap_value_free_len(bv); ldap_value_free_len(bv);
sudo_lbuf_append(lbuf, "\n"); bv = NULL;
} else {
if (no_runas_user) {
/* finish printing sudoRunAs */
sudo_lbuf_append(lbuf, "%s", def_runas_default);
}
sudo_lbuf_append(lbuf, "\n");
} }
/* Get the sudoNotBefore and sudoNotAfter Values from the entry */ /* Parse sudoNotBefore */
bv = ldap_get_values_len(ld, entry, "sudoNotBefore"); bv = ldap_get_values_len(ld, entry, "sudoNotBefore");
if (bv != NULL) { if (bv != NULL) {
sudo_lbuf_append(lbuf, " NotBefore: "); /* Only takes the last entry. */
for (p = bv; *p != NULL; p++) { for (p = bv; *p != NULL; p++) {
sudo_lbuf_append(lbuf, "%s%s", p != bv ? ", " : "", (*p)->bv_val); cmndspec->notbefore = parse_gentime((*p)->bv_val);
} }
ldap_value_free_len(bv); ldap_value_free_len(bv);
sudo_lbuf_append(lbuf, "\n"); bv = NULL;
} }
/* Parse sudoNotAfter */
bv = ldap_get_values_len(ld, entry, "sudoNotAfter"); bv = ldap_get_values_len(ld, entry, "sudoNotAfter");
if (bv != NULL) { if (bv != NULL) {
sudo_lbuf_append(lbuf, " NotAfter: "); /* Only takes the last entry. */
for (p = bv; *p != NULL; p++) { for (p = bv; *p != NULL; p++) {
sudo_lbuf_append(lbuf, "%s%s", p != bv ? ", " : "", (*p)->bv_val); cmndspec->notafter = parse_gentime((*p)->bv_val);
} }
ldap_value_free_len(bv); ldap_value_free_len(bv);
sudo_lbuf_append(lbuf, "\n"); bv = NULL;
} }
/* get the Option Values from the entry */ /* Parse sudoOptions. */
bv = ldap_get_values_len(ld, entry, "sudoOption"); bv = ldap_get_values_len(ld, entry, "sudoOption");
if (bv != NULL) { if (bv != NULL) {
sudo_lbuf_append(lbuf, " Options: ");
for (p = bv; *p != NULL; p++) { for (p = bv; *p != NULL; p++) {
sudo_lbuf_append(lbuf, "%s%s", p != bv ? ", " : "", (*p)->bv_val); char *var, *val;
int op;
op = sudo_ldap_parse_option((*p)->bv_val, &var, &val);
if (strcmp(var, "command_timeout") == 0) {
if (op == '=')
cmndspec->timeout = parse_timeout(val);
#ifdef HAVE_SELINUX
} else if (strcmp(var, "role") == 0) {
if (op == '=') {
if ((cmndspec->role = strdup(val)) == NULL)
goto oom;
}
} else if (strcmp(var, "type") == 0) {
if (op == '=') {
if ((cmndspec->type = strdup(val)) == NULL)
goto oom;
}
#endif /* HAVE_SELINUX */
#ifdef HAVE_PRIV_SET
} else if (strcmp(var, "privs") == 0) {
if (op == '=') {
if ((cmndspec->privs = strdup(val)) == NULL)
goto oom;
}
} else if (strcmp(val, "limitprivs") == 0) {
if (op == '=') {
if ((cmndspec->limitprivs = strdup(val)) == NULL)
goto oom;
}
#endif /* HAVE_PRIV_SET */
} else if (long_list) {
struct defaults *def = calloc(1, sizeof(*def));
if (def == NULL)
goto oom;
def->op = op;
if ((def->var = strdup(var)) == NULL) {
free(def);
goto oom;
}
if (val != NULL) {
if ((def->val = strdup(val)) == NULL) {
free(def->var);
free(def);
goto oom;
}
}
TAILQ_INSERT_TAIL(&priv->defaults, def, entries);
} else {
/* Convert to tags. */
if (op != true && op != false)
continue;
if (strcmp(var, "authenticate") == 0) {
cmndspec->tags.nopasswd = op == false;
} else if (strcmp(var, "sudoedit_follow") == 0) {
cmndspec->tags.follow = op == true;
} else if (strcmp(var, "noexec") == 0) {
cmndspec->tags.noexec = op == true;
} else if (strcmp(var, "setenv") == 0) {
cmndspec->tags.setenv = op == true;
} else if (strcmp(var, "mail_all_cmnds") == 0 ||
strcmp(var, "mail_always") == 0) {
cmndspec->tags.send_mail = op == true;
}
}
} }
ldap_value_free_len(bv); ldap_value_free_len(bv);
sudo_lbuf_append(lbuf, "\n"); bv = NULL;
} }
/* /* So we can inherit previous values. */
* Display order attribute if present. This attribute is single valued, prev_cmndspec = cmndspec;
* so there is no need for a loop.
*/
bv = ldap_get_values_len(ld, entry, "sudoOrder");
if (bv != NULL) {
if (*bv != NULL) {
sudo_lbuf_append(lbuf, _(" Order: %s\n"), (*bv)->bv_val);
} }
}
ldap_value_free_len(cmnd_bv);
cmnd_bv = NULL;
}
debug_return_ptr(ldap_userspecs);
oom:
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
if (cmnd_bv != NULL)
ldap_value_free_len(cmnd_bv);
if (bv != NULL)
ldap_value_free_len(bv); ldap_value_free_len(bv);
if (ldap_userspecs != NULL) {
while ((us = TAILQ_FIRST(ldap_userspecs)) != NULL) {
TAILQ_REMOVE(ldap_userspecs, us, entries);
free_userspec(us);
} }
free(ldap_userspecs);
/* Get the command values from the entry. */
bv = ldap_get_values_len(ld, entry, "sudoCommand");
if (bv != NULL) {
sudo_lbuf_append(lbuf, _(" Commands:\n"));
for (p = bv; *p != NULL; p++) {
sudo_lbuf_append(lbuf, "\t%s\n", (*p)->bv_val);
count++;
} }
ldap_value_free_len(bv); debug_return_ptr(NULL);
}
debug_return_int(count);
} }
/* /*
@@ -2725,10 +2783,10 @@ sudo_ldap_display_privs(struct sudo_nss *nss, struct passwd *pw,
struct sudo_lbuf *lbuf) struct sudo_lbuf *lbuf)
{ {
struct sudo_ldap_handle *handle = nss->handle; struct sudo_ldap_handle *handle = nss->handle;
LDAP *ld; struct userspec_list *ldap_userspecs = NULL;
struct ldap_result *lres; struct ldap_result *lres;
LDAPMessage *entry; LDAP *ld;
unsigned int i, count = 0; int ret = 0;
debug_decl(sudo_ldap_display_privs, SUDOERS_DEBUG_LDAP) debug_decl(sudo_ldap_display_privs, SUDOERS_DEBUG_LDAP)
if (handle == NULL || handle->ld == NULL) if (handle == NULL || handle->ld == NULL)
@@ -2740,19 +2798,27 @@ sudo_ldap_display_privs(struct sudo_nss *nss, struct passwd *pw,
if (lres == NULL) if (lres == NULL)
goto done; goto done;
/* Display all matching entries. */ /* Convert to sudoers parse tree. */
for (i = 0; i < lres->nentries; i++) { if ((ldap_userspecs = ldap2sudoers(ld, lres)) == NULL) {
entry = lres->entries[i].entry; ret = -1;
if (long_list) goto done;
count += sudo_ldap_display_entry_long(ld, entry, pw, lbuf);
else
count += sudo_ldap_display_entry_short(ld, entry, pw, lbuf);
} }
/* Call common display code. */
ret = sudo_display_userspecs(ldap_userspecs, pw, lbuf);
done: done:
if (ldap_userspecs != NULL) {
struct userspec *us;
while ((us = TAILQ_FIRST(ldap_userspecs)) != NULL) {
TAILQ_REMOVE(ldap_userspecs, us, entries);
free_userspec(us);
}
free(ldap_userspecs);
}
if (sudo_lbuf_error(lbuf)) if (sudo_lbuf_error(lbuf))
debug_return_int(-1); debug_return_int(-1);
debug_return_int(count); debug_return_int(ret);
} }
static int static int

View File

@@ -373,6 +373,8 @@ sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,
{ {
debug_decl(sudo_file_append_cmnd, SUDOERS_DEBUG_NSS) debug_decl(sudo_file_append_cmnd, SUDOERS_DEBUG_NSS)
/* XXX - should not print privs/limitprivs, role/type, timeout
or notbefore/after if unchanged from prior cs */
#ifdef HAVE_PRIV_SET #ifdef HAVE_PRIV_SET
if (cs->privs) if (cs->privs)
sudo_lbuf_append(lbuf, "PRIVS=\"%s\" ", cs->privs); sudo_lbuf_append(lbuf, "PRIVS=\"%s\" ", cs->privs);
@@ -438,6 +440,29 @@ sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,
debug_return_bool(!sudo_lbuf_error(lbuf)); debug_return_bool(!sudo_lbuf_error(lbuf));
} }
/*
* Format and append a defaults entry to the specified lbuf.
*/
static void
sudo_file_append_default(struct sudo_lbuf *lbuf, struct defaults *d)
{
debug_decl(sudo_file_append_default, SUDOERS_DEBUG_NSS)
if (d->val != NULL) {
sudo_lbuf_append(lbuf, "%s%s", d->var,
d->op == '+' ? "+=" : d->op == '-' ? "-=" : "=");
if (strpbrk(d->val, " \t") != NULL) {
sudo_lbuf_append(lbuf, "\"");
sudo_lbuf_append_quoted(lbuf, "\"", "%s", d->val);
sudo_lbuf_append(lbuf, "\"");
} else
sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", d->val);
} else {
sudo_lbuf_append(lbuf, "%s%s", d->op == false ? "!" : "", d->var);
}
debug_return;
}
static int static int
sudo_file_display_priv_short(struct passwd *pw, struct userspec *us, sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
struct sudo_lbuf *lbuf) struct sudo_lbuf *lbuf)
@@ -451,6 +476,9 @@ sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
/* gcc -Wuninitialized false positive */ /* gcc -Wuninitialized false positive */
TAGS_INIT(tags); TAGS_INIT(tags);
/* XXX - should init tags for each privilege */
/* XXX - does runas change inheriting? */
/* XXX - what about time and timeout inheriting? */
TAILQ_FOREACH(priv, &us->privileges, entries) { TAILQ_FOREACH(priv, &us->privileges, entries) {
if (hostlist_matches(pw, &priv->hostlist) != ALLOW) if (hostlist_matches(pw, &priv->hostlist) != ALLOW)
continue; continue;
@@ -519,6 +547,10 @@ new_long_entry(struct cmndspec *cs, struct cmndspec *prev_cs)
#endif /* HAVE_SELINUX */ #endif /* HAVE_SELINUX */
if (cs->timeout != prev_cs->timeout) if (cs->timeout != prev_cs->timeout)
return true; return true;
if (cs->notbefore != prev_cs->notbefore)
return true;
if (cs->notafter != prev_cs->notafter)
return true;
return false; return false;
} }
@@ -527,8 +559,9 @@ sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
struct sudo_lbuf *lbuf) struct sudo_lbuf *lbuf)
{ {
struct cmndspec *cs, *prev_cs; struct cmndspec *cs, *prev_cs;
struct member *m;
struct privilege *priv; struct privilege *priv;
struct defaults *def;
struct member *m;
int nfound = 0, olen; int nfound = 0, olen;
debug_decl(sudo_file_display_priv_long, SUDOERS_DEBUG_NSS) debug_decl(sudo_file_display_priv_long, SUDOERS_DEBUG_NSS)
@@ -538,7 +571,12 @@ sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
prev_cs = NULL; prev_cs = NULL;
TAILQ_FOREACH(cs, &priv->cmndlist, entries) { TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
if (new_long_entry(cs, prev_cs)) { if (new_long_entry(cs, prev_cs)) {
if (priv->ldap_role != NULL) {
sudo_lbuf_append(lbuf, _("\nLDAP Role: %s\n"),
priv->ldap_role);
} else {
sudo_lbuf_append(lbuf, _("\nSudoers entry:\n")); sudo_lbuf_append(lbuf, _("\nSudoers entry:\n"));
}
sudo_lbuf_append(lbuf, _(" RunAsUsers: ")); sudo_lbuf_append(lbuf, _(" RunAsUsers: "));
if (cs->runasuserlist != NULL) { if (cs->runasuserlist != NULL) {
TAILQ_FOREACH(m, cs->runasuserlist, entries) { TAILQ_FOREACH(m, cs->runasuserlist, entries) {
@@ -563,6 +601,10 @@ sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
} }
olen = lbuf->len; olen = lbuf->len;
sudo_lbuf_append(lbuf, _(" Options: ")); sudo_lbuf_append(lbuf, _(" Options: "));
TAILQ_FOREACH(def, &priv->defaults, entries) {
sudo_file_append_default(lbuf, def);
sudo_lbuf_append(lbuf, ", ");
}
if (TAG_SET(cs->tags.setenv)) if (TAG_SET(cs->tags.setenv))
sudo_lbuf_append(lbuf, "%ssetenv, ", cs->tags.setenv ? "" : "!"); sudo_lbuf_append(lbuf, "%ssetenv, ", cs->tags.setenv ? "" : "!");
if (TAG_SET(cs->tags.noexec)) if (TAG_SET(cs->tags.noexec))
@@ -624,21 +666,16 @@ sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
debug_return_int(nfound); debug_return_int(nfound);
} }
/* /* XXX - better naming */
* Returns the number of matching privileges or -1 on error.
*/
int int
sudo_file_display_privs(struct sudo_nss *nss, struct passwd *pw, sudo_display_userspecs(struct userspec_list *usl, struct passwd *pw,
struct sudo_lbuf *lbuf) struct sudo_lbuf *lbuf)
{ {
struct userspec *us; struct userspec *us;
int nfound = 0; int nfound = 0;
debug_decl(sudo_file_display_priv, SUDOERS_DEBUG_NSS) debug_decl(sudo_display_userspecs, SUDOERS_DEBUG_NSS)
if (nss->handle == NULL) TAILQ_FOREACH(us, usl, entries) {
goto done;
TAILQ_FOREACH(us, &userspecs, entries) {
if (userlist_matches(pw, &us->users) != ALLOW) if (userlist_matches(pw, &us->users) != ALLOW)
continue; continue;
@@ -649,10 +686,24 @@ sudo_file_display_privs(struct sudo_nss *nss, struct passwd *pw,
} }
if (sudo_lbuf_error(lbuf)) if (sudo_lbuf_error(lbuf))
debug_return_int(-1); debug_return_int(-1);
done:
debug_return_int(nfound); debug_return_int(nfound);
} }
/*
* Returns the number of matching privileges or -1 on error.
*/
static int
sudo_file_display_privs(struct sudo_nss *nss, struct passwd *pw,
struct sudo_lbuf *lbuf)
{
debug_decl(sudo_file_display_priv, SUDOERS_DEBUG_NSS)
if (nss->handle == NULL)
debug_return_int(0);
debug_return_int(sudo_display_userspecs(&userspecs, pw, lbuf));
}
/* /*
* Display matching Defaults entries for the given user on this host. * Display matching Defaults entries for the given user on this host.
*/ */
@@ -687,18 +738,8 @@ sudo_file_display_defaults(struct sudo_nss *nss, struct passwd *pw,
case DEFAULTS_CMND: case DEFAULTS_CMND:
continue; continue;
} }
if (d->val != NULL) { sudo_lbuf_append(lbuf, "%s", prefix);
sudo_lbuf_append(lbuf, "%s%s%s", prefix, d->var, sudo_file_append_default(lbuf, d);
d->op == '+' ? "+=" : d->op == '-' ? "-=" : "=");
if (strpbrk(d->val, " \t") != NULL) {
sudo_lbuf_append(lbuf, "\"");
sudo_lbuf_append_quoted(lbuf, "\"", "%s", d->val);
sudo_lbuf_append(lbuf, "\"");
} else
sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", d->val);
} else
sudo_lbuf_append(lbuf, "%s%s%s", prefix,
d->op == false ? "!" : "", d->var);
prefix = ", "; prefix = ", ";
nfound++; nfound++;
} }
@@ -778,11 +819,7 @@ display_bound_defaults(int deftype, struct sudo_lbuf *lbuf)
} }
} else } else
sudo_lbuf_append(lbuf, ", "); sudo_lbuf_append(lbuf, ", ");
if (d->val != NULL) { sudo_file_append_default(lbuf, d);
sudo_lbuf_append(lbuf, "%s%s%s", d->var, d->op == '+' ? "+=" :
d->op == '-' ? "-=" : "=", d->val);
} else
sudo_lbuf_append(lbuf, "%s%s", d->op == false ? "!" : "", d->var);
} }
if (sudo_lbuf_error(lbuf)) if (sudo_lbuf_error(lbuf))

View File

@@ -167,8 +167,10 @@ struct userspec {
*/ */
struct privilege { struct privilege {
TAILQ_ENTRY(privilege) entries; TAILQ_ENTRY(privilege) entries;
char *ldap_role; /* LDAP sudoRole */
struct member_list hostlist; /* list of hosts */ struct member_list hostlist; /* list of hosts */
struct cmndspec_list cmndlist; /* list of Cmnd_Specs */ struct cmndspec_list cmndlist; /* list of Cmnd_Specs */
struct defaults_list defaults; /* list of sudoOptions */
}; };
/* /*
@@ -302,4 +304,8 @@ unsigned char *sudo_filedigest(int fd, const char *file, int digest_type, size_t
/* digestname.c */ /* digestname.c */
const char *digest_type_to_name(int digest_type); const char *digest_type_to_name(int digest_type);
/* parse.c */
struct sudo_lbuf;
int sudo_display_userspecs(struct userspec_list *usl, struct passwd *pw, struct sudo_lbuf *lbuf);
#endif /* SUDOERS_PARSE_H */ #endif /* SUDOERS_PARSE_H */