diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 02:25:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 02:25:51 +0000 |
commit | ac8399db6ce846597966360732ce6d39a247bdd2 (patch) | |
tree | 046a28d2cbd02afa147291e8f69e9bb5dc29f1aa /debian/patches/shared-split-out-polkit-stuff-from-bus-util.c-bus-polkit..patch | |
parent | Adding upstream version 241. (diff) | |
download | systemd-ac8399db6ce846597966360732ce6d39a247bdd2.tar.xz systemd-ac8399db6ce846597966360732ce6d39a247bdd2.zip |
Adding debian version 241-7~deb10u8.debian/241-7_deb10u8
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/patches/shared-split-out-polkit-stuff-from-bus-util.c-bus-polkit..patch')
-rw-r--r-- | debian/patches/shared-split-out-polkit-stuff-from-bus-util.c-bus-polkit..patch | 1190 |
1 files changed, 1190 insertions, 0 deletions
diff --git a/debian/patches/shared-split-out-polkit-stuff-from-bus-util.c-bus-polkit..patch b/debian/patches/shared-split-out-polkit-stuff-from-bus-util.c-bus-polkit..patch new file mode 100644 index 0000000..3a14551 --- /dev/null +++ b/debian/patches/shared-split-out-polkit-stuff-from-bus-util.c-bus-polkit..patch @@ -0,0 +1,1190 @@ +From: Lennart Poettering <lennart@poettering.net> +Date: Wed, 22 Jan 2020 11:39:22 +0100 +Subject: =?utf-8?q?shared=3A_split_out_polkit_stuff_from_bus-util=2Ec_?= + =?utf-8?q?=E2=86=92_bus-polkit=2Ec?= + +It's enough, complex stuff to warrant its own source file. + +No other changes, just splitting out. + +(cherry picked from commit 269e4d2d6b75329ae39a71ebe2c14500e03cda95) +(cherry picked from commit 0a19ff7004e4a567566a0a7be6b050cf34c0bfe5) +(cherry picked from commit 31a1d569db43af04669ec487f3e741ddc6d12969) +(cherry picked from commit a4722a8df23f6612c47f1bb848a6a7c81dcbdccb) +--- + src/core/dbus-unit.c | 1 + + src/core/dbus.c | 2 +- + src/hostname/hostnamed.c | 2 +- + src/import/importd.c | 2 +- + src/locale/keymap-util.c | 2 + + src/locale/localed.c | 2 +- + src/login/logind-dbus.c | 1 + + src/login/logind-seat-dbus.c | 1 + + src/login/logind-session-dbus.c | 1 + + src/login/logind-user-dbus.c | 1 + + src/login/logind.c | 2 +- + src/machine/image-dbus.c | 1 + + src/machine/machine-dbus.c | 1 + + src/machine/machined-dbus.c | 1 + + src/machine/machined.c | 2 +- + src/network/networkd-link-bus.c | 2 + + src/network/networkd-manager-bus.c | 3 + + src/network/networkd-manager.c | 1 + + src/portable/portabled-bus.c | 2 +- + src/portable/portabled-image-bus.c | 1 + + src/portable/portabled.c | 2 +- + src/resolve/resolved-bus.c | 1 + + src/resolve/resolved-dnssd-bus.c | 5 +- + src/resolve/resolved-link-bus.c | 1 + + src/resolve/resolved-manager.c | 2 +- + src/shared/bus-polkit.c | 358 +++++++++++++++++++++++++++++++++++++ + src/shared/bus-polkit.h | 11 ++ + src/shared/bus-util.c | 357 +----------------------------------- + src/shared/bus-util.h | 7 +- + src/shared/meson.build | 2 + + src/timedate/timedated.c | 2 +- + 31 files changed, 406 insertions(+), 373 deletions(-) + create mode 100644 src/shared/bus-polkit.c + create mode 100644 src/shared/bus-polkit.h + +diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c +index 17c2003..ce0fbdb 100644 +--- a/src/core/dbus-unit.c ++++ b/src/core/dbus-unit.c +@@ -5,6 +5,7 @@ + #include "alloc-util.h" + #include "bpf-firewall.h" + #include "bus-common-errors.h" ++#include "bus-polkit.h" + #include "cgroup-util.h" + #include "condition.h" + #include "dbus-job.h" +diff --git a/src/core/dbus.c b/src/core/dbus.c +index 255b86e..91c06ce 100644 +--- a/src/core/dbus.c ++++ b/src/core/dbus.c +@@ -10,7 +10,7 @@ + #include "bus-common-errors.h" + #include "bus-error.h" + #include "bus-internal.h" +-#include "bus-util.h" ++#include "bus-polkit.h" + #include "dbus-automount.h" + #include "dbus-cgroup.h" + #include "dbus-device.h" +diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c +index 7777450..9b98f32 100644 +--- a/src/hostname/hostnamed.c ++++ b/src/hostname/hostnamed.c +@@ -7,7 +7,7 @@ + + #include "alloc-util.h" + #include "bus-common-errors.h" +-#include "bus-util.h" ++#include "bus-polkit.h" + #include "def.h" + #include "env-file-label.h" + #include "env-file.h" +diff --git a/src/import/importd.c b/src/import/importd.c +index 2426933..15430d8 100644 +--- a/src/import/importd.c ++++ b/src/import/importd.c +@@ -7,7 +7,7 @@ + + #include "alloc-util.h" + #include "bus-common-errors.h" +-#include "bus-util.h" ++#include "bus-polkit.h" + #include "def.h" + #include "fd-util.h" + #include "float.h" +diff --git a/src/locale/keymap-util.c b/src/locale/keymap-util.c +index 6b6b32a..c203c7a 100644 +--- a/src/locale/keymap-util.c ++++ b/src/locale/keymap-util.c +@@ -6,7 +6,9 @@ + #include <unistd.h> + + #include "bus-util.h" ++#include "bus-polkit.h" + #include "def.h" ++#include "env-file-label.h" + #include "env-file.h" + #include "env-file-label.h" + #include "env-util.h" +diff --git a/src/locale/localed.c b/src/locale/localed.c +index f851d35..0bc02a0 100644 +--- a/src/locale/localed.c ++++ b/src/locale/localed.c +@@ -14,7 +14,7 @@ + #include "alloc-util.h" + #include "bus-error.h" + #include "bus-message.h" +-#include "bus-util.h" ++#include "bus-polkit.h" + #include "def.h" + #include "keymap-util.h" + #include "locale-util.h" +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index b9ea370..91350fd 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -12,6 +12,7 @@ + #include "audit-util.h" + #include "bus-common-errors.h" + #include "bus-error.h" ++#include "bus-polkit.h" + #include "bus-unit-util.h" + #include "bus-util.h" + #include "cgroup-util.h" +diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c +index 6ee5a1c..28ea5b7 100644 +--- a/src/login/logind-seat-dbus.c ++++ b/src/login/logind-seat-dbus.c +@@ -6,6 +6,7 @@ + #include "alloc-util.h" + #include "bus-common-errors.h" + #include "bus-label.h" ++#include "bus-polkit.h" + #include "bus-util.h" + #include "logind-seat.h" + #include "logind.h" +diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c +index df5bfba..bd5c1fe 100644 +--- a/src/login/logind-session-dbus.c ++++ b/src/login/logind-session-dbus.c +@@ -6,6 +6,7 @@ + #include "alloc-util.h" + #include "bus-common-errors.h" + #include "bus-label.h" ++#include "bus-polkit.h" + #include "bus-util.h" + #include "fd-util.h" + #include "logind-session-device.h" +diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c +index fcaeba1..129696e 100644 +--- a/src/login/logind-user-dbus.c ++++ b/src/login/logind-user-dbus.c +@@ -4,6 +4,7 @@ + #include <string.h> + + #include "alloc-util.h" ++#include "bus-polkit.h" + #include "bus-util.h" + #include "format-util.h" + #include "logind-user.h" +diff --git a/src/login/logind.c b/src/login/logind.c +index 95ec0a5..171b898 100644 +--- a/src/login/logind.c ++++ b/src/login/logind.c +@@ -10,7 +10,7 @@ + + #include "alloc-util.h" + #include "bus-error.h" +-#include "bus-util.h" ++#include "bus-polkit.h" + #include "cgroup-util.h" + #include "def.h" + #include "device-util.h" +diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c +index 7e7f0d5..1322f3e 100644 +--- a/src/machine/image-dbus.c ++++ b/src/machine/image-dbus.c +@@ -5,6 +5,7 @@ + + #include "alloc-util.h" + #include "bus-label.h" ++#include "bus-polkit.h" + #include "bus-util.h" + #include "copy.h" + #include "dissect-image.h" +diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c +index 7a558df..39905e5 100644 +--- a/src/machine/machine-dbus.c ++++ b/src/machine/machine-dbus.c +@@ -15,6 +15,7 @@ + #include "bus-common-errors.h" + #include "bus-internal.h" + #include "bus-label.h" ++#include "bus-polkit.h" + #include "bus-util.h" + #include "copy.h" + #include "env-file.h" +diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c +index fea9cc2..f00be23 100644 +--- a/src/machine/machined-dbus.c ++++ b/src/machine/machined-dbus.c +@@ -9,6 +9,7 @@ + #include "alloc-util.h" + #include "btrfs-util.h" + #include "bus-common-errors.h" ++#include "bus-polkit.h" + #include "bus-util.h" + #include "cgroup-util.h" + #include "fd-util.h" +diff --git a/src/machine/machined.c b/src/machine/machined.c +index 0b92b1c..e3456d8 100644 +--- a/src/machine/machined.c ++++ b/src/machine/machined.c +@@ -8,7 +8,7 @@ + + #include "alloc-util.h" + #include "bus-error.h" +-#include "bus-util.h" ++#include "bus-polkit.h" + #include "cgroup-util.h" + #include "dirent-util.h" + #include "fd-util.h" +diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c +index 0dbcd86..beee910 100644 +--- a/src/network/networkd-link-bus.c ++++ b/src/network/networkd-link-bus.c +@@ -1,6 +1,8 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + + #include "alloc-util.h" ++#include "bus-common-errors.h" ++#include "bus-polkit.h" + #include "bus-util.h" + #include "networkd-link.h" + #include "networkd-manager.h" +diff --git a/src/network/networkd-manager-bus.c b/src/network/networkd-manager-bus.c +index 8c52783..7628878 100644 +--- a/src/network/networkd-manager-bus.c ++++ b/src/network/networkd-manager-bus.c +@@ -1,7 +1,10 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + + #include "alloc-util.h" ++#include "bus-common-errors.h" ++#include "bus-polkit.h" + #include "bus-util.h" ++#include "networkd-link.h" + #include "networkd-manager.h" + #include "strv.h" + +diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c +index acb9a75..bd29fd0 100644 +--- a/src/network/networkd-manager.c ++++ b/src/network/networkd-manager.c +@@ -9,6 +9,7 @@ + #include "sd-netlink.h" + + #include "alloc-util.h" ++#include "bus-polkit.h" + #include "bus-util.h" + #include "conf-parser.h" + #include "def.h" +diff --git a/src/portable/portabled-bus.c b/src/portable/portabled-bus.c +index 3cbdb0b..708ec94 100644 +--- a/src/portable/portabled-bus.c ++++ b/src/portable/portabled-bus.c +@@ -3,7 +3,7 @@ + #include "alloc-util.h" + #include "btrfs-util.h" + #include "bus-common-errors.h" +-#include "bus-util.h" ++#include "bus-polkit.h" + #include "fd-util.h" + #include "io-util.h" + #include "machine-image.h" +diff --git a/src/portable/portabled-image-bus.c b/src/portable/portabled-image-bus.c +index 3605598..beebcf8 100644 +--- a/src/portable/portabled-image-bus.c ++++ b/src/portable/portabled-image-bus.c +@@ -3,6 +3,7 @@ + #include "alloc-util.h" + #include "bus-common-errors.h" + #include "bus-label.h" ++#include "bus-polkit.h" + #include "bus-util.h" + #include "fd-util.h" + #include "fileio.h" +diff --git a/src/portable/portabled.c b/src/portable/portabled.c +index 49a359f..f5a34ff 100644 +--- a/src/portable/portabled.c ++++ b/src/portable/portabled.c +@@ -4,7 +4,7 @@ + #include "sd-daemon.h" + + #include "alloc-util.h" +-#include "bus-util.h" ++#include "bus-polkit.h" + #include "def.h" + #include "main-func.h" + #include "portabled-bus.h" +diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c +index 5b547ba..1638d3b 100644 +--- a/src/resolve/resolved-bus.c ++++ b/src/resolve/resolved-bus.c +@@ -2,6 +2,7 @@ + + #include "alloc-util.h" + #include "bus-common-errors.h" ++#include "bus-polkit.h" + #include "bus-util.h" + #include "dns-domain.h" + #include "missing_capability.h" +diff --git a/src/resolve/resolved-dnssd-bus.c b/src/resolve/resolved-dnssd-bus.c +index 24bb37b..f7dcb3b 100644 +--- a/src/resolve/resolved-dnssd-bus.c ++++ b/src/resolve/resolved-dnssd-bus.c +@@ -1,9 +1,10 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ + + #include "alloc-util.h" +-#include "bus-util.h" ++#include "bus-polkit.h" + #include "missing_capability.h" +-#include "resolved-dnssd.h" + #include "resolved-dnssd-bus.h" ++#include "resolved-dnssd.h" + #include "resolved-link.h" + #include "strv.h" + #include "user-util.h" +diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c +index 96093ff..53f017c 100644 +--- a/src/resolve/resolved-link-bus.c ++++ b/src/resolve/resolved-link-bus.c +@@ -2,6 +2,7 @@ + + #include "alloc-util.h" + #include "bus-common-errors.h" ++#include "bus-polkit.h" + #include "bus-util.h" + #include "parse-util.h" + #include "resolve-util.h" +diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c +index 2017b0e..422ec23 100644 +--- a/src/resolve/resolved-manager.c ++++ b/src/resolve/resolved-manager.c +@@ -11,7 +11,7 @@ + + #include "af-list.h" + #include "alloc-util.h" +-#include "bus-util.h" ++#include "bus-polkit.h" + #include "dirent-util.h" + #include "dns-domain.h" + #include "fd-util.h" +diff --git a/src/shared/bus-polkit.c b/src/shared/bus-polkit.c +new file mode 100644 +index 0000000..da4aee5 +--- /dev/null ++++ b/src/shared/bus-polkit.c +@@ -0,0 +1,358 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "bus-internal.h" ++#include "bus-message.h" ++#include "bus-polkit.h" ++#include "strv.h" ++#include "user-util.h" ++ ++static int check_good_user(sd_bus_message *m, uid_t good_user) { ++ _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; ++ uid_t sender_uid; ++ int r; ++ ++ assert(m); ++ ++ if (good_user == UID_INVALID) ++ return 0; ++ ++ r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_EUID, &creds); ++ if (r < 0) ++ return r; ++ ++ /* Don't trust augmented credentials for authorization */ ++ assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EUID) == 0, -EPERM); ++ ++ r = sd_bus_creds_get_euid(creds, &sender_uid); ++ if (r < 0) ++ return r; ++ ++ return sender_uid == good_user; ++} ++ ++int bus_test_polkit( ++ sd_bus_message *call, ++ int capability, ++ const char *action, ++ const char **details, ++ uid_t good_user, ++ bool *_challenge, ++ sd_bus_error *e) { ++ ++ int r; ++ ++ assert(call); ++ assert(action); ++ ++ /* Tests non-interactively! */ ++ ++ r = check_good_user(call, good_user); ++ if (r != 0) ++ return r; ++ ++ r = sd_bus_query_sender_privilege(call, capability); ++ if (r < 0) ++ return r; ++ else if (r > 0) ++ return 1; ++#if ENABLE_POLKIT ++ else { ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; ++ int authorized = false, challenge = false; ++ const char *sender, **k, **v; ++ ++ sender = sd_bus_message_get_sender(call); ++ if (!sender) ++ return -EBADMSG; ++ ++ r = sd_bus_message_new_method_call( ++ call->bus, ++ &request, ++ "org.freedesktop.PolicyKit1", ++ "/org/freedesktop/PolicyKit1/Authority", ++ "org.freedesktop.PolicyKit1.Authority", ++ "CheckAuthorization"); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_append( ++ request, ++ "(sa{sv})s", ++ "system-bus-name", 1, "name", "s", sender, ++ action); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_open_container(request, 'a', "{ss}"); ++ if (r < 0) ++ return r; ++ ++ STRV_FOREACH_PAIR(k, v, details) { ++ r = sd_bus_message_append(request, "{ss}", *k, *v); ++ if (r < 0) ++ return r; ++ } ++ ++ r = sd_bus_message_close_container(request); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_append(request, "us", 0, NULL); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_call(call->bus, request, 0, e, &reply); ++ if (r < 0) { ++ /* Treat no PK available as access denied */ ++ if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) { ++ sd_bus_error_free(e); ++ return -EACCES; ++ } ++ ++ return r; ++ } ++ ++ r = sd_bus_message_enter_container(reply, 'r', "bba{ss}"); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_read(reply, "bb", &authorized, &challenge); ++ if (r < 0) ++ return r; ++ ++ if (authorized) ++ return 1; ++ ++ if (_challenge) { ++ *_challenge = challenge; ++ return 0; ++ } ++ } ++#endif ++ ++ return -EACCES; ++} ++ ++#if ENABLE_POLKIT ++ ++typedef struct AsyncPolkitQuery { ++ sd_bus_message *request, *reply; ++ sd_bus_message_handler_t callback; ++ void *userdata; ++ sd_bus_slot *slot; ++ Hashmap *registry; ++} AsyncPolkitQuery; ++ ++static void async_polkit_query_free(AsyncPolkitQuery *q) { ++ ++ if (!q) ++ return; ++ ++ sd_bus_slot_unref(q->slot); ++ ++ if (q->registry && q->request) ++ hashmap_remove(q->registry, q->request); ++ ++ sd_bus_message_unref(q->request); ++ sd_bus_message_unref(q->reply); ++ ++ free(q); ++} ++ ++static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) { ++ _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL; ++ AsyncPolkitQuery *q = userdata; ++ int r; ++ ++ assert(reply); ++ assert(q); ++ ++ q->slot = sd_bus_slot_unref(q->slot); ++ q->reply = sd_bus_message_ref(reply); ++ ++ r = sd_bus_message_rewind(q->request, true); ++ if (r < 0) { ++ r = sd_bus_reply_method_errno(q->request, r, NULL); ++ goto finish; ++ } ++ ++ r = q->callback(q->request, q->userdata, &error_buffer); ++ r = bus_maybe_reply_error(q->request, r, &error_buffer); ++ ++finish: ++ async_polkit_query_free(q); ++ ++ return r; ++} ++ ++#endif ++ ++int bus_verify_polkit_async( ++ sd_bus_message *call, ++ int capability, ++ const char *action, ++ const char **details, ++ bool interactive, ++ uid_t good_user, ++ Hashmap **registry, ++ sd_bus_error *error) { ++ ++#if ENABLE_POLKIT ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL; ++ AsyncPolkitQuery *q; ++ const char *sender, **k, **v; ++ sd_bus_message_handler_t callback; ++ void *userdata; ++ int c; ++#endif ++ int r; ++ ++ assert(call); ++ assert(action); ++ assert(registry); ++ ++ r = check_good_user(call, good_user); ++ if (r != 0) ++ return r; ++ ++#if ENABLE_POLKIT ++ q = hashmap_get(*registry, call); ++ if (q) { ++ int authorized, challenge; ++ ++ /* This is the second invocation of this function, and ++ * there's already a response from polkit, let's ++ * process it */ ++ assert(q->reply); ++ ++ if (sd_bus_message_is_method_error(q->reply, NULL)) { ++ const sd_bus_error *e; ++ ++ e = sd_bus_message_get_error(q->reply); ++ ++ /* Treat no PK available as access denied */ ++ if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN) || ++ sd_bus_error_has_name(e, SD_BUS_ERROR_NAME_HAS_NO_OWNER)) ++ return -EACCES; ++ ++ /* Copy error from polkit reply */ ++ sd_bus_error_copy(error, e); ++ return -sd_bus_error_get_errno(e); ++ } ++ ++ r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}"); ++ if (r >= 0) ++ r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge); ++ if (r < 0) ++ return r; ++ ++ if (authorized) ++ return 1; ++ ++ if (challenge) ++ return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required."); ++ ++ return -EACCES; ++ } ++#endif ++ ++ r = sd_bus_query_sender_privilege(call, capability); ++ if (r < 0) ++ return r; ++ else if (r > 0) ++ return 1; ++ ++#if ENABLE_POLKIT ++ if (sd_bus_get_current_message(call->bus) != call) ++ return -EINVAL; ++ ++ callback = sd_bus_get_current_handler(call->bus); ++ if (!callback) ++ return -EINVAL; ++ ++ userdata = sd_bus_get_current_userdata(call->bus); ++ ++ sender = sd_bus_message_get_sender(call); ++ if (!sender) ++ return -EBADMSG; ++ ++ c = sd_bus_message_get_allow_interactive_authorization(call); ++ if (c < 0) ++ return c; ++ if (c > 0) ++ interactive = true; ++ ++ r = hashmap_ensure_allocated(registry, NULL); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_new_method_call( ++ call->bus, ++ &pk, ++ "org.freedesktop.PolicyKit1", ++ "/org/freedesktop/PolicyKit1/Authority", ++ "org.freedesktop.PolicyKit1.Authority", ++ "CheckAuthorization"); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_append( ++ pk, ++ "(sa{sv})s", ++ "system-bus-name", 1, "name", "s", sender, ++ action); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_open_container(pk, 'a', "{ss}"); ++ if (r < 0) ++ return r; ++ ++ STRV_FOREACH_PAIR(k, v, details) { ++ r = sd_bus_message_append(pk, "{ss}", *k, *v); ++ if (r < 0) ++ return r; ++ } ++ ++ r = sd_bus_message_close_container(pk); ++ if (r < 0) ++ return r; ++ ++ r = sd_bus_message_append(pk, "us", interactive, NULL); ++ if (r < 0) ++ return r; ++ ++ q = new0(AsyncPolkitQuery, 1); ++ if (!q) ++ return -ENOMEM; ++ ++ q->request = sd_bus_message_ref(call); ++ q->callback = callback; ++ q->userdata = userdata; ++ ++ r = hashmap_put(*registry, call, q); ++ if (r < 0) { ++ async_polkit_query_free(q); ++ return r; ++ } ++ ++ q->registry = *registry; ++ ++ r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0); ++ if (r < 0) { ++ async_polkit_query_free(q); ++ return r; ++ } ++ ++ return 0; ++#endif ++ ++ return -EACCES; ++} ++ ++void bus_verify_polkit_async_registry_free(Hashmap *registry) { ++#if ENABLE_POLKIT ++ hashmap_free_with_destructor(registry, async_polkit_query_free); ++#endif ++} +diff --git a/src/shared/bus-polkit.h b/src/shared/bus-polkit.h +new file mode 100644 +index 0000000..29b3923 +--- /dev/null ++++ b/src/shared/bus-polkit.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++#pragma once ++ ++#include "sd-bus.h" ++ ++#include "hashmap.h" ++ ++int bus_test_polkit(sd_bus_message *call, int capability, const char *action, const char **details, uid_t good_user, bool *_challenge, sd_bus_error *e); ++ ++int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, const char **details, bool interactive, uid_t good_user, Hashmap **registry, sd_bus_error *error); ++void bus_verify_polkit_async_registry_free(Hashmap *registry); +diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c +index a406dd8..c9d7e76 100644 +--- a/src/shared/bus-util.c ++++ b/src/shared/bus-util.c +@@ -11,7 +11,6 @@ + #include <sys/socket.h> + #include <unistd.h> + +-#include "sd-bus-protocol.h" + #include "sd-bus.h" + #include "sd-daemon.h" + #include "sd-event.h" +@@ -24,15 +23,14 @@ + #include "bus-util.h" + #include "cap-list.h" + #include "cgroup-util.h" +-#include "def.h" +-#include "escape.h" +-#include "fd-util.h" + #include "missing.h" + #include "mountpoint-util.h" + #include "nsflags.h" + #include "parse-util.h" + #include "proc-cmdline.h" ++#include "path-util.h" + #include "rlimit-util.h" ++#include "socket-util.h" + #include "stdio-util.h" + #include "strv.h" + #include "user-util.h" +@@ -187,357 +185,6 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) { + return has_owner; + } + +-static int check_good_user(sd_bus_message *m, uid_t good_user) { +- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; +- uid_t sender_uid; +- int r; +- +- assert(m); +- +- if (good_user == UID_INVALID) +- return 0; +- +- r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_EUID, &creds); +- if (r < 0) +- return r; +- +- /* Don't trust augmented credentials for authorization */ +- assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EUID) == 0, -EPERM); +- +- r = sd_bus_creds_get_euid(creds, &sender_uid); +- if (r < 0) +- return r; +- +- return sender_uid == good_user; +-} +- +-int bus_test_polkit( +- sd_bus_message *call, +- int capability, +- const char *action, +- const char **details, +- uid_t good_user, +- bool *_challenge, +- sd_bus_error *e) { +- +- int r; +- +- assert(call); +- assert(action); +- +- /* Tests non-interactively! */ +- +- r = check_good_user(call, good_user); +- if (r != 0) +- return r; +- +- r = sd_bus_query_sender_privilege(call, capability); +- if (r < 0) +- return r; +- else if (r > 0) +- return 1; +-#if ENABLE_POLKIT +- else { +- _cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL; +- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; +- int authorized = false, challenge = false; +- const char *sender, **k, **v; +- +- sender = sd_bus_message_get_sender(call); +- if (!sender) +- return -EBADMSG; +- +- r = sd_bus_message_new_method_call( +- call->bus, +- &request, +- "org.freedesktop.PolicyKit1", +- "/org/freedesktop/PolicyKit1/Authority", +- "org.freedesktop.PolicyKit1.Authority", +- "CheckAuthorization"); +- if (r < 0) +- return r; +- +- r = sd_bus_message_append( +- request, +- "(sa{sv})s", +- "system-bus-name", 1, "name", "s", sender, +- action); +- if (r < 0) +- return r; +- +- r = sd_bus_message_open_container(request, 'a', "{ss}"); +- if (r < 0) +- return r; +- +- STRV_FOREACH_PAIR(k, v, details) { +- r = sd_bus_message_append(request, "{ss}", *k, *v); +- if (r < 0) +- return r; +- } +- +- r = sd_bus_message_close_container(request); +- if (r < 0) +- return r; +- +- r = sd_bus_message_append(request, "us", 0, NULL); +- if (r < 0) +- return r; +- +- r = sd_bus_call(call->bus, request, 0, e, &reply); +- if (r < 0) { +- /* Treat no PK available as access denied */ +- if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) { +- sd_bus_error_free(e); +- return -EACCES; +- } +- +- return r; +- } +- +- r = sd_bus_message_enter_container(reply, 'r', "bba{ss}"); +- if (r < 0) +- return r; +- +- r = sd_bus_message_read(reply, "bb", &authorized, &challenge); +- if (r < 0) +- return r; +- +- if (authorized) +- return 1; +- +- if (_challenge) { +- *_challenge = challenge; +- return 0; +- } +- } +-#endif +- +- return -EACCES; +-} +- +-#if ENABLE_POLKIT +- +-typedef struct AsyncPolkitQuery { +- sd_bus_message *request, *reply; +- sd_bus_message_handler_t callback; +- void *userdata; +- sd_bus_slot *slot; +- Hashmap *registry; +-} AsyncPolkitQuery; +- +-static void async_polkit_query_free(AsyncPolkitQuery *q) { +- +- if (!q) +- return; +- +- sd_bus_slot_unref(q->slot); +- +- if (q->registry && q->request) +- hashmap_remove(q->registry, q->request); +- +- sd_bus_message_unref(q->request); +- sd_bus_message_unref(q->reply); +- +- free(q); +-} +- +-static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) { +- _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL; +- AsyncPolkitQuery *q = userdata; +- int r; +- +- assert(reply); +- assert(q); +- +- q->slot = sd_bus_slot_unref(q->slot); +- q->reply = sd_bus_message_ref(reply); +- +- r = sd_bus_message_rewind(q->request, true); +- if (r < 0) { +- r = sd_bus_reply_method_errno(q->request, r, NULL); +- goto finish; +- } +- +- r = q->callback(q->request, q->userdata, &error_buffer); +- r = bus_maybe_reply_error(q->request, r, &error_buffer); +- +-finish: +- async_polkit_query_free(q); +- +- return r; +-} +- +-#endif +- +-int bus_verify_polkit_async( +- sd_bus_message *call, +- int capability, +- const char *action, +- const char **details, +- bool interactive, +- uid_t good_user, +- Hashmap **registry, +- sd_bus_error *error) { +- +-#if ENABLE_POLKIT +- _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL; +- AsyncPolkitQuery *q; +- const char *sender, **k, **v; +- sd_bus_message_handler_t callback; +- void *userdata; +- int c; +-#endif +- int r; +- +- assert(call); +- assert(action); +- assert(registry); +- +- r = check_good_user(call, good_user); +- if (r != 0) +- return r; +- +-#if ENABLE_POLKIT +- q = hashmap_get(*registry, call); +- if (q) { +- int authorized, challenge; +- +- /* This is the second invocation of this function, and +- * there's already a response from polkit, let's +- * process it */ +- assert(q->reply); +- +- if (sd_bus_message_is_method_error(q->reply, NULL)) { +- const sd_bus_error *e; +- +- e = sd_bus_message_get_error(q->reply); +- +- /* Treat no PK available as access denied */ +- if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) +- return -EACCES; +- +- /* Copy error from polkit reply */ +- sd_bus_error_copy(error, e); +- return -sd_bus_error_get_errno(e); +- } +- +- r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}"); +- if (r >= 0) +- r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge); +- +- if (r < 0) +- return r; +- +- if (authorized) +- return 1; +- +- if (challenge) +- return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required."); +- +- return -EACCES; +- } +-#endif +- +- r = sd_bus_query_sender_privilege(call, capability); +- if (r < 0) +- return r; +- else if (r > 0) +- return 1; +- +-#if ENABLE_POLKIT +- if (sd_bus_get_current_message(call->bus) != call) +- return -EINVAL; +- +- callback = sd_bus_get_current_handler(call->bus); +- if (!callback) +- return -EINVAL; +- +- userdata = sd_bus_get_current_userdata(call->bus); +- +- sender = sd_bus_message_get_sender(call); +- if (!sender) +- return -EBADMSG; +- +- c = sd_bus_message_get_allow_interactive_authorization(call); +- if (c < 0) +- return c; +- if (c > 0) +- interactive = true; +- +- r = hashmap_ensure_allocated(registry, NULL); +- if (r < 0) +- return r; +- +- r = sd_bus_message_new_method_call( +- call->bus, +- &pk, +- "org.freedesktop.PolicyKit1", +- "/org/freedesktop/PolicyKit1/Authority", +- "org.freedesktop.PolicyKit1.Authority", +- "CheckAuthorization"); +- if (r < 0) +- return r; +- +- r = sd_bus_message_append( +- pk, +- "(sa{sv})s", +- "system-bus-name", 1, "name", "s", sender, +- action); +- if (r < 0) +- return r; +- +- r = sd_bus_message_open_container(pk, 'a', "{ss}"); +- if (r < 0) +- return r; +- +- STRV_FOREACH_PAIR(k, v, details) { +- r = sd_bus_message_append(pk, "{ss}", *k, *v); +- if (r < 0) +- return r; +- } +- +- r = sd_bus_message_close_container(pk); +- if (r < 0) +- return r; +- +- r = sd_bus_message_append(pk, "us", interactive, NULL); +- if (r < 0) +- return r; +- +- q = new0(AsyncPolkitQuery, 1); +- if (!q) +- return -ENOMEM; +- +- q->request = sd_bus_message_ref(call); +- q->callback = callback; +- q->userdata = userdata; +- +- r = hashmap_put(*registry, call, q); +- if (r < 0) { +- async_polkit_query_free(q); +- return r; +- } +- +- q->registry = *registry; +- +- r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0); +- if (r < 0) { +- async_polkit_query_free(q); +- return r; +- } +- +- return 0; +-#endif +- +- return -EACCES; +-} +- +-void bus_verify_polkit_async_registry_free(Hashmap *registry) { +-#if ENABLE_POLKIT +- hashmap_free_with_destructor(registry, async_polkit_query_free); +-#endif +-} +- + int bus_check_peercred(sd_bus *c) { + struct ucred ucred; + int fd, r; +diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h +index 71c248f..c9cbf76 100644 +--- a/src/shared/bus-util.h ++++ b/src/shared/bus-util.h +@@ -9,8 +9,8 @@ + #include "sd-bus.h" + #include "sd-event.h" + +-#include "hashmap.h" + #include "macro.h" ++#include "set.h" + #include "string-util.h" + + typedef enum BusTransport { +@@ -51,11 +51,6 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error); + + int bus_check_peercred(sd_bus *c); + +-int bus_test_polkit(sd_bus_message *call, int capability, const char *action, const char **details, uid_t good_user, bool *_challenge, sd_bus_error *e); +- +-int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, const char **details, bool interactive, uid_t good_user, Hashmap **registry, sd_bus_error *error); +-void bus_verify_polkit_async_registry_free(Hashmap *registry); +- + int bus_connect_system_systemd(sd_bus **_bus); + int bus_connect_user_systemd(sd_bus **_bus); + +diff --git a/src/shared/meson.build b/src/shared/meson.build +index 99d6ba1..f6d1092 100644 +--- a/src/shared/meson.build ++++ b/src/shared/meson.build +@@ -25,6 +25,8 @@ shared_sources = files(''' + bus-unit-util.h + bus-util.c + bus-util.h ++ bus-polkit.c ++ bus-polkit.h + calendarspec.c + calendarspec.h + cgroup-show.c +diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c +index 324d4a4..398d4f4 100644 +--- a/src/timedate/timedated.c ++++ b/src/timedate/timedated.c +@@ -11,7 +11,7 @@ + #include "alloc-util.h" + #include "bus-common-errors.h" + #include "bus-error.h" +-#include "bus-util.h" ++#include "bus-polkit.h" + #include "clock-util.h" + #include "def.h" + #include "fileio-label.h" |