diff options
Diffstat (limited to 'src/libsystemd/sd-bus/bus-convenience.c')
-rw-r--r-- | src/libsystemd/sd-bus/bus-convenience.c | 25 |
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) |