[daemon-dev][daemon-fix] starting services by direct message (autostart) and some...
[platform/upstream/dbus.git] / dbus / kdbus-common.c
1 /*
2  * kdbus_common.c
3  *
4  *  Created on: Sep 13, 2013
5  *      Author: r.pajak
6  *
7  *  Kdbus internal util functions used by daemon and libdbus
8  */
9
10 #include "kdbus.h"
11 #include "kdbus-common.h"
12 #include <string.h>
13 #include <stddef.h>
14 #include <stdlib.h>
15 #include <errno.h>
16 #include <unistd.h>
17 #include <dbus/dbus-internals.h>
18 #include <dbus/dbus-shared.h>
19
20 static struct kdbus_policy *make_policy_name(const char *name)
21 {
22         struct kdbus_policy *p;
23         __u64 size;
24
25         size = offsetof(struct kdbus_policy, name) + strlen(name) + 1;
26         p = malloc(size);
27         if (!p)
28                 return NULL;
29         memset(p, 0, size);
30         p->size = size;
31         p->type = KDBUS_POLICY_NAME;
32         strcpy(p->name, name);
33
34         return p;
35 }
36
37 static struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id)
38 {
39         struct kdbus_policy *p;
40         __u64 size = sizeof(*p);
41
42         p = malloc(size);
43         if (!p)
44                 return NULL;
45
46         memset(p, 0, size);
47         p->size = size;
48         p->type = KDBUS_POLICY_ACCESS;
49         p->access.type = type;
50         p->access.bits = bits;
51         p->access.id = id;
52
53         return p;
54 }
55
56 static void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size)
57 {
58         struct kdbus_policy *dst = (struct kdbus_policy *) ((char *) cmd_policy + cmd_policy->size);
59
60         if (cmd_policy->size + policy->size > max_size)
61                 return;
62
63         memcpy(dst, policy, policy->size);
64         cmd_policy->size += KDBUS_ALIGN8(policy->size);
65         free(policy);
66 }
67
68 /**
69  * Registers kdbus policy for given connection.
70  *
71  * Policy sets rights of the name (unique or well known) on the bus. Without policy it is
72  * not possible to send or receive messages. It must be set separately for unique id and
73  * well known name of the connection. It is set after registering on the bus, but before
74  * requesting for name. The policy is valid for the given name, not for the connection.
75  *
76  * Name of the policy equals name on the bus.
77  *
78  * @param name name of the policy = name of the connection
79  * @param connection the connection
80  * @param error place to store errors
81  *
82  * @returns #TRUE on success
83  */
84 dbus_bool_t register_kdbus_policy(const char* name, int fd)
85 {
86         struct kdbus_cmd_policy *cmd_policy;
87         struct kdbus_policy *policy;
88         int size = 0xffff;
89
90         cmd_policy = alloca(size);
91         memset(cmd_policy, 0, size);
92
93         policy = (struct kdbus_policy *) cmd_policy->policies;
94         cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
95
96         policy = make_policy_name(name);
97         append_policy(cmd_policy, policy, size);
98
99         policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, getuid());
100         append_policy(cmd_policy, policy, size);
101
102         policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
103         append_policy(cmd_policy, policy, size);
104
105         policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
106         append_policy(cmd_policy, policy, size);
107
108         if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
109         {
110                 _dbus_verbose ("Error setting policy: %m, %d", errno);
111                 return FALSE;
112         }
113
114         _dbus_verbose("Policy %s set correctly\n", name);
115         return TRUE;
116 }
117
118 dbus_bool_t list_kdbus_names(int fd, char ***listp, int *array_len)
119 {
120         struct kdbus_cmd_names* pCmd;
121         __u64 cmd_size;
122         dbus_bool_t ret_val = FALSE;
123         char** list;
124         int list_len = 0;
125         int i = 0;
126         int j;
127
128         cmd_size = sizeof(struct kdbus_cmd_names) + KDBUS_ITEM_SIZE(1);
129         pCmd = malloc(cmd_size);
130         if(pCmd == NULL)
131                 goto out;
132         pCmd->size = cmd_size;
133
134 again:
135         cmd_size = 0;
136         if(ioctl(fd, KDBUS_CMD_NAME_LIST, pCmd))
137         {
138                 if(errno == EINTR)
139                         goto again;
140                 if(errno == ENOBUFS)                    //buffer to small to put all names into it
141                         cmd_size = pCmd->size;          //here kernel tells how much memory it needs
142                 else
143                 {
144                         _dbus_verbose("kdbus error asking for name list: err %d (%m)\n",errno);
145                         goto out;
146                 }
147         }
148         if(cmd_size)  //kernel needs more memory
149         {
150                 pCmd = realloc(pCmd, cmd_size);  //prepare memory
151                 if(pCmd == NULL)
152                         return FALSE;
153                 goto again;                                             //and try again
154         }
155         else
156         {
157                 struct kdbus_cmd_name* pCmd_name;
158
159                 for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name))
160                         list_len++;
161
162                 list = malloc(sizeof(char*) * (list_len + 1));
163                 if(list == NULL)
164                         goto out;
165
166                 for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name))
167                 {
168                         list[i] = strdup(pCmd_name->name);
169                         if(list[i] == NULL)
170                         {
171                                 for(j=0; j<i; j++)
172                                         free(list[j]);
173                                 free(list);
174                                 goto out;
175                         }
176                         _dbus_verbose ("Name %d: %s\n", i, list[i]);
177                         ++i;
178                 }
179                 list[i] = NULL;
180         }
181
182         *array_len = list_len;
183         *listp = list;
184         ret_val = TRUE;
185
186 out:
187         if(pCmd)
188                 free(pCmd);
189         return ret_val;
190 }
191
192 /**
193  * kdbus version of dbus_bus_request_name.
194  *
195  * Asks the bus to assign the given name to this connection.
196  *
197  * Use same flags as original dbus version with one exception below.
198  * Result flag #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER is currently
199  * never returned by kdbus, instead DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
200  * is returned by kdbus.
201  *
202  * @param connection the connection
203  * @param name the name to request
204  * @param flags flags
205  * @param error location to store the error
206  * @returns a result code, -1 if error is set
207  */
208 int request_kdbus_name(int fd, const char *name, const __u64 flags, __u64 id)
209 {
210         struct kdbus_cmd_name *cmd_name;
211
212         __u64 size = sizeof(*cmd_name) + strlen(name) + 1;
213         __u64 flags_kdbus = 0;
214
215         cmd_name = alloca(size);
216
217 //      memset(cmd_name, 0, size);
218         strcpy(cmd_name->name, name);
219         cmd_name->size = size;
220
221         if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
222                 flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
223         if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
224                 flags_kdbus |= KDBUS_NAME_QUEUE;
225         if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
226                 flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
227         if(flags & KDBUS_NAME_STARTER)
228             flags_kdbus |= KDBUS_NAME_STARTER;
229
230         cmd_name->flags = flags_kdbus;
231         cmd_name->id = id;
232 //      cmd_name->conn_flags = 0;
233
234         _dbus_verbose("Request name - flags sent: 0x%llx       !!!!!!!!!\n", cmd_name->flags);
235
236         if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
237         {
238                 _dbus_verbose ("error acquiring name '%s': %m, %d\n", name, errno);
239                 if(errno == EEXIST)
240                         return DBUS_REQUEST_NAME_REPLY_EXISTS;
241                 return -errno;
242         }
243
244         _dbus_verbose("Request name - received flag: 0x%llx       !!!!!!!!!\n", cmd_name->flags);
245
246         if(cmd_name->flags & KDBUS_NAME_IN_QUEUE)
247                 return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
248         else
249                 return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
250         /*todo now 1 code is never returned -  DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
251          * because kdbus never returns it now
252          */
253 }
254
255 int release_kdbus_name(int fd, const char *name, __u64 id)
256 {
257         struct kdbus_cmd_name *cmd_name;
258
259         __u64 size = sizeof(*cmd_name) + strlen(name) + 1;
260
261         cmd_name = alloca(size);
262         cmd_name->id = id;
263         strcpy(cmd_name->name, name);
264         cmd_name->size = size;
265
266         if (ioctl(fd, KDBUS_CMD_NAME_RELEASE, cmd_name))
267         {
268                 if(errno == ESRCH)
269                         return DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
270                 else if (errno == EPERM)
271                         return DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
272                 _dbus_verbose ("error releasing name '%s' for id:%llu. Error: %m, %d\n", name, (unsigned long long)id, errno);
273                 return -errno;
274         }
275
276         _dbus_verbose("Name '%s' released\n", name);
277
278         return DBUS_RELEASE_NAME_REPLY_RELEASED;
279 }