From: Mike Yuan Date: Tue, 29 Jul 2025 13:16:05 +0000 (+0200) Subject: pam_systemd: never reset existing $XDG_RUNTIME_DIR for non-area logins X-Git-Tag: v258-rc2~47^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F38405%2Fhead;p=thirdparty%2Fsystemd.git pam_systemd: never reset existing $XDG_RUNTIME_DIR for non-area logins Follow-up for cfb7abc7fc8a7a3a79d44d0511e65a40566f1949 For whatever reason, ly is setting $XDG_RUNTIME_DIR before invoking PAM session on its own (https://github.com/fairyglade/ly/blob/v1.1.1/src/auth.zig#L45), which after the offending commit will potentially be unset again by pam_systemd. Let's restore the previous behavior if not switching area. Fixes #38402 --- diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index 344db418bc1..782e428ba34 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -1460,6 +1460,7 @@ static int export_legacy_dbus_address( const char *runtime) { assert(handle); + assert(runtime); /* We need to export $DBUS_SESSION_BUS_ADDRESS because various applications will not connect * correctly to the bus without it. This setting matches what dbus.socket does for the user session @@ -1473,9 +1474,6 @@ static int export_legacy_dbus_address( * expect the socket to be present by the time we do this check, so we can just as well check once * here. */ - if (!runtime) - return PAM_SUCCESS; - const char *s = strjoina(runtime, "/bus"); if (access(s, F_OK) < 0) { if (errno != ENOENT) @@ -1491,6 +1489,46 @@ static int export_legacy_dbus_address( return update_environment(handle, "DBUS_SESSION_BUS_ADDRESS", t); } +static int setup_runtime_directory( + pam_handle_t *handle, + UserRecord *ur, + const char *runtime_directory, + const char *area) { + + int r; + + assert(handle); + assert(ur); + + if (!runtime_directory) { + /* If this is an area switch request, always reset $XDG_RUNTIME_DIR if we got nothing + * to ensure the main runtime dir won't be clobbered. */ + if (area) + return update_environment(handle, "XDG_RUNTIME_DIR", NULL); + + return PAM_SUCCESS; + } + + /* Also create a per-area subdirectory for $XDG_RUNTIME_DIR, so that each area has their own + * set of runtime services. We follow the same directory structure as for $HOME. Note that we + * do not define any form of automatic clean-up for the per-aera subdirs beyond the regular + * clean-up of the whole $XDG_RUNTIME_DIR hierarchy when the user finally logs out. */ + _cleanup_free_ char *per_area_runtime_directory = NULL; + if (area) { + r = make_area_runtime_directory(handle, ur, runtime_directory, area, &per_area_runtime_directory); + if (r != PAM_SUCCESS) + return r; + + runtime_directory = per_area_runtime_directory; + } + + r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_directory); + if (r != PAM_SUCCESS) + return r; + + return export_legacy_dbus_address(handle, runtime_directory); +} + static int setup_environment( pam_handle_t *handle, UserRecord *ur, @@ -1558,25 +1596,7 @@ static int setup_environment( if (r != PAM_SUCCESS) return r; - _cleanup_free_ char *per_area_runtime_directory = NULL; - if (runtime_directory && area) { - /* Also create a per-area subdirectory for $XDG_RUNTIME_DIR, so that each area has their own - * set of runtime services. We follow the same directory structure as for $HOME. Note that we - * do not define any form of automatic clean-up for the per-aera subdirs beyond the regular - * clean-up of the whole $XDG_RUNTIME_DIR hierarchy when the user finally logs out. */ - - r = make_area_runtime_directory(handle, ur, runtime_directory, area, &per_area_runtime_directory); - if (r != PAM_SUCCESS) - return r; - - runtime_directory = per_area_runtime_directory; - } - - r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_directory); - if (r != PAM_SUCCESS) - return r; - - return export_legacy_dbus_address(handle, runtime_directory); + return setup_runtime_directory(handle, ur, runtime_directory, area); } static int open_osc_context(pam_handle_t *handle, const char *session_type, UserRecord *ur) {