Bug#956216: buster-pu: package systemd/241-7~deb10u3
Michael Biebl
biebl at debian.org
Mon Apr 27 18:17:14 BST 2020
Am 25.04.20 um 21:41 schrieb Adam D. Barratt:
> On Wed, 2020-04-08 at 16:11 +0200, Michael Biebl wrote:
> I'd be OK with that, but this will need a KiBi-ack, so CCing and
> tagging accordingly.
After talking to KiBi on IRC, we decided to include the fix for #958397
as well. I kept the changes minimal and only included 60-rules in
udev-udeb and the initramfs.
We might consider a different, opt-out approach for udev-rules in the
future as suggested by Steve [1] and Marco [2]. But that's probably too
invasive for a stable upload.
Updated debdiff is attached. The changes to the previous debdiff can be
found at
https://salsa.debian.org/systemd-team/systemd/-/commit/4b7f1d2b1763574cfc9ef43e728045518d440c1a
Regards,
Michael
[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=958397#12
[2] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=958397#22
-------------- next part --------------
diff --git a/debian/changelog b/debian/changelog
index 1d263f7..14ef57f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,18 @@
+systemd (241-7~deb10u4) buster; urgency=medium
+
+ * polkit: when authorizing via PolicyKit re-resolve callback/userdata
+ instead of caching it.
+ This fixes a heap use-after-free vulnerability in systemd, when
+ asynchronous PolicyKit queries are performed while handling DBus messages.
+ CVE-2020-1712 (Closes: #950732)
+ * Install 60-block.rules in udev-udeb and initramfs-tools.
+ The block device rules were split out from 60-persistent-storage.rules
+ into its own rules file in v220. Those rules ensure that change events
+ are emitted and the udev db is updated after metadata changes.
+ Thanks to Pascal Hambourg (Closes: #958397)
+
+ -- Michael Biebl <biebl at debian.org> Mon, 27 Apr 2020 19:02:57 +0200
+
systemd (241-7~deb10u3) buster; urgency=medium
* core: set fs.file-max sysctl to LONG_MAX rather than ULONG_MAX.
diff --git a/debian/extra/initramfs-tools/hooks/udev b/debian/extra/initramfs-tools/hooks/udev
index 6305d09..bbbd351 100755
--- a/debian/extra/initramfs-tools/hooks/udev
+++ b/debian/extra/initramfs-tools/hooks/udev
@@ -28,7 +28,8 @@ if [ -d /etc/systemd/network ]; then
fi
mkdir -p "$DESTDIR/lib/udev/rules.d/"
-for rules in 50-firmware.rules 50-udev-default.rules 60-persistent-storage.rules \
+for rules in 50-firmware.rules 50-udev-default.rules \
+ 60-block.rules 60-persistent-storage.rules \
61-persistent-storage-android.rules 71-seat.rules 73-special-net-names.rules \
73-usb-net-by-mac.rules 75-net-description.rules \
80-net-setup-link.rules 80-drivers.rules; do
diff --git a/debian/patches/Fix-typo-in-function-name.patch b/debian/patches/Fix-typo-in-function-name.patch
new file mode 100644
index 0000000..4f3c521
--- /dev/null
+++ b/debian/patches/Fix-typo-in-function-name.patch
@@ -0,0 +1,77 @@
+From: =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Tue, 4 Feb 2020 18:39:04 +0100
+Subject: Fix typo in function name
+
+(cherry picked from commit bc130b6858327b382b07b3985cf48e2aa9016b2d)
+(cherry picked from commit b4eb8848240c3540180e4768216a0b884a5ed783)
+(cherry picked from commit f14fa558ae9e139c94ee3af4a1ef1df313b2ff66)
+(cherry picked from commit dd8aa0871d9cafa60a916d4ec01dd82d64edf7ed)
+---
+ TODO | 2 +-
+ src/libsystemd/sd-bus/bus-message.h | 2 +-
+ src/libsystemd/sd-bus/sd-bus.c | 8 ++++----
+ src/shared/bus-polkit.c | 2 +-
+ 4 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/TODO b/TODO
+index 462db57..327fead 100644
+--- a/TODO
++++ b/TODO
+@@ -138,7 +138,7 @@ Features:
+
+ * the a-posteriori stopping of units bound to units that disappeared logic
+ should be reworked: there should be a queue of units, and we should only
+- enqeue stop jobs from a defer event that processes queue instead of
++ enqueue stop jobs from a defer event that processes queue instead of
+ right-away when we find a unit that is bound to one that doesn't exist
+ anymore. (similar to how the stop-unneeded queue has been reworked the same
+ way)
+diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h
+index 7fd3f11..849d638 100644
+--- a/src/libsystemd/sd-bus/bus-message.h
++++ b/src/libsystemd/sd-bus/bus-message.h
+@@ -211,4 +211,4 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m);
+
+ void bus_message_set_sender_driver(sd_bus *bus, sd_bus_message *m);
+ void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m);
+-int sd_bus_enqeue_for_read(sd_bus *bus, sd_bus_message *m);
++int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m);
+diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
+index 94380af..c20adcf 100644
+--- a/src/libsystemd/sd-bus/sd-bus.c
++++ b/src/libsystemd/sd-bus/sd-bus.c
+@@ -4145,7 +4145,7 @@ _public_ int sd_bus_get_close_on_exit(sd_bus *bus) {
+ return bus->close_on_exit;
+ }
+
+-int sd_bus_enqeue_for_read(sd_bus *bus, sd_bus_message *m) {
++int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m) {
+ int r;
+
+ assert_return(bus, -EINVAL);
+@@ -4157,9 +4157,9 @@ int sd_bus_enqeue_for_read(sd_bus *bus, sd_bus_message *m) {
+ if (!BUS_IS_OPEN(bus->state))
+ return -ENOTCONN;
+
+- /* Re-enqeue a message for reading. This is primarily useful for PolicyKit-style authentication,
+- * where we want accept a message, then determine we need to interactively authenticate the user, and
+- * when we have that process the message again. */
++ /* Re-enqueue a message for reading. This is primarily useful for PolicyKit-style authentication,
++ * where we accept a message, then determine we need to interactively authenticate the user, and then
++ * we want to process the message again. */
+
+ r = bus_rqueue_make_room(bus);
+ if (r < 0)
+diff --git a/src/shared/bus-polkit.c b/src/shared/bus-polkit.c
+index 02c11aa..d1d2456 100644
+--- a/src/shared/bus-polkit.c
++++ b/src/shared/bus-polkit.c
+@@ -236,7 +236,7 @@ static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_e
+ if (r < 0)
+ goto fail;
+
+- r = sd_bus_enqeue_for_read(sd_bus_message_get_bus(q->request), q->request);
++ r = sd_bus_enqueue_for_read(sd_bus_message_get_bus(q->request), q->request);
+ if (r < 0)
+ goto fail;
+
diff --git a/debian/patches/bus-polkit-rename-return-error-parameter-to-ret_error.patch b/debian/patches/bus-polkit-rename-return-error-parameter-to-ret_error.patch
new file mode 100644
index 0000000..a7c9cc5
--- /dev/null
+++ b/debian/patches/bus-polkit-rename-return-error-parameter-to-ret_error.patch
@@ -0,0 +1,67 @@
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 22 Jan 2020 14:29:43 +0100
+Subject: bus-polkit: rename return error parameter to ret_error
+
+(cherry picked from commit 773b1a7916bfce3aa2a21ecf534d475032e8528e)
+(cherry picked from commit 5b2442d5c3ec1c86a3a8d1c1abe3234a570ba5e6)
+(cherry picked from commit 4441844d5889a39d9d059c30e5d94c916d9d6735)
+(cherry picked from commit 816d5e2d6dd83a3bd0ff56a352295831cb937198)
+---
+ src/shared/bus-polkit.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/src/shared/bus-polkit.c b/src/shared/bus-polkit.c
+index da4aee5..f93aa17 100644
+--- a/src/shared/bus-polkit.c
++++ b/src/shared/bus-polkit.c
+@@ -37,7 +37,7 @@ int bus_test_polkit(
+ const char **details,
+ uid_t good_user,
+ bool *_challenge,
+- sd_bus_error *e) {
++ sd_bus_error *ret_error) {
+
+ int r;
+
+@@ -102,11 +102,11 @@ int bus_test_polkit(
+ if (r < 0)
+ return r;
+
+- r = sd_bus_call(call->bus, request, 0, e, &reply);
++ r = sd_bus_call(call->bus, request, 0, ret_error, &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);
++ if (sd_bus_error_has_name(ret_error, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
++ sd_bus_error_free(ret_error);
+ return -EACCES;
+ }
+
+@@ -196,7 +196,7 @@ int bus_verify_polkit_async(
+ bool interactive,
+ uid_t good_user,
+ Hashmap **registry,
+- sd_bus_error *error) {
++ sd_bus_error *ret_error) {
+
+ #if ENABLE_POLKIT
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
+@@ -237,7 +237,7 @@ int bus_verify_polkit_async(
+ return -EACCES;
+
+ /* Copy error from polkit reply */
+- sd_bus_error_copy(error, e);
++ sd_bus_error_copy(ret_error, e);
+ return -sd_bus_error_get_errno(e);
+ }
+
+@@ -251,7 +251,7 @@ int bus_verify_polkit_async(
+ return 1;
+
+ if (challenge)
+- return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
++ return sd_bus_error_set(ret_error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
+
+ return -EACCES;
+ }
diff --git a/debian/patches/bus-util-treat-org.freedesktop.DBus.Error.ServiceUnknown-.patch b/debian/patches/bus-util-treat-org.freedesktop.DBus.Error.ServiceUnknown-.patch
new file mode 100644
index 0000000..ffd349f
--- /dev/null
+++ b/debian/patches/bus-util-treat-org.freedesktop.DBus.Error.ServiceUnknown-.patch
@@ -0,0 +1,34 @@
+From: Yu Watanabe <watanabe.yu+github at gmail.com>
+Date: Thu, 4 Apr 2019 13:35:29 +0900
+Subject: bus-util: treat org.freedesktop.DBus.Error.ServiceUnknown nicely
+ when polkit does not exist
+
+Fixes #12209.
+
+(cherry picked from commit 8c69fe79df6394f6b8b8d0bb536a265caf417868)
+(cherry picked from commit 0bb488b22144aeb87d93e97123f71babe116261f)
+---
+ src/shared/bus-util.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
+index 9d31fba..a406dd8 100644
+--- a/src/shared/bus-util.c
++++ b/src/shared/bus-util.c
+@@ -410,14 +410,14 @@ int bus_verify_polkit_async(
+ if (sd_bus_message_is_method_error(q->reply, NULL)) {
+ const sd_bus_error *e;
+
+- /* Copy error from polkit reply */
+ e = sd_bus_message_get_error(q->reply);
+- sd_bus_error_copy(error, e);
+
+ /* 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);
+ }
+
diff --git a/debian/patches/debian/Use-Debian-specific-config-files.patch b/debian/patches/debian/Use-Debian-specific-config-files.patch
index ba4d9ba..1ad2608 100644
--- a/debian/patches/debian/Use-Debian-specific-config-files.patch
+++ b/debian/patches/debian/Use-Debian-specific-config-files.patch
@@ -80,10 +80,10 @@ index aa4a89c..8f36bbe 100644
char *s;
diff --git a/src/locale/keymap-util.c b/src/locale/keymap-util.c
-index 6b6b32a..cb63d45 100644
+index c203c7a..f4ee123 100644
--- a/src/locale/keymap-util.c
+++ b/src/locale/keymap-util.c
-@@ -95,6 +95,7 @@ void locale_simplify(char *locale[_VARIABLE_LC_MAX]) {
+@@ -97,6 +97,7 @@ void locale_simplify(char *locale[_VARIABLE_LC_MAX]) {
int locale_read_data(Context *c, sd_bus_message *m) {
struct stat st;
int r;
@@ -91,7 +91,7 @@ index 6b6b32a..cb63d45 100644
/* Do not try to re-read the file within single bus operation. */
if (m) {
-@@ -105,7 +106,11 @@ int locale_read_data(Context *c, sd_bus_message *m) {
+@@ -107,7 +108,11 @@ int locale_read_data(Context *c, sd_bus_message *m) {
c->locale_cache = sd_bus_message_ref(m);
}
@@ -104,7 +104,7 @@ index 6b6b32a..cb63d45 100644
if (r < 0 && errno != ENOENT)
return -errno;
-@@ -120,7 +125,7 @@ int locale_read_data(Context *c, sd_bus_message *m) {
+@@ -122,7 +127,7 @@ int locale_read_data(Context *c, sd_bus_message *m) {
c->locale_mtime = t;
context_free_locale(c);
@@ -113,7 +113,7 @@ index 6b6b32a..cb63d45 100644
"LANG", &c->locale[VARIABLE_LANG],
"LANGUAGE", &c->locale[VARIABLE_LANGUAGE],
"LC_CTYPE", &c->locale[VARIABLE_LC_CTYPE],
-@@ -201,8 +206,6 @@ int vconsole_read_data(Context *c, sd_bus_message *m) {
+@@ -203,8 +208,6 @@ int vconsole_read_data(Context *c, sd_bus_message *m) {
}
int x11_read_data(Context *c, sd_bus_message *m) {
@@ -122,7 +122,7 @@ index 6b6b32a..cb63d45 100644
struct stat st;
usec_t t;
int r;
-@@ -216,7 +219,7 @@ int x11_read_data(Context *c, sd_bus_message *m) {
+@@ -218,7 +221,7 @@ int x11_read_data(Context *c, sd_bus_message *m) {
c->x11_cache = sd_bus_message_ref(m);
}
@@ -131,7 +131,7 @@ index 6b6b32a..cb63d45 100644
if (errno != ENOENT)
return -errno;
-@@ -233,61 +236,14 @@ int x11_read_data(Context *c, sd_bus_message *m) {
+@@ -235,61 +238,14 @@ int x11_read_data(Context *c, sd_bus_message *m) {
c->x11_mtime = t;
context_free_x11(c);
@@ -200,7 +200,7 @@ index 6b6b32a..cb63d45 100644
return 0;
}
-@@ -296,9 +252,18 @@ int locale_write_data(Context *c, char ***settings) {
+@@ -298,9 +254,18 @@ int locale_write_data(Context *c, char ***settings) {
_cleanup_strv_free_ char **l = NULL;
struct stat st;
int r, p;
@@ -219,7 +219,7 @@ index 6b6b32a..cb63d45 100644
for (p = 0; p < _VARIABLE_LC_MAX; p++) {
_cleanup_free_ char *t = NULL;
char **u;
-@@ -321,20 +286,20 @@ int locale_write_data(Context *c, char ***settings) {
+@@ -323,20 +288,20 @@ int locale_write_data(Context *c, char ***settings) {
}
if (strv_isempty(l)) {
@@ -243,7 +243,7 @@ index 6b6b32a..cb63d45 100644
c->locale_mtime = timespec_load(&st.st_mtim);
return 0;
-@@ -402,70 +367,104 @@ int vconsole_write_data(Context *c) {
+@@ -404,70 +369,104 @@ int vconsole_write_data(Context *c) {
}
int x11_write_data(Context *c) {
@@ -392,7 +392,7 @@ index 6b6b32a..cb63d45 100644
return r;
}
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
-index 324d4a4..4d54ac3 100644
+index 398d4f4..d681d58 100644
--- a/src/timedate/timedated.c
+++ b/src/timedate/timedated.c
@@ -215,6 +215,7 @@ static int context_read_data(Context *c) {
diff --git a/debian/patches/polkit-on-async-pk-requests-re-validate-action-details.patch b/debian/patches/polkit-on-async-pk-requests-re-validate-action-details.patch
new file mode 100644
index 0000000..c6ffacf
--- /dev/null
+++ b/debian/patches/polkit-on-async-pk-requests-re-validate-action-details.patch
@@ -0,0 +1,81 @@
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 22 Jan 2020 16:52:10 +0100
+Subject: polkit: on async pk requests, re-validate action/details
+
+When we do an async pk request, let's store which action/details we used
+for the original request, and when we are called for the second time,
+let's compare. If the action/details changed, let's not allow the access
+to go through.
+
+(cherry picked from commit 7f56982289275ce84e20f0554475864953e6aaab)
+(cherry picked from commit 0697d0d972c8d91395eb539a8e87e4aec8b37b75)
+(cherry picked from commit 54791aff01aa93a8b621808d80ab506b54f245c8)
+(cherry picked from commit 70d0f5ea5952a0cedd84c352070613df4ba5fc8f)
+---
+ src/shared/bus-polkit.c | 30 +++++++++++++++++++++++++++---
+ 1 file changed, 27 insertions(+), 3 deletions(-)
+
+diff --git a/src/shared/bus-polkit.c b/src/shared/bus-polkit.c
+index 81193b8..6343dd6 100644
+--- a/src/shared/bus-polkit.c
++++ b/src/shared/bus-polkit.c
+@@ -155,6 +155,9 @@ int bus_test_polkit(
+ #if ENABLE_POLKIT
+
+ typedef struct AsyncPolkitQuery {
++ char *action;
++ char **details;
++
+ sd_bus_message *request, *reply;
+ sd_bus_message_handler_t callback;
+ void *userdata;
+@@ -175,6 +178,9 @@ static void async_polkit_query_free(AsyncPolkitQuery *q) {
+ sd_bus_message_unref(q->request);
+ sd_bus_message_unref(q->reply);
+
++ free(q->action);
++ strv_free(q->details);
++
+ free(q);
+ }
+
+@@ -239,11 +245,17 @@ int bus_verify_polkit_async(
+ 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 */
++ /* This is the second invocation of this function, and there's already a response from
++ * polkit, let's process it */
+ assert(q->reply);
+
++ /* If the operation we want to authenticate changed between the first and the second time,
++ * let's not use this authentication, it might be out of date as the object and context we
++ * operate on might have changed. */
++ if (!streq(q->action, action) ||
++ !strv_equal(q->details, (char**) details))
++ return -ESTALE;
++
+ if (sd_bus_message_is_method_error(q->reply, NULL)) {
+ const sd_bus_error *e;
+
+@@ -339,6 +351,18 @@ int bus_verify_polkit_async(
+ q->callback = callback;
+ q->userdata = userdata;
+
++ q->action = strdup(action);
++ if (!q->action) {
++ async_polkit_query_free(q);
++ return -ENOMEM;
++ }
++
++ q->details = strv_copy((char**) details);
++ if (!q->details) {
++ async_polkit_query_free(q);
++ return -ENOMEM;
++ }
++
+ r = hashmap_put(*registry, call, q);
+ if (r < 0) {
+ async_polkit_query_free(q);
diff --git a/debian/patches/polkit-reuse-some-common-bus-message-appending-code.patch b/debian/patches/polkit-reuse-some-common-bus-message-appending-code.patch
new file mode 100644
index 0000000..98e43ca
--- /dev/null
+++ b/debian/patches/polkit-reuse-some-common-bus-message-appending-code.patch
@@ -0,0 +1,107 @@
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 22 Jan 2020 16:44:43 +0100
+Subject: polkit: reuse some common bus message appending code
+
+(cherry picked from commit 95f82ae9d774f3508ce89dcbdd0714ef7385df59)
+(cherry picked from commit 2589995acdb297a073270b54d8fff54b98fa57e9)
+(cherry picked from commit 81532beddcc3b7946a573e15641742c452c66db7)
+(cherry picked from commit 18b7b7fe307f03928bfea3ef0663048b7be6e4fb)
+---
+ src/shared/bus-polkit.c | 56 ++++++++++++++++++++++++++++---------------------
+ 1 file changed, 32 insertions(+), 24 deletions(-)
+
+diff --git a/src/shared/bus-polkit.c b/src/shared/bus-polkit.c
+index f93aa17..81193b8 100644
+--- a/src/shared/bus-polkit.c
++++ b/src/shared/bus-polkit.c
+@@ -30,6 +30,34 @@ static int check_good_user(sd_bus_message *m, uid_t good_user) {
+ return sender_uid == good_user;
+ }
+
++#if ENABLE_POLKIT
++static int bus_message_append_strv_key_value(
++ sd_bus_message *m,
++ const char **l) {
++
++ const char **k, **v;
++ int r;
++
++ assert(m);
++
++ r = sd_bus_message_open_container(m, 'a', "{ss}");
++ if (r < 0)
++ return r;
++
++ STRV_FOREACH_PAIR(k, v, l) {
++ r = sd_bus_message_append(m, "{ss}", *k, *v);
++ if (r < 0)
++ return r;
++ }
++
++ r = sd_bus_message_close_container(m);
++ if (r < 0)
++ return r;
++
++ return r;
++}
++#endif
++
+ int bus_test_polkit(
+ sd_bus_message *call,
+ int capability,
+@@ -60,7 +88,7 @@ int bus_test_polkit(
+ _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;
++ const char *sender;
+
+ sender = sd_bus_message_get_sender(call);
+ if (!sender)
+@@ -84,17 +112,7 @@ int bus_test_polkit(
+ 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);
++ r = bus_message_append_strv_key_value(request, details);
+ if (r < 0)
+ return r;
+
+@@ -201,7 +219,7 @@ int bus_verify_polkit_async(
+ #if ENABLE_POLKIT
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
+ AsyncPolkitQuery *q;
+- const char *sender, **k, **v;
++ const char *sender;
+ sd_bus_message_handler_t callback;
+ void *userdata;
+ int c;
+@@ -305,17 +323,7 @@ int bus_verify_polkit_async(
+ 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);
++ r = bus_message_append_strv_key_value(pk, details);
+ if (r < 0)
+ return r;
+
diff --git a/debian/patches/polkit-use-structured-initialization.patch b/debian/patches/polkit-use-structured-initialization.patch
new file mode 100644
index 0000000..683fb3b
--- /dev/null
+++ b/debian/patches/polkit-use-structured-initialization.patch
@@ -0,0 +1,36 @@
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 22 Jan 2020 16:53:59 +0100
+Subject: polkit: use structured initialization
+
+(cherry picked from commit f4425c72c7395ec93ae00052916a66e2f60f200b)
+(cherry picked from commit 5926f9f1723fd753a0c524ed96a13538c851395e)
+(cherry picked from commit 4d80c8f158333117dabb0e6f7592059cddb1d6d0)
+(cherry picked from commit 9131bb3d45e6384309eea42affd1aa757ef28cd7)
+---
+ src/shared/bus-polkit.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/src/shared/bus-polkit.c b/src/shared/bus-polkit.c
+index 6343dd6..c42c39a 100644
+--- a/src/shared/bus-polkit.c
++++ b/src/shared/bus-polkit.c
+@@ -343,13 +343,15 @@ int bus_verify_polkit_async(
+ if (r < 0)
+ return r;
+
+- q = new0(AsyncPolkitQuery, 1);
++ q = new(AsyncPolkitQuery, 1);
+ if (!q)
+ return -ENOMEM;
+
+- q->request = sd_bus_message_ref(call);
+- q->callback = callback;
+- q->userdata = userdata;
++ *q = (AsyncPolkitQuery) {
++ .request = sd_bus_message_ref(call),
++ .callback = callback,
++ .userdata = userdata,
++ };
+
+ q->action = strdup(action);
+ if (!q->action) {
diff --git a/debian/patches/polkit-when-authorizing-via-PK-let-s-re-resolve-callback-.patch b/debian/patches/polkit-when-authorizing-via-PK-let-s-re-resolve-callback-.patch
new file mode 100644
index 0000000..2175b78
--- /dev/null
+++ b/debian/patches/polkit-when-authorizing-via-PK-let-s-re-resolve-callback-.patch
@@ -0,0 +1,166 @@
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 22 Jan 2020 17:07:47 +0100
+Subject: polkit: when authorizing via PK let's re-resolve callback/userdata
+ instead of caching it
+
+Previously, when doing an async PK query we'd store the original
+callback/userdata pair and call it again after the PK request is
+complete. This is problematic, since PK queries might be slow and in the
+meantime the userdata might be released and re-acquired. Let's avoid
+this by always traversing through the message handlers so that we always
+re-resolve the callback and userdata pair and thus can be sure it's
+up-to-date and properly valid.
+
+(cherry picked from commit 637486261528e8aa3da9f26a4487dc254f4b7abb)
+(cherry picked from commit e2d4cb9843c50eff76e9104fec6b448c0d7c8814)
+(cherry picked from commit fb21e13e8ecbe25d80c1219b14e6495795df18ef)
+(cherry picked from commit c3141774dfb84b1526c4991bb775457c739eb179)
+---
+ src/shared/bus-polkit.c | 78 ++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 52 insertions(+), 26 deletions(-)
+
+diff --git a/src/shared/bus-polkit.c b/src/shared/bus-polkit.c
+index c42c39a..02c11aa 100644
+--- a/src/shared/bus-polkit.c
++++ b/src/shared/bus-polkit.c
+@@ -159,14 +159,13 @@ typedef struct AsyncPolkitQuery {
+ char **details;
+
+ sd_bus_message *request, *reply;
+- sd_bus_message_handler_t callback;
+- void *userdata;
+ sd_bus_slot *slot;
++
+ Hashmap *registry;
++ sd_event_source *defer_event_source;
+ } AsyncPolkitQuery;
+
+ static void async_polkit_query_free(AsyncPolkitQuery *q) {
+-
+ if (!q)
+ return;
+
+@@ -181,9 +180,24 @@ static void async_polkit_query_free(AsyncPolkitQuery *q) {
+ free(q->action);
+ strv_free(q->details);
+
++ if (q->defer_event_source)
++ (void) sd_event_source_set_enabled(q->defer_event_source, SD_EVENT_OFF);
++ sd_event_source_unref(q->defer_event_source);
+ free(q);
+ }
+
++static int async_polkit_defer(sd_event_source *s, void *userdata) {
++ AsyncPolkitQuery *q = userdata;
++
++ assert(s);
++
++ /* This is called as idle event source after we processed the async polkit reply, hopefully after the
++ * method call we re-enqueued has been properly processed. */
++
++ async_polkit_query_free(q);
++ return 0;
++}
++
+ 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;
+@@ -192,21 +206,46 @@ static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_e
+ assert(reply);
+ assert(q);
+
++ assert(q->slot);
+ q->slot = sd_bus_slot_unref(q->slot);
++
++ assert(!q->reply);
+ q->reply = sd_bus_message_ref(reply);
+
++ /* Now, let's dispatch the original message a second time be re-enqueing. This will then traverse the
++ * whole message processing again, and thus re-validating and re-retrieving the "userdata" field
++ * again.
++ *
++ * We install an idle event loop event to clean-up the PolicyKit request data when we are idle again,
++ * i.e. after the second time the message is processed is complete. */
++
++ assert(!q->defer_event_source);
++ r = sd_event_add_defer(sd_bus_get_event(sd_bus_message_get_bus(reply)), &q->defer_event_source, async_polkit_defer, q);
++ if (r < 0)
++ goto fail;
++
++ r = sd_event_source_set_priority(q->defer_event_source, SD_EVENT_PRIORITY_IDLE);
++ if (r < 0)
++ goto fail;
++
++ r = sd_event_source_set_enabled(q->defer_event_source, SD_EVENT_ONESHOT);
++ if (r < 0)
++ goto fail;
++
+ r = sd_bus_message_rewind(q->request, true);
+- if (r < 0) {
+- r = sd_bus_reply_method_errno(q->request, r, NULL);
+- goto finish;
+- }
++ if (r < 0)
++ goto fail;
++
++ r = sd_bus_enqeue_for_read(sd_bus_message_get_bus(q->request), q->request);
++ if (r < 0)
++ goto fail;
+
+- r = q->callback(q->request, q->userdata, &error_buffer);
+- r = bus_maybe_reply_error(q->request, r, &error_buffer);
++ return 1;
+
+-finish:
++fail:
++ log_debug_errno(r, "Processing asynchronous PolicyKit reply failed, ignoring: %m");
++ (void) sd_bus_reply_method_errno(q->request, r, NULL);
+ async_polkit_query_free(q);
+-
+ return r;
+ }
+
+@@ -225,11 +264,9 @@ int bus_verify_polkit_async(
+ #if ENABLE_POLKIT
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
+ AsyncPolkitQuery *q;
+- const char *sender;
+- sd_bus_message_handler_t callback;
+- void *userdata;
+ int c;
+ #endif
++ const char *sender;
+ int r;
+
+ assert(call);
+@@ -293,20 +330,11 @@ int bus_verify_polkit_async(
+ 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;
+
++#if ENABLE_POLKIT
+ c = sd_bus_message_get_allow_interactive_authorization(call);
+ if (c < 0)
+ return c;
+@@ -349,8 +377,6 @@ int bus_verify_polkit_async(
+
+ *q = (AsyncPolkitQuery) {
+ .request = sd_bus_message_ref(call),
+- .callback = callback,
+- .userdata = userdata,
+ };
+
+ q->action = strdup(action);
diff --git a/debian/patches/resolve-fix-memleak.patch b/debian/patches/resolve-fix-memleak.patch
new file mode 100644
index 0000000..f37f322
--- /dev/null
+++ b/debian/patches/resolve-fix-memleak.patch
@@ -0,0 +1,32 @@
+From: Yu Watanabe <watanabe.yu+github at gmail.com>
+Date: Fri, 12 Jul 2019 14:19:36 +0900
+Subject: resolve: fix memleak
+
+(cherry picked from commit 2400ae29a55aab8659fa778f02d1884b86a95062)
+(cherry picked from commit 7727e6c0ae1769ba7ea9959aa721236c025adbdf)
+(cherry picked from commit 9755ac0744f858cfa952033552ac6f2401e0f2d0)
+---
+ src/resolve/resolved-manager.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
+index b3d35c8..2017b0e 100644
+--- a/src/resolve/resolved-manager.c
++++ b/src/resolve/resolved-manager.c
+@@ -11,6 +11,7 @@
+
+ #include "af-list.h"
+ #include "alloc-util.h"
++#include "bus-util.h"
+ #include "dirent-util.h"
+ #include "dns-domain.h"
+ #include "fd-util.h"
+@@ -689,6 +690,8 @@ Manager *manager_free(Manager *m) {
+ manager_mdns_stop(m);
+ manager_dns_stub_stop(m);
+
++ bus_verify_polkit_async_registry_free(m->polkit_registry);
++
+ sd_bus_flush_close_unref(m->bus);
+
+ sd_event_source_unref(m->sigusr1_event_source);
diff --git a/debian/patches/sd-bus-introduce-API-for-re-enqueuing-incoming-messages.patch b/debian/patches/sd-bus-introduce-API-for-re-enqueuing-incoming-messages.patch
new file mode 100644
index 0000000..a628fdd
--- /dev/null
+++ b/debian/patches/sd-bus-introduce-API-for-re-enqueuing-incoming-messages.patch
@@ -0,0 +1,65 @@
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 22 Jan 2020 17:05:17 +0100
+Subject: sd-bus: introduce API for re-enqueuing incoming messages
+
+When authorizing via PolicyKit we want to process incoming method calls
+twice: once to process and figure out that we need PK authentication,
+and a second time after we aquired PK authentication to actually execute
+the operation. With this new call sd_bus_enqueue_for_read() we have a
+way to put an incoming message back into the read queue for this
+purpose.
+
+This might have other uses too, for example debugging.
+
+(cherry picked from commit 1068447e6954dc6ce52f099ed174c442cb89ed54)
+
+zjs: patch modified to not make the function public
+(cherry picked from commit 83bfc0d8dd026814d23e3fdfa46806394f775526)
+(cherry picked from commit 2e504c92d195d407cec3ba9ed156b195c31a5f3f)
+(cherry picked from commit 351627d4bfa39dd05f28d889967383af2372de6d)
+---
+ src/libsystemd/sd-bus/bus-message.h | 1 +
+ src/libsystemd/sd-bus/sd-bus.c | 24 ++++++++++++++++++++++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h
+index 0115437..7fd3f11 100644
+--- a/src/libsystemd/sd-bus/bus-message.h
++++ b/src/libsystemd/sd-bus/bus-message.h
+@@ -211,3 +211,4 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m);
+
+ void bus_message_set_sender_driver(sd_bus *bus, sd_bus_message *m);
+ void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m);
++int sd_bus_enqeue_for_read(sd_bus *bus, sd_bus_message *m);
+diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
+index 1ff858f..94380af 100644
+--- a/src/libsystemd/sd-bus/sd-bus.c
++++ b/src/libsystemd/sd-bus/sd-bus.c
+@@ -4144,3 +4144,27 @@ _public_ int sd_bus_get_close_on_exit(sd_bus *bus) {
+
+ return bus->close_on_exit;
+ }
++
++int sd_bus_enqeue_for_read(sd_bus *bus, sd_bus_message *m) {
++ int r;
++
++ assert_return(bus, -EINVAL);
++ assert_return(bus = bus_resolve(bus), -ENOPKG);
++ assert_return(m, -EINVAL);
++ assert_return(m->sealed, -EINVAL);
++ assert_return(!bus_pid_changed(bus), -ECHILD);
++
++ if (!BUS_IS_OPEN(bus->state))
++ return -ENOTCONN;
++
++ /* Re-enqeue a message for reading. This is primarily useful for PolicyKit-style authentication,
++ * where we want accept a message, then determine we need to interactively authenticate the user, and
++ * when we have that process the message again. */
++
++ r = bus_rqueue_make_room(bus);
++ if (r < 0)
++ return r;
++
++ bus->rqueue[bus->rqueue_size++] = sd_bus_message_ref(m);
++ return 0;
++}
diff --git a/debian/patches/series b/debian/patches/series
index d1a5bd2..1f3cd3d 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -42,6 +42,8 @@ mount-remove-unused-mount_is_auto-and-mount_is_automount.patch
core-set-fs.file-max-sysctl-to-LONG_MAX-rather-than-ULONG.patch
execute-remove-one-redundant-comparison-check.patch
core-change-ownership-mode-of-the-execution-directories-a.patch
+bus-util-treat-org.freedesktop.DBus.Error.ServiceUnknown-.patch
+resolve-fix-memleak.patch
debian/Use-Debian-specific-config-files.patch
debian/Bring-tmpfiles.d-tmp.conf-in-line-with-Debian-defaul.patch
debian/Make-run-lock-tmpfs-an-API-fs.patch
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 at 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"
diff --git a/debian/udev-udeb.install b/debian/udev-udeb.install
index 0e9ff40..478276b 100644
--- a/debian/udev-udeb.install
+++ b/debian/udev-udeb.install
@@ -5,6 +5,7 @@ lib/udev/ata_id
lib/udev/scsi_id
lib/udev/cdrom_id
lib/udev/rules.d/50-udev-default.rules
+lib/udev/rules.d/60-block.rules
lib/udev/rules.d/60-cdrom_id.rules
lib/udev/rules.d/60-input-id.rules
lib/udev/rules.d/60-persistent-input.rules
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://alioth-lists.debian.net/pipermail/pkg-systemd-maintainers/attachments/20200427/1d762c0f/attachment-0001.sig>
More information about the Pkg-systemd-maintainers
mailing list