]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
login: add polkit example rules for allowing root to ignore inhibitors
authorNick Rosbrook <enr0n@ubuntu.com>
Fri, 21 Mar 2025 19:14:20 +0000 (15:14 -0400)
committerNick Rosbrook <enr0n@ubuntu.com>
Tue, 25 Mar 2025 20:15:34 +0000 (16:15 -0400)
The semantics of strong inhibitors require that POLKIT_ALWAYS_QUERY
always be set when checking if we can allow blocking inhibitors to be
ignored on shutdown, reboot, etc. With the default polkit rules and
policy, users may experience a situation where users in the sudo group
are authorized to run:

 systemctl reboot --check-inhibitors=no

but the root user is not authorized. Instead, the following error is
given:

 Call to Reboot failed: Interactive authentication required.

While this is correct according to the semantics of strong inhibitors,
it is confusing. To help the situation, provide example polkit rules
that allow root to perform these actions.

Finally, when root receives SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED
when calling e.g. systemctl reboot, print a message explaining that this
is due to the current polkit policy, and point to the new example rule.

Related: https://github.com/systemd/systemd/issues/36786

meson.build
src/login/10-systemd-logind-root-ignore-inhibitors.rules.example [new file with mode: 0644]
src/login/meson.build
src/systemctl/systemctl-logind.c

index 48d4f0027c05425e5977aaf778c162b519079354..57e26dfed6d4e19711277c90b9c1fee6ce947a32 100644 (file)
@@ -259,6 +259,7 @@ conf.set_quoted('MODPROBE_DIR',                               modprobedir)
 conf.set_quoted('MODULESLOAD_DIR',                            modulesloaddir)
 conf.set_quoted('PKGSYSCONFDIR',                              pkgsysconfdir)
 conf.set_quoted('POLKIT_AGENT_BINARY_PATH',                   bindir / 'pkttyagent')
+conf.set_quoted('POLKIT_RULES_DIR',                           polkitrulesdir)
 conf.set_quoted('PREFIX',                                     prefixdir)
 conf.set_quoted('PREFIX_NOSLASH',                             prefixdir_noslash)
 conf.set_quoted('RANDOM_SEED',                                randomseeddir / 'random-seed')
diff --git a/src/login/10-systemd-logind-root-ignore-inhibitors.rules.example b/src/login/10-systemd-logind-root-ignore-inhibitors.rules.example
new file mode 100644 (file)
index 0000000..ff79172
--- /dev/null
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: MIT-0
+//
+// This config file is installed as part of systemd.
+// It may be freely copied and edited (following the MIT No Attribution license).
+//
+// This example can be enabled by symlinking this file to
+// /etc/polkit-1/rules.d/10-systemd-logind-root-ignore-inhibitors.rules
+
+// Allow the root user to ignore inhibitors when calling reboot etc.
+polkit.addRule(function(action, subject) {
+    if ((action.id == "org.freedesktop.login1.power-off-ignore-inhibit" ||
+         action.id == "org.freedesktop.login1.reboot-ignore-inhibit" ||
+         action.id == "org.freedesktop.login1.halt-ignore-inhibit" ||
+         action.id == "org.freedesktop.login1.suspend-ignore-inhibit" ||
+         action.id == "org.freedesktop.login1.hibernate-ignore-inhibit") &&
+       subject.user == "root") {
+
+       return polkit.Result.YES;
+    }
+});
index 86879b472379d4ddfd7228addf992e90c91abae7..b74484393361daac230e179b36bfd0e90298a618 100644 (file)
@@ -150,4 +150,6 @@ if enable_logind
                      install_dir : dbussystemservicedir)
         install_data('org.freedesktop.login1.policy',
                      install_dir : polkitpolicydir)
+        install_data('10-systemd-logind-root-ignore-inhibitors.rules.example',
+                     install_dir : polkitrulesdir)
 endif
index 0df669f484e974d6306f303e250ee9e4752e2e79..4acd32832cf188866c465d62dea3919422219058 100644 (file)
@@ -109,6 +109,12 @@ int logind_reboot(enum action a) {
         }
         if (r >= 0)
                 return 0;
+        if (geteuid() == 0 && sd_bus_error_has_name(&error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED))
+                return log_error_errno(r,
+                                       "The current polkit policy does not allow root to ignore inhibitors without authentication in order to %s.\n"
+                                       "To allow this action, a new polkit rule is needed.\n"
+                                       "See " POLKIT_RULES_DIR "/10-systemd-logind-root-ignore-inhibitors.rules.example.",
+                                       action_table[a].verb);
         if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD) || a == ACTION_SLEEP)
                 return log_error_errno(r, "Call to %s failed: %s", actions[a], bus_error_message(&error, r));