]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: validate /run/user/1000 before we set it 9824/head
authorLennart Poettering <lennart@poettering.net>
Tue, 9 Oct 2018 20:23:41 +0000 (22:23 +0200)
committerLennart Poettering <lennart@poettering.net>
Sat, 13 Oct 2018 11:01:08 +0000 (13:01 +0200)
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.

src/login/pam_systemd.c

index 90ccbd7a830477be7baeeec450fd15eb8561f1ae..99c253df4a81f0ed46584c351060248643067595 100644 (file)
@@ -308,6 +308,36 @@ static int update_environment(pam_handle_t *handle, const char *key, const char
         return r;
 }
 
+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,
@@ -367,10 +397,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;
+                        }
                 }
 
                 return PAM_SUCCESS;
@@ -574,9 +606,11 @@ _public_ PAM_EXTERN int pam_sm_open_session(
                  * in privileged apps clobbering the runtime directory
                  * unnecessarily. */
 
-                r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_path);
-                if (r != PAM_SUCCESS)
-                        return r;
+                if (validate_runtime_directory(handle, runtime_path, pw->pw_uid)) {
+                        r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_path);
+                        if (r != PAM_SUCCESS)
+                                return r;
+                }
         }
 
         /* Most likely we got the session/type/class from environment variables, but might have gotten the data