[daemon-dev] List of queued owners read from kdbus
[platform/upstream/dbus.git] / bus / driver.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* driver.c  Bus client (driver)
3  *
4  * Copyright (C) 2003 CodeFactory AB
5  * Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
6  * Copyright (C) 2013  Samsung Electronics
7  *
8  * Licensed under the Academic Free License version 2.1
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23  *
24  */
25
26 #include <config.h>
27 #include "activation.h"
28 #include "connection.h"
29 #include "driver.h"
30 #include "dispatch.h"
31 #include "services.h"
32 #include "selinux.h"
33 #include "signals.h"
34 #include "stats.h"
35 #include "utils.h"
36
37 #include <dbus/dbus-asv-util.h>
38 #include <dbus/dbus-string.h>
39 #include <dbus/dbus-internals.h>
40 #include <dbus/dbus-message.h>
41 #include <dbus/dbus-marshal-recursive.h>
42 #include <string.h>
43
44 #ifdef ENABLE_KDBUS_TRANSPORT
45 #include "kdbus-d.h"
46 #include <stdio.h>
47 #include <errno.h>
48 #include <limits.h>
49 #include <stdlib.h>
50 #endif
51
52 static DBusConnection *
53 bus_driver_get_conn_helper (DBusConnection  *connection,
54                             DBusMessage     *message,
55                             const char      *what_we_want,
56                             const char     **name_p,
57                             DBusError       *error)
58 {
59   const char *name;
60   BusRegistry *registry;
61   BusService *serv;
62   DBusString str;
63   DBusConnection *conn;
64
65   if (!dbus_message_get_args (message, error,
66                               DBUS_TYPE_STRING, &name,
67                               DBUS_TYPE_INVALID))
68     return NULL;
69
70   _dbus_assert (name != NULL);
71   _dbus_verbose ("asked for %s of connection %s\n", what_we_want, name);
72
73   registry = bus_connection_get_registry (connection);
74   _dbus_string_init_const (&str, name);
75   serv = bus_registry_lookup (registry, &str);
76
77   if (serv == NULL)
78     {
79       dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
80                       "Could not get %s of name '%s': no such name",
81                       what_we_want, name);
82       return NULL;
83     }
84
85   conn = bus_service_get_primary_owners_connection (serv);
86   _dbus_assert (conn != NULL);
87
88   if (name_p != NULL)
89     *name_p = name;
90
91   return conn;
92 }
93
94 static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
95                                                     DBusMessage    *hello_message,
96                                                     BusTransaction *transaction,
97                                                     DBusError      *error);
98
99 dbus_bool_t
100 bus_driver_send_service_owner_changed (const char     *service_name,
101                                        const char     *old_owner,
102                                        const char     *new_owner,
103                                        BusTransaction *transaction,
104                                        DBusError      *error)
105 {
106   DBusMessage *message;
107   dbus_bool_t retval;
108   const char *null_service;
109
110 #ifdef ENABLE_KDBUS_TRANSPORT
111   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
112           return TRUE;
113 #endif
114
115   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
116
117   null_service = "";
118   _dbus_verbose ("sending name owner changed: %s [%s -> %s]\n",
119                  service_name,
120                  old_owner ? old_owner : null_service,
121                  new_owner ? new_owner : null_service);
122
123   message = dbus_message_new_signal (DBUS_PATH_DBUS,
124                                      DBUS_INTERFACE_DBUS,
125                                      "NameOwnerChanged");
126
127   if (message == NULL)
128     {
129       BUS_SET_OOM (error);
130       return FALSE;
131     }
132
133   if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
134     goto oom;
135
136   if (!dbus_message_append_args (message,
137                                  DBUS_TYPE_STRING, &service_name,
138                                  DBUS_TYPE_STRING, old_owner ? &old_owner : &null_service,
139                                  DBUS_TYPE_STRING, new_owner ? &new_owner : &null_service,
140                                  DBUS_TYPE_INVALID))
141     goto oom;
142
143   _dbus_assert (dbus_message_has_signature (message, "sss"));
144
145   retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
146   dbus_message_unref (message);
147
148   return retval;
149
150  oom:
151   dbus_message_unref (message);
152   BUS_SET_OOM (error);
153   return FALSE;
154 }
155
156 dbus_bool_t
157 bus_driver_send_service_lost (DBusConnection *connection,
158                               const char     *service_name,
159                               BusTransaction *transaction,
160                               DBusError      *error)
161 {
162   DBusMessage *message;
163
164 #ifdef ENABLE_KDBUS_TRANSPORT
165   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
166           return TRUE;
167 #endif
168
169   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
170
171   message = dbus_message_new_signal (DBUS_PATH_DBUS,
172                                      DBUS_INTERFACE_DBUS,
173                                      "NameLost");
174
175   if (message == NULL)
176     {
177       BUS_SET_OOM (error);
178       return FALSE;
179     }
180
181   if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
182       !dbus_message_append_args (message,
183                                  DBUS_TYPE_STRING, &service_name,
184                                  DBUS_TYPE_INVALID))
185     {
186       dbus_message_unref (message);
187       BUS_SET_OOM (error);
188       return FALSE;
189     }
190
191   if (!bus_transaction_send_from_driver (transaction, connection, message))
192     {
193       dbus_message_unref (message);
194       BUS_SET_OOM (error);
195       return FALSE;
196     }
197   else
198     {
199       dbus_message_unref (message);
200       return TRUE;
201     }
202 }
203
204 dbus_bool_t
205 bus_driver_send_service_acquired (DBusConnection *connection,
206                                   const char     *service_name,
207                                   BusTransaction *transaction,
208                                   DBusError      *error)
209 {
210   DBusMessage *message;
211
212 #ifdef ENABLE_KDBUS_TRANSPORT
213   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
214           return TRUE;
215 #endif
216
217   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
218
219   message = dbus_message_new_signal (DBUS_PATH_DBUS,
220                                      DBUS_INTERFACE_DBUS,
221                                      "NameAcquired");
222
223   if (message == NULL)
224     {
225       BUS_SET_OOM (error);
226       return FALSE;
227     }
228
229   if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
230       !dbus_message_append_args (message,
231                                  DBUS_TYPE_STRING, &service_name,
232                                  DBUS_TYPE_INVALID))
233     {
234       dbus_message_unref (message);
235       BUS_SET_OOM (error);
236       return FALSE;
237     }
238
239   if (!bus_transaction_send_from_driver (transaction, connection, message))
240     {
241       dbus_message_unref (message);
242       BUS_SET_OOM (error);
243       return FALSE;
244     }
245   else
246     {
247       dbus_message_unref (message);
248       return TRUE;
249     }
250 }
251
252 static dbus_bool_t
253 create_unique_client_name (BusRegistry *registry,
254                            DBusString  *str)
255 {
256   /* We never want to use the same unique client name twice, because
257    * we want to guarantee that if you send a message to a given unique
258    * name, you always get the same application. So we use two numbers
259    * for INT_MAX * INT_MAX combinations, should be pretty safe against
260    * wraparound.
261    */
262   /* FIXME these should be in BusRegistry rather than static vars */
263   static int next_major_number = 0;
264   static int next_minor_number = 0;
265   int len;
266
267   len = _dbus_string_get_length (str);
268
269   while (TRUE)
270     {
271       /* start out with 1-0, go to 1-1, 1-2, 1-3,
272        * up to 1-MAXINT, then 2-0, 2-1, etc.
273        */
274       if (next_minor_number <= 0)
275         {
276           next_major_number += 1;
277           next_minor_number = 0;
278           if (next_major_number <= 0)
279             _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
280         }
281
282       _dbus_assert (next_major_number > 0);
283       _dbus_assert (next_minor_number >= 0);
284
285       /* appname:MAJOR-MINOR */
286
287       if (!_dbus_string_append (str, ":"))
288         return FALSE;
289
290       if (!_dbus_string_append_int (str, next_major_number))
291         return FALSE;
292
293       if (!_dbus_string_append (str, "."))
294         return FALSE;
295
296       if (!_dbus_string_append_int (str, next_minor_number))
297         return FALSE;
298
299       next_minor_number += 1;
300
301       /* Check if a client with the name exists */
302       if (bus_registry_lookup (registry, str) == NULL)
303         break;
304
305       /* drop the number again, try the next one. */
306       _dbus_string_set_length (str, len);
307     }
308
309   return TRUE;
310 }
311
312 static dbus_bool_t
313 bus_driver_handle_hello (DBusConnection *connection,
314                          BusTransaction *transaction,
315                          DBusMessage    *message,
316                          DBusError      *error)
317 {
318   DBusString unique_name;
319   BusService *service;
320   dbus_bool_t retval;
321   BusRegistry *registry;
322   BusConnections *connections;
323
324   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
325
326   if (bus_connection_is_active (connection))
327     {
328       /* We already handled an Hello message for this connection. */
329       dbus_set_error (error, DBUS_ERROR_FAILED,
330                       "Already handled an Hello message");
331       return FALSE;
332     }
333
334   /* Note that when these limits are exceeded we don't disconnect the
335    * connection; we just sort of leave it hanging there until it times
336    * out or disconnects itself or is dropped due to the max number of
337    * incomplete connections. It's even OK if the connection wants to
338    * retry the hello message, we support that.
339    */
340   connections = bus_connection_get_connections (connection);
341   if (!bus_connections_check_limits (connections, connection,
342                                      error))
343     {
344       _DBUS_ASSERT_ERROR_IS_SET (error);
345       return FALSE;
346     }
347
348   if (!_dbus_string_init (&unique_name))
349     {
350       BUS_SET_OOM (error);
351       return FALSE;
352     }
353
354   retval = FALSE;
355
356   registry = bus_connection_get_registry (connection);
357
358   if (!create_unique_client_name (registry, &unique_name))
359     {
360       BUS_SET_OOM (error);
361       goto out_0;
362     }
363
364   if (!bus_connection_complete (connection, &unique_name, error))
365     {
366       _DBUS_ASSERT_ERROR_IS_SET (error);
367       goto out_0;
368     }
369
370   if (!dbus_message_set_sender (message,
371                                 bus_connection_get_name (connection)))
372     {
373       BUS_SET_OOM (error);
374       goto out_0;
375     }
376
377   if (!bus_driver_send_welcome_message (connection, message, transaction, error))
378     goto out_0;
379
380   /* Create the service */
381   service = bus_registry_ensure (registry,
382                                  &unique_name, connection, 0, transaction, error);
383   if (service == NULL)
384     goto out_0;
385
386   _dbus_assert (bus_connection_is_active (connection));
387   retval = TRUE;
388
389  out_0:
390   _dbus_string_free (&unique_name);
391   return retval;
392 }
393
394 static dbus_bool_t
395 bus_driver_send_welcome_message (DBusConnection *connection,
396                                  DBusMessage    *hello_message,
397                                  BusTransaction *transaction,
398                                  DBusError      *error)
399 {
400   DBusMessage *welcome;
401   const char *name;
402
403   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
404
405   name = bus_connection_get_name (connection);
406   _dbus_assert (name != NULL);
407
408   welcome = dbus_message_new_method_return (hello_message);
409   if (welcome == NULL)
410     {
411       BUS_SET_OOM (error);
412       return FALSE;
413     }
414
415   if (!dbus_message_append_args (welcome,
416                                  DBUS_TYPE_STRING, &name,
417                                  DBUS_TYPE_INVALID))
418     {
419       dbus_message_unref (welcome);
420       BUS_SET_OOM (error);
421       return FALSE;
422     }
423
424   _dbus_assert (dbus_message_has_signature (welcome, DBUS_TYPE_STRING_AS_STRING));
425
426   if (!bus_transaction_send_from_driver (transaction, connection, welcome))
427     {
428       dbus_message_unref (welcome);
429       BUS_SET_OOM (error);
430       return FALSE;
431     }
432   else
433     {
434       dbus_message_unref (welcome);
435       return TRUE;
436     }
437 }
438
439 static dbus_bool_t
440 bus_driver_handle_list_services (DBusConnection *connection,
441                                  BusTransaction *transaction,
442                                  DBusMessage    *message,
443                                  DBusError      *error)
444 {
445   DBusMessage *reply;
446   int len;
447   char **services;
448   BusRegistry *registry;
449   int i;
450   DBusMessageIter iter;
451   DBusMessageIter sub;
452
453   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
454
455   registry = bus_connection_get_registry (connection);
456
457   reply = dbus_message_new_method_return (message);
458   if (reply == NULL)
459     {
460       BUS_SET_OOM (error);
461       return FALSE;
462     }
463
464 #ifdef ENABLE_KDBUS_TRANSPORT
465   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
466   {
467           if(!kdbus_list_services (connection, &services, &len))
468             {
469               dbus_message_unref (reply);
470               BUS_SET_OOM (error);
471               return FALSE;
472             }
473   }
474   else
475 #endif
476   {
477       if (!bus_registry_list_services (registry, &services, &len))
478         {
479           dbus_message_unref (reply);
480           BUS_SET_OOM (error);
481           return FALSE;
482         }
483   }
484
485   dbus_message_iter_init_append (reply, &iter);
486
487   if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
488                                          DBUS_TYPE_STRING_AS_STRING,
489                                          &sub))
490     {
491       dbus_free_string_array (services);
492       dbus_message_unref (reply);
493       BUS_SET_OOM (error);
494       return FALSE;
495     }
496
497 #ifdef ENABLE_KDBUS_TRANSPORT
498   if(!bus_context_is_kdbus(bus_transaction_get_context (transaction))) //not needed for kdbus, we got it from kdbus_list_services
499 #endif
500   {
501
502     /* Include the bus driver in the list */
503     const char *v_STRING = DBUS_SERVICE_DBUS;
504     if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
505                                          &v_STRING))
506       {
507         dbus_free_string_array (services);
508         dbus_message_unref (reply);
509         BUS_SET_OOM (error);
510         return FALSE;
511       }
512   }
513
514   i = 0;
515   while (i < len)
516     {
517       if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
518                                            &services[i]))
519         {
520           dbus_free_string_array (services);
521           dbus_message_unref (reply);
522           BUS_SET_OOM (error);
523           return FALSE;
524         }
525       ++i;
526     }
527
528   dbus_free_string_array (services);
529
530   if (!dbus_message_iter_close_container (&iter, &sub))
531     {
532       dbus_message_unref (reply);
533       BUS_SET_OOM (error);
534       return FALSE;
535     }
536
537   if (!bus_transaction_send_from_driver (transaction, connection, reply))
538     {
539       dbus_message_unref (reply);
540       BUS_SET_OOM (error);
541       return FALSE;
542     }
543   else
544     {
545       dbus_message_unref (reply);
546       return TRUE;
547     }
548 }
549
550 static dbus_bool_t
551 bus_driver_handle_list_activatable_services (DBusConnection *connection,
552                                              BusTransaction *transaction,
553                                              DBusMessage    *message,
554                                              DBusError      *error)
555 {
556   DBusMessage *reply;
557   int len;
558   char **services;
559   BusActivation *activation;
560   int i;
561   DBusMessageIter iter;
562   DBusMessageIter sub;
563
564   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
565
566   activation = bus_connection_get_activation (connection);
567
568   reply = dbus_message_new_method_return (message);
569   if (reply == NULL)
570     {
571       BUS_SET_OOM (error);
572       return FALSE;
573     }
574
575   if (!bus_activation_list_services (activation, &services, &len))
576     {
577       dbus_message_unref (reply);
578       BUS_SET_OOM (error);
579       return FALSE;
580     }
581
582   dbus_message_iter_init_append (reply, &iter);
583
584   if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
585                                          DBUS_TYPE_STRING_AS_STRING,
586                                          &sub))
587     {
588       dbus_free_string_array (services);
589       dbus_message_unref (reply);
590       BUS_SET_OOM (error);
591       return FALSE;
592     }
593
594   {
595     /* Include the bus driver in the list */
596     const char *v_STRING = DBUS_SERVICE_DBUS;
597     if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
598                                          &v_STRING))
599       {
600         dbus_free_string_array (services);
601         dbus_message_unref (reply);
602         BUS_SET_OOM (error);
603         return FALSE;
604       }
605   }
606
607   i = 0;
608   while (i < len)
609     {
610       if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
611                                            &services[i]))
612         {
613           dbus_free_string_array (services);
614           dbus_message_unref (reply);
615           BUS_SET_OOM (error);
616           return FALSE;
617         }
618       ++i;
619     }
620
621   dbus_free_string_array (services);
622
623   if (!dbus_message_iter_close_container (&iter, &sub))
624     {
625       dbus_message_unref (reply);
626       BUS_SET_OOM (error);
627       return FALSE;
628     }
629
630   if (!bus_transaction_send_from_driver (transaction, connection, reply))
631     {
632       dbus_message_unref (reply);
633       BUS_SET_OOM (error);
634       return FALSE;
635     }
636   else
637     {
638       dbus_message_unref (reply);
639       return TRUE;
640     }
641 }
642
643 static dbus_bool_t
644 bus_driver_handle_acquire_service (DBusConnection *connection,
645                                    BusTransaction *transaction,
646                                    DBusMessage    *message,
647                                    DBusError      *error)
648 {
649   DBusMessage *reply;
650   DBusString service_name;
651   const char *name;
652   dbus_uint32_t service_reply;
653   dbus_uint32_t flags;
654   dbus_bool_t retval;
655   BusRegistry *registry;
656
657   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
658
659   registry = bus_connection_get_registry (connection);
660
661   if (!dbus_message_get_args (message, error,
662                               DBUS_TYPE_STRING, &name,
663                               DBUS_TYPE_UINT32, &flags,
664                               DBUS_TYPE_INVALID))
665     return FALSE;
666
667   _dbus_verbose ("Trying to own name %s with flags 0x%x\n", name, flags);
668
669   retval = FALSE;
670   reply = NULL;
671
672 #ifdef ENABLE_KDBUS_TRANSPORT
673   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
674   {
675           if (!bus_registry_acquire_kdbus_service (registry, connection,
676                                                                                  message,
677                                              &service_reply, transaction,
678                                              error))
679             goto out;
680   }
681   else
682 #endif
683   {
684
685           _dbus_string_init_const (&service_name, name);
686
687           if (!bus_registry_acquire_service (registry, connection,
688                                              &service_name, flags,
689                                              &service_reply, transaction,
690                                              error))
691             goto out;
692   }
693
694   reply = dbus_message_new_method_return (message);
695   if (reply == NULL)
696     {
697       BUS_SET_OOM (error);
698       goto out;
699     }
700
701   if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
702     {
703       BUS_SET_OOM (error);
704       goto out;
705     }
706
707   if (!bus_transaction_send_from_driver (transaction, connection, reply))
708     {
709       BUS_SET_OOM (error);
710       goto out;
711     }
712
713   retval = TRUE;
714
715  out:
716   if (reply)
717     dbus_message_unref (reply);
718   return retval;
719 }
720
721 static dbus_bool_t
722 bus_driver_handle_release_service (DBusConnection *connection,
723                                    BusTransaction *transaction,
724                                    DBusMessage    *message,
725                                    DBusError      *error)
726 {
727   DBusMessage *reply;
728   DBusString service_name;
729   const char *name;
730   dbus_uint32_t service_reply;
731   dbus_bool_t retval;
732   BusRegistry *registry;
733
734   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
735
736   if (!dbus_message_get_args (message, error,
737                               DBUS_TYPE_STRING, &name,
738                               DBUS_TYPE_INVALID))
739     return FALSE;
740
741   _dbus_verbose ("Trying to release name %s\n", name);
742
743   retval = FALSE;
744   reply = NULL;
745
746   _dbus_string_init_const (&service_name, name);
747   registry = bus_connection_get_registry (connection);
748
749 #ifdef ENABLE_KDBUS_TRANSPORT
750   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
751   {
752           if (!bus_registry_release_service_kdbus (dbus_message_get_sender(message), connection,
753                                              &service_name, &service_reply,
754                                              transaction, error))
755               goto out;
756   }
757   else
758 #endif
759   if (!bus_registry_release_service (registry, connection,
760                                      &service_name, &service_reply,
761                                      transaction, error))
762     goto out;
763
764   reply = dbus_message_new_method_return (message);
765   if (reply == NULL)
766     {
767       BUS_SET_OOM (error);
768       goto out;
769     }
770
771   if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
772     {
773       BUS_SET_OOM (error);
774       goto out;
775     }
776
777   if (!bus_transaction_send_from_driver (transaction, connection, reply))
778     {
779       BUS_SET_OOM (error);
780       goto out;
781     }
782
783   retval = TRUE;
784
785  out:
786   if (reply)
787     dbus_message_unref (reply);
788   return retval;
789 }
790
791 static dbus_bool_t
792 bus_driver_handle_service_exists (DBusConnection *connection,
793                                   BusTransaction *transaction,
794                                   DBusMessage    *message,
795                                   DBusError      *error)
796 {
797   DBusMessage *reply;
798   DBusString service_name;
799   BusService *service;
800   dbus_bool_t service_exists;
801   const char *name;
802   dbus_bool_t retval;
803   BusRegistry *registry;
804
805   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
806
807   registry = bus_connection_get_registry (connection);
808
809   if (!dbus_message_get_args (message, error,
810                               DBUS_TYPE_STRING, &name,
811                               DBUS_TYPE_INVALID))
812     return FALSE;
813
814   retval = FALSE;
815
816   if (strcmp (name, DBUS_SERVICE_DBUS) == 0)
817     {
818       service_exists = TRUE;
819     }
820   else
821     {
822 #ifdef ENABLE_KDBUS_TRANSPORT
823           if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
824           {
825                   int inter_ret;
826                   struct nameInfo info;
827
828                   inter_ret = kdbus_NameQuery(name, dbus_connection_get_transport(connection), &info);
829                         if((inter_ret == 0) || (inter_ret == -ENOENT))
830                                 service_exists = (inter_ret == 0) ? TRUE : FALSE;
831                         else
832                         {
833                                 _dbus_verbose("kdbus error checking if name exists: err %d (%m)\n", errno);
834                                 dbus_set_error (error, DBUS_ERROR_FAILED, "Could not determine whether name '%s' exists", name);
835                                 service_exists = FALSE;
836                         }
837           }
838           else
839 #endif
840           {
841               _dbus_string_init_const (&service_name, name);
842               service = bus_registry_lookup (registry, &service_name);
843               service_exists = service != NULL;
844           }
845     }
846
847   reply = dbus_message_new_method_return (message);
848   if (reply == NULL)
849     {
850       BUS_SET_OOM (error);
851       goto out;
852     }
853
854   if (!dbus_message_append_args (reply,
855                                  DBUS_TYPE_BOOLEAN, &service_exists,
856                                  0))
857     {
858       BUS_SET_OOM (error);
859       goto out;
860     }
861
862   if (!bus_transaction_send_from_driver (transaction, connection, reply))
863     {
864       BUS_SET_OOM (error);
865       goto out;
866     }
867
868   retval = TRUE;
869
870  out:
871   if (reply)
872     dbus_message_unref (reply);
873
874   return retval;
875 }
876
877 static dbus_bool_t
878 bus_driver_handle_activate_service (DBusConnection *connection,
879                                     BusTransaction *transaction,
880                                     DBusMessage    *message,
881                                     DBusError      *error)
882 {
883   dbus_uint32_t flags;
884   const char *name;
885   dbus_bool_t retval;
886   BusActivation *activation;
887
888   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
889
890   activation = bus_connection_get_activation (connection);
891
892   if (!dbus_message_get_args (message, error,
893                               DBUS_TYPE_STRING, &name,
894                               DBUS_TYPE_UINT32, &flags,
895                               DBUS_TYPE_INVALID))
896     {
897       _DBUS_ASSERT_ERROR_IS_SET (error);
898       _dbus_verbose ("No memory to get arguments to StartServiceByName\n");
899       return FALSE;
900     }
901
902   retval = FALSE;
903
904   if (!bus_activation_activate_service (activation, connection, transaction, FALSE,
905                                         message, name, error))
906     {
907       _DBUS_ASSERT_ERROR_IS_SET (error);
908       _dbus_verbose ("bus_activation_activate_service() failed\n");
909       goto out;
910     }
911
912   retval = TRUE;
913
914  out:
915   return retval;
916 }
917
918 static dbus_bool_t
919 send_ack_reply (DBusConnection *connection,
920                 BusTransaction *transaction,
921                 DBusMessage    *message,
922                 DBusError      *error)
923 {
924   DBusMessage *reply;
925
926   if (dbus_message_get_no_reply (message))
927     return TRUE;
928
929   reply = dbus_message_new_method_return (message);
930   if (reply == NULL)
931     {
932       BUS_SET_OOM (error);
933       return FALSE;
934     }
935
936   if (!bus_transaction_send_from_driver (transaction, connection, reply))
937     {
938       BUS_SET_OOM (error);
939       dbus_message_unref (reply);
940       return FALSE;
941     }
942
943   dbus_message_unref (reply);
944
945   return TRUE;
946 }
947
948 static dbus_bool_t
949 bus_driver_handle_update_activation_environment (DBusConnection *connection,
950                                                  BusTransaction *transaction,
951                                                  DBusMessage    *message,
952                                                  DBusError      *error)
953 {
954   dbus_bool_t retval;
955   BusActivation *activation;
956   DBusMessageIter iter;
957   DBusMessageIter dict_iter;
958   DBusMessageIter dict_entry_iter;
959   int array_type;
960   int key_type;
961   DBusList *keys, *key_link;
962   DBusList *values, *value_link;
963
964   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
965
966   activation = bus_connection_get_activation (connection);
967
968   dbus_message_iter_init (message, &iter);
969
970   /* The message signature has already been checked for us,
971    * so let's just assert it's right.
972    */
973   _dbus_assert (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY);
974
975   dbus_message_iter_recurse (&iter, &dict_iter);
976
977   retval = FALSE;
978
979   /* Then loop through the sent dictionary, add the location of
980    * the environment keys and values to lists. The result will
981    * be in reverse order, so we don't have to constantly search
982    * for the end of the list in a loop.
983    */
984   keys = NULL;
985   values = NULL;
986   while ((array_type = dbus_message_iter_get_arg_type (&dict_iter)) == DBUS_TYPE_DICT_ENTRY)
987     {
988       dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
989
990       while ((key_type = dbus_message_iter_get_arg_type (&dict_entry_iter)) == DBUS_TYPE_STRING)
991         {
992           char *key;
993           char *value;
994           int value_type;
995
996           dbus_message_iter_get_basic (&dict_entry_iter, &key);
997           dbus_message_iter_next (&dict_entry_iter);
998
999           value_type = dbus_message_iter_get_arg_type (&dict_entry_iter);
1000
1001           if (value_type != DBUS_TYPE_STRING)
1002             break;
1003
1004           dbus_message_iter_get_basic (&dict_entry_iter, &value);
1005
1006           if (!_dbus_list_append (&keys, key))
1007             {
1008               BUS_SET_OOM (error);
1009               break;
1010             }
1011
1012           if (!_dbus_list_append (&values, value))
1013             {
1014               BUS_SET_OOM (error);
1015               break;
1016             }
1017
1018           dbus_message_iter_next (&dict_entry_iter);
1019         }
1020
1021       if (key_type != DBUS_TYPE_INVALID)
1022         break;
1023
1024       dbus_message_iter_next (&dict_iter);
1025     }
1026
1027   if (array_type != DBUS_TYPE_INVALID)
1028     goto out;
1029
1030   _dbus_assert (_dbus_list_get_length (&keys) == _dbus_list_get_length (&values));
1031
1032   key_link = keys;
1033   value_link = values;
1034   while (key_link != NULL)
1035   {
1036       const char *key;
1037       const char *value;
1038
1039       key = key_link->data;
1040       value = value_link->data;
1041
1042       if (!bus_activation_set_environment_variable (activation,
1043                                                     key, value, error))
1044       {
1045           _DBUS_ASSERT_ERROR_IS_SET (error);
1046           _dbus_verbose ("bus_activation_set_environment_variable() failed\n");
1047           break;
1048       }
1049       key_link = _dbus_list_get_next_link (&keys, key_link);
1050       value_link = _dbus_list_get_next_link (&values, value_link);
1051   }
1052
1053   /* FIXME: We can fail early having set only some of the environment variables,
1054    * (because of OOM failure).  It's sort of hard to fix and it doesn't really
1055    * matter, so we're punting for now.
1056    */
1057   if (key_link != NULL)
1058     goto out;
1059
1060   if (!send_ack_reply (connection, transaction,
1061                        message, error))
1062     goto out;
1063
1064   retval = TRUE;
1065
1066  out:
1067   _dbus_list_clear (&keys);
1068   _dbus_list_clear (&values);
1069   return retval;
1070 }
1071
1072 static dbus_bool_t
1073 bus_driver_handle_add_match (DBusConnection *connection,
1074                              BusTransaction *transaction,
1075                              DBusMessage    *message,
1076                              DBusError      *error)
1077 {
1078   BusMatchRule *rule;
1079   const char *text;
1080   DBusString str;
1081   BusMatchmaker *matchmaker;
1082
1083   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1084
1085   text = NULL;
1086   rule = NULL;
1087
1088   if (bus_connection_get_n_match_rules (connection) >=
1089       bus_context_get_max_match_rules_per_connection (bus_transaction_get_context (transaction)))
1090     {
1091       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
1092                       "Connection \"%s\" is not allowed to add more match rules "
1093                       "(increase limits in configuration file if required)",
1094                       bus_connection_is_active (connection) ?
1095                       bus_connection_get_name (connection) :
1096                       "(inactive)");
1097       goto failed;
1098     }
1099
1100   if (!dbus_message_get_args (message, error,
1101                               DBUS_TYPE_STRING, &text,
1102                               DBUS_TYPE_INVALID))
1103     {
1104       _dbus_verbose ("No memory to get arguments to AddMatch\n");
1105       goto failed;
1106     }
1107
1108   _dbus_string_init_const (&str, text);
1109
1110   rule = bus_match_rule_parse (connection, &str, error);
1111   if (rule == NULL)
1112     goto failed;
1113
1114 #ifdef ENABLE_KDBUS_TRANSPORT
1115   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1116   {
1117
1118           if (!kdbus_add_match_rule (connection, message, text, error))
1119               goto failed;
1120
1121           if (!send_ack_reply (connection, transaction,
1122                                message, error))
1123               goto failed;
1124   }
1125   else
1126 #endif
1127   {
1128
1129           matchmaker = bus_connection_get_matchmaker (connection);
1130
1131           if (!bus_matchmaker_add_rule (matchmaker, rule))
1132             {
1133               BUS_SET_OOM (error);
1134               goto failed;
1135             }
1136
1137           if (!send_ack_reply (connection, transaction,
1138                                message, error))
1139             {
1140               bus_matchmaker_remove_rule (matchmaker, rule);
1141               goto failed;
1142             }
1143   }
1144
1145   bus_match_rule_unref (rule);
1146
1147   return TRUE;
1148
1149  failed:
1150   _DBUS_ASSERT_ERROR_IS_SET (error);
1151   if (rule)
1152     bus_match_rule_unref (rule);
1153   return FALSE;
1154 }
1155
1156 static dbus_bool_t
1157 bus_driver_handle_remove_match (DBusConnection *connection,
1158                                 BusTransaction *transaction,
1159                                 DBusMessage    *message,
1160                                 DBusError      *error)
1161 {
1162   BusMatchRule *rule;
1163   const char *text;
1164   DBusString str;
1165   BusMatchmaker *matchmaker;
1166
1167   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1168
1169   text = NULL;
1170   rule = NULL;
1171
1172   if (!dbus_message_get_args (message, error,
1173                               DBUS_TYPE_STRING, &text,
1174                               DBUS_TYPE_INVALID))
1175     {
1176       _dbus_verbose ("No memory to get arguments to RemoveMatch\n");
1177       goto failed;
1178     }
1179
1180   _dbus_string_init_const (&str, text);
1181
1182   rule = bus_match_rule_parse (connection, &str, error);
1183   if (rule == NULL)
1184     goto failed;
1185
1186 #ifdef ENABLE_KDBUS_TRANSPORT
1187   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1188   {
1189           if(!kdbus_remove_match(connection, message, error))
1190                   goto failed;
1191   }
1192 #endif
1193
1194   /* Send the ack before we remove the rule, since the ack is undone
1195    * on transaction cancel, but rule removal isn't.
1196    */
1197   if (!send_ack_reply (connection, transaction,
1198                        message, error))
1199     goto failed;
1200
1201 #ifdef ENABLE_KDBUS_TRANSPORT
1202   if(!bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1203 #endif
1204   {
1205           matchmaker = bus_connection_get_matchmaker (connection);
1206
1207           if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error))
1208                 goto failed;
1209   }
1210
1211   bus_match_rule_unref (rule);
1212
1213   return TRUE;
1214
1215  failed:
1216   _DBUS_ASSERT_ERROR_IS_SET (error);
1217   if (rule)
1218     bus_match_rule_unref (rule);
1219   return FALSE;
1220 }
1221
1222 static dbus_bool_t
1223 bus_driver_handle_get_service_owner (DBusConnection *connection,
1224                                      BusTransaction *transaction,
1225                                      DBusMessage    *message,
1226                                      DBusError      *error)
1227 {
1228   const char *text;
1229   const char *base_name;
1230   DBusString str;
1231   BusRegistry *registry;
1232   BusService *service;
1233   DBusMessage *reply;
1234 #ifdef ENABLE_KDBUS_TRANSPORT
1235   char unique_name[(unsigned int)(snprintf((char*)base_name, 0, "%llu", ULLONG_MAX) + sizeof(":1."))];
1236 #endif
1237
1238   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1239
1240   registry = bus_connection_get_registry (connection);
1241
1242   text = NULL;
1243   reply = NULL;
1244
1245   if (! dbus_message_get_args (message, error,
1246                                DBUS_TYPE_STRING, &text,
1247                                DBUS_TYPE_INVALID))
1248       goto failed;
1249
1250 #ifdef ENABLE_KDBUS_TRANSPORT
1251   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1252     {
1253       int ret;
1254
1255       ret = kdbus_get_name_owner(connection, text, unique_name);
1256       if(ret == 0)
1257         base_name = unique_name;
1258       else if(ret == -ENOENT)  //name has no owner
1259         {
1260           dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
1261                   "Could not get owner of name '%s': no such name", text);
1262           goto failed;
1263         }
1264       else
1265         {
1266           dbus_set_error (error, DBUS_ERROR_FAILED,
1267                   "Could not determine unique name for '%s'", text);
1268           goto failed;
1269         }
1270     }
1271   else
1272 #endif
1273     {
1274           _dbus_string_init_const (&str, text);
1275           service = bus_registry_lookup (registry, &str);
1276           if (service == NULL &&
1277                   _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1278                 {
1279                   /* ORG_FREEDESKTOP_DBUS owns itself */
1280                   base_name = DBUS_SERVICE_DBUS;
1281                 }
1282           else if (service == NULL)
1283                 {
1284                   dbus_set_error (error,
1285                                                   DBUS_ERROR_NAME_HAS_NO_OWNER,
1286                                                   "Could not get owner of name '%s': no such name", text);
1287                   goto failed;
1288                 }
1289           else
1290                 {
1291                   base_name = bus_connection_get_name (bus_service_get_primary_owners_connection (service));
1292                   if (base_name == NULL)
1293                         {
1294                           /* FIXME - how is this error possible? */
1295                           dbus_set_error (error,
1296                                                           DBUS_ERROR_FAILED,
1297                                                           "Could not determine unique name for '%s'", text);
1298                           goto failed;
1299                         }
1300                   _dbus_assert (*base_name == ':');
1301                 }
1302   }
1303   _dbus_assert (base_name != NULL);
1304
1305   reply = dbus_message_new_method_return (message);
1306   if (reply == NULL)
1307     goto oom;
1308
1309   if (! dbus_message_append_args (reply,
1310                                   DBUS_TYPE_STRING, &base_name,
1311                                   DBUS_TYPE_INVALID))
1312     goto oom;
1313
1314   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1315     goto oom;
1316
1317   dbus_message_unref (reply);
1318
1319   return TRUE;
1320
1321  oom:
1322   BUS_SET_OOM (error);
1323
1324  failed:
1325   _DBUS_ASSERT_ERROR_IS_SET (error);
1326   if (reply)
1327     dbus_message_unref (reply);
1328   return FALSE;
1329 }
1330
1331 static dbus_bool_t
1332 bus_driver_handle_list_queued_owners (DBusConnection *connection,
1333                                       BusTransaction *transaction,
1334                                       DBusMessage    *message,
1335                                       DBusError      *error)
1336 {
1337   const char *text;
1338   DBusList *base_names;
1339   DBusList *link;
1340   DBusString str;
1341   BusRegistry *registry;
1342   BusService *service;
1343   DBusMessage *reply;
1344   DBusMessageIter iter, array_iter;
1345   char *dbus_service_name = DBUS_SERVICE_DBUS;
1346
1347   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1348
1349   registry = bus_connection_get_registry (connection);
1350
1351   base_names = NULL;
1352   text = NULL;
1353   reply = NULL;
1354
1355   if (! dbus_message_get_args (message, error,
1356                                DBUS_TYPE_STRING, &text,
1357                                DBUS_TYPE_INVALID))
1358       goto failed;
1359
1360   _dbus_string_init_const (&str, text);
1361   service = bus_registry_lookup (registry, &str);
1362   if (service == NULL &&
1363       _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1364     {
1365       /* ORG_FREEDESKTOP_DBUS owns itself */
1366       if (! _dbus_list_append (&base_names, dbus_service_name))
1367         goto oom;
1368     }
1369 #ifdef ENABLE_KDBUS_TRANSPORT
1370   else if (!bus_context_is_kdbus(bus_transaction_get_context (transaction)) && (service == NULL))
1371 #else
1372   else if (service == NULL)
1373 #endif
1374     {
1375       dbus_set_error (error,
1376                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1377                       "Could not get owners of name '%s': no such name", text);
1378       goto failed;
1379     }
1380   else
1381     {
1382 #ifdef ENABLE_KDBUS_TRANSPORT
1383       if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1384         {
1385           if(!kdbus_list_queued (connection,  &base_names, text ,error))
1386             goto failed;
1387         }
1388       else
1389 #endif
1390         {
1391           if (!bus_service_list_queued_owners (service,
1392               &base_names,
1393               error))
1394             goto failed;
1395         }
1396     }
1397
1398   _dbus_assert (base_names != NULL);
1399
1400   reply = dbus_message_new_method_return (message);
1401   if (reply == NULL)
1402     goto oom;
1403
1404   dbus_message_iter_init_append (reply, &iter);
1405   if (!dbus_message_iter_open_container (&iter,
1406                                          DBUS_TYPE_ARRAY,
1407                                          DBUS_TYPE_STRING_AS_STRING,
1408                                          &array_iter))
1409     goto oom;
1410
1411   link = _dbus_list_get_first_link (&base_names);
1412   while (link != NULL)
1413     {
1414       char *uname;
1415
1416       _dbus_assert (link->data != NULL);
1417       uname = (char *)link->data;
1418
1419       if (!dbus_message_iter_append_basic (&array_iter,
1420                                            DBUS_TYPE_STRING,
1421                                            &uname))
1422         goto oom;
1423
1424       link = _dbus_list_get_next_link (&base_names, link);
1425     }
1426
1427   if (! dbus_message_iter_close_container (&iter, &array_iter))
1428     goto oom;
1429
1430
1431   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1432     goto oom;
1433
1434   dbus_message_unref (reply);
1435
1436   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1437     {
1438       link = _dbus_list_get_first_link (&base_names);
1439       while (link != NULL)
1440         {
1441           DBusList *next = _dbus_list_get_next_link (&base_names, link);
1442
1443           if(link->data != NULL)
1444             free(link->data);
1445
1446           _dbus_list_free_link (link);
1447           link = next;
1448         }
1449     }
1450
1451   return TRUE;
1452
1453  oom:
1454   BUS_SET_OOM (error);
1455
1456  failed:
1457   _DBUS_ASSERT_ERROR_IS_SET (error);
1458   if (reply)
1459     dbus_message_unref (reply);
1460   if (base_names)
1461     _dbus_list_clear (&base_names);
1462   return FALSE;
1463 }
1464
1465 static dbus_bool_t
1466 bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
1467                                             BusTransaction *transaction,
1468                                             DBusMessage    *message,
1469                                             DBusError      *error)
1470 {
1471   DBusConnection *conn;
1472   DBusMessage *reply;
1473   unsigned long uid;
1474   dbus_uint32_t uid32;
1475   const char *service;
1476
1477   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1478
1479   reply = dbus_message_new_method_return (message);
1480   if (reply == NULL)
1481     goto oom;
1482
1483 #ifdef ENABLE_KDBUS_TRANSPORT
1484   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1485   {
1486           const char* name;
1487
1488           if(!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
1489                   goto failed;
1490           if(!kdbus_get_unix_user(connection, name, &uid, error))
1491                   goto failed;
1492   }
1493   else
1494 #endif
1495   {
1496           conn = bus_driver_get_conn_helper (connection, message, "UID", &service,
1497                                      error);
1498
1499           if (conn == NULL)
1500                   goto failed;
1501
1502           if (!dbus_connection_get_unix_user (conn, &uid))
1503                 {
1504                   dbus_set_error (error,
1505                                                   DBUS_ERROR_FAILED,
1506                                                   "Could not determine UID for '%s'", service);
1507                   goto failed;
1508                 }
1509   }
1510
1511   uid32 = uid;
1512   if (! dbus_message_append_args (reply,
1513                                   DBUS_TYPE_UINT32, &uid32,
1514                                   DBUS_TYPE_INVALID))
1515     goto oom;
1516
1517   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1518     goto oom;
1519
1520   dbus_message_unref (reply);
1521
1522   return TRUE;
1523
1524  oom:
1525   BUS_SET_OOM (error);
1526
1527  failed:
1528   _DBUS_ASSERT_ERROR_IS_SET (error);
1529   if (reply)
1530     dbus_message_unref (reply);
1531   return FALSE;
1532 }
1533
1534 static dbus_bool_t
1535 bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
1536                                                   BusTransaction *transaction,
1537                                                   DBusMessage    *message,
1538                                                   DBusError      *error)
1539 {
1540   DBusConnection *conn;
1541   DBusMessage *reply;
1542   unsigned long pid;
1543   dbus_uint32_t pid32;
1544   const char *service;
1545
1546   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1547
1548   reply = dbus_message_new_method_return (message);
1549   if (reply == NULL)
1550     goto oom;
1551 #ifdef ENABLE_KDBUS_TRANSPORT
1552   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1553     {
1554       const char* name;
1555
1556       if(!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
1557         goto failed;
1558       if(!kdbus_get_connection_unix_process_id(connection, name, &pid, error))
1559         goto failed;
1560     }
1561     else
1562 #endif
1563   {
1564     conn = bus_driver_get_conn_helper (connection, message, "PID", &service,
1565                        error);
1566     if (conn == NULL)
1567       goto failed;
1568
1569     if (!dbus_connection_get_unix_process_id (conn, &pid))
1570     {
1571       dbus_set_error (error,
1572                 DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
1573                 "Could not determine PID for '%s'", service);
1574       goto failed;
1575     }
1576   }
1577
1578   pid32 = pid;
1579   if (! dbus_message_append_args (reply,
1580                                   DBUS_TYPE_UINT32, &pid32,
1581                                   DBUS_TYPE_INVALID))
1582     goto oom;
1583
1584   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1585     goto oom;
1586
1587   dbus_message_unref (reply);
1588
1589   return TRUE;
1590
1591  oom:
1592   BUS_SET_OOM (error);
1593
1594  failed:
1595   _DBUS_ASSERT_ERROR_IS_SET (error);
1596   if (reply)
1597     dbus_message_unref (reply);
1598   return FALSE;
1599 }
1600
1601 static dbus_bool_t
1602 bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection,
1603                                               BusTransaction *transaction,
1604                                               DBusMessage    *message,
1605                                               DBusError      *error)
1606 {
1607   DBusConnection *conn;
1608   DBusMessage *reply;
1609   void *data = NULL;
1610   dbus_uint32_t data_size;
1611   const char *service;
1612
1613   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1614
1615   reply = NULL;
1616
1617   conn = bus_driver_get_conn_helper (connection, message,
1618                                      "audit session data", &service, error);
1619
1620   if (conn == NULL)
1621     goto failed;
1622
1623   reply = dbus_message_new_method_return (message);
1624   if (reply == NULL)
1625     goto oom;
1626
1627   if (!dbus_connection_get_adt_audit_session_data (conn, &data, &data_size) || data == NULL)
1628     {
1629       dbus_set_error (error,
1630                       DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN,
1631                       "Could not determine audit session data for '%s'", service);
1632       goto failed;
1633     }
1634
1635   if (! dbus_message_append_args (reply,
1636                                   DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_size,
1637                                   DBUS_TYPE_INVALID))
1638     goto oom;
1639
1640   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1641     goto oom;
1642
1643   dbus_message_unref (reply);
1644
1645   return TRUE;
1646
1647  oom:
1648   BUS_SET_OOM (error);
1649
1650  failed:
1651   _DBUS_ASSERT_ERROR_IS_SET (error);
1652   if (reply)
1653     dbus_message_unref (reply);
1654   return FALSE;
1655 }
1656
1657 static dbus_bool_t
1658 bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection,
1659                                                            BusTransaction *transaction,
1660                                                            DBusMessage    *message,
1661                                                            DBusError      *error)
1662 {
1663   DBusConnection *conn;
1664   DBusMessage *reply;
1665   BusSELinuxID *context;
1666   const char *service;
1667
1668   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1669
1670   reply = dbus_message_new_method_return (message);
1671   if (reply == NULL)
1672     goto oom;
1673
1674 #ifdef ENABLE_KDBUS_TRANSPORT
1675   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1676   {
1677           if(!kdbus_get_connection_unix_selinux_security_context(connection, message, reply, error))
1678                   goto failed;
1679   }
1680   else
1681 #endif
1682   {
1683           conn = bus_driver_get_conn_helper (connection, message, "security context",
1684                                                                                  &service, error);
1685
1686           if (conn == NULL)
1687                 goto failed;
1688
1689           context = bus_connection_get_selinux_id (conn);
1690           if (!context)
1691                 {
1692                   dbus_set_error (error,
1693                                                   DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN,
1694                                                   "Could not determine security context for '%s'", service);
1695                   goto failed;
1696                 }
1697
1698           if (! bus_selinux_append_context (reply, context, error))
1699                 goto failed;
1700   }
1701
1702   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1703     goto oom;
1704
1705   dbus_message_unref (reply);
1706
1707   return TRUE;
1708
1709  oom:
1710   BUS_SET_OOM (error);
1711
1712  failed:
1713   _DBUS_ASSERT_ERROR_IS_SET (error);
1714   if (reply)
1715     dbus_message_unref (reply);
1716   return FALSE;
1717 }
1718
1719 static dbus_bool_t
1720 bus_driver_handle_get_connection_credentials (DBusConnection *connection,
1721                                               BusTransaction *transaction,
1722                                               DBusMessage    *message,
1723                                               DBusError      *error)
1724 {
1725   DBusConnection *conn;
1726   DBusMessage *reply;
1727   DBusMessageIter reply_iter;
1728   DBusMessageIter array_iter;
1729   unsigned long ulong_val;
1730   const char *service;
1731
1732   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1733
1734   reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter);
1735   if (reply == NULL)
1736     goto oom;
1737
1738 #ifdef ENABLE_KDBUS_TRANSPORT
1739   if(!bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1740   {
1741 #endif
1742           conn = bus_driver_get_conn_helper (connection, message, "credentials",
1743                                                                                  &service, error);
1744
1745           if (conn == NULL)
1746                 goto failed;
1747
1748           /* we can't represent > 32-bit pids; if your system needs them, please
1749            * add ProcessID64 to the spec or something */
1750           if (dbus_connection_get_unix_process_id (conn, &ulong_val) &&
1751                   ulong_val <= _DBUS_UINT32_MAX)
1752                 {
1753                   if (!_dbus_asv_add_uint32 (&array_iter, "ProcessID", ulong_val))
1754                         goto oom;
1755                 }
1756
1757           /* we can't represent > 32-bit uids; if your system needs them, please
1758            * add UnixUserID64 to the spec or something */
1759           if (dbus_connection_get_unix_user (conn, &ulong_val) &&
1760                   ulong_val <= _DBUS_UINT32_MAX)
1761                 {
1762                   if (!_dbus_asv_add_uint32 (&array_iter, "UnixUserID", ulong_val))
1763                         goto oom;
1764                 }
1765 #ifdef ENABLE_KDBUS_TRANSPORT
1766   }
1767   else
1768   {
1769           const char* name;
1770
1771           if(!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
1772                   goto failed;
1773           if(kdbus_get_connection_unix_process_id(connection, name, &ulong_val, error))
1774           {
1775                   if (!_dbus_asv_add_uint32 (&array_iter, "ProcessID", ulong_val))
1776                         goto oom;
1777           }
1778           else
1779                   goto failed;
1780
1781           if(kdbus_get_unix_user(connection, name, &ulong_val, error))
1782           {
1783                   if (!_dbus_asv_add_uint32 (&array_iter, "UnixUserID", ulong_val))
1784                         goto oom;
1785           }
1786           else
1787                   goto failed;
1788   }
1789 #endif
1790
1791   if (!_dbus_asv_close (&reply_iter, &array_iter))
1792     goto oom;
1793
1794   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1795     {
1796       /* this time we don't want to close the iterator again, so just
1797        * get rid of the message */
1798       dbus_message_unref (reply);
1799       reply = NULL;
1800       goto oom;
1801     }
1802
1803   return TRUE;
1804
1805  oom:
1806   BUS_SET_OOM (error);
1807
1808  failed:
1809   _DBUS_ASSERT_ERROR_IS_SET (error);
1810
1811   if (reply)
1812     {
1813       _dbus_asv_abandon (&reply_iter, &array_iter);
1814       dbus_message_unref (reply);
1815     }
1816
1817   return FALSE;
1818 }
1819
1820 static dbus_bool_t
1821 bus_driver_handle_reload_config (DBusConnection *connection,
1822                                  BusTransaction *transaction,
1823                                  DBusMessage    *message,
1824                                  DBusError      *error)
1825 {
1826   BusContext *context;
1827   DBusMessage *reply;
1828
1829   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1830
1831   reply = NULL;
1832
1833   context = bus_connection_get_context (connection);
1834   if (!bus_context_reload_config (context, error))
1835     goto failed;
1836
1837   reply = dbus_message_new_method_return (message);
1838   if (reply == NULL)
1839     goto oom;
1840
1841   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1842     goto oom;
1843
1844   dbus_message_unref (reply);
1845   return TRUE;
1846
1847  oom:
1848   BUS_SET_OOM (error);
1849
1850  failed:
1851   _DBUS_ASSERT_ERROR_IS_SET (error);
1852   if (reply)
1853     dbus_message_unref (reply);
1854   return FALSE;
1855 }
1856
1857 static dbus_bool_t
1858 bus_driver_handle_get_id (DBusConnection *connection,
1859                           BusTransaction *transaction,
1860                           DBusMessage    *message,
1861                           DBusError      *error)
1862 {
1863   BusContext *context;
1864   DBusMessage *reply;
1865   DBusString uuid;
1866   const char *v_STRING;
1867
1868   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1869
1870   if (!_dbus_string_init (&uuid))
1871     {
1872       BUS_SET_OOM (error);
1873       return FALSE;
1874     }
1875
1876   reply = NULL;
1877
1878   context = bus_connection_get_context (connection);
1879   if (!bus_context_get_id (context, &uuid))
1880     goto oom;
1881
1882   reply = dbus_message_new_method_return (message);
1883   if (reply == NULL)
1884     goto oom;
1885
1886   v_STRING = _dbus_string_get_const_data (&uuid);
1887   if (!dbus_message_append_args (reply,
1888                                  DBUS_TYPE_STRING, &v_STRING,
1889                                  DBUS_TYPE_INVALID))
1890     goto oom;
1891
1892   _dbus_assert (dbus_message_has_signature (reply, "s"));
1893
1894   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1895     goto oom;
1896
1897   _dbus_string_free (&uuid);
1898   dbus_message_unref (reply);
1899   return TRUE;
1900
1901  oom:
1902   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1903
1904   BUS_SET_OOM (error);
1905
1906   if (reply)
1907     dbus_message_unref (reply);
1908   _dbus_string_free (&uuid);
1909   return FALSE;
1910 }
1911
1912 typedef struct
1913 {
1914   const char *name;
1915   const char *in_args;
1916   const char *out_args;
1917   dbus_bool_t (* handler) (DBusConnection *connection,
1918                            BusTransaction *transaction,
1919                            DBusMessage    *message,
1920                            DBusError      *error);
1921 } MessageHandler;
1922
1923 /* For speed it might be useful to sort this in order of
1924  * frequency of use (but doesn't matter with only a few items
1925  * anyhow)
1926  */
1927 static const MessageHandler dbus_message_handlers[] = {
1928   { "Hello",
1929     "",
1930     DBUS_TYPE_STRING_AS_STRING,
1931     bus_driver_handle_hello },
1932   { "RequestName",
1933     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
1934     DBUS_TYPE_UINT32_AS_STRING,
1935     bus_driver_handle_acquire_service },
1936   { "ReleaseName",
1937     DBUS_TYPE_STRING_AS_STRING,
1938     DBUS_TYPE_UINT32_AS_STRING,
1939     bus_driver_handle_release_service },
1940   { "StartServiceByName",
1941     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
1942     DBUS_TYPE_UINT32_AS_STRING,
1943     bus_driver_handle_activate_service },
1944   { "UpdateActivationEnvironment",
1945     DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1946     "",
1947     bus_driver_handle_update_activation_environment },
1948   { "NameHasOwner",
1949     DBUS_TYPE_STRING_AS_STRING,
1950     DBUS_TYPE_BOOLEAN_AS_STRING,
1951     bus_driver_handle_service_exists },
1952   { "ListNames",
1953     "",
1954     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1955     bus_driver_handle_list_services },
1956   { "ListActivatableNames",
1957     "",
1958     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1959     bus_driver_handle_list_activatable_services },
1960   { "AddMatch",
1961     DBUS_TYPE_STRING_AS_STRING,
1962     "",
1963     bus_driver_handle_add_match },
1964   { "RemoveMatch",
1965     DBUS_TYPE_STRING_AS_STRING,
1966     "",
1967     bus_driver_handle_remove_match },
1968   { "GetNameOwner",
1969     DBUS_TYPE_STRING_AS_STRING,
1970     DBUS_TYPE_STRING_AS_STRING,
1971     bus_driver_handle_get_service_owner },
1972   { "ListQueuedOwners",
1973     DBUS_TYPE_STRING_AS_STRING,
1974     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1975     bus_driver_handle_list_queued_owners },
1976   { "GetConnectionUnixUser",
1977     DBUS_TYPE_STRING_AS_STRING,
1978     DBUS_TYPE_UINT32_AS_STRING,
1979     bus_driver_handle_get_connection_unix_user },
1980   { "GetConnectionUnixProcessID",
1981     DBUS_TYPE_STRING_AS_STRING,
1982     DBUS_TYPE_UINT32_AS_STRING,
1983     bus_driver_handle_get_connection_unix_process_id },
1984   { "GetAdtAuditSessionData",
1985     DBUS_TYPE_STRING_AS_STRING,
1986     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
1987     bus_driver_handle_get_adt_audit_session_data },
1988   { "GetConnectionSELinuxSecurityContext",
1989     DBUS_TYPE_STRING_AS_STRING,
1990     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
1991     bus_driver_handle_get_connection_selinux_security_context },
1992   { "ReloadConfig",
1993     "",
1994     "",
1995     bus_driver_handle_reload_config },
1996   { "GetId",
1997     "",
1998     DBUS_TYPE_STRING_AS_STRING,
1999     bus_driver_handle_get_id },
2000   { "GetConnectionCredentials", "s", "a{sv}",
2001     bus_driver_handle_get_connection_credentials },
2002   { NULL, NULL, NULL, NULL }
2003 };
2004
2005 static dbus_bool_t bus_driver_handle_introspect (DBusConnection *,
2006     BusTransaction *, DBusMessage *, DBusError *);
2007
2008 static const MessageHandler introspectable_message_handlers[] = {
2009   { "Introspect", "", DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_introspect },
2010   { NULL, NULL, NULL, NULL }
2011 };
2012
2013 #ifdef DBUS_ENABLE_STATS
2014 static const MessageHandler stats_message_handlers[] = {
2015   { "GetStats", "", "a{sv}", bus_stats_handle_get_stats },
2016   { "GetConnectionStats", "s", "a{sv}", bus_stats_handle_get_connection_stats },
2017   { NULL, NULL, NULL, NULL }
2018 };
2019 #endif
2020
2021 typedef struct {
2022   const char *name;
2023   const MessageHandler *message_handlers;
2024   const char *extra_introspection;
2025 } InterfaceHandler;
2026
2027 /* These should ideally be sorted by frequency of use, although it
2028  * probably doesn't matter with this few items */
2029 static InterfaceHandler interface_handlers[] = {
2030   { DBUS_INTERFACE_DBUS, dbus_message_handlers,
2031     "    <signal name=\"NameOwnerChanged\">\n"
2032     "      <arg type=\"s\"/>\n"
2033     "      <arg type=\"s\"/>\n"
2034     "      <arg type=\"s\"/>\n"
2035     "    </signal>\n"
2036     "    <signal name=\"NameLost\">\n"
2037     "      <arg type=\"s\"/>\n"
2038     "    </signal>\n"
2039     "    <signal name=\"NameAcquired\">\n"
2040     "      <arg type=\"s\"/>\n"
2041     "    </signal>\n" },
2042   { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL },
2043 #ifdef DBUS_ENABLE_STATS
2044   { BUS_INTERFACE_STATS, stats_message_handlers, NULL },
2045 #endif
2046   { NULL, NULL, NULL }
2047 };
2048
2049 static dbus_bool_t
2050 write_args_for_direction (DBusString *xml,
2051                           const char *signature,
2052                           dbus_bool_t in)
2053 {
2054   DBusTypeReader typereader;
2055   DBusString sigstr;
2056   int current_type;
2057
2058   _dbus_string_init_const (&sigstr, signature);
2059   _dbus_type_reader_init_types_only (&typereader, &sigstr, 0);
2060
2061   while ((current_type = _dbus_type_reader_get_current_type (&typereader)) != DBUS_TYPE_INVALID)
2062     {
2063       const DBusString *subsig;
2064       int start, len;
2065
2066       _dbus_type_reader_get_signature (&typereader, &subsig, &start, &len);
2067       if (!_dbus_string_append_printf (xml, "      <arg direction=\"%s\" type=\"",
2068                                        in ? "in" : "out"))
2069         goto oom;
2070       if (!_dbus_string_append_len (xml,
2071                                     _dbus_string_get_const_data (subsig) + start,
2072                                     len))
2073         goto oom;
2074       if (!_dbus_string_append (xml, "\"/>\n"))
2075         goto oom;
2076
2077       _dbus_type_reader_next (&typereader);
2078     }
2079   return TRUE;
2080  oom:
2081   return FALSE;
2082 }
2083
2084 dbus_bool_t
2085 bus_driver_generate_introspect_string (DBusString *xml)
2086 {
2087   const InterfaceHandler *ih;
2088   const MessageHandler *mh;
2089
2090   if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
2091     return FALSE;
2092   if (!_dbus_string_append (xml, "<node>\n"))
2093     return FALSE;
2094
2095   for (ih = interface_handlers; ih->name != NULL; ih++)
2096     {
2097       if (!_dbus_string_append_printf (xml, "  <interface name=\"%s\">\n",
2098                                        ih->name))
2099         return FALSE;
2100
2101       for (mh = ih->message_handlers; mh->name != NULL; mh++)
2102         {
2103           if (!_dbus_string_append_printf (xml, "    <method name=\"%s\">\n",
2104                                            mh->name))
2105             return FALSE;
2106
2107           if (!write_args_for_direction (xml, mh->in_args, TRUE))
2108             return FALSE;
2109
2110           if (!write_args_for_direction (xml, mh->out_args, FALSE))
2111             return FALSE;
2112
2113           if (!_dbus_string_append (xml, "    </method>\n"))
2114             return FALSE;
2115         }
2116
2117       if (ih->extra_introspection != NULL &&
2118           !_dbus_string_append (xml, ih->extra_introspection))
2119         return FALSE;
2120
2121       if (!_dbus_string_append (xml, "  </interface>\n"))
2122         return FALSE;
2123     }
2124
2125   if (!_dbus_string_append (xml, "</node>\n"))
2126     return FALSE;
2127
2128   return TRUE;
2129 }
2130
2131 static dbus_bool_t
2132 bus_driver_handle_introspect (DBusConnection *connection,
2133                               BusTransaction *transaction,
2134                               DBusMessage    *message,
2135                               DBusError      *error)
2136 {
2137   DBusString xml;
2138   DBusMessage *reply;
2139   const char *v_STRING;
2140
2141   _dbus_verbose ("Introspect() on bus driver\n");
2142
2143   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2144
2145   reply = NULL;
2146
2147   if (! dbus_message_get_args (message, error,
2148                                DBUS_TYPE_INVALID))
2149     {
2150       _DBUS_ASSERT_ERROR_IS_SET (error);
2151       return FALSE;
2152     }
2153
2154   if (!_dbus_string_init (&xml))
2155     {
2156       BUS_SET_OOM (error);
2157       return FALSE;
2158     }
2159
2160   if (!bus_driver_generate_introspect_string (&xml))
2161     goto oom;
2162
2163   v_STRING = _dbus_string_get_const_data (&xml);
2164
2165   reply = dbus_message_new_method_return (message);
2166   if (reply == NULL)
2167     goto oom;
2168
2169   if (! dbus_message_append_args (reply,
2170                                   DBUS_TYPE_STRING, &v_STRING,
2171                                   DBUS_TYPE_INVALID))
2172     goto oom;
2173
2174   if (! bus_transaction_send_from_driver (transaction, connection, reply))
2175     goto oom;
2176
2177   dbus_message_unref (reply);
2178   _dbus_string_free (&xml);
2179
2180   return TRUE;
2181
2182  oom:
2183   BUS_SET_OOM (error);
2184
2185   if (reply)
2186     dbus_message_unref (reply);
2187
2188   _dbus_string_free (&xml);
2189
2190   return FALSE;
2191 }
2192
2193 dbus_bool_t
2194 bus_driver_handle_message (DBusConnection *connection,
2195                            BusTransaction *transaction,
2196                            DBusMessage    *message,
2197                            DBusError      *error)
2198 {
2199   const char *name, *interface;
2200   const InterfaceHandler *ih;
2201   const MessageHandler *mh;
2202   dbus_bool_t found_interface = FALSE;
2203
2204   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2205
2206   if (dbus_message_is_signal (message, "org.freedesktop.systemd1.Activator", "ActivationFailure"))
2207     {
2208       BusContext *context;
2209
2210       context = bus_connection_get_context (connection);
2211       return dbus_activation_systemd_failure(bus_context_get_activation(context), message);
2212     }
2213
2214   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
2215     {
2216       _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
2217       return TRUE; /* we just ignore this */
2218     }
2219
2220   /* may be NULL, which means "any interface will do" */
2221   interface = dbus_message_get_interface (message);
2222
2223   _dbus_assert (dbus_message_get_member (message) != NULL);
2224
2225   name = dbus_message_get_member (message);
2226
2227   _dbus_verbose ("Driver got a method call: %s\n", name);
2228
2229   /* security checks should have kept this from getting here */
2230   _dbus_assert (dbus_message_get_sender (message) != NULL ||
2231                 strcmp (name, "Hello") == 0);
2232
2233   for (ih = interface_handlers; ih->name != NULL; ih++)
2234     {
2235       if (interface != NULL && strcmp (interface, ih->name) != 0)
2236         continue;
2237
2238       found_interface = TRUE;
2239
2240       for (mh = ih->message_handlers; mh->name != NULL; mh++)
2241         {
2242           if (strcmp (mh->name, name) != 0)
2243             continue;
2244
2245           _dbus_verbose ("Found driver handler for %s\n", name);
2246
2247           if (!dbus_message_has_signature (message, mh->in_args))
2248             {
2249               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2250               _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n",
2251                              name, dbus_message_get_signature (message),
2252                              mh->in_args);
2253
2254               dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2255                               "Call to %s has wrong args (%s, expected %s)\n",
2256                               name, dbus_message_get_signature (message),
2257                               mh->in_args);
2258               _DBUS_ASSERT_ERROR_IS_SET (error);
2259               return FALSE;
2260             }
2261
2262           if ((* mh->handler) (connection, transaction, message, error))
2263             {
2264               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2265               _dbus_verbose ("Driver handler succeeded\n");
2266               return TRUE;
2267             }
2268           else
2269             {
2270               _DBUS_ASSERT_ERROR_IS_SET (error);
2271               _dbus_verbose ("Driver handler returned failure\n");
2272               return FALSE;
2273             }
2274         }
2275     }
2276
2277   _dbus_verbose ("No driver handler for message \"%s\"\n",
2278                  name);
2279
2280   dbus_set_error (error, found_interface ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_INTERFACE,
2281                   "%s does not understand message %s",
2282                   DBUS_SERVICE_DBUS, name);
2283
2284   return FALSE;
2285 }
2286
2287 void
2288 bus_driver_remove_connection (DBusConnection *connection)
2289 {
2290   /* FIXME 1.0 Does nothing for now, should unregister the connection
2291    * with the bus driver.
2292    */
2293 }