diff --git a/meson.build b/meson.build index 48d4f0027c..57e26dfed6 100644 --- a/meson.build +++ b/meson.build @@ -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 index 0000000000..ff79172cdf --- /dev/null +++ b/src/login/10-systemd-logind-root-ignore-inhibitors.rules.example @@ -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; + } +}); diff --git a/src/login/meson.build b/src/login/meson.build index 86879b4723..b744843933 100644 --- a/src/login/meson.build +++ b/src/login/meson.build @@ -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 diff --git a/src/systemctl/systemctl-logind.c b/src/systemctl/systemctl-logind.c index 0df669f484..4acd32832c 100644 --- a/src/systemctl/systemctl-logind.c +++ b/src/systemctl/systemctl-logind.c @@ -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));