From 57d43430e101daf9dffa6ee8a45c676569e79efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Fri, 22 Dec 2017 01:14:19 +0100 Subject: [PATCH] qrexec: setup process environment when not using fork server If fork server is used, proper environment is inherited from the session. But in other case (like non-default user), it needs to be created by qrexec-agent itself. PAM provide some variables, but not the most basic: HOME, SHELL, USER, LOGNAME. Also process should be started in user home directory (if available). Fixes QubesOS/qubes-issues#3416 --- qrexec/qrexec-agent.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/qrexec/qrexec-agent.c b/qrexec/qrexec-agent.c index 7fa2f66..2148f2a 100644 --- a/qrexec/qrexec-agent.c +++ b/qrexec/qrexec-agent.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -143,7 +144,7 @@ void do_exec(const char *cmd) struct passwd pw_copy; pid_t child, pid; char **env; - char pid_s[32]; + char env_buf[64]; char *arg0; char *shell_basename; #endif @@ -217,8 +218,24 @@ void do_exec(const char *cmd) goto error; /* provide this variable to child process */ - snprintf(pid_s, sizeof(pid_s), "QREXEC_AGENT_PID=%d", getppid()); - retval = pam_putenv(pamh, pid_s); + snprintf(env_buf, sizeof(env_buf), "QREXEC_AGENT_PID=%d", getppid()); + retval = pam_putenv(pamh, env_buf); + if (retval != PAM_SUCCESS) + goto error; + snprintf(env_buf, sizeof(env_buf), "HOME=%s", pw->pw_dir); + retval = pam_putenv(pamh, env_buf); + if (retval != PAM_SUCCESS) + goto error; + snprintf(env_buf, sizeof(env_buf), "SHELL=%s", pw->pw_shell); + retval = pam_putenv(pamh, env_buf); + if (retval != PAM_SUCCESS) + goto error; + snprintf(env_buf, sizeof(env_buf), "USER=%s", pw->pw_name); + retval = pam_putenv(pamh, env_buf); + if (retval != PAM_SUCCESS) + goto error; + snprintf(env_buf, sizeof(env_buf), "LOGNAME=%s", pw->pw_name); + retval = pam_putenv(pamh, env_buf); if (retval != PAM_SUCCESS) goto error; @@ -236,9 +253,13 @@ void do_exec(const char *cmd) if (setuid (pw->pw_uid)) exit(126); setsid(); - /* This is a copy but don't care to free as we exec later anyways. */ + /* This is a copy but don't care to free as we exec later anyway. */ env = pam_getenvlist (pamh); + /* try to enter home dir, but don't abort if it fails */ + retval = chdir(pw->pw_dir); + if (retval == -1) + warn("chdir(%s)", pw->pw_dir); execle(pw->pw_shell, arg0, "-c", realcmd, (char*)NULL, env); exit(127); default: