From 4ae930d9ddb8d2f806f89068142f4e7cd4df85e6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 26 Nov 2013 05:05:00 +0100 Subject: [PATCH] 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. This changes the bus call parameters of CreateSession(), but that is explicitly an internal API hence should be fine. Note however, that a logind restart (the way the RPM postinst scriptlets do it) is necessary to make things work again. (cherry picked from commit baae0358f349870544884e405e82e4be7d8add9f) Conflicts: src/login/logind-dbus.c src/login/logind-session-dbus.c src/login/pam-module.c Note: Backported by Dr. Werner Fink --- src/login/logind-dbus.c | 1 + src/login/logind-session-dbus.c | 1 + src/login/pam-module.c | 67 ++++++++++++++++++++++------------------- 3 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 583d62e15d..6f3e442efb 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -523,6 +523,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message) { 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, diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index be4e01c5e3..86b0746313 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -755,6 +755,7 @@ int session_send_create_reply(Session *s, DBusError *error) { 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, diff --git a/src/login/pam-module.c b/src/login/pam-module.c index aa09ec1dbe..4d6b052497 100644 --- a/src/login/pam-module.c +++ b/src/login/pam-module.c @@ -86,31 +86,24 @@ static int get_user_data( const char *username = NULL; struct passwd *pw = NULL; - uid_t uid; int r; assert(handle); 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 +116,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,14 +185,12 @@ _public_ PAM_EXTERN int pam_sm_open_session( dbus_bool_t remote, existing; int r; uint32_t vtnr = 0; + uid_t original_uid; assert(handle); dbus_error_init(&error); - if (debug) - pam_syslog(handle, LOG_INFO, "pam-systemd initializing"); - /* Make this a NOP on non-logind systems */ if (!logind_running()) return PAM_SUCCESS; @@ -214,6 +203,9 @@ _public_ PAM_EXTERN int pam_sm_open_session( 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; @@ -381,7 +373,11 @@ _public_ PAM_EXTERN int pam_sm_open_session( 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) { @@ -395,6 +391,7 @@ _public_ PAM_EXTERN int pam_sm_open_session( 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, @@ -406,8 +403,8 @@ _public_ PAM_EXTERN int pam_sm_open_session( 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) { @@ -415,10 +412,18 @@ _public_ PAM_EXTERN int pam_sm_open_session( 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; + } } if (!isempty(seat)) {