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.
161 lines
5.5 KiB
161 lines
5.5 KiB
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 |
|
|
|
|