]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: respect SD_LOGIND_ROOT_CHECK_INHIBITORS with weak blockers
authorLuca Boccassi <luca.boccassi@gmail.com>
Thu, 31 Oct 2024 16:02:38 +0000 (16:02 +0000)
committerLuca Boccassi <luca.boccassi@gmail.com>
Fri, 1 Nov 2024 15:43:14 +0000 (15:43 +0000)
The check for the old flag was not restored when the weak
blocker was added, add it back. Also skip polkit check for
root for the weak blocker, to keep compatibility with the
previous behaviour.

Partially fixes https://github.com/systemd/systemd/issues/34091

Follow-up for 804874d26ac73e0af07c4c5d7165c95372f03f6d

src/login/logind-dbus.c

index 7557ab2d93b820e554d82ee8771229589cd5102c..467c5f78a053c40d51668817cda0549b53a62931 100644 (file)
@@ -2056,6 +2056,7 @@ static int verify_shutdown_creds(
 
         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
         bool multiple_sessions, blocked, interactive;
+        Inhibitor *offending = NULL;
         uid_t uid;
         int r;
 
@@ -2076,7 +2077,7 @@ static int verify_shutdown_creds(
                 return r;
 
         multiple_sessions = r > 0;
-        blocked = manager_is_inhibited(m, a->inhibit_what, /* block= */ true, NULL, false, true, uid, NULL);
+        blocked = manager_is_inhibited(m, a->inhibit_what, /* block= */ true, NULL, false, true, uid, &offending);
         interactive = flags & SD_LOGIND_INTERACTIVE;
 
         if (multiple_sessions) {
@@ -2095,13 +2096,21 @@ static int verify_shutdown_creds(
         }
 
         if (blocked) {
-                if (!FLAGS_SET(flags, SD_LOGIND_SKIP_INHIBITORS))
+                PolkitFlags polkit_flags = 0;
+
+                /* With a strong inhibitor, if the skip flag is not set, reject outright.
+                 * With a weak inhibitor, if root is asking and the root flag is set, reject outright.
+                 * All else, check polkit first. */
+                if (!FLAGS_SET(flags, SD_LOGIND_SKIP_INHIBITORS) &&
+                    (offending->mode != INHIBIT_BLOCK_WEAK ||
+                     (uid == 0 && FLAGS_SET(flags, SD_LOGIND_ROOT_CHECK_INHIBITORS))))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED,
                                                  "Access denied due to active block inhibitor");
 
                 /* We want to always ask here, even for root, to only allow bypassing if explicitly allowed
-                 * by polkit */
-                PolkitFlags polkit_flags = POLKIT_ALWAYS_QUERY;
+                 * by polkit, unless a weak blocker is used, in which case it will be authorized. */
+                if (offending->mode != INHIBIT_BLOCK_WEAK)
+                        polkit_flags |= POLKIT_ALWAYS_QUERY;
 
                 if (interactive)
                         polkit_flags |= POLKIT_ALLOW_INTERACTIVE;