From e4b4d9cc7adf245950e8676be0e0f4a813069500 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Oct 2024 10:52:56 +0200 Subject: [PATCH 1/2] core: make sure that if PAMName= is set we always do the full user changing even if no user is specified explicitly When PAMName= is set this should be enough to go through our entire user changing story, so that PAM is definitely run, and environment variables definitely pulled in and so on. Previously, it would happen that under some circumstances we might no do this when transitioning from root to root itself even though PAM was enabled. Fixes: #34682 --- src/core/exec-invoke.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index cdfa9f823b..4b63e2a204 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -4061,7 +4061,7 @@ int exec_invoke( int r, ngids = 0; _cleanup_free_ gid_t *supplementary_gids = NULL; const char *username = NULL, *groupname = NULL; - _cleanup_free_ char *home_buffer = NULL, *memory_pressure_path = NULL; + _cleanup_free_ char *home_buffer = NULL, *memory_pressure_path = NULL, *own_user = NULL; const char *home = NULL, *shell = NULL; char **final_argv = NULL; dev_t journal_stream_dev = 0; @@ -4298,8 +4298,23 @@ int exec_invoke( username = runtime->dynamic_creds->user->name; } else { - if (context->user) { - r = get_fixed_user(context->user, &username, &uid, &gid, &home, &shell); + const char *u; + + if (context->user) + u = context->user; + else if (context->pam_name) { + /* If PAM is enabled but no user name is explicitly selected, then use our own one. */ + own_user = getusername_malloc(); + if (!own_user) { + *exit_status = EXIT_USER; + return log_exec_error_errno(context, params, r, "Failed to determine my own user ID: %m"); + } + u = own_user; + } else + u = NULL; + + if (u) { + r = get_fixed_user(u, &username, &uid, &gid, &home, &shell); if (r < 0) { *exit_status = EXIT_USER; return log_exec_error_errno(context, params, r, "Failed to determine user credentials: %m"); From f515ea1cd4981ceb1a2c85d676f279db2972283f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Oct 2024 22:51:49 +0200 Subject: [PATCH 2/2] test: add quick test to verify the PAM stack really ran in all run0 modes of operation --- test/units/TEST-74-AUX-UTILS.run.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/units/TEST-74-AUX-UTILS.run.sh b/test/units/TEST-74-AUX-UTILS.run.sh index 5b46e11409..3ef9c88d79 100755 --- a/test/units/TEST-74-AUX-UTILS.run.sh +++ b/test/units/TEST-74-AUX-UTILS.run.sh @@ -238,10 +238,13 @@ if [[ -e /usr/lib/pam.d/systemd-run0 ]] || [[ -e /etc/pam.d/systemd-run0 ]]; the run0 ls / assert_eq "$(run0 echo foo)" "foo" # Check if we set some expected environment variables - for arg in "" "--user=root" "--user=testuser"; do + for arg in "" "--user=root" "--user=0" "--user=testuser"; do assert_eq "$(run0 ${arg:+"$arg"} bash -c 'echo $SUDO_USER')" "$USER" assert_eq "$(run0 ${arg:+"$arg"} bash -c 'echo $SUDO_UID')" "$(id -u "$USER")" assert_eq "$(run0 ${arg:+"$arg"} bash -c 'echo $SUDO_GID')" "$(id -u "$USER")" + + # Validate that we actually went properly through PAM (XDG_SESSION_TYPE is set by pam_systemd) + assert_eq "$(run0 ${arg:+"$arg"} bash -c 'echo $XDG_SESSION_TYPE')" "unspecified" done # Let's chain a couple of run0 calls together, for fun readarray -t cmdline < <(printf "%.0srun0\n" {0..31})