diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-11-24 21:41:40 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-11-25 14:28:34 +0100 |
commit | 705a415f684f8e9ee19983e5859de00bbb1477cb (patch) | |
tree | 5cbabb53de92d7ee21ada427c24a88d18073c9dc /src/libsystemd/sd-bus/bus-convenience.c | |
parent | 1d58a1fe13cd725110be595c40cdc973d7e57d9e (diff) |
sd-bus: update to current kernel version, by splitting off the extended KDBUS_ITEM_PIDS structure from KDBUS_ITEM_CREDS
Also:
- adds support for euid, suid, fsuid, egid, sgid, fsgid fields.
- makes augmentation of creds with data from /proc explicitly
controllable to give apps better control over this, given that this is
racy.
- enables augmentation for kdbus connections (previously we only did it
for dbus1). This is useful since with recent kdbus versions it is
possible for clients to control the metadata they want to send.
- changes sd_bus_query_sender_privilege() to take the euid of the client
into consideration, if known
- when we don't have permissions to read augmentation data from /proc,
don't fail, just don't add the data in
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) |