break;
case KDBUS_ITEM_AUDIT:
- m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
- m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
- m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
+ if ((uint32_t) d->audit.sessionid != (uint32_t) -1) {
+ m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
+ m->creds.mask |= SD_BUS_CREDS_AUDIT_SESSION_ID & bus->creds_mask;
+ }
+
+ if ((uid_t) d->audit.loginuid != (uid_t) -1) {
+ m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
+ m->creds.mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID & bus->creds_mask;
+ }
break;
case KDBUS_ITEM_CAPS:
break;
case KDBUS_ITEM_DST_NAME:
- if (!service_name_is_valid(d->str))
- return -EBADMSG;
+ if (!service_name_is_valid(d->str)) {
+ r = -EBADMSG;
+ goto fail;
+ }
destination = d->str;
break;
case KDBUS_ITEM_OWNED_NAME:
- if (!service_name_is_valid(d->name.name))
- return -EBADMSG;
-
- r = strv_extend(&m->creds.well_known_names, d->name.name);
- if (r < 0)
+ if (!service_name_is_valid(d->name.name)) {
+ r = -EBADMSG;
goto fail;
+ }
+
+ if (bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
+ r = strv_extend(&m->creds.well_known_names, d->name.name);
+ if (r < 0)
+ goto fail;
+
+ m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
+ }
break;
case KDBUS_ITEM_CONN_DESCRIPTION:
m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
break;
+ case KDBUS_ITEM_AUXGROUPS:
+
+ if (bus->creds_mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
+ size_t i, n;
+ uid_t *u;
+ n = (d->size - offsetof(struct kdbus_item, data64)) / sizeof(uint64_t);
+ u = new(uid_t, n);
+ if (!u) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ for (i = 0; i < n; i++)
+ u[i] = (uid_t) d->data64[i];
+
+ m->creds.supplementary_gids = u;
+ m->creds.n_supplementary_gids = n;
+
+ m->creds.mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
+ }
+
+ break;
+
case KDBUS_ITEM_FDS:
case KDBUS_ITEM_SECLABEL:
break;
}
static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
- struct kdbus_cmd_free cmd;
+ struct kdbus_cmd_free cmd = {};
struct kdbus_item *d;
assert(bus);
assert(k);
- cmd.flags = 0;
cmd.offset = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
KDBUS_ITEM_FOREACH(d, k, items) {
if (errno == EAGAIN)
return 0;
+ if (errno == EOVERFLOW) {
+ log_debug("%s: kdbus reports %" PRIu64 " dropped broadcast messages, ignoring.", strna(bus->description), (uint64_t) recv.dropped_msgs);
+ return 0;
+ }
+
return -errno;
}
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;
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;
if (mask & SD_BUS_CREDS_DESCRIPTION)
m |= KDBUS_ATTACH_CONN_DESCRIPTION;
- *kdbus_mask = m;
- return 0;
+ if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS)
+ m |= KDBUS_ATTACH_AUXGROUPS;
+
+ return m;
}
int bus_kernel_create_bus(const char *name, bool world, char **s) {
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;
+}