When determining whether or not "sudo -l" or "sudo -b" should prompt

for a password, take all sudoers sources into account.  In other
words, if both file and ldap sudoers sources are in use, "sudo -v"
will now require that all entries in both sources be have NOPASSWD
(file) or !authenticate (ldap) in the entries.
This commit is contained in:
Todd C. Miller
2016-04-19 10:08:51 -06:00
parent b2d1c457ce
commit 6717c32022
5 changed files with 56 additions and 35 deletions

View File

@@ -3178,22 +3178,17 @@ sudo_ldap_lookup(struct sudo_nss *nss, int ret, int pwflag)
if (matched == true || user_uid == 0) { if (matched == true || user_uid == 0) {
SET(ret, VALIDATE_SUCCESS); SET(ret, VALIDATE_SUCCESS);
CLR(ret, VALIDATE_FAILURE); CLR(ret, VALIDATE_FAILURE);
if (def_authenticate) { switch (pwcheck) {
switch (pwcheck) { case always:
case always: SET(ret, FLAG_CHECK_USER);
SET(ret, FLAG_CHECK_USER); break;
break; case all:
case all: case any:
case any: if (doauth == false)
if (doauth == false) SET(ret, FLAG_NOPASSWD);
def_authenticate = false; break;
break; default:
case never: break;
def_authenticate = false;
break;
default:
break;
}
} }
} }
goto done; goto done;

View File

@@ -197,8 +197,8 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
SET(validated, VALIDATE_FAILURE); SET(validated, VALIDATE_FAILURE);
if (pwcheck == always && def_authenticate) if (pwcheck == always && def_authenticate)
SET(validated, FLAG_CHECK_USER); SET(validated, FLAG_CHECK_USER);
else if (pwcheck == never || nopass == true) else if (nopass == true)
def_authenticate = false; SET(validated, FLAG_NOPASSWD);
debug_return_int(validated); debug_return_int(validated);
} }

View File

@@ -1146,22 +1146,17 @@ sudo_sss_lookup(struct sudo_nss *nss, int ret, int pwflag)
if (matched == true || user_uid == 0) { if (matched == true || user_uid == 0) {
SET(ret, VALIDATE_SUCCESS); SET(ret, VALIDATE_SUCCESS);
CLR(ret, VALIDATE_FAILURE); CLR(ret, VALIDATE_FAILURE);
if (def_authenticate) { switch (pwcheck) {
switch (pwcheck) { case always:
case always: SET(ret, FLAG_CHECK_USER);
SET(ret, FLAG_CHECK_USER); break;
break; case all:
case all: case any:
case any: if (doauth == false)
if (doauth == false) SET(ret, FLAG_NOPASSWD);
def_authenticate = false; break;
break; default:
case never: break;
def_authenticate = false;
break;
default:
break;
}
} }
} }
goto done; goto done;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1993-1996, 1998-2015 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 1993-1996, 1998-2016 Todd C. Miller <Todd.Miller@courtesan.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -261,6 +261,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
char *iolog_path = NULL; char *iolog_path = NULL;
mode_t cmnd_umask = 0777; mode_t cmnd_umask = 0777;
struct sudo_nss *nss; struct sudo_nss *nss;
bool nopass = false;
int cmnd_status = -1, oldlocale, validated; int cmnd_status = -1, oldlocale, validated;
int rval = -1; int rval = -1;
debug_decl(sudoers_policy_main, SUDOERS_DEBUG_PLUGIN) debug_decl(sudoers_policy_main, SUDOERS_DEBUG_PLUGIN)
@@ -343,6 +344,33 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
TAILQ_FOREACH(nss, snl, entries) { TAILQ_FOREACH(nss, snl, entries) {
validated = nss->lookup(nss, validated, pwflag); validated = nss->lookup(nss, validated, pwflag);
/*
* The NOPASSWD tag needs special handling among all sources
* in -l or -v mode.
*/
if (pwflag) {
enum def_tuple pwcheck =
(pwflag == -1) ? never : sudo_defs_table[pwflag].sd_un.tuple;
switch (pwcheck) {
case all:
if (!ISSET(validated, FLAG_NOPASSWD))
nopass = false;
break;
case any:
if (ISSET(validated, FLAG_NOPASSWD))
nopass = true;
break;
case never:
nopass = true;
break;
case always:
nopass = false;
break;
default:
break;
}
}
if (ISSET(validated, VALIDATE_ERROR)) { if (ISSET(validated, VALIDATE_ERROR)) {
/* The lookup function should have printed an error. */ /* The lookup function should have printed an error. */
goto done; goto done;
@@ -356,6 +384,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
break; break;
} }
} }
if (pwflag && nopass)
def_authenticate = false;
/* Restore user's locale. */ /* Restore user's locale. */
sudoers_setlocale(oldlocale, NULL); sudoers_setlocale(oldlocale, NULL);

View File

@@ -123,6 +123,7 @@ struct sudo_user {
#define FLAG_NON_INTERACTIVE 0x100 #define FLAG_NON_INTERACTIVE 0x100
#define FLAG_BAD_PASSWORD 0x200 #define FLAG_BAD_PASSWORD 0x200
#define FLAG_AUTH_ERROR 0x400 #define FLAG_AUTH_ERROR 0x400
#define FLAG_NOPASSWD 0x800
/* /*
* find_path()/set_cmnd() return values * find_path()/set_cmnd() return values