Skip to content

Commit 82ebb1e

Browse files
committed
log_failure: only display "command not found" if running a command
If the user is not allowed to run a command, we try to give them a more useful message than "Sorry, user foo may not run sudo on bar." However, this should only be done when running, not listing, a command. Otherwise, it would be possible for a user with no sudo privileges to use "sudo -l /path/to/some/command" to determine whether an executable exists in a directory that they do not have search access to.
1 parent 111fd83 commit 82ebb1e

File tree

1 file changed

+17
-15
lines changed

1 file changed

+17
-15
lines changed

plugins/sudoers/logging.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -369,28 +369,30 @@ bool
369369
log_failure(const struct sudoers_context *ctx, unsigned int status,
370370
int cmnd_status)
371371
{
372-
bool ret, inform_user = true;
372+
bool ret, warn_not_found = false;
373373
debug_decl(log_failure, SUDOERS_DEBUG_LOGGING);
374374

375-
/* The user doesn't always get to see the log message (path info). */
375+
/*
376+
* If the command was not found but the user has a sudoers entry
377+
* for this host, we want to give them a better warning than just
378+
* "Sorry, user foo may not run sudo on bar." Otherwise, a mistyped
379+
* sudo command can make it appear that the user has no sudo
380+
* privileges on the host, even when they do.
381+
*
382+
* This behavior is controlled by the "path_info" setting. We
383+
* only do this when running an actual command since FLAG_NO_USER
384+
* and FLAG_NO_HOST are not set for pseudo-commands like "list".
385+
*/
376386
if (!ISSET(status, FLAG_NO_USER | FLAG_NO_HOST) &&
377-
ctx->runas.list_pw == NULL && def_path_info &&
387+
ISSET(ctx->mode, MODE_RUN) && def_path_info &&
378388
(cmnd_status == NOT_FOUND_DOT || cmnd_status == NOT_FOUND))
379-
inform_user = false;
380-
ret = log_denial(ctx, status, inform_user);
389+
warn_not_found = true;
390+
ret = log_denial(ctx, status, !warn_not_found);
381391

382-
if (!inform_user) {
392+
if (warn_not_found) {
383393
const char *cmnd = ctx->user.cmnd;
384-
if (ISSET(ctx->mode, MODE_CHECK))
385-
cmnd = ctx->user.cmnd_list ? ctx->user.cmnd_list : ctx->runas.argv[1];
386394

387-
/*
388-
* We'd like to not leak path info at all here, but that can
389-
* *really* confuse the users. To really close the leak we'd
390-
* have to say "not allowed to run foo" even when the problem
391-
* is just "no foo in path" since the user can trivially set
392-
* their path to just contain a single dir.
393-
*/
395+
/* This text must be kept in sync with sudoers_check_common() */
394396
if (cmnd_status == NOT_FOUND)
395397
sudo_warnx(U_("%s: command not found"), cmnd);
396398
else if (cmnd_status == NOT_FOUND_DOT)

0 commit comments

Comments
 (0)