summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-bus/bus-convenience.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd/sd-bus/bus-convenience.c')
-rw-r--r--src/libsystemd/sd-bus/bus-convenience.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c
index 8081a2f9c0..ae0f4fa217 100644
--- a/src/libsystemd/sd-bus/bus-convenience.c
+++ b/src/libsystemd/sd-bus/bus-convenience.c
@@ -476,6 +476,7 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b
_public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) {
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
uid_t our_uid;
+ bool know_caps = false;
int r;
assert_return(call, -EINVAL);
@@ -486,21 +487,21 @@ _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability)
if (!BUS_IS_OPEN(call->bus->state))
return -ENOTCONN;
- /* We only trust the effective capability set if this is
- * kdbus. On classic dbus1 we cannot retrieve the value
- * without races. Since this function is supposed to be useful
- * for authentication decision we hence avoid requesting and
- * using that information. */
- if (call->bus->is_kernel && capability >= 0) {
- r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
+ if (capability >= 0) {
+ r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
if (r < 0)
return r;
+ /* Note that not even on kdbus we might have the caps
+ * field, due to faked identities, or namespace
+ * translation issues. */
r = sd_bus_creds_has_effective_cap(creds, capability);
if (r > 0)
return 1;
+ if (r == 0)
+ know_caps = true;
} else {
- r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID, &creds);
+ r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID, &creds);
if (r < 0)
return r;
}
@@ -508,10 +509,14 @@ _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability)
/* Now, check the UID, but only if the capability check wasn't
* sufficient */
our_uid = getuid();
- if (our_uid != 0 || !call->bus->is_kernel || capability < 0) {
+ if (our_uid != 0 || !know_caps || capability < 0) {
uid_t sender_uid;
- r = sd_bus_creds_get_uid(creds, &sender_uid);
+ /* Try to use the EUID, if we have it. */
+ r = sd_bus_creds_get_euid(creds, &sender_uid);
+ if (r < 0)
+ r = sd_bus_creds_get_uid(creds, &sender_uid);
+
if (r >= 0) {
/* Sender has same UID as us, then let's grant access */
if (sender_uid == our_uid)