[lib-fix] moved dbus_connection_get_unix_user from daemon to library
[platform/upstream/dbus.git] / bus / kdbus-d.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* kdbus-d.c  kdbus related daemon functions
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 <dbus/dbus-connection-internal.h>
27 #include "kdbus-d.h"
28 #include <dbus/kdbus.h>
29 #include <dbus/dbus-bus.h>
30 #include "dispatch.h"
31 #include <dbus/dbus-transport.h>
32 #include <dbus/dbus-transport-kdbus.h>
33 #include "connection.h"
34 #include "activation.h"
35 #include "services.h"
36 #include <dbus/dbus-connection.h>
37
38 #include <utils.h>
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <fcntl.h>
42 #include <unistd.h>
43 #include <errno.h>
44
45 /*
46  * Converts string with unique name into __u64 id number. If the name is not unique, sets error.
47  */
48 __u64 sender_name_to_id(const char* name, DBusError* error)
49 {
50         __u64 sender_id = 0;
51
52         if(!strncmp(name, ":1.", 3)) /*if name is unique name it must be converted to unique id*/
53                 sender_id = strtoull(&name[3], NULL, 10);
54         else
55                 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Could not convert sender of the message into kdbus unique id");
56
57         return sender_id;
58 }
59
60 /**
61  * Seeks key in rule string, and duplicates value of the key into pValue.
62  * Because of the duplication, pValue must be freed after use.
63  *
64  * @param rule rule to look through
65  * @param key key to look for
66  * @param pValue pointer to value of the key found
67  * @return length of the value string, 0 means not found
68  */
69 static int parse_match_key(const char *rule, const char* key, char** pValue)
70 {
71   const char* pBegin;
72   const char* pValueEnd;
73   int value_length = 0;
74
75   pBegin = strstr(rule, key);
76   if(pBegin)
77   {
78     pBegin += strlen(key);
79     pValueEnd = strchr(pBegin, '\'');
80     if(pValueEnd)
81     {
82       value_length = pValueEnd - pBegin;
83       *pValue = strndup(pBegin, value_length);
84       if(*pValue)
85         _dbus_verbose ("found for key: %s value:'%s'\n", key, *pValue);
86     }
87   }
88   return value_length;
89 }
90
91 /**
92  * Adds a match rule to match broadcast messages going through the message bus.
93  * Do no affect messages addressed directly.
94  *
95  * The "rule" argument is the string form of a match rule.
96  *
97  * Only part of the dbus's matching capabilities is implemented in kdbus now, because of different mechanism.
98  * Current mapping:
99  * interface match key mapped to bloom
100  * sender match key mapped to src_name
101  *
102  * @param transport transport
103  * @param id id of connection for which the rule is to be added
104  * @param rule textual form of match rule
105   */
106 dbus_bool_t add_match_kdbus (DBusTransport* transport, __u64 id, const char *rule)
107 {
108   struct kdbus_cmd_match* pCmd_match;
109   struct kdbus_item *pItem;
110   __u64 src_id = KDBUS_MATCH_SRC_ID_ANY;
111   uint64_t size;
112   int name_size;
113   char* pName = NULL;
114   char* pInterface = NULL;
115   dbus_bool_t ret_value = FALSE;
116   int fd;
117   __u64 bloom_size;
118
119   if(!_dbus_transport_get_socket_fd(transport, &fd))
120     return FALSE;
121
122   bloom_size = dbus_transport_get_bloom_size(transport);
123
124   /*parsing rule and calculating size of command*/
125   size = sizeof(struct kdbus_cmd_match);
126   if(parse_match_key(rule, "interface='", &pInterface))       /*actual size is not important for interface because bloom size is defined by bus*/
127     size += KDBUS_ITEM_HEADER_SIZE + bloom_size;
128   name_size = parse_match_key(rule, "sender='", &pName);
129   if(name_size)
130   {
131     if(!strncmp(pName, ":1.", 3)) /*if name is unique name it must be converted to unique id*/
132     {
133       src_id = strtoull(&pName[3], NULL, 10);
134       free(pName);
135       pName = NULL;
136     }
137     else
138       size += KDBUS_ITEM_SIZE(name_size + 1);  //well known name
139   }
140
141   pCmd_match = alloca(size);
142   if(pCmd_match == NULL)
143     goto out;
144
145   pCmd_match->id = id;
146   pCmd_match->cookie = id;
147   pCmd_match->size = size;
148   pCmd_match->src_id = src_id;
149
150   pItem = pCmd_match->items;
151   if(pName)
152   {
153     pItem->type = KDBUS_MATCH_SRC_NAME;
154     pItem->size = KDBUS_ITEM_HEADER_SIZE + name_size + 1;
155     memcpy(pItem->str, pName, strlen(pName) + 1);
156     pItem = KDBUS_PART_NEXT(pItem);
157   }
158   if(pInterface)
159   {
160     pItem->type = KDBUS_MATCH_BLOOM;
161     pItem->size = KDBUS_ITEM_HEADER_SIZE + bloom_size;
162     strncpy(pItem->data, pInterface, bloom_size);
163   }
164
165   if(ioctl(fd, KDBUS_CMD_MATCH_ADD, pCmd_match))
166     _dbus_verbose("Failed adding match bus rule %s,\nerror: %d, %m\n", rule, errno);
167   else
168   {
169     _dbus_verbose("Added match bus rule %s for id:%llu\n", rule, (unsigned long long)id);
170     ret_value = TRUE;
171   }
172
173 out:
174   if(pName)
175     free(pName);
176   if(pInterface)
177     free(pInterface);
178   return ret_value;
179 }
180
181 /**
182  * Opposing to dbus, in kdbus removes all match rules with given
183  * cookie, which in this implementation is equal to uniqe id.
184  *
185  * @param transport transport
186  * @param id connection id for which rules are to be removed
187  */
188 dbus_bool_t remove_match_kdbus (DBusTransport* transport, __u64 id)
189 {
190   struct kdbus_cmd_match __attribute__ ((__aligned__(8))) cmd;
191   int fd;
192
193   if(!_dbus_transport_get_socket_fd(transport, &fd))
194     return FALSE;
195
196   cmd.cookie = id;
197   cmd.id = id;
198   cmd.size = sizeof(struct kdbus_cmd_match);
199
200   if(ioctl(fd, KDBUS_CMD_MATCH_REMOVE, &cmd))
201   {
202     _dbus_verbose("Failed removing match rule for id: %llu; error: %d, %m\n", (unsigned long long)id, errno);
203     return FALSE;
204   }
205   else
206   {
207     _dbus_verbose("Match rule removed correctly.\n");
208     return TRUE;
209   }
210 }
211
212 /*
213  * Creates kdbus bus of given type.
214  */
215 char* make_kdbus_bus(DBusBusType type, const char* address, DBusError *error)
216 {
217   // TODO Function alloca() used. In upstream there was a patch proposing to
218   // replace alloca() with malloc() to assure memory alignment. If there will be
219   // suggestion to use malloc instead of alloca this function has to be modified
220   struct kdbus_cmd_make *bus_make;
221   struct kdbus_item *item;
222   __u64 name_size, bus_make_size;
223   int fdc, ret;
224   char *addr_value = NULL;
225   char *bus = NULL;
226   char *name = NULL;
227
228   if(type == DBUS_BUS_SYSTEM)
229     name_size = snprintf(name, 0, "%u-kdbus-%s", getuid(), "system") + 1;
230   else if(type == DBUS_BUS_SESSION)
231     name_size = snprintf(name, 0, "%u-kdbus", getuid()) + 1;
232   else
233     name_size = snprintf(name, 0, "%u-kdbus-%u", getuid(), getpid()) + 1;
234
235   name = alloca(name_size);
236   if (!name)
237     {
238       return NULL;
239     }
240
241   bus_make_size = sizeof(struct kdbus_cmd_make) + KDBUS_ITEM_SIZE(name_size) + KDBUS_ITEM_SIZE(sizeof(__u64));
242   bus_make = alloca(bus_make_size);
243   if (!bus_make)
244     {
245       return NULL;
246     }
247
248   bus_make->size = bus_make_size;
249 #ifdef POLICY_TO_KDBUS
250   bus_make->flags = KDBUS_MAKE_ACCESS_WORLD;
251 #else
252   bus_make->flags = KDBUS_MAKE_ACCESS_WORLD | KDBUS_MAKE_POLICY_OPEN;
253 #endif
254   item = bus_make->items;
255
256   item->type = KDBUS_ITEM_MAKE_NAME;
257   item->size = KDBUS_ITEM_HEADER_SIZE + name_size;
258   if(type == DBUS_BUS_SYSTEM)
259     sprintf(name, "%u-kdbus-%s", getuid(), "system");
260   else if(type == DBUS_BUS_SESSION)
261     sprintf(name, "%u-kdbus", getuid());
262   else
263     sprintf(name, "%u-kdbus-%u", getuid(), getpid());
264   memcpy((bus_make->items)->str, name, name_size);
265
266   item = KDBUS_PART_NEXT(item);
267   item->type = KDBUS_ITEM_BLOOM_SIZE;
268   item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(__u64);
269   item->data64[0] = 64;
270
271 #ifdef KDBUS_FOR_SBB
272   addr_value = strchr(address, ':') + 1;
273   if(*addr_value)
274     {
275       if(!strcmp(addr_value, "sbb"))
276         bus_make->flags |= KDBUS_MAKE_SBB_OFFSET;
277       else
278         {
279           dbus_set_error_const(error, DBUS_ERROR_BAD_ADDRESS, "Invalid address parameter.");
280           return NULL;
281         }
282     }
283 #endif
284
285   _dbus_verbose("Opening /dev/kdbus/control\n");
286   fdc = open("/dev/kdbus/control", O_RDWR|O_CLOEXEC);
287   if (fdc < 0)
288     {
289       _dbus_verbose("--- error %d (%m)\n", fdc);
290       dbus_set_error(error, DBUS_ERROR_FAILED, "Opening /dev/kdbus/control failed: %d (%m)", fdc);
291       return NULL;
292     }
293
294   _dbus_verbose("Creating bus '%s'\n", (bus_make->items[0]).str);
295   ret = ioctl(fdc, KDBUS_CMD_BUS_MAKE, bus_make);
296   if (ret)
297     {
298       _dbus_verbose("--- error %d (%m)\n", errno);
299       dbus_set_error(error, DBUS_ERROR_FAILED, "Creating bus '%s' failed: %d (%m)",
300           (bus_make->items[0]).str, errno);
301       return NULL;
302     }
303
304   if (asprintf(&bus, "kdbus:path=/dev/kdbus/%s/bus", (bus_make->items[0]).str) < 0)
305     {
306       BUS_SET_OOM (error);
307       return NULL;
308     }
309
310   _dbus_verbose("Return value '%s'\n", bus);
311   return bus;
312 }
313
314 /*
315  * Minimal server init needed by context to go further.
316  */
317 DBusServer* empty_server_init(char* address)
318 {
319         return dbus_server_init_mini(address);
320 }
321
322 static dbus_bool_t add_matches_for_kdbus_broadcasts(DBusConnection* connection)
323 {
324   struct kdbus_cmd_match* pCmd_match;
325   struct kdbus_item *pItem;
326   uint64_t size;
327   int fd;
328   DBusTransport *transport;
329
330   transport = dbus_connection_get_transport(connection);
331
332   if(!_dbus_transport_get_socket_fd(transport, &fd))
333     {
334       errno = EPERM;
335       return FALSE;
336     }
337
338   size = sizeof(struct kdbus_cmd_match);
339   size += KDBUS_ITEM_SIZE(1)*3 + KDBUS_ITEM_SIZE(sizeof(__u64))*2;  /*3 name related items plus 2 id related items*/
340
341   pCmd_match = alloca(size);
342   if(pCmd_match == NULL)
343     {
344       errno = ENOMEM;
345       return FALSE;
346     }
347
348   pCmd_match->id = 0;
349   pCmd_match->cookie = 1;
350   pCmd_match->size = size;
351   pCmd_match->src_id = 0;
352
353   pItem = pCmd_match->items;
354   pItem->type = KDBUS_MATCH_NAME_CHANGE;
355   pItem->size = KDBUS_ITEM_HEADER_SIZE + 1;
356   pItem = KDBUS_PART_NEXT(pItem);
357   pItem->type = KDBUS_MATCH_NAME_ADD;
358   pItem->size = KDBUS_ITEM_HEADER_SIZE + 1;
359   pItem = KDBUS_PART_NEXT(pItem);
360   pItem->type = KDBUS_MATCH_NAME_REMOVE;
361   pItem->size = KDBUS_ITEM_HEADER_SIZE + 1;
362   pItem = KDBUS_PART_NEXT(pItem);
363   pItem->type = KDBUS_MATCH_ID_ADD;
364   pItem->size = KDBUS_ITEM_HEADER_SIZE + sizeof(__u64);
365   pItem->id = KDBUS_MATCH_SRC_ID_ANY;
366   pItem = KDBUS_PART_NEXT(pItem);
367   pItem->type = KDBUS_MATCH_ID_REMOVE;
368   pItem->size = KDBUS_ITEM_HEADER_SIZE + sizeof(__u64);
369   pItem->id = KDBUS_MATCH_SRC_ID_ANY;
370
371   if(ioctl(fd, KDBUS_CMD_MATCH_ADD, pCmd_match))
372     {
373       _dbus_verbose("Failed adding match rule for daemon, error: %d, %m\n", errno);
374       return FALSE;
375     }
376
377   _dbus_verbose("Added match rule for daemon correctly.\n");
378   return TRUE;
379 }
380
381 /*
382  * Connects daemon to bus created by him and adds matches for "system" broadcasts.
383  * Do not requests org.freedesktop.DBus name, because it's to early
384  * (some structures of BusContext are not ready yet).
385  */
386 DBusConnection* daemon_as_client(DBusBusType type, char* address, DBusError *error)
387 {
388   DBusConnection* connection;
389
390   dbus_bus_set_bus_connection_address(type, address);
391
392   connection = dbus_bus_get_private(type, error);  /*todo possibly could be optimised by using lower functions*/
393   if(connection == NULL)
394     return NULL;
395
396   if(!add_matches_for_kdbus_broadcasts(connection))
397     {
398       dbus_set_error (error, _dbus_error_from_errno (errno), "Could not add match for daemon, %s", _dbus_strerror_from_errno ());
399       goto failed;
400     }
401
402   if(dbus_error_is_set(error))
403     {
404       failed:
405       _dbus_connection_close_possibly_shared (connection);
406       dbus_connection_unref (connection);
407       connection = NULL;
408     }
409   else
410     _dbus_verbose ("Daemon connected as kdbus client.\n");
411
412   return connection;
413 }
414
415 /*
416  * Asks bus for org.freedesktop.DBus well-known name.
417  */
418 dbus_bool_t register_daemon_name(DBusConnection* connection)
419 {
420     DBusString daemon_name;
421     dbus_bool_t retval = FALSE;
422     BusTransaction *transaction;
423
424     _dbus_string_init_const(&daemon_name, DBUS_SERVICE_DBUS);
425 #ifdef POLICY_TO_KDBUS
426     if(!register_kdbus_policy(DBUS_SERVICE_DBUS, dbus_connection_get_transport(connection), geteuid()))
427       return FALSE;
428 #endif
429
430     if(kdbus_request_name(connection, &daemon_name, 0, 0) != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
431        return FALSE;
432
433     transaction = bus_transaction_new (bus_connection_get_context(connection));
434     if (transaction == NULL)
435     {
436         kdbus_release_name(connection, &daemon_name, 0);
437         goto out;
438     }
439
440     if(!bus_registry_ensure (bus_connection_get_registry (connection), &daemon_name, connection, 0, transaction, NULL))
441     {
442         kdbus_release_name(connection, &daemon_name, 0);
443         goto out;
444     }
445
446     retval = TRUE;
447
448 out:
449   if(retval)
450     bus_transaction_execute_and_free(transaction);
451   else
452     bus_transaction_cancel_and_free(transaction);
453
454   return retval;
455 }
456
457 dbus_uint32_t kdbus_request_name(DBusConnection* connection, const DBusString *service_name, dbus_uint32_t flags, __u64 sender_id)
458 {
459         int fd;
460
461         _dbus_transport_get_socket_fd(dbus_connection_get_transport(connection), &fd);
462
463         return request_kdbus_name(fd, _dbus_string_get_const_data(service_name), flags, sender_id);
464 }
465
466 dbus_uint32_t kdbus_release_name(DBusConnection* connection, const DBusString *service_name, __u64 sender_id)
467 {
468         int fd;
469
470         _dbus_transport_get_socket_fd(dbus_connection_get_transport(connection), &fd);
471
472         return release_kdbus_name(fd, _dbus_string_get_const_data(service_name), sender_id);
473 }
474
475 /*
476  * Asks kdbus for well-known names registered on the bus
477  */
478 dbus_bool_t kdbus_list_services (DBusConnection* connection, char ***listp, int *array_len)
479 {
480         int fd;
481         struct kdbus_cmd_name_list __attribute__ ((__aligned__(8))) cmd;
482         struct kdbus_name_list *name_list;
483         struct kdbus_cmd_name *name;
484         DBusTransport *transport = dbus_connection_get_transport(connection);
485         dbus_bool_t ret_val = FALSE;
486         char** list;
487         int list_len = 0;
488         int i = 0;
489         int j;
490
491         if(!_dbus_transport_get_socket_fd(transport, &fd))
492           return FALSE;
493
494   cmd.flags = KDBUS_NAME_LIST_NAMES | KDBUS_NAME_LIST_UNIQUE;
495
496 again:
497         if(ioctl(fd, KDBUS_CMD_NAME_LIST, &cmd))
498         {
499                 if(errno == EINTR)
500                         goto again;
501                 else
502                 {
503                         _dbus_verbose("kdbus error asking for name list: err %d (%m)\n",errno);
504                         return FALSE;
505                 }
506         }
507
508         name_list = (struct kdbus_name_list *)((char*)dbus_transport_get_pool_pointer(transport) + cmd.offset);
509
510   for (name = name_list->names; (uint8_t *)(name) < (uint8_t *)(name_list) + name_list->size; name = KDBUS_PART_NEXT(name))
511     list_len++;
512
513   _dbus_verbose ("List len: %d\n", list_len);
514
515   list = malloc(sizeof(char*) * (list_len + 1));
516   if(list == NULL)
517     goto out;
518
519   for (name = name_list->names; (uint8_t *)(name) < (uint8_t *)(name_list) + name_list->size; name = KDBUS_PART_NEXT(name))
520   {
521       if(name->size > sizeof(struct kdbus_cmd_name) )
522       {
523         list[i] = strdup(name->name);
524         if(list[i] == NULL)
525           goto out;
526       }
527       else
528       {
529         list[i] = malloc(snprintf(list[i], 0, ":1.%llu0", (unsigned long long)name->id));
530         if(list[i] == NULL)
531           goto out;
532         sprintf(list[i], ":1.%llu", (unsigned long long int)name->id);
533       }
534     _dbus_verbose ("Name %d: %s\n", i, list[i]);
535     ++i;
536   }
537
538   list[i] = NULL;
539         *array_len = list_len;
540         *listp = list;
541         ret_val = TRUE;
542
543 out:
544   if (ioctl(fd, KDBUS_CMD_FREE, &cmd.offset) < 0)
545   {
546     if(errno == EINTR)
547       goto out;
548     _dbus_verbose("kdbus error freeing pool: %d (%m)\n", errno);
549     ret_val = FALSE;
550   }
551   if(ret_val == FALSE)
552     {
553       for(j=0; j<i; j++)
554         free(list[j]);
555       free(list);
556       *array_len = 0;
557       *listp = NULL;
558     }
559
560         return ret_val;
561 }
562
563 /*
564  * Asks kdbus for list of connections being in the queue to own
565  * given well-known name. The list includes the owner of the name on the
566  * first position.
567  */
568 dbus_bool_t kdbus_list_queued (DBusConnection *connection, DBusList  **return_list,
569                                const char *name, DBusError  *error)
570 {
571   int fd;
572   dbus_bool_t ret_val = FALSE;
573   int name_length;
574   struct kdbus_cmd_conn_info *pCmd;
575   __u64 cmd_size;
576   DBusTransport *transport = dbus_connection_get_transport(connection);
577   struct kdbus_name_list *name_list;
578   struct kdbus_cmd_name *owner;
579
580   _dbus_assert (*return_list == NULL);
581
582   name_length = strlen(name) + 1;
583   cmd_size = sizeof(struct kdbus_cmd_conn_info) + name_length;
584   pCmd = alloca(cmd_size);
585   if(pCmd == NULL)
586     goto out;
587   pCmd->size = cmd_size;
588   pCmd->id = 0;
589   memcpy(pCmd->name, name, name_length);
590
591   _dbus_verbose ("Asking for queued owners of %s\n", pCmd->name);
592
593   _dbus_transport_get_socket_fd(transport, &fd);
594
595   again:
596   if(ioctl(fd, KDBUS_CMD_NAME_LIST_QUEUED, pCmd))
597     {
598       if(errno == EINTR)
599         goto again;
600       else if(errno == ESRCH)
601         {
602           dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
603                       "Could not get owners of name '%s': no such name", name);
604           return FALSE;
605         }
606       else
607         {
608           _dbus_verbose("kdbus error asking for queued owners list: err %d (%m)\n",errno);
609           goto out;
610         }
611     }
612
613   name_list = (struct kdbus_name_list *)((char*)dbus_transport_get_pool_pointer(transport) + pCmd->offset);
614
615   for (owner = name_list->names; (uint8_t *)(owner) < (uint8_t *)(name_list) + name_list->size; owner = KDBUS_PART_NEXT(owner))
616     {
617       char *uname = NULL;
618
619       _dbus_verbose ("Got queued owner id: %llu\n", (unsigned long long)owner->id);
620       uname = malloc(snprintf(uname, 0, ":1.%llu0", (unsigned long long)owner->id));
621       if(uname == NULL)
622         goto out;
623       sprintf(uname, ":1.%llu", (unsigned long long int)owner->id);
624       if (!_dbus_list_append (return_list, uname))
625         goto out;
626     }
627
628   ret_val = TRUE;
629
630   out:
631   if (ioctl(fd, KDBUS_CMD_FREE, &pCmd->offset) < 0)
632   {
633     if(errno == EINTR)
634       goto out;
635     _dbus_verbose("kdbus error freeing pool: %d (%m)\n", errno);
636     ret_val = FALSE;
637   }
638   if(ret_val == FALSE)
639     {
640       DBusList *link;
641
642       dbus_set_error (error, _dbus_error_from_errno (errno),
643           "Failed to list queued owners of \"%s\": %s",
644           name, _dbus_strerror (errno));
645
646       link = _dbus_list_get_first_link (return_list);
647       while (link != NULL)
648         {
649           DBusList *next = _dbus_list_get_next_link (return_list, link);
650
651           if(link->data != NULL)
652             free(link->data);
653
654           _dbus_list_free_link (link);
655           link = next;
656         }
657     }
658
659   return ret_val;
660 }
661
662 /*
663  *  Register match rule in kdbus on behalf of sender of the message
664  */
665 dbus_bool_t kdbus_add_match_rule (DBusConnection* connection, DBusMessage* message, const char* text, DBusError* error)
666 {
667         __u64 sender_id;
668
669         sender_id = sender_name_to_id(dbus_message_get_sender(message), error);
670         if(dbus_error_is_set(error))
671                 return FALSE;
672
673         if(!add_match_kdbus (dbus_connection_get_transport(connection), sender_id, text))
674         {
675               dbus_set_error (error, _dbus_error_from_errno (errno), "Could not add match for id:%llu, %s",
676                               sender_id, _dbus_strerror_from_errno ());
677               return FALSE;
678         }
679
680         return TRUE;
681 }
682
683 /*
684  *  Removes match rule in kdbus on behalf of sender of the message
685  */
686 dbus_bool_t kdbus_remove_match (DBusConnection* connection, DBusMessage* message, DBusError* error)
687 {
688         __u64 sender_id;
689
690         sender_id = sender_name_to_id(dbus_message_get_sender(message), error);
691         if(dbus_error_is_set(error))
692                 return FALSE;
693
694         if(!remove_match_kdbus (dbus_connection_get_transport(connection), sender_id))
695         {
696               dbus_set_error (error, _dbus_error_from_errno (errno), "Could not remove match rules for id:%llu", sender_id);
697               return FALSE;
698         }
699
700         return TRUE;
701 }
702
703 int kdbus_get_name_owner(DBusConnection* connection, const char* name, char* owner)
704 {
705   int ret;
706   struct nameInfo info;
707
708   ret = kdbus_NameQuery(name, dbus_connection_get_transport(connection), &info);
709   if(ret == 0) //unique id of the name
710   {
711     sprintf(owner, ":1.%llu", (unsigned long long int)info.uniqueId);
712     _dbus_verbose("Unique name discovered:%s\n", owner);
713   }
714   else if((ret != -ENOENT) && (ret != -ENXIO))
715     _dbus_verbose("kdbus error sending name query: err %d (%m)\n", ret);
716
717   return ret;
718 }
719
720 /*
721  *  Asks kdbus for selinux_security_context of the owner of the name given in the message
722  */
723 dbus_bool_t kdbus_get_connection_unix_selinux_security_context(DBusConnection* connection, DBusMessage* message, DBusMessage* reply, DBusError* error)
724 {
725         char* name = NULL;
726         struct nameInfo info;
727         int inter_ret;
728         dbus_bool_t ret = FALSE;
729
730         dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
731         inter_ret = kdbus_NameQuery(name, dbus_connection_get_transport(connection), &info);
732         if((inter_ret == -ENOENT) || (inter_ret == -ENXIO)) //name has no owner
733                 dbus_set_error (error, DBUS_ERROR_FAILED, "Could not get security context of name '%s': no such name", name);
734         else if(inter_ret < 0)
735         {
736                 _dbus_verbose("kdbus error determining security context: err %d (%m)\n", errno);
737                 dbus_set_error (error, DBUS_ERROR_FAILED, "Could not determine security context for '%s'", name);
738         }
739         else
740         {
741                 if (!dbus_message_append_args (reply, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &info.sec_label, info.sec_label_len, DBUS_TYPE_INVALID))
742                 {
743                       _DBUS_SET_OOM (error);
744                       return FALSE;
745                 }
746                 ret = TRUE;
747         }
748
749         return ret;
750 }
751
752 /*
753  * Create connection structure for given name. It is needed to control starters - activatable services
754  * and for ListQueued method (as long as kdbus is not supporting it). This connections don't have it's own
755  * fd so it is set up on the basis of daemon's transport. Functionality of such connection is limited.
756  */
757 DBusConnection* create_phantom_connection(DBusConnection* connection, const char* name, DBusError* error)
758 {
759     DBusConnection *phantom_connection;
760     DBusString Sname;
761
762     _dbus_string_init_const(&Sname, name);
763
764     phantom_connection = _dbus_connection_new_for_used_transport (dbus_connection_get_transport(connection));
765     if(phantom_connection == NULL)
766         return FALSE;
767     if(!bus_connections_setup_connection(bus_connection_get_connections(connection), phantom_connection))
768     {
769         dbus_connection_unref_phantom(phantom_connection);
770         phantom_connection = NULL;
771         dbus_set_error (error, DBUS_ERROR_FAILED , "Name \"%s\" could not be acquired", name);
772         goto out;
773     }
774     dbus_bus_set_unique_name(phantom_connection, name);
775     if(!bus_connection_complete(phantom_connection, &Sname, error))
776     {
777         bus_connection_disconnected(phantom_connection);
778         phantom_connection = NULL;
779         goto out;
780     }
781
782     _dbus_verbose ("Created phantom connection for %s\n", bus_connection_get_name(phantom_connection));
783
784 out:
785     return phantom_connection;
786 }
787
788 /*
789  * Registers activatable services as kdbus starters.
790  */
791 dbus_bool_t register_kdbus_starters(DBusConnection* connection)
792 {
793     int i,j, len;
794     char **services;
795     dbus_bool_t retval = FALSE;
796     int fd;
797     BusTransaction *transaction;
798     DBusString name;
799     DBusTransport* transport;
800
801     transaction = bus_transaction_new (bus_connection_get_context(connection));
802     if (transaction == NULL)
803         return FALSE;
804
805     if (!bus_activation_list_services (bus_connection_get_activation (connection), &services, &len))
806         return FALSE;
807
808     transport = dbus_connection_get_transport(connection);
809
810     if(!_dbus_transport_get_socket_fd (transport, &fd))
811       return FALSE;
812
813     _dbus_string_init(&name);
814
815     for(i=0; i<len; i++)
816     {
817 #ifdef POLICY_TO_KDBUS
818         if(!register_kdbus_policy(services[i], transport, geteuid()))
819           goto out;
820 #endif
821
822         if (request_kdbus_name(fd, services[i], (DBUS_NAME_FLAG_ALLOW_REPLACEMENT | KDBUS_NAME_STARTER_NAME) , 0) < 0)
823             goto out;
824
825         if(!_dbus_string_append(&name, services[i]))
826                 goto out;
827         if(!bus_registry_ensure (bus_connection_get_registry (connection), &name, connection,
828                         (DBUS_NAME_FLAG_ALLOW_REPLACEMENT | KDBUS_NAME_STARTER_NAME), transaction, NULL))
829                 goto out;
830         if(!_dbus_string_set_length(&name, 0))
831                 goto out;
832     }
833     retval = TRUE;
834
835 out:
836     if(retval == FALSE)
837     {
838         for(j=0; j<i; j++)
839             release_kdbus_name(fd, services[j], 0);
840     }
841     dbus_free_string_array (services);
842     _dbus_string_free(&name);
843   if(retval)
844     bus_transaction_execute_and_free(transaction);
845   else
846     bus_transaction_cancel_and_free(transaction);
847
848   return retval;
849 }
850
851 /*
852  * Updates kdbus starters (activatable services) after configuration was reloaded.
853  * It releases all previous starters and registers all new.
854  */
855 dbus_bool_t update_kdbus_starters(DBusConnection* connection)
856 {
857     dbus_bool_t retval = FALSE;
858     DBusList **services_old;
859     DBusList *link;
860     BusService *service = NULL;
861     BusTransaction *transaction;
862     int fd;
863
864     transaction = bus_transaction_new (bus_connection_get_context(connection));
865     if (transaction == NULL)
866         return FALSE;
867
868     if(!_dbus_transport_get_socket_fd(dbus_connection_get_transport(connection), &fd))
869         goto out;
870
871     services_old = bus_connection_get_services_owned(connection);
872     link = _dbus_list_get_first_link(services_old);
873     link = _dbus_list_get_next_link (services_old, link); //skip org.freedesktop.DBus which is not starter
874
875     while (link != NULL)
876     {
877         int ret;
878
879         service = (BusService*) link->data;
880         if(service == NULL)
881             goto out;
882
883         ret = release_kdbus_name(fd, bus_service_get_name(service), 0);
884
885         if (ret == DBUS_RELEASE_NAME_REPLY_RELEASED)
886         {
887             if(!bus_service_remove_owner(service, connection, transaction, NULL))
888                 _dbus_verbose ("Unable to remove\n");
889         }
890         else if(ret < 0)
891             goto out;
892
893         link = _dbus_list_get_next_link (services_old, link);
894     }
895
896     if(!register_kdbus_starters(connection))
897     {
898         _dbus_verbose ("Registering kdbus starters for dbus activatable names failed!\n");
899         goto out;
900     }
901     retval = TRUE;
902
903 out:
904   if(retval)
905     bus_transaction_execute_and_free(transaction);
906   else
907     bus_transaction_cancel_and_free(transaction);
908
909   return retval;
910 }
911
912 /*
913  * Analyzes system broadcasts about id and name changes.
914  * Basing on this it sends NameAcquired and NameLost signals and clear phantom connections.
915  */
916 void handleNameOwnerChanged(DBusMessage *msg, BusTransaction *transaction, DBusConnection *connection)
917 {
918     const char *name, *old, *new;
919
920     if(!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old, DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID))
921     {
922         _dbus_verbose ("Couldn't get args of NameOwnerChanged signal.\n");//, error.message);
923         return;
924     }
925
926     _dbus_verbose ("Got NameOwnerChanged signal:\nName: %s\nOld: %s\nNew: %s\n", name, old, new);
927
928     if(!strncmp(name, ":1.", 3))/*if it starts from :1. it is unique name - this might be IdRemoved info*/
929     {
930         if(!strcmp(name, old))  //yes it is - someone has disconnected
931         {
932             DBusConnection* conn;
933
934             conn = bus_connections_find_conn_by_name(bus_connection_get_connections(connection), name);
935             if(conn)
936                 bus_connection_disconnected(conn);
937         }
938     }
939     else //it is well-known name
940     {
941         if((*old != 0) && (strcmp(old, bus_connection_get_name(connection))))
942         {
943             DBusMessage *message;
944
945             if(bus_connections_find_conn_by_name(bus_connection_get_connections(connection), old) == NULL)
946                 goto next;
947
948             _dbus_verbose ("Owner '%s' lost name '%s'. Sending NameLost.\n", old, name);
949
950             message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameLost");
951             if (message == NULL)
952                 goto next;
953
954             if (!dbus_message_set_destination (message, old) || !dbus_message_append_args (message,
955                                                                  DBUS_TYPE_STRING, &name,
956                                                                  DBUS_TYPE_INVALID))
957             {
958                 dbus_message_unref (message);
959                 goto next;
960             }
961
962             bus_transaction_send_from_driver (transaction, connection, message);
963             dbus_message_unref (message);
964         }
965     next:
966         if((*new != 0) && (strcmp(new, bus_connection_get_name(connection))))
967         {
968             DBusMessage *message;
969
970             _dbus_verbose ("Owner '%s' acquired name '%s'. Sending NameAcquired.\n", new, name);
971
972             message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameAcquired");
973             if (message == NULL)
974                 return;
975
976             if (!dbus_message_set_destination (message, new) || !dbus_message_append_args (message,
977                                                                  DBUS_TYPE_STRING, &name,
978                                                                  DBUS_TYPE_INVALID))
979             {
980                 dbus_message_unref (message);
981                 return;
982             }
983
984             bus_transaction_send_from_driver (transaction, connection, message);
985             dbus_message_unref (message);
986         }
987     }
988
989     if(bus_transaction_send(transaction, connection, msg))
990       _dbus_verbose ("NameOwnerChanged sent\n");
991     else
992       _dbus_verbose ("Sending NameOwnerChanged failed\n");
993 }