valeriyvdovin / rpms / systemd

Forked from rpms/systemd 3 years ago
Clone

Blame SOURCES/0197-pam-do-not-set-XDG_RUNTIME_DIR-unconditionally.patch

9fc0f6
From 281100560056e06f69d2cdb4dcc854bd3717734f Mon Sep 17 00:00:00 2001
9fc0f6
From: Michal Sekletar <msekleta@redhat.com>
9fc0f6
Date: Mon, 10 Feb 2014 17:41:32 +0100
9fc0f6
Subject: [PATCH] pam: do not set XDG_RUNTIME_DIR unconditionally
9fc0f6
9fc0f6
If the session's original user is not the same as the newly logged in one we
9fc0f6
will not set XDG_RUNTIME_DIR.
9fc0f6
9fc0f6
Patch based on upstream commit baae0358f349870544884e405e82e4be7d8add9f
9fc0f6
---
9fc0f6
 src/login/logind-dbus.c         |  2 ++
9fc0f6
 src/login/logind-session-dbus.c |  1 +
9fc0f6
 src/login/pam-module.c          | 52 ++++++++++++++++++++---------------------
9fc0f6
 3 files changed, 29 insertions(+), 26 deletions(-)
9fc0f6
9fc0f6
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
9fc0f6
index bb85c7d..69e94aa 100644
9fc0f6
--- a/src/login/logind-dbus.c
9fc0f6
+++ b/src/login/logind-dbus.c
9fc0f6
@@ -90,6 +90,7 @@
9fc0f6
         "   <arg name=\"path\" type=\"o\" direction=\"out\"/>\n"        \
9fc0f6
         "   <arg name=\"runtime_path\" type=\"o\" direction=\"out\"/>\n" \
9fc0f6
         "   <arg name=\"fd\" type=\"h\" direction=\"out\"/>\n"          \
9fc0f6
+        "   <arg name=\"uid\" type=\"u\" direction=\"out\"/>\n"         \
9fc0f6
         "   <arg name=\"seat\" type=\"s\" direction=\"out\"/>\n"        \
9fc0f6
         "   <arg name=\"vtnr\" type=\"u\" direction=\"out\"/>\n"        \
9fc0f6
         "   <arg name=\"existing\" type=\"b\" direction=\"out\"/>\n"    \
9fc0f6
@@ -523,6 +524,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message) {
9fc0f6
                                 DBUS_TYPE_OBJECT_PATH, &path,
9fc0f6
                                 DBUS_TYPE_STRING, &session->user->runtime_path,
9fc0f6
                                 DBUS_TYPE_UNIX_FD, &fifo_fd,
9fc0f6
+                                DBUS_TYPE_UINT32, &session->user->uid,
9fc0f6
                                 DBUS_TYPE_STRING, &cseat,
9fc0f6
                                 DBUS_TYPE_UINT32, &vtnr,
9fc0f6
                                 DBUS_TYPE_BOOLEAN, &exists,
9fc0f6
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
9fc0f6
index be4e01c..86b0746 100644
9fc0f6
--- a/src/login/logind-session-dbus.c
9fc0f6
+++ b/src/login/logind-session-dbus.c
9fc0f6
@@ -755,6 +755,7 @@ int session_send_create_reply(Session *s, DBusError *error) {
9fc0f6
                                     DBUS_TYPE_OBJECT_PATH, &path,
9fc0f6
                                     DBUS_TYPE_STRING, &s->user->runtime_path,
9fc0f6
                                     DBUS_TYPE_UNIX_FD, &fifo_fd,
9fc0f6
+                                    DBUS_TYPE_UINT32, &s->user->uid,
9fc0f6
                                     DBUS_TYPE_STRING, &cseat,
9fc0f6
                                     DBUS_TYPE_UINT32, &vtnr,
9fc0f6
                                     DBUS_TYPE_BOOLEAN, &exists,
9fc0f6
diff --git a/src/login/pam-module.c b/src/login/pam-module.c
9fc0f6
index 02f1618..22d9733 100644
9fc0f6
--- a/src/login/pam-module.c
9fc0f6
+++ b/src/login/pam-module.c
9fc0f6
@@ -86,31 +86,24 @@ static int get_user_data(
9fc0f6
 
9fc0f6
         const char *username = NULL;
9fc0f6
         struct passwd *pw = NULL;
9fc0f6
-        uid_t uid;
9fc0f6
         int r;
9fc0f6
 
9fc0f6
         assert(handle);
9fc0f6
         assert(ret_username);
9fc0f6
         assert(ret_pw);
9fc0f6
 
9fc0f6
-        r = audit_loginuid_from_pid(0, &uid);
9fc0f6
-        if (r >= 0)
9fc0f6
-                pw = pam_modutil_getpwuid(handle, uid);
9fc0f6
-        else {
9fc0f6
-                r = pam_get_user(handle, &username, NULL);
9fc0f6
-                if (r != PAM_SUCCESS) {
9fc0f6
-                        pam_syslog(handle, LOG_ERR, "Failed to get user name.");
9fc0f6
-                        return r;
9fc0f6
-                }
9fc0f6
-
9fc0f6
-                if (isempty(username)) {
9fc0f6
-                        pam_syslog(handle, LOG_ERR, "User name not valid.");
9fc0f6
-                        return PAM_AUTH_ERR;
9fc0f6
-                }
9fc0f6
+        r = pam_get_user(handle, &username, NULL);
9fc0f6
+        if (r != PAM_SUCCESS) {
9fc0f6
+                pam_syslog(handle, LOG_ERR, "Failed to get user name.");
9fc0f6
+                return r;
9fc0f6
+        }
9fc0f6
 
9fc0f6
-                pw = pam_modutil_getpwnam(handle, username);
9fc0f6
+        if (isempty(username)) {
9fc0f6
+                pam_syslog(handle, LOG_ERR, "User name not valid.");
9fc0f6
+                return PAM_AUTH_ERR;
9fc0f6
         }
9fc0f6
 
9fc0f6
+        pw = pam_modutil_getpwnam(handle, username);
9fc0f6
         if (!pw) {
9fc0f6
                 pam_syslog(handle, LOG_ERR, "Failed to get user data.");
9fc0f6
                 return PAM_USER_UNKNOWN;
9fc0f6
@@ -123,16 +116,14 @@ static int get_user_data(
9fc0f6
 }
9fc0f6
 
9fc0f6
 static int get_seat_from_display(const char *display, const char **seat, uint32_t *vtnr) {
9fc0f6
-        _cleanup_free_ char *p = NULL;
9fc0f6
-        int r;
9fc0f6
+        _cleanup_free_ char *p = NULL, *tty=NULL;
9fc0f6
         _cleanup_close_ int fd = -1;
9fc0f6
         union sockaddr_union sa = {
9fc0f6
                 .un.sun_family = AF_UNIX,
9fc0f6
         };
9fc0f6
         struct ucred ucred;
9fc0f6
         socklen_t l;
9fc0f6
-        _cleanup_free_ char *tty = NULL;
9fc0f6
-        int v;
9fc0f6
+        int v, r;
9fc0f6
 
9fc0f6
         assert(display);
9fc0f6
         assert(vtnr);
9fc0f6
@@ -186,14 +177,14 @@ _public_ PAM_EXTERN int pam_sm_open_session(
9fc0f6
         bool debug = false;
9fc0f6
         const char *username, *id, *object_path, *runtime_path, *service = NULL, *tty = NULL, *display = NULL, *remote_user = NULL, *remote_host = NULL, *seat = NULL, *type = NULL, *class = NULL, *class_pam = NULL, *cvtnr = NULL;
9fc0f6
         DBusError error;
9fc0f6
-        uint32_t uid, pid;
9fc0f6
         DBusMessageIter iter;
9fc0f6
         int session_fd = -1;
9fc0f6
         DBusConnection *bus = NULL;
9fc0f6
         DBusMessage *m = NULL, *reply = NULL;
9fc0f6
         dbus_bool_t remote, existing;
9fc0f6
         int r;
9fc0f6
-        uint32_t vtnr = 0;
9fc0f6
+        uint32_t uid, pid, vtnr = 0;
9fc0f6
+        uid_t original_uid;
9fc0f6
 
9fc0f6
         assert(handle);
9fc0f6
 
9fc0f6
@@ -389,6 +380,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
9fc0f6
                                    DBUS_TYPE_OBJECT_PATH, &object_path,
9fc0f6
                                    DBUS_TYPE_STRING, &runtime_path,
9fc0f6
                                    DBUS_TYPE_UNIX_FD, &session_fd,
9fc0f6
+                                   DBUS_TYPE_UINT32, &original_uid,
9fc0f6
                                    DBUS_TYPE_STRING, &seat,
9fc0f6
                                    DBUS_TYPE_UINT32, &vtnr,
9fc0f6
                                    DBUS_TYPE_BOOLEAN, &existing,
9fc0f6
@@ -409,10 +401,18 @@ _public_ PAM_EXTERN int pam_sm_open_session(
9fc0f6
                 goto finish;
9fc0f6
         }
9fc0f6
 
9fc0f6
-        r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", runtime_path, 0);
9fc0f6
-        if (r != PAM_SUCCESS) {
9fc0f6
-                pam_syslog(handle, LOG_ERR, "Failed to set runtime dir.");
9fc0f6
-                goto finish;
9fc0f6
+        if (original_uid == pw->pw_uid) {
9fc0f6
+               /* Don't set $XDG_RUNTIME_DIR if the user we now
9fc0f6
+                * authenticated for does not match the original user
9fc0f6
+                * of the session. We do this in order not to result
9fc0f6
+                * in privileged apps clobbering the runtime directory
9fc0f6
+                * unnecessarily. */
9fc0f6
+
9fc0f6
+                r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", runtime_path, 0);
9fc0f6
+                if (r != PAM_SUCCESS) {
9fc0f6
+                        pam_syslog(handle, LOG_ERR, "Failed to set runtime dir.");
9fc0f6
+                        return r;
9fc0f6
+                }
9fc0f6
         }
9fc0f6
 
9fc0f6
         if (!isempty(seat)) {