diff --git a/changelog/next.md b/changelog/next.md index ede8442d..4d8ec9a9 100644 --- a/changelog/next.md +++ b/changelog/next.md @@ -6,3 +6,4 @@ - Fixed missing/wrong change signals on various properties. - Fixed session lock crashes on sleep, wake, DPMS, and unlocking. - QsWindow.updatesEnabled makes sure windows are redrawn when set to true. +- Fixed the polkit agent failing to register when running outside a session cgroup, such as a systemd user service, by resolving the session from XDG_SESSION_ID. diff --git a/src/services/polkit/listener.cpp b/src/services/polkit/listener.cpp index e4bca4cf..f8a32ffc 100644 --- a/src/services/polkit/listener.cpp +++ b/src/services/polkit/listener.cpp @@ -11,8 +11,11 @@ #include #include #include +#include #include #include +#include +#include #include #include "../../core/logcat.hpp" @@ -93,6 +96,34 @@ void qs_polkit_agent_register(QsPolkitAgent* agent, const char* path) { return; } + const auto sessionId = qEnvironmentVariable("XDG_SESSION_ID"); + if (!sessionId.isEmpty()) { + const auto sessionIdUtf8 = sessionId.toUtf8(); + auto* subject = polkit_unix_session_new(sessionIdUtf8.constData()); + if (subject != nullptr) { + GError* error = nullptr; + agent->registration_handle = polkit_agent_listener_register( + POLKIT_AGENT_LISTENER(agent), + POLKIT_AGENT_REGISTER_FLAGS_NONE, + subject, + path, + nullptr, + &error + ); + g_object_unref(subject); + + if (error != nullptr) { + qCWarning(logPolkitListener) << "failed to register listener:" << error->message; + g_clear_error(&error); + agent->cb->registerComplete(false); + return; + } + + agent->cb->registerComplete(true); + return; + } + } + auto* data = new RegisterCbData {.agent = GObjectRef(agent), .path = path}; polkit_unix_session_new_for_process(getpid(), nullptr, &qs_polkit_agent_register_cb, data); }