X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-kernel.c;h=505f335e0722c5b0612aaa24a16e0e3bcb3eaefa;hb=e7d718afdb28b1049d382604e5e7bf1d213a8291;hp=3ca271c70423d3ac9df206c45f5aea1d8739a4a4;hpb=fe3f22d116f6f0cac3bdfa512ac54c0faf8bb7cd;p=elogind.git diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index 3ca271c70..505f335e0 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -1322,19 +1323,19 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) { return fd; } -static int bus_kernel_translate_access(BusNamePolicyAccess access) { +static int bus_kernel_translate_access(BusPolicyAccess access) { assert(access >= 0); - assert(access < _BUSNAME_POLICY_ACCESS_MAX); + assert(access < _BUS_POLICY_ACCESS_MAX); switch (access) { - case BUSNAME_POLICY_ACCESS_SEE: + case BUS_POLICY_ACCESS_SEE: return KDBUS_POLICY_SEE; - case BUSNAME_POLICY_ACCESS_TALK: + case BUS_POLICY_ACCESS_TALK: return KDBUS_POLICY_TALK; - case BUSNAME_POLICY_ACCESS_OWN: + case BUS_POLICY_ACCESS_OWN: return KDBUS_POLICY_OWN; default: @@ -1408,13 +1409,102 @@ int bus_kernel_open_bus_fd(const char *bus, char **path) { return fd; } +int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **ep_path) { + _cleanup_free_ char *path; + struct kdbus_cmd_make *make; + struct kdbus_item *n; + size_t size; + int fd; + + fd = bus_kernel_open_bus_fd(bus_name, &path); + if (fd < 0) + return fd; + + size = ALIGN8(offsetof(struct kdbus_cmd_make, items)); + size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(ep_name) + 1); + + make = alloca0(size); + make->size = size; + make->flags = KDBUS_MAKE_ACCESS_WORLD; + + n = make->items; + + n->type = KDBUS_ITEM_MAKE_NAME; + n->size = offsetof(struct kdbus_item, str) + strlen(ep_name) + 1; + strcpy(n->str, ep_name); + + if (ioctl(fd, KDBUS_CMD_EP_MAKE, make) < 0) { + safe_close(fd); + return -errno; + } + + /* The higher 32bit of the flags field are considered + * 'incompatible flags'. Refuse them all for now. */ + if (make->flags > 0xFFFFFFFFULL) { + safe_close(fd); + return -ENOTSUP; + } + + if (ep_path) { + asprintf(ep_path, "%s/%s", dirname(path), ep_name); + if (!*ep_path) + return -ENOMEM; + } + + return fd; +} + +int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) { + + struct kdbus_cmd_update *update; + struct kdbus_item *n; + BusEndpointPolicy *po; + Iterator i; + size_t size; + int r; + + size = ALIGN8(offsetof(struct kdbus_cmd_update, items)); + + HASHMAP_FOREACH(po, ep->policy_hash, i) { + size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1); + size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access)); + } + + update = alloca0(size); + update->size = size; + + n = update->items; + + HASHMAP_FOREACH(po, ep->policy_hash, i) { + n->type = KDBUS_ITEM_NAME; + n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1; + strcpy(n->str, po->name); + n = KDBUS_ITEM_NEXT(n); + + n->type = KDBUS_ITEM_POLICY_ACCESS; + n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access); + + n->policy_access.type = KDBUS_POLICY_ACCESS_USER; + n->policy_access.access = bus_kernel_translate_access(po->access); + n->policy_access.id = uid; + + n = KDBUS_ITEM_NEXT(n); + } + + r = ioctl(fd, KDBUS_CMD_EP_UPDATE, update); + if (r < 0) + return -errno; + + return 0; +} + int bus_kernel_make_starter( int fd, const char *name, bool activating, bool accept_fd, BusNamePolicy *policy, - BusNamePolicyAccess world_policy) { + BusPolicyAccess world_policy) { struct kdbus_cmd_hello *hello; struct kdbus_item *n; @@ -1535,37 +1625,6 @@ int bus_kernel_create_domain(const char *name, char **s) { return fd; } -int bus_kernel_create_monitor(const char *bus) { - struct kdbus_cmd_hello *hello; - int fd; - - assert(bus); - - fd = bus_kernel_open_bus_fd(bus, NULL); - if (fd < 0) - return fd; - - hello = alloca0(sizeof(struct kdbus_cmd_hello)); - hello->size = sizeof(struct kdbus_cmd_hello); - hello->conn_flags = KDBUS_HELLO_ACTIVATOR; - hello->pool_size = KDBUS_POOL_SIZE; - - if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) { - safe_close(fd); - return -errno; - } - - /* The higher 32bit of both flags fields are considered - * 'incompatible flags'. Refuse them all for now. */ - if (hello->bus_flags > 0xFFFFFFFFULL || - hello->conn_flags > 0xFFFFFFFFULL) { - safe_close(fd); - return -ENOTSUP; - } - - return fd; -} - int bus_kernel_try_close(sd_bus *bus) { assert(bus); assert(bus->is_kernel);