[daemon-dev][lib-opt] Fix in freeing memory, cleanup, comments, renames
[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 #endif
50
51 static DBusConnection *
52 bus_driver_get_conn_helper (DBusConnection  *connection,
53                             DBusMessage     *message,
54                             const char      *what_we_want,
55                             const char     **name_p,
56                             DBusError       *error)
57 {
58   const char *name;
59   BusRegistry *registry;
60   BusService *serv;
61   DBusString str;
62   DBusConnection *conn;
63
64   if (!dbus_message_get_args (message, error,
65                               DBUS_TYPE_STRING, &name,
66                               DBUS_TYPE_INVALID))
67     return NULL;
68
69   _dbus_assert (name != NULL);
70   _dbus_verbose ("asked for %s of connection %s\n", what_we_want, name);
71
72   registry = bus_connection_get_registry (connection);
73   _dbus_string_init_const (&str, name);
74   serv = bus_registry_lookup (registry, &str);
75
76   if (serv == NULL)
77     {
78       dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
79                       "Could not get %s of name '%s': no such name",
80                       what_we_want, name);
81       return NULL;
82     }
83
84   conn = bus_service_get_primary_owners_connection (serv);
85   _dbus_assert (conn != NULL);
86
87   if (name_p != NULL)
88     *name_p = name;
89
90   return conn;
91 }
92
93 static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
94                                                     DBusMessage    *hello_message,
95                                                     BusTransaction *transaction,
96                                                     DBusError      *error);
97
98 dbus_bool_t
99 bus_driver_send_service_owner_changed (const char     *service_name,
100                                        const char     *old_owner,
101                                        const char     *new_owner,
102                                        BusTransaction *transaction,
103                                        DBusError      *error)
104 {
105   DBusMessage *message;
106   dbus_bool_t retval;
107   const char *null_service;
108
109 #ifdef ENABLE_KDBUS_TRANSPORT
110   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
111           return TRUE;
112 #endif
113
114   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
115
116   null_service = "";
117   _dbus_verbose ("sending name owner changed: %s [%s -> %s]\n",
118                  service_name,
119                  old_owner ? old_owner : null_service,
120                  new_owner ? new_owner : null_service);
121
122   message = dbus_message_new_signal (DBUS_PATH_DBUS,
123                                      DBUS_INTERFACE_DBUS,
124                                      "NameOwnerChanged");
125
126   if (message == NULL)
127     {
128       BUS_SET_OOM (error);
129       return FALSE;
130     }
131
132   if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
133     goto oom;
134
135   if (!dbus_message_append_args (message,
136                                  DBUS_TYPE_STRING, &service_name,
137                                  DBUS_TYPE_STRING, old_owner ? &old_owner : &null_service,
138                                  DBUS_TYPE_STRING, new_owner ? &new_owner : &null_service,
139                                  DBUS_TYPE_INVALID))
140     goto oom;
141
142   _dbus_assert (dbus_message_has_signature (message, "sss"));
143
144   retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
145   dbus_message_unref (message);
146
147   return retval;
148
149  oom:
150   dbus_message_unref (message);
151   BUS_SET_OOM (error);
152   return FALSE;
153 }
154
155 dbus_bool_t
156 bus_driver_send_service_lost (DBusConnection *connection,
157                               const char     *service_name,
158                               BusTransaction *transaction,
159                               DBusError      *error)
160 {
161   DBusMessage *message;
162
163 #ifdef ENABLE_KDBUS_TRANSPORT
164   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
165           return TRUE;
166 #endif
167
168   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
169
170   message = dbus_message_new_signal (DBUS_PATH_DBUS,
171                                      DBUS_INTERFACE_DBUS,
172                                      "NameLost");
173
174   if (message == NULL)
175     {
176       BUS_SET_OOM (error);
177       return FALSE;
178     }
179
180   if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
181       !dbus_message_append_args (message,
182                                  DBUS_TYPE_STRING, &service_name,
183                                  DBUS_TYPE_INVALID))
184     {
185       dbus_message_unref (message);
186       BUS_SET_OOM (error);
187       return FALSE;
188     }
189
190   if (!bus_transaction_send_from_driver (transaction, connection, message))
191     {
192       dbus_message_unref (message);
193       BUS_SET_OOM (error);
194       return FALSE;
195     }
196   else
197     {
198       dbus_message_unref (message);
199       return TRUE;
200     }
201 }
202
203 dbus_bool_t
204 bus_driver_send_service_acquired (DBusConnection *connection,
205                                   const char     *service_name,
206                                   BusTransaction *transaction,
207                                   DBusError      *error)
208 {
209   DBusMessage *message;
210
211 #ifdef ENABLE_KDBUS_TRANSPORT
212   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
213           return TRUE;
214 #endif
215
216   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
217
218   message = dbus_message_new_signal (DBUS_PATH_DBUS,
219                                      DBUS_INTERFACE_DBUS,
220                                      "NameAcquired");
221
222   if (message == NULL)
223     {
224       BUS_SET_OOM (error);
225       return FALSE;
226     }
227
228   if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
229       !dbus_message_append_args (message,
230                                  DBUS_TYPE_STRING, &service_name,
231                                  DBUS_TYPE_INVALID))
232     {
233       dbus_message_unref (message);
234       BUS_SET_OOM (error);
235       return FALSE;
236     }
237
238   if (!bus_transaction_send_from_driver (transaction, connection, message))
239     {
240       dbus_message_unref (message);
241       BUS_SET_OOM (error);
242       return FALSE;
243     }
244   else
245     {
246       dbus_message_unref (message);
247       return TRUE;
248     }
249 }
250
251 static dbus_bool_t
252 create_unique_client_name (BusRegistry *registry,
253                            DBusString  *str)
254 {
255   /* We never want to use the same unique client name twice, because
256    * we want to guarantee that if you send a message to a given unique
257    * name, you always get the same application. So we use two numbers
258    * for INT_MAX * INT_MAX combinations, should be pretty safe against
259    * wraparound.
260    */
261   /* FIXME these should be in BusRegistry rather than static vars */
262   static int next_major_number = 0;
263   static int next_minor_number = 0;
264   int len;
265
266   len = _dbus_string_get_length (str);
267
268   while (TRUE)
269     {
270       /* start out with 1-0, go to 1-1, 1-2, 1-3,
271        * up to 1-MAXINT, then 2-0, 2-1, etc.
272        */
273       if (next_minor_number <= 0)
274         {
275           next_major_number += 1;
276           next_minor_number = 0;
277           if (next_major_number <= 0)
278             _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
279         }
280
281       _dbus_assert (next_major_number > 0);
282       _dbus_assert (next_minor_number >= 0);
283
284       /* appname:MAJOR-MINOR */
285
286       if (!_dbus_string_append (str, ":"))
287         return FALSE;
288
289       if (!_dbus_string_append_int (str, next_major_number))
290         return FALSE;
291
292       if (!_dbus_string_append (str, "."))
293         return FALSE;
294
295       if (!_dbus_string_append_int (str, next_minor_number))
296         return FALSE;
297
298       next_minor_number += 1;
299
300       /* Check if a client with the name exists */
301       if (bus_registry_lookup (registry, str) == NULL)
302         break;
303
304       /* drop the number again, try the next one. */
305       _dbus_string_set_length (str, len);
306     }
307
308   return TRUE;
309 }
310
311 static dbus_bool_t
312 bus_driver_handle_hello (DBusConnection *connection,
313                          BusTransaction *transaction,
314                          DBusMessage    *message,
315                          DBusError      *error)
316 {
317   DBusString unique_name;
318   BusService *service;
319   dbus_bool_t retval;
320   BusRegistry *registry;
321   BusConnections *connections;
322
323   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
324
325   if (bus_connection_is_active (connection))
326     {
327       /* We already handled an Hello message for this connection. */
328       dbus_set_error (error, DBUS_ERROR_FAILED,
329                       "Already handled an Hello message");
330       return FALSE;
331     }
332
333   /* Note that when these limits are exceeded we don't disconnect the
334    * connection; we just sort of leave it hanging there until it times
335    * out or disconnects itself or is dropped due to the max number of
336    * incomplete connections. It's even OK if the connection wants to
337    * retry the hello message, we support that.
338    */
339   connections = bus_connection_get_connections (connection);
340   if (!bus_connections_check_limits (connections, connection,
341                                      error))
342     {
343       _DBUS_ASSERT_ERROR_IS_SET (error);
344       return FALSE;
345     }
346
347   if (!_dbus_string_init (&unique_name))
348     {
349       BUS_SET_OOM (error);
350       return FALSE;
351     }
352
353   retval = FALSE;
354
355   registry = bus_connection_get_registry (connection);
356
357   if (!create_unique_client_name (registry, &unique_name))
358     {
359       BUS_SET_OOM (error);
360       goto out_0;
361     }
362
363   if (!bus_connection_complete (connection, &unique_name, error))
364     {
365       _DBUS_ASSERT_ERROR_IS_SET (error);
366       goto out_0;
367     }
368
369   if (!dbus_message_set_sender (message,
370                                 bus_connection_get_name (connection)))
371     {
372       BUS_SET_OOM (error);
373       goto out_0;
374     }
375
376   if (!bus_driver_send_welcome_message (connection, message, transaction, error))
377     goto out_0;
378
379   /* Create the service */
380   service = bus_registry_ensure (registry,
381                                  &unique_name, connection, 0, transaction, error);
382   if (service == NULL)
383     goto out_0;
384
385   _dbus_assert (bus_connection_is_active (connection));
386   retval = TRUE;
387
388  out_0:
389   _dbus_string_free (&unique_name);
390   return retval;
391 }
392
393 static dbus_bool_t
394 bus_driver_send_welcome_message (DBusConnection *connection,
395                                  DBusMessage    *hello_message,
396                                  BusTransaction *transaction,
397                                  DBusError      *error)
398 {
399   DBusMessage *welcome;
400   const char *name;
401
402   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
403
404   name = bus_connection_get_name (connection);
405   _dbus_assert (name != NULL);
406
407   welcome = dbus_message_new_method_return (hello_message);
408   if (welcome == NULL)
409     {
410       BUS_SET_OOM (error);
411       return FALSE;
412     }
413
414   if (!dbus_message_append_args (welcome,
415                                  DBUS_TYPE_STRING, &name,
416                                  DBUS_TYPE_INVALID))
417     {
418       dbus_message_unref (welcome);
419       BUS_SET_OOM (error);
420       return FALSE;
421     }
422
423   _dbus_assert (dbus_message_has_signature (welcome, DBUS_TYPE_STRING_AS_STRING));
424
425   if (!bus_transaction_send_from_driver (transaction, connection, welcome))
426     {
427       dbus_message_unref (welcome);
428       BUS_SET_OOM (error);
429       return FALSE;
430     }
431   else
432     {
433       dbus_message_unref (welcome);
434       return TRUE;
435     }
436 }
437
438 static dbus_bool_t
439 bus_driver_handle_list_services (DBusConnection *connection,
440                                  BusTransaction *transaction,
441                                  DBusMessage    *message,
442                                  DBusError      *error)
443 {
444   DBusMessage *reply;
445   int len;
446   char **services;
447   BusRegistry *registry;
448   int i;
449   DBusMessageIter iter;
450   DBusMessageIter sub;
451
452   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
453
454   registry = bus_connection_get_registry (connection);
455
456   reply = dbus_message_new_method_return (message);
457   if (reply == NULL)
458     {
459       BUS_SET_OOM (error);
460       return FALSE;
461     }
462
463 #ifdef ENABLE_KDBUS_TRANSPORT
464   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
465   {
466           if(!kdbus_list_services (connection, &services, &len))
467             {
468               dbus_message_unref (reply);
469               BUS_SET_OOM (error);
470               return FALSE;
471             }
472   }
473   else
474 #endif
475   {
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
1235   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1236
1237   registry = bus_connection_get_registry (connection);
1238
1239   text = NULL;
1240   reply = NULL;
1241
1242   if (! dbus_message_get_args (message, error,
1243                                DBUS_TYPE_STRING, &text,
1244                                DBUS_TYPE_INVALID))
1245       goto failed;
1246
1247 #ifdef ENABLE_KDBUS_TRANSPORT
1248   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1249   {
1250           int ret;
1251           struct nameInfo info;
1252           char unique_name[(unsigned int)(snprintf((char*)base_name, 0, "%llu", ULLONG_MAX) + sizeof(":1."))];
1253
1254           ret = kdbus_NameQuery(text, dbus_connection_get_transport(connection), &info);
1255                 if(ret == 0) //unique id of the name
1256                 {
1257                         sprintf(unique_name, ":1.%llu", (unsigned long long int)info.uniqueId);
1258                         _dbus_verbose("Unique name discovered:%s\n", unique_name);
1259                         base_name = unique_name;
1260                 }
1261                 else if(ret == -ENOENT)  //name has no owner
1262                 {
1263                           dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
1264                                                           "Could not get owner of name '%s': no such name", text);
1265                           goto failed;
1266                 }
1267                 else
1268                 {
1269                         _dbus_verbose("kdbus error sending name query: err %d (%m)\n", errno);
1270                         dbus_set_error (error, DBUS_ERROR_FAILED,
1271                                                           "Could not determine unique name for '%s'", text);
1272                         goto failed;
1273                 }
1274   }
1275   else
1276 #endif
1277     {
1278           _dbus_string_init_const (&str, text);
1279           service = bus_registry_lookup (registry, &str);
1280           if (service == NULL &&
1281                   _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1282                 {
1283                   /* ORG_FREEDESKTOP_DBUS owns itself */
1284                   base_name = DBUS_SERVICE_DBUS;
1285                 }
1286           else if (service == NULL)
1287                 {
1288                   dbus_set_error (error,
1289                                                   DBUS_ERROR_NAME_HAS_NO_OWNER,
1290                                                   "Could not get owner of name '%s': no such name", text);
1291                   goto failed;
1292                 }
1293           else
1294                 {
1295                   base_name = bus_connection_get_name (bus_service_get_primary_owners_connection (service));
1296                   if (base_name == NULL)
1297                         {
1298                           /* FIXME - how is this error possible? */
1299                           dbus_set_error (error,
1300                                                           DBUS_ERROR_FAILED,
1301                                                           "Could not determine unique name for '%s'", text);
1302                           goto failed;
1303                         }
1304                   _dbus_assert (*base_name == ':');
1305                 }
1306   }
1307   _dbus_assert (base_name != NULL);
1308
1309   reply = dbus_message_new_method_return (message);
1310   if (reply == NULL)
1311     goto oom;
1312
1313   if (! dbus_message_append_args (reply,
1314                                   DBUS_TYPE_STRING, &base_name,
1315                                   DBUS_TYPE_INVALID))
1316     goto oom;
1317
1318   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1319     goto oom;
1320
1321   dbus_message_unref (reply);
1322
1323   return TRUE;
1324
1325  oom:
1326   BUS_SET_OOM (error);
1327
1328  failed:
1329   _DBUS_ASSERT_ERROR_IS_SET (error);
1330   if (reply)
1331     dbus_message_unref (reply);
1332   return FALSE;
1333 }
1334
1335 static dbus_bool_t
1336 bus_driver_handle_list_queued_owners (DBusConnection *connection,
1337                                       BusTransaction *transaction,
1338                                       DBusMessage    *message,
1339                                       DBusError      *error)
1340 {
1341   const char *text;
1342   DBusList *base_names;
1343   DBusList *link;
1344   DBusString str;
1345   BusRegistry *registry;
1346   BusService *service;
1347   DBusMessage *reply;
1348   DBusMessageIter iter, array_iter;
1349   char *dbus_service_name = DBUS_SERVICE_DBUS;
1350
1351   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1352
1353   registry = bus_connection_get_registry (connection);
1354
1355   base_names = NULL;
1356   text = NULL;
1357   reply = NULL;
1358
1359   if (! dbus_message_get_args (message, error,
1360                                DBUS_TYPE_STRING, &text,
1361                                DBUS_TYPE_INVALID))
1362       goto failed;
1363
1364   _dbus_string_init_const (&str, text);
1365   service = bus_registry_lookup (registry, &str);
1366   if (service == NULL &&
1367       _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1368     {
1369       /* ORG_FREEDESKTOP_DBUS owns itself */
1370       if (! _dbus_list_append (&base_names, dbus_service_name))
1371         goto oom;
1372     }
1373   else if (service == NULL)
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       if (!bus_service_list_queued_owners (service,
1383                                            &base_names,
1384                                            error))
1385         goto failed;
1386     }
1387
1388   _dbus_assert (base_names != NULL);
1389
1390   reply = dbus_message_new_method_return (message);
1391   if (reply == NULL)
1392     goto oom;
1393
1394   dbus_message_iter_init_append (reply, &iter);
1395   if (!dbus_message_iter_open_container (&iter,
1396                                          DBUS_TYPE_ARRAY,
1397                                          DBUS_TYPE_STRING_AS_STRING,
1398                                          &array_iter))
1399     goto oom;
1400
1401   link = _dbus_list_get_first_link (&base_names);
1402   while (link != NULL)
1403     {
1404       char *uname;
1405
1406       _dbus_assert (link->data != NULL);
1407       uname = (char *)link->data;
1408
1409       if (!dbus_message_iter_append_basic (&array_iter,
1410                                            DBUS_TYPE_STRING,
1411                                            &uname))
1412         goto oom;
1413
1414       link = _dbus_list_get_next_link (&base_names, link);
1415     }
1416
1417   if (! dbus_message_iter_close_container (&iter, &array_iter))
1418     goto oom;
1419
1420
1421   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1422     goto oom;
1423
1424   dbus_message_unref (reply);
1425
1426   return TRUE;
1427
1428  oom:
1429   BUS_SET_OOM (error);
1430
1431  failed:
1432   _DBUS_ASSERT_ERROR_IS_SET (error);
1433   if (reply)
1434     dbus_message_unref (reply);
1435
1436   if (base_names)
1437     _dbus_list_clear (&base_names);
1438
1439   return FALSE;
1440 }
1441
1442 static dbus_bool_t
1443 bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
1444                                             BusTransaction *transaction,
1445                                             DBusMessage    *message,
1446                                             DBusError      *error)
1447 {
1448   DBusConnection *conn;
1449   DBusMessage *reply;
1450   unsigned long uid;
1451   dbus_uint32_t uid32;
1452   const char *service;
1453
1454   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1455
1456   reply = dbus_message_new_method_return (message);
1457   if (reply == NULL)
1458     goto oom;
1459
1460 #ifdef ENABLE_KDBUS_TRANSPORT
1461   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1462   {
1463           if(!kdbus_get_connection_unix_user(connection, message, &uid, error))
1464                   goto failed;
1465   }
1466   else
1467 #endif
1468   {
1469           conn = bus_driver_get_conn_helper (connection, message, "UID", &service,
1470                                      error);
1471
1472           if (conn == NULL)
1473                   goto failed;
1474
1475           if (!dbus_connection_get_unix_user (conn, &uid))
1476                 {
1477                   dbus_set_error (error,
1478                                                   DBUS_ERROR_FAILED,
1479                                                   "Could not determine UID for '%s'", service);
1480                   goto failed;
1481                 }
1482   }
1483
1484   uid32 = uid;
1485   if (! dbus_message_append_args (reply,
1486                                   DBUS_TYPE_UINT32, &uid32,
1487                                   DBUS_TYPE_INVALID))
1488     goto oom;
1489
1490   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1491     goto oom;
1492
1493   dbus_message_unref (reply);
1494
1495   return TRUE;
1496
1497  oom:
1498   BUS_SET_OOM (error);
1499
1500  failed:
1501   _DBUS_ASSERT_ERROR_IS_SET (error);
1502   if (reply)
1503     dbus_message_unref (reply);
1504   return FALSE;
1505 }
1506
1507 static dbus_bool_t
1508 bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
1509                                                   BusTransaction *transaction,
1510                                                   DBusMessage    *message,
1511                                                   DBusError      *error)
1512 {
1513   DBusConnection *conn;
1514   DBusMessage *reply;
1515   unsigned long pid;
1516   dbus_uint32_t pid32;
1517   const char *service;
1518
1519   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1520
1521   reply = dbus_message_new_method_return (message);
1522   if (reply == NULL)
1523     goto oom;
1524
1525 #ifdef ENABLE_KDBUS_TRANSPORT
1526   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1527   {
1528           if(!kdbus_get_connection_unix_process_id(connection, message, &pid, error))
1529                   goto failed;
1530   }
1531   else
1532 #endif
1533   {
1534           conn = bus_driver_get_conn_helper (connection, message, "PID", &service,
1535                                                                                  error);
1536
1537           if (conn == NULL)
1538                 goto failed;
1539
1540
1541
1542           if (!dbus_connection_get_unix_process_id (conn, &pid))
1543                 {
1544                   dbus_set_error (error,
1545                                                   DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
1546                                                   "Could not determine PID for '%s'", service);
1547                   goto failed;
1548                 }
1549   }
1550
1551   pid32 = pid;
1552   if (! dbus_message_append_args (reply,
1553                                   DBUS_TYPE_UINT32, &pid32,
1554                                   DBUS_TYPE_INVALID))
1555     goto oom;
1556
1557   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1558     goto oom;
1559
1560   dbus_message_unref (reply);
1561
1562   return TRUE;
1563
1564  oom:
1565   BUS_SET_OOM (error);
1566
1567  failed:
1568   _DBUS_ASSERT_ERROR_IS_SET (error);
1569   if (reply)
1570     dbus_message_unref (reply);
1571   return FALSE;
1572 }
1573
1574 static dbus_bool_t
1575 bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection,
1576                                               BusTransaction *transaction,
1577                                               DBusMessage    *message,
1578                                               DBusError      *error)
1579 {
1580   DBusConnection *conn;
1581   DBusMessage *reply;
1582   void *data = NULL;
1583   dbus_uint32_t data_size;
1584   const char *service;
1585
1586   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1587
1588   reply = NULL;
1589
1590   conn = bus_driver_get_conn_helper (connection, message,
1591                                      "audit session data", &service, error);
1592
1593   if (conn == NULL)
1594     goto failed;
1595
1596   reply = dbus_message_new_method_return (message);
1597   if (reply == NULL)
1598     goto oom;
1599
1600   if (!dbus_connection_get_adt_audit_session_data (conn, &data, &data_size) || data == NULL)
1601     {
1602       dbus_set_error (error,
1603                       DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN,
1604                       "Could not determine audit session data for '%s'", service);
1605       goto failed;
1606     }
1607
1608   if (! dbus_message_append_args (reply,
1609                                   DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_size,
1610                                   DBUS_TYPE_INVALID))
1611     goto oom;
1612
1613   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1614     goto oom;
1615
1616   dbus_message_unref (reply);
1617
1618   return TRUE;
1619
1620  oom:
1621   BUS_SET_OOM (error);
1622
1623  failed:
1624   _DBUS_ASSERT_ERROR_IS_SET (error);
1625   if (reply)
1626     dbus_message_unref (reply);
1627   return FALSE;
1628 }
1629
1630 static dbus_bool_t
1631 bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection,
1632                                                            BusTransaction *transaction,
1633                                                            DBusMessage    *message,
1634                                                            DBusError      *error)
1635 {
1636   DBusConnection *conn;
1637   DBusMessage *reply;
1638   BusSELinuxID *context;
1639   const char *service;
1640
1641   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1642
1643   reply = dbus_message_new_method_return (message);
1644   if (reply == NULL)
1645     goto oom;
1646
1647 #ifdef ENABLE_KDBUS_TRANSPORT
1648   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1649   {
1650           if(!kdbus_get_connection_unix_selinux_security_context(connection, message, reply, error))
1651                   goto failed;
1652   }
1653   else
1654 #endif
1655   {
1656           conn = bus_driver_get_conn_helper (connection, message, "security context",
1657                                                                                  &service, error);
1658
1659           if (conn == NULL)
1660                 goto failed;
1661
1662           context = bus_connection_get_selinux_id (conn);
1663           if (!context)
1664                 {
1665                   dbus_set_error (error,
1666                                                   DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN,
1667                                                   "Could not determine security context for '%s'", service);
1668                   goto failed;
1669                 }
1670
1671           if (! bus_selinux_append_context (reply, context, error))
1672                 goto failed;
1673   }
1674
1675   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1676     goto oom;
1677
1678   dbus_message_unref (reply);
1679
1680   return TRUE;
1681
1682  oom:
1683   BUS_SET_OOM (error);
1684
1685  failed:
1686   _DBUS_ASSERT_ERROR_IS_SET (error);
1687   if (reply)
1688     dbus_message_unref (reply);
1689   return FALSE;
1690 }
1691
1692 static dbus_bool_t
1693 bus_driver_handle_get_connection_credentials (DBusConnection *connection,
1694                                               BusTransaction *transaction,
1695                                               DBusMessage    *message,
1696                                               DBusError      *error)
1697 {
1698   DBusConnection *conn;
1699   DBusMessage *reply;
1700   DBusMessageIter reply_iter;
1701   DBusMessageIter array_iter;
1702   unsigned long ulong_val;
1703   const char *service;
1704
1705   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1706
1707   reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter);
1708   if (reply == NULL)
1709     goto oom;
1710
1711 #ifdef ENABLE_KDBUS_TRANSPORT
1712   if(!bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1713   {
1714 #endif
1715           conn = bus_driver_get_conn_helper (connection, message, "credentials",
1716                                                                                  &service, error);
1717
1718           if (conn == NULL)
1719                 goto failed;
1720
1721           /* we can't represent > 32-bit pids; if your system needs them, please
1722            * add ProcessID64 to the spec or something */
1723           if (dbus_connection_get_unix_process_id (conn, &ulong_val) &&
1724                   ulong_val <= _DBUS_UINT32_MAX)
1725                 {
1726                   if (!_dbus_asv_add_uint32 (&array_iter, "ProcessID", ulong_val))
1727                         goto oom;
1728                 }
1729
1730           /* we can't represent > 32-bit uids; if your system needs them, please
1731            * add UnixUserID64 to the spec or something */
1732           if (dbus_connection_get_unix_user (conn, &ulong_val) &&
1733                   ulong_val <= _DBUS_UINT32_MAX)
1734                 {
1735                   if (!_dbus_asv_add_uint32 (&array_iter, "UnixUserID", ulong_val))
1736                         goto oom;
1737                 }
1738 #ifdef ENABLE_KDBUS_TRANSPORT
1739   }
1740   else
1741   {
1742           if(kdbus_get_connection_unix_process_id(connection, message, &ulong_val, error))
1743           {
1744                   if (!_dbus_asv_add_uint32 (&array_iter, "ProcessID", ulong_val))
1745                         goto oom;
1746           }
1747           else
1748                   goto failed;
1749
1750           if(kdbus_get_connection_unix_user(connection, message, &ulong_val, error))
1751           {
1752                   if (!_dbus_asv_add_uint32 (&array_iter, "UnixUserID", ulong_val))
1753                         goto oom;
1754           }
1755           else
1756                   goto failed;
1757   }
1758 #endif
1759
1760   if (!_dbus_asv_close (&reply_iter, &array_iter))
1761     goto oom;
1762
1763   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1764     {
1765       /* this time we don't want to close the iterator again, so just
1766        * get rid of the message */
1767       dbus_message_unref (reply);
1768       reply = NULL;
1769       goto oom;
1770     }
1771
1772   return TRUE;
1773
1774  oom:
1775   BUS_SET_OOM (error);
1776
1777  failed:
1778   _DBUS_ASSERT_ERROR_IS_SET (error);
1779
1780   if (reply)
1781     {
1782       _dbus_asv_abandon (&reply_iter, &array_iter);
1783       dbus_message_unref (reply);
1784     }
1785
1786   return FALSE;
1787 }
1788
1789 static dbus_bool_t
1790 bus_driver_handle_reload_config (DBusConnection *connection,
1791                                  BusTransaction *transaction,
1792                                  DBusMessage    *message,
1793                                  DBusError      *error)
1794 {
1795   BusContext *context;
1796   DBusMessage *reply;
1797
1798   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1799
1800   reply = NULL;
1801
1802   context = bus_connection_get_context (connection);
1803   if (!bus_context_reload_config (context, error))
1804     goto failed;
1805
1806   reply = dbus_message_new_method_return (message);
1807   if (reply == NULL)
1808     goto oom;
1809
1810   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1811     goto oom;
1812
1813   dbus_message_unref (reply);
1814   return TRUE;
1815
1816  oom:
1817   BUS_SET_OOM (error);
1818
1819  failed:
1820   _DBUS_ASSERT_ERROR_IS_SET (error);
1821   if (reply)
1822     dbus_message_unref (reply);
1823   return FALSE;
1824 }
1825
1826 static dbus_bool_t
1827 bus_driver_handle_get_id (DBusConnection *connection,
1828                           BusTransaction *transaction,
1829                           DBusMessage    *message,
1830                           DBusError      *error)
1831 {
1832   BusContext *context;
1833   DBusMessage *reply;
1834   DBusString uuid;
1835   const char *v_STRING;
1836
1837   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1838
1839   if (!_dbus_string_init (&uuid))
1840     {
1841       BUS_SET_OOM (error);
1842       return FALSE;
1843     }
1844
1845   reply = NULL;
1846
1847   context = bus_connection_get_context (connection);
1848   if (!bus_context_get_id (context, &uuid))
1849     goto oom;
1850
1851   reply = dbus_message_new_method_return (message);
1852   if (reply == NULL)
1853     goto oom;
1854
1855   v_STRING = _dbus_string_get_const_data (&uuid);
1856   if (!dbus_message_append_args (reply,
1857                                  DBUS_TYPE_STRING, &v_STRING,
1858                                  DBUS_TYPE_INVALID))
1859     goto oom;
1860
1861   _dbus_assert (dbus_message_has_signature (reply, "s"));
1862
1863   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1864     goto oom;
1865
1866   _dbus_string_free (&uuid);
1867   dbus_message_unref (reply);
1868   return TRUE;
1869
1870  oom:
1871   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1872
1873   BUS_SET_OOM (error);
1874
1875   if (reply)
1876     dbus_message_unref (reply);
1877   _dbus_string_free (&uuid);
1878   return FALSE;
1879 }
1880
1881 typedef struct
1882 {
1883   const char *name;
1884   const char *in_args;
1885   const char *out_args;
1886   dbus_bool_t (* handler) (DBusConnection *connection,
1887                            BusTransaction *transaction,
1888                            DBusMessage    *message,
1889                            DBusError      *error);
1890 } MessageHandler;
1891
1892 /* For speed it might be useful to sort this in order of
1893  * frequency of use (but doesn't matter with only a few items
1894  * anyhow)
1895  */
1896 static const MessageHandler dbus_message_handlers[] = {
1897   { "Hello",
1898     "",
1899     DBUS_TYPE_STRING_AS_STRING,
1900     bus_driver_handle_hello },
1901   { "RequestName",
1902     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
1903     DBUS_TYPE_UINT32_AS_STRING,
1904     bus_driver_handle_acquire_service },
1905   { "ReleaseName",
1906     DBUS_TYPE_STRING_AS_STRING,
1907     DBUS_TYPE_UINT32_AS_STRING,
1908     bus_driver_handle_release_service },
1909   { "StartServiceByName",
1910     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
1911     DBUS_TYPE_UINT32_AS_STRING,
1912     bus_driver_handle_activate_service },
1913   { "UpdateActivationEnvironment",
1914     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,
1915     "",
1916     bus_driver_handle_update_activation_environment },
1917   { "NameHasOwner",
1918     DBUS_TYPE_STRING_AS_STRING,
1919     DBUS_TYPE_BOOLEAN_AS_STRING,
1920     bus_driver_handle_service_exists },
1921   { "ListNames",
1922     "",
1923     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1924     bus_driver_handle_list_services },
1925   { "ListActivatableNames",
1926     "",
1927     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1928     bus_driver_handle_list_activatable_services },
1929   { "AddMatch",
1930     DBUS_TYPE_STRING_AS_STRING,
1931     "",
1932     bus_driver_handle_add_match },
1933   { "RemoveMatch",
1934     DBUS_TYPE_STRING_AS_STRING,
1935     "",
1936     bus_driver_handle_remove_match },
1937   { "GetNameOwner",
1938     DBUS_TYPE_STRING_AS_STRING,
1939     DBUS_TYPE_STRING_AS_STRING,
1940     bus_driver_handle_get_service_owner },
1941   { "ListQueuedOwners",
1942     DBUS_TYPE_STRING_AS_STRING,
1943     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1944     bus_driver_handle_list_queued_owners },
1945   { "GetConnectionUnixUser",
1946     DBUS_TYPE_STRING_AS_STRING,
1947     DBUS_TYPE_UINT32_AS_STRING,
1948     bus_driver_handle_get_connection_unix_user },
1949   { "GetConnectionUnixProcessID",
1950     DBUS_TYPE_STRING_AS_STRING,
1951     DBUS_TYPE_UINT32_AS_STRING,
1952     bus_driver_handle_get_connection_unix_process_id },
1953   { "GetAdtAuditSessionData",
1954     DBUS_TYPE_STRING_AS_STRING,
1955     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
1956     bus_driver_handle_get_adt_audit_session_data },
1957   { "GetConnectionSELinuxSecurityContext",
1958     DBUS_TYPE_STRING_AS_STRING,
1959     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
1960     bus_driver_handle_get_connection_selinux_security_context },
1961   { "ReloadConfig",
1962     "",
1963     "",
1964     bus_driver_handle_reload_config },
1965   { "GetId",
1966     "",
1967     DBUS_TYPE_STRING_AS_STRING,
1968     bus_driver_handle_get_id },
1969   { "GetConnectionCredentials", "s", "a{sv}",
1970     bus_driver_handle_get_connection_credentials },
1971   { NULL, NULL, NULL, NULL }
1972 };
1973
1974 static dbus_bool_t bus_driver_handle_introspect (DBusConnection *,
1975     BusTransaction *, DBusMessage *, DBusError *);
1976
1977 static const MessageHandler introspectable_message_handlers[] = {
1978   { "Introspect", "", DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_introspect },
1979   { NULL, NULL, NULL, NULL }
1980 };
1981
1982 #ifdef DBUS_ENABLE_STATS
1983 static const MessageHandler stats_message_handlers[] = {
1984   { "GetStats", "", "a{sv}", bus_stats_handle_get_stats },
1985   { "GetConnectionStats", "s", "a{sv}", bus_stats_handle_get_connection_stats },
1986   { NULL, NULL, NULL, NULL }
1987 };
1988 #endif
1989
1990 typedef struct {
1991   const char *name;
1992   const MessageHandler *message_handlers;
1993   const char *extra_introspection;
1994 } InterfaceHandler;
1995
1996 /* These should ideally be sorted by frequency of use, although it
1997  * probably doesn't matter with this few items */
1998 static InterfaceHandler interface_handlers[] = {
1999   { DBUS_INTERFACE_DBUS, dbus_message_handlers,
2000     "    <signal name=\"NameOwnerChanged\">\n"
2001     "      <arg type=\"s\"/>\n"
2002     "      <arg type=\"s\"/>\n"
2003     "      <arg type=\"s\"/>\n"
2004     "    </signal>\n"
2005     "    <signal name=\"NameLost\">\n"
2006     "      <arg type=\"s\"/>\n"
2007     "    </signal>\n"
2008     "    <signal name=\"NameAcquired\">\n"
2009     "      <arg type=\"s\"/>\n"
2010     "    </signal>\n" },
2011   { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL },
2012 #ifdef DBUS_ENABLE_STATS
2013   { BUS_INTERFACE_STATS, stats_message_handlers, NULL },
2014 #endif
2015   { NULL, NULL, NULL }
2016 };
2017
2018 static dbus_bool_t
2019 write_args_for_direction (DBusString *xml,
2020                           const char *signature,
2021                           dbus_bool_t in)
2022 {
2023   DBusTypeReader typereader;
2024   DBusString sigstr;
2025   int current_type;
2026
2027   _dbus_string_init_const (&sigstr, signature);
2028   _dbus_type_reader_init_types_only (&typereader, &sigstr, 0);
2029
2030   while ((current_type = _dbus_type_reader_get_current_type (&typereader)) != DBUS_TYPE_INVALID)
2031     {
2032       const DBusString *subsig;
2033       int start, len;
2034
2035       _dbus_type_reader_get_signature (&typereader, &subsig, &start, &len);
2036       if (!_dbus_string_append_printf (xml, "      <arg direction=\"%s\" type=\"",
2037                                        in ? "in" : "out"))
2038         goto oom;
2039       if (!_dbus_string_append_len (xml,
2040                                     _dbus_string_get_const_data (subsig) + start,
2041                                     len))
2042         goto oom;
2043       if (!_dbus_string_append (xml, "\"/>\n"))
2044         goto oom;
2045
2046       _dbus_type_reader_next (&typereader);
2047     }
2048   return TRUE;
2049  oom:
2050   return FALSE;
2051 }
2052
2053 dbus_bool_t
2054 bus_driver_generate_introspect_string (DBusString *xml)
2055 {
2056   const InterfaceHandler *ih;
2057   const MessageHandler *mh;
2058
2059   if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
2060     return FALSE;
2061   if (!_dbus_string_append (xml, "<node>\n"))
2062     return FALSE;
2063
2064   for (ih = interface_handlers; ih->name != NULL; ih++)
2065     {
2066       if (!_dbus_string_append_printf (xml, "  <interface name=\"%s\">\n",
2067                                        ih->name))
2068         return FALSE;
2069
2070       for (mh = ih->message_handlers; mh->name != NULL; mh++)
2071         {
2072           if (!_dbus_string_append_printf (xml, "    <method name=\"%s\">\n",
2073                                            mh->name))
2074             return FALSE;
2075
2076           if (!write_args_for_direction (xml, mh->in_args, TRUE))
2077             return FALSE;
2078
2079           if (!write_args_for_direction (xml, mh->out_args, FALSE))
2080             return FALSE;
2081
2082           if (!_dbus_string_append (xml, "    </method>\n"))
2083             return FALSE;
2084         }
2085
2086       if (ih->extra_introspection != NULL &&
2087           !_dbus_string_append (xml, ih->extra_introspection))
2088         return FALSE;
2089
2090       if (!_dbus_string_append (xml, "  </interface>\n"))
2091         return FALSE;
2092     }
2093
2094   if (!_dbus_string_append (xml, "</node>\n"))
2095     return FALSE;
2096
2097   return TRUE;
2098 }
2099
2100 static dbus_bool_t
2101 bus_driver_handle_introspect (DBusConnection *connection,
2102                               BusTransaction *transaction,
2103                               DBusMessage    *message,
2104                               DBusError      *error)
2105 {
2106   DBusString xml;
2107   DBusMessage *reply;
2108   const char *v_STRING;
2109
2110   _dbus_verbose ("Introspect() on bus driver\n");
2111
2112   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2113
2114   reply = NULL;
2115
2116   if (! dbus_message_get_args (message, error,
2117                                DBUS_TYPE_INVALID))
2118     {
2119       _DBUS_ASSERT_ERROR_IS_SET (error);
2120       return FALSE;
2121     }
2122
2123   if (!_dbus_string_init (&xml))
2124     {
2125       BUS_SET_OOM (error);
2126       return FALSE;
2127     }
2128
2129   if (!bus_driver_generate_introspect_string (&xml))
2130     goto oom;
2131
2132   v_STRING = _dbus_string_get_const_data (&xml);
2133
2134   reply = dbus_message_new_method_return (message);
2135   if (reply == NULL)
2136     goto oom;
2137
2138   if (! dbus_message_append_args (reply,
2139                                   DBUS_TYPE_STRING, &v_STRING,
2140                                   DBUS_TYPE_INVALID))
2141     goto oom;
2142
2143   if (! bus_transaction_send_from_driver (transaction, connection, reply))
2144     goto oom;
2145
2146   dbus_message_unref (reply);
2147   _dbus_string_free (&xml);
2148
2149   return TRUE;
2150
2151  oom:
2152   BUS_SET_OOM (error);
2153
2154   if (reply)
2155     dbus_message_unref (reply);
2156
2157   _dbus_string_free (&xml);
2158
2159   return FALSE;
2160 }
2161
2162 dbus_bool_t
2163 bus_driver_handle_message (DBusConnection *connection,
2164                            BusTransaction *transaction,
2165                            DBusMessage    *message,
2166                            DBusError      *error)
2167 {
2168   const char *name, *interface;
2169   const InterfaceHandler *ih;
2170   const MessageHandler *mh;
2171   dbus_bool_t found_interface = FALSE;
2172
2173   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2174
2175   if (dbus_message_is_signal (message, "org.freedesktop.systemd1.Activator", "ActivationFailure"))
2176     {
2177       BusContext *context;
2178
2179       context = bus_connection_get_context (connection);
2180       return dbus_activation_systemd_failure(bus_context_get_activation(context), message);
2181     }
2182
2183   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
2184     {
2185       _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
2186       return TRUE; /* we just ignore this */
2187     }
2188
2189   /* may be NULL, which means "any interface will do" */
2190   interface = dbus_message_get_interface (message);
2191
2192   _dbus_assert (dbus_message_get_member (message) != NULL);
2193
2194   name = dbus_message_get_member (message);
2195
2196   _dbus_verbose ("Driver got a method call: %s\n", name);
2197
2198   /* security checks should have kept this from getting here */
2199   _dbus_assert (dbus_message_get_sender (message) != NULL ||
2200                 strcmp (name, "Hello") == 0);
2201
2202   for (ih = interface_handlers; ih->name != NULL; ih++)
2203     {
2204       if (interface != NULL && strcmp (interface, ih->name) != 0)
2205         continue;
2206
2207       found_interface = TRUE;
2208
2209       for (mh = ih->message_handlers; mh->name != NULL; mh++)
2210         {
2211           if (strcmp (mh->name, name) != 0)
2212             continue;
2213
2214           _dbus_verbose ("Found driver handler for %s\n", name);
2215
2216           if (!dbus_message_has_signature (message, mh->in_args))
2217             {
2218               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2219               _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n",
2220                              name, dbus_message_get_signature (message),
2221                              mh->in_args);
2222
2223               dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2224                               "Call to %s has wrong args (%s, expected %s)\n",
2225                               name, dbus_message_get_signature (message),
2226                               mh->in_args);
2227               _DBUS_ASSERT_ERROR_IS_SET (error);
2228               return FALSE;
2229             }
2230
2231           if ((* mh->handler) (connection, transaction, message, error))
2232             {
2233               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2234               _dbus_verbose ("Driver handler succeeded\n");
2235               return TRUE;
2236             }
2237           else
2238             {
2239               _DBUS_ASSERT_ERROR_IS_SET (error);
2240               _dbus_verbose ("Driver handler returned failure\n");
2241               return FALSE;
2242             }
2243         }
2244     }
2245
2246   _dbus_verbose ("No driver handler for message \"%s\"\n",
2247                  name);
2248
2249   dbus_set_error (error, found_interface ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_INTERFACE,
2250                   "%s does not understand message %s",
2251                   DBUS_SERVICE_DBUS, name);
2252
2253   return FALSE;
2254 }
2255
2256 void
2257 bus_driver_remove_connection (DBusConnection *connection)
2258 {
2259   /* FIXME 1.0 Does nothing for now, should unregister the connection
2260    * with the bus driver.
2261    */
2262 }