File 1003-logind-store-a-timestamp-when-the-ACPI-power-button-.patch of Package systemd.24852

From 2cd7287269514aafc52035d6617179f523c53576 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@gnome.org>
Date: Thu, 16 Jun 2016 17:38:44 -0500
Subject: [PATCH 1003/1003] logind: store a timestamp when the ACPI power
 button is pressed

When we get a D-Bus call to shutdown, we'll use the corresponding
timestamp to see if this call is due to GDM responding to the ACPI
power button itself, or just due to any random program calling the
D-Bus shutdown method.

[federico: fixes bsc#981830]
[federico: fixes bsc#888612]
[fbui: fixes bsc#1072933]
---
 src/basic/login-util.h    |  3 ++-
 src/login/logind-action.c |  4 ++++
 src/login/logind-dbus.c   | 19 +++++++++++++++++--
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/basic/login-util.h b/src/basic/login-util.h
index 9832207458..a7ba835c65 100644
--- a/src/basic/login-util.h
+++ b/src/basic/login-util.h
@@ -7,10 +7,11 @@
 #define SD_LOGIND_ROOT_CHECK_INHIBITORS           (UINT64_C(1) << 0)
 
 /* For internal use only */
+#define SD_LOGIND_SLEEP_VERB                      (UINT64_C(1) << 62)
 #define SD_LOGIND_INTERACTIVE                     (UINT64_C(1) << 63)
 
 #define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC (SD_LOGIND_ROOT_CHECK_INHIBITORS)
-#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_ALL    (SD_LOGIND_ROOT_CHECK_INHIBITORS|SD_LOGIND_INTERACTIVE)
+#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_ALL    (SD_LOGIND_ROOT_CHECK_INHIBITORS|SD_LOGIND_SLEEP_VERB|SD_LOGIND_INTERACTIVE)
 
 bool session_id_valid(const char *id);
 
diff --git a/src/login/logind-action.c b/src/login/logind-action.c
index 1aeacfaf2b..1b856d41df 100644
--- a/src/login/logind-action.c
+++ b/src/login/logind-action.c
@@ -7,6 +7,7 @@
 #include "bus-util.h"
 #include "conf-parser.h"
 #include "format-util.h"
+#include "fs-util.h"
 #include "logind-action.h"
 #include "logind-dbus.h"
 #include "logind-session-dbus.h"
@@ -83,6 +84,9 @@ 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)
+                        (void) touch("/run/systemd/acpi-shutdown");
+
                 if (manager_is_inhibited(m, inhibit_key, INHIBIT_BLOCK, NULL, true, false, 0, NULL)) {
                         log_debug("Refusing %s operation, %s is inhibited.",
                                   handle_action_to_string(handle),
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 207347e166..b6f44339d0 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -1806,6 +1806,7 @@ static int verify_shutdown_creds(
 
         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
         bool multiple_sessions, blocked, interactive;
+        bool shutdown_through_acpi;
         uid_t uid;
         int r;
 
@@ -1830,7 +1831,19 @@ static int verify_shutdown_creds(
         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
         interactive = flags & SD_LOGIND_INTERACTIVE;
 
-        if (multiple_sessions && action_multiple_sessions) {
+        shutdown_through_acpi = false;
+        if (access("/run/systemd/acpi-shutdown", F_OK) == 0) {
+                struct stat buf;
+
+                if (!(flags & SD_LOGIND_SLEEP_VERB) &&
+                    stat("/run/systemd/acpi-shutdown", &buf) == 0)
+                        /* FIXME: this is really ugly. */
+                        shutdown_through_acpi = (time(NULL) - buf.st_mtime) <= 65;
+
+                unlink("/run/systemd/acpi-shutdown");
+        }
+
+        if (multiple_sessions && action_multiple_sessions && !shutdown_through_acpi) {
                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
                 if (r < 0)
                         return r;
@@ -1853,7 +1866,7 @@ static int verify_shutdown_creds(
                 }
         }
 
-        if (!multiple_sessions && !blocked && action) {
+        if (!multiple_sessions && !blocked && action && !shutdown_through_acpi) {
                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
                 if (r < 0)
                         return r;
@@ -1920,6 +1933,8 @@ static int method_do_shutdown_or_sleep(
                                                  "Sleep verb \"%s\" not supported", sleep_verb);
                 if (r < 0)
                         return r;
+
+                flags |= SD_LOGIND_SLEEP_VERB;
         }
 
         r = verify_shutdown_creds(m, message, w, action, action_multiple_sessions,
-- 
2.26.2

openSUSE Build Service is sponsored by