diff options
author | Daniel Mack <zonque@gmail.com> | 2014-08-18 19:58:42 +0200 |
---|---|---|
committer | Daniel Mack <daniel@zonque.org> | 2014-09-08 11:06:45 +0200 |
commit | e7d718afdb28b1049d382604e5e7bf1d213a8291 (patch) | |
tree | c36560fef6105abc4dbcbc9b5c3c0b754f1752e0 /src/libsystemd | |
parent | bb7dd0b04a6e89674100476eed0bbd05c6a4cbd8 (diff) |
bus: add code to create custom endpoints and set their policy
Custom endpoints are alternative connection points to a bus, allowing
specific policy to be uploaded.
Add two functions to bus-kernel. One to create such endpoints, and another
one for setting a policy for them.
Diffstat (limited to 'src/libsystemd')
-rw-r--r-- | src/libsystemd/sd-bus/bus-kernel.c | 90 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-kernel.h | 4 |
2 files changed, 94 insertions, 0 deletions
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index ca0eddb38d..505f335e07 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -25,6 +25,7 @@ #include <fcntl.h> #include <malloc.h> +#include <libgen.h> #include <sys/mman.h> #include <sys/prctl.h> @@ -1408,6 +1409,95 @@ 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, diff --git a/src/libsystemd/sd-bus/bus-kernel.h b/src/libsystemd/sd-bus/bus-kernel.h index 182f953d47..f1d832a764 100644 --- a/src/libsystemd/sd-bus/bus-kernel.h +++ b/src/libsystemd/sd-bus/bus-kernel.h @@ -24,6 +24,7 @@ #include <stdbool.h> #include "busname.h" +#include "bus-endpoint.h" #include "sd-bus.h" #define KDBUS_ITEM_NEXT(item) \ @@ -69,8 +70,11 @@ int bus_kernel_open_bus_fd(const char *bus, char **path); int bus_kernel_make_starter(int fd, const char *name, bool activating, bool accept_fd, BusNamePolicy *policy, BusPolicyAccess world_policy); int bus_kernel_create_bus(const char *name, bool world, char **s); +int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **path); int bus_kernel_create_domain(const char *name, char **s); +int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep); + int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated); void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated); |