summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-10-09 22:23:41 +0200
committerSven Eden <sven.eden@prydeworx.com>2018-10-29 10:18:39 +0100
commit11ddca4e536ec6d3ae6b216a8db7d196a4ca4a01 (patch)
tree2e2437024404fddf85573b25a308710f2a45da6c /src
parentaafb6f802c6a6f9339319e9e2d3d669d99f51e5b (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')
-rw-r--r--src/login/pam_elogind.c50
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);