mirror of
https://github.com/sudo-project/sudo.git
synced 2025-09-02 23:35:36 +00:00
Correctly handle multiple privileges per userspec and runas inheritence.
This commit is contained in:
91
parse.c
91
parse.c
@@ -90,6 +90,7 @@ sudoers_lookup(pwflag)
|
|||||||
enum def_tupple pwcheck = 0;
|
enum def_tupple pwcheck = 0;
|
||||||
struct cmndspec *cs;
|
struct cmndspec *cs;
|
||||||
struct cmndtag *tags = NULL;
|
struct cmndtag *tags = NULL;
|
||||||
|
struct member *runas;
|
||||||
struct privilege *priv;
|
struct privilege *priv;
|
||||||
struct userspec *us;
|
struct userspec *us;
|
||||||
|
|
||||||
@@ -118,17 +119,18 @@ sudoers_lookup(pwflag)
|
|||||||
matched = FALSE;
|
matched = FALSE;
|
||||||
for (us = userspecs; us != NULL; us = us->next) {
|
for (us = userspecs; us != NULL; us = us->next) {
|
||||||
if (user_matches(sudo_user.pw, us->user) == TRUE) {
|
if (user_matches(sudo_user.pw, us->user) == TRUE) {
|
||||||
priv = us->privileges;
|
for (priv = us->privileges; priv != NULL; priv = priv->next) {
|
||||||
if (host_matches(priv->hostlist) == TRUE) {
|
if (host_matches(priv->hostlist) == TRUE) {
|
||||||
for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
|
for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
|
||||||
/* Only check the command when listing another user. */
|
/* Only check the command when listing another user. */
|
||||||
if (user_uid == 0 || list_pw == NULL ||
|
if (user_uid == 0 || list_pw == NULL ||
|
||||||
user_uid == list_pw->pw_uid ||
|
user_uid == list_pw->pw_uid ||
|
||||||
cmnd_matches(cs->cmnd) == TRUE)
|
cmnd_matches(cs->cmnd) == TRUE)
|
||||||
matched = TRUE;
|
matched = TRUE;
|
||||||
if ((pwcheck == any && nopass != TRUE) ||
|
if ((pwcheck == any && nopass != TRUE) ||
|
||||||
(pwcheck == all && nopass == TRUE))
|
(pwcheck == all && nopass == TRUE))
|
||||||
nopass = cs->tags.nopasswd;
|
nopass = cs->tags.nopasswd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,15 +154,19 @@ sudoers_lookup(pwflag)
|
|||||||
for (us = userspecs; us != NULL; us = us->next) {
|
for (us = userspecs; us != NULL; us = us->next) {
|
||||||
if (user_matches(sudo_user.pw, us->user) == TRUE) {
|
if (user_matches(sudo_user.pw, us->user) == TRUE) {
|
||||||
CLR(validated, FLAG_NO_USER);
|
CLR(validated, FLAG_NO_USER);
|
||||||
priv = us->privileges;
|
for (priv = us->privileges; priv != NULL; priv = priv->next) {
|
||||||
if (host_matches(priv->hostlist) == TRUE) {
|
if (host_matches(priv->hostlist) == TRUE) {
|
||||||
CLR(validated, FLAG_NO_HOST);
|
CLR(validated, FLAG_NO_HOST);
|
||||||
for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
|
runas = NULL;
|
||||||
if (runas_matches(cs->runaslist) == TRUE) {
|
for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
|
||||||
rval = cmnd_matches(cs->cmnd);
|
if (cs->runaslist != NULL)
|
||||||
if (rval != UNSPEC) {
|
runas = cs->runaslist;
|
||||||
matched = rval;
|
if (runas_matches(runas) == TRUE) {
|
||||||
tags = &cs->tags;
|
rval = cmnd_matches(cs->cmnd);
|
||||||
|
if (rval != UNSPEC) {
|
||||||
|
matched = rval;
|
||||||
|
tags = &cs->tags;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,30 +209,31 @@ display_privs(pw)
|
|||||||
host_matches(us->privileges->hostlist) != TRUE)
|
host_matches(us->privileges->hostlist) != TRUE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
priv = us->privileges;
|
for (priv = us->privileges; priv != NULL; priv = priv->next) {
|
||||||
runas = NULL;
|
runas = NULL;
|
||||||
for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
|
for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
|
||||||
fputs(" ", stdout);
|
if (cs->runaslist != NULL)
|
||||||
if (cs->runaslist != NULL)
|
runas = cs->runaslist;
|
||||||
runas = cs->runaslist;
|
fputs(" ", stdout);
|
||||||
if (runas != NULL) {
|
if (runas != NULL) {
|
||||||
fputs("(", stdout);
|
fputs("(", stdout);
|
||||||
for (m = runas; m != NULL; m = m->next) {
|
for (m = runas; m != NULL; m = m->next) {
|
||||||
if (m != runas)
|
if (m != runas)
|
||||||
fputs(", ", stdout);
|
fputs(", ", stdout);
|
||||||
print_member(m->name, m->type, m->negated, RUNASALIAS);
|
print_member(m->name, m->type, m->negated, RUNASALIAS);
|
||||||
|
}
|
||||||
|
fputs(") ", stdout);
|
||||||
}
|
}
|
||||||
fputs(") ", stdout);
|
if (cs->tags.monitor != UNSPEC && cs->tags.monitor != def_monitor)
|
||||||
|
printf("%sMONITOR: ", cs->tags.monitor ? "" : "NO");
|
||||||
|
if (cs->tags.noexec != UNSPEC && cs->tags.noexec != def_noexec)
|
||||||
|
printf("%sEXEC: ", cs->tags.noexec ? "NO" : "");
|
||||||
|
if (cs->tags.nopasswd != UNSPEC && cs->tags.nopasswd != !def_authenticate)
|
||||||
|
printf("%sPASSWD: ", cs->tags.nopasswd ? "NO" : "");
|
||||||
|
m = cs->cmnd;
|
||||||
|
print_member(m->name, m->type, m->negated, CMNDALIAS);
|
||||||
|
putchar('\n');
|
||||||
}
|
}
|
||||||
if (cs->tags.monitor != UNSPEC && cs->tags.monitor != def_monitor)
|
|
||||||
printf("%sMONITOR: ", cs->tags.monitor ? "" : "NO");
|
|
||||||
if (cs->tags.noexec != UNSPEC && cs->tags.noexec != def_noexec)
|
|
||||||
printf("%sEXEC: ", cs->tags.noexec ? "NO" : "");
|
|
||||||
if (cs->tags.nopasswd != UNSPEC && cs->tags.nopasswd != !def_authenticate)
|
|
||||||
printf("%sPASSWD: ", cs->tags.nopasswd ? "NO" : "");
|
|
||||||
m = cs->cmnd;
|
|
||||||
print_member(m->name, m->type, m->negated, CMNDALIAS);
|
|
||||||
putchar('\n');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -105,6 +105,7 @@ main(argc, argv)
|
|||||||
{
|
{
|
||||||
struct cmndspec *cs;
|
struct cmndspec *cs;
|
||||||
struct passwd pw, rpw;
|
struct passwd pw, rpw;
|
||||||
|
struct member *runas;
|
||||||
struct privilege *priv;
|
struct privilege *priv;
|
||||||
struct userspec *us;
|
struct userspec *us;
|
||||||
char *p, hbuf[MAXHOSTNAMELEN];
|
char *p, hbuf[MAXHOSTNAMELEN];
|
||||||
@@ -220,20 +221,24 @@ main(argc, argv)
|
|||||||
matched = UNSPEC;
|
matched = UNSPEC;
|
||||||
for (us = userspecs; us != NULL; us = us->next) {
|
for (us = userspecs; us != NULL; us = us->next) {
|
||||||
if (user_matches(sudo_user.pw, us->user) == TRUE) {
|
if (user_matches(sudo_user.pw, us->user) == TRUE) {
|
||||||
priv = us->privileges;
|
for (priv = us->privileges; priv != NULL; priv = priv->next) {
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
print_privilege(priv);
|
print_privilege(priv);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
if (host_matches(priv->hostlist) == TRUE) {
|
if (host_matches(priv->hostlist) == TRUE) {
|
||||||
puts("\thost matched");
|
puts("\thost matched");
|
||||||
for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
|
runas = NULL;
|
||||||
if (runas_matches(cs->runaslist) == TRUE) {
|
for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
|
||||||
puts("\trunas matched");
|
if (cs->runaslist != NULL)
|
||||||
rval = cmnd_matches(cs->cmnd);
|
runas = cs->runaslist;
|
||||||
if (rval != UNSPEC)
|
if (runas_matches(runas) == TRUE) {
|
||||||
matched = rval;
|
puts("\trunas matched");
|
||||||
printf("\tcommand %s\n", rval == ALLOW ? "allowed" :
|
rval = cmnd_matches(cs->cmnd);
|
||||||
rval == DENY ? "denied" : "unmatched");
|
if (rval != UNSPEC)
|
||||||
|
matched = rval;
|
||||||
|
printf("\tcommand %s\n", rval == ALLOW ? "allowed" :
|
||||||
|
rval == DENY ? "denied" : "unmatched");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user