diff options
author | Jouke Witteveen <j.witteveen@gmail.com> | 2016-06-13 12:50:12 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-06-13 12:50:12 +0200 |
commit | 2065ca699b38d97b2a4ebd34a7c2d2c186970d20 (patch) | |
tree | 9360de2b74a44b2f29adb3a20669af494908c583 | |
parent | 988b3b1765153051d48f1b47f42e78d02d2f7a9a (diff) |
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.
-rw-r--r-- | src/core/execute.c | 73 |
1 files changed, 39 insertions, 34 deletions
diff --git a/src/core/execute.c b/src/core/execute.c index 802f14d575..c20650626c 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -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; } |