From 4cb4e6cf6dce2b66dcb59a8534aa6ca885e2f732 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 27 Nov 2023 17:31:50 +0100 Subject: [PATCH] pam_systemd: register systemd user service manager as class='manager' 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 | 27 +++++++++---------------- test/units/testsuite-35.sh | 40 +++++++++++++++++++------------------- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index 297689203b0..d7814a7275d 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -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)) diff --git a/test/units/testsuite-35.sh b/test/units/testsuite-35.sh index 8ea801ee96e..78bc07d8963 100755 --- a/test/units/testsuite-35.sh +++ b/test/units/testsuite-35.sh @@ -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() {