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