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