mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
core/execute: pass env vars to PAM session setup (#3503)
Move the merger of environment variables before setting up the PAM session and pass the aggregate environment to PAM setup. This allows control over the PAM session hooks through environment variables. PAM session initiation may update the environment. On successful initiation of a PAM session, we adopt the environment of the PAM context.
This commit is contained in:
parent
988b3b1765
commit
2065ca699b
@ -799,7 +799,7 @@ static int setup_pam(
|
||||
const char *user,
|
||||
uid_t uid,
|
||||
const char *tty,
|
||||
char ***pam_env,
|
||||
char ***env,
|
||||
int fds[], unsigned n_fds) {
|
||||
|
||||
static const struct pam_conv conv = {
|
||||
@ -818,7 +818,7 @@ static int setup_pam(
|
||||
|
||||
assert(name);
|
||||
assert(user);
|
||||
assert(pam_env);
|
||||
assert(env);
|
||||
|
||||
/* We set up PAM in the parent process, then fork. The child
|
||||
* will then stay around until killed via PR_GET_PDEATHSIG or
|
||||
@ -846,6 +846,12 @@ static int setup_pam(
|
||||
goto fail;
|
||||
}
|
||||
|
||||
STRV_FOREACH(e, *env) {
|
||||
pam_code = pam_putenv(handle, *e);
|
||||
if (pam_code != PAM_SUCCESS)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pam_code = pam_acct_mgmt(handle, flags);
|
||||
if (pam_code != PAM_SUCCESS)
|
||||
goto fail;
|
||||
@ -966,8 +972,8 @@ static int setup_pam(
|
||||
if (!barrier_place_and_sync(&barrier))
|
||||
log_error("PAM initialization failed");
|
||||
|
||||
*pam_env = e;
|
||||
e = NULL;
|
||||
strv_free(*env);
|
||||
*env = e;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -1464,7 +1470,7 @@ static int exec_child(
|
||||
char **files_env,
|
||||
int *exit_status) {
|
||||
|
||||
_cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
|
||||
_cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **accum_env = NULL, **final_argv = NULL;
|
||||
_cleanup_free_ char *mac_selinux_context_net = NULL;
|
||||
const char *username = NULL, *home = NULL, *shell = NULL, *wd;
|
||||
uid_t uid = UID_INVALID;
|
||||
@ -1715,6 +1721,30 @@ static int exec_child(
|
||||
}
|
||||
}
|
||||
|
||||
r = build_environment(context, params, n_fds, home, username, shell, &our_env);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return r;
|
||||
}
|
||||
|
||||
r = build_pass_environment(context, &pass_env);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return r;
|
||||
}
|
||||
|
||||
accum_env = strv_env_merge(5,
|
||||
params->environment,
|
||||
our_env,
|
||||
pass_env,
|
||||
context->environment,
|
||||
files_env,
|
||||
NULL);
|
||||
if (!accum_env) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
umask(context->umask);
|
||||
|
||||
if (params->apply_permissions && !command->privileged) {
|
||||
@ -1751,7 +1781,7 @@ static int exec_child(
|
||||
#endif
|
||||
#ifdef HAVE_PAM
|
||||
if (context->pam_name && username) {
|
||||
r = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
|
||||
r = setup_pam(context->pam_name, username, uid, context->tty_path, &accum_env, fds, n_fds);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_PAM;
|
||||
return r;
|
||||
@ -1997,38 +2027,13 @@ static int exec_child(
|
||||
#endif
|
||||
}
|
||||
|
||||
r = build_environment(context, params, n_fds, home, username, shell, &our_env);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return r;
|
||||
}
|
||||
|
||||
r = build_pass_environment(context, &pass_env);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return r;
|
||||
}
|
||||
|
||||
final_env = strv_env_merge(6,
|
||||
params->environment,
|
||||
our_env,
|
||||
pass_env,
|
||||
context->environment,
|
||||
files_env,
|
||||
pam_env,
|
||||
NULL);
|
||||
if (!final_env) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
final_argv = replace_env_argv(argv, final_env);
|
||||
final_argv = replace_env_argv(argv, accum_env);
|
||||
if (!final_argv) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
final_env = strv_env_clean(final_env);
|
||||
accum_env = strv_env_clean(accum_env);
|
||||
|
||||
if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) {
|
||||
_cleanup_free_ char *line;
|
||||
@ -2045,7 +2050,7 @@ static int exec_child(
|
||||
}
|
||||
}
|
||||
|
||||
execve(command->path, final_argv, final_env);
|
||||
execve(command->path, final_argv, accum_env);
|
||||
*exit_status = EXIT_EXEC;
|
||||
return -errno;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user