patch: bus: Fix timeout restarts
[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 "apparmor.h"
28 #include "connection.h"
29 #include "driver.h"
30 #include "dispatch.h"
31 #include "services.h"
32 #include "selinux.h"
33 #include "signals.h"
34 #include "smack.h"
35 #include "stats.h"
36 #include "utils.h"
37
38 #include <dbus/dbus-asv-util.h>
39 #include <dbus/dbus-connection-internal.h>
40 #include <dbus/dbus-string.h>
41 #include <dbus/dbus-internals.h>
42 #include <dbus/dbus-message.h>
43 #include <dbus/dbus-marshal-recursive.h>
44 #include <dbus/dbus-marshal-validate.h>
45 #include <string.h>
46
47 typedef enum
48 {
49   BUS_DRIVER_FOUND_SELF,
50   BUS_DRIVER_FOUND_PEER,
51   BUS_DRIVER_FOUND_ERROR,
52 } BusDriverFound;
53
54 static inline const char *
55 nonnull (const char *maybe_null,
56          const char *if_null)
57 {
58   return (maybe_null ? maybe_null : if_null);
59 }
60
61 static DBusConnection *
62 bus_driver_get_owner_of_name (DBusConnection *connection,
63                               const char     *name)
64 {
65   BusRegistry *registry;
66   BusService *serv;
67   DBusString str;
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     return NULL;
75
76   return bus_service_get_primary_owners_connection (serv);
77 }
78
79 static BusDriverFound
80 bus_driver_get_conn_helper (DBusConnection  *connection,
81                             DBusMessage     *message,
82                             const char      *what_we_want,
83                             const char     **name_p,
84                             DBusConnection **peer_conn_p,
85                             DBusError       *error)
86 {
87   DBusConnection *conn;
88   const char *name;
89
90   if (!dbus_message_get_args (message, error,
91                               DBUS_TYPE_STRING, &name,
92                               DBUS_TYPE_INVALID))
93     return BUS_DRIVER_FOUND_ERROR;
94
95   _dbus_assert (name != NULL);
96   _dbus_verbose ("asked for %s of connection %s\n", what_we_want, name);
97
98   if (name_p != NULL)
99     *name_p = name;
100
101   if (strcmp (name, DBUS_SERVICE_DBUS) == 0)
102     return BUS_DRIVER_FOUND_SELF;
103
104   conn = bus_driver_get_owner_of_name (connection, name);
105
106   if (conn == NULL)
107     {
108       dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
109                       "Could not get %s of name '%s': no such name",
110                       what_we_want, name);
111       return BUS_DRIVER_FOUND_ERROR;
112     }
113
114   if (peer_conn_p != NULL)
115     *peer_conn_p = conn;
116
117   return BUS_DRIVER_FOUND_PEER;
118 }
119
120 /*
121  * Log a security warning and set error unless the uid of the connection
122  * is either the uid of this process, or on Unix, uid 0 (root).
123  *
124  * This is intended to be a second line of defence after <deny> rules,
125  * to mitigate incorrect system bus security policy configuration files
126  * like the ones in CVE-2014-8148 and CVE-2014-8156, and (if present)
127  * LSM rules; so it doesn't need to be perfect, but as long as we have
128  * potentially dangerous functionality in the system bus, it does need
129  * to exist.
130  */
131 static dbus_bool_t
132 bus_driver_check_caller_is_privileged (DBusConnection *connection,
133                                        BusTransaction *transaction,
134                                        DBusMessage    *message,
135                                        DBusError      *error)
136 {
137 #ifdef DBUS_UNIX
138   unsigned long uid;
139
140   if (!dbus_connection_get_unix_user (connection, &uid))
141     {
142       const char *method = dbus_message_get_member (message);
143
144       bus_context_log_and_set_error (bus_transaction_get_context (transaction),
145           DBUS_SYSTEM_LOG_SECURITY, error, DBUS_ERROR_ACCESS_DENIED,
146           "rejected attempt to call %s by connection %s (%s) with "
147           "unknown uid", method,
148           nonnull (bus_connection_get_name (connection), "(inactive)"),
149           bus_connection_get_loginfo (connection));
150       return FALSE;
151     }
152
153   /* I'm writing it in this slightly strange form so that it's more
154    * obvious that this security-sensitive code is correct.
155    */
156   if (_dbus_unix_user_is_process_owner (uid))
157     {
158       /* OK */
159     }
160   else if (uid == 0)
161     {
162       /* OK */
163     }
164   else
165     {
166       const char *method = dbus_message_get_member (message);
167
168       bus_context_log_and_set_error (bus_transaction_get_context (transaction),
169           DBUS_SYSTEM_LOG_SECURITY, error, DBUS_ERROR_ACCESS_DENIED,
170           "rejected attempt to call %s by connection %s (%s) with "
171           "uid %lu", method,
172           nonnull (bus_connection_get_name (connection), "(inactive)"),
173           bus_connection_get_loginfo (connection), uid);
174       return FALSE;
175     }
176
177   return TRUE;
178 #elif defined(DBUS_WIN)
179   char *windows_sid = NULL;
180   dbus_bool_t ret = FALSE;
181
182   if (!dbus_connection_get_windows_user (connection, &windows_sid))
183     {
184       const char *method = dbus_message_get_member (message);
185
186       bus_context_log_and_set_error (bus_transaction_get_context (transaction),
187           DBUS_SYSTEM_LOG_SECURITY, error, DBUS_ERROR_ACCESS_DENIED,
188           "rejected attempt to call %s by unknown uid", method);
189       goto out;
190     }
191
192   if (!_dbus_windows_user_is_process_owner (windows_sid))
193     {
194       const char *method = dbus_message_get_member (message);
195
196       bus_context_log_and_set_error (bus_transaction_get_context (transaction),
197           DBUS_SYSTEM_LOG_SECURITY, error, DBUS_ERROR_ACCESS_DENIED,
198           "rejected attempt to call %s by uid %s", method, windows_sid);
199       goto out;
200     }
201
202   ret = TRUE;
203 out:
204   dbus_free (windows_sid);
205   return ret;
206 #else
207   /* make sure we fail closed in the hypothetical case that we are neither
208    * Unix nor Windows */
209   dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
210       "please teach bus/driver.c how uids work on this platform");
211   return FALSE;
212 #endif
213 }
214
215 static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
216                                                     DBusMessage    *hello_message,
217                                                     BusTransaction *transaction,
218                                                     DBusError      *error);
219
220 dbus_bool_t
221 bus_driver_send_service_owner_changed (const char     *service_name,
222                                        const char     *old_owner,
223                                        const char     *new_owner,
224                                        BusTransaction *transaction,
225                                        DBusError      *error)
226 {
227   DBusMessage *message;
228   dbus_bool_t retval;
229   const char *null_service;
230
231   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
232
233   null_service = "";
234   _dbus_verbose ("sending name owner changed: %s [%s -> %s]\n",
235                  service_name,
236                  old_owner ? old_owner : null_service,
237                  new_owner ? new_owner : null_service);
238
239   message = dbus_message_new_signal (DBUS_PATH_DBUS,
240                                      DBUS_INTERFACE_DBUS,
241                                      "NameOwnerChanged");
242
243   if (message == NULL)
244     {
245       BUS_SET_OOM (error);
246       return FALSE;
247     }
248
249   if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
250     goto oom;
251
252   if (!dbus_message_append_args (message,
253                                  DBUS_TYPE_STRING, &service_name,
254                                  DBUS_TYPE_STRING, old_owner ? &old_owner : &null_service,
255                                  DBUS_TYPE_STRING, new_owner ? &new_owner : &null_service,
256                                  DBUS_TYPE_INVALID))
257     goto oom;
258
259   _dbus_assert (dbus_message_has_signature (message, "sss"));
260
261   if (!bus_transaction_capture (transaction, NULL, message))
262     goto oom;
263
264   switch (bus_dispatch_matches (transaction, NULL, NULL, message, NULL, error))
265     {
266     case BUS_RESULT_TRUE:
267       retval = TRUE;
268       break;
269     case BUS_RESULT_FALSE:
270       retval = FALSE;
271       break;
272     default:
273       /* should never happen */
274       _dbus_assert_not_reached ("bus_dispatch_matches returned BUS_RESULT_LATER unexpectedly");
275       retval = FALSE;
276       break;
277     }
278   dbus_message_unref (message);
279
280   return retval;
281
282  oom:
283   dbus_message_unref (message);
284   BUS_SET_OOM (error);
285   return FALSE;
286 }
287
288 dbus_bool_t
289 bus_driver_send_service_lost (DBusConnection *connection,
290                               const char     *service_name,
291                               BusTransaction *transaction,
292                               DBusError      *error)
293 {
294   DBusMessage *message;
295
296   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
297
298   message = dbus_message_new_signal (DBUS_PATH_DBUS,
299                                      DBUS_INTERFACE_DBUS,
300                                      "NameLost");
301
302   if (message == NULL)
303     {
304       BUS_SET_OOM (error);
305       return FALSE;
306     }
307
308   if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
309       !dbus_message_append_args (message,
310                                  DBUS_TYPE_STRING, &service_name,
311                                  DBUS_TYPE_INVALID))
312     {
313       dbus_message_unref (message);
314       BUS_SET_OOM (error);
315       return FALSE;
316     }
317
318   if (!bus_transaction_send_from_driver (transaction, connection, message))
319     {
320       dbus_message_unref (message);
321       BUS_SET_OOM (error);
322       return FALSE;
323     }
324   else
325     {
326       dbus_message_unref (message);
327       return TRUE;
328     }
329 }
330
331 dbus_bool_t
332 bus_driver_send_service_acquired (DBusConnection *connection,
333                                   const char     *service_name,
334                                   BusTransaction *transaction,
335                                   DBusError      *error)
336 {
337   DBusMessage *message;
338
339   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
340
341   message = dbus_message_new_signal (DBUS_PATH_DBUS,
342                                      DBUS_INTERFACE_DBUS,
343                                      "NameAcquired");
344
345   if (message == NULL)
346     {
347       BUS_SET_OOM (error);
348       return FALSE;
349     }
350
351   if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
352       !dbus_message_append_args (message,
353                                  DBUS_TYPE_STRING, &service_name,
354                                  DBUS_TYPE_INVALID))
355     {
356       dbus_message_unref (message);
357       BUS_SET_OOM (error);
358       return FALSE;
359     }
360
361   if (!bus_transaction_send_from_driver (transaction, connection, message))
362     {
363       dbus_message_unref (message);
364       BUS_SET_OOM (error);
365       return FALSE;
366     }
367   else
368     {
369       dbus_message_unref (message);
370       return TRUE;
371     }
372 }
373
374 static dbus_bool_t
375 create_unique_client_name (BusRegistry *registry,
376                            DBusString  *str)
377 {
378   /* We never want to use the same unique client name twice, because
379    * we want to guarantee that if you send a message to a given unique
380    * name, you always get the same application. So we use two numbers
381    * for INT_MAX * INT_MAX combinations, should be pretty safe against
382    * wraparound.
383    */
384   /* FIXME these should be in BusRegistry rather than static vars */
385   static int next_major_number = 0;
386   static int next_minor_number = 0;
387   int len;
388
389   len = _dbus_string_get_length (str);
390
391   while (TRUE)
392     {
393       /* start out with 1-0, go to 1-1, 1-2, 1-3,
394        * up to 1-MAXINT, then 2-0, 2-1, etc.
395        */
396       if (next_minor_number <= 0)
397         {
398           next_major_number += 1;
399           next_minor_number = 0;
400           if (next_major_number <= 0)
401             _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
402         }
403
404       _dbus_assert (next_major_number > 0);
405       _dbus_assert (next_minor_number >= 0);
406
407       /* appname:MAJOR-MINOR */
408
409       if (!_dbus_string_append (str, ":"))
410         return FALSE;
411
412       if (!_dbus_string_append_int (str, next_major_number))
413         return FALSE;
414
415       if (!_dbus_string_append (str, "."))
416         return FALSE;
417
418       if (!_dbus_string_append_int (str, next_minor_number))
419         return FALSE;
420
421       next_minor_number += 1;
422
423       /* Check if a client with the name exists */
424       if (bus_registry_lookup (registry, str) == NULL)
425         break;
426
427       /* drop the number again, try the next one. */
428       _dbus_string_set_length (str, len);
429     }
430
431   return TRUE;
432 }
433
434 static BusResult
435 bus_driver_handle_hello (DBusConnection *connection,
436                          BusTransaction *transaction,
437                          DBusMessage    *message,
438                          DBusError      *error)
439 {
440   DBusString unique_name;
441   BusService *service;
442   BusResult retval;
443   BusRegistry *registry;
444   BusConnections *connections;
445
446   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
447
448   if (bus_connection_is_active (connection))
449     {
450       /* We already handled an Hello message for this connection. */
451       dbus_set_error (error, DBUS_ERROR_FAILED,
452                       "Already handled an Hello message");
453       return BUS_RESULT_FALSE;
454     }
455
456   /* Note that when these limits are exceeded we don't disconnect the
457    * connection; we just sort of leave it hanging there until it times
458    * out or disconnects itself or is dropped due to the max number of
459    * incomplete connections. It's even OK if the connection wants to
460    * retry the hello message, we support that.
461    */
462   connections = bus_connection_get_connections (connection);
463   if (!bus_connections_check_limits (connections, connection,
464                                      error))
465     {
466       _DBUS_ASSERT_ERROR_IS_SET (error);
467       return BUS_RESULT_FALSE;
468     }
469
470   if (!_dbus_string_init (&unique_name))
471     {
472       BUS_SET_OOM (error);
473       return BUS_RESULT_FALSE;
474     }
475
476   retval = BUS_RESULT_FALSE;
477
478   registry = bus_connection_get_registry (connection);
479
480   if (!create_unique_client_name (registry, &unique_name))
481     {
482       BUS_SET_OOM (error);
483       goto out_0;
484     }
485
486   if (!bus_connection_complete (connection, &unique_name, error))
487     {
488       _DBUS_ASSERT_ERROR_IS_SET (error);
489       goto out_0;
490     }
491
492   if (!dbus_message_set_sender (message,
493                                 bus_connection_get_name (connection)))
494     {
495       BUS_SET_OOM (error);
496       goto out_0;
497     }
498
499   if (!bus_driver_send_welcome_message (connection, message, transaction, error))
500     goto out_0;
501
502   /* Create the service */
503   service = bus_registry_ensure (registry,
504                                  &unique_name, connection, 0, transaction, error);
505   if (service == NULL)
506     goto out_0;
507
508   _dbus_assert (bus_connection_is_active (connection));
509   retval = BUS_RESULT_TRUE;
510
511  out_0:
512   _dbus_string_free (&unique_name);
513   return retval;
514 }
515
516 static dbus_bool_t
517 bus_driver_send_welcome_message (DBusConnection *connection,
518                                  DBusMessage    *hello_message,
519                                  BusTransaction *transaction,
520                                  DBusError      *error)
521 {
522   DBusMessage *welcome;
523   const char *name;
524
525   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
526
527   name = bus_connection_get_name (connection);
528   _dbus_assert (name != NULL);
529
530   welcome = dbus_message_new_method_return (hello_message);
531   if (welcome == NULL)
532     {
533       BUS_SET_OOM (error);
534       return FALSE;
535     }
536
537   if (!dbus_message_append_args (welcome,
538                                  DBUS_TYPE_STRING, &name,
539                                  DBUS_TYPE_INVALID))
540     {
541       dbus_message_unref (welcome);
542       BUS_SET_OOM (error);
543       return FALSE;
544     }
545
546   _dbus_assert (dbus_message_has_signature (welcome, DBUS_TYPE_STRING_AS_STRING));
547
548   if (!bus_transaction_send_from_driver (transaction, connection, welcome))
549     {
550       dbus_message_unref (welcome);
551       BUS_SET_OOM (error);
552       return FALSE;
553     }
554   else
555     {
556       dbus_message_unref (welcome);
557       return TRUE;
558     }
559 }
560
561 static BusResult
562 bus_driver_handle_list_services (DBusConnection *connection,
563                                  BusTransaction *transaction,
564                                  DBusMessage    *message,
565                                  DBusError      *error)
566 {
567   DBusMessage *reply;
568   int len;
569   char **services;
570   BusRegistry *registry;
571   int i;
572   DBusMessageIter iter;
573   DBusMessageIter sub;
574
575   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
576
577   registry = bus_connection_get_registry (connection);
578
579   reply = dbus_message_new_method_return (message);
580   if (reply == NULL)
581     {
582       BUS_SET_OOM (error);
583       return BUS_RESULT_FALSE;
584     }
585
586   if (!bus_registry_list_services (registry, &services, &len))
587     {
588       dbus_message_unref (reply);
589       BUS_SET_OOM (error);
590       return BUS_RESULT_FALSE;
591     }
592
593   dbus_message_iter_init_append (reply, &iter);
594
595   if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
596                                          DBUS_TYPE_STRING_AS_STRING,
597                                          &sub))
598     {
599       dbus_free_string_array (services);
600       dbus_message_unref (reply);
601       BUS_SET_OOM (error);
602       return BUS_RESULT_FALSE;
603     }
604
605   {
606     /* Include the bus driver in the list */
607     const char *v_STRING = DBUS_SERVICE_DBUS;
608     if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
609                                          &v_STRING))
610       {
611         dbus_free_string_array (services);
612         dbus_message_unref (reply);
613         BUS_SET_OOM (error);
614         return BUS_RESULT_FALSE;
615       }
616   }
617
618   i = 0;
619   while (i < len)
620     {
621       if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
622                                            &services[i]))
623         {
624           dbus_free_string_array (services);
625           dbus_message_unref (reply);
626           BUS_SET_OOM (error);
627           return BUS_RESULT_FALSE;
628         }
629       ++i;
630     }
631
632   dbus_free_string_array (services);
633
634   if (!dbus_message_iter_close_container (&iter, &sub))
635     {
636       dbus_message_unref (reply);
637       BUS_SET_OOM (error);
638       return BUS_RESULT_FALSE;
639     }
640
641   if (!bus_transaction_send_from_driver (transaction, connection, reply))
642     {
643       dbus_message_unref (reply);
644       BUS_SET_OOM (error);
645       return BUS_RESULT_FALSE;
646     }
647   else
648     {
649       dbus_message_unref (reply);
650       return BUS_RESULT_TRUE;
651     }
652 }
653
654 static BusResult
655 bus_driver_handle_list_activatable_services (DBusConnection *connection,
656                                              BusTransaction *transaction,
657                                              DBusMessage    *message,
658                                              DBusError      *error)
659 {
660   DBusMessage *reply;
661   int len;
662   char **services;
663   BusActivation *activation;
664   int i;
665   DBusMessageIter iter;
666   DBusMessageIter sub;
667
668   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
669
670   activation = bus_connection_get_activation (connection);
671
672   reply = dbus_message_new_method_return (message);
673   if (reply == NULL)
674     {
675       BUS_SET_OOM (error);
676       return BUS_RESULT_FALSE;
677     }
678
679   if (!bus_activation_list_services (activation, &services, &len))
680     {
681       dbus_message_unref (reply);
682       BUS_SET_OOM (error);
683       return BUS_RESULT_FALSE;
684     }
685
686   dbus_message_iter_init_append (reply, &iter);
687
688   if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
689                                          DBUS_TYPE_STRING_AS_STRING,
690                                          &sub))
691     {
692       dbus_free_string_array (services);
693       dbus_message_unref (reply);
694       BUS_SET_OOM (error);
695       return BUS_RESULT_FALSE;
696     }
697
698   {
699     /* Include the bus driver in the list */
700     const char *v_STRING = DBUS_SERVICE_DBUS;
701     if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
702                                          &v_STRING))
703       {
704         dbus_free_string_array (services);
705         dbus_message_unref (reply);
706         BUS_SET_OOM (error);
707         return BUS_RESULT_FALSE;
708       }
709   }
710
711   i = 0;
712   while (i < len)
713     {
714       if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
715                                            &services[i]))
716         {
717           dbus_free_string_array (services);
718           dbus_message_unref (reply);
719           BUS_SET_OOM (error);
720           return BUS_RESULT_FALSE;
721         }
722       ++i;
723     }
724
725   dbus_free_string_array (services);
726
727   if (!dbus_message_iter_close_container (&iter, &sub))
728     {
729       dbus_message_unref (reply);
730       BUS_SET_OOM (error);
731       return BUS_RESULT_FALSE;
732     }
733
734   if (!bus_transaction_send_from_driver (transaction, connection, reply))
735     {
736       dbus_message_unref (reply);
737       BUS_SET_OOM (error);
738       return BUS_RESULT_FALSE;
739     }
740   else
741     {
742       dbus_message_unref (reply);
743       return BUS_RESULT_TRUE;
744     }
745 }
746
747 static BusResult
748 bus_driver_handle_acquire_service (DBusConnection *connection,
749                                    BusTransaction *transaction,
750                                    DBusMessage    *message,
751                                    DBusError      *error)
752 {
753   DBusMessage *reply;
754   DBusString service_name;
755   const char *name;
756   dbus_uint32_t service_reply;
757   dbus_uint32_t flags;
758   BusResult retval;
759   BusRegistry *registry;
760
761   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
762
763   registry = bus_connection_get_registry (connection);
764
765   if (!dbus_message_get_args (message, error,
766                               DBUS_TYPE_STRING, &name,
767                               DBUS_TYPE_UINT32, &flags,
768                               DBUS_TYPE_INVALID))
769     return BUS_RESULT_FALSE;
770
771   _dbus_verbose ("Trying to own name %s with flags 0x%x\n", name, flags);
772
773   retval = BUS_RESULT_FALSE;
774   reply = NULL;
775
776   _dbus_string_init_const (&service_name, name);
777
778   switch (bus_registry_acquire_service (registry, connection, message,
779                                        &service_name, flags,
780                                        &service_reply, transaction,
781                                        error))
782     {
783       case BUS_RESULT_TRUE:
784         break;
785       case BUS_RESULT_FALSE:
786         goto out;
787       case BUS_RESULT_LATER:
788         retval = BUS_RESULT_LATER;
789         goto out;
790     }
791
792   reply = dbus_message_new_method_return (message);
793   if (reply == NULL)
794     {
795       BUS_SET_OOM (error);
796       goto out;
797     }
798
799   if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
800     {
801       BUS_SET_OOM (error);
802       goto out;
803     }
804
805   if (!bus_transaction_send_from_driver (transaction, connection, reply))
806     {
807       BUS_SET_OOM (error);
808       goto out;
809     }
810
811   retval = BUS_RESULT_TRUE;
812
813  out:
814   if (reply)
815     dbus_message_unref (reply);
816   return retval;
817 }
818
819 static BusResult
820 bus_driver_handle_release_service (DBusConnection *connection,
821                                    BusTransaction *transaction,
822                                    DBusMessage    *message,
823                                    DBusError      *error)
824 {
825   DBusMessage *reply;
826   DBusString service_name;
827   const char *name;
828   dbus_uint32_t service_reply;
829   BusResult retval;
830   BusRegistry *registry;
831
832   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
833
834   registry = bus_connection_get_registry (connection);
835
836   if (!dbus_message_get_args (message, error,
837                               DBUS_TYPE_STRING, &name,
838                               DBUS_TYPE_INVALID))
839     return BUS_RESULT_FALSE;
840
841   _dbus_verbose ("Trying to release name %s\n", name);
842
843   retval = BUS_RESULT_FALSE;
844   reply = NULL;
845
846   _dbus_string_init_const (&service_name, name);
847
848   if (!bus_registry_release_service (registry, connection,
849                                      &service_name, &service_reply,
850                                      transaction, error))
851     goto out;
852
853   reply = dbus_message_new_method_return (message);
854   if (reply == NULL)
855     {
856       BUS_SET_OOM (error);
857       goto out;
858     }
859
860   if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
861     {
862       BUS_SET_OOM (error);
863       goto out;
864     }
865
866   if (!bus_transaction_send_from_driver (transaction, connection, reply))
867     {
868       BUS_SET_OOM (error);
869       goto out;
870     }
871
872   retval = BUS_RESULT_TRUE;
873
874  out:
875   if (reply)
876     dbus_message_unref (reply);
877   return retval;
878 }
879
880 static BusResult
881 bus_driver_handle_service_exists (DBusConnection *connection,
882                                   BusTransaction *transaction,
883                                   DBusMessage    *message,
884                                   DBusError      *error)
885 {
886   DBusMessage *reply;
887   DBusString service_name;
888   BusService *service;
889   dbus_bool_t service_exists;
890   const char *name;
891   BusResult retval;
892   BusRegistry *registry;
893
894   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
895
896   registry = bus_connection_get_registry (connection);
897
898   if (!dbus_message_get_args (message, error,
899                               DBUS_TYPE_STRING, &name,
900                               DBUS_TYPE_INVALID))
901     return BUS_RESULT_FALSE;
902
903   retval = BUS_RESULT_FALSE;
904
905   if (strcmp (name, DBUS_SERVICE_DBUS) == 0)
906     {
907       service_exists = TRUE;
908     }
909   else
910     {
911       _dbus_string_init_const (&service_name, name);
912       service = bus_registry_lookup (registry, &service_name);
913       service_exists = service != NULL;
914     }
915
916   reply = dbus_message_new_method_return (message);
917   if (reply == NULL)
918     {
919       BUS_SET_OOM (error);
920       goto out;
921     }
922
923   if (!dbus_message_append_args (reply,
924                                  DBUS_TYPE_BOOLEAN, &service_exists,
925                                  0))
926     {
927       BUS_SET_OOM (error);
928       goto out;
929     }
930
931   if (!bus_transaction_send_from_driver (transaction, connection, reply))
932     {
933       BUS_SET_OOM (error);
934       goto out;
935     }
936
937   retval = BUS_RESULT_TRUE;
938
939  out:
940   if (reply)
941     dbus_message_unref (reply);
942
943   return retval;
944 }
945
946 static BusResult
947 bus_driver_handle_activate_service (DBusConnection *connection,
948                                     BusTransaction *transaction,
949                                     DBusMessage    *message,
950                                     DBusError      *error)
951 {
952   dbus_uint32_t flags;
953   const char *name;
954   BusResult retval;
955   BusActivation *activation;
956
957   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
958
959   activation = bus_connection_get_activation (connection);
960
961   if (!dbus_message_get_args (message, error,
962                               DBUS_TYPE_STRING, &name,
963                               DBUS_TYPE_UINT32, &flags,
964                               DBUS_TYPE_INVALID))
965     {
966       _DBUS_ASSERT_ERROR_IS_SET (error);
967       _dbus_verbose ("No memory to get arguments to StartServiceByName\n");
968       return BUS_RESULT_FALSE;
969     }
970
971   retval = BUS_RESULT_FALSE;
972
973   if (!bus_activation_activate_service (activation, connection, transaction, FALSE,
974                                         message, name, error))
975     {
976       _DBUS_ASSERT_ERROR_IS_SET (error);
977       _dbus_verbose ("bus_activation_activate_service() failed\n");
978       goto out;
979     }
980
981   retval = BUS_RESULT_TRUE;
982
983  out:
984   return retval;
985 }
986
987 static dbus_bool_t
988 send_ack_reply (DBusConnection *connection,
989                 BusTransaction *transaction,
990                 DBusMessage    *message,
991                 DBusError      *error)
992 {
993   DBusMessage *reply;
994
995   if (dbus_message_get_no_reply (message))
996     return TRUE;
997
998   reply = dbus_message_new_method_return (message);
999   if (reply == NULL)
1000     {
1001       BUS_SET_OOM (error);
1002       return FALSE;
1003     }
1004
1005   if (!bus_transaction_send_from_driver (transaction, connection, reply))
1006     {
1007       BUS_SET_OOM (error);
1008       dbus_message_unref (reply);
1009       return FALSE;
1010     }
1011
1012   dbus_message_unref (reply);
1013
1014   return TRUE;
1015 }
1016
1017 /*
1018  * Send a message from the driver, activating the destination if necessary.
1019  * The message must already have a destination set.
1020  */
1021 static dbus_bool_t
1022 bus_driver_send_or_activate (BusTransaction *transaction,
1023                              DBusMessage    *message,
1024                              DBusError      *error)
1025 {
1026   BusContext *context;
1027   BusService *service;
1028   const char *service_name;
1029   DBusString service_string;
1030
1031   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1032
1033   service_name = dbus_message_get_destination (message);
1034
1035   _dbus_assert (service_name != NULL);
1036
1037   _dbus_string_init_const (&service_string, service_name);
1038
1039   context = bus_transaction_get_context (transaction);
1040
1041   service = bus_registry_lookup (bus_context_get_registry (context),
1042                                  &service_string);
1043
1044   if (service == NULL)
1045     {
1046       /* destination isn't connected yet; pass the message to activation */
1047       BusActivation *activation;
1048
1049       activation = bus_context_get_activation (context);
1050
1051       if (!bus_transaction_capture (transaction, NULL, message))
1052         {
1053           BUS_SET_OOM (error);
1054           _dbus_verbose ("No memory for bus_transaction_capture()");
1055           return FALSE;
1056         }
1057
1058       if (!bus_activation_activate_service (activation, NULL, transaction, TRUE,
1059                                             message, service_name, error))
1060         {
1061           _DBUS_ASSERT_ERROR_IS_SET (error);
1062           _dbus_verbose ("bus_activation_activate_service() failed");
1063           return FALSE;
1064         }
1065     }
1066   else
1067     {
1068       DBusConnection *service_conn;
1069
1070       service_conn = bus_service_get_primary_owners_connection (service);
1071
1072       if (!bus_transaction_send_from_driver (transaction, service_conn, message))
1073         {
1074           BUS_SET_OOM (error);
1075           _dbus_verbose ("No memory for bus_transaction_send_from_driver()");
1076           return FALSE;
1077         }
1078     }
1079
1080   return TRUE;
1081 }
1082
1083 static BusResult
1084 bus_driver_handle_update_activation_environment (DBusConnection *connection,
1085                                                  BusTransaction *transaction,
1086                                                  DBusMessage    *message,
1087                                                  DBusError      *error)
1088 {
1089   BusResult retval;
1090   BusActivation *activation;
1091   BusContext *context;
1092   DBusMessageIter iter;
1093   DBusMessageIter dict_iter;
1094   DBusMessageIter dict_entry_iter;
1095   int array_type;
1096   int key_type;
1097   DBusList *keys, *key_link;
1098   DBusList *values, *value_link;
1099   DBusMessage *systemd_message;
1100   DBusMessageIter systemd_iter;
1101
1102   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1103
1104   if (!bus_driver_check_message_is_for_us (message, error))
1105     return FALSE;
1106
1107 #ifdef DBUS_UNIX
1108     {
1109       /* UpdateActivationEnvironment is basically a recipe for privilege
1110        * escalation so let's be extra-careful: do not allow the sysadmin
1111        * to shoot themselves in the foot.
1112        */
1113       if (!bus_driver_check_caller_is_privileged (connection, transaction,
1114                                                   message, error))
1115         return FALSE;
1116     }
1117 #endif
1118
1119   context = bus_connection_get_context (connection);
1120
1121   if (bus_context_get_servicehelper (context) != NULL)
1122     {
1123       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
1124                       "Cannot change activation environment "
1125                       "on a system bus.");
1126       return FALSE;
1127     }
1128
1129   activation = bus_connection_get_activation (connection);
1130
1131   dbus_message_iter_init (message, &iter);
1132
1133   /* The message signature has already been checked for us,
1134    * so let's just assert it's right.
1135    */
1136   _dbus_assert (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY);
1137
1138   dbus_message_iter_recurse (&iter, &dict_iter);
1139
1140   retval = BUS_RESULT_FALSE;
1141   systemd_message = NULL;
1142
1143   /* Then loop through the sent dictionary, add the location of
1144    * the environment keys and values to lists. The result will
1145    * be in reverse order, so we don't have to constantly search
1146    * for the end of the list in a loop.
1147    */
1148   keys = NULL;
1149   values = NULL;
1150   while ((array_type = dbus_message_iter_get_arg_type (&dict_iter)) == DBUS_TYPE_DICT_ENTRY)
1151     {
1152       dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
1153
1154       while ((key_type = dbus_message_iter_get_arg_type (&dict_entry_iter)) == DBUS_TYPE_STRING)
1155         {
1156           char *key;
1157           char *value;
1158           int value_type;
1159
1160           dbus_message_iter_get_basic (&dict_entry_iter, &key);
1161           dbus_message_iter_next (&dict_entry_iter);
1162
1163           value_type = dbus_message_iter_get_arg_type (&dict_entry_iter);
1164
1165           if (value_type != DBUS_TYPE_STRING)
1166             break;
1167
1168           dbus_message_iter_get_basic (&dict_entry_iter, &value);
1169
1170           if (!_dbus_list_append (&keys, key))
1171             {
1172               BUS_SET_OOM (error);
1173               break;
1174             }
1175
1176           if (!_dbus_list_append (&values, value))
1177             {
1178               BUS_SET_OOM (error);
1179               break;
1180             }
1181
1182           dbus_message_iter_next (&dict_entry_iter);
1183         }
1184
1185       if (key_type != DBUS_TYPE_INVALID)
1186         break;
1187
1188       dbus_message_iter_next (&dict_iter);
1189     }
1190
1191   if (array_type != DBUS_TYPE_INVALID)
1192     goto out;
1193
1194   _dbus_assert (_dbus_list_get_length (&keys) == _dbus_list_get_length (&values));
1195
1196   if (bus_context_get_systemd_activation (bus_connection_get_context (connection)))
1197     {
1198       /* Prepare a call to forward environment updates to systemd */
1199       systemd_message = dbus_message_new_method_call ("org.freedesktop.systemd1",
1200                                                       "/org/freedesktop/systemd1",
1201                                                       "org.freedesktop.systemd1.Manager",
1202                                                       "SetEnvironment");
1203       if (systemd_message == NULL ||
1204           !dbus_message_set_sender (systemd_message, DBUS_SERVICE_DBUS))
1205         {
1206           BUS_SET_OOM (error);
1207           _dbus_verbose ("No memory to create systemd message\n");
1208           goto out;
1209         }
1210
1211       dbus_message_set_no_reply (systemd_message, TRUE);
1212       dbus_message_iter_init_append (systemd_message, &iter);
1213
1214       if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s",
1215                                              &systemd_iter))
1216         {
1217           BUS_SET_OOM (error);
1218           _dbus_verbose ("No memory to open systemd message container\n");
1219           goto out;
1220         }
1221     }
1222
1223   key_link = keys;
1224   value_link = values;
1225   while (key_link != NULL)
1226   {
1227       const char *key;
1228       const char *value;
1229
1230       key = key_link->data;
1231       value = value_link->data;
1232
1233       if (!bus_activation_set_environment_variable (activation,
1234                                                     key, value, error))
1235         {
1236           _DBUS_ASSERT_ERROR_IS_SET (error);
1237           _dbus_verbose ("bus_activation_set_environment_variable() failed\n");
1238           break;
1239         }
1240
1241       if (systemd_message != NULL)
1242         {
1243           DBusString envline;
1244           const char *s;
1245
1246           /* SetEnvironment wants an array of KEY=VALUE strings */
1247           if (!_dbus_string_init (&envline) ||
1248               !_dbus_string_append_printf (&envline, "%s=%s", key, value))
1249             {
1250               BUS_SET_OOM (error);
1251               _dbus_verbose ("No memory to format systemd environment line\n");
1252               _dbus_string_free (&envline);
1253               break;
1254             }
1255
1256           s = _dbus_string_get_data (&envline);
1257
1258           if (!dbus_message_iter_append_basic (&systemd_iter,
1259                                                DBUS_TYPE_STRING, &s))
1260             {
1261               BUS_SET_OOM (error);
1262               _dbus_verbose ("No memory to append systemd environment line\n");
1263               _dbus_string_free (&envline);
1264               break;
1265             }
1266
1267           _dbus_string_free (&envline);
1268         }
1269
1270       key_link = _dbus_list_get_next_link (&keys, key_link);
1271       value_link = _dbus_list_get_next_link (&values, value_link);
1272   }
1273
1274   /* FIXME: We can fail early having set only some of the environment variables,
1275    * (because of OOM failure).  It's sort of hard to fix and it doesn't really
1276    * matter, so we're punting for now.
1277    */
1278   if (key_link != NULL)
1279     {
1280       if (systemd_message != NULL)
1281         dbus_message_iter_abandon_container (&iter, &systemd_iter);
1282       goto out;
1283     }
1284
1285   if (systemd_message != NULL)
1286     {
1287       if (!dbus_message_iter_close_container (&iter, &systemd_iter))
1288         {
1289           BUS_SET_OOM (error);
1290           _dbus_verbose ("No memory to close systemd message container\n");
1291           goto out;
1292         }
1293
1294       if (!bus_driver_send_or_activate (transaction, systemd_message, error))
1295         {
1296           _DBUS_ASSERT_ERROR_IS_SET (error);
1297           _dbus_verbose ("bus_driver_send_or_activate() failed\n");
1298           goto out;
1299         }
1300     }
1301
1302   if (!send_ack_reply (connection, transaction,
1303                        message, error))
1304     goto out;
1305
1306   retval = BUS_RESULT_TRUE;
1307
1308  out:
1309   if (systemd_message != NULL)
1310     dbus_message_unref (systemd_message);
1311   _dbus_list_clear (&keys);
1312   _dbus_list_clear (&values);
1313   return retval;
1314 }
1315
1316 static BusResult
1317 bus_driver_handle_add_match (DBusConnection *connection,
1318                              BusTransaction *transaction,
1319                              DBusMessage    *message,
1320                              DBusError      *error)
1321 {
1322   BusMatchRule *rule;
1323   const char *text, *bustype;
1324   DBusString str;
1325   BusMatchmaker *matchmaker;
1326   BusContext *context;
1327
1328   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1329
1330   text = NULL;
1331   rule = NULL;
1332
1333   if (bus_connection_get_n_match_rules (connection) >=
1334       bus_context_get_max_match_rules_per_connection (bus_transaction_get_context (transaction)))
1335     {
1336       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
1337                       "Connection \"%s\" is not allowed to add more match rules "
1338                       "(increase limits in configuration file if required)",
1339                       bus_connection_is_active (connection) ?
1340                       bus_connection_get_name (connection) :
1341                       "(inactive)");
1342       goto failed;
1343     }
1344
1345   if (!dbus_message_get_args (message, error,
1346                               DBUS_TYPE_STRING, &text,
1347                               DBUS_TYPE_INVALID))
1348     {
1349       _dbus_verbose ("No memory to get arguments to AddMatch\n");
1350       goto failed;
1351     }
1352
1353   _dbus_string_init_const (&str, text);
1354
1355   rule = bus_match_rule_parse (connection, &str, error);
1356   if (rule == NULL)
1357     goto failed;
1358
1359   context = bus_transaction_get_context (transaction);
1360   bustype = context ? bus_context_get_type (context) : NULL;
1361   if (bus_match_rule_get_client_is_eavesdropping (rule) &&
1362       !bus_apparmor_allows_eavesdropping (connection, bustype, error))
1363     goto failed;
1364
1365   matchmaker = bus_connection_get_matchmaker (connection);
1366
1367   if (!bus_matchmaker_add_rule (matchmaker, rule))
1368     {
1369       BUS_SET_OOM (error);
1370       goto failed;
1371     }
1372
1373   if (!send_ack_reply (connection, transaction,
1374                        message, error))
1375     {
1376       bus_matchmaker_remove_rule (matchmaker, rule);
1377       goto failed;
1378     }
1379
1380   bus_match_rule_unref (rule);
1381
1382   return BUS_RESULT_TRUE;
1383
1384  failed:
1385   _DBUS_ASSERT_ERROR_IS_SET (error);
1386   if (rule)
1387     bus_match_rule_unref (rule);
1388   return BUS_RESULT_FALSE;
1389 }
1390
1391 static BusResult
1392 bus_driver_handle_remove_match (DBusConnection *connection,
1393                                 BusTransaction *transaction,
1394                                 DBusMessage    *message,
1395                                 DBusError      *error)
1396 {
1397   BusMatchRule *rule;
1398   const char *text;
1399   DBusString str;
1400   BusMatchmaker *matchmaker;
1401
1402   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1403
1404   text = NULL;
1405   rule = NULL;
1406
1407   if (!dbus_message_get_args (message, error,
1408                               DBUS_TYPE_STRING, &text,
1409                               DBUS_TYPE_INVALID))
1410     {
1411       _dbus_verbose ("No memory to get arguments to RemoveMatch\n");
1412       goto failed;
1413     }
1414
1415   _dbus_string_init_const (&str, text);
1416
1417   rule = bus_match_rule_parse (connection, &str, error);
1418   if (rule == NULL)
1419     goto failed;
1420
1421   /* Send the ack before we remove the rule, since the ack is undone
1422    * on transaction cancel, but rule removal isn't.
1423    */
1424   if (!send_ack_reply (connection, transaction,
1425                        message, error))
1426     goto failed;
1427
1428   matchmaker = bus_connection_get_matchmaker (connection);
1429
1430   if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error))
1431     goto failed;
1432
1433   bus_match_rule_unref (rule);
1434
1435   return BUS_RESULT_TRUE;
1436
1437  failed:
1438   _DBUS_ASSERT_ERROR_IS_SET (error);
1439   if (rule)
1440     bus_match_rule_unref (rule);
1441   return BUS_RESULT_FALSE;
1442 }
1443
1444 static BusResult
1445 bus_driver_handle_get_service_owner (DBusConnection *connection,
1446                                      BusTransaction *transaction,
1447                                      DBusMessage    *message,
1448                                      DBusError      *error)
1449 {
1450   const char *text;
1451   const char *base_name;
1452   DBusString str;
1453   BusRegistry *registry;
1454   BusService *service;
1455   DBusMessage *reply;
1456
1457   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1458
1459   registry = bus_connection_get_registry (connection);
1460
1461   text = NULL;
1462   reply = NULL;
1463
1464   if (! dbus_message_get_args (message, error,
1465                                DBUS_TYPE_STRING, &text,
1466                                DBUS_TYPE_INVALID))
1467       goto failed;
1468
1469   _dbus_string_init_const (&str, text);
1470   service = bus_registry_lookup (registry, &str);
1471   if (service == NULL &&
1472       _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1473     {
1474       /* ORG_FREEDESKTOP_DBUS owns itself */
1475       base_name = DBUS_SERVICE_DBUS;
1476     }
1477   else if (service == NULL)
1478     {
1479       dbus_set_error (error,
1480                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1481                       "Could not get owner of name '%s': no such name", text);
1482       goto failed;
1483     }
1484   else
1485     {
1486       base_name = bus_connection_get_name (bus_service_get_primary_owners_connection (service));
1487       if (base_name == NULL)
1488         {
1489           /* FIXME - how is this error possible? */
1490           dbus_set_error (error,
1491                           DBUS_ERROR_FAILED,
1492                           "Could not determine unique name for '%s'", text);
1493           goto failed;
1494         }
1495       _dbus_assert (*base_name == ':');
1496     }
1497
1498   _dbus_assert (base_name != NULL);
1499
1500   reply = dbus_message_new_method_return (message);
1501   if (reply == NULL)
1502     goto oom;
1503
1504   if (! dbus_message_append_args (reply,
1505                                   DBUS_TYPE_STRING, &base_name,
1506                                   DBUS_TYPE_INVALID))
1507     goto oom;
1508
1509   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1510     goto oom;
1511
1512   dbus_message_unref (reply);
1513
1514   return BUS_RESULT_TRUE;
1515
1516  oom:
1517   BUS_SET_OOM (error);
1518
1519  failed:
1520   _DBUS_ASSERT_ERROR_IS_SET (error);
1521   if (reply)
1522     dbus_message_unref (reply);
1523   return BUS_RESULT_FALSE;
1524 }
1525
1526 static BusResult
1527 bus_driver_handle_list_queued_owners (DBusConnection *connection,
1528                                       BusTransaction *transaction,
1529                                       DBusMessage    *message,
1530                                       DBusError      *error)
1531 {
1532   const char *text;
1533   DBusList *base_names;
1534   DBusList *link;
1535   DBusString str;
1536   BusRegistry *registry;
1537   BusService *service;
1538   DBusMessage *reply;
1539   DBusMessageIter iter, array_iter;
1540   char *dbus_service_name = DBUS_SERVICE_DBUS;
1541
1542   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1543
1544   registry = bus_connection_get_registry (connection);
1545
1546   base_names = NULL;
1547   text = NULL;
1548   reply = NULL;
1549
1550   if (! dbus_message_get_args (message, error,
1551                                DBUS_TYPE_STRING, &text,
1552                                DBUS_TYPE_INVALID))
1553       goto failed;
1554
1555   _dbus_string_init_const (&str, text);
1556   service = bus_registry_lookup (registry, &str);
1557   if (service == NULL &&
1558       _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1559     {
1560       /* ORG_FREEDESKTOP_DBUS owns itself */
1561       if (! _dbus_list_append (&base_names, dbus_service_name))
1562         goto oom;
1563     }
1564   else if (service == NULL)
1565     {
1566       dbus_set_error (error,
1567                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1568                       "Could not get owners of name '%s': no such name", text);
1569       goto failed;
1570     }
1571   else
1572     {
1573       if (!bus_service_list_queued_owners (service,
1574                                            &base_names,
1575                                            error))
1576         goto failed;
1577     }
1578
1579   _dbus_assert (base_names != NULL);
1580
1581   reply = dbus_message_new_method_return (message);
1582   if (reply == NULL)
1583     goto oom;
1584
1585   dbus_message_iter_init_append (reply, &iter);
1586   if (!dbus_message_iter_open_container (&iter,
1587                                          DBUS_TYPE_ARRAY,
1588                                          DBUS_TYPE_STRING_AS_STRING,
1589                                          &array_iter))
1590     goto oom;
1591
1592   link = _dbus_list_get_first_link (&base_names);
1593   while (link != NULL)
1594     {
1595       char *uname;
1596
1597       _dbus_assert (link->data != NULL);
1598       uname = (char *)link->data;
1599
1600       if (!dbus_message_iter_append_basic (&array_iter,
1601                                            DBUS_TYPE_STRING,
1602                                            &uname))
1603         goto oom;
1604
1605       link = _dbus_list_get_next_link (&base_names, link);
1606     }
1607
1608   if (! dbus_message_iter_close_container (&iter, &array_iter))
1609     goto oom;
1610
1611
1612   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1613     goto oom;
1614
1615   dbus_message_unref (reply);
1616
1617   return BUS_RESULT_TRUE;
1618
1619  oom:
1620   BUS_SET_OOM (error);
1621
1622  failed:
1623   _DBUS_ASSERT_ERROR_IS_SET (error);
1624   if (reply)
1625     dbus_message_unref (reply);
1626
1627   if (base_names)
1628     _dbus_list_clear (&base_names);
1629
1630   return BUS_RESULT_FALSE;
1631 }
1632
1633 static BusResult
1634 bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
1635                                             BusTransaction *transaction,
1636                                             DBusMessage    *message,
1637                                             DBusError      *error)
1638 {
1639   DBusConnection *conn;
1640   DBusMessage *reply;
1641   dbus_uid_t uid;
1642   dbus_uint32_t uid32;
1643   const char *service;
1644   BusDriverFound found;
1645
1646   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1647
1648   reply = NULL;
1649
1650   found = bus_driver_get_conn_helper (connection, message, "UID", &service,
1651                                       &conn, error);
1652   switch (found)
1653     {
1654       case BUS_DRIVER_FOUND_SELF:
1655         uid = _dbus_getuid ();
1656         break;
1657       case BUS_DRIVER_FOUND_PEER:
1658         if (!dbus_connection_get_unix_user (conn, &uid))
1659           uid = DBUS_UID_UNSET;
1660         break;
1661       case BUS_DRIVER_FOUND_ERROR:
1662         goto failed;
1663     }
1664
1665   if (uid == DBUS_UID_UNSET)
1666     {
1667       dbus_set_error (error,
1668                       DBUS_ERROR_FAILED,
1669                       "Could not determine UID for '%s'", service);
1670       goto failed;
1671     }
1672
1673   reply = dbus_message_new_method_return (message);
1674   if (reply == NULL)
1675     goto oom;
1676
1677   uid32 = uid;
1678   if (! dbus_message_append_args (reply,
1679                                   DBUS_TYPE_UINT32, &uid32,
1680                                   DBUS_TYPE_INVALID))
1681     goto oom;
1682
1683   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1684     goto oom;
1685
1686   dbus_message_unref (reply);
1687
1688   return BUS_RESULT_TRUE;
1689
1690  oom:
1691   BUS_SET_OOM (error);
1692
1693  failed:
1694   _DBUS_ASSERT_ERROR_IS_SET (error);
1695   if (reply)
1696     dbus_message_unref (reply);
1697   return BUS_RESULT_FALSE;
1698 }
1699
1700 static BusResult
1701 bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
1702                                                   BusTransaction *transaction,
1703                                                   DBusMessage    *message,
1704                                                   DBusError      *error)
1705 {
1706   DBusConnection *conn;
1707   DBusMessage *reply;
1708   dbus_pid_t pid;
1709   dbus_uint32_t pid32;
1710   const char *service;
1711   BusDriverFound found;
1712
1713   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1714
1715   reply = NULL;
1716
1717   found = bus_driver_get_conn_helper (connection, message, "PID", &service,
1718                                       &conn, error);
1719   switch (found)
1720     {
1721       case BUS_DRIVER_FOUND_SELF:
1722         pid = _dbus_getpid ();
1723         break;
1724       case BUS_DRIVER_FOUND_PEER:
1725         if (!dbus_connection_get_unix_process_id (conn, &pid))
1726           pid = DBUS_PID_UNSET;
1727         break;
1728       case BUS_DRIVER_FOUND_ERROR:
1729         goto failed;
1730     }
1731
1732   if (pid == DBUS_PID_UNSET)
1733     {
1734       dbus_set_error (error,
1735                       DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
1736                       "Could not determine PID for '%s'", service);
1737       goto failed;
1738     }
1739
1740   reply = dbus_message_new_method_return (message);
1741   if (reply == NULL)
1742     goto oom;
1743
1744   pid32 = pid;
1745   if (! dbus_message_append_args (reply,
1746                                   DBUS_TYPE_UINT32, &pid32,
1747                                   DBUS_TYPE_INVALID))
1748     goto oom;
1749
1750   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1751     goto oom;
1752
1753   dbus_message_unref (reply);
1754
1755   return BUS_RESULT_TRUE;
1756
1757  oom:
1758   BUS_SET_OOM (error);
1759
1760  failed:
1761   _DBUS_ASSERT_ERROR_IS_SET (error);
1762   if (reply)
1763     dbus_message_unref (reply);
1764   return BUS_RESULT_FALSE;
1765 }
1766
1767 static BusResult
1768 bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection,
1769                                               BusTransaction *transaction,
1770                                               DBusMessage    *message,
1771                                               DBusError      *error)
1772 {
1773   DBusConnection *conn;
1774   DBusMessage *reply;
1775   void *data = NULL;
1776   dbus_uint32_t data_size;
1777   const char *service;
1778   BusDriverFound found;
1779
1780   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1781
1782   reply = NULL;
1783
1784   found = bus_driver_get_conn_helper (connection, message, "audit session data",
1785                                       &service, &conn, error);
1786
1787   if (found == BUS_DRIVER_FOUND_ERROR)
1788     goto failed;
1789
1790   reply = dbus_message_new_method_return (message);
1791   if (reply == NULL)
1792     goto oom;
1793
1794   /* We don't know how to find "ADT audit session data" for the bus daemon
1795    * itself. Is that even meaningful?
1796    * FIXME: Implement this or briefly note it makes no sense.
1797    */
1798   if (found != BUS_DRIVER_FOUND_PEER ||
1799       !dbus_connection_get_adt_audit_session_data (conn, &data, &data_size) ||
1800       data == NULL)
1801     {
1802       dbus_set_error (error,
1803                       DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN,
1804                       "Could not determine audit session data for '%s'", service);
1805       goto failed;
1806     }
1807
1808   if (! dbus_message_append_args (reply,
1809                                   DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_size,
1810                                   DBUS_TYPE_INVALID))
1811     goto oom;
1812
1813   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1814     goto oom;
1815
1816   dbus_message_unref (reply);
1817
1818   return BUS_RESULT_TRUE;
1819
1820  oom:
1821   BUS_SET_OOM (error);
1822
1823  failed:
1824   _DBUS_ASSERT_ERROR_IS_SET (error);
1825   if (reply)
1826     dbus_message_unref (reply);
1827   return BUS_RESULT_FALSE;
1828 }
1829
1830 static BusResult
1831 bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection,
1832                                                            BusTransaction *transaction,
1833                                                            DBusMessage    *message,
1834                                                            DBusError      *error)
1835 {
1836   DBusConnection *conn;
1837   DBusMessage *reply;
1838   BusSELinuxID *context;
1839   const char *service;
1840   BusDriverFound found;
1841
1842   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1843
1844   reply = NULL;
1845
1846   found = bus_driver_get_conn_helper (connection, message, "security context",
1847                                       &service, &conn, error);
1848
1849   if (found == BUS_DRIVER_FOUND_ERROR)
1850     goto failed;
1851
1852   reply = dbus_message_new_method_return (message);
1853   if (reply == NULL)
1854     goto oom;
1855
1856   /* FIXME: Obtain the SELinux security context for the bus daemon itself */
1857   if (found == BUS_DRIVER_FOUND_PEER)
1858     context = bus_connection_get_selinux_id (conn);
1859   else
1860     context = NULL;
1861
1862   if (!context)
1863     {
1864       dbus_set_error (error,
1865                       DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN,
1866                       "Could not determine security context for '%s'", service);
1867       goto failed;
1868     }
1869
1870   if (! bus_selinux_append_context (reply, context, error))
1871     goto failed;
1872
1873   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1874     goto oom;
1875
1876   dbus_message_unref (reply);
1877
1878   return BUS_RESULT_TRUE;
1879
1880  oom:
1881   BUS_SET_OOM (error);
1882
1883  failed:
1884   _DBUS_ASSERT_ERROR_IS_SET (error);
1885   if (reply)
1886     dbus_message_unref (reply);
1887   return BUS_RESULT_FALSE;
1888 }
1889
1890 static BusResult
1891 bus_driver_handle_get_connection_credentials (DBusConnection *connection,
1892                                               BusTransaction *transaction,
1893                                               DBusMessage    *message,
1894                                               DBusError      *error)
1895 {
1896   DBusConnection *conn;
1897   DBusMessage *reply;
1898   DBusMessageIter reply_iter;
1899   DBusMessageIter array_iter;
1900   unsigned long ulong_uid, ulong_pid;
1901   char *s;
1902   const char *service;
1903   BusDriverFound found;
1904
1905   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1906
1907   reply = NULL;
1908
1909   found = bus_driver_get_conn_helper (connection, message, "credentials",
1910                                       &service, &conn, error);
1911
1912   switch (found)
1913     {
1914       case BUS_DRIVER_FOUND_SELF:
1915         ulong_pid = _dbus_getpid ();
1916         ulong_uid = _dbus_getuid ();
1917         break;
1918
1919       case BUS_DRIVER_FOUND_PEER:
1920         if (!dbus_connection_get_unix_process_id (conn, &ulong_pid))
1921           ulong_pid = DBUS_PID_UNSET;
1922         if (!dbus_connection_get_unix_user (conn, &ulong_uid))
1923           ulong_uid = DBUS_UID_UNSET;
1924         break;
1925       case BUS_DRIVER_FOUND_ERROR:
1926         goto failed;
1927     }
1928
1929   reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter);
1930   if (reply == NULL)
1931     goto oom;
1932
1933   /* we can't represent > 32-bit pids; if your system needs them, please
1934    * add ProcessID64 to the spec or something */
1935   if (ulong_pid <= _DBUS_UINT32_MAX && ulong_pid != DBUS_PID_UNSET &&
1936       !_dbus_asv_add_uint32 (&array_iter, "ProcessID", ulong_pid))
1937     goto oom;
1938
1939   /* we can't represent > 32-bit uids; if your system needs them, please
1940    * add UnixUserID64 to the spec or something */
1941   if (ulong_uid <= _DBUS_UINT32_MAX && ulong_uid != DBUS_UID_UNSET &&
1942       !_dbus_asv_add_uint32 (&array_iter, "UnixUserID", ulong_uid))
1943     goto oom;
1944
1945   /* FIXME: Obtain the Windows user of the bus daemon itself */
1946   if (found == BUS_DRIVER_FOUND_PEER &&
1947       dbus_connection_get_windows_user (conn, &s))
1948     {
1949       DBusString str;
1950       dbus_bool_t result;
1951
1952       if (s == NULL)
1953         goto oom;
1954
1955       _dbus_string_init_const (&str, s);
1956       result = _dbus_validate_utf8 (&str, 0, _dbus_string_get_length (&str));
1957       _dbus_string_free (&str);
1958       if (result)
1959         {
1960           if (!_dbus_asv_add_string (&array_iter, "WindowsSID", s))
1961             {
1962               dbus_free (s);
1963               goto oom;
1964             }
1965         }
1966       dbus_free (s);
1967     }
1968
1969   /* FIXME: Obtain the security label for the bus daemon itself */
1970   if (found == BUS_DRIVER_FOUND_PEER &&
1971       _dbus_connection_get_linux_security_label (conn, &s))
1972     {
1973       if (s == NULL)
1974         goto oom;
1975
1976       /* use the GVariant bytestring convention for strings of unknown
1977        * encoding: include the \0 in the payload, for zero-copy reading */
1978       if (!_dbus_asv_add_byte_array (&array_iter, "LinuxSecurityLabel",
1979                                      s, strlen (s) + 1))
1980         {
1981           dbus_free (s);
1982           goto oom;
1983         }
1984
1985       dbus_free (s);
1986     }
1987
1988 #ifdef DBUS_ENABLE_SMACK
1989   {
1990     const char *smack_label;
1991     if (dbus_connection_get_smack_label (conn, &smack_label)) {
1992       if (!_dbus_asv_add_string (&array_iter, "SmackLabel", smack_label))
1993         goto oom;
1994     }
1995   }
1996 #endif
1997
1998   if (!_dbus_asv_close (&reply_iter, &array_iter))
1999     goto oom;
2000
2001   if (! bus_transaction_send_from_driver (transaction, connection, reply))
2002     {
2003       /* this time we don't want to close the iterator again, so just
2004        * get rid of the message */
2005       dbus_message_unref (reply);
2006       reply = NULL;
2007       goto oom;
2008     }
2009
2010   dbus_message_unref (reply);
2011
2012   return BUS_RESULT_TRUE;
2013
2014  oom:
2015   BUS_SET_OOM (error);
2016
2017  failed:
2018   _DBUS_ASSERT_ERROR_IS_SET (error);
2019
2020   if (reply)
2021     {
2022       _dbus_asv_abandon (&reply_iter, &array_iter);
2023       dbus_message_unref (reply);
2024     }
2025
2026   return BUS_RESULT_FALSE;
2027 }
2028
2029 static BusResult
2030 bus_driver_handle_reload_config (DBusConnection *connection,
2031                                  BusTransaction *transaction,
2032                                  DBusMessage    *message,
2033                                  DBusError      *error)
2034 {
2035   BusContext *context;
2036   DBusMessage *reply;
2037
2038   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2039
2040   reply = NULL;
2041
2042   context = bus_connection_get_context (connection);
2043   if (!bus_context_reload_config (context, error))
2044     goto failed;
2045
2046   reply = dbus_message_new_method_return (message);
2047   if (reply == NULL)
2048     goto oom;
2049
2050   if (! bus_transaction_send_from_driver (transaction, connection, reply))
2051     goto oom;
2052
2053   dbus_message_unref (reply);
2054   return BUS_RESULT_TRUE;
2055
2056  oom:
2057   BUS_SET_OOM (error);
2058
2059  failed:
2060   _DBUS_ASSERT_ERROR_IS_SET (error);
2061   if (reply)
2062     dbus_message_unref (reply);
2063   return BUS_RESULT_FALSE;
2064 }
2065
2066 #ifdef DBUS_ENABLE_VERBOSE_MODE
2067 static dbus_bool_t
2068 bus_driver_handle_enable_verbose (DBusConnection *connection,
2069                                   BusTransaction *transaction,
2070                                   DBusMessage    *message,
2071                                   DBusError      *error)
2072 {
2073     DBusMessage *reply = NULL;
2074
2075     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2076
2077     reply = dbus_message_new_method_return (message);
2078     if (reply == NULL)
2079       goto oom;
2080
2081     if (! bus_transaction_send_from_driver (transaction, connection, reply))
2082       goto oom;
2083
2084     _dbus_set_verbose(TRUE);
2085
2086     dbus_message_unref (reply);
2087     return TRUE;
2088
2089    oom:
2090     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2091
2092     BUS_SET_OOM (error);
2093
2094     if (reply)
2095       dbus_message_unref (reply);
2096     return FALSE;
2097 }
2098
2099 static dbus_bool_t
2100 bus_driver_handle_disable_verbose (DBusConnection *connection,
2101                                    BusTransaction *transaction,
2102                                    DBusMessage    *message,
2103                                    DBusError      *error)
2104 {
2105     DBusMessage *reply = NULL;
2106
2107     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2108
2109     reply = dbus_message_new_method_return (message);
2110     if (reply == NULL)
2111       goto oom;
2112
2113     if (! bus_transaction_send_from_driver (transaction, connection, reply))
2114       goto oom;
2115
2116     _dbus_set_verbose(FALSE);
2117
2118     dbus_message_unref (reply);
2119     return TRUE;
2120
2121    oom:
2122     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2123
2124     BUS_SET_OOM (error);
2125
2126     if (reply)
2127       dbus_message_unref (reply);
2128     return FALSE;
2129 }
2130 #endif
2131
2132 static BusResult
2133 bus_driver_handle_get_id (DBusConnection *connection,
2134                           BusTransaction *transaction,
2135                           DBusMessage    *message,
2136                           DBusError      *error)
2137 {
2138   BusContext *context;
2139   DBusMessage *reply;
2140   DBusString uuid;
2141   const char *v_STRING;
2142
2143   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2144
2145   if (!_dbus_string_init (&uuid))
2146     {
2147       BUS_SET_OOM (error);
2148       return BUS_RESULT_FALSE;
2149     }
2150
2151   reply = NULL;
2152
2153   context = bus_connection_get_context (connection);
2154   if (!bus_context_get_id (context, &uuid))
2155     goto oom;
2156
2157   reply = dbus_message_new_method_return (message);
2158   if (reply == NULL)
2159     goto oom;
2160
2161   v_STRING = _dbus_string_get_const_data (&uuid);
2162   if (!dbus_message_append_args (reply,
2163                                  DBUS_TYPE_STRING, &v_STRING,
2164                                  DBUS_TYPE_INVALID))
2165     goto oom;
2166
2167   _dbus_assert (dbus_message_has_signature (reply, "s"));
2168
2169   if (! bus_transaction_send_from_driver (transaction, connection, reply))
2170     goto oom;
2171
2172   _dbus_string_free (&uuid);
2173   dbus_message_unref (reply);
2174   return BUS_RESULT_TRUE;
2175
2176  oom:
2177   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2178
2179   BUS_SET_OOM (error);
2180
2181   if (reply)
2182     dbus_message_unref (reply);
2183   _dbus_string_free (&uuid);
2184   return BUS_RESULT_FALSE;
2185 }
2186
2187 static dbus_bool_t
2188 bus_driver_handle_become_monitor (DBusConnection *connection,
2189                                   BusTransaction *transaction,
2190                                   DBusMessage    *message,
2191                                   DBusError      *error)
2192 {
2193   char **match_rules = NULL;
2194   const char *bustype;
2195   BusContext *context;
2196   BusMatchRule *rule;
2197   DBusList *rules = NULL;
2198   DBusList *iter;
2199   DBusString str;
2200   int i;
2201   int n_match_rules;
2202   dbus_uint32_t flags;
2203   dbus_bool_t ret = FALSE;
2204
2205   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2206
2207   if (!bus_driver_check_message_is_for_us (message, error))
2208     goto out;
2209
2210   context = bus_transaction_get_context (transaction);
2211   bustype = context ? bus_context_get_type (context) : NULL;
2212   if (!bus_apparmor_allows_eavesdropping (connection, bustype, error))
2213     goto out;
2214
2215   if (!bus_driver_check_caller_is_privileged (connection, transaction,
2216                                               message, error))
2217     goto out;
2218
2219   if (!dbus_message_get_args (message, error,
2220         DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &match_rules, &n_match_rules,
2221         DBUS_TYPE_UINT32, &flags,
2222         DBUS_TYPE_INVALID))
2223     goto out;
2224
2225   if (flags != 0)
2226     {
2227       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2228           "BecomeMonitor does not support any flags yet");
2229       goto out;
2230     }
2231
2232   /* Special case: a zero-length array becomes [""] */
2233   if (n_match_rules == 0)
2234     {
2235       match_rules = dbus_malloc (2 * sizeof (char *));
2236
2237       if (match_rules == NULL)
2238         {
2239           BUS_SET_OOM (error);
2240           goto out;
2241         }
2242
2243       match_rules[0] = _dbus_strdup ("");
2244
2245       if (match_rules[0] == NULL)
2246         {
2247           BUS_SET_OOM (error);
2248           goto out;
2249         }
2250
2251       match_rules[1] = NULL;
2252       n_match_rules = 1;
2253     }
2254
2255   for (i = 0; i < n_match_rules; i++)
2256     {
2257       _dbus_string_init_const (&str, match_rules[i]);
2258       rule = bus_match_rule_parse (connection, &str, error);
2259
2260       if (rule == NULL)
2261         goto out;
2262
2263       /* monitors always eavesdrop */
2264       bus_match_rule_set_client_is_eavesdropping (rule, TRUE);
2265
2266       if (!_dbus_list_append (&rules, rule))
2267         {
2268           BUS_SET_OOM (error);
2269           bus_match_rule_unref (rule);
2270           goto out;
2271         }
2272     }
2273
2274   /* Send the ack before we remove the rule, since the ack is undone
2275    * on transaction cancel, but becoming a monitor isn't.
2276    */
2277   if (!send_ack_reply (connection, transaction, message, error))
2278     goto out;
2279
2280   if (!bus_connection_be_monitor (connection, transaction, &rules, error))
2281     goto out;
2282
2283   ret = TRUE;
2284
2285 out:
2286   if (ret)
2287     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2288   else
2289     _DBUS_ASSERT_ERROR_IS_SET (error);
2290
2291   for (iter = _dbus_list_get_first_link (&rules);
2292       iter != NULL;
2293       iter = _dbus_list_get_next_link (&rules, iter))
2294     bus_match_rule_unref (iter->data);
2295
2296   _dbus_list_clear (&rules);
2297
2298   dbus_free_string_array (match_rules);
2299   return ret;
2300 }
2301
2302 typedef struct
2303 {
2304   const char *name;
2305   const char *in_args;
2306   const char *out_args;
2307   BusResult (* handler) (DBusConnection *connection,
2308                          BusTransaction *transaction,
2309                          DBusMessage    *message,
2310                          DBusError      *error);
2311 } MessageHandler;
2312
2313 /* For speed it might be useful to sort this in order of
2314  * frequency of use (but doesn't matter with only a few items
2315  * anyhow)
2316  */
2317 static const MessageHandler dbus_message_handlers[] = {
2318   { "Hello",
2319     "",
2320     DBUS_TYPE_STRING_AS_STRING,
2321     bus_driver_handle_hello },
2322   { "RequestName",
2323     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
2324     DBUS_TYPE_UINT32_AS_STRING,
2325     bus_driver_handle_acquire_service },
2326   { "ReleaseName",
2327     DBUS_TYPE_STRING_AS_STRING,
2328     DBUS_TYPE_UINT32_AS_STRING,
2329     bus_driver_handle_release_service },
2330   { "StartServiceByName",
2331     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
2332     DBUS_TYPE_UINT32_AS_STRING,
2333     bus_driver_handle_activate_service },
2334   { "UpdateActivationEnvironment",
2335     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,
2336     "",
2337     bus_driver_handle_update_activation_environment },
2338   { "NameHasOwner",
2339     DBUS_TYPE_STRING_AS_STRING,
2340     DBUS_TYPE_BOOLEAN_AS_STRING,
2341     bus_driver_handle_service_exists },
2342   { "ListNames",
2343     "",
2344     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
2345     bus_driver_handle_list_services },
2346   { "ListActivatableNames",
2347     "",
2348     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
2349     bus_driver_handle_list_activatable_services },
2350   { "AddMatch",
2351     DBUS_TYPE_STRING_AS_STRING,
2352     "",
2353     bus_driver_handle_add_match },
2354   { "RemoveMatch",
2355     DBUS_TYPE_STRING_AS_STRING,
2356     "",
2357     bus_driver_handle_remove_match },
2358   { "GetNameOwner",
2359     DBUS_TYPE_STRING_AS_STRING,
2360     DBUS_TYPE_STRING_AS_STRING,
2361     bus_driver_handle_get_service_owner },
2362   { "ListQueuedOwners",
2363     DBUS_TYPE_STRING_AS_STRING,
2364     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
2365     bus_driver_handle_list_queued_owners },
2366   { "GetConnectionUnixUser",
2367     DBUS_TYPE_STRING_AS_STRING,
2368     DBUS_TYPE_UINT32_AS_STRING,
2369     bus_driver_handle_get_connection_unix_user },
2370   { "GetConnectionUnixProcessID",
2371     DBUS_TYPE_STRING_AS_STRING,
2372     DBUS_TYPE_UINT32_AS_STRING,
2373     bus_driver_handle_get_connection_unix_process_id },
2374   { "GetAdtAuditSessionData",
2375     DBUS_TYPE_STRING_AS_STRING,
2376     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
2377     bus_driver_handle_get_adt_audit_session_data },
2378   { "GetConnectionSELinuxSecurityContext",
2379     DBUS_TYPE_STRING_AS_STRING,
2380     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
2381     bus_driver_handle_get_connection_selinux_security_context },
2382   { "ReloadConfig",
2383     "",
2384     "",
2385     bus_driver_handle_reload_config },
2386   { "GetId",
2387     "",
2388     DBUS_TYPE_STRING_AS_STRING,
2389     bus_driver_handle_get_id },
2390   { "GetConnectionCredentials", "s", "a{sv}",
2391     bus_driver_handle_get_connection_credentials },
2392   { "GetConnectionSmackContext",
2393     DBUS_TYPE_STRING_AS_STRING,
2394     DBUS_TYPE_STRING_AS_STRING,
2395     bus_smack_handle_get_connection_context },
2396   { NULL, NULL, NULL, NULL }
2397 };
2398
2399 static BusResult bus_driver_handle_introspect (DBusConnection *,
2400     BusTransaction *, DBusMessage *, DBusError *);
2401
2402 static const MessageHandler introspectable_message_handlers[] = {
2403   { "Introspect", "", DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_introspect },
2404   { NULL, NULL, NULL, NULL }
2405 };
2406
2407 static const MessageHandler monitoring_message_handlers[] = {
2408   { "BecomeMonitor", "asu", "", bus_driver_handle_become_monitor },
2409   { NULL, NULL, NULL, NULL }
2410 };
2411
2412 #ifdef DBUS_ENABLE_VERBOSE_MODE
2413 static const MessageHandler verbose_message_handlers[] = {
2414   { "EnableVerbose", "", "", bus_driver_handle_enable_verbose},
2415   { "DisableVerbose", "", "", bus_driver_handle_disable_verbose},
2416   { NULL, NULL, NULL, NULL }
2417 };
2418 #endif
2419
2420 #ifdef DBUS_ENABLE_STATS
2421 static const MessageHandler stats_message_handlers[] = {
2422   { "GetStats", "", "a{sv}", bus_stats_handle_get_stats },
2423   { "GetConnectionStats", "s", "a{sv}", bus_stats_handle_get_connection_stats },
2424   { "GetAllMatchRules", "", "a{sas}", bus_stats_handle_get_all_match_rules },
2425   { NULL, NULL, NULL, NULL }
2426 };
2427 #endif
2428
2429 typedef struct {
2430   const char *name;
2431   const MessageHandler *message_handlers;
2432   const char *extra_introspection;
2433 } InterfaceHandler;
2434
2435 /* These should ideally be sorted by frequency of use, although it
2436  * probably doesn't matter with this few items */
2437 static InterfaceHandler interface_handlers[] = {
2438   { DBUS_INTERFACE_DBUS, dbus_message_handlers,
2439     "    <signal name=\"NameOwnerChanged\">\n"
2440     "      <arg type=\"s\"/>\n"
2441     "      <arg type=\"s\"/>\n"
2442     "      <arg type=\"s\"/>\n"
2443     "    </signal>\n"
2444     "    <signal name=\"NameLost\">\n"
2445     "      <arg type=\"s\"/>\n"
2446     "    </signal>\n"
2447     "    <signal name=\"NameAcquired\">\n"
2448     "      <arg type=\"s\"/>\n"
2449     "    </signal>\n" },
2450   { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL },
2451   { DBUS_INTERFACE_MONITORING, monitoring_message_handlers, NULL },
2452 #ifdef DBUS_ENABLE_VERBOSE_MODE
2453   { DBUS_INTERFACE_VERBOSE, verbose_message_handlers, NULL },
2454 #endif
2455 #ifdef DBUS_ENABLE_STATS
2456   { BUS_INTERFACE_STATS, stats_message_handlers, NULL },
2457 #endif
2458   { NULL, NULL, NULL }
2459 };
2460
2461 static dbus_bool_t
2462 write_args_for_direction (DBusString *xml,
2463                           const char *signature,
2464                           dbus_bool_t in)
2465 {
2466   DBusTypeReader typereader;
2467   DBusString sigstr;
2468   int current_type;
2469
2470   _dbus_string_init_const (&sigstr, signature);
2471   _dbus_type_reader_init_types_only (&typereader, &sigstr, 0);
2472
2473   while ((current_type = _dbus_type_reader_get_current_type (&typereader)) != DBUS_TYPE_INVALID)
2474     {
2475       const DBusString *subsig;
2476       int start, len;
2477
2478       _dbus_type_reader_get_signature (&typereader, &subsig, &start, &len);
2479       if (!_dbus_string_append_printf (xml, "      <arg direction=\"%s\" type=\"",
2480                                        in ? "in" : "out"))
2481         goto oom;
2482       if (!_dbus_string_append_len (xml,
2483                                     _dbus_string_get_const_data (subsig) + start,
2484                                     len))
2485         goto oom;
2486       if (!_dbus_string_append (xml, "\"/>\n"))
2487         goto oom;
2488
2489       _dbus_type_reader_next (&typereader);
2490     }
2491   return TRUE;
2492  oom:
2493   return FALSE;
2494 }
2495
2496 dbus_bool_t
2497 bus_driver_generate_introspect_string (DBusString *xml)
2498 {
2499   const InterfaceHandler *ih;
2500   const MessageHandler *mh;
2501
2502   if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
2503     return FALSE;
2504   if (!_dbus_string_append (xml, "<node>\n"))
2505     return FALSE;
2506
2507   for (ih = interface_handlers; ih->name != NULL; ih++)
2508     {
2509       if (!_dbus_string_append_printf (xml, "  <interface name=\"%s\">\n",
2510                                        ih->name))
2511         return FALSE;
2512
2513       for (mh = ih->message_handlers; mh->name != NULL; mh++)
2514         {
2515           if (!_dbus_string_append_printf (xml, "    <method name=\"%s\">\n",
2516                                            mh->name))
2517             return FALSE;
2518
2519           if (!write_args_for_direction (xml, mh->in_args, TRUE))
2520             return FALSE;
2521
2522           if (!write_args_for_direction (xml, mh->out_args, FALSE))
2523             return FALSE;
2524
2525           if (!_dbus_string_append (xml, "    </method>\n"))
2526             return FALSE;
2527         }
2528
2529       if (ih->extra_introspection != NULL &&
2530           !_dbus_string_append (xml, ih->extra_introspection))
2531         return FALSE;
2532
2533       if (!_dbus_string_append (xml, "  </interface>\n"))
2534         return FALSE;
2535     }
2536
2537   if (!_dbus_string_append (xml, "</node>\n"))
2538     return FALSE;
2539
2540   return TRUE;
2541 }
2542
2543 static BusResult
2544 bus_driver_handle_introspect (DBusConnection *connection,
2545                               BusTransaction *transaction,
2546                               DBusMessage    *message,
2547                               DBusError      *error)
2548 {
2549   DBusString xml;
2550   DBusMessage *reply;
2551   const char *v_STRING;
2552
2553   _dbus_verbose ("Introspect() on bus driver\n");
2554
2555   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2556
2557   reply = NULL;
2558
2559   if (! dbus_message_get_args (message, error,
2560                                DBUS_TYPE_INVALID))
2561     {
2562       _DBUS_ASSERT_ERROR_IS_SET (error);
2563       return BUS_RESULT_FALSE;
2564     }
2565
2566   if (!_dbus_string_init (&xml))
2567     {
2568       BUS_SET_OOM (error);
2569       return BUS_RESULT_FALSE;
2570     }
2571
2572   if (!bus_driver_generate_introspect_string (&xml))
2573     goto oom;
2574
2575   v_STRING = _dbus_string_get_const_data (&xml);
2576
2577   reply = dbus_message_new_method_return (message);
2578   if (reply == NULL)
2579     goto oom;
2580
2581   if (! dbus_message_append_args (reply,
2582                                   DBUS_TYPE_STRING, &v_STRING,
2583                                   DBUS_TYPE_INVALID))
2584     goto oom;
2585
2586   if (! bus_transaction_send_from_driver (transaction, connection, reply))
2587     goto oom;
2588
2589   dbus_message_unref (reply);
2590   _dbus_string_free (&xml);
2591
2592   return BUS_RESULT_TRUE;
2593
2594  oom:
2595   BUS_SET_OOM (error);
2596
2597   if (reply)
2598     dbus_message_unref (reply);
2599
2600   _dbus_string_free (&xml);
2601
2602   return BUS_RESULT_FALSE;
2603 }
2604
2605 /*
2606  * Set @error and return FALSE if the message is not directed to the
2607  * dbus-daemon by its canonical object path. This is hardening against
2608  * system services with poorly-written security policy files, which
2609  * might allow sending dangerously broad equivalence classes of messages
2610  * such as "anything with this assumed-to-be-safe object path".
2611  *
2612  * dbus-daemon is unusual in that it normally ignores the object path
2613  * of incoming messages; we need to keep that behaviour for the "read"
2614  * read-only method calls like GetConnectionUnixUser for backwards
2615  * compatibility, but it seems safer to be more restrictive for things
2616  * intended to be root-only or privileged-developers-only.
2617  *
2618  * It is possible that there are other system services with the same
2619  * quirk as dbus-daemon.
2620  */
2621 dbus_bool_t
2622 bus_driver_check_message_is_for_us (DBusMessage *message,
2623                                     DBusError   *error)
2624 {
2625   if (!dbus_message_has_path (message, DBUS_PATH_DBUS))
2626     {
2627       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
2628           "Method '%s' is only available at the canonical object path '%s'",
2629           dbus_message_get_member (message), DBUS_PATH_DBUS);
2630
2631       return FALSE;
2632     }
2633
2634   return TRUE;
2635 }
2636
2637 BusResult
2638 bus_driver_handle_message (DBusConnection *connection,
2639                            BusTransaction *transaction,
2640                            DBusMessage    *message,
2641                            DBusError      *error)
2642 {
2643   const char *name, *interface;
2644   const InterfaceHandler *ih;
2645   const MessageHandler *mh;
2646   dbus_bool_t found_interface = FALSE;
2647
2648   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2649
2650   if (dbus_message_is_signal (message, "org.freedesktop.systemd1.Activator", "ActivationFailure"))
2651     {
2652       BusContext *context;
2653       DBusConnection *systemd;
2654
2655       context = bus_connection_get_context (connection);
2656       systemd = bus_driver_get_owner_of_name (connection,
2657           "org.freedesktop.systemd1");
2658
2659       if (systemd != connection)
2660         {
2661           const char *attacker;
2662
2663           attacker = bus_connection_get_name (connection);
2664           bus_context_log (context, DBUS_SYSTEM_LOG_SECURITY,
2665                            "Ignoring forged ActivationFailure message from "
2666                            "connection %s (%s)",
2667                            attacker ? attacker : "(unauthenticated)",
2668                            bus_connection_get_loginfo (connection));
2669           /* ignore it */
2670           return BUS_RESULT_TRUE;
2671         }
2672
2673       return dbus_activation_systemd_failure(bus_context_get_activation(context), message) == TRUE ? BUS_RESULT_TRUE : BUS_RESULT_FALSE;
2674     }
2675
2676   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
2677     {
2678       _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
2679       return BUS_RESULT_TRUE; /* we just ignore this */
2680     }
2681
2682   /* may be NULL, which means "any interface will do" */
2683   interface = dbus_message_get_interface (message);
2684
2685   _dbus_assert (dbus_message_get_member (message) != NULL);
2686
2687   name = dbus_message_get_member (message);
2688
2689   _dbus_verbose ("Driver got a method call: %s\n", name);
2690
2691   /* security checks should have kept this from getting here */
2692   _dbus_assert (dbus_message_get_sender (message) != NULL ||
2693                 strcmp (name, "Hello") == 0);
2694
2695   for (ih = interface_handlers; ih->name != NULL; ih++)
2696     {
2697       if (interface != NULL && strcmp (interface, ih->name) != 0)
2698         continue;
2699
2700       found_interface = TRUE;
2701
2702       for (mh = ih->message_handlers; mh->name != NULL; mh++)
2703         {
2704           if (strcmp (mh->name, name) != 0)
2705             continue;
2706
2707           _dbus_verbose ("Found driver handler for %s\n", name);
2708
2709           if (!dbus_message_has_signature (message, mh->in_args))
2710             {
2711               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2712               _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n",
2713                              name, dbus_message_get_signature (message),
2714                              mh->in_args);
2715
2716               dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2717                               "Call to %s has wrong args (%s, expected %s)\n",
2718                               name, dbus_message_get_signature (message),
2719                               mh->in_args);
2720               _DBUS_ASSERT_ERROR_IS_SET (error);
2721               return BUS_RESULT_FALSE;
2722             }
2723
2724           switch ((* mh->handler) (connection, transaction, message, error))
2725             {
2726               case BUS_RESULT_TRUE:
2727                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2728                 _dbus_verbose ("Driver handler succeeded\n");
2729                 return BUS_RESULT_TRUE;
2730               case BUS_RESULT_FALSE:
2731                 _DBUS_ASSERT_ERROR_IS_SET (error);
2732                 _dbus_verbose ("Driver handler returned failure\n");
2733                 return BUS_RESULT_FALSE;
2734               case BUS_RESULT_LATER:
2735                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2736                 _dbus_verbose ("Driver handler delayed message processing due to policy check\n");
2737                 return BUS_RESULT_LATER;
2738             }
2739         }
2740     }
2741
2742   _dbus_verbose ("No driver handler for message \"%s\"\n",
2743                  name);
2744
2745   dbus_set_error (error, found_interface ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_INTERFACE,
2746                   "%s does not understand message %s",
2747                   DBUS_SERVICE_DBUS, name);
2748
2749   return BUS_RESULT_FALSE;
2750 }
2751
2752 void
2753 bus_driver_remove_connection (DBusConnection *connection)
2754 {
2755   /* FIXME 1.0 Does nothing for now, should unregister the connection
2756    * with the bus driver.
2757    */
2758 }