diff --git a/doc/sudo_plugin.cat b/doc/sudo_plugin.cat
index 63841c527..81dc3de09 100644
--- a/doc/sudo_plugin.cat
+++ b/doc/sudo_plugin.cat
@@ -61,7 +61,7 @@ SSuuddoo PPlluuggiinn AAPPII
 
 
 
-1.8.0a1                    May 17, 2010                         1
+1.8.0a1                    May 24, 2010                         1
 
 
 
@@ -127,7 +127,7 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
 
-1.8.0a1                    May 17, 2010                         2
+1.8.0a1                    May 24, 2010                         2
 
 
 
@@ -193,7 +193,7 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
 
-1.8.0a1                    May 17, 2010                         3
+1.8.0a1                    May 24, 2010                         3
 
 
 
@@ -242,6 +242,12 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                    error if the plugin does not support _s_u_d_o_e_d_i_t.  For more
                    information, see the _c_h_e_c_k___p_o_l_i_c_y section.
 
+               closefrom=number
+                   If specified, the user has requested via the -C flag that
+                   ssuuddoo close all files descriptors with a value of _n_u_m_b_e_r or
+                   higher.  The plugin may optionally pass this, or another
+                   value, back in the _c_o_m_m_a_n_d___i_n_f_o list.
+
                Additional settings may be added in the future so the plugin
                should silently ignore settings that it does not recognize.
 
@@ -250,16 +256,10 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                the form of "name=value" strings.  The vector is terminated by
                a NULL pointer.
 
-               When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt
-               equal sign ('=') since the _n_a_m_e field will never include one
-               itself but the _v_a_l_u_e might.
-
-               user=string
-                   The name of the user invoking ssuuddoo.
 
 
 
-1.8.0a1                    May 17, 2010                         4
+1.8.0a1                    May 24, 2010                         4
 
 
 
@@ -268,6 +268,13 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+               When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt
+               equal sign ('=') since the _n_a_m_e field will never include one
+               itself but the _v_a_l_u_e might.
+
+               user=string
+                   The name of the user invoking ssuuddoo.
+
                uid=uid_t
                    The real user ID of the user invoking ssuuddoo.
 
@@ -316,16 +323,9 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
            The function arguments are as follows:
 
-           exit_status
-               The command's exit status, as returned by the _w_a_i_t(2) system
-               call.  The value of exit_status is undefined if error is non-
-               zero.
 
 
-
-
-
-1.8.0a1                    May 17, 2010                         5
+1.8.0a1                    May 24, 2010                         5
 
 
 
@@ -334,6 +334,11 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+           exit_status
+               The command's exit status, as returned by the _w_a_i_t(2) system
+               call.  The value of exit_status is undefined if error is non-
+               zero.
+
            error
                If the command could not be executed, this is set to the value
                of errno set by the _e_x_e_c_v_e(2) system call.  The plugin is
@@ -384,14 +389,9 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
            The function arguments are as follows:
 
-           argc
-               The number of elements in _a_r_g_v, not counting the final NULL
-               pointer.
 
 
-
-
-1.8.0a1                    May 17, 2010                         6
+1.8.0a1                    May 24, 2010                         6
 
 
 
@@ -400,6 +400,10 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+           argc
+               The number of elements in _a_r_g_v, not counting the final NULL
+               pointer.
+
            argv
                The argument vector describing the command the user wishes to
                run, in the same form as what would be passed to the _e_x_e_c_v_e_(_)
@@ -451,13 +455,9 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                    nice value (optional).  This option is only set on systems
                    that support login classes.
 
-               preserve_groups=bool
-                   If set, ssuuddoo will preserve the user's group vector instead
-                   of initializing the group vector based on runas_user.
 
 
-
-1.8.0a1                    May 17, 2010                         7
+1.8.0a1                    May 24, 2010                         7
 
 
 
@@ -466,6 +466,10 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+               preserve_groups=bool
+                   If set, ssuuddoo will preserve the user's group vector instead
+                   of initializing the group vector based on runas_user.
+
                cwd=string
                    The current working directory to change to when executing
                    the command.
@@ -501,6 +505,10 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                    transparently enable _s_u_d_o_e_d_i_t when the user attempts to run
                    an editor.
 
+               closefrom=number
+                   If specified, ssuuddoo will close all files descriptors with a
+                   value of _n_u_m_b_e_r or higher.
+
                Unsupported values will be ignored.
 
            argv_out
@@ -513,17 +521,9 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                the command.  The plugin is responsible for allocating and
                populating the vector.
 
-       list
-            int (*list)(int verbose, const char *list_user,
-                        int argc, char * const argv[]);
-
-           List available privileges for the invoking user.  Returns 1 on
-           success, 0 on failure and -1 on error.  On error, the plugin may
-           optionally call the conversation or plugin_printf function with
 
 
-
-1.8.0a1                    May 17, 2010                         8
+1.8.0a1                    May 24, 2010                         8
 
 
 
@@ -532,6 +532,13 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+       list
+            int (*list)(int verbose, const char *list_user,
+                        int argc, char * const argv[]);
+
+           List available privileges for the invoking user.  Returns 1 on
+           success, 0 on failure and -1 on error.  On error, the plugin may
+           optionally call the conversation or plugin_printf function with
            SUDO_CONF_ERROR_MSG to present additional error information to the
            user.
 
@@ -579,17 +586,10 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
            The invalidate function is called when ssuuddoo is called with the -k
            or -K flag.  For policy plugins such as _s_u_d_o_e_r_s that cache
            authentication credentials, this function will invalidate the
-           credentials.  If the _r_e_m_o_v_e flag is set, the plugin may remove the
-           credentials instead of simply invalidating them.
-
-           The invalidate function should be NULL if the plugin does not
-           support credential caching.
-
-       _C_o_n_v_e_r_s_a_t_i_o_n _A_P_I
 
 
 
-1.8.0a1                    May 17, 2010                         9
+1.8.0a1                    May 24, 2010                         9
 
 
 
@@ -598,6 +598,14 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+           credentials.  If the _r_e_m_o_v_e flag is set, the plugin may remove the
+           credentials instead of simply invalidating them.
+
+           The invalidate function should be NULL if the plugin does not
+           support credential caching.
+
+       _C_o_n_v_e_r_s_a_t_i_o_n _A_P_I
+
        If the plugin needs to interact with the user, it may do so via the
        conversation function.  A plugin should not attempt to read directly
        from the standard input or the user's tty (neither of which are
@@ -644,18 +652,10 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
        needed and supports standard _p_r_i_n_t_f_(_) escape sequences.
 
        See the sample plugin for an example of the conversation function
-       usage.
-
-   II//OO PPlluuggiinn AAPPII
 
 
 
-
-
-
-
-
-1.8.0a1                    May 17, 2010                        10
+1.8.0a1                    May 24, 2010                        10
 
 
 
@@ -664,6 +664,9 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+       usage.
+
+   II//OO PPlluuggiinn AAPPII
         struct io_plugin {
         #define SUDO_IO_PLUGIN         2
             unsigned int type; /* always SUDO_IO_PLUGIN */
@@ -716,12 +719,9 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                         char * const user_info[], int argc, char * const argv[],
                         char * const user_env[]);
 
-           The _o_p_e_n function is run before the _l_o_g___i_n_p_u_t, _l_o_g___o_u_t_p_u_t or
-           _s_h_o_w___v_e_r_s_i_o_n functions are called.  It is only called if the
 
 
-
-1.8.0a1                    May 17, 2010                        11
+1.8.0a1                    May 24, 2010                        11
 
 
 
@@ -730,6 +730,8 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+           The _o_p_e_n function is run before the _l_o_g___i_n_p_u_t, _l_o_g___o_u_t_p_u_t or
+           _s_h_o_w___v_e_r_s_i_o_n functions are called.  It is only called if the
            version is being requested or the _c_h_e_c_k___p_o_l_i_c_y function has
            returned successfully.  It returns 1 on success, 0 on failure, -1
            if a general error occurred, or -2 if there was a usage error.  In
@@ -785,9 +787,7 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
 
-
-
-1.8.0a1                    May 17, 2010                        12
+1.8.0a1                    May 24, 2010                        12
 
 
 
@@ -853,7 +853,7 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
 
-1.8.0a1                    May 17, 2010                        13
+1.8.0a1                    May 24, 2010                        13
 
 
 
@@ -919,7 +919,7 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
 
-1.8.0a1                    May 17, 2010                        14
+1.8.0a1                    May 24, 2010                        14
 
 
 
@@ -979,12 +979,12 @@ PPOODD EERRRROORRSS
        Hey! TThhee aabboovvee ddooccuummeenntt hhaadd ssoommee ccooddiinngg eerrrroorrss,, wwhhiicchh aarree eexxppllaaiinneedd
        bbeellooww::
 
-       Around line 597:
+       Around line 609:
            You forgot a '=back' before '=head3'
 
 
 
 
-1.8.0a1                    May 17, 2010                        15
+1.8.0a1                    May 24, 2010                        15
 
 
diff --git a/doc/sudo_plugin.man.in b/doc/sudo_plugin.man.in
index b3e76cc13..52f49d839 100644
--- a/doc/sudo_plugin.man.in
+++ b/doc/sudo_plugin.man.in
@@ -139,7 +139,7 @@
 .\" ========================================================================
 .\"
 .IX Title "SUDO_PLUGIN @mansectsu@"
-.TH SUDO_PLUGIN @mansectsu@ "May 17, 2010" "1.8.0a1" "MAINTENANCE COMMANDS"
+.TH SUDO_PLUGIN @mansectsu@ "May 24, 2010" "1.8.0a1" "MAINTENANCE COMMANDS"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -352,6 +352,12 @@ Set to true when the \f(CW\*(C`\-e\*(C'\fR flag is is specified or if invoked as
 in the \fIcheck_policy\fR function or return \f(CW\*(C`\-2\*(C'\fR with a usage error
 if the plugin does not support \fIsudoedit\fR.  For more information,
 see the \fIcheck_policy\fR section.
+.IP "closefrom=number" 4
+.IX Item "closefrom=number"
+If specified, the user has requested via the \f(CW\*(C`\-C\*(C'\fR flag that \fBsudo\fR
+close all files descriptors with a value of \fInumber\fR or higher.
+The plugin may optionally pass this, or another value, back in the
+\&\fIcommand_info\fR list.
 .RE
 .RS 4
 .Sp
@@ -578,6 +584,10 @@ Set to true when in \fIsudoedit\fR mode.  The plugin may enable
 \&\fIsudoedit\fR mode even if \fBsudo\fR was not invoked as \fBsudoedit\fR.
 This allows the plugin to perform command substitution and transparently
 enable \fIsudoedit\fR when the user attempts to run an editor.
+.IP "closefrom=number" 4
+.IX Item "closefrom=number"
+If specified, \fBsudo\fR will close all files descriptors with a value
+of \fInumber\fR or higher.
 .RE
 .RS 4
 .Sp
@@ -1045,6 +1055,6 @@ the plugin type.
 .SH "POD ERRORS"
 .IX Header "POD ERRORS"
 Hey! \fBThe above document had some coding errors, which are explained below:\fR
-.IP "Around line 597:" 4
-.IX Item "Around line 597:"
+.IP "Around line 609:" 4
+.IX Item "Around line 609:"
 You forgot a '=back' before '=head3'
diff --git a/doc/sudo_plugin.pod b/doc/sudo_plugin.pod
index 07b9034a6..e866f2309 100644
--- a/doc/sudo_plugin.pod
+++ b/doc/sudo_plugin.pod
@@ -248,6 +248,13 @@ in the I<check_policy> function or return C<-2> with a usage error
 if the plugin does not support I<sudoedit>.  For more information,
 see the I<check_policy> section.
 
+=item closefrom=number
+
+If specified, the user has requested via the C<-C> flag that B<sudo>
+close all files descriptors with a value of I<number> or higher.
+The plugin may optionally pass this, or another value, back in the
+I<command_info> list.
+
 =back
 
 Additional settings may be added in the future so the plugin should
@@ -505,6 +512,11 @@ I<sudoedit> mode even if B<sudo> was not invoked as B<sudoedit>.
 This allows the plugin to perform command substitution and transparently
 enable I<sudoedit> when the user attempts to run an editor.
 
+=item closefrom=number
+
+If specified, B<sudo> will close all files descriptors with a value
+of I<number> or higher.
+
 =back
 
 Unsupported values will be ignored.
diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c
index 7902f73bf..46a0cd6a4 100644
--- a/plugins/sudoers/sudoers.c
+++ b/plugins/sudoers/sudoers.c
@@ -289,14 +289,21 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
     int info_len = 0;
     int rval = FALSE;
 
-    /* refactor so list can use it too */
-
     /* Is root even allowed to run sudo? */
     if (user_uid == 0 && !def_root_sudo) {
         warningx("sudoers specifies that root is not allowed to sudo");
         goto done;
     }    
 
+    /* Check for -C overriding def_closefrom. */
+    if (user_closefrom >= 0 && user_closefrom != def_closefrom) {
+	if (!def_closefrom_override) {
+	    warningx("you are not permitted to use the -C option");
+	    goto done;
+	}
+	def_closefrom = user_closefrom;
+    }
+
     if (sigsetjmp(error_jmp, 1)) {
 	/* error recovery via error(), errorx() or log_error() */
 	rewind_perms();
@@ -599,6 +606,8 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
 	}
 	command_info[info_len++] = gid_list;
     }
+    if (def_closefrom >= 0)
+	easprintf(&command_info[info_len++], "closefrom=%d", def_closefrom);
 
     /* Must audit before uid change. */
     audit_success(NewArgv);
@@ -1169,7 +1178,12 @@ deserialize_info(char * const settings[], char * const user_info[])
 #define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0)
 
     /* Parse command line settings. */
+    user_closefrom = -1;
     for (cur = settings; *cur != NULL; cur++) {
+	if (MATCHES(*cur, "closefrom=")) {
+	    user_closefrom = atoi(*cur + sizeof("closefrom=") - 1);
+	    continue;
+	}
 	if (MATCHES(*cur, "debug_level=")) {
 	    debug_level = atoi(*cur + sizeof("debug_level=") - 1);
 	    continue;
diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h
index bf95ac783..0b7661702 100644
--- a/plugins/sudoers/sudoers.h
+++ b/plugins/sudoers/sudoers.h
@@ -62,6 +62,7 @@ struct sudo_user {
     char *krb5_ccname;
     char *display;
     char *askpass;
+    int   closefrom;
     int   ngroups;
     uid_t uid;
     uid_t gid;
@@ -178,6 +179,7 @@ struct sudo_user {
 #define runas_gr		(sudo_user._runas_gr)
 #define user_role		(sudo_user.role)
 #define user_type		(sudo_user.type)
+#define user_closefrom		(sudo_user.closefrom)
 
 /*
  * We used to use the system definition of PASS_MAX or _PASSWD_LEN,
diff --git a/src/parse_args.c b/src/parse_args.c
index 59e1595e2..f6e490cd9 100644
--- a/src/parse_args.c
+++ b/src/parse_args.c
@@ -60,7 +60,6 @@ extern struct user_details user_details;
 
 /* XXX - better home for these and extern in header file */
 int tgetpass_flags;
-int user_closefrom = -1;
 const char *list_user, *runas_user, *runas_group;
 
 /*
@@ -109,7 +108,9 @@ static struct sudo_settings {
     { "noninteractive" },
 #define ARG_SUDOEDIT 16
     { "sudoedit" },
-#define NUM_SETTINGS 17
+#define ARG_CLOSEFROM 17
+    { "closefrom" },
+#define NUM_SETTINGS 18
     { NULL }
 };
 
@@ -174,10 +175,11 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
 		    SET(flags, MODE_BACKGROUND);
 		    break;
 		case 'C':
-		    if ((user_closefrom = atoi(optarg)) < 3) {
+		    if (atoi(optarg) < 3) {
 			warningx("the argument to -C must be at least 3");
 			usage(1);
 		    }
+		    sudo_settings[ARG_CLOSEFROM].value = optarg;
 		    break;
 #ifdef HAVE_LOGIN_CAP_H
 		case 'c':
diff --git a/src/script.c b/src/script.c
index caef0dc9b..42e57ee7e 100644
--- a/src/script.c
+++ b/src/script.c
@@ -125,8 +125,12 @@ static int suspend_parent(int signo, struct io_buffer *iobufs);
 static void flush_output(struct io_buffer *iobufs);
 static int perform_io(struct io_buffer *iobufs, fd_set *fdsr, fd_set *fdsw);
 static void handler(int s);
-static int script_child(const char *path, char *argv[], char *envp[], int, int);
-static void script_run(const char *path, char *argv[], char *envp[], int);
+static int my_execve(const char *path, char *const argv[],
+    char *const envp[]);
+static int script_child(struct command_details *details, char *argv[],
+    char *envp[], int, int);
+static void script_run(struct command_details *detail, char *argv[],
+    char *envp[], int);
 static void sigwinch(int s);
 static void sync_ttysize(int src, int dst);
 static void deliver_signal(pid_t pid, int signo);
@@ -353,7 +357,7 @@ suspend_parent(int signo, struct io_buffer *iobufs)
 
 /*
  * Like execve(2) but falls back to running through /bin/sh
- * like execvp(3) if we get ENOEXEC.
+ * ala execvp(3) if we get ENOEXEC.
  */
 static int
 my_execve(const char *path, char *const argv[], char *const envp[])
@@ -637,6 +641,7 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
 	/* child */
 	close(sv[0]);
 	fcntl(sv[1], F_SETFD, FD_CLOEXEC);
+	/* XXX - defer call to exec_setup() until my_execve()? */
 	if (exec_setup(details) == 0) {
 	    /* headed for execve() */
 	    if (log_io) {
@@ -647,8 +652,10 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
 		    close(io_pipe[STDOUT_FILENO][0]);
 		if (io_pipe[STDERR_FILENO][0])
 		    close(io_pipe[STDERR_FILENO][0]);
-		script_child(details->command, argv, envp, sv[1], rbac_enabled);
+		script_child(details, argv, envp, sv[1], rbac_enabled);
 	    } else {
+		if (details->closefrom >= 0)
+		    closefrom(details->closefrom);
 #ifdef HAVE_SELINUX
 		if (rbac_enabled)
 		    selinux_execve(details->command, argv, envp);
@@ -979,7 +986,8 @@ handle_sigchld(int backchannel, struct command_status *cstat)
  * Returns an error if fork(2) fails, else calls _exit(2).
  */
 int
-script_child(const char *path, char *argv[], char *envp[], int backchannel, int rbac)
+script_child(struct command_details *details, char *argv[], char *envp[],
+    int backchannel, int rbac)
 {
     struct command_status cstat;
     struct timeval tv;
@@ -1083,7 +1091,7 @@ script_child(const char *path, char *argv[], char *envp[], int backchannel, int
 	fcntl(errpipe[1], F_SETFD, FD_CLOEXEC);
 
 	/* setup tty and exec command */
-	script_run(path, argv, envp, rbac);
+	script_run(details, argv, envp, rbac);
 	cstat.type = CMD_ERRNO;
 	cstat.val = errno;
 	write(errpipe[1], &cstat, sizeof(cstat));
@@ -1265,7 +1273,8 @@ flush_output(struct io_buffer *iobufs)
  * Returns only if execve() fails.
  */
 static void
-script_run(const char *path, char *argv[], char *envp[], int rbac_enabled)
+script_run(struct command_details *details, char *argv[], char *envp[],
+    int rbac_enabled)
 {
     pid_t self = getpid();
 
@@ -1293,12 +1302,14 @@ script_run(const char *path, char *argv[], char *envp[], int rbac_enabled)
     if (script_fds[SFD_STDERR] != script_fds[SFD_SLAVE])
 	close(script_fds[SFD_STDERR]);
 
+    if (details->closefrom >= 0)
+	closefrom(details->closefrom);
 #ifdef HAVE_SELINUX
     if (rbac_enabled)
-	selinux_execve(path, argv, envp);
+	selinux_execve(details->command, argv, envp);
     else
 #endif
-    my_execve(path, argv, envp);
+	my_execve(details->command, argv, envp);
 }
 
 /*
diff --git a/src/selinux.c b/src/selinux.c
index 1e71acefc..c1c97658f 100644
--- a/src/selinux.c
+++ b/src/selinux.c
@@ -240,7 +240,7 @@ selinux_prefork(char *role, char *type, int ttyfd)
 }
 
 void
-selinux_execv(char *path, char **argv)
+selinux_execve(const char *path, char *argv[], char *envp[])
 {
     if (setexeccon(new_context)) {
 	warning("unable to set exec context to %s", new_context);
@@ -260,11 +260,12 @@ selinux_execv(char *path, char **argv)
 #endif
 
     /* We use the "spare" slot in argv to store sesh. */
+    /* XXX - no longer can do this XXX */
     --argv;
     argv[0] = *argv[1] == '-' ? "-sesh" : "sesh";
-    argv[1] = path;
+    argv[1] = (char *)path;
 
-    execv(_PATH_SUDO_SESH, argv);
+    execve(_PATH_SUDO_SESH, argv, envp);
     warning("%s", path);
 }
 
diff --git a/src/sudo.c b/src/sudo.c
index d9a0d0730..004617381 100644
--- a/src/sudo.c
+++ b/src/sudo.c
@@ -393,6 +393,7 @@ command_info_to_details(char * const info[], struct command_details *details)
     char *cp, *ep;
 
     memset(details, 0, sizeof(*details));
+    details->closefrom = -1;
 
 #define SET_STRING(s, n) \
     if (strncmp(s, info[i], sizeof(s) - 1) == 0 && info[i][sizeof(s) - 1]) { \
@@ -407,6 +408,20 @@ command_info_to_details(char * const info[], struct command_details *details)
 		SET_STRING("chroot=", chroot)
 		SET_STRING("command=", command)
 		SET_STRING("cwd=", cwd)
+		if (strncmp("closefrom=", info[i], sizeof("closefrom=") - 1) == 0) {
+		    cp = info[i] + sizeof("closefrom=") - 1;
+		    if (*cp == '\0')
+			break;
+		    errno = 0;
+		    lval = strtol(cp, &ep, 0);
+		    if (*cp != '\0' && *ep == '\0' &&
+			!(errno == ERANGE &&
+			(lval == LONG_MAX || lval == LONG_MIN)) &&
+			lval < INT_MAX && lval > INT_MIN) {
+			details->closefrom = (int)lval;
+		    }
+		    break;
+		}
 		break;
 	    case 'l':
 		SET_STRING("login_class=", login_class)
diff --git a/src/sudo.h b/src/sudo.h
index 76bb5c81e..27e0c2417 100644
--- a/src/sudo.h
+++ b/src/sudo.h
@@ -127,6 +127,7 @@ struct command_details {
     int priority;
     int timeout;
     int ngroups;
+    int closefrom;
     GETGROUPS_T *groups;
     const char *command;
     const char *cwd;
