From: Unfolded Circle Date: Tue, 12 Aug 2026 00:00:00 +0000 Subject: [PATCH] logind: allow delay-mode inhibitor locks without polkit The image ships no polkit, so logind's authorization fallback for Inhibit() is effectively uid-0 only: the CAP_SYS_BOOT fallback cannot trigger because dbus-daemon never transmits capabilities and sd-bus refuses /proc-augmented capability data for authorization decisions (sd_bus_query_sender_privilege). That makes delay locks root-only, although upstream's polkit defaults allow them for everyone (org.freedesktop.login1.inhibit-delay-{sleep,shutdown}: allow_any=yes). Skip the authorization for delay-mode locks only, reproducing the upstream default. Block and handle-* inhibitors keep the standard authorization. Delay mode is already restricted to shutdown/sleep by the preceding check, and logind bounds every delay lock with InhibitDelayMaxSec regardless of who holds it. Used by remote-core to hold the pre-sleep window for the suspend handshake (remote-core ADR 0005). --- src/login/logind-dbus.c | 45 ++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -3239,25 +3239,32 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running"); - r = bus_verify_polkit_async( - message, - CAP_SYS_BOOT, - w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") : - w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") : - w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" : - w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" : - w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" : - w == INHIBIT_HANDLE_REBOOT_KEY ? "org.freedesktop.login1.inhibit-handle-reboot-key" : - w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" : - "org.freedesktop.login1.inhibit-handle-lid-switch", - NULL, - false, - UID_INVALID, - &m->polkit_registry, - error); - if (r < 0) - return r; - if (r == 0) - return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ + /* Unfolded Circle: no polkit in this image. Delay-mode locks are allowed for + * everyone, matching the upstream polkit defaults + * (org.freedesktop.login1.inhibit-delay-{sleep,shutdown}: allow_any=yes). + * Without polkit the built-in fallback is uid-0 only, which would make delay + * locks root-only. Block and handle-* inhibitors keep the default authorization. */ + if (mm != INHIBIT_DELAY) { + r = bus_verify_polkit_async( + message, + CAP_SYS_BOOT, + w == INHIBIT_SHUTDOWN ? "org.freedesktop.login1.inhibit-block-shutdown" : + w == INHIBIT_SLEEP ? "org.freedesktop.login1.inhibit-block-sleep" : + w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" : + w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" : + w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" : + w == INHIBIT_HANDLE_REBOOT_KEY ? "org.freedesktop.login1.inhibit-handle-reboot-key" : + w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" : + "org.freedesktop.login1.inhibit-handle-lid-switch", + NULL, + false, + UID_INVALID, + &m->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ + } r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds); if (r < 0)