The listpw and verifypw sudoers options would not take effect because

the value of the default was checked *before* sudoers was parsed.
Instead of passing in the value of PWCHECK_* to sudoers_lookup(),
pass in the arg for def_ival() so the check can be deferred until
after sudoers is parsed.
This commit is contained in:
Todd C. Miller
2000-08-12 20:48:29 +00:00
parent d76537718b
commit 6525e882a4
2 changed files with 27 additions and 16 deletions

30
parse.c
View File

@@ -112,10 +112,11 @@ static int has_meta __P((char *));
* allowed to run the specified command on this host as the target user. * allowed to run the specified command on this host as the target user.
*/ */
int int
sudoers_lookup(pwflags) sudoers_lookup(pwflag)
int pwflags; int pwflag;
{ {
int error; int error;
int pwcheck;
/* Become sudoers file owner */ /* Become sudoers file owner */
set_perms(PERM_SUDOERS, 0); set_perms(PERM_SUDOERS, 0);
@@ -128,8 +129,8 @@ sudoers_lookup(pwflags)
/* Allocate space for data structures in the parser. */ /* Allocate space for data structures in the parser. */
init_parser(); init_parser();
/* For most pwflags to be useful we need to keep more state around. */ /* If pwcheck *could* be PWCHECK_ALL or PWCHECK_ANY, keep more state. */
if (pwflags && pwflags != PWCHECK_NEVER && pwflags != PWCHECK_ALWAYS) if (pwflag > 0)
keepall = TRUE; keepall = TRUE;
/* Need to be root while stat'ing things in the parser. */ /* Need to be root while stat'ing things in the parser. */
@@ -143,6 +144,15 @@ sudoers_lookup(pwflags)
if (error || parse_error) if (error || parse_error)
return(VALIDATE_ERROR); return(VALIDATE_ERROR);
/*
* The pw options may have changed during sudoers parse so we
* wait until now to set this.
*/
if (pwflag)
pwcheck = (pwflag == -1) ? PWCHECK_NEVER : def_ival(pwflag);
else
pwcheck = 0;
/* /*
* Assume the worst. If the stack is empty the user was * Assume the worst. If the stack is empty the user was
* not mentioned at all. * not mentioned at all.
@@ -151,7 +161,7 @@ sudoers_lookup(pwflags)
error = VALIDATE_NOT_OK; error = VALIDATE_NOT_OK;
else else
error = VALIDATE_NOT_OK | FLAG_NOPASS; error = VALIDATE_NOT_OK | FLAG_NOPASS;
if (pwflags) { if (pwcheck) {
error |= FLAG_NO_CHECK; error |= FLAG_NO_CHECK;
} else { } else {
error |= FLAG_NO_HOST; error |= FLAG_NO_HOST;
@@ -160,14 +170,14 @@ sudoers_lookup(pwflags)
} }
/* /*
* Only check the actual command if pwflags flag is not set. * Only check the actual command if pwcheck flag is not set.
* It is set for the "validate", "list" and "kill" pseudo-commands. * It is set for the "validate", "list" and "kill" pseudo-commands.
* Always check the host and user. * Always check the host and user.
*/ */
if (pwflags) { if (pwcheck) {
int nopass, found; int nopass, found;
if (pwflags == PWCHECK_NEVER || !def_flag(I_AUTHENTICATE)) if (pwcheck == PWCHECK_NEVER || !def_flag(I_AUTHENTICATE))
nopass = FLAG_NOPASS; nopass = FLAG_NOPASS;
else else
nopass = -1; nopass = -1;
@@ -175,9 +185,9 @@ sudoers_lookup(pwflags)
while (top) { while (top) {
if (host_matches == TRUE) { if (host_matches == TRUE) {
found = 1; found = 1;
if (pwflags == PWCHECK_ANY && no_passwd == TRUE) if (pwcheck == PWCHECK_ANY && no_passwd == TRUE)
nopass = FLAG_NOPASS; nopass = FLAG_NOPASS;
else if (pwflags == PWCHECK_ALL && nopass != 0) else if (pwcheck == PWCHECK_ALL && nopass != 0)
nopass = (no_passwd == TRUE) ? FLAG_NOPASS : 0; nopass = (no_passwd == TRUE) ? FLAG_NOPASS : 0;
} }
top--; top--;

13
sudo.c
View File

@@ -61,6 +61,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netdb.h> #include <netdb.h>
#ifdef HAVE_SETRLIMIT #ifdef HAVE_SETRLIMIT
@@ -176,7 +177,7 @@ main(argc, argv)
int fd; int fd;
int cmnd_status; int cmnd_status;
int sudo_mode; int sudo_mode;
int sudoers_flags; int pwflag;
#ifdef POSIX_SIGNALS #ifdef POSIX_SIGNALS
sigset_t set, oset; sigset_t set, oset;
#else #else
@@ -237,7 +238,7 @@ main(argc, argv)
/* Load the list of local ip addresses and netmasks. */ /* Load the list of local ip addresses and netmasks. */
load_interfaces(); load_interfaces();
sudoers_flags = 0; pwflag = 0;
if (sudo_mode & MODE_SHELL) if (sudo_mode & MODE_SHELL)
user_cmnd = "shell"; user_cmnd = "shell";
else else
@@ -257,12 +258,12 @@ main(argc, argv)
break; break;
case MODE_VALIDATE: case MODE_VALIDATE:
user_cmnd = "validate"; user_cmnd = "validate";
sudoers_flags = def_ival(I_VERIFYPW); pwflag = I_VERIFYPW;
break; break;
case MODE_KILL: case MODE_KILL:
case MODE_INVALIDATE: case MODE_INVALIDATE:
user_cmnd = "kill"; user_cmnd = "kill";
sudoers_flags = PWCHECK_NEVER; pwflag = -1;
break; break;
case MODE_LISTDEFS: case MODE_LISTDEFS:
list_options(); list_options();
@@ -270,8 +271,8 @@ main(argc, argv)
break; break;
case MODE_LIST: case MODE_LIST:
user_cmnd = "list"; user_cmnd = "list";
pwflag = I_LISTPW;
printmatches = 1; printmatches = 1;
sudoers_flags = def_ival(I_LISTPW);
break; break;
} }
@@ -288,7 +289,7 @@ main(argc, argv)
add_env(!(sudo_mode & MODE_SHELL)); /* add in SUDO_* envariables */ add_env(!(sudo_mode & MODE_SHELL)); /* add in SUDO_* envariables */
/* Validate the user but don't search for pseudo-commands. */ /* Validate the user but don't search for pseudo-commands. */
validated = sudoers_lookup(sudoers_flags); validated = sudoers_lookup(pwflag);
/* This goes after the sudoers parse since we honor sudoers options. */ /* This goes after the sudoers parse since we honor sudoers options. */
if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) { if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) {