From: Luca Boccassi Date: Thu, 31 Oct 2024 16:02:38 +0000 (+0000) Subject: logind: respect SD_LOGIND_ROOT_CHECK_INHIBITORS with weak blockers X-Git-Tag: v257-rc1~52^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=845f95b9e003f8386f80f4b7c157c805f3a46ad0;p=thirdparty%2Fsystemd.git logind: respect SD_LOGIND_ROOT_CHECK_INHIBITORS with weak blockers 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 --- diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 7557ab2d93b..467c5f78a05 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -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;