From a7137a522548c5bb94d6e4e3b0641bf6c99ec174 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 19 Jul 2019 13:51:23 -0600 Subject: [PATCH] If the command in sudoers does not exist on the file system, match by name. We still want to match the command even if it doesn't exist so that the NOPASSWD flag on sudoers entries with non-existant paths works as expected. Bug #888. --- plugins/sudoers/match_command.c | 17 ++++++++++------- plugins/sudoers/match_digest.c | 3 +++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/plugins/sudoers/match_command.c b/plugins/sudoers/match_command.c index 995a508b4..a92d5fcbe 100644 --- a/plugins/sudoers/match_command.c +++ b/plugins/sudoers/match_command.c @@ -457,20 +457,23 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const /* Open the file for fdexec or for digest matching. */ if (!open_cmnd(sudoers_cmnd, digest, &fd)) goto bad; - if (!do_stat(fd, sudoers_cmnd, &sudoers_stat)) - goto bad; /* - * Return true if inode/device matches AND + * Return true if command matches AND * a) there are no args in sudoers OR * b) there are no args on command line and none req by sudoers OR * c) there are args in sudoers and on command line and they match * d) there is a digest and it matches */ - if (user_stat != NULL && - (user_stat->st_dev != sudoers_stat.st_dev || - user_stat->st_ino != sudoers_stat.st_ino)) - goto bad; + if (user_stat != NULL && do_stat(fd, sudoers_cmnd, &sudoers_stat)) { + if (user_stat->st_dev != sudoers_stat.st_dev || + user_stat->st_ino != sudoers_stat.st_ino) + goto bad; + } else { + /* Either user or sudoers command does not exist, match by name. */ + if (strcmp(user_cmnd, sudoers_cmnd) != 0) + goto bad; + } if (!command_args_match(sudoers_cmnd, sudoers_args)) goto bad; if (digest != NULL && !digest_matches(fd, sudoers_cmnd, digest)) { diff --git a/plugins/sudoers/match_digest.c b/plugins/sudoers/match_digest.c index c2eb17d53..a531185ee 100644 --- a/plugins/sudoers/match_digest.c +++ b/plugins/sudoers/match_digest.c @@ -52,6 +52,9 @@ digest_matches(int fd, const char *file, const struct command_digest *digest) size_t digest_len; debug_decl(digest_matches, SUDOERS_DEBUG_MATCH) + if (fd == -1) + goto done; + file_digest = sudo_filedigest(fd, file, digest->digest_type, &digest_len); if (lseek(fd, (off_t)0, SEEK_SET) == -1) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,