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"
28 #include "dbus-transport-kdbus.h"
34 #include <dbus/dbus-internals.h>
35 #include <dbus/dbus-shared.h>
37 static struct kdbus_item *make_policy_name(const char *name)
42 size = offsetof(struct kdbus_item, policy.name) + strlen(name) + 1;
48 p->type = KDBUS_ITEM_POLICY_NAME;
49 memcpy(p->policy.name, name, strlen(name) + 1);
54 static struct kdbus_item *make_policy_access(__u64 type, __u64 bits, __u64 id)
57 __u64 size = sizeof(*p);
65 p->type = KDBUS_ITEM_POLICY_ACCESS;
66 p->policy.access.type = type;
67 p->policy.access.bits = bits;
68 p->policy.access.id = id;
73 static void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_item *policy, __u64 max_size)
75 struct kdbus_item *dst = (struct kdbus_item *) ((char *) cmd_policy + cmd_policy->size);
77 if (cmd_policy->size + policy->size > max_size)
80 memcpy(dst, policy, policy->size);
81 cmd_policy->size += KDBUS_ALIGN8(policy->size);
86 * Registers kdbus policy for given connection.
88 * Policy sets rights of the name (unique or well known) on the bus. Without policy it is
89 * not possible to send or receive messages. It must be set separately for unique id and
90 * well known name of the connection. It is set after registering on the bus, but before
91 * requesting for name. The policy is valid for the given name, not for the connection.
93 * Name of the policy equals name on the bus.
95 * @param name name of the policy = name of the connection
96 * @param transport - transport
97 * @param owner_uid - uid or euid of the process being owner of the name
99 * @returns #TRUE on success
101 dbus_bool_t register_kdbus_policy(const char* name, DBusTransport *transport, unsigned long int owner_uid)
103 struct kdbus_cmd_policy *cmd_policy;
104 struct kdbus_item *policy;
108 if(!_dbus_transport_get_socket_fd (transport, &fd))
111 cmd_policy = alloca(size);
112 memset(cmd_policy, 0, size);
114 policy = (struct kdbus_item *) cmd_policy->policies;
115 cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
117 policy = make_policy_name(name);
118 append_policy(cmd_policy, policy, size);
120 policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, owner_uid);
121 append_policy(cmd_policy, policy, size);
123 policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
124 append_policy(cmd_policy, policy, size);
126 policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
127 append_policy(cmd_policy, policy, size);
129 if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
131 _dbus_verbose ("Error setting policy: %m, %d\n", errno);
135 _dbus_verbose("Policy %s set correctly\n", name);
141 * Asks the bus to assign the given name to the connection.
143 * Use same flags as original dbus version with one exception below.
144 * Result flag #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER is currently
145 * never returned by kdbus, instead DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
146 * is returned by kdbus.
148 * @param fd - file descriptor of the connection
149 * @param name the name to request
151 * @param id unique id of the connection for which the name is being registered
152 * @returns a DBus result code on success, -errno on error
154 int request_kdbus_name(int fd, const char *name, const __u64 flags, __u64 id)
156 struct kdbus_cmd_name *cmd_name;
158 __u64 size = sizeof(*cmd_name) + strlen(name) + 1;
159 __u64 flags_kdbus = 0;
161 cmd_name = alloca(size);
163 strcpy(cmd_name->name, name);
164 cmd_name->size = size;
166 if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
167 flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
168 if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
169 flags_kdbus |= KDBUS_NAME_QUEUE;
170 if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
171 flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
172 if(flags & KDBUS_NAME_STARTER_NAME)
173 flags_kdbus |= KDBUS_NAME_STARTER_NAME;
175 cmd_name->flags = flags_kdbus;
178 _dbus_verbose("Request name - flags sent: 0x%llx !!!!!!!!!\n", cmd_name->flags);
180 if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
182 _dbus_verbose ("error acquiring name '%s': %m, %d\n", name, errno);
184 return DBUS_REQUEST_NAME_REPLY_EXISTS;
185 if(errno == EALREADY)
186 return DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
190 _dbus_verbose("Request name - received flag: 0x%llx !!!!!!!!!\n", cmd_name->flags);
192 if(cmd_name->flags & KDBUS_NAME_IN_QUEUE)
193 return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
195 return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
200 * Releases well-known name - the connections resign from the name
201 * which can be then assigned to another connection or the connection
202 * is being removed from the queue for that name
204 * @param fd - file descriptor of the connection
205 * @param name the name to request
206 * @param id unique id of the connection for which the name is being released
207 * @returns a DBus result code on success, -errno on error
209 int release_kdbus_name(int fd, const char *name, __u64 id)
211 struct kdbus_cmd_name *cmd_name;
213 __u64 size = sizeof(*cmd_name) + strlen(name) + 1;
215 cmd_name = alloca(size);
217 strcpy(cmd_name->name, name);
218 cmd_name->size = size;
220 if (ioctl(fd, KDBUS_CMD_NAME_RELEASE, cmd_name))
222 if((errno == ESRCH) || (errno == ENXIO))
223 return DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
224 else if (errno == EPERM)
225 return DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
226 _dbus_verbose ("error releasing name '%s' for id:%llu. Error: %m, %d\n", name, (unsigned long long)id, errno);
230 _dbus_verbose("Name '%s' released\n", name);
232 return DBUS_RELEASE_NAME_REPLY_RELEASED;