diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-10-09 22:23:41 +0200 |
---|---|---|
committer | Sven Eden <sven.eden@prydeworx.com> | 2018-10-29 10:18:39 +0100 |
commit | 11ddca4e536ec6d3ae6b216a8db7d196a4ca4a01 (patch) | |
tree | 2e2437024404fddf85573b25a308710f2a45da6c /src/login/pam_elogind.c | |
parent | aafb6f802c6a6f9339319e9e2d3d669d99f51e5b (diff) |
logind: validate /run/user/1000 before we set it
Let's be safe than sorry, in particular as logind doesn't set it up
anymore, but user-runtime-dir@.service does, and logind doesn't really
track success of that.
(cherry picked from commit b92171124819305985ed292cc472f6668a027425)
Diffstat (limited to 'src/login/pam_elogind.c')
-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); |