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:
@@ -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;
|
||||||
|
@@ -358,26 +358,40 @@ 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. */
|
||||||
log_warningx(SLOG_NO_STDERR|SLOG_AUDIT,
|
if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
|
||||||
N_("user not allowed to change directory to %s"), user_runcwd);
|
allowed = strcmp(user_runcwd, runas_pw->pw_dir) == 0;
|
||||||
sudo_warnx(U_("you are not permitted to use the -D option with %s"),
|
} else {
|
||||||
user_cmnd);
|
allowed = strcmp(user_runcwd, user_cwd) == 0;
|
||||||
debug_return_bool(false);
|
|
||||||
}
|
|
||||||
free(def_runcwd);
|
|
||||||
if ((def_runcwd = strdup(user_runcwd)) == NULL) {
|
|
||||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
|
||||||
debug_return_int(-1);
|
|
||||||
}
|
}
|
||||||
|
} 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,
|
||||||
|
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"),
|
||||||
|
user_cmnd);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
free(def_runcwd);
|
||||||
|
if ((def_runcwd = strdup(user_runcwd)) == NULL) {
|
||||||
|
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
|
debug_return_int(-1);
|
||||||
}
|
}
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user