You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
5.5 KiB
162 lines
5.5 KiB
7 years ago
|
From 9b1f0f16bfe7552810b4adb6b17ac3674da660f9 Mon Sep 17 00:00:00 2001
|
||
|
From: Tomas Sykora <tosykora@redhat.com>
|
||
|
Date: Mon, 15 Aug 2016 15:13:31 +0200
|
||
|
Subject: [PATCH] Backport direct exec of command from sudo
|
||
|
|
||
|
Added cmnd_no_wait option
|
||
|
Sudo does not run command in a new child process,
|
||
|
when cmnd_no_wait is enabled.
|
||
|
|
||
|
!!!
|
||
|
Upstream can do that too now in 1.8.17 with combination of
|
||
|
pam_session, pam_setcred and use_pty option.
|
||
|
They must be disabled and I/O logging must not be configured.
|
||
|
See "man sudoers".
|
||
|
|
||
|
rebased from:
|
||
|
Patch8: sudo-1.8.6p3-nowaitopt.patch
|
||
|
|
||
|
Resolves:
|
||
|
rhbz#840980
|
||
|
---
|
||
|
plugins/sudoers/def_data.c | 4 ++++
|
||
|
plugins/sudoers/def_data.h | 2 ++
|
||
|
plugins/sudoers/def_data.in | 3 +++
|
||
|
plugins/sudoers/policy.c | 4 ++++
|
||
|
src/exec.c | 34 ++++++++++++++++++++++++++++++++++
|
||
|
src/sudo.c | 5 +++++
|
||
|
src/sudo.h | 1 +
|
||
|
7 files changed, 53 insertions(+)
|
||
|
|
||
|
diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c
|
||
|
index 00caa8b..d8b1ada 100644
|
||
|
--- a/plugins/sudoers/def_data.c
|
||
|
+++ b/plugins/sudoers/def_data.c
|
||
|
@@ -435,6 +435,10 @@ struct sudo_defs_types sudo_defs_table[] = {
|
||
|
N_("File mode to use for the I/O log files: 0%o"),
|
||
|
NULL,
|
||
|
}, {
|
||
|
+ "cmnd_no_wait", T_FLAG,
|
||
|
+ N_("Don't fork and wait for the command to finish, just exec it"),
|
||
|
+ NULL,
|
||
|
+ }, {
|
||
|
NULL, 0, NULL
|
||
|
}
|
||
|
};
|
||
|
diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h
|
||
|
index d83d2c3..1b6be3d 100644
|
||
|
--- a/plugins/sudoers/def_data.h
|
||
|
+++ b/plugins/sudoers/def_data.h
|
||
|
@@ -204,6 +204,8 @@
|
||
|
#define def_iolog_group (sudo_defs_table[I_IOLOG_GROUP].sd_un.str)
|
||
|
#define I_IOLOG_MODE 102
|
||
|
#define def_iolog_mode (sudo_defs_table[I_IOLOG_MODE].sd_un.mode)
|
||
|
+#define I_CMND_NO_WAIT 103
|
||
|
+#define def_cmnd_no_wait (sudo_defs_table[I_CMND_NO_WAIT].sd_un.flag)
|
||
|
|
||
|
enum def_tuple {
|
||
|
never,
|
||
|
diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in
|
||
|
index 9f069f1..5200fe3 100644
|
||
|
--- a/plugins/sudoers/def_data.in
|
||
|
+++ b/plugins/sudoers/def_data.in
|
||
|
@@ -322,3 +322,6 @@ iolog_group
|
||
|
iolog_mode
|
||
|
T_MODE
|
||
|
"File mode to use for the I/O log files: 0%o"
|
||
|
+cmnd_no_wait
|
||
|
+ T_FLAG
|
||
|
+ "Don't fork and wait for the command to finish, just exec it"
|
||
|
diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c
|
||
|
index 4ee1e28..93df1dd 100644
|
||
|
--- a/plugins/sudoers/policy.c
|
||
|
+++ b/plugins/sudoers/policy.c
|
||
|
@@ -564,6 +564,10 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
|
||
|
if ((command_info[info_len++] = strdup("use_pty=true")) == NULL)
|
||
|
goto oom;
|
||
|
}
|
||
|
+ if (def_cmnd_no_wait) {
|
||
|
+ if ((command_info[info_len++] = strdup("cmnd_no_wait=true")) == NULL)
|
||
|
+ goto oom;
|
||
|
+ }
|
||
|
if (def_utmp_runas) {
|
||
|
if ((command_info[info_len++] = sudo_new_key_val("utmp_user", runas_pw->pw_name)) == NULL)
|
||
|
goto oom;
|
||
|
diff --git a/src/exec.c b/src/exec.c
|
||
|
index 56da013..08bc86d 100644
|
||
|
--- a/src/exec.c
|
||
|
+++ b/src/exec.c
|
||
|
@@ -384,6 +384,41 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
+ * If we don't want to wait for the command to exit, then just exec it.
|
||
|
+ * THIS WILL BREAK SEVERAL THINGS including SELinux, PAM sessions and I/O
|
||
|
+ * logging. Implemented because of rhbz#840980 (backwards compatibility).
|
||
|
+ * In 1.8.x branch this is even harder to get back, since the nowait code
|
||
|
+ * was completely removed.
|
||
|
+ */
|
||
|
+ if (details->flags & CD_DONTWAIT) {
|
||
|
+ if (exec_setup(details, NULL, -1) == true) {
|
||
|
+ restore_signals();
|
||
|
+ /* headed for execve() */
|
||
|
+ sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
|
||
|
+ details->argv, details->envp);
|
||
|
+ if (details->closefrom >= 0) {
|
||
|
+ closefrom(details->closefrom);
|
||
|
+ }
|
||
|
+#ifdef HAVE_SELINUX
|
||
|
+ if (ISSET(details->flags, CD_RBAC_ENABLED)) {
|
||
|
+ selinux_execve(-1, details->command, details->argv, details->envp,
|
||
|
+ ISSET(details->flags, CD_NOEXEC));
|
||
|
+ } else
|
||
|
+#endif
|
||
|
+ {
|
||
|
+ sudo_execve(-1, details->command, details->argv, details->envp,
|
||
|
+ ISSET(details->flags, CD_NOEXEC));
|
||
|
+ }
|
||
|
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to exec %s: %s",
|
||
|
+ details->command, strerror(errno));
|
||
|
+ }
|
||
|
+ cstat->type = CMD_ERRNO;
|
||
|
+ cstat->val = errno;
|
||
|
+ return 127;
|
||
|
+ }
|
||
|
+
|
||
|
+
|
||
|
+ /*
|
||
|
* We communicate with the child over a bi-directional pair of sockets.
|
||
|
* Parent sends signal info to child and child sends back wait status.
|
||
|
*/
|
||
|
diff --git a/src/sudo.c b/src/sudo.c
|
||
|
index 5dd090d..0606a19 100644
|
||
|
--- a/src/sudo.c
|
||
|
+++ b/src/sudo.c
|
||
|
@@ -670,6 +670,11 @@ command_info_to_details(char * const info[], struct command_details *details)
|
||
|
sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
|
||
|
break;
|
||
|
}
|
||
|
+ if (strncmp("cmnd_no_wait=", info[i], sizeof("cmnd_no_wait=") - 1) == 0) {
|
||
|
+ if (sudo_strtobool(info[i] + sizeof("cmnd_no_wait=") - 1) == true)
|
||
|
+ SET(details->flags, CD_DONTWAIT);
|
||
|
+ break;
|
||
|
+ }
|
||
|
break;
|
||
|
case 'e':
|
||
|
SET_FLAG("exec_background=", CD_EXEC_BG)
|
||
|
diff --git a/src/sudo.h b/src/sudo.h
|
||
|
index 3ac2c9d..f07ba11 100644
|
||
|
--- a/src/sudo.h
|
||
|
+++ b/src/sudo.h
|
||
|
@@ -130,6 +130,7 @@ struct user_details {
|
||
|
#define CD_SUDOEDIT_FOLLOW 0x10000
|
||
|
#define CD_SUDOEDIT_CHECKDIR 0x20000
|
||
|
#define CD_SET_GROUPS 0x40000
|
||
|
+#define CD_DONTWAIT 0x80000
|
||
|
|
||
|
struct preserved_fd {
|
||
|
TAILQ_ENTRY(preserved_fd) entries;
|
||
|
--
|
||
|
2.7.4
|
||
|
|