Merge "Optional autogen.sh flag --enable-kdbus-transport added allowing to compile...
[platform/upstream/dbus.git] / dbus / kdbus-common.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* kdbus-common.c  kdbus related utils for daemon and libdbus
3  *
4  * Copyright (C) 2013  Samsung Electronics
5  *
6  * Licensed under the Academic Free License version 2.1
7  *
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.
15  *
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.
20  *
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
24  *
25  */
26 #include "kdbus.h"
27 #include "kdbus-common.h"
28 #include <string.h>
29 #include <stddef.h>
30 #include <stdlib.h>
31 #include <errno.h>
32 #include <unistd.h>
33 #include <dbus/dbus-internals.h>
34 #include <dbus/dbus-shared.h>
35
36 static struct kdbus_policy *make_policy_name(const char *name)
37 {
38         struct kdbus_policy *p;
39         __u64 size;
40
41         size = offsetof(struct kdbus_policy, name) + strlen(name) + 1;
42         p = malloc(size);
43         if (!p)
44                 return NULL;
45         memset(p, 0, size);
46         p->size = size;
47         p->type = KDBUS_POLICY_NAME;
48         strcpy(p->name, name);
49
50         return p;
51 }
52
53 static struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id)
54 {
55         struct kdbus_policy *p;
56         __u64 size = sizeof(*p);
57
58         p = malloc(size);
59         if (!p)
60                 return NULL;
61
62         memset(p, 0, size);
63         p->size = size;
64         p->type = KDBUS_POLICY_ACCESS;
65         p->access.type = type;
66         p->access.bits = bits;
67         p->access.id = id;
68
69         return p;
70 }
71
72 static void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size)
73 {
74         struct kdbus_policy *dst = (struct kdbus_policy *) ((char *) cmd_policy + cmd_policy->size);
75
76         if (cmd_policy->size + policy->size > max_size)
77                 return;
78
79         memcpy(dst, policy, policy->size);
80         cmd_policy->size += KDBUS_ALIGN8(policy->size);
81         free(policy);
82 }
83
84 /**
85  * Registers kdbus policy for given connection.
86  *
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.
91  *
92  * Name of the policy equals name on the bus.
93  *
94  * @param name name of the policy = name of the connection
95  * @param connection the connection
96  * @param error place to store errors
97  *
98  * @returns #TRUE on success
99  */
100 dbus_bool_t register_kdbus_policy(const char* name, int fd)
101 {
102         struct kdbus_cmd_policy *cmd_policy;
103         struct kdbus_policy *policy;
104         int size = 0xffff;
105
106         cmd_policy = alloca(size);
107         memset(cmd_policy, 0, size);
108
109         policy = (struct kdbus_policy *) cmd_policy->policies;
110         cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
111
112         policy = make_policy_name(name);
113         append_policy(cmd_policy, policy, size);
114
115         policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, getuid());
116         append_policy(cmd_policy, policy, size);
117
118         policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
119         append_policy(cmd_policy, policy, size);
120
121         policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
122         append_policy(cmd_policy, policy, size);
123
124         if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
125         {
126                 _dbus_verbose ("Error setting policy: %m, %d\n", errno);
127                 return FALSE;
128         }
129
130         _dbus_verbose("Policy %s set correctly\n", name);
131         return TRUE;
132 }
133
134 dbus_bool_t list_kdbus_names(int fd, char ***listp, int *array_len)
135 {
136         struct kdbus_cmd_names* pCmd;
137         __u64 cmd_size;
138         dbus_bool_t ret_val = FALSE;
139         char** list;
140         int list_len = 0;
141         int i = 0;
142         int j;
143
144         cmd_size = sizeof(struct kdbus_cmd_names) + KDBUS_ITEM_SIZE(1);
145         pCmd = malloc(cmd_size);
146         if(pCmd == NULL)
147                 goto out;
148         pCmd->size = cmd_size;
149
150 again:
151         cmd_size = 0;
152         if(ioctl(fd, KDBUS_CMD_NAME_LIST, pCmd))
153         {
154                 if(errno == EINTR)
155                         goto again;
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
158                 else
159                 {
160                         _dbus_verbose("kdbus error asking for name list: err %d (%m)\n",errno);
161                         goto out;
162                 }
163         }
164         if(cmd_size)  //kernel needs more memory
165         {
166                 pCmd = realloc(pCmd, cmd_size);  //prepare memory
167                 if(pCmd == NULL)
168                         return FALSE;
169                 goto again;                                             //and try again
170         }
171         else
172         {
173                 struct kdbus_cmd_name* pCmd_name;
174
175                 for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name))
176                         list_len++;
177
178                 list = malloc(sizeof(char*) * (list_len + 1));
179                 if(list == NULL)
180                         goto out;
181
182                 for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name))
183                 {
184                         list[i] = strdup(pCmd_name->name);
185                         if(list[i] == NULL)
186                         {
187                                 for(j=0; j<i; j++)
188                                         free(list[j]);
189                                 free(list);
190                                 goto out;
191                         }
192                         _dbus_verbose ("Name %d: %s\n", i, list[i]);
193                         ++i;
194                 }
195                 list[i] = NULL;
196         }
197
198         *array_len = list_len;
199         *listp = list;
200         ret_val = TRUE;
201
202 out:
203         if(pCmd)
204                 free(pCmd);
205         return ret_val;
206 }
207
208 /**
209  * kdbus version of dbus_bus_request_name.
210  *
211  * Asks the bus to assign the given name to this connection.
212  *
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.
217  *
218  * @param connection the connection
219  * @param name the name to request
220  * @param flags flags
221  * @param error location to store the error
222  * @returns a result code, -1 if error is set
223  */
224 int request_kdbus_name(int fd, const char *name, const __u64 flags, __u64 id)
225 {
226         struct kdbus_cmd_name *cmd_name;
227
228         __u64 size = sizeof(*cmd_name) + strlen(name) + 1;
229         __u64 flags_kdbus = 0;
230
231         cmd_name = alloca(size);
232
233 //      memset(cmd_name, 0, size);
234         strcpy(cmd_name->name, name);
235         cmd_name->size = size;
236
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;
245
246         cmd_name->flags = flags_kdbus;
247         cmd_name->id = id;
248 //      cmd_name->conn_flags = 0;
249
250         _dbus_verbose("Request name - flags sent: 0x%llx       !!!!!!!!!\n", cmd_name->flags);
251
252         if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
253         {
254                 _dbus_verbose ("error acquiring name '%s': %m, %d\n", name, errno);
255                 if(errno == EEXIST)
256                         return DBUS_REQUEST_NAME_REPLY_EXISTS;
257                 return -errno;
258         }
259
260         _dbus_verbose("Request name - received flag: 0x%llx       !!!!!!!!!\n", cmd_name->flags);
261
262         if(cmd_name->flags & KDBUS_NAME_IN_QUEUE)
263                 return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
264         else
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
268          */
269 }
270
271 int release_kdbus_name(int fd, const char *name, __u64 id)
272 {
273         struct kdbus_cmd_name *cmd_name;
274
275         __u64 size = sizeof(*cmd_name) + strlen(name) + 1;
276
277         cmd_name = alloca(size);
278         cmd_name->id = id;
279         strcpy(cmd_name->name, name);
280         cmd_name->size = size;
281
282         if (ioctl(fd, KDBUS_CMD_NAME_RELEASE, cmd_name))
283         {
284                 if(errno == ESRCH)
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);
289                 return -errno;
290         }
291
292         _dbus_verbose("Name '%s' released\n", name);
293
294         return DBUS_RELEASE_NAME_REPLY_RELEASED;
295 }