--- src/login/logind-action.c | 5 +++++ src/login/logind-dbus.c | 31 +++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-) Index: systemd-221/src/login/logind-action.c =================================================================== --- systemd-221.orig/src/login/logind-action.c +++ systemd-221/src/login/logind-action.c @@ -85,6 +85,11 @@ int manager_handle_action( /* If the key handling is inhibited, don't do anything */ if (inhibit_key > 0) { + if (inhibit_key == INHIBIT_HANDLE_POWER_KEY) { + int fd; + fd = open("/run/systemd/acpi-shutdown", O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR); + close(fd); + } if (manager_is_inhibited(m, inhibit_key, INHIBIT_BLOCK, NULL, true, false, 0, NULL)) { log_debug("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_key)); return 0; Index: systemd-221/src/login/logind-dbus.c =================================================================== --- systemd-221.orig/src/login/logind-dbus.c +++ systemd-221/src/login/logind-dbus.c @@ -1625,12 +1625,13 @@ static int verify_shutdown_creds( const char *action, const char *action_multiple_sessions, const char *action_ignore_inhibit, - sd_bus_error *error) { + sd_bus_error *error, const char *sleep_verb) { _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; - bool multiple_sessions, blocked; + bool multiple_sessions, blocked, shutdown_through_acpi; uid_t uid; - int r; + int r, fd; + struct stat buf; assert(m); assert(message); @@ -1652,7 +1653,19 @@ static int verify_shutdown_creds( multiple_sessions = r > 0; blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL); - if (multiple_sessions && action_multiple_sessions) { + fd = open ("/run/systemd/acpi-shutdown", O_NOFOLLOW|O_PATH|O_CLOEXEC); + if (fd >= 0) { + shutdown_through_acpi = fstat(fd, &buf) == 0 && + time(NULL) - buf.st_mtime <= 65 && + sleep_verb == NULL; + close(fd); + unlink ("/run/systemd/acpi-shutdown"); + } + else + shutdown_through_acpi = false; + + if (multiple_sessions && action_multiple_sessions && + !shutdown_through_acpi) { r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error); if (r < 0) return r; @@ -1660,7 +1673,7 @@ static int verify_shutdown_creds( return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ } - if (blocked && action_ignore_inhibit) { + if (blocked && action_ignore_inhibit && !shutdown_through_acpi) { r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error); if (r < 0) return r; @@ -1668,7 +1681,8 @@ static int verify_shutdown_creds( return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ } - if (!multiple_sessions && !blocked && action) { + if (!multiple_sessions && !blocked && action && + !shutdown_through_acpi) { r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error); if (r < 0) return r; @@ -1716,7 +1730,7 @@ static int method_do_shutdown_or_sleep( } r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions, - action_ignore_inhibit, error); + action_ignore_inhibit, error, sleep_verb); if (r != 0) return r; @@ -1896,7 +1910,8 @@ static int method_schedule_shutdown(sd_b return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type"); r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false, - action, action_multiple_sessions, action_ignore_inhibit, error); + action, action_multiple_sessions, + action_ignore_inhibit, error, "UNUSED"); if (r != 0) return r;