57265e520d25d4c4da4df43094b5309d80f42797
[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 #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   else if (service == NULL)
1370     {
1371       dbus_set_error (error,
1372                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1373                       "Could not get owners of name '%s': no such name", text);
1374       goto failed;
1375     }
1376   else
1377     {
1378       if (!bus_service_list_queued_owners (service,
1379                                            &base_names,
1380                                            error))
1381         goto failed;
1382     }
1383
1384   _dbus_assert (base_names != NULL);
1385
1386   reply = dbus_message_new_method_return (message);
1387   if (reply == NULL)
1388     goto oom;
1389
1390   dbus_message_iter_init_append (reply, &iter);
1391   if (!dbus_message_iter_open_container (&iter,
1392                                          DBUS_TYPE_ARRAY,
1393                                          DBUS_TYPE_STRING_AS_STRING,
1394                                          &array_iter))
1395     goto oom;
1396
1397   link = _dbus_list_get_first_link (&base_names);
1398   while (link != NULL)
1399     {
1400       char *uname;
1401
1402       _dbus_assert (link->data != NULL);
1403       uname = (char *)link->data;
1404
1405       if (!dbus_message_iter_append_basic (&array_iter,
1406                                            DBUS_TYPE_STRING,
1407                                            &uname))
1408         goto oom;
1409
1410       link = _dbus_list_get_next_link (&base_names, link);
1411     }
1412
1413   if (! dbus_message_iter_close_container (&iter, &array_iter))
1414     goto oom;
1415
1416
1417   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1418     goto oom;
1419
1420   dbus_message_unref (reply);
1421
1422   return TRUE;
1423
1424  oom:
1425   BUS_SET_OOM (error);
1426
1427  failed:
1428   _DBUS_ASSERT_ERROR_IS_SET (error);
1429   if (reply)
1430     dbus_message_unref (reply);
1431
1432   if (base_names)
1433     _dbus_list_clear (&base_names);
1434
1435   return FALSE;
1436 }
1437
1438 static dbus_bool_t
1439 bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
1440                                             BusTransaction *transaction,
1441                                             DBusMessage    *message,
1442                                             DBusError      *error)
1443 {
1444   DBusConnection *conn;
1445   DBusMessage *reply;
1446   unsigned long uid;
1447   dbus_uint32_t uid32;
1448   const char *service;
1449
1450   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1451
1452   reply = dbus_message_new_method_return (message);
1453   if (reply == NULL)
1454     goto oom;
1455
1456 #ifdef ENABLE_KDBUS_TRANSPORT
1457   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1458   {
1459           const char* name;
1460
1461           if(!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
1462                   goto failed;
1463           if(!kdbus_get_unix_user(connection, name, &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 #ifdef ENABLE_KDBUS_TRANSPORT
1525   if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
1526     {
1527       const char* name;
1528
1529       if(!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
1530         goto failed;
1531       if(!kdbus_get_connection_unix_process_id(connection, name, &pid, error))
1532         goto failed;
1533     }
1534     else
1535 #endif
1536   {
1537     conn = bus_driver_get_conn_helper (connection, message, "PID", &service,
1538                        error);
1539     if (conn == NULL)
1540       goto failed;
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           const char* name;
1743
1744           if(!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
1745                   goto failed;
1746           if(kdbus_get_connection_unix_process_id(connection, name, &ulong_val, error))
1747           {
1748                   if (!_dbus_asv_add_uint32 (&array_iter, "ProcessID", ulong_val))
1749                         goto oom;
1750           }
1751           else
1752                   goto failed;
1753
1754           if(kdbus_get_unix_user(connection, name, &ulong_val, error))
1755           {
1756                   if (!_dbus_asv_add_uint32 (&array_iter, "UnixUserID", ulong_val))
1757                         goto oom;
1758           }
1759           else
1760                   goto failed;
1761   }
1762 #endif
1763
1764   if (!_dbus_asv_close (&reply_iter, &array_iter))
1765     goto oom;
1766
1767   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1768     {
1769       /* this time we don't want to close the iterator again, so just
1770        * get rid of the message */
1771       dbus_message_unref (reply);
1772       reply = NULL;
1773       goto oom;
1774     }
1775
1776   return TRUE;
1777
1778  oom:
1779   BUS_SET_OOM (error);
1780
1781  failed:
1782   _DBUS_ASSERT_ERROR_IS_SET (error);
1783
1784   if (reply)
1785     {
1786       _dbus_asv_abandon (&reply_iter, &array_iter);
1787       dbus_message_unref (reply);
1788     }
1789
1790   return FALSE;
1791 }
1792
1793 static dbus_bool_t
1794 bus_driver_handle_reload_config (DBusConnection *connection,
1795                                  BusTransaction *transaction,
1796                                  DBusMessage    *message,
1797                                  DBusError      *error)
1798 {
1799   BusContext *context;
1800   DBusMessage *reply;
1801
1802   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1803
1804   reply = NULL;
1805
1806   context = bus_connection_get_context (connection);
1807   if (!bus_context_reload_config (context, error))
1808     goto failed;
1809
1810   reply = dbus_message_new_method_return (message);
1811   if (reply == NULL)
1812     goto oom;
1813
1814   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1815     goto oom;
1816
1817   dbus_message_unref (reply);
1818   return TRUE;
1819
1820  oom:
1821   BUS_SET_OOM (error);
1822
1823  failed:
1824   _DBUS_ASSERT_ERROR_IS_SET (error);
1825   if (reply)
1826     dbus_message_unref (reply);
1827   return FALSE;
1828 }
1829
1830 static dbus_bool_t
1831 bus_driver_handle_get_id (DBusConnection *connection,
1832                           BusTransaction *transaction,
1833                           DBusMessage    *message,
1834                           DBusError      *error)
1835 {
1836   BusContext *context;
1837   DBusMessage *reply;
1838   DBusString uuid;
1839   const char *v_STRING;
1840
1841   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1842
1843   if (!_dbus_string_init (&uuid))
1844     {
1845       BUS_SET_OOM (error);
1846       return FALSE;
1847     }
1848
1849   reply = NULL;
1850
1851   context = bus_connection_get_context (connection);
1852   if (!bus_context_get_id (context, &uuid))
1853     goto oom;
1854
1855   reply = dbus_message_new_method_return (message);
1856   if (reply == NULL)
1857     goto oom;
1858
1859   v_STRING = _dbus_string_get_const_data (&uuid);
1860   if (!dbus_message_append_args (reply,
1861                                  DBUS_TYPE_STRING, &v_STRING,
1862                                  DBUS_TYPE_INVALID))
1863     goto oom;
1864
1865   _dbus_assert (dbus_message_has_signature (reply, "s"));
1866
1867   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1868     goto oom;
1869
1870   _dbus_string_free (&uuid);
1871   dbus_message_unref (reply);
1872   return TRUE;
1873
1874  oom:
1875   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1876
1877   BUS_SET_OOM (error);
1878
1879   if (reply)
1880     dbus_message_unref (reply);
1881   _dbus_string_free (&uuid);
1882   return FALSE;
1883 }
1884
1885 typedef struct
1886 {
1887   const char *name;
1888   const char *in_args;
1889   const char *out_args;
1890   dbus_bool_t (* handler) (DBusConnection *connection,
1891                            BusTransaction *transaction,
1892                            DBusMessage    *message,
1893                            DBusError      *error);
1894 } MessageHandler;
1895
1896 /* For speed it might be useful to sort this in order of
1897  * frequency of use (but doesn't matter with only a few items
1898  * anyhow)
1899  */
1900 static const MessageHandler dbus_message_handlers[] = {
1901   { "Hello",
1902     "",
1903     DBUS_TYPE_STRING_AS_STRING,
1904     bus_driver_handle_hello },
1905   { "RequestName",
1906     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
1907     DBUS_TYPE_UINT32_AS_STRING,
1908     bus_driver_handle_acquire_service },
1909   { "ReleaseName",
1910     DBUS_TYPE_STRING_AS_STRING,
1911     DBUS_TYPE_UINT32_AS_STRING,
1912     bus_driver_handle_release_service },
1913   { "StartServiceByName",
1914     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
1915     DBUS_TYPE_UINT32_AS_STRING,
1916     bus_driver_handle_activate_service },
1917   { "UpdateActivationEnvironment",
1918     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,
1919     "",
1920     bus_driver_handle_update_activation_environment },
1921   { "NameHasOwner",
1922     DBUS_TYPE_STRING_AS_STRING,
1923     DBUS_TYPE_BOOLEAN_AS_STRING,
1924     bus_driver_handle_service_exists },
1925   { "ListNames",
1926     "",
1927     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1928     bus_driver_handle_list_services },
1929   { "ListActivatableNames",
1930     "",
1931     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1932     bus_driver_handle_list_activatable_services },
1933   { "AddMatch",
1934     DBUS_TYPE_STRING_AS_STRING,
1935     "",
1936     bus_driver_handle_add_match },
1937   { "RemoveMatch",
1938     DBUS_TYPE_STRING_AS_STRING,
1939     "",
1940     bus_driver_handle_remove_match },
1941   { "GetNameOwner",
1942     DBUS_TYPE_STRING_AS_STRING,
1943     DBUS_TYPE_STRING_AS_STRING,
1944     bus_driver_handle_get_service_owner },
1945   { "ListQueuedOwners",
1946     DBUS_TYPE_STRING_AS_STRING,
1947     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1948     bus_driver_handle_list_queued_owners },
1949   { "GetConnectionUnixUser",
1950     DBUS_TYPE_STRING_AS_STRING,
1951     DBUS_TYPE_UINT32_AS_STRING,
1952     bus_driver_handle_get_connection_unix_user },
1953   { "GetConnectionUnixProcessID",
1954     DBUS_TYPE_STRING_AS_STRING,
1955     DBUS_TYPE_UINT32_AS_STRING,
1956     bus_driver_handle_get_connection_unix_process_id },
1957   { "GetAdtAuditSessionData",
1958     DBUS_TYPE_STRING_AS_STRING,
1959     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
1960     bus_driver_handle_get_adt_audit_session_data },
1961   { "GetConnectionSELinuxSecurityContext",
1962     DBUS_TYPE_STRING_AS_STRING,
1963     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
1964     bus_driver_handle_get_connection_selinux_security_context },
1965   { "ReloadConfig",
1966     "",
1967     "",
1968     bus_driver_handle_reload_config },
1969   { "GetId",
1970     "",
1971     DBUS_TYPE_STRING_AS_STRING,
1972     bus_driver_handle_get_id },
1973   { "GetConnectionCredentials", "s", "a{sv}",
1974     bus_driver_handle_get_connection_credentials },
1975   { NULL, NULL, NULL, NULL }
1976 };
1977
1978 static dbus_bool_t bus_driver_handle_introspect (DBusConnection *,
1979     BusTransaction *, DBusMessage *, DBusError *);
1980
1981 static const MessageHandler introspectable_message_handlers[] = {
1982   { "Introspect", "", DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_introspect },
1983   { NULL, NULL, NULL, NULL }
1984 };
1985
1986 #ifdef DBUS_ENABLE_STATS
1987 static const MessageHandler stats_message_handlers[] = {
1988   { "GetStats", "", "a{sv}", bus_stats_handle_get_stats },
1989   { "GetConnectionStats", "s", "a{sv}", bus_stats_handle_get_connection_stats },
1990   { NULL, NULL, NULL, NULL }
1991 };
1992 #endif
1993
1994 typedef struct {
1995   const char *name;
1996   const MessageHandler *message_handlers;
1997   const char *extra_introspection;
1998 } InterfaceHandler;
1999
2000 /* These should ideally be sorted by frequency of use, although it
2001  * probably doesn't matter with this few items */
2002 static InterfaceHandler interface_handlers[] = {
2003   { DBUS_INTERFACE_DBUS, dbus_message_handlers,
2004     "    <signal name=\"NameOwnerChanged\">\n"
2005     "      <arg type=\"s\"/>\n"
2006     "      <arg type=\"s\"/>\n"
2007     "      <arg type=\"s\"/>\n"
2008     "    </signal>\n"
2009     "    <signal name=\"NameLost\">\n"
2010     "      <arg type=\"s\"/>\n"
2011     "    </signal>\n"
2012     "    <signal name=\"NameAcquired\">\n"
2013     "      <arg type=\"s\"/>\n"
2014     "    </signal>\n" },
2015   { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL },
2016 #ifdef DBUS_ENABLE_STATS
2017   { BUS_INTERFACE_STATS, stats_message_handlers, NULL },
2018 #endif
2019   { NULL, NULL, NULL }
2020 };
2021
2022 static dbus_bool_t
2023 write_args_for_direction (DBusString *xml,
2024                           const char *signature,
2025                           dbus_bool_t in)
2026 {
2027   DBusTypeReader typereader;
2028   DBusString sigstr;
2029   int current_type;
2030
2031   _dbus_string_init_const (&sigstr, signature);
2032   _dbus_type_reader_init_types_only (&typereader, &sigstr, 0);
2033
2034   while ((current_type = _dbus_type_reader_get_current_type (&typereader)) != DBUS_TYPE_INVALID)
2035     {
2036       const DBusString *subsig;
2037       int start, len;
2038
2039       _dbus_type_reader_get_signature (&typereader, &subsig, &start, &len);
2040       if (!_dbus_string_append_printf (xml, "      <arg direction=\"%s\" type=\"",
2041                                        in ? "in" : "out"))
2042         goto oom;
2043       if (!_dbus_string_append_len (xml,
2044                                     _dbus_string_get_const_data (subsig) + start,
2045                                     len))
2046         goto oom;
2047       if (!_dbus_string_append (xml, "\"/>\n"))
2048         goto oom;
2049
2050       _dbus_type_reader_next (&typereader);
2051     }
2052   return TRUE;
2053  oom:
2054   return FALSE;
2055 }
2056
2057 dbus_bool_t
2058 bus_driver_generate_introspect_string (DBusString *xml)
2059 {
2060   const InterfaceHandler *ih;
2061   const MessageHandler *mh;
2062
2063   if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
2064     return FALSE;
2065   if (!_dbus_string_append (xml, "<node>\n"))
2066     return FALSE;
2067
2068   for (ih = interface_handlers; ih->name != NULL; ih++)
2069     {
2070       if (!_dbus_string_append_printf (xml, "  <interface name=\"%s\">\n",
2071                                        ih->name))
2072         return FALSE;
2073
2074       for (mh = ih->message_handlers; mh->name != NULL; mh++)
2075         {
2076           if (!_dbus_string_append_printf (xml, "    <method name=\"%s\">\n",
2077                                            mh->name))
2078             return FALSE;
2079
2080           if (!write_args_for_direction (xml, mh->in_args, TRUE))
2081             return FALSE;
2082
2083           if (!write_args_for_direction (xml, mh->out_args, FALSE))
2084             return FALSE;
2085
2086           if (!_dbus_string_append (xml, "    </method>\n"))
2087             return FALSE;
2088         }
2089
2090       if (ih->extra_introspection != NULL &&
2091           !_dbus_string_append (xml, ih->extra_introspection))
2092         return FALSE;
2093
2094       if (!_dbus_string_append (xml, "  </interface>\n"))
2095         return FALSE;
2096     }
2097
2098   if (!_dbus_string_append (xml, "</node>\n"))
2099     return FALSE;
2100
2101   return TRUE;
2102 }
2103
2104 static dbus_bool_t
2105 bus_driver_handle_introspect (DBusConnection *connection,
2106                               BusTransaction *transaction,
2107                               DBusMessage    *message,
2108                               DBusError      *error)
2109 {
2110   DBusString xml;
2111   DBusMessage *reply;
2112   const char *v_STRING;
2113
2114   _dbus_verbose ("Introspect() on bus driver\n");
2115
2116   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2117
2118   reply = NULL;
2119
2120   if (! dbus_message_get_args (message, error,
2121                                DBUS_TYPE_INVALID))
2122     {
2123       _DBUS_ASSERT_ERROR_IS_SET (error);
2124       return FALSE;
2125     }
2126
2127   if (!_dbus_string_init (&xml))
2128     {
2129       BUS_SET_OOM (error);
2130       return FALSE;
2131     }
2132
2133   if (!bus_driver_generate_introspect_string (&xml))
2134     goto oom;
2135
2136   v_STRING = _dbus_string_get_const_data (&xml);
2137
2138   reply = dbus_message_new_method_return (message);
2139   if (reply == NULL)
2140     goto oom;
2141
2142   if (! dbus_message_append_args (reply,
2143                                   DBUS_TYPE_STRING, &v_STRING,
2144                                   DBUS_TYPE_INVALID))
2145     goto oom;
2146
2147   if (! bus_transaction_send_from_driver (transaction, connection, reply))
2148     goto oom;
2149
2150   dbus_message_unref (reply);
2151   _dbus_string_free (&xml);
2152
2153   return TRUE;
2154
2155  oom:
2156   BUS_SET_OOM (error);
2157
2158   if (reply)
2159     dbus_message_unref (reply);
2160
2161   _dbus_string_free (&xml);
2162
2163   return FALSE;
2164 }
2165
2166 dbus_bool_t
2167 bus_driver_handle_message (DBusConnection *connection,
2168                            BusTransaction *transaction,
2169                            DBusMessage    *message,
2170                            DBusError      *error)
2171 {
2172   const char *name, *interface;
2173   const InterfaceHandler *ih;
2174   const MessageHandler *mh;
2175   dbus_bool_t found_interface = FALSE;
2176
2177   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2178
2179   if (dbus_message_is_signal (message, "org.freedesktop.systemd1.Activator", "ActivationFailure"))
2180     {
2181       BusContext *context;
2182
2183       context = bus_connection_get_context (connection);
2184       return dbus_activation_systemd_failure(bus_context_get_activation(context), message);
2185     }
2186
2187   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
2188     {
2189       _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
2190       return TRUE; /* we just ignore this */
2191     }
2192
2193   /* may be NULL, which means "any interface will do" */
2194   interface = dbus_message_get_interface (message);
2195
2196   _dbus_assert (dbus_message_get_member (message) != NULL);
2197
2198   name = dbus_message_get_member (message);
2199
2200   _dbus_verbose ("Driver got a method call: %s\n", name);
2201
2202   /* security checks should have kept this from getting here */
2203   _dbus_assert (dbus_message_get_sender (message) != NULL ||
2204                 strcmp (name, "Hello") == 0);
2205
2206   for (ih = interface_handlers; ih->name != NULL; ih++)
2207     {
2208       if (interface != NULL && strcmp (interface, ih->name) != 0)
2209         continue;
2210
2211       found_interface = TRUE;
2212
2213       for (mh = ih->message_handlers; mh->name != NULL; mh++)
2214         {
2215           if (strcmp (mh->name, name) != 0)
2216             continue;
2217
2218           _dbus_verbose ("Found driver handler for %s\n", name);
2219
2220           if (!dbus_message_has_signature (message, mh->in_args))
2221             {
2222               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2223               _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n",
2224                              name, dbus_message_get_signature (message),
2225                              mh->in_args);
2226
2227               dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2228                               "Call to %s has wrong args (%s, expected %s)\n",
2229                               name, dbus_message_get_signature (message),
2230                               mh->in_args);
2231               _DBUS_ASSERT_ERROR_IS_SET (error);
2232               return FALSE;
2233             }
2234
2235           if ((* mh->handler) (connection, transaction, message, error))
2236             {
2237               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2238               _dbus_verbose ("Driver handler succeeded\n");
2239               return TRUE;
2240             }
2241           else
2242             {
2243               _DBUS_ASSERT_ERROR_IS_SET (error);
2244               _dbus_verbose ("Driver handler returned failure\n");
2245               return FALSE;
2246             }
2247         }
2248     }
2249
2250   _dbus_verbose ("No driver handler for message \"%s\"\n",
2251                  name);
2252
2253   dbus_set_error (error, found_interface ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_INTERFACE,
2254                   "%s does not understand message %s",
2255                   DBUS_SERVICE_DBUS, name);
2256
2257   return FALSE;
2258 }
2259
2260 void
2261 bus_driver_remove_connection (DBusConnection *connection)
2262 {
2263   /* FIXME 1.0 Does nothing for now, should unregister the connection
2264    * with the bus driver.
2265    */
2266 }