Call the policy's init_session() function before we fork the child.

That way, the session is created and destroyed in the same process,
which is needed by some modules, such as  pam_mount.
This commit is contained in:
Todd C. Miller
2012-04-23 16:38:16 -04:00
parent 1480bb88b7
commit 23b7a1fa5c
8 changed files with 43 additions and 32 deletions

View File

@@ -658,11 +658,12 @@ DDEESSCCRRIIPPTTIIOONN
init_session
int (*init_session)(struct passwd *pwd, char **user_envp[);
The init_session function is called when ssuuddoo sets up the execution
environment for the command, immediately before the contents of the
_c_o_m_m_a_n_d___i_n_f_o list are applied (before the uid changes). This can
be used to do session setup that is not supported by _c_o_m_m_a_n_d___i_n_f_o,
such as opening the PAM session.
The init_session function is called before ssuuddoo sets up the
execution environment for the command. It is run in the parent
ssuuddoo process and before any uid or gid changes. This can be used
to perform session setup that is not supported by _c_o_m_m_a_n_d___i_n_f_o,
such as opening the PAM session. The close function can be used to
tear down the session that was opened by init_session.
The _p_w_d argument points to a passwd struct for the user the command
will be run as if the uid the command will run as was found in the
@@ -1354,4 +1355,4 @@ DDIISSCCLLAAIIMMEERR
1.8.5 April 13, 2012 SUDO_PLUGIN(1m)
1.8.5 April 23, 2012 SUDO_PLUGIN(1m)

View File

@@ -139,7 +139,7 @@
.\" ========================================================================
.\"
.IX Title "SUDO_PLUGIN @mansectsu@"
.TH SUDO_PLUGIN @mansectsu@ "April 13, 2012" "1.8.5" "MAINTENANCE COMMANDS"
.TH SUDO_PLUGIN @mansectsu@ "April 23, 2012" "1.8.5" "MAINTENANCE COMMANDS"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -830,11 +830,12 @@ support credential caching.
\& int (*init_session)(struct passwd *pwd, char **user_envp[);
.Ve
.Sp
The \f(CW\*(C`init_session\*(C'\fR function is called when \fBsudo\fR sets up the
execution environment for the command, immediately before the
contents of the \fIcommand_info\fR list are applied (before the uid
changes). This can be used to do session setup that is not supported
by \fIcommand_info\fR, such as opening the \s-1PAM\s0 session.
The \f(CW\*(C`init_session\*(C'\fR function is called before \fBsudo\fR sets up the
execution environment for the command. It is run in the parent
\&\fBsudo\fR process and before any uid or gid changes. This can be used
to perform session setup that is not supported by \fIcommand_info\fR,
such as opening the \s-1PAM\s0 session. The \f(CW\*(C`close\*(C'\fR function can be
used to tear down the session that was opened by \f(CW\*(C`init_session\*(C'\fR.
.Sp
The \fIpwd\fR argument points to a passwd struct for the user the
command will be run as if the uid the command will run as was found

View File

@@ -781,11 +781,12 @@ support credential caching.
int (*init_session)(struct passwd *pwd, char **user_envp[);
The C<init_session> function is called when B<sudo> sets up the
execution environment for the command, immediately before the
contents of the I<command_info> list are applied (before the uid
changes). This can be used to do session setup that is not supported
by I<command_info>, such as opening the PAM session.
The C<init_session> function is called before B<sudo> sets up the
execution environment for the command. It is run in the parent
B<sudo> process and before any uid or gid changes. This can be used
to perform session setup that is not supported by I<command_info>,
such as opening the PAM session. The C<close> function can be
used to tear down the session that was opened by C<init_session>.
The I<pwd> argument points to a passwd struct for the user the
command will be run as if the uid the command will run as was found

View File

@@ -274,6 +274,7 @@ sudo_pam_end_session(struct passwd *pw, sudo_auth *auth)
/*
* Update PAM_USER to reference the user we are running the command
* as, as opposed to the user we authenticated as.
* XXX - still needed now that session init is in parent?
*/
(void) pam_set_item(pamh, PAM_USER, pw->pw_name);
#ifndef NO_PAM_SESSION

View File

@@ -99,6 +99,13 @@ static int fork_cmnd(struct command_details *details, int sv[2])
sa.sa_handler = handler;
sigaction(SIGCONT, &sa, NULL);
/*
* The policy plugin's session init must be run before we fork
* or certain pam modules won't be able to track their state.
*/
if (policy_init_session(details) != true)
errorx(1, _("policy plugin failed session initialization"));
child = sudo_debug_fork();
switch (child) {
case -1:

View File

@@ -620,6 +620,13 @@ fork_pty(struct command_details *details, int sv[], int *maxfd)
}
}
/*
* The policy plugin's session init must be run before we fork
* or certain pam modules won't be able to track their state.
*/
if (policy_init_session(details) != true)
errorx(1, _("policy plugin failed session initialization"));
child = sudo_debug_fork();
switch (child) {
case -1:

View File

@@ -130,8 +130,6 @@ static int policy_list(struct plugin_container *plugin, int argc,
char * const argv[], int verbose, const char *list_user);
static int policy_validate(struct plugin_container *plugin);
static void policy_invalidate(struct plugin_container *plugin, int remove);
static int policy_init_session(struct plugin_container *plugin,
struct passwd *pwd, char **user_env[]);
/* I/O log plugin convenience functions. */
static int iolog_open(struct plugin_container *plugin, char * const settings[],
@@ -890,13 +888,6 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
bool rval = false;
debug_decl(exec_setup, SUDO_DEBUG_EXEC)
/*
* Call policy plugin's session init before other setup occurs.
* The session init code is expected to print an error as needed.
*/
if (policy_init_session(&policy_plugin, details->pw, &details->envp) != true)
goto done;
#ifdef HAVE_SELINUX
if (ISSET(details->flags, CD_RBAC_ENABLED)) {
if (selinux_setup(details->selinux_role, details->selinux_type,
@@ -1177,23 +1168,24 @@ policy_invalidate(struct plugin_container *plugin, int remove)
debug_return;
}
static int
policy_init_session(struct plugin_container *plugin, struct passwd *pwd, char **user_env[])
int
policy_init_session(struct command_details *details)
{
int rval = true;
debug_decl(policy_init_session, SUDO_DEBUG_PCOMM)
if (plugin->u.policy->init_session) {
if (policy_plugin.u.policy->init_session) {
/*
* Backwards compatibility for older API versions
*/
switch (plugin->u.generic->version) {
switch (policy_plugin.u.generic->version) {
case SUDO_API_MKVERSION(1, 0):
case SUDO_API_MKVERSION(1, 1):
rval = plugin->u.policy_1_0->init_session(pwd);
rval = policy_plugin.u.policy_1_0->init_session(details->pw);
break;
default:
rval = plugin->u.policy->init_session(pwd, user_env);
rval = policy_plugin.u.policy->init_session(details->pw,
&details->envp);
}
}
debug_return_bool(rval);

View File

@@ -204,6 +204,7 @@ void get_ttysize(int *rowp, int *colp);
/* sudo.c */
bool exec_setup(struct command_details *details, const char *ptyname, int ptyfd);
int policy_init_session(struct command_details *details);
int run_command(struct command_details *details);
extern const char *list_user, *runas_user, *runas_group;
extern struct user_details user_details;