diff --git a/plugins/sudoers/match_command.c b/plugins/sudoers/match_command.c index 997f8ce0f..db7c2721d 100644 --- a/plugins/sudoers/match_command.c +++ b/plugins/sudoers/match_command.c @@ -33,11 +33,13 @@ #include #include #include -#ifdef HAVE_GLOB -# include -#else -# include "compat/glob.h" -#endif /* HAVE_GLOB */ +#ifndef SUDOERS_NAME_MATCH +# ifdef HAVE_GLOB +# include +# else +# include "compat/glob.h" +# endif /* HAVE_GLOB */ +#endif /* SUDOERS_NAME_MATCH */ #include #include #include @@ -206,6 +208,7 @@ set_cmnd_fd(int fd) debug_return; } +#ifndef SUDOERS_NAME_MATCH /* * Return true if user_cmnd names one of the inodes in dir, else false. */ @@ -290,6 +293,19 @@ command_matches_dir(const char *sudoers_dir, size_t dlen, const char *runchroot, close(fd); debug_return_bool(false); } +#else /* SUDOERS_NAME_MATCH */ +/* + * Return true if user_cmnd names one of the inodes in dir, else false. + */ +static bool +command_matches_dir(const char *sudoers_dir, size_t dlen, const char *runchroot, + const struct command_digest_list *digests) +{ + debug_decl(command_matches_dir, SUDOERS_DEBUG_MATCH); + /* XXX - check digest */ + debug_return_bool(strncmp(user_cmnd, sudoers_dir, dlen) == 0); +} +#endif /* SUDOERS_NAME_MATCH */ static bool command_matches_all(const char *runchroot, @@ -364,6 +380,7 @@ bad: debug_return_bool(false); } +#ifndef SUDOERS_NAME_MATCH static bool command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args, const char *runchroot, const struct command_digest_list *digests) @@ -570,6 +587,41 @@ bad: close(fd); debug_return_bool(false); } +#else /* SUDOERS_NAME_MATCH */ +static bool +command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args, + const char *runchroot, const struct command_digest_list *digests) +{ + return command_matches_fnmatch(sudoers_cmnd, sudoers_args, runchroot, + digests); +} + +static bool +command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, + const char *runchroot, const struct command_digest_list *digests) +{ + size_t dlen; + debug_decl(command_matches_normal, SUDOERS_DEBUG_MATCH); + + /* If it ends in '/' it is a directory spec. */ + dlen = strlen(sudoers_cmnd); + if (sudoers_cmnd[dlen - 1] == '/') { + debug_return_bool(command_matches_dir(sudoers_cmnd, dlen, runchroot, + digests)); + } + + if (strcmp(user_cmnd, sudoers_cmnd) == 0) { + if (command_args_match(sudoers_cmnd, sudoers_args)) { + /* XXX - check digest */ + free(safe_cmnd); + if ((safe_cmnd = strdup(sudoers_cmnd)) != NULL) + debug_return_bool(true); + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + } + } + debug_return_bool(false); +} +#endif /* SUDOERS_NAME_MATCH */ /* * If path doesn't end in /, return true iff cmnd & path name the same inode; diff --git a/plugins/sudoers/match_digest.c b/plugins/sudoers/match_digest.c index 5c39f5297..626f0f93c 100644 --- a/plugins/sudoers/match_digest.c +++ b/plugins/sudoers/match_digest.c @@ -38,6 +38,7 @@ #include "sudo_digest.h" #include +#ifndef SUDOERS_NAME_MATCH bool digest_matches(int fd, const char *path, const char *runchroot, const struct command_digest_list *digests) @@ -133,3 +134,15 @@ done: free(file_digest); debug_return_bool(matched); } +#else /* SUDOERS_NAME_MATCH */ +bool +digest_matches(int fd, const char *path, const char *runchroot, + const struct command_digest_list *digests) +{ + debug_decl(digest_matches, SUDOERS_DEBUG_MATCH); + + /* Digests are not supported when matching only by name. */ + + debug_return_bool(false); +} +#endif /* SUDOERS_NAME_MATCH */ diff --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h index d18bd75c7..2eb97c5e9 100644 --- a/plugins/sudoers/parse.h +++ b/plugins/sudoers/parse.h @@ -29,6 +29,11 @@ /* Returns true if string 's' contains meta characters. */ #define has_meta(s) (strpbrk(s, "\\?*[]") != NULL) +/* Match by name, not inode, when fuzzing. */ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +# define SUDOERS_NAME_MATCH +#endif + #undef UNSPEC #define UNSPEC -1 #undef DENY