diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index a33d8f05c5..2fd930ec7d 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -196,13 +196,30 @@ static int export_legacy_dbus_address( uid_t uid, const char *runtime) { - _cleanup_free_ char *s = NULL; + const char *s; + _cleanup_free_ char *t = NULL; int r = PAM_BUF_ERR; - if (asprintf(&s, DEFAULT_USER_BUS_ADDRESS_FMT, runtime) < 0) + /* 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 using 'systemctl --user set-environment'. We want to have the same configuration + * in processes started from the PAM session. + * + * The setting of the address is guarded by the access() check because it is also possible to compile + * dbus without --enable-user-session, in which case this socket is not used, and + * $DBUS_SESSION_BUS_ADDRESS should not be set. An alternative approach would to not do the access() + * check here, and let applications try on their own, by using "unix:path=%s/bus;autolaunch:". But we + * expect the socket to be present by the time we do this check, so we can just as well check once + * here. */ + + s = strjoina(runtime, "/bus"); + if (access(s, F_OK) < 0) + return PAM_SUCCESS; + + if (asprintf(&t, DEFAULT_USER_BUS_ADDRESS_FMT, runtime) < 0) goto error; - r = pam_misc_setenv(handle, "DBUS_SESSION_BUS_ADDRESS", s, 0); + r = pam_misc_setenv(handle, "DBUS_SESSION_BUS_ADDRESS", t, 0); if (r != PAM_SUCCESS) goto error;