diff --git a/1012-pam_systemd_do_override_XDG_RUNTIME_DIR_of_the_original_user.patch b/1012-pam_systemd_do_override_XDG_RUNTIME_DIR_of_the_original_user.patch new file mode 100644 index 00000000..59d166ae --- /dev/null +++ b/1012-pam_systemd_do_override_XDG_RUNTIME_DIR_of_the_original_user.patch @@ -0,0 +1,168 @@ +Based on upstream baae0358f349870544884e405e82e4be7d8add9f +| From: Lennart Poettering +| Date: Tue, 26 Nov 2013 04:05:00 +0000 +| Subject: pam_systemd: do not set XDG_RUNTIME_DIR if the session's original user is not the same as the newly logged in one +| It's better not to set any XDG_RUNTIME_DIR at all rather than one of a +| different user. So let's do this. +--- systemd-208/src/login/logind-dbus.c ++++ systemd-208/src/login/logind-dbus.c 2013-11-26 13:37:05.730735774 +0000 +@@ -523,6 +523,7 @@ static int bus_manager_create_session(Ma + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_STRING, &session->user->runtime_path, + DBUS_TYPE_UNIX_FD, &fifo_fd, ++ DBUS_TYPE_UINT32, &session->user->uid, + DBUS_TYPE_STRING, &cseat, + DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_BOOLEAN, &exists, +--- systemd-208/src/login/logind-session-dbus.c ++++ systemd-208/src/login/logind-session-dbus.c 2013-11-26 13:36:07.478236401 +0000 +@@ -755,6 +755,7 @@ int session_send_create_reply(Session *s + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_STRING, &s->user->runtime_path, + DBUS_TYPE_UNIX_FD, &fifo_fd, ++ DBUS_TYPE_UINT32, &s->user->uid, + DBUS_TYPE_STRING, &cseat, + DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_BOOLEAN, &exists, +--- systemd-208/src/login/pam-module.c ++++ systemd-208/src/login/pam-module.c 2013-11-26 14:32:20.194235777 +0000 +@@ -93,24 +93,18 @@ static int get_user_data( + assert(ret_username); + assert(ret_pw); + +- r = audit_loginuid_from_pid(0, &uid); +- if (r >= 0) +- pw = pam_modutil_getpwuid(handle, uid); +- else { +- r = pam_get_user(handle, &username, NULL); +- if (r != PAM_SUCCESS) { +- pam_syslog(handle, LOG_ERR, "Failed to get user name."); +- return r; +- } +- +- if (isempty(username)) { +- pam_syslog(handle, LOG_ERR, "User name not valid."); +- return PAM_AUTH_ERR; +- } ++ r = pam_get_user(handle, &username, NULL); ++ if (r != PAM_SUCCESS) { ++ pam_syslog(handle, LOG_ERR, "Failed to get user name."); ++ return r; ++ } + +- pw = pam_modutil_getpwnam(handle, username); ++ if (isempty(username)) { ++ pam_syslog(handle, LOG_ERR, "User name not valid."); ++ return PAM_AUTH_ERR; + } + ++ pw = pam_modutil_getpwnam(handle, username); + if (!pw) { + pam_syslog(handle, LOG_ERR, "Failed to get user data."); + return PAM_USER_UNKNOWN; +@@ -123,16 +117,14 @@ static int get_user_data( + } + + static int get_seat_from_display(const char *display, const char **seat, uint32_t *vtnr) { +- _cleanup_free_ char *p = NULL; +- int r; +- _cleanup_close_ int fd = -1; + union sockaddr_union sa = { + .un.sun_family = AF_UNIX, + }; ++ _cleanup_free_ char *p = NULL, *tty = NULL; ++ _cleanup_close_ int fd = -1; + struct ucred ucred; + socklen_t l; +- _cleanup_free_ char *tty = NULL; +- int v; ++ int v, r; + + assert(display); + assert(vtnr); +@@ -194,13 +186,12 @@ _public_ PAM_EXTERN int pam_sm_open_sess + dbus_bool_t remote, existing; + int r; + uint32_t vtnr = 0; ++ uid_t original_uid; + + assert(handle); + + dbus_error_init(&error); + +- /* pam_syslog(handle, LOG_INFO, "pam-systemd initializing"); */ +- + /* Make this a NOP on non-logind systems */ + if (!logind_running()) + return PAM_SUCCESS; +@@ -213,6 +204,9 @@ _public_ PAM_EXTERN int pam_sm_open_sess + goto finish; + } + ++ if (debug) ++ pam_syslog(handle, LOG_INFO, "pam-systemd initializing"); ++ + r = get_user_data(handle, &username, &pw); + if (r != PAM_SUCCESS) + goto finish; +@@ -374,7 +368,11 @@ _public_ PAM_EXTERN int pam_sm_open_sess + if (debug) + pam_syslog(handle, LOG_DEBUG, "Asking logind to create session: " + "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", +- uid, pid, service, type, class, seat, vtnr, tty, display, yes_no(remote), remote_user, remote_host); ++ pw->pw_uid, pid, ++ strempty(service), ++ type, class, ++ seat, vtnr, tty, display, ++ yes_no(remote), remote_user, remote_host); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { +@@ -388,6 +386,7 @@ _public_ PAM_EXTERN int pam_sm_open_sess + DBUS_TYPE_OBJECT_PATH, &object_path, + DBUS_TYPE_STRING, &runtime_path, + DBUS_TYPE_UNIX_FD, &session_fd, ++ DBUS_TYPE_UINT32, &original_uid, + DBUS_TYPE_STRING, &seat, + DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_BOOLEAN, &existing, +@@ -399,8 +398,8 @@ _public_ PAM_EXTERN int pam_sm_open_sess + + if (debug) + pam_syslog(handle, LOG_DEBUG, "Reply from logind: " +- "id=%s object_path=%s runtime_path=%s session_fd=%d seat=%s vtnr=%u", +- id, object_path, runtime_path, session_fd, seat, vtnr); ++ "id=%s object_path=%s runtime_path=%s session_fd=%d seat=%s vtnr=%u original_uid=%u", ++ id, object_path, runtime_path, session_fd, seat, vtnr, original_uid); + + r = pam_misc_setenv(handle, "XDG_SESSION_ID", id, 0); + if (r != PAM_SUCCESS) { +@@ -408,10 +407,24 @@ _public_ PAM_EXTERN int pam_sm_open_sess + goto finish; + } + +- r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", runtime_path, 0); +- if (r != PAM_SUCCESS) { +- pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); +- goto finish; ++ if (original_uid == pw->pw_uid) { ++ /* Don't set $XDG_RUNTIME_DIR if the user we now ++ * authenticated for does not match the original user ++ * of the session. We do this in order not to result ++ * in privileged apps clobbering the runtime directory ++ * unnecessarily. */ ++ ++ r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", runtime_path, 0); ++ if (r != PAM_SUCCESS) { ++ pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); ++ goto finish; ++ } ++ } else { ++ (void) unsetenv("XDG_RUNTIME_DIR"); ++ r = pam_putenv(handle, "XDG_RUNTIME_DIR"); ++ if (r != PAM_SUCCESS && r != PAM_BAD_ITEM) { ++ pam_syslog(handle, LOG_ERR, "Failed to unset runtime dir."); ++ } + } + + if (!isempty(seat)) { diff --git a/systemd.changes b/systemd.changes index 20b2c0b1..39296aa2 100644 --- a/systemd.changes +++ b/systemd.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Tue Nov 26 15:12:58 UTC 2013 - werner@suse.de + +- Add patch + 1012-pam_systemd_do_override_XDG_RUNTIME_DIR_of_the_original_user.patch + to avoid (xdg-)su to set XDG_RUNTIME_DIR to the original user and + avoid that e.g. pulseaudio will create /run/user//pulse owned + by root (bnc#852015) + ------------------------------------------------------------------- Thu Nov 21 12:27:11 UTC 2013 - werner@suse.de diff --git a/systemd.spec b/systemd.spec index 22d16489..d6abe492 100644 --- a/systemd.spec +++ b/systemd.spec @@ -260,6 +260,8 @@ Patch1009: 1009-make-xsltproc-use-correct-ROFF-links.patch Patch1010: 1010-do-not-install-sulogin-unit-with-poweroff.patch # PATCH-FIX-OPENSUSE 1011-check-4-valid-kmsg-device.patch -- Avoid busy systemd-journald (bnc#851393) Patch1011: 1011-check-4-valid-kmsg-device.patch +# PATCH-FIX-PSTREAM 1012-pam_systemd_do_override_XDG_RUNTIME_DIR_of_the_original_user.patch +Patch1012: 1012-pam_systemd_do_override_XDG_RUNTIME_DIR_of_the_original_user.patch %description Systemd is a system and service manager, compatible with SysV and LSB @@ -537,6 +539,7 @@ cp %{SOURCE7} m4/ %patch1009 -p1 %patch1010 -p1 %patch1011 -p1 +%patch1012 -p1 # ensure generate files are removed rm -f units/emergency.service