diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-11-26 02:20:28 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-11-26 02:20:55 +0100 |
commit | b5dae4c7f77f7c87b91e0afb60a31c690dda4a1f (patch) | |
tree | 0bc1ce84ed97884bae8f4c332074c532c28f6470 /src/libsystemd/sd-bus | |
parent | f3c0588651927ebac691130aa861b878fa22e527 (diff) |
sd-bus: add suppot for renegotiating message credential attach flags
Diffstat (limited to 'src/libsystemd/sd-bus')
-rw-r--r-- | src/libsystemd/sd-bus/bus-control.c | 6 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-kernel.c | 37 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-kernel.h | 6 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/busctl.c | 2 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/sd-bus.c | 38 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/test-bus-kernel.c | 9 |
6 files changed, 73 insertions, 25 deletions
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index 0ebaf85d57..9cd5cd5fb6 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -62,7 +62,7 @@ static int bus_request_name_kernel(sd_bus *bus, const char *name, uint64_t flags size = offsetof(struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(l); n = alloca0_align(size, 8); n->size = size; - kdbus_translate_request_name_flags(flags, (uint64_t *) &n->flags); + n->flags = request_name_flags_to_kdbus(flags); n->items[0].size = KDBUS_ITEM_HEADER_SIZE + l; n->items[0].type = KDBUS_ITEM_NAME; @@ -643,7 +643,7 @@ static int bus_get_name_creds_kdbus( } cmd->size = size; - kdbus_translate_attach_flags(mask, (uint64_t*) &cmd->flags); + cmd->flags = attach_flags_to_kdbus(mask); /* If augmentation is on, and the bus doesn't didn't allow us * to get the bits we want, then ask for the PID/TID so that we @@ -927,7 +927,7 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r struct kdbus_info *creator_info; cmd.size = sizeof(cmd); - kdbus_translate_attach_flags(mask, (uint64_t*) &cmd.flags); + cmd.flags = attach_flags_to_kdbus(mask); /* If augmentation is on, and the bus doesn't didn't allow us * to get the bits we want, then ask for the PID/TID so that we diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index e03e4471ce..d0cb7eec1b 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -1313,11 +1313,9 @@ void bus_kernel_flush_memfd(sd_bus *b) { close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped); } -int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) { +uint64_t request_name_flags_to_kdbus(uint64_t flags) { uint64_t f = 0; - assert(kdbus_flags); - if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT) f |= KDBUS_NAME_ALLOW_REPLACEMENT; @@ -1327,15 +1325,12 @@ int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) { if (flags & SD_BUS_NAME_QUEUE) f |= KDBUS_NAME_QUEUE; - *kdbus_flags = f; - return 0; + return f; } -int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) { +uint64_t attach_flags_to_kdbus(uint64_t mask) { uint64_t m = 0; - assert(kdbus_mask); - if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID| SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) m |= KDBUS_ATTACH_CREDS; @@ -1376,8 +1371,7 @@ int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) { if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) m |= KDBUS_ATTACH_AUXGROUPS; - *kdbus_mask = m; - return 0; + return m; } int bus_kernel_create_bus(const char *name, bool world, char **s) { @@ -1713,3 +1707,26 @@ int bus_kernel_drop_one(int fd) { return 0; } + +int bus_kernel_realize_attach_flags(sd_bus *bus) { + struct kdbus_cmd_update *update; + struct kdbus_item *n; + + assert(bus); + assert(bus->is_kernel); + + update = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_update, items) + + offsetof(struct kdbus_item, data64) + sizeof(uint64_t)), 8); + + n = update->items; + n->type = KDBUS_ITEM_ATTACH_FLAGS_RECV; + n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t); + n->data64[0] = bus->attach_flags; + + update->size = offsetof(struct kdbus_cmd_update, items) + n->size; + + if (ioctl(bus->input_fd, KDBUS_CMD_CONN_UPDATE, update) < 0) + return -errno; + + return 0; +} diff --git a/src/libsystemd/sd-bus/bus-kernel.h b/src/libsystemd/sd-bus/bus-kernel.h index c1ee285cd1..8994b35f52 100644 --- a/src/libsystemd/sd-bus/bus-kernel.h +++ b/src/libsystemd/sd-bus/bus-kernel.h @@ -81,9 +81,11 @@ void bus_kernel_flush_memfd(sd_bus *bus); int bus_kernel_parse_unique_name(const char *s, uint64_t *id); -int kdbus_translate_request_name_flags(uint64_t sd_bus_flags, uint64_t *kdbus_flags); -int kdbus_translate_attach_flags(uint64_t sd_bus_flags, uint64_t *kdbus_flags); +uint64_t request_name_flags_to_kdbus(uint64_t sd_bus_flags); +uint64_t attach_flags_to_kdbus(uint64_t sd_bus_flags); int bus_kernel_try_close(sd_bus *bus); int bus_kernel_drop_one(int fd); + +int bus_kernel_realize_attach_flags(sd_bus *bus); diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c index 50291bafc1..e432db406b 100644 --- a/src/libsystemd/sd-bus/busctl.c +++ b/src/libsystemd/sd-bus/busctl.c @@ -1975,7 +1975,7 @@ int main(int argc, char *argv[]) { goto finish; } - r = sd_bus_negotiate_creds(bus, _SD_BUS_CREDS_ALL); + r = sd_bus_negotiate_creds(bus, true, _SD_BUS_CREDS_ALL); if (r < 0) { log_error("Failed to enable credentials: %s", strerror(-r)); goto finish; diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 5aa8eacebb..6b01c0cab5 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -274,24 +274,50 @@ _public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) { } _public_ int sd_bus_negotiate_timestamp(sd_bus *bus, int b) { + uint64_t new_flags; assert_return(bus, -EINVAL); - assert_return(bus->state == BUS_UNSET, -EPERM); + assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); - SET_FLAG(bus->attach_flags, KDBUS_ATTACH_TIMESTAMP, b); + new_flags = bus->attach_flags; + SET_FLAG(new_flags, KDBUS_ATTACH_TIMESTAMP, b); + + if (bus->attach_flags == new_flags) + return 0; + + bus->attach_flags = new_flags; + if (bus->state != BUS_UNSET && bus->is_kernel) + bus_kernel_realize_attach_flags(bus); + return 0; } -_public_ int sd_bus_negotiate_creds(sd_bus *bus, uint64_t mask) { +_public_ int sd_bus_negotiate_creds(sd_bus *bus, int b, uint64_t mask) { + uint64_t new_flags; + assert_return(bus, -EINVAL); assert_return(mask <= _SD_BUS_CREDS_ALL, -EINVAL); - assert_return(bus->state == BUS_UNSET, -EPERM); + assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM); assert_return(!bus_pid_changed(bus), -ECHILD); + if (b) + bus->creds_mask |= mask; + else + bus->creds_mask &= ~mask; + /* The well knowns we need unconditionally, so that matches can work */ - bus->creds_mask = mask | SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME; + bus->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME; + + /* Make sure we don't lose the timestamp flag */ + new_flags = (bus->attach_flags & KDBUS_ATTACH_TIMESTAMP) | attach_flags_to_kdbus(bus->creds_mask); + if (bus->attach_flags == new_flags) + return 0; + + bus->attach_flags = new_flags; + if (bus->state != BUS_UNSET && bus->is_kernel) + bus_kernel_realize_attach_flags(bus); - return kdbus_translate_attach_flags(bus->creds_mask, &bus->attach_flags); + return 0; } _public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) { diff --git a/src/libsystemd/sd-bus/test-bus-kernel.c b/src/libsystemd/sd-bus/test-bus-kernel.c index 9cc0f01c5b..0e6c2ac402 100644 --- a/src/libsystemd/sd-bus/test-bus-kernel.c +++ b/src/libsystemd/sd-bus/test-bus-kernel.c @@ -70,10 +70,10 @@ int main(int argc, char *argv[]) { assert_se(r >= 0); assert_se(sd_bus_negotiate_timestamp(a, 1) >= 0); - assert_se(sd_bus_negotiate_creds(a, _SD_BUS_CREDS_ALL) >= 0); + assert_se(sd_bus_negotiate_creds(a, true, _SD_BUS_CREDS_ALL) >= 0); - assert_se(sd_bus_negotiate_timestamp(b, 1) >= 0); - assert_se(sd_bus_negotiate_creds(b, _SD_BUS_CREDS_ALL) >= 0); + assert_se(sd_bus_negotiate_timestamp(b, 0) >= 0); + assert_se(sd_bus_negotiate_creds(b, true, 0) >= 0); r = sd_bus_start(a); assert_se(r >= 0); @@ -81,6 +81,9 @@ int main(int argc, char *argv[]) { r = sd_bus_start(b); assert_se(r >= 0); + assert_se(sd_bus_negotiate_timestamp(b, 1) >= 0); + assert_se(sd_bus_negotiate_creds(b, true, _SD_BUS_CREDS_ALL) >= 0); + r = sd_bus_get_unique_name(a, &ua); assert_se(r >= 0); printf("unique a: %s\n", ua); |