2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-09-03 15:55:40 +00:00

Make matching but negated commands/hosts/runas entries override a

previous match as expected.  Also reduce some levels of indent by
a few placed continue statements.
This commit is contained in:
Todd C. Miller
2007-07-06 00:20:51 +00:00
parent bdd5b43f75
commit 7f0bb4b1a8

85
parse.c
View File

@@ -98,7 +98,7 @@ int
sudoers_lookup(pwflag) sudoers_lookup(pwflag)
int pwflag; int pwflag;
{ {
int rval, validated, matched; int validated, matched, host_matched, runas_matched, cmnd_matched;
enum def_tupple pwcheck = 0; enum def_tupple pwcheck = 0;
struct cmndspec *cs; struct cmndspec *cs;
struct cmndtag *tags = NULL; struct cmndtag *tags = NULL;
@@ -130,20 +130,20 @@ sudoers_lookup(pwflag)
CLR(validated, FLAG_NO_HOST); CLR(validated, FLAG_NO_HOST);
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)
for (priv = us->privileges; priv != NULL; priv = priv->next) { continue;
if (host_matches(priv->hostlist) == TRUE) { for (priv = us->privileges; priv != NULL; priv = priv->next) {
for (cs = priv->cmndlist; cs != NULL; cs = cs->next) { if (host_matches(priv->hostlist) != TRUE)
/* Only check the command when listing another user. */ continue;
if (user_uid == 0 || list_pw == NULL || for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
user_uid == list_pw->pw_uid || /* Only check the command when listing another user. */
cmnd_matches(cs->cmnd) == TRUE) if (user_uid == 0 || list_pw == NULL ||
matched = TRUE; user_uid == list_pw->pw_uid ||
if ((pwcheck == any && nopass != TRUE) || cmnd_matches(cs->cmnd) == TRUE)
(pwcheck == all && nopass == TRUE)) matched = TRUE;
nopass = cs->tags.nopasswd; if ((pwcheck == any && nopass != TRUE) ||
} (pwcheck == all && nopass == TRUE))
} nopass = cs->tags.nopasswd;
} }
} }
} }
@@ -164,23 +164,27 @@ sudoers_lookup(pwflag)
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)
CLR(validated, FLAG_NO_USER); continue;
for (priv = us->privileges; priv != NULL; priv = priv->next) { CLR(validated, FLAG_NO_USER);
if (host_matches(priv->hostlist) == TRUE) { for (priv = us->privileges; priv != NULL; priv = priv->next) {
CLR(validated, FLAG_NO_HOST); host_matched = host_matches(priv->hostlist);
runas = NULL; if (host_matched == UNSPEC)
for (cs = priv->cmndlist; cs != NULL; cs = cs->next) { continue;
if (cs->runaslist != NULL) if (host_matched == TRUE)
runas = cs->runaslist; CLR(validated, FLAG_NO_HOST);
if (runas_matches(runas) == TRUE) { runas = NULL;
rval = cmnd_matches(cs->cmnd); for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
if (rval != UNSPEC) { if (cs->runaslist != NULL)
matched = rval; runas = cs->runaslist;
tags = &cs->tags; runas_matched = runas_matches(runas);
} if (runas_matched != UNSPEC) {
} cmnd_matched = cmnd_matches(cs->cmnd);
} if (cmnd_matched != UNSPEC)
matched = host_matched && runas_matched &&
cmnd_matched;
if (matched)
tags = &cs->tags;
} }
} }
} }
@@ -416,6 +420,7 @@ display_cmnd(v, pw)
struct privilege *priv; struct privilege *priv;
struct userspec *us; struct userspec *us;
int rval = 1; int rval = 1;
int host_matched, runas_matched, cmnd_matched;
#ifdef HAVE_LDAP #ifdef HAVE_LDAP
if (v != NULL) if (v != NULL)
@@ -423,18 +428,24 @@ display_cmnd(v, pw)
#endif #endif
if (rval != 0 && !def_ignore_local_sudoers) { if (rval != 0 && !def_ignore_local_sudoers) {
for (match = NULL, us = userspecs; us != NULL; us = us->next) { for (match = NULL, us = userspecs; us != NULL; us = us->next) {
if (user_matches(pw, us->user) != TRUE || if (user_matches(pw, us->user) != TRUE)
host_matches(us->privileges->hostlist) != TRUE)
continue; continue;
for (priv = us->privileges; priv != NULL; priv = priv->next) { for (priv = us->privileges; priv != NULL; priv = priv->next) {
host_matched = host_matches(priv->hostlist);
if (host_matched == UNSPEC)
continue;
runas = NULL; runas = NULL;
for (cs = priv->cmndlist; cs != NULL; cs = cs->next) { for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
if (cs->runaslist != NULL) if (cs->runaslist != NULL)
runas = cs->runaslist; runas = cs->runaslist;
if (runas_matches(runas) == TRUE && runas_matched = runas_matches(runas);
cmnd_matches(cs->cmnd) != UNSPEC) if (runas_matched != UNSPEC) {
match = cs->cmnd; cmnd_matched = cmnd_matches(cs->cmnd);
if (cmnd_matched != UNSPEC)
match = host_matched && runas_matched ?
cs->cmnd : NULL;
}
} }
} }
} }