sd-bus: add suppot for renegotiating message credential attach flags
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
/* 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;
|
||||
if (b)
|
||||
bus->creds_mask |= mask;
|
||||
else
|
||||
bus->creds_mask &= ~mask;
|
||||
|
||||
return kdbus_translate_attach_flags(bus->creds_mask, &bus->attach_flags);
|
||||
/* The well knowns we need unconditionally, so that matches can work */
|
||||
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 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user