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/>.
24 #include "bus-kernel.h"
25 #include "bus-policy.h"
27 int bus_kernel_translate_access(BusPolicyAccess access
) {
29 assert(access
< _BUS_POLICY_ACCESS_MAX
);
33 case BUS_POLICY_ACCESS_SEE
:
34 return KDBUS_POLICY_SEE
;
36 case BUS_POLICY_ACCESS_TALK
:
37 return KDBUS_POLICY_TALK
;
39 case BUS_POLICY_ACCESS_OWN
:
40 return KDBUS_POLICY_OWN
;
43 assert_not_reached("Unknown policy access");
47 int bus_kernel_translate_policy(const BusNamePolicy
*policy
, struct kdbus_item
*item
) {
53 switch (policy
->type
) {
55 case BUSNAME_POLICY_TYPE_USER
: {
56 const char *user
= policy
->name
;
59 r
= get_user_creds(&user
, &uid
, NULL
, NULL
, NULL
);
63 item
->policy_access
.type
= KDBUS_POLICY_ACCESS_USER
;
64 item
->policy_access
.id
= uid
;
68 case BUSNAME_POLICY_TYPE_GROUP
: {
69 const char *group
= policy
->name
;
72 r
= get_group_creds(&group
, &gid
);
76 item
->policy_access
.type
= KDBUS_POLICY_ACCESS_GROUP
;
77 item
->policy_access
.id
= gid
;
82 assert_not_reached("Unknown policy type");
85 item
->policy_access
.access
= bus_kernel_translate_access(policy
->access
);
90 int bus_kernel_make_starter(
95 BusNamePolicy
*policy
,
96 BusPolicyAccess world_policy
) {
98 struct kdbus_cmd_free cmd_free
= { .size
= sizeof(cmd_free
) };
99 struct kdbus_cmd_hello
*hello
;
100 struct kdbus_item
*n
;
101 size_t policy_cnt
= 0;
109 LIST_FOREACH(policy
, po
, policy
)
112 if (world_policy
>= 0)
115 size
= offsetof(struct kdbus_cmd_hello
, items
) +
116 ALIGN8(offsetof(struct kdbus_item
, str
) + strlen(name
) + 1) +
117 policy_cnt
* ALIGN8(offsetof(struct kdbus_item
, policy_access
) + sizeof(struct kdbus_policy_access
));
119 hello
= alloca0_align(size
, 8);
122 strcpy(n
->str
, name
);
123 n
->size
= offsetof(struct kdbus_item
, str
) + strlen(n
->str
) + 1;
124 n
->type
= KDBUS_ITEM_NAME
;
125 n
= KDBUS_ITEM_NEXT(n
);
127 LIST_FOREACH(policy
, po
, policy
) {
128 n
->type
= KDBUS_ITEM_POLICY_ACCESS
;
129 n
->size
= offsetof(struct kdbus_item
, policy_access
) + sizeof(struct kdbus_policy_access
);
131 r
= bus_kernel_translate_policy(po
, n
);
135 n
= KDBUS_ITEM_NEXT(n
);
138 if (world_policy
>= 0) {
139 n
->type
= KDBUS_ITEM_POLICY_ACCESS
;
140 n
->size
= offsetof(struct kdbus_item
, policy_access
) + sizeof(struct kdbus_policy_access
);
141 n
->policy_access
.type
= KDBUS_POLICY_ACCESS_WORLD
;
142 n
->policy_access
.access
= bus_kernel_translate_access(world_policy
);
147 (activating
? KDBUS_HELLO_ACTIVATOR
: KDBUS_HELLO_POLICY_HOLDER
) |
148 (accept_fd
? KDBUS_HELLO_ACCEPT_FD
: 0);
149 hello
->pool_size
= KDBUS_POOL_SIZE
;
150 hello
->attach_flags_send
= _KDBUS_ATTACH_ANY
;
151 hello
->attach_flags_recv
= _KDBUS_ATTACH_ANY
;
153 if (ioctl(fd
, KDBUS_CMD_HELLO
, hello
) < 0) {
154 if (errno
== ENOTTY
) /* Major API change */
155 return -ESOCKTNOSUPPORT
;
159 /* not interested in any output values */
160 cmd_free
.offset
= hello
->offset
;
161 (void) ioctl(fd
, KDBUS_CMD_FREE
, &cmd_free
);
163 /* The higher 32bit of the bus_flags fields are considered
164 * 'incompatible flags'. Refuse them all for now. */
165 if (hello
->bus_flags
> 0xFFFFFFFFULL
)
166 return -ESOCKTNOSUPPORT
;
171 static const char* const bus_policy_access_table
[_BUS_POLICY_ACCESS_MAX
] = {
172 [BUS_POLICY_ACCESS_SEE
] = "see",
173 [BUS_POLICY_ACCESS_TALK
] = "talk",
174 [BUS_POLICY_ACCESS_OWN
] = "own",
177 DEFINE_STRING_TABLE_LOOKUP(bus_policy_access
, BusPolicyAccess
);