diff options
-rw-r--r-- | src/login/pam_elogind.c | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/src/login/pam_elogind.c b/src/login/pam_elogind.c index bb6da2aac..c55066e23 100644 --- a/src/login/pam_elogind.c +++ b/src/login/pam_elogind.c @@ -274,6 +274,36 @@ static int append_session_cg_weight(pam_handle_t *handle, sd_bus_message *m, con return 0; } +static bool validate_runtime_directory(pam_handle_t *handle, const char *path, uid_t uid) { + struct stat st; + + assert(path); + + /* Just some extra paranoia: let's not set $XDG_RUNTIME_DIR if the directory we'd set it to isn't actually set + * up properly for us. */ + + if (lstat(path, &st) < 0) { + pam_syslog(handle, LOG_ERR, "Failed to stat() runtime directory '%s': %s", path, strerror(errno)); + goto fail; + } + + if (!S_ISDIR(st.st_mode)) { + pam_syslog(handle, LOG_ERR, "Runtime directory '%s' is not actually a directory.", path); + goto fail; + } + + if (st.st_uid != uid) { + pam_syslog(handle, LOG_ERR, "Runtime directory '%s' is not owned by UID " UID_FMT ", as it should.", path, uid); + goto fail; + } + + return true; + +fail: + pam_syslog(handle, LOG_WARNING, "Not setting $XDG_RUNTIME_DIR, as the directory is not in order."); + return false; +} + _public_ PAM_EXTERN int pam_sm_open_session( pam_handle_t *handle, int flags, @@ -334,10 +364,12 @@ _public_ PAM_EXTERN int pam_sm_open_session( if (asprintf(&rt, "/run/user/"UID_FMT, pw->pw_uid) < 0) return PAM_BUF_ERR; - r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0); - if (r != PAM_SUCCESS) { - pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); - return r; + if (validate_runtime_directory(handle, rt, pw->pw_uid)) { + r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); + return r; + } } r = export_legacy_dbus_address(handle, pw->pw_uid, rt); @@ -565,10 +597,12 @@ _public_ PAM_EXTERN int pam_sm_open_session( * 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."); - return r; + if (validate_runtime_directory(handle, runtime_path, pw->pw_uid)) { + 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."); + return r; + } } r = export_legacy_dbus_address(handle, pw->pw_uid, runtime_path); |