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 "alloc-util.h"
23 #include "bus-kernel.h"
24 #include "bus-policy.h"
26 #include "string-table.h"
27 #include "user-util.h"
30 int bus_kernel_translate_access(BusPolicyAccess access
) {
32 assert(access
< _BUS_POLICY_ACCESS_MAX
);
36 case BUS_POLICY_ACCESS_SEE
:
37 return KDBUS_POLICY_SEE
;
39 case BUS_POLICY_ACCESS_TALK
:
40 return KDBUS_POLICY_TALK
;
42 case BUS_POLICY_ACCESS_OWN
:
43 return KDBUS_POLICY_OWN
;
46 assert_not_reached("Unknown policy access");
50 int bus_kernel_translate_policy(const BusNamePolicy
*policy
, struct kdbus_item
*item
) {
56 switch (policy
->type
) {
58 case BUSNAME_POLICY_TYPE_USER
: {
59 const char *user
= policy
->name
;
62 r
= get_user_creds(&user
, &uid
, NULL
, NULL
, NULL
);
66 item
->policy_access
.type
= KDBUS_POLICY_ACCESS_USER
;
67 item
->policy_access
.id
= uid
;
71 case BUSNAME_POLICY_TYPE_GROUP
: {
72 const char *group
= policy
->name
;
75 r
= get_group_creds(&group
, &gid
);
79 item
->policy_access
.type
= KDBUS_POLICY_ACCESS_GROUP
;
80 item
->policy_access
.id
= gid
;
85 assert_not_reached("Unknown policy type");
88 item
->policy_access
.access
= bus_kernel_translate_access(policy
->access
);
93 int bus_kernel_make_starter(
98 BusNamePolicy
*policy
,
99 BusPolicyAccess world_policy
) {
101 struct kdbus_cmd_free cmd_free
= { .size
= sizeof(cmd_free
) };
102 struct kdbus_cmd_hello
*hello
;
103 struct kdbus_item
*n
;
104 size_t policy_cnt
= 0;
112 LIST_FOREACH(policy
, po
, policy
)
115 if (world_policy
>= 0)
118 size
= offsetof(struct kdbus_cmd_hello
, items
) +
119 ALIGN8(offsetof(struct kdbus_item
, str
) + strlen(name
) + 1) +
120 policy_cnt
* ALIGN8(offsetof(struct kdbus_item
, policy_access
) + sizeof(struct kdbus_policy_access
));
122 hello
= alloca0_align(size
, 8);
125 strcpy(n
->str
, name
);
126 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
127 n
->type
= KDBUS_ITEM_NAME
;
128 n
= KDBUS_ITEM_NEXT(n
);
130 LIST_FOREACH(policy
, po
, policy
) {
131 n
->type
= KDBUS_ITEM_POLICY_ACCESS
;
132 n
->size
= offsetof(struct kdbus_item
, policy_access
) + sizeof(struct kdbus_policy_access
);
134 r
= bus_kernel_translate_policy(po
, n
);
138 n
= KDBUS_ITEM_NEXT(n
);
141 if (world_policy
>= 0) {
142 n
->type
= KDBUS_ITEM_POLICY_ACCESS
;
143 n
->size
= offsetof(struct kdbus_item
, policy_access
) + sizeof(struct kdbus_policy_access
);
144 n
->policy_access
.type
= KDBUS_POLICY_ACCESS_WORLD
;
145 n
->policy_access
.access
= bus_kernel_translate_access(world_policy
);
150 (activating
? KDBUS_HELLO_ACTIVATOR
: KDBUS_HELLO_POLICY_HOLDER
) |
151 (accept_fd
? KDBUS_HELLO_ACCEPT_FD
: 0);
152 hello
->pool_size
= KDBUS_POOL_SIZE
;
153 hello
->attach_flags_send
= _KDBUS_ATTACH_ANY
;
154 hello
->attach_flags_recv
= _KDBUS_ATTACH_ANY
;
156 if (ioctl(fd
, KDBUS_CMD_HELLO
, hello
) < 0) {
157 if (errno
== ENOTTY
) /* Major API change */
158 return -ESOCKTNOSUPPORT
;
162 /* not interested in any output values */
163 cmd_free
.offset
= hello
->offset
;
164 (void) ioctl(fd
, KDBUS_CMD_FREE
, &cmd_free
);
166 /* The higher 32bit of the bus_flags fields are considered
167 * 'incompatible flags'. Refuse them all for now. */
168 if (hello
->bus_flags
> 0xFFFFFFFFULL
)
169 return -ESOCKTNOSUPPORT
;
174 static const char* const bus_policy_access_table
[_BUS_POLICY_ACCESS_MAX
] = {
175 [BUS_POLICY_ACCESS_SEE
] = "see",
176 [BUS_POLICY_ACCESS_TALK
] = "talk",
177 [BUS_POLICY_ACCESS_OWN
] = "own",
180 DEFINE_STRING_TABLE_LOOKUP(bus_policy_access
, BusPolicyAccess
);