Bring back closefrom settings.

This commit is contained in:
Todd C. Miller
2010-05-24 15:40:36 -04:00
parent 60e0e496ef
commit 0487aee6b4
10 changed files with 154 additions and 86 deletions

View File

@@ -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 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. 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 Additional settings may be added in the future so the plugin
should silently ignore settings that it does not recognize. 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 the form of "name=value" strings. The vector is terminated by
a NULL pointer. 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) 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 uid=uid_t
The real user ID of the user invoking ssuuddoo. 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: 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 24, 2010 5
1.8.0a1 May 17, 2010 5
@@ -334,6 +334,11 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
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 error
If the command could not be executed, this is set to the value 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 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: 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 24, 2010 6
1.8.0a1 May 17, 2010 6
@@ -400,6 +400,10 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
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 argv
The argument vector describing the command the user wishes to 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_(_) 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 nice value (optional). This option is only set on systems
that support login classes. 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 24, 2010 7
1.8.0a1 May 17, 2010 7
@@ -466,6 +466,10 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
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 cwd=string
The current working directory to change to when executing The current working directory to change to when executing
the command. 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 transparently enable _s_u_d_o_e_d_i_t when the user attempts to run
an editor. 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. Unsupported values will be ignored.
argv_out argv_out
@@ -513,17 +521,9 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
the command. The plugin is responsible for allocating and the command. The plugin is responsible for allocating and
populating the vector. 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 24, 2010 8
1.8.0a1 May 17, 2010 8
@@ -532,6 +532,13 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
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 SUDO_CONF_ERROR_MSG to present additional error information to the
user. 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 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 or -K flag. For policy plugins such as _s_u_d_o_e_r_s that cache
authentication credentials, this function will invalidate the 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) 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 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 conversation function. A plugin should not attempt to read directly
from the standard input or the user's tty (neither of which are 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. needed and supports standard _p_r_i_n_t_f_(_) escape sequences.
See the sample plugin for an example of the conversation function See the sample plugin for an example of the conversation function
usage.
II//OO PPlluuggiinn AAPPII
1.8.0a1 May 24, 2010 10
1.8.0a1 May 17, 2010 10
@@ -664,6 +664,9 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
usage.
II//OO PPlluuggiinn AAPPII
struct io_plugin { struct io_plugin {
#define SUDO_IO_PLUGIN 2 #define SUDO_IO_PLUGIN 2
unsigned int type; /* always SUDO_IO_PLUGIN */ 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_info[], int argc, char * const argv[],
char * const user_env[]); 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 24, 2010 11
1.8.0a1 May 17, 2010 11
@@ -730,6 +730,8 @@ SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m)
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 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 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 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 24, 2010 12
1.8.0a1 May 17, 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 Hey! TThhee aabboovvee ddooccuummeenntt hhaadd ssoommee ccooddiinngg eerrrroorrss,, wwhhiicchh aarree eexxppllaaiinneedd
bbeellooww:: bbeellooww::
Around line 597: Around line 609:
You forgot a '=back' before '=head3' You forgot a '=back' before '=head3'
1.8.0a1 May 17, 2010 15 1.8.0a1 May 24, 2010 15

View File

@@ -139,7 +139,7 @@
.\" ======================================================================== .\" ========================================================================
.\" .\"
.IX Title "SUDO_PLUGIN @mansectsu@" .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 .\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents. .\" way too many mistakes in technical documents.
.if n .ad l .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 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, if the plugin does not support \fIsudoedit\fR. For more information,
see the \fIcheck_policy\fR section. 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 .RE
.RS 4 .RS 4
.Sp .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. \&\fIsudoedit\fR mode even if \fBsudo\fR was not invoked as \fBsudoedit\fR.
This allows the plugin to perform command substitution and transparently This allows the plugin to perform command substitution and transparently
enable \fIsudoedit\fR when the user attempts to run an editor. 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 .RE
.RS 4 .RS 4
.Sp .Sp
@@ -1045,6 +1055,6 @@ the plugin type.
.SH "POD ERRORS" .SH "POD ERRORS"
.IX Header "POD ERRORS" .IX Header "POD ERRORS"
Hey! \fBThe above document had some coding errors, which are explained below:\fR Hey! \fBThe above document had some coding errors, which are explained below:\fR
.IP "Around line 597:" 4 .IP "Around line 609:" 4
.IX Item "Around line 597:" .IX Item "Around line 609:"
You forgot a '=back' before '=head3' You forgot a '=back' before '=head3'

View File

@@ -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, if the plugin does not support I<sudoedit>. For more information,
see the I<check_policy> section. 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 =back
Additional settings may be added in the future so the plugin should 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 This allows the plugin to perform command substitution and transparently
enable I<sudoedit> when the user attempts to run an editor. 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 =back
Unsupported values will be ignored. Unsupported values will be ignored.

View File

@@ -289,14 +289,21 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
int info_len = 0; int info_len = 0;
int rval = FALSE; int rval = FALSE;
/* refactor so list can use it too */
/* Is root even allowed to run sudo? */ /* Is root even allowed to run sudo? */
if (user_uid == 0 && !def_root_sudo) { if (user_uid == 0 && !def_root_sudo) {
warningx("sudoers specifies that root is not allowed to sudo"); warningx("sudoers specifies that root is not allowed to sudo");
goto done; 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)) { if (sigsetjmp(error_jmp, 1)) {
/* error recovery via error(), errorx() or log_error() */ /* error recovery via error(), errorx() or log_error() */
rewind_perms(); 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; command_info[info_len++] = gid_list;
} }
if (def_closefrom >= 0)
easprintf(&command_info[info_len++], "closefrom=%d", def_closefrom);
/* Must audit before uid change. */ /* Must audit before uid change. */
audit_success(NewArgv); 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) #define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0)
/* Parse command line settings. */ /* Parse command line settings. */
user_closefrom = -1;
for (cur = settings; *cur != NULL; cur++) { for (cur = settings; *cur != NULL; cur++) {
if (MATCHES(*cur, "closefrom=")) {
user_closefrom = atoi(*cur + sizeof("closefrom=") - 1);
continue;
}
if (MATCHES(*cur, "debug_level=")) { if (MATCHES(*cur, "debug_level=")) {
debug_level = atoi(*cur + sizeof("debug_level=") - 1); debug_level = atoi(*cur + sizeof("debug_level=") - 1);
continue; continue;

View File

@@ -62,6 +62,7 @@ struct sudo_user {
char *krb5_ccname; char *krb5_ccname;
char *display; char *display;
char *askpass; char *askpass;
int closefrom;
int ngroups; int ngroups;
uid_t uid; uid_t uid;
uid_t gid; uid_t gid;
@@ -178,6 +179,7 @@ struct sudo_user {
#define runas_gr (sudo_user._runas_gr) #define runas_gr (sudo_user._runas_gr)
#define user_role (sudo_user.role) #define user_role (sudo_user.role)
#define user_type (sudo_user.type) #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, * We used to use the system definition of PASS_MAX or _PASSWD_LEN,

View File

@@ -60,7 +60,6 @@ extern struct user_details user_details;
/* XXX - better home for these and extern in header file */ /* XXX - better home for these and extern in header file */
int tgetpass_flags; int tgetpass_flags;
int user_closefrom = -1;
const char *list_user, *runas_user, *runas_group; const char *list_user, *runas_user, *runas_group;
/* /*
@@ -109,7 +108,9 @@ static struct sudo_settings {
{ "noninteractive" }, { "noninteractive" },
#define ARG_SUDOEDIT 16 #define ARG_SUDOEDIT 16
{ "sudoedit" }, { "sudoedit" },
#define NUM_SETTINGS 17 #define ARG_CLOSEFROM 17
{ "closefrom" },
#define NUM_SETTINGS 18
{ NULL } { NULL }
}; };
@@ -174,10 +175,11 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
SET(flags, MODE_BACKGROUND); SET(flags, MODE_BACKGROUND);
break; break;
case 'C': case 'C':
if ((user_closefrom = atoi(optarg)) < 3) { if (atoi(optarg) < 3) {
warningx("the argument to -C must be at least 3"); warningx("the argument to -C must be at least 3");
usage(1); usage(1);
} }
sudo_settings[ARG_CLOSEFROM].value = optarg;
break; break;
#ifdef HAVE_LOGIN_CAP_H #ifdef HAVE_LOGIN_CAP_H
case 'c': case 'c':

View File

@@ -125,8 +125,12 @@ static int suspend_parent(int signo, struct io_buffer *iobufs);
static void flush_output(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 int perform_io(struct io_buffer *iobufs, fd_set *fdsr, fd_set *fdsw);
static void handler(int s); static void handler(int s);
static int script_child(const char *path, char *argv[], char *envp[], int, int); static int my_execve(const char *path, char *const argv[],
static void script_run(const char *path, char *argv[], char *envp[], int); 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 sigwinch(int s);
static void sync_ttysize(int src, int dst); static void sync_ttysize(int src, int dst);
static void deliver_signal(pid_t pid, int signo); 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 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 static int
my_execve(const char *path, char *const argv[], char *const envp[]) 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 */ /* child */
close(sv[0]); close(sv[0]);
fcntl(sv[1], F_SETFD, FD_CLOEXEC); fcntl(sv[1], F_SETFD, FD_CLOEXEC);
/* XXX - defer call to exec_setup() until my_execve()? */
if (exec_setup(details) == 0) { if (exec_setup(details) == 0) {
/* headed for execve() */ /* headed for execve() */
if (log_io) { if (log_io) {
@@ -647,8 +652,10 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
close(io_pipe[STDOUT_FILENO][0]); close(io_pipe[STDOUT_FILENO][0]);
if (io_pipe[STDERR_FILENO][0]) if (io_pipe[STDERR_FILENO][0])
close(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 { } else {
if (details->closefrom >= 0)
closefrom(details->closefrom);
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
if (rbac_enabled) if (rbac_enabled)
selinux_execve(details->command, argv, envp); 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). * Returns an error if fork(2) fails, else calls _exit(2).
*/ */
int 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 command_status cstat;
struct timeval tv; 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); fcntl(errpipe[1], F_SETFD, FD_CLOEXEC);
/* setup tty and exec command */ /* setup tty and exec command */
script_run(path, argv, envp, rbac); script_run(details, argv, envp, rbac);
cstat.type = CMD_ERRNO; cstat.type = CMD_ERRNO;
cstat.val = errno; cstat.val = errno;
write(errpipe[1], &cstat, sizeof(cstat)); write(errpipe[1], &cstat, sizeof(cstat));
@@ -1265,7 +1273,8 @@ flush_output(struct io_buffer *iobufs)
* Returns only if execve() fails. * Returns only if execve() fails.
*/ */
static void 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(); 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]) if (script_fds[SFD_STDERR] != script_fds[SFD_SLAVE])
close(script_fds[SFD_STDERR]); close(script_fds[SFD_STDERR]);
if (details->closefrom >= 0)
closefrom(details->closefrom);
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
if (rbac_enabled) if (rbac_enabled)
selinux_execve(path, argv, envp); selinux_execve(details->command, argv, envp);
else else
#endif #endif
my_execve(path, argv, envp); my_execve(details->command, argv, envp);
} }
/* /*

View File

@@ -240,7 +240,7 @@ selinux_prefork(char *role, char *type, int ttyfd)
} }
void void
selinux_execv(char *path, char **argv) selinux_execve(const char *path, char *argv[], char *envp[])
{ {
if (setexeccon(new_context)) { if (setexeccon(new_context)) {
warning("unable to set exec context to %s", new_context); warning("unable to set exec context to %s", new_context);
@@ -260,11 +260,12 @@ selinux_execv(char *path, char **argv)
#endif #endif
/* We use the "spare" slot in argv to store sesh. */ /* We use the "spare" slot in argv to store sesh. */
/* XXX - no longer can do this XXX */
--argv; --argv;
argv[0] = *argv[1] == '-' ? "-sesh" : "sesh"; 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); warning("%s", path);
} }

View File

@@ -393,6 +393,7 @@ command_info_to_details(char * const info[], struct command_details *details)
char *cp, *ep; char *cp, *ep;
memset(details, 0, sizeof(*details)); memset(details, 0, sizeof(*details));
details->closefrom = -1;
#define SET_STRING(s, n) \ #define SET_STRING(s, n) \
if (strncmp(s, info[i], sizeof(s) - 1) == 0 && info[i][sizeof(s) - 1]) { \ 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("chroot=", chroot)
SET_STRING("command=", command) SET_STRING("command=", command)
SET_STRING("cwd=", cwd) 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; break;
case 'l': case 'l':
SET_STRING("login_class=", login_class) SET_STRING("login_class=", login_class)

View File

@@ -127,6 +127,7 @@ struct command_details {
int priority; int priority;
int timeout; int timeout;
int ngroups; int ngroups;
int closefrom;
GETGROUPS_T *groups; GETGROUPS_T *groups;
const char *command; const char *command;
const char *cwd; const char *cwd;