]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pam-systemd: automatically enable "incomplete" user session if XDG_SESSION_INCOMPLETE...
authorLennart Poettering <lennart@poettering.net>
Mon, 27 Nov 2023 16:30:15 +0000 (17:30 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 14 Feb 2024 13:59:53 +0000 (14:59 +0100)
This allows earlier PAM modules (i.e. pam_systemd_home) to inform
pam_systemd that the session is not "complete" yet (i.e. doesn't have
the home dir set up properly yet).

src/login/pam_systemd.c

index 197729dd345d047d6cebc720c7c24aa592c0ac77..0e67d063a4cbe700deaba18896d46bed35f26b0a 100644 (file)
@@ -525,6 +525,26 @@ static const char* getenv_harder(pam_handle_t *handle, const char *key, const ch
         return fallback;
 }
 
+static bool getenv_harder_bool(pam_handle_t *handle, const char *key, bool fallback) {
+        const char *v;
+        int r;
+
+        assert(handle);
+        assert(key);
+
+        v = getenv_harder(handle, key, NULL);
+        if (isempty(v))
+                return fallback;
+
+        r = parse_boolean(v);
+        if (r < 0) {
+                pam_syslog(handle, LOG_ERR, "Boolean environment variable value of '%s' is not valid: %s", key, v);
+                return fallback;
+        }
+
+        return r;
+}
+
 static int update_environment(pam_handle_t *handle, const char *key, const char *value) {
         int r;
 
@@ -903,7 +923,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
         int session_fd = -EBADF, existing, r;
-        bool debug = false, remote;
+        bool debug = false, remote, incomplete;
         uint32_t vtnr = 0;
         uid_t original_uid;
 
@@ -944,6 +964,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         type = getenv_harder(handle, "XDG_SESSION_TYPE", type_pam);
         class = getenv_harder(handle, "XDG_SESSION_CLASS", class_pam);
         desktop = getenv_harder(handle, "XDG_SESSION_DESKTOP", desktop_pam);
+        incomplete = getenv_harder_bool(handle, "XDG_SESSION_INCOMPLETE", false);
 
         if (streq_ptr(service, "systemd-user")) {
                 /* If we detect that we are running in the "systemd-user" PAM stack, then let's patch the class to
@@ -1009,6 +1030,13 @@ _public_ PAM_EXTERN int pam_sm_open_session(
                         ((IN_SET(user_record_disposition(ur), USER_INTRINSIC, USER_SYSTEM, USER_DYNAMIC) &&
                          streq(type, "tty")) ? "user-early" : "user");
 
+        if (incomplete) {
+                if (streq(class, "user"))
+                        class = "user-incomplete";
+                else
+                        pam_syslog_pam_error(handle, LOG_WARNING, 0, "PAM session of class '%s' is incomplete, which is not supported, ignoring.", class);
+        }
+
         remote = !isempty(remote_host) && !is_localhost(remote_host);
 
         r = pam_get_data(handle, "systemd.memory_max", (const void **)&memory_max);