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