2 This file is part of systemd.
4 Copyright 2014 Daniel Mack
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include "bus-kernel.h"
24 #include "bus-policy.h"
25 #include "bus-endpoint.h"
27 int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) {
29 struct kdbus_cmd_update *update;
31 BusEndpointPolicy *po;
36 size = ALIGN8(offsetof(struct kdbus_cmd_update, items));
38 HASHMAP_FOREACH(po, ep->policy_hash, i) {
39 size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1);
40 size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
43 update = alloca0_align(size, 8);
48 HASHMAP_FOREACH(po, ep->policy_hash, i) {
49 n->type = KDBUS_ITEM_NAME;
50 n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1;
51 strcpy(n->str, po->name);
52 n = KDBUS_ITEM_NEXT(n);
54 n->type = KDBUS_ITEM_POLICY_ACCESS;
55 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
57 n->policy_access.type = KDBUS_POLICY_ACCESS_USER;
58 n->policy_access.access = bus_kernel_translate_access(po->access);
59 n->policy_access.id = uid;
61 n = KDBUS_ITEM_NEXT(n);
64 r = ioctl(fd, KDBUS_CMD_ENDPOINT_UPDATE, update);
71 int bus_endpoint_new(BusEndpoint **ep) {
74 *ep = new0(BusEndpoint, 1);
81 int bus_endpoint_add_policy(BusEndpoint *ep, const char *name, BusPolicyAccess access) {
82 _cleanup_free_ BusEndpointPolicy *po = NULL;
83 _cleanup_free_ char *key = NULL;
88 assert(access > _BUS_POLICY_ACCESS_INVALID && access < _BUS_POLICY_ACCESS_MAX);
90 /* check if we already have this name in the policy list. If we do, see if the new access level
91 * is higher than the exising one, and upgrade the entry in that case. Otherwise, do nothing.
94 if (ep->policy_hash) {
95 po = hashmap_get(ep->policy_hash, name);
97 if (po->access < access)
103 ep->policy_hash = hashmap_new(&string_hash_ops);
104 if (!ep->policy_hash)
108 po = new0(BusEndpointPolicy, 1);
119 r = hashmap_put(ep->policy_hash, key, po);
128 void bus_endpoint_free(BusEndpoint *endpoint) {
132 hashmap_free_free_free(endpoint->policy_hash);