]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pam_systemd: register systemd user service manager as class='manager'
authorLennart Poettering <lennart@poettering.net>
Mon, 27 Nov 2023 16:31:50 +0000 (17:31 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 11 Jan 2024 16:23:47 +0000 (17:23 +0100)
Now that we have thew new class, start making us of it in pam_systemd.so
when running for user@.service.

src/login/pam_systemd.c
test/units/testsuite-35.sh

index 297689203b0a5d6a5318cc60278f2bb7f46f5070..d7814a7275dfb4f4ee96325036eb30ce04dc440b 100644 (file)
@@ -936,30 +936,21 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         if (r != PAM_SUCCESS)
                 return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get PAM items: @PAMERR@");
 
-        /* Make sure we don't enter a loop by talking to systemd-logind when it is actually waiting for the
-         * background to finish start-up. If the service is "systemd-user" we simply set XDG_RUNTIME_DIR and
-         * leave. */
-
-        if (streq_ptr(service, "systemd-user")) {
-                char rt[STRLEN("/run/user/") + DECIMAL_STR_MAX(uid_t)];
-
-                xsprintf(rt, "/run/user/"UID_FMT, ur->uid);
-                r = configure_runtime_directory(handle, ur, rt);
-                if (r != PAM_SUCCESS)
-                        return r;
-
-                goto success;
-        }
-
-        /* Otherwise, we ask logind to create a session for us */
-
         seat = getenv_harder(handle, "XDG_SEAT", NULL);
         cvtnr = getenv_harder(handle, "XDG_VTNR", NULL);
         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);
 
-        if (tty && strchr(tty, ':')) {
+        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
+                 * 'manager' if not set, simply for robustness reasons. */
+                type = "unspecified";
+                class = IN_SET(user_record_disposition(ur), USER_INTRINSIC, USER_SYSTEM, USER_DYNAMIC) ?
+                        "manager-early" : "manager";
+                tty = NULL;
+
+        } else if (tty && strchr(tty, ':')) {
                 /* A tty with a colon is usually an X11 display, placed there to show up in utmp. We rearrange things
                  * and don't pretend that an X display was a tty. */
                 if (isempty(display))
index 8ea801ee96ee44069b0eb3e4219f3065b59fa947..78bc07d896318dd9b9d877e0ca71c3a7b6b25233 100755 (executable)
@@ -258,7 +258,7 @@ cleanup_session() (
 
     systemctl stop getty@tty2.service
 
-    for s in $(loginctl --no-legend list-sessions | awk '$3 == "logind-test-user" { print $1 }'); do
+    for s in $(loginctl --no-legend list-sessions | grep tty | awk '$3 == "logind-test-user" { print $1 }'); do
         echo "INFO: stopping session $s"
         loginctl terminate-session "$s"
     done
@@ -308,18 +308,18 @@ check_session() (
 
     local seat session leader_pid
 
-    if [[ $(loginctl --no-legend | grep -c "logind-test-user") != 1 ]]; then
+    if [[ $(loginctl --no-legend | grep tty | grep -c "logind-test-user") != 1 ]]; then
         echo "no session or multiple sessions for logind-test-user." >&2
         return 1
     fi
 
-    seat=$(loginctl --no-legend | grep 'logind-test-user *seat' | awk '{ print $4 }')
+    seat=$(loginctl --no-legend | grep tty | grep 'logind-test-user *seat' | awk '{ print $4 }')
     if [[ -z "$seat" ]]; then
         echo "no seat found for user logind-test-user" >&2
         return 1
     fi
 
-    session=$(loginctl --no-legend | awk '$3 == "logind-test-user" { print $1 }')
+    session=$(loginctl --no-legend | grep tty | awk '$3 == "logind-test-user" { print $1 }')
     if [[ -z "$session" ]]; then
         echo "no session found for user logind-test-user" >&2
         return 1
@@ -364,7 +364,7 @@ EOF
         check_session && break
     done
     check_session
-    assert_eq "$(loginctl --no-legend | awk '$3=="logind-test-user" { print $5 }')" "tty2"
+    assert_eq "$(loginctl --no-legend | grep tty | awk '$3=="logind-test-user" { print $5 }')" "tty2"
 }
 
 testcase_sanity_check() {
@@ -455,7 +455,7 @@ EOF
     udevadm info "$dev"
 
     # trigger logind and activate session
-    loginctl activate "$(loginctl --no-legend | awk '$3 == "logind-test-user" { print $1 }')"
+    loginctl activate "$(loginctl --no-legend | grep tty | awk '$3 == "logind-test-user" { print $1 }')"
 
     # check ACL
     sleep 1
@@ -496,7 +496,7 @@ testcase_lock_idle_action() {
         return
     fi
 
-    if loginctl --no-legend | grep -q logind-test-user; then
+    if loginctl --no-legend | grep tty | grep -q logind-test-user; then
         echo >&2 "Session of the 'logind-test-user' is already present."
         exit 1
     fi
@@ -545,7 +545,7 @@ testcase_session_properties() {
     trap cleanup_session RETURN
     create_session
 
-    s=$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $1 }')
+    s=$(loginctl list-sessions --no-legend | grep tty | awk '$3 == "logind-test-user" { print $1 }')
     /usr/lib/systemd/tests/unit-tests/manual/test-session-properties "/org/freedesktop/login1/session/_3${s?}" /dev/tty2
 }
 
@@ -561,17 +561,17 @@ testcase_list_users_sessions_seats() {
     create_session
 
     # Activate the session
-    loginctl activate "$(loginctl --no-legend | awk '$3 == "logind-test-user" { print $1 }')"
+    loginctl activate "$(loginctl --no-legend | grep tty | awk '$3 == "logind-test-user" { print $1 }')"
 
-    session=$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $1 }')
+    session=$(loginctl list-sessions --no-legend | grep tty | awk '$3 == "logind-test-user" { print $1 }')
     : check that we got a valid session id
     busctl get-property org.freedesktop.login1 "/org/freedesktop/login1/session/_3${session?}" org.freedesktop.login1.Session Id
-    assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $2 }')" "$(id -ru logind-test-user)"
-    seat=$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $4 }')
-    assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $5 }')" tty2
-    assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $6 }')" active
-    assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $7 }')" no
-    assert_eq "$(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $8 }')" '-'
+    assert_eq "$(loginctl list-sessions --no-legend | grep tty | awk '$3 == "logind-test-user" { print $2 }')" "$(id -ru logind-test-user)"
+    seat=$(loginctl list-sessions --no-legend | grep tty | awk '$3 == "logind-test-user" { print $4 }')
+    assert_eq "$(loginctl list-sessions --no-legend | grep tty | awk '$3 == "logind-test-user" { print $5 }')" tty2
+    assert_eq "$(loginctl list-sessions --no-legend | grep tty | awk '$3 == "logind-test-user" { print $6 }')" active
+    assert_eq "$(loginctl list-sessions --no-legend | grep tty | awk '$3 == "logind-test-user" { print $7 }')" no
+    assert_eq "$(loginctl list-sessions --no-legend | grep tty | awk '$3 == "logind-test-user" { print $8 }')" '-'
 
     loginctl list-seats --no-legend | grep -Fwq "${seat?}"
 
@@ -582,10 +582,10 @@ testcase_list_users_sessions_seats() {
     loginctl enable-linger logind-test-user
     assert_eq "$(loginctl list-users --no-legend | awk '$2 == "logind-test-user" { print $3 }')" yes
 
-    for s in $(loginctl list-sessions --no-legend | awk '$3 == "logind-test-user" { print $1 }'); do
+    for s in $(loginctl list-sessions --no-legend | grep tty | awk '$3 == "logind-test-user" { print $1 }'); do
         loginctl terminate-session "$s"
     done
-    if ! timeout 30 bash -c "while loginctl --no-legend | grep -q logind-test-user; do sleep 1; done"; then
+    if ! timeout 30 bash -c "while loginctl --no-legend | grep tty | grep -q logind-test-user; do sleep 1; done"; then
         echo "WARNING: session for logind-test-user still active, ignoring."
         return
     fi
@@ -613,7 +613,7 @@ testcase_stop_idle_session() {
     create_session
     trap teardown_stop_idle_session RETURN
 
-    id="$(loginctl --no-legend | awk '$3 == "logind-test-user" { print $1; }')"
+    id="$(loginctl --no-legend | grep tty | awk '$3 == "logind-test-user" { print $1; }')"
     ts="$(date '+%H:%M:%S')"
 
     mkdir -p /run/systemd/logind.conf.d
@@ -625,7 +625,7 @@ EOF
     sleep 5
 
     assert_eq "$(journalctl -b -u systemd-logind.service --since="$ts" --grep "Session \"$id\" of user \"logind-test-user\" is idle, stopping." | wc -l)" 1
-    assert_eq "$(loginctl --no-legend | grep -c "logind-test-user")" 0
+    assert_eq "$(loginctl --no-legend | grep tty | grep -c "logind-test-user")" 0
 }
 
 testcase_ambient_caps() {