a52f674
From 4ae930d9ddb8d2f806f89068142f4e7cd4df85e6 Mon Sep 17 00:00:00 2001
a52f674
From: Lennart Poettering <lennart@poettering.net>
a52f674
Date: Tue, 26 Nov 2013 05:05:00 +0100
a52f674
Subject: [PATCH] pam_systemd: do not set XDG_RUNTIME_DIR if the session's
a52f674
 original user is not the same as the newly logged in one
a52f674
a52f674
It's better not to set any XDG_RUNTIME_DIR at all rather than one of a
a52f674
different user. So let's do this.
a52f674
a52f674
This changes the bus call parameters of CreateSession(), but that is
a52f674
explicitly an internal API hence should be fine. Note however, that a
a52f674
logind restart (the way the RPM postinst scriptlets do it) is necessary
a52f674
to make things work again.
a52f674
a52f674
(cherry picked from commit baae0358f349870544884e405e82e4be7d8add9f)
a52f674
a52f674
Conflicts:
a52f674
	src/login/logind-dbus.c
a52f674
	src/login/logind-session-dbus.c
a52f674
	src/login/pam-module.c
a52f674
a52f674
Note: Backported by Dr. Werner Fink <werner@suse.de>
a52f674
---
a52f674
 src/login/logind-dbus.c         |  1 +
a52f674
 src/login/logind-session-dbus.c |  1 +
a52f674
 src/login/pam-module.c          | 67 ++++++++++++++++++++++-------------------
a52f674
 3 files changed, 38 insertions(+), 31 deletions(-)
a52f674
a52f674
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
a52f674
index 583d62e..6f3e442 100644
a52f674
--- a/src/login/logind-dbus.c
a52f674
+++ b/src/login/logind-dbus.c
a52f674
@@ -523,6 +523,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message) {
a52f674
                                 DBUS_TYPE_OBJECT_PATH, &path,
a52f674
                                 DBUS_TYPE_STRING, &session->user->runtime_path,
a52f674
                                 DBUS_TYPE_UNIX_FD, &fifo_fd,
a52f674
+                                DBUS_TYPE_UINT32, &session->user->uid,
a52f674
                                 DBUS_TYPE_STRING, &cseat,
a52f674
                                 DBUS_TYPE_UINT32, &vtnr,
a52f674
                                 DBUS_TYPE_BOOLEAN, &exists,
a52f674
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
a52f674
index be4e01c..86b0746 100644
a52f674
--- a/src/login/logind-session-dbus.c
a52f674
+++ b/src/login/logind-session-dbus.c
a52f674
@@ -755,6 +755,7 @@ int session_send_create_reply(Session *s, DBusError *error) {
a52f674
                                     DBUS_TYPE_OBJECT_PATH, &path,
a52f674
                                     DBUS_TYPE_STRING, &s->user->runtime_path,
a52f674
                                     DBUS_TYPE_UNIX_FD, &fifo_fd,
a52f674
+                                    DBUS_TYPE_UINT32, &s->user->uid,
a52f674
                                     DBUS_TYPE_STRING, &cseat,
a52f674
                                     DBUS_TYPE_UINT32, &vtnr,
a52f674
                                     DBUS_TYPE_BOOLEAN, &exists,
a52f674
diff --git a/src/login/pam-module.c b/src/login/pam-module.c
a52f674
index aa09ec1..4d6b052 100644
a52f674
--- a/src/login/pam-module.c
a52f674
+++ b/src/login/pam-module.c
a52f674
@@ -86,31 +86,24 @@ static int get_user_data(
a52f674
 
a52f674
         const char *username = NULL;
a52f674
         struct passwd *pw = NULL;
a52f674
-        uid_t uid;
a52f674
         int r;
a52f674
 
a52f674
         assert(handle);
a52f674
         assert(ret_username);
a52f674
         assert(ret_pw);
a52f674
 
a52f674
-        r = audit_loginuid_from_pid(0, &uid);
a52f674
-        if (r >= 0)
a52f674
-                pw = pam_modutil_getpwuid(handle, uid);
a52f674
-        else {
a52f674
-                r = pam_get_user(handle, &username, NULL);
a52f674
-                if (r != PAM_SUCCESS) {
a52f674
-                        pam_syslog(handle, LOG_ERR, "Failed to get user name.");
a52f674
-                        return r;
a52f674
-                }
a52f674
-
a52f674
-                if (isempty(username)) {
a52f674
-                        pam_syslog(handle, LOG_ERR, "User name not valid.");
a52f674
-                        return PAM_AUTH_ERR;
a52f674
-                }
a52f674
+        r = pam_get_user(handle, &username, NULL);
a52f674
+        if (r != PAM_SUCCESS) {
a52f674
+                pam_syslog(handle, LOG_ERR, "Failed to get user name.");
a52f674
+                return r;
a52f674
+        }
a52f674
 
a52f674
-                pw = pam_modutil_getpwnam(handle, username);
a52f674
+        if (isempty(username)) {
a52f674
+                pam_syslog(handle, LOG_ERR, "User name not valid.");
a52f674
+                return PAM_AUTH_ERR;
a52f674
         }
a52f674
 
a52f674
+        pw = pam_modutil_getpwnam(handle, username);
a52f674
         if (!pw) {
a52f674
                 pam_syslog(handle, LOG_ERR, "Failed to get user data.");
a52f674
                 return PAM_USER_UNKNOWN;
a52f674
@@ -123,16 +116,14 @@ static int get_user_data(
a52f674
 }
a52f674
 
a52f674
 static int get_seat_from_display(const char *display, const char **seat, uint32_t *vtnr) {
a52f674
-        _cleanup_free_ char *p = NULL;
a52f674
-        int r;
a52f674
-        _cleanup_close_ int fd = -1;
a52f674
         union sockaddr_union sa = {
a52f674
                 .un.sun_family = AF_UNIX,
a52f674
         };
a52f674
+         _cleanup_free_ char *p = NULL, *tty = NULL;
a52f674
+         _cleanup_close_ int fd = -1;
a52f674
         struct ucred ucred;
a52f674
         socklen_t l;
a52f674
-        _cleanup_free_ char *tty = NULL;
a52f674
-        int v;
a52f674
+        int v, r;
a52f674
 
a52f674
         assert(display);
a52f674
         assert(vtnr);
a52f674
@@ -194,14 +185,12 @@ _public_ PAM_EXTERN int pam_sm_open_session(
a52f674
         dbus_bool_t remote, existing;
a52f674
         int r;
a52f674
         uint32_t vtnr = 0;
a52f674
+        uid_t original_uid;
a52f674
 
a52f674
         assert(handle);
a52f674
 
a52f674
         dbus_error_init(&error);
a52f674
 
a52f674
-        if (debug)
a52f674
-                pam_syslog(handle, LOG_INFO, "pam-systemd initializing");
a52f674
-
a52f674
         /* Make this a NOP on non-logind systems */
a52f674
         if (!logind_running())
a52f674
                 return PAM_SUCCESS;
a52f674
@@ -214,6 +203,9 @@ _public_ PAM_EXTERN int pam_sm_open_session(
a52f674
                 goto finish;
a52f674
         }
a52f674
 
a52f674
+        if (debug)
a52f674
+                pam_syslog(handle, LOG_INFO, "pam-systemd initializing");
a52f674
+
a52f674
         r = get_user_data(handle, &username, &pw;;
a52f674
         if (r != PAM_SUCCESS)
a52f674
                 goto finish;
a52f674
@@ -381,7 +373,11 @@ _public_ PAM_EXTERN int pam_sm_open_session(
a52f674
         if (debug)
a52f674
                 pam_syslog(handle, LOG_DEBUG, "Asking logind to create session: "
a52f674
                            "uid=%u pid=%u service=%s type=%s class=%s seat=%s vtnr=%u tty=%s display=%s remote=%s remote_user=%s remote_host=%s",
a52f674
-                           uid, pid, service, type, class, seat, vtnr, tty, display, yes_no(remote), remote_user, remote_host);
a52f674
+                              pw->pw_uid, pid,
a52f674
+                              strempty(service),
a52f674
+                              type, class,
a52f674
+                              seat, vtnr, tty, display,
a52f674
+                              yes_no(remote), remote_user, remote_host);
a52f674
 
a52f674
         reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
a52f674
         if (!reply) {
a52f674
@@ -395,6 +391,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
a52f674
                                    DBUS_TYPE_OBJECT_PATH, &object_path,
a52f674
                                    DBUS_TYPE_STRING, &runtime_path,
a52f674
                                    DBUS_TYPE_UNIX_FD, &session_fd,
a52f674
+                                   DBUS_TYPE_UINT32, &original_uid,
a52f674
                                    DBUS_TYPE_STRING, &seat,
a52f674
                                    DBUS_TYPE_UINT32, &vtnr,
a52f674
                                    DBUS_TYPE_BOOLEAN, &existing,
a52f674
@@ -406,8 +403,8 @@ _public_ PAM_EXTERN int pam_sm_open_session(
a52f674
 
a52f674
         if (debug)
a52f674
                 pam_syslog(handle, LOG_DEBUG, "Reply from logind: "
a52f674
-                           "id=%s object_path=%s runtime_path=%s session_fd=%d seat=%s vtnr=%u",
a52f674
-                           id, object_path, runtime_path, session_fd, seat, vtnr);
a52f674
+                           "id=%s object_path=%s runtime_path=%s session_fd=%d seat=%s vtnr=%u original_uid=%u",
a52f674
+                           id, object_path, runtime_path, session_fd, seat, vtnr, original_uid);
a52f674
 
a52f674
         r = pam_misc_setenv(handle, "XDG_SESSION_ID", id, 0);
a52f674
         if (r != PAM_SUCCESS) {
a52f674
@@ -415,10 +412,18 @@ _public_ PAM_EXTERN int pam_sm_open_session(
a52f674
                 goto finish;
a52f674
         }
a52f674
 
a52f674
-        r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", runtime_path, 0);
a52f674
-        if (r != PAM_SUCCESS) {
a52f674
-                pam_syslog(handle, LOG_ERR, "Failed to set runtime dir.");
a52f674
-                goto finish;
a52f674
+        if (original_uid == pw->pw_uid) {
a52f674
+                /* Don't set $XDG_RUNTIME_DIR if the user we now
a52f674
+                 * authenticated for does not match the original user
a52f674
+                 * of the session. We do this in order not to result
a52f674
+                 * in privileged apps clobbering the runtime directory
a52f674
+                 * unnecessarily. */
a52f674
+
a52f674
+                r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", runtime_path, 0);
a52f674
+                if (r != PAM_SUCCESS) {
a52f674
+                         pam_syslog(handle, LOG_ERR, "Failed to set runtime dir.");
a52f674
+                         goto finish;
a52f674
+                }
a52f674
         }
a52f674
 
a52f674
         if (!isempty(seat)) {