]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/bus-endpoint.c
util-lib: split out allocation calls into alloc-util.[ch]
[thirdparty/systemd.git] / src / core / bus-endpoint.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2014 Daniel Mack
5
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.
10
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.
15
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/>.
18 ***/
19
20 #include <stdlib.h>
21
22 #include "alloc-util.h"
23 #include "bus-endpoint.h"
24 #include "bus-kernel.h"
25 #include "bus-policy.h"
26 #include "kdbus.h"
27
28 int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) {
29
30 struct kdbus_cmd *update;
31 struct kdbus_item *n;
32 BusEndpointPolicy *po;
33 Iterator i;
34 size_t size;
35 int r;
36
37 size = ALIGN8(offsetof(struct kdbus_cmd, items));
38
39 HASHMAP_FOREACH(po, ep->policy_hash, i) {
40 size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1);
41 size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
42 }
43
44 update = alloca0_align(size, 8);
45 update->size = size;
46
47 n = update->items;
48
49 HASHMAP_FOREACH(po, ep->policy_hash, i) {
50 n->type = KDBUS_ITEM_NAME;
51 n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1;
52 strcpy(n->str, po->name);
53 n = KDBUS_ITEM_NEXT(n);
54
55 n->type = KDBUS_ITEM_POLICY_ACCESS;
56 n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
57
58 n->policy_access.type = KDBUS_POLICY_ACCESS_USER;
59 n->policy_access.access = bus_kernel_translate_access(po->access);
60 n->policy_access.id = uid;
61
62 n = KDBUS_ITEM_NEXT(n);
63 }
64
65 r = ioctl(fd, KDBUS_CMD_ENDPOINT_UPDATE, update);
66 if (r < 0)
67 return -errno;
68
69 return 0;
70 }
71
72 int bus_endpoint_new(BusEndpoint **ep) {
73 assert(ep);
74
75 *ep = new0(BusEndpoint, 1);
76 if (!*ep)
77 return -ENOMEM;
78
79 return 0;
80 }
81
82 int bus_endpoint_add_policy(BusEndpoint *ep, const char *name, BusPolicyAccess access) {
83 _cleanup_free_ BusEndpointPolicy *po = NULL;
84 _cleanup_free_ char *key = NULL;
85 int r;
86
87 assert(ep);
88 assert(name);
89 assert(access > _BUS_POLICY_ACCESS_INVALID && access < _BUS_POLICY_ACCESS_MAX);
90
91 /* check if we already have this name in the policy list. If we do, see if the new access level
92 * is higher than the exising one, and upgrade the entry in that case. Otherwise, do nothing.
93 */
94
95 if (ep->policy_hash) {
96 po = hashmap_get(ep->policy_hash, name);
97 if (po) {
98 if (po->access < access)
99 po->access = access;
100
101 return 0;
102 }
103 } else {
104 ep->policy_hash = hashmap_new(&string_hash_ops);
105 if (!ep->policy_hash)
106 return -ENOMEM;
107 }
108
109 po = new0(BusEndpointPolicy, 1);
110 if (!po)
111 return -ENOMEM;
112
113 key = strdup(name);
114 if (!key)
115 return -ENOMEM;
116
117 po->name = key;
118 po->access = access;
119
120 r = hashmap_put(ep->policy_hash, key, po);
121 if (r < 0)
122 return r;
123
124 po = NULL;
125 key = NULL;
126 return 0;
127 }
128
129 void bus_endpoint_free(BusEndpoint *endpoint) {
130 if (!endpoint)
131 return;
132
133 hashmap_free_free_free(endpoint->policy_hash);
134 free(endpoint);
135 }