1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* kdbus-common.c kdbus related utils for daemon and libdbus
4 * Copyright (C) 2013 Samsung Electronics
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version and under the terms of the GNU
12 * Lesser General Public License as published by the
13 * Free Software Foundation; either version 2.1 of the License, or (at
14 * your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "kdbus-common.h"
33 #include <dbus/dbus-internals.h>
34 #include <dbus/dbus-shared.h>
36 static struct kdbus_policy *make_policy_name(const char *name)
38 struct kdbus_policy *p;
41 size = offsetof(struct kdbus_policy, name) + strlen(name) + 1;
47 p->type = KDBUS_POLICY_NAME;
48 strcpy(p->name, name);
53 static struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id)
55 struct kdbus_policy *p;
56 __u64 size = sizeof(*p);
64 p->type = KDBUS_POLICY_ACCESS;
65 p->access.type = type;
66 p->access.bits = bits;
72 static void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size)
74 struct kdbus_policy *dst = (struct kdbus_policy *) ((char *) cmd_policy + cmd_policy->size);
76 if (cmd_policy->size + policy->size > max_size)
79 memcpy(dst, policy, policy->size);
80 cmd_policy->size += KDBUS_ALIGN8(policy->size);
85 * Registers kdbus policy for given connection.
87 * Policy sets rights of the name (unique or well known) on the bus. Without policy it is
88 * not possible to send or receive messages. It must be set separately for unique id and
89 * well known name of the connection. It is set after registering on the bus, but before
90 * requesting for name. The policy is valid for the given name, not for the connection.
92 * Name of the policy equals name on the bus.
94 * @param name name of the policy = name of the connection
95 * @param connection the connection
96 * @param error place to store errors
98 * @returns #TRUE on success
100 dbus_bool_t register_kdbus_policy(const char* name, int fd)
102 struct kdbus_cmd_policy *cmd_policy;
103 struct kdbus_policy *policy;
106 cmd_policy = alloca(size);
107 memset(cmd_policy, 0, size);
109 policy = (struct kdbus_policy *) cmd_policy->policies;
110 cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
112 policy = make_policy_name(name);
113 append_policy(cmd_policy, policy, size);
115 policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, getuid());
116 append_policy(cmd_policy, policy, size);
118 policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
119 append_policy(cmd_policy, policy, size);
121 policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
122 append_policy(cmd_policy, policy, size);
124 if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
126 _dbus_verbose ("Error setting policy: %m, %d\n", errno);
130 _dbus_verbose("Policy %s set correctly\n", name);
134 dbus_bool_t list_kdbus_names(int fd, char ***listp, int *array_len)
136 struct kdbus_cmd_names* pCmd;
138 dbus_bool_t ret_val = FALSE;
144 cmd_size = sizeof(struct kdbus_cmd_names) + KDBUS_ITEM_SIZE(1);
145 pCmd = malloc(cmd_size);
148 pCmd->size = cmd_size;
152 if(ioctl(fd, KDBUS_CMD_NAME_LIST, pCmd))
156 if(errno == ENOBUFS) //buffer to small to put all names into it
157 cmd_size = pCmd->size; //here kernel tells how much memory it needs
160 _dbus_verbose("kdbus error asking for name list: err %d (%m)\n",errno);
164 if(cmd_size) //kernel needs more memory
166 pCmd = realloc(pCmd, cmd_size); //prepare memory
169 goto again; //and try again
173 struct kdbus_cmd_name* pCmd_name;
175 for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name))
178 list = malloc(sizeof(char*) * (list_len + 1));
182 for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name))
184 list[i] = strdup(pCmd_name->name);
192 _dbus_verbose ("Name %d: %s\n", i, list[i]);
198 *array_len = list_len;
209 * kdbus version of dbus_bus_request_name.
211 * Asks the bus to assign the given name to this connection.
213 * Use same flags as original dbus version with one exception below.
214 * Result flag #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER is currently
215 * never returned by kdbus, instead DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
216 * is returned by kdbus.
218 * @param connection the connection
219 * @param name the name to request
221 * @param error location to store the error
222 * @returns a result code, -1 if error is set
224 int request_kdbus_name(int fd, const char *name, const __u64 flags, __u64 id)
226 struct kdbus_cmd_name *cmd_name;
228 __u64 size = sizeof(*cmd_name) + strlen(name) + 1;
229 __u64 flags_kdbus = 0;
231 cmd_name = alloca(size);
233 // memset(cmd_name, 0, size);
234 strcpy(cmd_name->name, name);
235 cmd_name->size = size;
237 if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
238 flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
239 if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
240 flags_kdbus |= KDBUS_NAME_QUEUE;
241 if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
242 flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
243 if(flags & KDBUS_NAME_STARTER)
244 flags_kdbus |= KDBUS_NAME_STARTER;
246 cmd_name->flags = flags_kdbus;
248 // cmd_name->conn_flags = 0;
250 _dbus_verbose("Request name - flags sent: 0x%llx !!!!!!!!!\n", cmd_name->flags);
252 if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
254 _dbus_verbose ("error acquiring name '%s': %m, %d\n", name, errno);
256 return DBUS_REQUEST_NAME_REPLY_EXISTS;
260 _dbus_verbose("Request name - received flag: 0x%llx !!!!!!!!!\n", cmd_name->flags);
262 if(cmd_name->flags & KDBUS_NAME_IN_QUEUE)
263 return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
265 return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
266 /*todo now 1 code is never returned - DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
267 * because kdbus never returns it now
271 int release_kdbus_name(int fd, const char *name, __u64 id)
273 struct kdbus_cmd_name *cmd_name;
275 __u64 size = sizeof(*cmd_name) + strlen(name) + 1;
277 cmd_name = alloca(size);
279 strcpy(cmd_name->name, name);
280 cmd_name->size = size;
282 if (ioctl(fd, KDBUS_CMD_NAME_RELEASE, cmd_name))
285 return DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
286 else if (errno == EPERM)
287 return DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
288 _dbus_verbose ("error releasing name '%s' for id:%llu. Error: %m, %d\n", name, (unsigned long long)id, errno);
292 _dbus_verbose("Name '%s' released\n", name);
294 return DBUS_RELEASE_NAME_REPLY_RELEASED;