Add cwd_optional to command details and enable it in the sudoers plugin.

If cwd_optional is set to true, a failure to set the cwd will be a
warning, not an error, and the command will still run.
Debian bug #598519
This commit is contained in:
Todd C. Miller
2020-03-31 19:43:48 -06:00
parent 9dea4bb244
commit 93aa9f9e90
7 changed files with 55 additions and 6 deletions

5
NEWS
View File

@@ -69,6 +69,11 @@ What's new in Sudo 1.9.0
The list output also now includes the host name if one is present The list output also now includes the host name if one is present
in the log file. in the log file.
* For "sudo -i", if the target user's home directory does not
exist, sudo will now warn about the problem but run the command
in the current working directory. Previously, this was a fatal
error. Debian bug #598519
What's new in Sudo 1.8.31p1 What's new in Sudo 1.8.31p1
* Sudo once again ignores a failure to restore the RLIMIT_CORE * Sudo once again ignores a failure to restore the RLIMIT_CORE

View File

@@ -16,7 +16,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.TH "SUDO_PLUGIN" "5" "February 10, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" .TH "SUDO_PLUGIN" "5" "March 31, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
.nh .nh
.if n .ad l .if n .ad l
.SH "NAME" .SH "NAME"
@@ -886,6 +886,21 @@ Fully qualified path to the command to be executed.
.TP 6n .TP 6n
cwd=string cwd=string
The current working directory to change to when executing the command. The current working directory to change to when executing the command.
If
\fBsudo\fR
is unable to change to the new working directory, the command will
not be run unless
\fIcwd_optional\fR
is also set (see below).
.TP 6n
cwd_optional=bool
If enabled,
\fBsudo\fR
will treat an inability to change to the new working directory as a
non-fatal error.
This setting has no effect unless
\fIcwd\fR
is also set.
.TP 6n .TP 6n
exec_background=bool exec_background=bool
By default, By default,

View File

@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd February 10, 2020 .Dd March 31, 2020
.Dt SUDO_PLUGIN @mansectform@ .Dt SUDO_PLUGIN @mansectform@
.Os Sudo @PACKAGE_VERSION@ .Os Sudo @PACKAGE_VERSION@
.Sh NAME .Sh NAME
@@ -789,6 +789,20 @@ or higher.
Fully qualified path to the command to be executed. Fully qualified path to the command to be executed.
.It cwd=string .It cwd=string
The current working directory to change to when executing the command. The current working directory to change to when executing the command.
If
.Nm sudo
is unable to change to the new working directory, the command will
not be run unless
.Em cwd_optional
is also set (see below).
.It cwd_optional=bool
If enabled,
.Nm sudo
will treat an inability to change to the new working directory as a
non-fatal error.
This setting has no effect unless
.Em cwd
is also set.
.It exec_background=bool .It exec_background=bool
By default, By default,
.Nm sudo .Nm sudo

View File

@@ -564,7 +564,7 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
debug_return_bool(true); /* nothing to do */ debug_return_bool(true); /* nothing to do */
/* Increase the length of command_info as needed, it is *not* checked. */ /* Increase the length of command_info as needed, it is *not* checked. */
command_info = calloc(52, sizeof(char *)); command_info = calloc(53, sizeof(char *));
if (command_info == NULL) if (command_info == NULL)
goto oom; goto oom;
@@ -619,6 +619,8 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
/* Set cwd to run user's homedir. */ /* Set cwd to run user's homedir. */
if ((command_info[info_len++] = sudo_new_key_val("cwd", runas_pw->pw_dir)) == NULL) if ((command_info[info_len++] = sudo_new_key_val("cwd", runas_pw->pw_dir)) == NULL)
goto oom; goto oom;
if ((command_info[info_len++] = strdup("cwd_optional=true")) == NULL)
goto oom;
} }
if ((command_info[info_len++] = sudo_new_key_val("runas_user", runas_pw->pw_name)) == NULL) if ((command_info[info_len++] = sudo_new_key_val("runas_user", runas_pw->pw_name)) == NULL)
goto oom; goto oom;

View File

@@ -214,12 +214,15 @@ exec_setup(struct command_details *details, int errfd)
* specifies a different cwd. Must be done after uid change. * specifies a different cwd. Must be done after uid change.
*/ */
if (details->cwd != NULL) { if (details->cwd != NULL) {
if (details->chroot || user_details.cwd == NULL || if (details->chroot != NULL || user_details.cwd == NULL ||
strcmp(details->cwd, user_details.cwd) != 0) { strcmp(details->cwd, user_details.cwd) != 0) {
/* Note: cwd is relative to the new root, if any. */ /* Note: cwd is relative to the new root, if any. */
if (chdir(details->cwd) != 0) { if (chdir(details->cwd) == -1) {
sudo_warn(U_("unable to change directory to %s"), details->cwd); sudo_warn(U_("unable to change directory to %s"), details->cwd);
goto done; if (!details->cwd_optional)
goto done;
if (details->chroot != NULL)
sudo_warnx(U_("starting from %s"), "/");
} }
} }
} }

View File

@@ -678,6 +678,15 @@ command_info_to_details(char * const info[], struct command_details *details)
SET_STRING("chroot=", chroot) SET_STRING("chroot=", chroot)
SET_STRING("command=", command) SET_STRING("command=", command)
SET_STRING("cwd=", cwd) SET_STRING("cwd=", cwd)
if (strncmp("cwd_optional=", info[i], sizeof("cwd_optional=") - 1) == 0) {
cp = info[i] + sizeof("cwd_optional=") - 1;
details->cwd_optional = sudo_strtobool(cp);
if (details->cwd_optional == -1) {
errno = EINVAL;
sudo_fatal("%s", info[i]);
}
break;
}
if (strncmp("closefrom=", info[i], sizeof("closefrom=") - 1) == 0) { if (strncmp("closefrom=", info[i], sizeof("closefrom=") - 1) == 0) {
cp = info[i] + sizeof("closefrom=") - 1; cp = info[i] + sizeof("closefrom=") - 1;
details->closefrom = sudo_strtonum(cp, 0, INT_MAX, &errstr); details->closefrom = sudo_strtonum(cp, 0, INT_MAX, &errstr);

View File

@@ -157,6 +157,7 @@ struct command_details {
int closefrom; int closefrom;
int flags; int flags;
int execfd; int execfd;
int cwd_optional;
struct preserved_fd_list preserved_fds; struct preserved_fd_list preserved_fds;
struct passwd *pw; struct passwd *pw;
GETGROUPS_T *groups; GETGROUPS_T *groups;