diff --git a/plugins/sudoers/check_util.c b/plugins/sudoers/check_util.c index d98304490..54d397d7a 100644 --- a/plugins/sudoers/check_util.c +++ b/plugins/sudoers/check_util.c @@ -31,31 +31,6 @@ #include "sudoers.h" -/* - * Returns true if the specified shell is allowed by /etc/shells, else false. - */ -bool -check_user_shell(const struct passwd *pw) -{ - const char *shell; - debug_decl(check_user_shell, SUDOERS_DEBUG_AUTH); - - if (!def_runas_check_shell) - debug_return_bool(true); - - sudo_debug_printf(SUDO_DEBUG_INFO, - "%s: checking /etc/shells for %s", __func__, pw->pw_shell); - - setusershell(); - while ((shell = getusershell()) != NULL) { - if (strcmp(shell, pw->pw_shell) == 0) - debug_return_bool(true); - } - endusershell(); - - debug_return_bool(false); -} - /* * Check whether specified runchroot matches def_runchroot. * Returns true if matched, false if not matched and -1 on error. diff --git a/plugins/sudoers/pwutil.c b/plugins/sudoers/pwutil.c index ebdad3b39..6a220fc0f 100644 --- a/plugins/sudoers/pwutil.c +++ b/plugins/sudoers/pwutil.c @@ -1198,3 +1198,17 @@ done: __func__, pw->pw_name, matched ? "" : "NOT ", group); debug_return_bool(matched); } + +/* + * Returns true if the user's shell is considered to be valid. + */ +bool +user_shell_valid(const struct passwd *pw) +{ + debug_decl(user_shell_valid, SUDOERS_DEBUG_NSS); + + if (!def_runas_check_shell) + debug_return_bool(true); + + debug_return_bool(valid_shell(pw->pw_shell)); +} diff --git a/plugins/sudoers/pwutil.h b/plugins/sudoers/pwutil.h index 7bf02a736..c91714961 100644 --- a/plugins/sudoers/pwutil.h +++ b/plugins/sudoers/pwutil.h @@ -73,5 +73,6 @@ struct cache_item *sudo_make_gritem(gid_t gid, const char *group); struct cache_item *sudo_make_grlist_item(const struct passwd *pw, char * const *groups); struct cache_item *sudo_make_gidlist_item(const struct passwd *pw, int ngids, GETGROUPS_T *gids, char * const *gidstrs, unsigned int type); struct cache_item *sudo_make_pwitem(uid_t uid, const char *user); +bool valid_shell(const char *shell); #endif /* SUDOERS_PWUTIL_H */ diff --git a/plugins/sudoers/pwutil_impl.c b/plugins/sudoers/pwutil_impl.c index 6bc7e55d3..87c9a78cd 100644 --- a/plugins/sudoers/pwutil_impl.c +++ b/plugins/sudoers/pwutil_impl.c @@ -449,3 +449,26 @@ again: debug_return_ptr(&grlitem->cache); } + +/* + * Returns true if the specified shell is allowed by /etc/shells, else false. + */ +bool +valid_shell(const char *shell) +{ + const char *entry; + debug_decl(valid_shell, SUDOERS_DEBUG_NSS); + + sudo_debug_printf(SUDO_DEBUG_INFO, + "%s: checking /etc/shells for %s", __func__, shell); + + setusershell(); + while ((entry = getusershell()) != NULL) { + if (strcmp(entry, shell) == 0) + debug_return_bool(true); + } + endusershell(); + + debug_return_bool(false); +} + diff --git a/plugins/sudoers/regress/fuzz/fuzz_policy.c b/plugins/sudoers/regress/fuzz/fuzz_policy.c index a406a9041..6d5cde976 100644 --- a/plugins/sudoers/regress/fuzz/fuzz_policy.c +++ b/plugins/sudoers/regress/fuzz/fuzz_policy.c @@ -728,13 +728,6 @@ check_user_runcwd(const char *runcwd) return true; } -/* STUB */ -bool -check_user_shell(const struct passwd *pw) -{ - return true; -} - /* STUB */ void group_plugin_unload(void) diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index c0e497b0a..d7ace58ef 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -444,7 +444,7 @@ sudoers_check_common(struct sudoers_context *ctx, int pwflag) /* Check runas user's shell if running (or checking) a command. */ if (ISSET(ctx->mode, MODE_RUN|MODE_CHECK)) { - if (!check_user_shell(ctx->runas.pw)) { + if (!user_shell_valid(ctx->runas.pw)) { log_warningx(ctx, SLOG_RAW_MSG|SLOG_AUDIT, N_("invalid shell for user %s: %s"), ctx->runas.pw->pw_name, ctx->runas.pw->pw_shell); diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h index 9b9865e64..7deb34001 100644 --- a/plugins/sudoers/sudoers.h +++ b/plugins/sudoers/sudoers.h @@ -311,7 +311,6 @@ int check_user(struct sudoers_context *ctx, unsigned int validated, unsigned int bool user_is_exempt(const struct sudoers_context *ctx); /* check_util.c */ -bool check_user_shell(const struct passwd *pw); int check_user_runchroot(const char *runchroot); int check_user_runcwd(const char *runcwd); @@ -373,6 +372,7 @@ int sudo_pwutil_get_max_groups(void); void sudo_pwutil_set_max_groups(int); void sudo_pwutil_set_backend(sudo_make_pwitem_t, sudo_make_gritem_t, sudo_make_gidlist_item_t, sudo_make_grlist_item_t); void sudo_setspent(void); +bool user_shell_valid(const struct passwd *pw); /* timestr.c */ char *get_timestr(time_t, int); diff --git a/plugins/sudoers/testsudoers.c b/plugins/sudoers/testsudoers.c index e9df453f5..8ae25b6c3 100644 --- a/plugins/sudoers/testsudoers.c +++ b/plugins/sudoers/testsudoers.c @@ -383,7 +383,7 @@ main(int argc, char *argv[]) /* Validate user-specified chroot or cwd (if any) and runas user shell. */ if (ISSET(validated, VALIDATE_SUCCESS)) { - if (!check_user_shell(test_ctx.runas.pw)) { + if (!user_shell_valid(test_ctx.runas.pw)) { printf(U_("\nInvalid shell for user %s: %s\n"), test_ctx.runas.pw->pw_name, test_ctx.runas.pw->pw_shell); CLR(validated, VALIDATE_SUCCESS);