check_user_runcwd: allow -D option if it matches the cwd in sudoers

Previously, check_user_runcwd() would return true if the runcwd
matched the user's cwd, even if sudoers specified a different one.
The user-specified runcwd was ignored but it is better to error out
in this case.  It is now also possible to use "sudo -D" with the
directory specified in sudoers.
This commit is contained in:
Todd C. Miller
2023-06-28 09:59:33 -06:00
parent f2a274b061
commit e7d4c05ace
2 changed files with 27 additions and 17 deletions

View File

@@ -553,10 +553,6 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
if ((user_cwd = strdup("unknown")) == NULL) if ((user_cwd = strdup("unknown")) == NULL)
goto oom; goto oom;
} }
if (user_runcwd == NULL) {
/* Unlike user_cwd, user_runcwd is not free()d. */
user_runcwd = user_cwd;
}
if (user_tty == NULL) { if (user_tty == NULL) {
if ((user_tty = strdup("unknown")) == NULL) if ((user_tty = strdup("unknown")) == NULL)
goto oom; goto oom;
@@ -749,7 +745,7 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
} }
} }
if (def_runcwd && strcmp(def_runcwd, "*") != 0) { if (def_runcwd && strcmp(def_runcwd, "*") != 0) {
/* Set cwd to explicit value in sudoers. */ /* Set cwd to explicit value (sudoers or user-specified). */
if (!expand_tilde(&def_runcwd, runas_pw->pw_name)) { if (!expand_tilde(&def_runcwd, runas_pw->pw_name)) {
sudo_warnx(U_("invalid working directory: %s"), def_runcwd); sudo_warnx(U_("invalid working directory: %s"), def_runcwd);
goto bad; goto bad;

View File

@@ -358,15 +358,30 @@ check_user_runchroot(void)
static int static int
check_user_runcwd(void) check_user_runcwd(void)
{ {
bool allowed = false;
debug_decl(check_user_runcwd, SUDOERS_DEBUG_PLUGIN); debug_decl(check_user_runcwd, SUDOERS_DEBUG_PLUGIN);
if (user_runcwd == NULL)
debug_return_bool(true);
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"def_runcwd %s, user_runcwd %s, user_cwd %s", "def_runcwd %s, user_runcwd %s, user_cwd %s",
def_runcwd ? def_runcwd : "none", user_runcwd ? user_runcwd : "none", def_runcwd ? def_runcwd : "none", user_runcwd ? user_runcwd : "none",
user_cwd ? user_cwd : "none"); user_cwd ? user_cwd : "none");
if (strcmp(user_cwd, user_runcwd) != 0) { if (def_runcwd == NULL) {
if (def_runcwd == NULL || strcmp(def_runcwd, "*") != 0) { /* No runcwd in sudoers, compare against user cwd or runas homedir. */
if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
allowed = strcmp(user_runcwd, runas_pw->pw_dir) == 0;
} else {
allowed = strcmp(user_runcwd, user_cwd) == 0;
}
} else {
/* runcwd is set in sudoers, it must match user_runcwd (or be '*'). */
allowed = strcmp(def_runcwd, "*") == 0 ||
strcmp(def_runcwd, user_runcwd) == 0;
}
if (!allowed) {
log_warningx(SLOG_NO_STDERR|SLOG_AUDIT, log_warningx(SLOG_NO_STDERR|SLOG_AUDIT,
N_("user not allowed to change directory to %s"), user_runcwd); N_("user not allowed to change directory to %s"), user_runcwd);
sudo_warnx(U_("you are not permitted to use the -D option with %s"), sudo_warnx(U_("you are not permitted to use the -D option with %s"),
@@ -378,7 +393,6 @@ check_user_runcwd(void)
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
debug_return_int(-1); debug_return_int(-1);
} }
}
debug_return_bool(true); debug_return_bool(true);
} }