s = container_of(c, sd_bus_slot, node_vtable);
u = s->userdata;
if (c->find) {
- bus->current_slot = s;
+ bus->current_slot = sd_bus_slot_ref(s);
+ bus->current_userdata = u;
r = c->find(bus, path, c->interface, u, &u, error);
- bus->current_slot = NULL;
+ bus->current_userdata = NULL;
+ bus->current_slot = sd_bus_slot_unref(s);
if (r < 0)
return r;
LIST_FOREACH(enumerators, c, first) {
char **children = NULL, **k;
+ sd_bus_slot *slot;
if (bus->nodes_modified)
return 0;
- bus->current_slot = container_of(c, sd_bus_slot, node_enumerator);
- r = c->callback(bus, prefix, bus->current_slot->userdata, &children, error);
- bus->current_slot = NULL;
+ slot = container_of(c, sd_bus_slot, node_enumerator);
+
+ bus->current_slot = sd_bus_slot_ref(slot);
+ bus->current_userdata = slot->userdata;
+ r = c->callback(bus, prefix, slot->userdata, &children, error);
+ bus->current_userdata = NULL;
+ bus->current_slot = sd_bus_slot_unref(slot);
if (r < 0)
return r;
LIST_FOREACH(callbacks, c, first) {
_cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
+ sd_bus_slot *slot;
if (bus->nodes_modified)
return 0;
if (r < 0)
return r;
- bus->current_slot = container_of(c, sd_bus_slot, node_callback);
- r = c->callback(bus, m, bus->current_slot->userdata, &error_buffer);
- bus->current_slot = NULL;
+ slot = container_of(c, sd_bus_slot, node_callback);
+
+ bus->current_slot = sd_bus_slot_ref(slot);
+ bus->current_handler = c->callback;
+ bus->current_userdata = slot->userdata;
+ r = c->callback(bus, m, slot->userdata, &error_buffer);
+ bus->current_userdata = NULL;
+ bus->current_handler = NULL;
+ bus->current_slot = sd_bus_slot_unref(slot);
r = bus_maybe_reply_error(m, r, &error_buffer);
if (r != 0)
#define CAPABILITY_SHIFT(x) (((x) >> __builtin_ctzll(_SD_BUS_VTABLE_CAPABILITY_MASK)) & 0xFFFF)
static int check_access(sd_bus *bus, sd_bus_message *m, struct vtable_member *c, sd_bus_error *error) {
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
uint64_t cap;
- uid_t uid;
int r;
assert(bus);
if (c->vtable->flags & SD_BUS_VTABLE_UNPRIVILEGED)
return 0;
- /* If we are not connected to kdbus we cannot retrieve the
- * effective capability set without race. Since we need this
- * for a security decision we cannot use racy data, hence
- * don't request it. */
- if (bus->is_kernel)
- r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
- else
- r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
- if (r < 0)
- return r;
-
/* Check have the caller has the requested capability
* set. Note that the flags value contains the capability
* number plus one, which we need to subtract here. We do this
else
cap --;
- r = sd_bus_creds_has_effective_cap(creds, cap);
+ r = sd_bus_query_sender_privilege(m, cap);
+ if (r < 0)
+ return r;
if (r > 0)
- return 1;
-
- /* Caller has same UID as us, then let's grant access */
- r = sd_bus_creds_get_uid(creds, &uid);
- if (r >= 0) {
- if (uid == getuid())
- return 1;
- }
+ return 0;
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Access to %s.%s() not permitted.", c->interface, c->member);
}
m->enforced_reply_signature = strempty(c->vtable->x.method.result);
if (c->vtable->x.method.handler) {
+ sd_bus_slot *slot;
+
+ slot = container_of(c->parent, sd_bus_slot, node_vtable);
- bus->current_slot = container_of(c->parent, sd_bus_slot, node_vtable);
+ bus->current_slot = sd_bus_slot_ref(slot);
+ bus->current_handler = c->vtable->x.method.handler;
+ bus->current_userdata = u;
r = c->vtable->x.method.handler(bus, m, u, &error);
- bus->current_slot = NULL;
+ bus->current_userdata = NULL;
+ bus->current_handler = NULL;
+ bus->current_slot = sd_bus_slot_unref(slot);
return bus_maybe_reply_error(m, r, &error);
}
if (v->x.property.get) {
- bus->current_slot = slot;
+ bus->current_slot = sd_bus_slot_ref(slot);
+ bus->current_userdata = userdata;
r = v->x.property.get(bus, path, interface, property, reply, userdata, error);
- bus->current_slot = NULL;
+ bus->current_userdata = NULL;
+ bus->current_slot = sd_bus_slot_unref(slot);
if (r < 0)
return r;
if (v->x.property.set) {
- bus->current_slot = slot;
+ bus->current_slot = sd_bus_slot_ref(slot);
+ bus->current_userdata = userdata;
r = v->x.property.set(bus, path, interface, property, value, userdata, error);
- bus->current_slot = NULL;
+ bus->current_userdata = NULL;
+ bus->current_slot = sd_bus_slot_unref(slot);
if (r < 0)
return r;
sd_bus_object_find_t find,
void *userdata) {
- sd_bus_slot *s;
+ sd_bus_slot *s = NULL;
struct node_vtable *i, *existing = NULL;
const sd_bus_vtable *v;
struct node *n;