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/>.
22 #include "bus-kernel.h"
23 #include "bus-policy.h"
25 #include "string-table.h"
26 #include "user-util.h"
29 int bus_kernel_translate_access(BusPolicyAccess access
) {
31 assert(access
< _BUS_POLICY_ACCESS_MAX
);
35 case BUS_POLICY_ACCESS_SEE
:
36 return KDBUS_POLICY_SEE
;
38 case BUS_POLICY_ACCESS_TALK
:
39 return KDBUS_POLICY_TALK
;
41 case BUS_POLICY_ACCESS_OWN
:
42 return KDBUS_POLICY_OWN
;
45 assert_not_reached("Unknown policy access");
49 int bus_kernel_translate_policy(const BusNamePolicy
*policy
, struct kdbus_item
*item
) {
55 switch (policy
->type
) {
57 case BUSNAME_POLICY_TYPE_USER
: {
58 const char *user
= policy
->name
;
61 r
= get_user_creds(&user
, &uid
, NULL
, NULL
, NULL
);
65 item
->policy_access
.type
= KDBUS_POLICY_ACCESS_USER
;
66 item
->policy_access
.id
= uid
;
70 case BUSNAME_POLICY_TYPE_GROUP
: {
71 const char *group
= policy
->name
;
74 r
= get_group_creds(&group
, &gid
);
78 item
->policy_access
.type
= KDBUS_POLICY_ACCESS_GROUP
;
79 item
->policy_access
.id
= gid
;
84 assert_not_reached("Unknown policy type");
87 item
->policy_access
.access
= bus_kernel_translate_access(policy
->access
);
92 int bus_kernel_make_starter(
97 BusNamePolicy
*policy
,
98 BusPolicyAccess world_policy
) {
100 struct kdbus_cmd_free cmd_free
= { .size
= sizeof(cmd_free
) };
101 struct kdbus_cmd_hello
*hello
;
102 struct kdbus_item
*n
;
103 size_t policy_cnt
= 0;
111 LIST_FOREACH(policy
, po
, policy
)
114 if (world_policy
>= 0)
117 size
= offsetof(struct kdbus_cmd_hello
, items
) +
118 ALIGN8(offsetof(struct kdbus_item
, str
) + strlen(name
) + 1) +
119 policy_cnt
* ALIGN8(offsetof(struct kdbus_item
, policy_access
) + sizeof(struct kdbus_policy_access
));
121 hello
= alloca0_align(size
, 8);
124 strcpy(n
->str
, name
);
125 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
126 n
->type
= KDBUS_ITEM_NAME
;
127 n
= KDBUS_ITEM_NEXT(n
);
129 LIST_FOREACH(policy
, po
, policy
) {
130 n
->type
= KDBUS_ITEM_POLICY_ACCESS
;
131 n
->size
= offsetof(struct kdbus_item
, policy_access
) + sizeof(struct kdbus_policy_access
);
133 r
= bus_kernel_translate_policy(po
, n
);
137 n
= KDBUS_ITEM_NEXT(n
);
140 if (world_policy
>= 0) {
141 n
->type
= KDBUS_ITEM_POLICY_ACCESS
;
142 n
->size
= offsetof(struct kdbus_item
, policy_access
) + sizeof(struct kdbus_policy_access
);
143 n
->policy_access
.type
= KDBUS_POLICY_ACCESS_WORLD
;
144 n
->policy_access
.access
= bus_kernel_translate_access(world_policy
);
149 (activating
? KDBUS_HELLO_ACTIVATOR
: KDBUS_HELLO_POLICY_HOLDER
) |
150 (accept_fd
? KDBUS_HELLO_ACCEPT_FD
: 0);
151 hello
->pool_size
= KDBUS_POOL_SIZE
;
152 hello
->attach_flags_send
= _KDBUS_ATTACH_ANY
;
153 hello
->attach_flags_recv
= _KDBUS_ATTACH_ANY
;
155 if (ioctl(fd
, KDBUS_CMD_HELLO
, hello
) < 0) {
156 if (errno
== ENOTTY
) /* Major API change */
157 return -ESOCKTNOSUPPORT
;
161 /* not interested in any output values */
162 cmd_free
.offset
= hello
->offset
;
163 (void) ioctl(fd
, KDBUS_CMD_FREE
, &cmd_free
);
165 /* The higher 32bit of the bus_flags fields are considered
166 * 'incompatible flags'. Refuse them all for now. */
167 if (hello
->bus_flags
> 0xFFFFFFFFULL
)
168 return -ESOCKTNOSUPPORT
;
173 static const char* const bus_policy_access_table
[_BUS_POLICY_ACCESS_MAX
] = {
174 [BUS_POLICY_ACCESS_SEE
] = "see",
175 [BUS_POLICY_ACCESS_TALK
] = "talk",
176 [BUS_POLICY_ACCESS_OWN
] = "own",
179 DEFINE_STRING_TABLE_LOOKUP(bus_policy_access
, BusPolicyAccess
);