bus: Assign a serial number for messages from the driver
[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 static inline const char *
47 nonnull (const char *maybe_null,
48          const char *if_null)
49 {
50   return (maybe_null ? maybe_null : if_null);
51 }
52
53 static DBusConnection *
54 bus_driver_get_owner_of_name (DBusConnection *connection,
55                               const char     *name)
56 {
57   BusRegistry *registry;
58   BusService *serv;
59   DBusString str;
60
61   registry = bus_connection_get_registry (connection);
62   _dbus_string_init_const (&str, name);
63   serv = bus_registry_lookup (registry, &str);
64
65   if (serv == NULL)
66     return NULL;
67
68   return bus_service_get_primary_owners_connection (serv);
69 }
70
71 BusDriverFound
72 bus_driver_get_conn_helper (DBusConnection  *connection,
73                             DBusMessage     *message,
74                             const char      *what_we_want,
75                             const char     **name_p,
76                             DBusConnection **peer_conn_p,
77                             DBusError       *error)
78 {
79   DBusConnection *conn;
80   const char *name;
81
82   if (!dbus_message_get_args (message, error,
83                               DBUS_TYPE_STRING, &name,
84                               DBUS_TYPE_INVALID))
85     return BUS_DRIVER_FOUND_ERROR;
86
87   _dbus_assert (name != NULL);
88   _dbus_verbose ("asked for %s of connection %s\n", what_we_want, name);
89
90   if (name_p != NULL)
91     *name_p = name;
92
93   if (strcmp (name, DBUS_SERVICE_DBUS) == 0)
94     return BUS_DRIVER_FOUND_SELF;
95
96   conn = bus_driver_get_owner_of_name (connection, name);
97
98   if (conn == NULL)
99     {
100       dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
101                       "Could not get %s of name '%s': no such name",
102                       what_we_want, name);
103       return BUS_DRIVER_FOUND_ERROR;
104     }
105
106   if (peer_conn_p != NULL)
107     *peer_conn_p = conn;
108
109   return BUS_DRIVER_FOUND_PEER;
110 }
111
112 /*
113  * Log a security warning and set error unless the uid of the connection
114  * is either the uid of this process, or on Unix, uid 0 (root).
115  *
116  * This is intended to be a second line of defence after <deny> rules,
117  * to mitigate incorrect system bus security policy configuration files
118  * like the ones in CVE-2014-8148 and CVE-2014-8156, and (if present)
119  * LSM rules; so it doesn't need to be perfect, but as long as we have
120  * potentially dangerous functionality in the system bus, it does need
121  * to exist.
122  */
123 static dbus_bool_t
124 bus_driver_check_caller_is_privileged (DBusConnection *connection,
125                                        BusTransaction *transaction,
126                                        DBusMessage    *message,
127                                        DBusError      *error)
128 {
129 #ifdef DBUS_UNIX
130   unsigned long uid;
131
132   if (!dbus_connection_get_unix_user (connection, &uid))
133     {
134       const char *method = dbus_message_get_member (message);
135
136       bus_context_log_and_set_error (bus_transaction_get_context (transaction),
137           DBUS_SYSTEM_LOG_SECURITY, error, DBUS_ERROR_ACCESS_DENIED,
138           "rejected attempt to call %s by connection %s (%s) with "
139           "unknown uid", method,
140           nonnull (bus_connection_get_name (connection), "(inactive)"),
141           bus_connection_get_loginfo (connection));
142       return FALSE;
143     }
144
145   /* I'm writing it in this slightly strange form so that it's more
146    * obvious that this security-sensitive code is correct.
147    */
148   if (_dbus_unix_user_is_process_owner (uid))
149     {
150       /* OK */
151     }
152   else if (uid == 0)
153     {
154       /* OK */
155     }
156   else
157     {
158       const char *method = dbus_message_get_member (message);
159
160       bus_context_log_and_set_error (bus_transaction_get_context (transaction),
161           DBUS_SYSTEM_LOG_SECURITY, error, DBUS_ERROR_ACCESS_DENIED,
162           "rejected attempt to call %s by connection %s (%s) with "
163           "uid %lu", method,
164           nonnull (bus_connection_get_name (connection), "(inactive)"),
165           bus_connection_get_loginfo (connection), uid);
166       return FALSE;
167     }
168
169   return TRUE;
170 #elif defined(DBUS_WIN)
171   char *windows_sid = NULL;
172   dbus_bool_t ret = FALSE;
173
174   if (!dbus_connection_get_windows_user (connection, &windows_sid))
175     {
176       const char *method = dbus_message_get_member (message);
177
178       bus_context_log_and_set_error (bus_transaction_get_context (transaction),
179           DBUS_SYSTEM_LOG_SECURITY, error, DBUS_ERROR_ACCESS_DENIED,
180           "rejected attempt to call %s by unknown uid", method);
181       goto out;
182     }
183
184   if (!_dbus_windows_user_is_process_owner (windows_sid))
185     {
186       const char *method = dbus_message_get_member (message);
187
188       bus_context_log_and_set_error (bus_transaction_get_context (transaction),
189           DBUS_SYSTEM_LOG_SECURITY, error, DBUS_ERROR_ACCESS_DENIED,
190           "rejected attempt to call %s by uid %s", method, windows_sid);
191       goto out;
192     }
193
194   ret = TRUE;
195 out:
196   dbus_free (windows_sid);
197   return ret;
198 #else
199   /* make sure we fail closed in the hypothetical case that we are neither
200    * Unix nor Windows */
201   dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
202       "please teach bus/driver.c how uids work on this platform");
203   return FALSE;
204 #endif
205 }
206
207 static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
208                                                     DBusMessage    *hello_message,
209                                                     BusTransaction *transaction,
210                                                     DBusError      *error);
211
212 dbus_bool_t
213 bus_driver_send_connection_overflow (DBusConnection *connection,
214                                      BusTransaction *transaction,
215                                      DBusError      *error)
216 {
217   DBusMessage *message;
218   dbus_bool_t retval;
219   const char *name;
220
221   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
222
223   message = dbus_message_new_signal (DBUS_PATH_DBUS,
224                                      DBUS_INTERFACE_TIZEN,
225                                      DBUS_TIZEN_CONNECTION_OVERFLOW_SIGNAL);
226
227   if (message == NULL)
228     {
229       BUS_SET_OOM (error);
230       return FALSE;
231     }
232
233   if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
234     goto oom;
235
236   name = bus_connection_get_name (connection);
237
238   if (!dbus_message_append_args (message,
239                                  DBUS_TYPE_STRING, &name,
240                                  DBUS_TYPE_INVALID))
241     goto oom;
242
243   _dbus_assert (dbus_message_has_signature (message, "s"));
244
245   if (!bus_transaction_capture (transaction, NULL, NULL, message))
246     goto oom;
247
248   switch (bus_dispatch_matches (transaction, NULL, NULL, message, NULL, error))
249     {
250     case BUS_RESULT_TRUE:
251       retval = TRUE;
252       break;
253     case BUS_RESULT_FALSE:
254       retval = FALSE;
255       break;
256     case BUS_RESULT_LATER:
257     default:
258       /* should never happen */
259       _dbus_assert_not_reached ("bus_dispatch_matches returned BUS_RESULT_LATER unexpectedly");
260       retval = FALSE;
261       break;
262     }
263   dbus_message_unref (message);
264
265   return retval;
266
267  oom:
268   dbus_message_unref (message);
269   BUS_SET_OOM (error);
270   return FALSE;
271 }
272
273 dbus_bool_t
274 bus_driver_send_service_owner_changed (const char     *service_name,
275                                        const char     *old_owner,
276                                        const char     *new_owner,
277                                        BusTransaction *transaction,
278                                        DBusError      *error)
279 {
280   DBusMessage *message;
281   dbus_bool_t retval;
282   const char *null_service;
283
284   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
285
286   null_service = "";
287   _dbus_verbose ("sending name owner changed: %s [%s -> %s]\n",
288                  service_name,
289                  old_owner ? old_owner : null_service,
290                  new_owner ? new_owner : null_service);
291
292   message = dbus_message_new_signal (DBUS_PATH_DBUS,
293                                      DBUS_INTERFACE_DBUS,
294                                      "NameOwnerChanged");
295
296   if (message == NULL)
297     {
298       BUS_SET_OOM (error);
299       return FALSE;
300     }
301
302   if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
303     goto oom;
304
305   if (!dbus_message_append_args (message,
306                                  DBUS_TYPE_STRING, &service_name,
307                                  DBUS_TYPE_STRING, old_owner ? &old_owner : &null_service,
308                                  DBUS_TYPE_STRING, new_owner ? &new_owner : &null_service,
309                                  DBUS_TYPE_INVALID))
310     goto oom;
311
312   _dbus_assert (dbus_message_has_signature (message, "sss"));
313
314   if (!bus_transaction_capture (transaction, NULL, NULL, message))
315     goto oom;
316
317   switch (bus_dispatch_matches (transaction, NULL, NULL, message, NULL, error))
318     {
319     case BUS_RESULT_TRUE:
320       retval = TRUE;
321       break;
322     case BUS_RESULT_FALSE:
323       retval = FALSE;
324       break;
325     default:
326       /* should never happen */
327       _dbus_assert_not_reached ("bus_dispatch_matches returned BUS_RESULT_LATER unexpectedly");
328       retval = FALSE;
329       break;
330     }
331   dbus_message_unref (message);
332
333   return retval;
334
335  oom:
336   dbus_message_unref (message);
337   BUS_SET_OOM (error);
338   return FALSE;
339 }
340
341 dbus_bool_t
342 bus_driver_send_service_lost (DBusConnection *connection,
343                               const char     *service_name,
344                               BusTransaction *transaction,
345                               DBusError      *error)
346 {
347   DBusMessage *message;
348
349   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
350
351   message = dbus_message_new_signal (DBUS_PATH_DBUS,
352                                      DBUS_INTERFACE_DBUS,
353                                      "NameLost");
354
355   if (message == NULL)
356     {
357       BUS_SET_OOM (error);
358       return FALSE;
359     }
360
361   if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
362       !dbus_message_append_args (message,
363                                  DBUS_TYPE_STRING, &service_name,
364                                  DBUS_TYPE_INVALID))
365     {
366       dbus_message_unref (message);
367       BUS_SET_OOM (error);
368       return FALSE;
369     }
370
371   if (!bus_transaction_send_from_driver (transaction, connection, message))
372     {
373       dbus_message_unref (message);
374       BUS_SET_OOM (error);
375       return FALSE;
376     }
377   else
378     {
379       dbus_message_unref (message);
380       return TRUE;
381     }
382 }
383
384 dbus_bool_t
385 bus_driver_send_service_acquired (DBusConnection *connection,
386                                   const char     *service_name,
387                                   BusTransaction *transaction,
388                                   DBusError      *error)
389 {
390   DBusMessage *message;
391
392   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
393
394   message = dbus_message_new_signal (DBUS_PATH_DBUS,
395                                      DBUS_INTERFACE_DBUS,
396                                      "NameAcquired");
397
398   if (message == NULL)
399     {
400       BUS_SET_OOM (error);
401       return FALSE;
402     }
403
404   if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
405       !dbus_message_append_args (message,
406                                  DBUS_TYPE_STRING, &service_name,
407                                  DBUS_TYPE_INVALID))
408     {
409       dbus_message_unref (message);
410       BUS_SET_OOM (error);
411       return FALSE;
412     }
413
414   if (!bus_transaction_send_from_driver (transaction, connection, message))
415     {
416       dbus_message_unref (message);
417       BUS_SET_OOM (error);
418       return FALSE;
419     }
420   else
421     {
422       dbus_message_unref (message);
423       return TRUE;
424     }
425 }
426
427 static dbus_bool_t
428 create_unique_client_name (BusRegistry *registry,
429                            DBusString  *str)
430 {
431   /* We never want to use the same unique client name twice, because
432    * we want to guarantee that if you send a message to a given unique
433    * name, you always get the same application. So we use two numbers
434    * for INT_MAX * INT_MAX combinations, should be pretty safe against
435    * wraparound.
436    */
437   /* FIXME these should be in BusRegistry rather than static vars */
438   static int next_major_number = 0;
439   static int next_minor_number = 0;
440   int len;
441
442   len = _dbus_string_get_length (str);
443
444   while (TRUE)
445     {
446       /* start out with 1-0, go to 1-1, 1-2, 1-3,
447        * up to 1-MAXINT, then 2-0, 2-1, etc.
448        */
449       if (next_minor_number <= 0)
450         {
451           next_major_number += 1;
452           next_minor_number = 0;
453           if (next_major_number <= 0)
454             _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
455         }
456
457       _dbus_assert (next_major_number > 0);
458       _dbus_assert (next_minor_number >= 0);
459
460       /* appname:MAJOR-MINOR */
461
462       if (!_dbus_string_append (str, ":"))
463         return FALSE;
464
465       if (!_dbus_string_append_int (str, next_major_number))
466         return FALSE;
467
468       if (!_dbus_string_append (str, "."))
469         return FALSE;
470
471       if (!_dbus_string_append_int (str, next_minor_number))
472         return FALSE;
473
474       next_minor_number += 1;
475
476       /* Check if a client with the name exists */
477       if (bus_registry_lookup (registry, str) == NULL)
478         break;
479
480       /* drop the number again, try the next one. */
481       _dbus_string_set_length (str, len);
482     }
483
484   return TRUE;
485 }
486
487 static BusResult
488 bus_driver_handle_hello (DBusConnection *connection,
489                          BusTransaction *transaction,
490                          DBusMessage    *message,
491                          DBusError      *error)
492 {
493   DBusString unique_name;
494   BusService *service;
495   BusResult retval;
496   BusRegistry *registry;
497   BusConnections *connections;
498   DBusError tmp_error;
499   int limit;
500   const char *limit_name;
501
502   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
503
504   if (bus_connection_is_active (connection))
505     {
506       /* We already handled an Hello message for this connection. */
507       dbus_set_error (error, DBUS_ERROR_FAILED,
508                       "Already handled an Hello message");
509       return BUS_RESULT_FALSE;
510     }
511
512   /* Note that when these limits are exceeded we don't disconnect the
513    * connection; we just sort of leave it hanging there until it times
514    * out or disconnects itself or is dropped due to the max number of
515    * incomplete connections. It's even OK if the connection wants to
516    * retry the hello message, we support that.
517    */
518   dbus_error_init (&tmp_error);
519   connections = bus_connection_get_connections (connection);
520   if (!bus_connections_check_limits (connections, connection,
521                                      &limit_name, &limit,
522                                      &tmp_error))
523     {
524       BusContext *context;
525
526       _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
527       context = bus_connection_get_context (connection);
528       bus_context_log (context, DBUS_SYSTEM_LOG_WARNING, "%s (%s=%d)",
529           tmp_error.message, limit_name, limit);
530       dbus_move_error (&tmp_error, error);
531       return BUS_RESULT_FALSE;
532     }
533
534   if (!_dbus_string_init (&unique_name))
535     {
536       BUS_SET_OOM (error);
537       return BUS_RESULT_FALSE;
538     }
539
540   retval = BUS_RESULT_FALSE;
541
542   registry = bus_connection_get_registry (connection);
543
544   if (!create_unique_client_name (registry, &unique_name))
545     {
546       BUS_SET_OOM (error);
547       goto out_0;
548     }
549
550   if (!bus_connection_complete (connection, &unique_name, error))
551     {
552       _DBUS_ASSERT_ERROR_IS_SET (error);
553       goto out_0;
554     }
555
556   if (!dbus_message_set_sender (message,
557                                 bus_connection_get_name (connection)))
558     {
559       BUS_SET_OOM (error);
560       goto out_0;
561     }
562
563   if (!bus_driver_send_welcome_message (connection, message, transaction, error))
564     goto out_0;
565
566   /* Create the service */
567   service = bus_registry_ensure (registry,
568                                  &unique_name, connection, 0, transaction, error);
569   if (service == NULL)
570     goto out_0;
571
572   _dbus_assert (bus_connection_is_active (connection));
573   retval = BUS_RESULT_TRUE;
574
575  out_0:
576   _dbus_string_free (&unique_name);
577   return retval;
578 }
579
580 static dbus_bool_t
581 bus_driver_send_welcome_message (DBusConnection *connection,
582                                  DBusMessage    *hello_message,
583                                  BusTransaction *transaction,
584                                  DBusError      *error)
585 {
586   DBusMessage *welcome;
587   const char *name;
588
589   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
590
591   name = bus_connection_get_name (connection);
592   _dbus_assert (name != NULL);
593
594   welcome = dbus_message_new_method_return (hello_message);
595   if (welcome == NULL)
596     {
597       BUS_SET_OOM (error);
598       return FALSE;
599     }
600
601   if (!dbus_message_append_args (welcome,
602                                  DBUS_TYPE_STRING, &name,
603                                  DBUS_TYPE_INVALID))
604     {
605       dbus_message_unref (welcome);
606       BUS_SET_OOM (error);
607       return FALSE;
608     }
609
610   _dbus_assert (dbus_message_has_signature (welcome, DBUS_TYPE_STRING_AS_STRING));
611
612   if (!bus_transaction_send_from_driver (transaction, connection, welcome))
613     {
614       dbus_message_unref (welcome);
615       BUS_SET_OOM (error);
616       return FALSE;
617     }
618   else
619     {
620       dbus_message_unref (welcome);
621       return TRUE;
622     }
623 }
624
625 static BusResult
626 bus_driver_handle_list_services (DBusConnection *connection,
627                                  BusTransaction *transaction,
628                                  DBusMessage    *message,
629                                  DBusError      *error)
630 {
631   DBusMessage *reply;
632   int len;
633   char **services;
634   BusRegistry *registry;
635   int i;
636   DBusMessageIter iter;
637   DBusMessageIter sub;
638
639   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
640
641   registry = bus_connection_get_registry (connection);
642
643   reply = dbus_message_new_method_return (message);
644   if (reply == NULL)
645     {
646       BUS_SET_OOM (error);
647       return BUS_RESULT_FALSE;
648     }
649
650   if (!bus_registry_list_services (registry, &services, &len))
651     {
652       dbus_message_unref (reply);
653       BUS_SET_OOM (error);
654       return BUS_RESULT_FALSE;
655     }
656
657   dbus_message_iter_init_append (reply, &iter);
658
659   if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
660                                          DBUS_TYPE_STRING_AS_STRING,
661                                          &sub))
662     {
663       dbus_free_string_array (services);
664       dbus_message_unref (reply);
665       BUS_SET_OOM (error);
666       return BUS_RESULT_FALSE;
667     }
668
669   {
670     /* Include the bus driver in the list */
671     const char *v_STRING = DBUS_SERVICE_DBUS;
672     if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
673                                          &v_STRING))
674       {
675         dbus_free_string_array (services);
676         dbus_message_unref (reply);
677         BUS_SET_OOM (error);
678         return BUS_RESULT_FALSE;
679       }
680   }
681
682   i = 0;
683   while (i < len)
684     {
685       if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
686                                            &services[i]))
687         {
688           dbus_free_string_array (services);
689           dbus_message_unref (reply);
690           BUS_SET_OOM (error);
691           return BUS_RESULT_FALSE;
692         }
693       ++i;
694     }
695
696   dbus_free_string_array (services);
697
698   if (!dbus_message_iter_close_container (&iter, &sub))
699     {
700       dbus_message_unref (reply);
701       BUS_SET_OOM (error);
702       return BUS_RESULT_FALSE;
703     }
704
705   if (!bus_transaction_send_from_driver (transaction, connection, reply))
706     {
707       dbus_message_unref (reply);
708       BUS_SET_OOM (error);
709       return BUS_RESULT_FALSE;
710     }
711   else
712     {
713       dbus_message_unref (reply);
714       return BUS_RESULT_TRUE;
715     }
716 }
717
718 static BusResult
719 bus_driver_handle_list_activatable_services (DBusConnection *connection,
720                                              BusTransaction *transaction,
721                                              DBusMessage    *message,
722                                              DBusError      *error)
723 {
724   DBusMessage *reply;
725   int len;
726   char **services;
727   BusActivation *activation;
728   int i;
729   DBusMessageIter iter;
730   DBusMessageIter sub;
731
732   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
733
734   activation = bus_connection_get_activation (connection);
735
736   reply = dbus_message_new_method_return (message);
737   if (reply == NULL)
738     {
739       BUS_SET_OOM (error);
740       return BUS_RESULT_FALSE;
741     }
742
743   if (!bus_activation_list_services (activation, &services, &len))
744     {
745       dbus_message_unref (reply);
746       BUS_SET_OOM (error);
747       return BUS_RESULT_FALSE;
748     }
749
750   dbus_message_iter_init_append (reply, &iter);
751
752   if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
753                                          DBUS_TYPE_STRING_AS_STRING,
754                                          &sub))
755     {
756       dbus_free_string_array (services);
757       dbus_message_unref (reply);
758       BUS_SET_OOM (error);
759       return BUS_RESULT_FALSE;
760     }
761
762   {
763     /* Include the bus driver in the list */
764     const char *v_STRING = DBUS_SERVICE_DBUS;
765     if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
766                                          &v_STRING))
767       {
768         dbus_free_string_array (services);
769         dbus_message_unref (reply);
770         BUS_SET_OOM (error);
771         return BUS_RESULT_FALSE;
772       }
773   }
774
775   i = 0;
776   while (i < len)
777     {
778       if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
779                                            &services[i]))
780         {
781           dbus_free_string_array (services);
782           dbus_message_unref (reply);
783           BUS_SET_OOM (error);
784           return BUS_RESULT_FALSE;
785         }
786       ++i;
787     }
788
789   dbus_free_string_array (services);
790
791   if (!dbus_message_iter_close_container (&iter, &sub))
792     {
793       dbus_message_unref (reply);
794       BUS_SET_OOM (error);
795       return BUS_RESULT_FALSE;
796     }
797
798   if (!bus_transaction_send_from_driver (transaction, connection, reply))
799     {
800       dbus_message_unref (reply);
801       BUS_SET_OOM (error);
802       return BUS_RESULT_FALSE;
803     }
804   else
805     {
806       dbus_message_unref (reply);
807       return BUS_RESULT_TRUE;
808     }
809 }
810
811 static BusResult
812 bus_driver_handle_acquire_service (DBusConnection *connection,
813                                    BusTransaction *transaction,
814                                    DBusMessage    *message,
815                                    DBusError      *error)
816 {
817   DBusMessage *reply;
818   DBusString service_name;
819   const char *name;
820   dbus_uint32_t service_reply;
821   dbus_uint32_t flags;
822   BusResult retval;
823   BusRegistry *registry;
824
825   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
826
827   registry = bus_connection_get_registry (connection);
828
829   if (!dbus_message_get_args (message, error,
830                               DBUS_TYPE_STRING, &name,
831                               DBUS_TYPE_UINT32, &flags,
832                               DBUS_TYPE_INVALID))
833     return BUS_RESULT_FALSE;
834
835   _dbus_verbose ("Trying to own name %s with flags 0x%x\n", name, flags);
836
837   retval = BUS_RESULT_FALSE;
838   reply = NULL;
839
840   _dbus_string_init_const (&service_name, name);
841
842   switch (bus_registry_acquire_service (registry, connection, message,
843                                        &service_name, flags,
844                                        &service_reply, transaction,
845                                        error))
846     {
847       case BUS_RESULT_TRUE:
848         break;
849       case BUS_RESULT_FALSE:
850         goto out;
851       case BUS_RESULT_LATER:
852         retval = BUS_RESULT_LATER;
853         goto out;
854     }
855
856   reply = dbus_message_new_method_return (message);
857   if (reply == NULL)
858     {
859       BUS_SET_OOM (error);
860       goto out;
861     }
862
863   if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
864     {
865       BUS_SET_OOM (error);
866       goto out;
867     }
868
869   if (!bus_transaction_send_from_driver (transaction, connection, reply))
870     {
871       BUS_SET_OOM (error);
872       goto out;
873     }
874
875   retval = BUS_RESULT_TRUE;
876
877  out:
878   if (reply)
879     dbus_message_unref (reply);
880   return retval;
881 }
882
883 static BusResult
884 bus_driver_handle_release_service (DBusConnection *connection,
885                                    BusTransaction *transaction,
886                                    DBusMessage    *message,
887                                    DBusError      *error)
888 {
889   DBusMessage *reply;
890   DBusString service_name;
891   const char *name;
892   dbus_uint32_t service_reply;
893   BusResult retval;
894   BusRegistry *registry;
895
896   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
897
898   registry = bus_connection_get_registry (connection);
899
900   if (!dbus_message_get_args (message, error,
901                               DBUS_TYPE_STRING, &name,
902                               DBUS_TYPE_INVALID))
903     return BUS_RESULT_FALSE;
904
905   _dbus_verbose ("Trying to release name %s\n", name);
906
907   retval = BUS_RESULT_FALSE;
908   reply = NULL;
909
910   _dbus_string_init_const (&service_name, name);
911
912   if (!bus_registry_release_service (registry, connection,
913                                      &service_name, &service_reply,
914                                      transaction, error))
915     goto out;
916
917   reply = dbus_message_new_method_return (message);
918   if (reply == NULL)
919     {
920       BUS_SET_OOM (error);
921       goto out;
922     }
923
924   if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
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   return retval;
942 }
943
944 static BusResult
945 bus_driver_handle_service_exists (DBusConnection *connection,
946                                   BusTransaction *transaction,
947                                   DBusMessage    *message,
948                                   DBusError      *error)
949 {
950   DBusMessage *reply;
951   DBusString service_name;
952   BusService *service;
953   dbus_bool_t service_exists;
954   const char *name;
955   BusResult retval;
956   BusRegistry *registry;
957
958   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
959
960   registry = bus_connection_get_registry (connection);
961
962   if (!dbus_message_get_args (message, error,
963                               DBUS_TYPE_STRING, &name,
964                               DBUS_TYPE_INVALID))
965     return BUS_RESULT_FALSE;
966
967   retval = BUS_RESULT_FALSE;
968
969   if (strcmp (name, DBUS_SERVICE_DBUS) == 0)
970     {
971       service_exists = TRUE;
972     }
973   else
974     {
975       _dbus_string_init_const (&service_name, name);
976       service = bus_registry_lookup (registry, &service_name);
977       service_exists = service != NULL;
978     }
979
980   reply = dbus_message_new_method_return (message);
981   if (reply == NULL)
982     {
983       BUS_SET_OOM (error);
984       goto out;
985     }
986
987   if (!dbus_message_append_args (reply,
988                                  DBUS_TYPE_BOOLEAN, &service_exists,
989                                  0))
990     {
991       BUS_SET_OOM (error);
992       goto out;
993     }
994
995   if (!bus_transaction_send_from_driver (transaction, connection, reply))
996     {
997       BUS_SET_OOM (error);
998       goto out;
999     }
1000
1001   retval = BUS_RESULT_TRUE;
1002
1003  out:
1004   if (reply)
1005     dbus_message_unref (reply);
1006
1007   return retval;
1008 }
1009
1010 static BusResult
1011 bus_driver_handle_activate_service (DBusConnection *connection,
1012                                     BusTransaction *transaction,
1013                                     DBusMessage    *message,
1014                                     DBusError      *error)
1015 {
1016   dbus_uint32_t flags;
1017   const char *name;
1018   BusResult retval;
1019   BusActivation *activation;
1020
1021   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1022
1023   activation = bus_connection_get_activation (connection);
1024
1025   if (!dbus_message_get_args (message, error,
1026                               DBUS_TYPE_STRING, &name,
1027                               DBUS_TYPE_UINT32, &flags,
1028                               DBUS_TYPE_INVALID))
1029     {
1030       _DBUS_ASSERT_ERROR_IS_SET (error);
1031       _dbus_verbose ("No memory to get arguments to StartServiceByName\n");
1032       return BUS_RESULT_FALSE;
1033     }
1034
1035   retval = BUS_RESULT_FALSE;
1036
1037   if (bus_activation_activate_service (activation, connection, transaction, FALSE,
1038                                         message, name, error, NULL) == BUS_RESULT_FALSE)
1039     {
1040       _DBUS_ASSERT_ERROR_IS_SET (error);
1041       _dbus_verbose ("bus_activation_activate_service() failed\n");
1042       goto out;
1043     }
1044
1045   retval = BUS_RESULT_TRUE;
1046
1047  out:
1048   return retval;
1049 }
1050
1051 dbus_bool_t
1052 bus_driver_send_ack_reply (DBusConnection *connection,
1053                            BusTransaction *transaction,
1054                            DBusMessage    *message,
1055                            DBusError      *error)
1056 {
1057   DBusMessage *reply;
1058
1059   if (dbus_message_get_no_reply (message))
1060     return TRUE;
1061
1062   reply = dbus_message_new_method_return (message);
1063   if (reply == NULL)
1064     {
1065       BUS_SET_OOM (error);
1066       return FALSE;
1067     }
1068
1069   if (!bus_transaction_send_from_driver (transaction, connection, reply))
1070     {
1071       BUS_SET_OOM (error);
1072       dbus_message_unref (reply);
1073       return FALSE;
1074     }
1075
1076   dbus_message_unref (reply);
1077
1078   return TRUE;
1079 }
1080
1081 /*
1082  * Send a message from the driver, activating the destination if necessary.
1083  * The message must already have a destination set.
1084  */
1085 static dbus_bool_t
1086 bus_driver_send_or_activate (BusTransaction *transaction,
1087                              DBusMessage    *message,
1088                              DBusError      *error)
1089 {
1090   BusContext *context;
1091   BusService *service;
1092   const char *service_name;
1093   DBusString service_string;
1094
1095   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1096
1097   service_name = dbus_message_get_destination (message);
1098
1099   _dbus_assert (service_name != NULL);
1100
1101   _dbus_string_init_const (&service_string, service_name);
1102
1103   context = bus_transaction_get_context (transaction);
1104
1105   service = bus_registry_lookup (bus_context_get_registry (context),
1106                                  &service_string);
1107
1108   if (service == NULL)
1109     {
1110       /* destination isn't connected yet; pass the message to activation */
1111       BusActivation *activation;
1112
1113       activation = bus_context_get_activation (context);
1114
1115       if (!bus_transaction_capture (transaction, NULL, NULL, message))
1116         {
1117           BUS_SET_OOM (error);
1118           _dbus_verbose ("No memory for bus_transaction_capture()");
1119           return FALSE;
1120         }
1121
1122       if (bus_activation_activate_service (activation, NULL, transaction, TRUE,
1123                                             message, service_name, error, NULL) == BUS_RESULT_FALSE)
1124         {
1125           _DBUS_ASSERT_ERROR_IS_SET (error);
1126           _dbus_verbose ("bus_activation_activate_service() failed");
1127           return FALSE;
1128         }
1129     }
1130   else
1131     {
1132       DBusConnection *service_conn;
1133
1134       service_conn = bus_service_get_primary_owners_connection (service);
1135
1136       if (!bus_transaction_send_from_driver (transaction, service_conn, message))
1137         {
1138           BUS_SET_OOM (error);
1139           _dbus_verbose ("No memory for bus_transaction_send_from_driver()");
1140           return FALSE;
1141         }
1142     }
1143
1144   return TRUE;
1145 }
1146
1147 static BusResult
1148 bus_driver_handle_update_activation_environment (DBusConnection *connection,
1149                                                  BusTransaction *transaction,
1150                                                  DBusMessage    *message,
1151                                                  DBusError      *error)
1152 {
1153   BusResult retval;
1154   BusActivation *activation;
1155   BusContext *context;
1156   DBusMessageIter iter;
1157   DBusMessageIter dict_iter;
1158   DBusMessageIter dict_entry_iter;
1159   int array_type;
1160   int key_type;
1161   DBusList *keys, *key_link;
1162   DBusList *values, *value_link;
1163   DBusMessage *systemd_message;
1164   DBusMessageIter systemd_iter;
1165
1166   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1167
1168   context = bus_connection_get_context (connection);
1169
1170   if (bus_context_get_servicehelper (context) != NULL)
1171     {
1172       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
1173                       "Cannot change activation environment "
1174                       "on a system bus.");
1175       return BUS_RESULT_FALSE;
1176     }
1177
1178   activation = bus_connection_get_activation (connection);
1179
1180   dbus_message_iter_init (message, &iter);
1181
1182   /* The message signature has already been checked for us,
1183    * so let's just assert it's right.
1184    */
1185   _dbus_assert (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY);
1186
1187   dbus_message_iter_recurse (&iter, &dict_iter);
1188
1189   retval = BUS_RESULT_FALSE;
1190   systemd_message = NULL;
1191
1192   /* Then loop through the sent dictionary, add the location of
1193    * the environment keys and values to lists. The result will
1194    * be in reverse order, so we don't have to constantly search
1195    * for the end of the list in a loop.
1196    */
1197   keys = NULL;
1198   values = NULL;
1199   while ((array_type = dbus_message_iter_get_arg_type (&dict_iter)) == DBUS_TYPE_DICT_ENTRY)
1200     {
1201       dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
1202
1203       while ((key_type = dbus_message_iter_get_arg_type (&dict_entry_iter)) == DBUS_TYPE_STRING)
1204         {
1205           char *key;
1206           char *value;
1207           int value_type;
1208
1209           dbus_message_iter_get_basic (&dict_entry_iter, &key);
1210           dbus_message_iter_next (&dict_entry_iter);
1211
1212           value_type = dbus_message_iter_get_arg_type (&dict_entry_iter);
1213
1214           if (value_type != DBUS_TYPE_STRING)
1215             break;
1216
1217           dbus_message_iter_get_basic (&dict_entry_iter, &value);
1218
1219           if (!_dbus_list_append (&keys, key))
1220             {
1221               BUS_SET_OOM (error);
1222               break;
1223             }
1224
1225           if (!_dbus_list_append (&values, value))
1226             {
1227               BUS_SET_OOM (error);
1228               break;
1229             }
1230
1231           dbus_message_iter_next (&dict_entry_iter);
1232         }
1233
1234       if (key_type != DBUS_TYPE_INVALID)
1235         break;
1236
1237       dbus_message_iter_next (&dict_iter);
1238     }
1239
1240   if (array_type != DBUS_TYPE_INVALID)
1241     goto out;
1242
1243   _dbus_assert (_dbus_list_get_length (&keys) == _dbus_list_get_length (&values));
1244
1245   if (bus_context_get_systemd_activation (bus_connection_get_context (connection)))
1246     {
1247       /* Prepare a call to forward environment updates to systemd */
1248       systemd_message = dbus_message_new_method_call ("org.freedesktop.systemd1",
1249                                                       "/org/freedesktop/systemd1",
1250                                                       "org.freedesktop.systemd1.Manager",
1251                                                       "SetEnvironment");
1252       if (systemd_message == NULL ||
1253           !dbus_message_set_sender (systemd_message, DBUS_SERVICE_DBUS))
1254         {
1255           BUS_SET_OOM (error);
1256           _dbus_verbose ("No memory to create systemd message\n");
1257           goto out;
1258         }
1259
1260       dbus_message_set_no_reply (systemd_message, TRUE);
1261       dbus_message_iter_init_append (systemd_message, &iter);
1262
1263       if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s",
1264                                              &systemd_iter))
1265         {
1266           BUS_SET_OOM (error);
1267           _dbus_verbose ("No memory to open systemd message container\n");
1268           goto out;
1269         }
1270     }
1271
1272   key_link = keys;
1273   value_link = values;
1274   while (key_link != NULL)
1275   {
1276       const char *key;
1277       const char *value;
1278
1279       key = key_link->data;
1280       value = value_link->data;
1281
1282       if (!bus_activation_set_environment_variable (activation,
1283                                                     key, value, error))
1284         {
1285           _DBUS_ASSERT_ERROR_IS_SET (error);
1286           _dbus_verbose ("bus_activation_set_environment_variable() failed\n");
1287           break;
1288         }
1289
1290       if (systemd_message != NULL)
1291         {
1292           DBusString envline;
1293           const char *s;
1294
1295           /* SetEnvironment wants an array of KEY=VALUE strings */
1296           if (!_dbus_string_init (&envline) ||
1297               !_dbus_string_append_printf (&envline, "%s=%s", key, value))
1298             {
1299               BUS_SET_OOM (error);
1300               _dbus_verbose ("No memory to format systemd environment line\n");
1301               _dbus_string_free (&envline);
1302               break;
1303             }
1304
1305           s = _dbus_string_get_data (&envline);
1306
1307           if (!dbus_message_iter_append_basic (&systemd_iter,
1308                                                DBUS_TYPE_STRING, &s))
1309             {
1310               BUS_SET_OOM (error);
1311               _dbus_verbose ("No memory to append systemd environment line\n");
1312               _dbus_string_free (&envline);
1313               break;
1314             }
1315
1316           _dbus_string_free (&envline);
1317         }
1318
1319       key_link = _dbus_list_get_next_link (&keys, key_link);
1320       value_link = _dbus_list_get_next_link (&values, value_link);
1321   }
1322
1323   /* FIXME: We can fail early having set only some of the environment variables,
1324    * (because of OOM failure).  It's sort of hard to fix and it doesn't really
1325    * matter, so we're punting for now.
1326    */
1327   if (key_link != NULL)
1328     {
1329       if (systemd_message != NULL)
1330         dbus_message_iter_abandon_container (&iter, &systemd_iter);
1331       goto out;
1332     }
1333
1334   if (systemd_message != NULL)
1335     {
1336       if (!dbus_message_iter_close_container (&iter, &systemd_iter))
1337         {
1338           BUS_SET_OOM (error);
1339           _dbus_verbose ("No memory to close systemd message container\n");
1340           goto out;
1341         }
1342
1343       if (!bus_driver_send_or_activate (transaction, systemd_message, error))
1344         {
1345           _DBUS_ASSERT_ERROR_IS_SET (error);
1346           _dbus_verbose ("bus_driver_send_or_activate() failed\n");
1347           goto out;
1348         }
1349     }
1350
1351   if (!bus_driver_send_ack_reply (connection, transaction, message, error))
1352     goto out;
1353
1354   retval = BUS_RESULT_TRUE;
1355
1356  out:
1357   if (systemd_message != NULL)
1358     dbus_message_unref (systemd_message);
1359   _dbus_list_clear (&keys);
1360   _dbus_list_clear (&values);
1361   return retval;
1362 }
1363
1364 static BusResult
1365 bus_driver_handle_add_match (DBusConnection *connection,
1366                              BusTransaction *transaction,
1367                              DBusMessage    *message,
1368                              DBusError      *error)
1369 {
1370   BusMatchRule *rule;
1371   const char *text, *bustype;
1372   DBusString str;
1373   BusMatchmaker *matchmaker;
1374   int limit;
1375   BusContext *context;
1376
1377   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1378
1379   text = NULL;
1380   rule = NULL;
1381
1382   context = bus_transaction_get_context (transaction);
1383   limit = bus_context_get_max_match_rules_per_connection (context);
1384
1385   if (bus_connection_get_n_match_rules (connection) >= limit)
1386     {
1387       DBusError tmp_error;
1388
1389       dbus_error_init (&tmp_error);
1390       dbus_set_error (&tmp_error, DBUS_ERROR_LIMITS_EXCEEDED,
1391                       "Connection \"%s\" is not allowed to add more match rules "
1392                       "(increase limits in configuration file if required; "
1393                       "max_match_rules_per_connection=%d)",
1394                       bus_connection_is_active (connection) ?
1395                       bus_connection_get_name (connection) :
1396                       "(inactive)",
1397                       limit);
1398       bus_context_log (context, DBUS_SYSTEM_LOG_WARNING, "%s",
1399                        tmp_error.message);
1400       dbus_move_error (&tmp_error, error);
1401       goto failed;
1402     }
1403
1404   if (!dbus_message_get_args (message, error,
1405                               DBUS_TYPE_STRING, &text,
1406                               DBUS_TYPE_INVALID))
1407     {
1408       _dbus_verbose ("No memory to get arguments to AddMatch\n");
1409       goto failed;
1410     }
1411
1412   _dbus_string_init_const (&str, text);
1413
1414   rule = bus_match_rule_parse (connection, &str, error);
1415   if (rule == NULL)
1416     goto failed;
1417
1418   bustype = bus_context_get_type (context);
1419
1420   if (bus_match_rule_get_client_is_eavesdropping (rule))
1421     {
1422       if (!bus_driver_check_caller_is_privileged (connection,
1423                                                   transaction,
1424                                                   message,
1425                                                   error) ||
1426           !bus_apparmor_allows_eavesdropping (connection, bustype, error))
1427         goto failed;
1428     }
1429
1430   matchmaker = bus_connection_get_matchmaker (connection);
1431
1432   if (!bus_matchmaker_add_rule (matchmaker, rule))
1433     {
1434       BUS_SET_OOM (error);
1435       goto failed;
1436     }
1437
1438   if (!bus_driver_send_ack_reply (connection, transaction, message, error))
1439     {
1440       bus_matchmaker_remove_rule (matchmaker, rule);
1441       goto failed;
1442     }
1443
1444   bus_match_rule_unref (rule);
1445
1446   return BUS_RESULT_TRUE;
1447
1448  failed:
1449   _DBUS_ASSERT_ERROR_IS_SET (error);
1450   if (rule)
1451     bus_match_rule_unref (rule);
1452   return BUS_RESULT_FALSE;
1453 }
1454
1455 static BusResult
1456 bus_driver_handle_remove_match (DBusConnection *connection,
1457                                 BusTransaction *transaction,
1458                                 DBusMessage    *message,
1459                                 DBusError      *error)
1460 {
1461   BusMatchRule *rule;
1462   const char *text;
1463   DBusString str;
1464   BusMatchmaker *matchmaker;
1465
1466   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1467
1468   text = NULL;
1469   rule = NULL;
1470
1471   if (!dbus_message_get_args (message, error,
1472                               DBUS_TYPE_STRING, &text,
1473                               DBUS_TYPE_INVALID))
1474     {
1475       _dbus_verbose ("No memory to get arguments to RemoveMatch\n");
1476       goto failed;
1477     }
1478
1479   _dbus_string_init_const (&str, text);
1480
1481   rule = bus_match_rule_parse (connection, &str, error);
1482   if (rule == NULL)
1483     goto failed;
1484
1485   /* Send the ack before we remove the rule, since the ack is undone
1486    * on transaction cancel, but rule removal isn't.
1487    */
1488   if (!bus_driver_send_ack_reply (connection, transaction, message, error))
1489     goto failed;
1490
1491   matchmaker = bus_connection_get_matchmaker (connection);
1492
1493   if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error))
1494     goto failed;
1495
1496   bus_match_rule_unref (rule);
1497
1498   return BUS_RESULT_TRUE;
1499
1500  failed:
1501   _DBUS_ASSERT_ERROR_IS_SET (error);
1502   if (rule)
1503     bus_match_rule_unref (rule);
1504   return BUS_RESULT_FALSE;
1505 }
1506
1507 static BusResult
1508 bus_driver_handle_get_service_owner (DBusConnection *connection,
1509                                      BusTransaction *transaction,
1510                                      DBusMessage    *message,
1511                                      DBusError      *error)
1512 {
1513   const char *text;
1514   const char *base_name;
1515   DBusString str;
1516   BusRegistry *registry;
1517   BusService *service;
1518   DBusMessage *reply;
1519
1520   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1521
1522   registry = bus_connection_get_registry (connection);
1523
1524   text = NULL;
1525   reply = NULL;
1526
1527   if (! dbus_message_get_args (message, error,
1528                                DBUS_TYPE_STRING, &text,
1529                                DBUS_TYPE_INVALID))
1530       goto failed;
1531
1532   _dbus_string_init_const (&str, text);
1533   service = bus_registry_lookup (registry, &str);
1534   if (service == NULL &&
1535       _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1536     {
1537       /* ORG_FREEDESKTOP_DBUS owns itself */
1538       base_name = DBUS_SERVICE_DBUS;
1539     }
1540   else if (service == NULL)
1541     {
1542       dbus_set_error (error,
1543                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1544                       "Could not get owner of name '%s': no such name", text);
1545       goto failed;
1546     }
1547   else
1548     {
1549       base_name = bus_connection_get_name (bus_service_get_primary_owners_connection (service));
1550       if (base_name == NULL)
1551         {
1552           /* FIXME - how is this error possible? */
1553           dbus_set_error (error,
1554                           DBUS_ERROR_FAILED,
1555                           "Could not determine unique name for '%s'", text);
1556           goto failed;
1557         }
1558       _dbus_assert (*base_name == ':');
1559     }
1560
1561   _dbus_assert (base_name != NULL);
1562
1563   reply = dbus_message_new_method_return (message);
1564   if (reply == NULL)
1565     goto oom;
1566
1567   if (! dbus_message_append_args (reply,
1568                                   DBUS_TYPE_STRING, &base_name,
1569                                   DBUS_TYPE_INVALID))
1570     goto oom;
1571
1572   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1573     goto oom;
1574
1575   dbus_message_unref (reply);
1576
1577   return BUS_RESULT_TRUE;
1578
1579  oom:
1580   BUS_SET_OOM (error);
1581
1582  failed:
1583   _DBUS_ASSERT_ERROR_IS_SET (error);
1584   if (reply)
1585     dbus_message_unref (reply);
1586   return BUS_RESULT_FALSE;
1587 }
1588
1589 static BusResult
1590 bus_driver_handle_list_queued_owners (DBusConnection *connection,
1591                                       BusTransaction *transaction,
1592                                       DBusMessage    *message,
1593                                       DBusError      *error)
1594 {
1595   static const char dbus_service_name[] = DBUS_SERVICE_DBUS;
1596
1597   const char *text;
1598   DBusList *base_names;
1599   DBusList *link;
1600   DBusString str;
1601   BusRegistry *registry;
1602   BusService *service;
1603   DBusMessage *reply;
1604   DBusMessageIter iter, array_iter;
1605
1606   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1607
1608   registry = bus_connection_get_registry (connection);
1609
1610   base_names = NULL;
1611   text = NULL;
1612   reply = NULL;
1613
1614   if (! dbus_message_get_args (message, error,
1615                                DBUS_TYPE_STRING, &text,
1616                                DBUS_TYPE_INVALID))
1617       goto failed;
1618
1619   _dbus_string_init_const (&str, text);
1620   service = bus_registry_lookup (registry, &str);
1621   if (service == NULL &&
1622       _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
1623     {
1624       /* ORG_FREEDESKTOP_DBUS owns itself */
1625       if (! _dbus_list_append (&base_names, (char *) dbus_service_name))
1626         goto oom;
1627     }
1628   else if (service == NULL)
1629     {
1630       dbus_set_error (error,
1631                       DBUS_ERROR_NAME_HAS_NO_OWNER,
1632                       "Could not get owners of name '%s': no such name", text);
1633       goto failed;
1634     }
1635   else
1636     {
1637       if (!bus_service_list_queued_owners (service,
1638                                            &base_names,
1639                                            error))
1640         goto failed;
1641     }
1642
1643   _dbus_assert (base_names != NULL);
1644
1645   reply = dbus_message_new_method_return (message);
1646   if (reply == NULL)
1647     goto oom;
1648
1649   dbus_message_iter_init_append (reply, &iter);
1650   if (!dbus_message_iter_open_container (&iter,
1651                                          DBUS_TYPE_ARRAY,
1652                                          DBUS_TYPE_STRING_AS_STRING,
1653                                          &array_iter))
1654     goto oom;
1655
1656   link = _dbus_list_get_first_link (&base_names);
1657   while (link != NULL)
1658     {
1659       char *uname;
1660
1661       _dbus_assert (link->data != NULL);
1662       uname = (char *)link->data;
1663
1664       if (!dbus_message_iter_append_basic (&array_iter,
1665                                            DBUS_TYPE_STRING,
1666                                            &uname))
1667         goto oom;
1668
1669       link = _dbus_list_get_next_link (&base_names, link);
1670     }
1671
1672   if (! dbus_message_iter_close_container (&iter, &array_iter))
1673     goto oom;
1674
1675
1676   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1677     goto oom;
1678
1679   dbus_message_unref (reply);
1680
1681   return BUS_RESULT_TRUE;
1682
1683  oom:
1684   BUS_SET_OOM (error);
1685
1686  failed:
1687   _DBUS_ASSERT_ERROR_IS_SET (error);
1688   if (reply)
1689     dbus_message_unref (reply);
1690
1691   if (base_names)
1692     _dbus_list_clear (&base_names);
1693
1694   return BUS_RESULT_FALSE;
1695 }
1696
1697 static BusResult
1698 bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
1699                                             BusTransaction *transaction,
1700                                             DBusMessage    *message,
1701                                             DBusError      *error)
1702 {
1703   DBusConnection *conn;
1704   DBusMessage *reply;
1705   dbus_uid_t uid;
1706   dbus_uint32_t uid32;
1707   const char *service;
1708   BusDriverFound found;
1709
1710   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1711
1712   reply = NULL;
1713
1714   found = bus_driver_get_conn_helper (connection, message, "UID", &service,
1715                                       &conn, error);
1716   switch (found)
1717     {
1718       case BUS_DRIVER_FOUND_SELF:
1719         uid = _dbus_getuid ();
1720         break;
1721       case BUS_DRIVER_FOUND_PEER:
1722         if (!dbus_connection_get_unix_user (conn, &uid))
1723           uid = DBUS_UID_UNSET;
1724         break;
1725       case BUS_DRIVER_FOUND_ERROR:
1726         /* fall through */
1727       default:
1728         goto failed;
1729     }
1730
1731   if (uid == DBUS_UID_UNSET)
1732     {
1733       dbus_set_error (error,
1734                       DBUS_ERROR_FAILED,
1735                       "Could not determine UID 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   uid32 = uid;
1744   if (! dbus_message_append_args (reply,
1745                                   DBUS_TYPE_UINT32, &uid32,
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_connection_unix_process_id (DBusConnection *connection,
1768                                                   BusTransaction *transaction,
1769                                                   DBusMessage    *message,
1770                                                   DBusError      *error)
1771 {
1772   DBusConnection *conn;
1773   DBusMessage *reply;
1774   dbus_pid_t pid;
1775   dbus_uint32_t pid32;
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, "PID", &service,
1784                                       &conn, error);
1785   switch (found)
1786     {
1787       case BUS_DRIVER_FOUND_SELF:
1788         pid = _dbus_getpid ();
1789         break;
1790       case BUS_DRIVER_FOUND_PEER:
1791         if (!dbus_connection_get_unix_process_id (conn, &pid))
1792           pid = DBUS_PID_UNSET;
1793         break;
1794       case BUS_DRIVER_FOUND_ERROR:
1795         /* fall through */
1796       default:
1797         goto failed;
1798     }
1799
1800   if (pid == DBUS_PID_UNSET)
1801     {
1802       dbus_set_error (error,
1803                       DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
1804                       "Could not determine PID for '%s'", service);
1805       goto failed;
1806     }
1807
1808   reply = dbus_message_new_method_return (message);
1809   if (reply == NULL)
1810     goto oom;
1811
1812   pid32 = pid;
1813   if (! dbus_message_append_args (reply,
1814                                   DBUS_TYPE_UINT32, &pid32,
1815                                   DBUS_TYPE_INVALID))
1816     goto oom;
1817
1818   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1819     goto oom;
1820
1821   dbus_message_unref (reply);
1822
1823   return BUS_RESULT_TRUE;
1824
1825  oom:
1826   BUS_SET_OOM (error);
1827
1828  failed:
1829   _DBUS_ASSERT_ERROR_IS_SET (error);
1830   if (reply)
1831     dbus_message_unref (reply);
1832   return BUS_RESULT_FALSE;
1833 }
1834
1835 static BusResult
1836 bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection,
1837                                               BusTransaction *transaction,
1838                                               DBusMessage    *message,
1839                                               DBusError      *error)
1840 {
1841   DBusConnection *conn;
1842   DBusMessage *reply;
1843   void *data = NULL;
1844   dbus_int32_t data_size;
1845   const char *service;
1846   BusDriverFound found;
1847
1848   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1849
1850   reply = NULL;
1851
1852   found = bus_driver_get_conn_helper (connection, message, "audit session data",
1853                                       &service, &conn, error);
1854
1855   if (found == BUS_DRIVER_FOUND_ERROR)
1856     goto failed;
1857
1858   reply = dbus_message_new_method_return (message);
1859   if (reply == NULL)
1860     goto oom;
1861
1862   /* We don't know how to find "ADT audit session data" for the bus daemon
1863    * itself. Is that even meaningful?
1864    * FIXME: Implement this or briefly note it makes no sense.
1865    */
1866   if (found != BUS_DRIVER_FOUND_PEER ||
1867       !dbus_connection_get_adt_audit_session_data (conn, &data, &data_size) ||
1868       data == NULL)
1869     {
1870       dbus_set_error (error,
1871                       DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN,
1872                       "Could not determine audit session data for '%s'", service);
1873       goto failed;
1874     }
1875
1876   if (! dbus_message_append_args (reply,
1877                                   DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_size,
1878                                   DBUS_TYPE_INVALID))
1879     goto oom;
1880
1881   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1882     goto oom;
1883
1884   dbus_message_unref (reply);
1885
1886   return BUS_RESULT_TRUE;
1887
1888  oom:
1889   BUS_SET_OOM (error);
1890
1891  failed:
1892   _DBUS_ASSERT_ERROR_IS_SET (error);
1893   if (reply)
1894     dbus_message_unref (reply);
1895   return BUS_RESULT_FALSE;
1896 }
1897
1898 static BusResult
1899 bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection,
1900                                                            BusTransaction *transaction,
1901                                                            DBusMessage    *message,
1902                                                            DBusError      *error)
1903 {
1904   DBusConnection *conn;
1905   DBusMessage *reply;
1906   BusSELinuxID *context;
1907   const char *service;
1908   BusDriverFound found;
1909
1910   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1911
1912   reply = NULL;
1913
1914   found = bus_driver_get_conn_helper (connection, message, "security context",
1915                                       &service, &conn, error);
1916
1917   if (found == BUS_DRIVER_FOUND_ERROR)
1918     goto failed;
1919
1920   reply = dbus_message_new_method_return (message);
1921   if (reply == NULL)
1922     goto oom;
1923
1924   if (found == BUS_DRIVER_FOUND_SELF)
1925     context = bus_selinux_get_self ();
1926   else if (found == BUS_DRIVER_FOUND_PEER)
1927     context = bus_connection_get_selinux_id (conn);
1928   else
1929     context = NULL;
1930
1931   if (!context)
1932     {
1933       dbus_set_error (error,
1934                       DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN,
1935                       "Could not determine security context for '%s'", service);
1936       goto failed;
1937     }
1938
1939   if (! bus_selinux_append_context (reply, context, error))
1940     goto failed;
1941
1942   if (! bus_transaction_send_from_driver (transaction, connection, reply))
1943     goto oom;
1944
1945   dbus_message_unref (reply);
1946
1947   return BUS_RESULT_TRUE;
1948
1949  oom:
1950   BUS_SET_OOM (error);
1951
1952  failed:
1953   _DBUS_ASSERT_ERROR_IS_SET (error);
1954   if (reply)
1955     dbus_message_unref (reply);
1956   return BUS_RESULT_FALSE;
1957 }
1958
1959 static BusResult
1960 bus_driver_handle_get_connection_credentials (DBusConnection *connection,
1961                                               BusTransaction *transaction,
1962                                               DBusMessage    *message,
1963                                               DBusError      *error)
1964 {
1965   DBusConnection *conn;
1966   DBusMessage *reply;
1967   DBusMessageIter reply_iter;
1968   DBusMessageIter array_iter;
1969   unsigned long ulong_uid, ulong_pid;
1970   char *s;
1971   const char *service;
1972   BusDriverFound found;
1973
1974   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1975
1976   reply = NULL;
1977
1978   found = bus_driver_get_conn_helper (connection, message, "credentials",
1979                                       &service, &conn, error);
1980
1981   switch (found)
1982     {
1983       case BUS_DRIVER_FOUND_SELF:
1984         ulong_pid = _dbus_getpid ();
1985         ulong_uid = _dbus_getuid ();
1986         break;
1987
1988       case BUS_DRIVER_FOUND_PEER:
1989         if (!dbus_connection_get_unix_process_id (conn, &ulong_pid))
1990           ulong_pid = DBUS_PID_UNSET;
1991         if (!dbus_connection_get_unix_user (conn, &ulong_uid))
1992           ulong_uid = DBUS_UID_UNSET;
1993         break;
1994       case BUS_DRIVER_FOUND_ERROR:
1995         /* fall through */
1996       default:
1997         goto failed;
1998     }
1999
2000   reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter);
2001   if (reply == NULL)
2002     goto oom;
2003
2004   /* we can't represent > 32-bit pids; if your system needs them, please
2005    * add ProcessID64 to the spec or something */
2006   if (ulong_pid <= _DBUS_UINT32_MAX && ulong_pid != DBUS_PID_UNSET &&
2007       !_dbus_asv_add_uint32 (&array_iter, "ProcessID", ulong_pid))
2008     goto oom;
2009
2010   /* we can't represent > 32-bit uids; if your system needs them, please
2011    * add UnixUserID64 to the spec or something */
2012   if (ulong_uid <= _DBUS_UINT32_MAX && ulong_uid != DBUS_UID_UNSET &&
2013       !_dbus_asv_add_uint32 (&array_iter, "UnixUserID", ulong_uid))
2014     goto oom;
2015
2016   /* FIXME: Obtain the Windows user of the bus daemon itself */
2017   if (found == BUS_DRIVER_FOUND_PEER &&
2018       dbus_connection_get_windows_user (conn, &s))
2019     {
2020       DBusString str;
2021       dbus_bool_t result;
2022
2023       if (s == NULL)
2024         goto oom;
2025
2026       _dbus_string_init_const (&str, s);
2027       result = _dbus_validate_utf8 (&str, 0, _dbus_string_get_length (&str));
2028       _dbus_string_free (&str);
2029       if (result)
2030         {
2031           if (!_dbus_asv_add_string (&array_iter, "WindowsSID", s))
2032             {
2033               dbus_free (s);
2034               goto oom;
2035             }
2036         }
2037       dbus_free (s);
2038     }
2039
2040   /* FIXME: Obtain the security label for the bus daemon itself */
2041   if (found == BUS_DRIVER_FOUND_PEER &&
2042       _dbus_connection_get_linux_security_label (conn, &s))
2043     {
2044       if (s == NULL)
2045         goto oom;
2046
2047       /* use the GVariant bytestring convention for strings of unknown
2048        * encoding: include the \0 in the payload, for zero-copy reading */
2049       if (!_dbus_asv_add_byte_array (&array_iter, "LinuxSecurityLabel",
2050                                      s, strlen (s) + 1))
2051         {
2052           dbus_free (s);
2053           goto oom;
2054         }
2055
2056       dbus_free (s);
2057     }
2058
2059   if (!_dbus_asv_close (&reply_iter, &array_iter))
2060     goto oom;
2061
2062   if (! bus_transaction_send_from_driver (transaction, connection, reply))
2063     {
2064       /* this time we don't want to close the iterator again, so just
2065        * get rid of the message */
2066       dbus_message_unref (reply);
2067       reply = NULL;
2068       goto oom;
2069     }
2070
2071   dbus_message_unref (reply);
2072
2073   return BUS_RESULT_TRUE;
2074
2075  oom:
2076   BUS_SET_OOM (error);
2077
2078  failed:
2079   _DBUS_ASSERT_ERROR_IS_SET (error);
2080
2081   if (reply)
2082     {
2083       _dbus_asv_abandon (&reply_iter, &array_iter);
2084       dbus_message_unref (reply);
2085     }
2086
2087   return BUS_RESULT_FALSE;
2088 }
2089
2090 static BusResult
2091 bus_driver_handle_reload_config (DBusConnection *connection,
2092                                  BusTransaction *transaction,
2093                                  DBusMessage    *message,
2094                                  DBusError      *error)
2095 {
2096   BusContext *context;
2097   DBusMessage *reply;
2098
2099   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2100
2101   reply = NULL;
2102
2103   context = bus_connection_get_context (connection);
2104   if (!bus_context_reload_config (context, error))
2105     goto failed;
2106
2107   reply = dbus_message_new_method_return (message);
2108   if (reply == NULL)
2109     goto oom;
2110
2111   if (! bus_transaction_send_from_driver (transaction, connection, reply))
2112     goto oom;
2113
2114   dbus_message_unref (reply);
2115   return BUS_RESULT_TRUE;
2116
2117  oom:
2118   BUS_SET_OOM (error);
2119
2120  failed:
2121   _DBUS_ASSERT_ERROR_IS_SET (error);
2122   if (reply)
2123     dbus_message_unref (reply);
2124   return BUS_RESULT_FALSE;
2125 }
2126
2127 #ifdef DBUS_ENABLE_VERBOSE_MODE
2128 static dbus_bool_t
2129 bus_driver_handle_enable_verbose (DBusConnection *connection,
2130                                   BusTransaction *transaction,
2131                                   DBusMessage    *message,
2132                                   DBusError      *error)
2133 {
2134     DBusMessage *reply = NULL;
2135
2136     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2137
2138     reply = dbus_message_new_method_return (message);
2139     if (reply == NULL)
2140       goto oom;
2141
2142     if (! bus_transaction_send_from_driver (transaction, connection, reply))
2143       goto oom;
2144
2145     _dbus_set_verbose(TRUE);
2146
2147     dbus_message_unref (reply);
2148     return TRUE;
2149
2150    oom:
2151     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2152
2153     BUS_SET_OOM (error);
2154
2155     if (reply)
2156       dbus_message_unref (reply);
2157     return FALSE;
2158 }
2159
2160 static dbus_bool_t
2161 bus_driver_handle_disable_verbose (DBusConnection *connection,
2162                                    BusTransaction *transaction,
2163                                    DBusMessage    *message,
2164                                    DBusError      *error)
2165 {
2166     DBusMessage *reply = NULL;
2167
2168     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2169
2170     reply = dbus_message_new_method_return (message);
2171     if (reply == NULL)
2172       goto oom;
2173
2174     if (! bus_transaction_send_from_driver (transaction, connection, reply))
2175       goto oom;
2176
2177     _dbus_set_verbose(FALSE);
2178
2179     dbus_message_unref (reply);
2180     return TRUE;
2181
2182    oom:
2183     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2184
2185     BUS_SET_OOM (error);
2186
2187     if (reply)
2188       dbus_message_unref (reply);
2189     return FALSE;
2190 }
2191 #endif
2192
2193 static BusResult
2194 bus_driver_handle_get_id (DBusConnection *connection,
2195                           BusTransaction *transaction,
2196                           DBusMessage    *message,
2197                           DBusError      *error)
2198 {
2199   BusContext *context;
2200   DBusMessage *reply;
2201   DBusString uuid;
2202   const char *v_STRING;
2203
2204   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2205
2206   if (!_dbus_string_init (&uuid))
2207     {
2208       BUS_SET_OOM (error);
2209       return BUS_RESULT_FALSE;
2210     }
2211
2212   reply = NULL;
2213
2214   context = bus_connection_get_context (connection);
2215   if (!bus_context_get_id (context, &uuid))
2216     goto oom;
2217
2218   reply = dbus_message_new_method_return (message);
2219   if (reply == NULL)
2220     goto oom;
2221
2222   v_STRING = _dbus_string_get_const_data (&uuid);
2223   if (!dbus_message_append_args (reply,
2224                                  DBUS_TYPE_STRING, &v_STRING,
2225                                  DBUS_TYPE_INVALID))
2226     goto oom;
2227
2228   _dbus_assert (dbus_message_has_signature (reply, "s"));
2229
2230   if (! bus_transaction_send_from_driver (transaction, connection, reply))
2231     goto oom;
2232
2233   _dbus_string_free (&uuid);
2234   dbus_message_unref (reply);
2235   return BUS_RESULT_TRUE;
2236
2237  oom:
2238   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2239
2240   BUS_SET_OOM (error);
2241
2242   if (reply)
2243     dbus_message_unref (reply);
2244   _dbus_string_free (&uuid);
2245   return BUS_RESULT_FALSE;
2246 }
2247
2248 static dbus_bool_t
2249 bus_driver_handle_become_monitor (DBusConnection *connection,
2250                                   BusTransaction *transaction,
2251                                   DBusMessage    *message,
2252                                   DBusError      *error)
2253 {
2254   char **match_rules = NULL;
2255   const char *bustype;
2256   BusContext *context;
2257   BusMatchRule *rule;
2258   DBusList *rules = NULL;
2259   DBusList *iter;
2260   DBusString str;
2261   int i;
2262   int n_match_rules;
2263   dbus_uint32_t flags;
2264   dbus_bool_t ret = FALSE;
2265
2266   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2267
2268   context = bus_transaction_get_context (transaction);
2269   bustype = context ? bus_context_get_type (context) : NULL;
2270   if (!bus_apparmor_allows_eavesdropping (connection, bustype, error))
2271     goto out;
2272
2273   if (!dbus_message_get_args (message, error,
2274         DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &match_rules, &n_match_rules,
2275         DBUS_TYPE_UINT32, &flags,
2276         DBUS_TYPE_INVALID))
2277     goto out;
2278
2279   if (flags != 0)
2280     {
2281       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2282           "BecomeMonitor does not support any flags yet");
2283       goto out;
2284     }
2285
2286   /* Special case: a zero-length array becomes [""] */
2287   if (n_match_rules == 0)
2288     {
2289       match_rules = dbus_malloc (2 * sizeof (char *));
2290
2291       if (match_rules == NULL)
2292         {
2293           BUS_SET_OOM (error);
2294           goto out;
2295         }
2296
2297       match_rules[0] = _dbus_strdup ("");
2298
2299       if (match_rules[0] == NULL)
2300         {
2301           BUS_SET_OOM (error);
2302           goto out;
2303         }
2304
2305       match_rules[1] = NULL;
2306       n_match_rules = 1;
2307     }
2308
2309   for (i = 0; i < n_match_rules; i++)
2310     {
2311       _dbus_string_init_const (&str, match_rules[i]);
2312       rule = bus_match_rule_parse (connection, &str, error);
2313
2314       if (rule == NULL)
2315         goto out;
2316
2317       /* monitors always eavesdrop */
2318       bus_match_rule_set_client_is_eavesdropping (rule, TRUE);
2319
2320       if (!_dbus_list_append (&rules, rule))
2321         {
2322           BUS_SET_OOM (error);
2323           bus_match_rule_unref (rule);
2324           goto out;
2325         }
2326     }
2327
2328   /* Send the ack before we remove the rule, since the ack is undone
2329    * on transaction cancel, but becoming a monitor isn't.
2330    */
2331   if (!bus_driver_send_ack_reply (connection, transaction, message, error))
2332     goto out;
2333
2334   if (!bus_connection_be_monitor (connection, transaction, &rules, error))
2335     goto out;
2336
2337   ret = TRUE;
2338
2339 out:
2340   if (ret)
2341     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2342   else
2343     _DBUS_ASSERT_ERROR_IS_SET (error);
2344
2345   for (iter = _dbus_list_get_first_link (&rules);
2346       iter != NULL;
2347       iter = _dbus_list_get_next_link (&rules, iter))
2348     bus_match_rule_unref (iter->data);
2349
2350   _dbus_list_clear (&rules);
2351
2352   dbus_free_string_array (match_rules);
2353   return ret;
2354 }
2355
2356 static dbus_bool_t
2357 bus_driver_handle_get_machine_id (DBusConnection *connection,
2358                                   BusTransaction *transaction,
2359                                   DBusMessage *message,
2360                                   DBusError *error)
2361 {
2362   DBusMessage *reply = NULL;
2363   DBusString uuid;
2364   const char *str;
2365
2366   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2367
2368   if (!_dbus_string_init (&uuid))
2369     {
2370       BUS_SET_OOM (error);
2371       return FALSE;
2372     }
2373
2374   if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
2375     goto fail;
2376
2377   reply = dbus_message_new_method_return (message);
2378
2379   if (reply == NULL)
2380     goto oom;
2381
2382   str = _dbus_string_get_const_data (&uuid);
2383
2384   if (!dbus_message_append_args (reply,
2385                                  DBUS_TYPE_STRING, &str,
2386                                  DBUS_TYPE_INVALID))
2387     goto oom;
2388
2389   _dbus_assert (dbus_message_has_signature (reply, "s"));
2390
2391   if (!bus_transaction_send_from_driver (transaction, connection, reply))
2392     goto oom;
2393
2394   _dbus_string_free (&uuid);
2395   dbus_message_unref (reply);
2396   return TRUE;
2397
2398 oom:
2399   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2400
2401   BUS_SET_OOM (error);
2402
2403 fail:
2404   _DBUS_ASSERT_ERROR_IS_SET (error);
2405
2406   if (reply != NULL)
2407     dbus_message_unref (reply);
2408
2409   _dbus_string_free (&uuid);
2410   return FALSE;
2411 }
2412
2413 static dbus_bool_t
2414 bus_driver_handle_ping (DBusConnection *connection,
2415                         BusTransaction *transaction,
2416                         DBusMessage *message,
2417                         DBusError *error)
2418 {
2419   return bus_driver_send_ack_reply (connection, transaction, message, error);
2420 }
2421
2422 static dbus_bool_t bus_driver_handle_get (DBusConnection *connection,
2423                                           BusTransaction *transaction,
2424                                           DBusMessage *message,
2425                                           DBusError *error);
2426
2427 static dbus_bool_t bus_driver_handle_get_all (DBusConnection *connection,
2428                                               BusTransaction *transaction,
2429                                               DBusMessage *message,
2430                                               DBusError *error);
2431
2432 static dbus_bool_t bus_driver_handle_set (DBusConnection *connection,
2433                                           BusTransaction *transaction,
2434                                           DBusMessage *message,
2435                                           DBusError *error);
2436
2437 static dbus_bool_t features_getter (BusContext      *context,
2438                                     DBusMessageIter *variant_iter);
2439 static dbus_bool_t interfaces_getter (BusContext      *context,
2440                                       DBusMessageIter *variant_iter);
2441
2442 typedef enum
2443 {
2444   /* Various older methods were available at every object path. We have to
2445    * preserve that behaviour for backwards compatibility, but we can at least
2446    * stop doing that for newly added methods.
2447    * The special Peer interface should also work at any object path.
2448    * <https://bugs.freedesktop.org/show_bug.cgi?id=101256> */
2449   METHOD_FLAG_ANY_PATH = (1 << 0),
2450
2451   /* If set, callers must be privileged. On Unix, the uid of the connection
2452    * must either be the uid of this process, or 0 (root). On Windows,
2453    * the SID of the connection must be the SID of this process. */
2454   METHOD_FLAG_PRIVILEGED = (1 << 1),
2455
2456   METHOD_FLAG_NONE = 0
2457 } MethodFlags;
2458
2459 typedef struct
2460 {
2461   const char *name;
2462   const char *in_args;
2463   const char *out_args;
2464   BusResult (* handler) (DBusConnection *connection,
2465                          BusTransaction *transaction,
2466                          DBusMessage    *message,
2467                          DBusError      *error);
2468   MethodFlags flags;
2469 } MessageHandler;
2470
2471 typedef struct
2472 {
2473   const char *name;
2474   const char *type;
2475   dbus_bool_t (* getter) (BusContext      *context,
2476                           DBusMessageIter *variant_iter);
2477 } PropertyHandler;
2478
2479 /* For speed it might be useful to sort this in order of
2480  * frequency of use (but doesn't matter with only a few items
2481  * anyhow)
2482  */
2483 static const MessageHandler dbus_message_handlers[] = {
2484   { "Hello",
2485     "",
2486     DBUS_TYPE_STRING_AS_STRING,
2487     bus_driver_handle_hello,
2488     METHOD_FLAG_ANY_PATH },
2489   { "RequestName",
2490     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
2491     DBUS_TYPE_UINT32_AS_STRING,
2492     bus_driver_handle_acquire_service,
2493     METHOD_FLAG_ANY_PATH },
2494   { "ReleaseName",
2495     DBUS_TYPE_STRING_AS_STRING,
2496     DBUS_TYPE_UINT32_AS_STRING,
2497     bus_driver_handle_release_service,
2498     METHOD_FLAG_ANY_PATH },
2499   { "StartServiceByName",
2500     DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
2501     DBUS_TYPE_UINT32_AS_STRING,
2502     bus_driver_handle_activate_service,
2503     METHOD_FLAG_ANY_PATH },
2504   { "UpdateActivationEnvironment",
2505     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,
2506     "",
2507     bus_driver_handle_update_activation_environment,
2508     METHOD_FLAG_PRIVILEGED },
2509   { "NameHasOwner",
2510     DBUS_TYPE_STRING_AS_STRING,
2511     DBUS_TYPE_BOOLEAN_AS_STRING,
2512     bus_driver_handle_service_exists,
2513     METHOD_FLAG_ANY_PATH },
2514   { "ListNames",
2515     "",
2516     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
2517     bus_driver_handle_list_services,
2518     METHOD_FLAG_ANY_PATH },
2519   { "ListActivatableNames",
2520     "",
2521     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
2522     bus_driver_handle_list_activatable_services,
2523     METHOD_FLAG_ANY_PATH },
2524   { "AddMatch",
2525     DBUS_TYPE_STRING_AS_STRING,
2526     "",
2527     bus_driver_handle_add_match,
2528     METHOD_FLAG_ANY_PATH },
2529   { "RemoveMatch",
2530     DBUS_TYPE_STRING_AS_STRING,
2531     "",
2532     bus_driver_handle_remove_match,
2533     METHOD_FLAG_ANY_PATH },
2534   { "GetNameOwner",
2535     DBUS_TYPE_STRING_AS_STRING,
2536     DBUS_TYPE_STRING_AS_STRING,
2537     bus_driver_handle_get_service_owner,
2538     METHOD_FLAG_ANY_PATH },
2539   { "ListQueuedOwners",
2540     DBUS_TYPE_STRING_AS_STRING,
2541     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
2542     bus_driver_handle_list_queued_owners,
2543     METHOD_FLAG_ANY_PATH },
2544   { "GetConnectionUnixUser",
2545     DBUS_TYPE_STRING_AS_STRING,
2546     DBUS_TYPE_UINT32_AS_STRING,
2547     bus_driver_handle_get_connection_unix_user,
2548     METHOD_FLAG_ANY_PATH },
2549   { "GetConnectionUnixProcessID",
2550     DBUS_TYPE_STRING_AS_STRING,
2551     DBUS_TYPE_UINT32_AS_STRING,
2552     bus_driver_handle_get_connection_unix_process_id,
2553     METHOD_FLAG_ANY_PATH },
2554   { "GetAdtAuditSessionData",
2555     DBUS_TYPE_STRING_AS_STRING,
2556     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
2557     bus_driver_handle_get_adt_audit_session_data,
2558     METHOD_FLAG_ANY_PATH },
2559   { "GetConnectionSELinuxSecurityContext",
2560     DBUS_TYPE_STRING_AS_STRING,
2561     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
2562     bus_driver_handle_get_connection_selinux_security_context,
2563     METHOD_FLAG_ANY_PATH },
2564   { "ReloadConfig",
2565     "",
2566     "",
2567     bus_driver_handle_reload_config,
2568     METHOD_FLAG_ANY_PATH },
2569   { "GetId",
2570     "",
2571     DBUS_TYPE_STRING_AS_STRING,
2572     bus_driver_handle_get_id,
2573     METHOD_FLAG_ANY_PATH },
2574   { "GetConnectionCredentials", "s", "a{sv}",
2575     bus_driver_handle_get_connection_credentials,
2576     METHOD_FLAG_ANY_PATH },
2577   { NULL, NULL, NULL, NULL }
2578 };
2579
2580 static const PropertyHandler dbus_property_handlers[] = {
2581   { "Features", "as", features_getter },
2582   { "Interfaces", "as", interfaces_getter },
2583   { NULL, NULL, NULL }
2584 };
2585
2586 static BusResult bus_driver_handle_introspect (DBusConnection *,
2587     BusTransaction *, DBusMessage *, DBusError *);
2588
2589 static const MessageHandler properties_message_handlers[] = {
2590   { "Get", "ss", "v", bus_driver_handle_get, METHOD_FLAG_NONE },
2591   { "GetAll", "s", "a{sv}", bus_driver_handle_get_all, METHOD_FLAG_NONE },
2592   { "Set", "ssv", "", bus_driver_handle_set, METHOD_FLAG_NONE },
2593   { NULL, NULL, NULL, NULL }
2594 };
2595
2596 static const MessageHandler introspectable_message_handlers[] = {
2597   { "Introspect", "", DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_introspect,
2598     METHOD_FLAG_ANY_PATH },
2599   { NULL, NULL, NULL, NULL }
2600 };
2601
2602 static const MessageHandler monitoring_message_handlers[] = {
2603   { "BecomeMonitor", "asu", "", bus_driver_handle_become_monitor,
2604     METHOD_FLAG_PRIVILEGED },
2605   { NULL, NULL, NULL, NULL }
2606 };
2607
2608 #ifdef DBUS_ENABLE_VERBOSE_MODE
2609 static const MessageHandler verbose_message_handlers[] = {
2610   { "EnableVerbose", "", "", bus_driver_handle_enable_verbose,
2611     METHOD_FLAG_NONE },
2612   { "DisableVerbose", "", "", bus_driver_handle_disable_verbose,
2613     METHOD_FLAG_NONE },
2614   { NULL, NULL, NULL, NULL }
2615 };
2616 #endif
2617
2618 #ifdef DBUS_ENABLE_STATS
2619 static const MessageHandler stats_message_handlers[] = {
2620   { "GetStats", "", "a{sv}", bus_stats_handle_get_stats,
2621     METHOD_FLAG_NONE },
2622   { "GetConnectionStats", "s", "a{sv}", bus_stats_handle_get_connection_stats,
2623     METHOD_FLAG_NONE },
2624   { "GetAllMatchRules", "", "a{sas}", bus_stats_handle_get_all_match_rules,
2625     METHOD_FLAG_NONE },
2626   { NULL, NULL, NULL, NULL }
2627 };
2628 #endif
2629
2630 static const MessageHandler peer_message_handlers[] = {
2631   { "GetMachineId", "", "s", bus_driver_handle_get_machine_id,
2632     METHOD_FLAG_ANY_PATH },
2633   { "Ping", "", "", bus_driver_handle_ping, METHOD_FLAG_ANY_PATH },
2634   { NULL, NULL, NULL, NULL }
2635 };
2636
2637 typedef enum
2638 {
2639   /* Various older interfaces were available at every object path. We have to
2640    * preserve that behaviour for backwards compatibility, but we can at least
2641    * stop doing that for newly added interfaces:
2642    * <https://bugs.freedesktop.org/show_bug.cgi?id=101256>
2643    * Introspectable and Peer are also useful at all object paths. */
2644   INTERFACE_FLAG_ANY_PATH = (1 << 0),
2645
2646   /* Set this flag for interfaces that should not show up in the
2647    * Interfaces property. */
2648   INTERFACE_FLAG_UNINTERESTING = (1 << 1),
2649
2650   INTERFACE_FLAG_NONE = 0
2651 } InterfaceFlags;
2652
2653 typedef struct {
2654   const char *name;
2655   const MessageHandler *message_handlers;
2656   const char *extra_introspection;
2657   InterfaceFlags flags;
2658   const PropertyHandler *property_handlers;
2659 } InterfaceHandler;
2660
2661 /* These should ideally be sorted by frequency of use, although it
2662  * probably doesn't matter with this few items */
2663 static InterfaceHandler interface_handlers[] = {
2664   { DBUS_INTERFACE_DBUS, dbus_message_handlers,
2665     "    <signal name=\"NameOwnerChanged\">\n"
2666     "      <arg type=\"s\"/>\n"
2667     "      <arg type=\"s\"/>\n"
2668     "      <arg type=\"s\"/>\n"
2669     "    </signal>\n"
2670     "    <signal name=\"NameLost\">\n"
2671     "      <arg type=\"s\"/>\n"
2672     "    </signal>\n"
2673     "    <signal name=\"NameAcquired\">\n"
2674     "      <arg type=\"s\"/>\n"
2675     "    </signal>\n",
2676     /* Not in the Interfaces property because if you can get the properties
2677      * of the o.fd.DBus interface, then you certainly have the o.fd.DBus
2678      * interface, so there is little point in listing it explicitly.
2679      * Partially available at all paths for backwards compatibility. */
2680     INTERFACE_FLAG_ANY_PATH | INTERFACE_FLAG_UNINTERESTING,
2681     dbus_property_handlers },
2682   { DBUS_INTERFACE_PROPERTIES, properties_message_handlers,
2683     "    <signal name=\"PropertiesChanged\">\n"
2684     "      <arg type=\"s\" name=\"interface_name\"/>\n"
2685     "      <arg type=\"a{sv}\" name=\"changed_properties\"/>\n"
2686     "      <arg type=\"as\" name=\"invalidated_properties\"/>\n"
2687     "    </signal>\n",
2688     /* Not in the Interfaces property because if you can get the properties
2689      * of the o.fd.DBus interface, then you certainly have Properties. */
2690     INTERFACE_FLAG_UNINTERESTING },
2691   { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL,
2692     /* Not in the Interfaces property because introspection isn't really a
2693      * feature in the same way as e.g. Monitoring.
2694      * Available at all paths so tools like d-feet can start from "/". */
2695     INTERFACE_FLAG_ANY_PATH | INTERFACE_FLAG_UNINTERESTING },
2696   { DBUS_INTERFACE_MONITORING, monitoring_message_handlers, NULL,
2697     INTERFACE_FLAG_NONE },
2698 #ifdef DBUS_ENABLE_VERBOSE_MODE
2699   { DBUS_INTERFACE_VERBOSE, verbose_message_handlers, NULL,
2700     INTERFACE_FLAG_NONE },
2701 #endif
2702 #ifdef DBUS_ENABLE_STATS
2703   { BUS_INTERFACE_STATS, stats_message_handlers, NULL,
2704     INTERFACE_FLAG_NONE },
2705 #endif
2706   { DBUS_INTERFACE_PEER, peer_message_handlers, NULL,
2707     /* Not in the Interfaces property because it's a pseudo-interface
2708      * on all object paths of all connections, rather than a feature of the
2709      * bus driver object. */
2710     INTERFACE_FLAG_ANY_PATH | INTERFACE_FLAG_UNINTERESTING },
2711   { NULL, NULL, NULL }
2712 };
2713
2714 static dbus_bool_t
2715 write_args_for_direction (DBusString *xml,
2716                           const char *signature,
2717                           dbus_bool_t in)
2718 {
2719   DBusTypeReader typereader;
2720   DBusString sigstr;
2721   int current_type;
2722
2723   _dbus_string_init_const (&sigstr, signature);
2724   _dbus_type_reader_init_types_only (&typereader, &sigstr, 0);
2725
2726   while ((current_type = _dbus_type_reader_get_current_type (&typereader)) != DBUS_TYPE_INVALID)
2727     {
2728       const DBusString *subsig;
2729       int start, len;
2730
2731       _dbus_type_reader_get_signature (&typereader, &subsig, &start, &len);
2732       if (!_dbus_string_append_printf (xml, "      <arg direction=\"%s\" type=\"",
2733                                        in ? "in" : "out"))
2734         goto oom;
2735       if (!_dbus_string_append_len (xml,
2736                                     _dbus_string_get_const_data (subsig) + start,
2737                                     len))
2738         goto oom;
2739       if (!_dbus_string_append (xml, "\"/>\n"))
2740         goto oom;
2741
2742       _dbus_type_reader_next (&typereader);
2743     }
2744   return TRUE;
2745  oom:
2746   return FALSE;
2747 }
2748
2749 dbus_bool_t
2750 bus_driver_generate_introspect_string (DBusString *xml,
2751                                        dbus_bool_t is_canonical_path,
2752                                        DBusMessage *message)
2753 {
2754   const InterfaceHandler *ih;
2755   const MessageHandler *mh;
2756   const PropertyHandler *ph;
2757
2758   if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
2759     return FALSE;
2760   if (!_dbus_string_append (xml, "<node>\n"))
2761     return FALSE;
2762
2763   for (ih = interface_handlers; ih->name != NULL; ih++)
2764     {
2765       if (!(is_canonical_path || (ih->flags & INTERFACE_FLAG_ANY_PATH)))
2766         continue;
2767
2768       if (!_dbus_string_append_printf (xml, "  <interface name=\"%s\">\n",
2769                                        ih->name))
2770         return FALSE;
2771
2772       for (mh = ih->message_handlers; mh->name != NULL; mh++)
2773         {
2774           if (!_dbus_string_append_printf (xml, "    <method name=\"%s\">\n",
2775                                            mh->name))
2776             return FALSE;
2777
2778           if (!write_args_for_direction (xml, mh->in_args, TRUE))
2779             return FALSE;
2780
2781           if (!write_args_for_direction (xml, mh->out_args, FALSE))
2782             return FALSE;
2783
2784           if (!_dbus_string_append (xml, "    </method>\n"))
2785             return FALSE;
2786         }
2787
2788       for (ph = ih->property_handlers; ph != NULL && ph->name != NULL; ph++)
2789         {
2790           /* We only have constant properties so far, so hard-code that bit */
2791           if (!_dbus_string_append_printf (xml,
2792                                            "    <property name=\"%s\" type=\"%s\" access=\"read\">\n",
2793                                            ph->name, ph->type))
2794             return FALSE;
2795
2796           if (!_dbus_string_append (xml,
2797                                     "      <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n"
2798                                     "    </property>\n"))
2799             return FALSE;
2800         }
2801
2802       if (ih->extra_introspection != NULL &&
2803           !_dbus_string_append (xml, ih->extra_introspection))
2804         return FALSE;
2805
2806       if (!_dbus_string_append (xml, "  </interface>\n"))
2807         return FALSE;
2808     }
2809
2810   if (message != NULL)
2811     {
2812       /* Make the bus driver object path discoverable */
2813       if (dbus_message_has_path (message, "/"))
2814         {
2815           if (!_dbus_string_append (xml,
2816                 "  <node name=\"org/freedesktop/DBus\"/>\n"))
2817             return FALSE;
2818         }
2819       else if (dbus_message_has_path (message, "/org"))
2820         {
2821           if (!_dbus_string_append (xml,
2822                 "  <node name=\"freedesktop/DBus\"/>\n"))
2823             return FALSE;
2824         }
2825       else if (dbus_message_has_path (message, "/org/freedesktop"))
2826         {
2827           if (!_dbus_string_append (xml, "  <node name=\"DBus\"/>\n"))
2828             return FALSE;
2829         }
2830     }
2831
2832   if (!_dbus_string_append (xml, "</node>\n"))
2833     return FALSE;
2834
2835   return TRUE;
2836 }
2837
2838 static BusResult
2839 bus_driver_handle_introspect (DBusConnection *connection,
2840                               BusTransaction *transaction,
2841                               DBusMessage    *message,
2842                               DBusError      *error)
2843 {
2844   DBusString xml;
2845   DBusMessage *reply;
2846   const char *v_STRING;
2847   dbus_bool_t is_canonical_path;
2848
2849   _dbus_verbose ("Introspect() on bus driver\n");
2850
2851   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2852
2853   reply = NULL;
2854
2855   if (! dbus_message_get_args (message, error,
2856                                DBUS_TYPE_INVALID))
2857     {
2858       _DBUS_ASSERT_ERROR_IS_SET (error);
2859       return BUS_RESULT_FALSE;
2860     }
2861
2862   if (!_dbus_string_init (&xml))
2863     {
2864       BUS_SET_OOM (error);
2865       return BUS_RESULT_FALSE;
2866     }
2867
2868   is_canonical_path = dbus_message_has_path (message, DBUS_PATH_DBUS);
2869
2870   if (!bus_driver_generate_introspect_string (&xml, is_canonical_path, message))
2871     goto oom;
2872
2873   v_STRING = _dbus_string_get_const_data (&xml);
2874
2875   reply = dbus_message_new_method_return (message);
2876   if (reply == NULL)
2877     goto oom;
2878
2879   if (! dbus_message_append_args (reply,
2880                                   DBUS_TYPE_STRING, &v_STRING,
2881                                   DBUS_TYPE_INVALID))
2882     goto oom;
2883
2884   if (! bus_transaction_send_from_driver (transaction, connection, reply))
2885     goto oom;
2886
2887   dbus_message_unref (reply);
2888   _dbus_string_free (&xml);
2889
2890   return BUS_RESULT_TRUE;
2891
2892  oom:
2893   BUS_SET_OOM (error);
2894
2895   if (reply)
2896     dbus_message_unref (reply);
2897
2898   _dbus_string_free (&xml);
2899
2900   return BUS_RESULT_FALSE;
2901 }
2902
2903 BusResult
2904 bus_driver_handle_message (DBusConnection *connection,
2905                            BusTransaction *transaction,
2906                            DBusMessage    *message,
2907                            DBusError      *error)
2908 {
2909   const char *name, *interface;
2910   const InterfaceHandler *ih;
2911   const MessageHandler *mh;
2912   dbus_bool_t found_interface = FALSE;
2913   dbus_bool_t is_canonical_path;
2914
2915   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2916
2917   if (dbus_message_is_signal (message, "org.freedesktop.systemd1.Activator", "ActivationFailure"))
2918     {
2919       BusContext *context;
2920       DBusConnection *systemd;
2921
2922       /* This is a directed signal, not a method call, so the log message
2923        * is a little weird (it talks about "calling" ActivationFailure),
2924        * but it's close enough */
2925       if (!bus_driver_check_caller_is_privileged (connection,
2926                                                   transaction,
2927                                                   message,
2928                                                   error))
2929         return BUS_RESULT_FALSE;
2930
2931       context = bus_connection_get_context (connection);
2932       systemd = bus_driver_get_owner_of_name (connection,
2933           "org.freedesktop.systemd1");
2934
2935       if (systemd != connection)
2936         {
2937           const char *attacker;
2938
2939           attacker = bus_connection_get_name (connection);
2940           bus_context_log (context, DBUS_SYSTEM_LOG_SECURITY,
2941                            "Ignoring forged ActivationFailure message from "
2942                            "connection %s (%s)",
2943                            attacker ? attacker : "(unauthenticated)",
2944                            bus_connection_get_loginfo (connection));
2945           /* ignore it */
2946           return BUS_RESULT_TRUE;
2947         }
2948
2949       if (!bus_context_get_systemd_activation (context))
2950         {
2951           bus_context_log (context, DBUS_SYSTEM_LOG_WARNING,
2952                            "Ignoring unexpected ActivationFailure message "
2953                            "while not using systemd activation");
2954           return BUS_RESULT_FALSE;
2955         }
2956
2957       return dbus_activation_systemd_failure(bus_context_get_activation(context), message) == TRUE ? BUS_RESULT_TRUE : BUS_RESULT_FALSE;
2958     }
2959
2960   if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
2961     {
2962       _dbus_verbose ("Driver got a non-method-call message, ignoring\n");
2963       return BUS_RESULT_TRUE; /* we just ignore this */
2964     }
2965
2966   /* may be NULL, which means "any interface will do" */
2967   interface = dbus_message_get_interface (message);
2968
2969   _dbus_assert (dbus_message_get_member (message) != NULL);
2970
2971   name = dbus_message_get_member (message);
2972
2973   _dbus_verbose ("Driver got a method call: %s\n", name);
2974
2975   /* security checks should have kept this from getting here */
2976   _dbus_assert (dbus_message_get_sender (message) != NULL ||
2977                 strcmp (name, "Hello") == 0);
2978
2979   is_canonical_path = dbus_message_has_path (message, DBUS_PATH_DBUS);
2980
2981   for (ih = interface_handlers; ih->name != NULL; ih++)
2982     {
2983       if (!(is_canonical_path || (ih->flags & INTERFACE_FLAG_ANY_PATH)))
2984         continue;
2985
2986       if (interface != NULL && strcmp (interface, ih->name) != 0)
2987         continue;
2988
2989       found_interface = TRUE;
2990
2991       for (mh = ih->message_handlers; mh->name != NULL; mh++)
2992         {
2993           if (strcmp (mh->name, name) != 0)
2994             continue;
2995
2996           _dbus_verbose ("Found driver handler for %s\n", name);
2997
2998           if ((mh->flags & METHOD_FLAG_PRIVILEGED) &&
2999               !bus_driver_check_caller_is_privileged (connection, transaction,
3000                                                       message, error))
3001             {
3002               _DBUS_ASSERT_ERROR_IS_SET (error);
3003               return BUS_RESULT_FALSE;
3004             }
3005
3006           if (!(is_canonical_path || (mh->flags & METHOD_FLAG_ANY_PATH)))
3007             {
3008               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3009               dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
3010                   "Method '%s' is only available at the canonical object path '%s'",
3011                   dbus_message_get_member (message), DBUS_PATH_DBUS);
3012               _DBUS_ASSERT_ERROR_IS_SET (error);
3013               return BUS_RESULT_FALSE;
3014             }
3015
3016           if (!dbus_message_has_signature (message, mh->in_args))
3017             {
3018               _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3019               _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n",
3020                              name, dbus_message_get_signature (message),
3021                              mh->in_args);
3022
3023               dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
3024                               "Call to %s has wrong args (%s, expected %s)\n",
3025                               name, dbus_message_get_signature (message),
3026                               mh->in_args);
3027               _DBUS_ASSERT_ERROR_IS_SET (error);
3028               return BUS_RESULT_FALSE;
3029             }
3030
3031           switch ((* mh->handler) (connection, transaction, message, error))
3032             {
3033               case BUS_RESULT_TRUE:
3034                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3035                 _dbus_verbose ("Driver handler succeeded\n");
3036                 return BUS_RESULT_TRUE;
3037               case BUS_RESULT_FALSE:
3038                 _DBUS_ASSERT_ERROR_IS_SET (error);
3039                 _dbus_verbose ("Driver handler returned failure\n");
3040                 return BUS_RESULT_FALSE;
3041               case BUS_RESULT_LATER:
3042                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3043                 _dbus_verbose ("Driver handler delayed message processing due to policy check\n");
3044                 return BUS_RESULT_LATER;
3045             }
3046         }
3047     }
3048
3049   _dbus_verbose ("No driver handler for message \"%s\"\n",
3050                  name);
3051
3052   dbus_set_error (error, found_interface ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_INTERFACE,
3053                   "%s does not understand message %s",
3054                   DBUS_SERVICE_DBUS, name);
3055
3056   return BUS_RESULT_FALSE;
3057 }
3058
3059 void
3060 bus_driver_remove_connection (DBusConnection *connection)
3061 {
3062   /* FIXME 1.0 Does nothing for now, should unregister the connection
3063    * with the bus driver.
3064    */
3065 }
3066
3067 static dbus_bool_t
3068 features_getter (BusContext      *context,
3069                  DBusMessageIter *variant_iter)
3070 {
3071   DBusMessageIter arr_iter;
3072
3073   if (!dbus_message_iter_open_container (variant_iter, DBUS_TYPE_ARRAY,
3074                                          DBUS_TYPE_STRING_AS_STRING,
3075                                          &arr_iter))
3076     return FALSE;
3077
3078   if (bus_apparmor_enabled ())
3079     {
3080       const char *s = "AppArmor";
3081
3082       if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_STRING, &s))
3083         goto abandon;
3084     }
3085
3086   if (bus_selinux_enabled ())
3087     {
3088       const char *s = "SELinux";
3089
3090       if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_STRING, &s))
3091         goto abandon;
3092     }
3093
3094   if (bus_context_get_systemd_activation (context))
3095     {
3096       const char *s = "SystemdActivation";
3097
3098       if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_STRING, &s))
3099         goto abandon;
3100     }
3101
3102   return dbus_message_iter_close_container (variant_iter, &arr_iter);
3103
3104 abandon:
3105   dbus_message_iter_abandon_container (variant_iter, &arr_iter);
3106   return FALSE;
3107 }
3108
3109 static dbus_bool_t
3110 interfaces_getter (BusContext      *context,
3111                    DBusMessageIter *variant_iter)
3112 {
3113   DBusMessageIter arr_iter;
3114   const InterfaceHandler *ih;
3115
3116   if (!dbus_message_iter_open_container (variant_iter, DBUS_TYPE_ARRAY,
3117                                          DBUS_TYPE_STRING_AS_STRING,
3118                                          &arr_iter))
3119     return FALSE;
3120
3121   for (ih = interface_handlers; ih->name != NULL; ih++)
3122     {
3123       if (ih->flags & INTERFACE_FLAG_UNINTERESTING)
3124         continue;
3125
3126       if (!dbus_message_iter_append_basic (&arr_iter, DBUS_TYPE_STRING,
3127                                            &ih->name))
3128         goto abandon;
3129     }
3130
3131   return dbus_message_iter_close_container (variant_iter, &arr_iter);
3132
3133 abandon:
3134   dbus_message_iter_abandon_container (variant_iter, &arr_iter);
3135   return FALSE;
3136 }
3137
3138 static const InterfaceHandler *
3139 bus_driver_find_interface (const char  *name,
3140                            dbus_bool_t  canonical_path,
3141                            DBusError   *error)
3142 {
3143   const InterfaceHandler *ih;
3144
3145   for (ih = interface_handlers; ih->name != NULL; ih++)
3146     {
3147       if (!(canonical_path || (ih->flags & INTERFACE_FLAG_ANY_PATH)))
3148         continue;
3149
3150       if (strcmp (name, ih->name) == 0)
3151         return ih;
3152     }
3153
3154   dbus_set_error (error, DBUS_ERROR_UNKNOWN_INTERFACE,
3155                   "Interface \"%s\" not found", name);
3156   return NULL;
3157 }
3158
3159 static const PropertyHandler *
3160 interface_handler_find_property (const InterfaceHandler *ih,
3161                                  const char             *name,
3162                                  DBusError              *error)
3163 {
3164   const PropertyHandler *ph;
3165
3166   for (ph = ih->property_handlers; ph != NULL && ph->name != NULL; ph++)
3167     {
3168       if (strcmp (name, ph->name) == 0)
3169         return ph;
3170     }
3171
3172   dbus_set_error (error, DBUS_ERROR_UNKNOWN_PROPERTY,
3173                   "Property \"%s.%s\" not found", ih->name, name);
3174   return NULL;
3175 }
3176
3177 static dbus_bool_t
3178 bus_driver_handle_get (DBusConnection *connection,
3179                        BusTransaction *transaction,
3180                        DBusMessage    *message,
3181                        DBusError      *error)
3182 {
3183   const InterfaceHandler *ih;
3184   const PropertyHandler *handler;
3185   const char *iface;
3186   const char *prop;
3187   BusContext *context;
3188   DBusMessage *reply = NULL;
3189   DBusMessageIter iter;
3190   DBusMessageIter var_iter;
3191
3192   /* The message signature has already been checked for us,
3193    * so this should always succeed. */
3194   if (!dbus_message_get_args (message, error,
3195                               DBUS_TYPE_STRING, &iface,
3196                               DBUS_TYPE_STRING, &prop,
3197                               DBUS_TYPE_INVALID))
3198     return FALSE;
3199
3200   /* We only implement Properties on /org/freedesktop/DBus so far. */
3201   ih = bus_driver_find_interface (iface, TRUE, error);
3202
3203   if (ih == NULL)
3204     return FALSE;
3205
3206   handler = interface_handler_find_property (ih, prop, error);
3207
3208   if (handler == NULL)
3209     return FALSE;
3210
3211   context = bus_transaction_get_context (transaction);
3212
3213   reply = dbus_message_new_method_return (message);
3214
3215   if (reply == NULL)
3216     goto oom;
3217
3218   dbus_message_iter_init_append (reply, &iter);
3219
3220   if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT,
3221                                          handler->type, &var_iter))
3222     goto oom;
3223
3224   if (!handler->getter (context, &var_iter))
3225     {
3226       dbus_message_iter_abandon_container (&iter, &var_iter);
3227       goto oom;
3228     }
3229
3230   if (!dbus_message_iter_close_container (&iter, &var_iter))
3231     goto oom;
3232
3233   if (!bus_transaction_send_from_driver (transaction, connection, reply))
3234     goto oom;
3235
3236   dbus_message_unref (reply);
3237   return TRUE;
3238
3239 oom:
3240   if (reply != NULL)
3241     dbus_message_unref (reply);
3242
3243   BUS_SET_OOM (error);
3244   return FALSE;
3245 }
3246
3247 static dbus_bool_t
3248 bus_driver_handle_get_all (DBusConnection *connection,
3249                            BusTransaction *transaction,
3250                            DBusMessage    *message,
3251                            DBusError      *error)
3252 {
3253   const InterfaceHandler *ih;
3254   const char *iface;
3255   const PropertyHandler *ph;
3256   DBusMessageIter reply_iter;
3257   DBusMessageIter array_iter;
3258   BusContext *context;
3259   DBusMessage *reply = NULL;
3260
3261   /* The message signature has already been checked for us,
3262    * so this should always succeed. */
3263   if (!dbus_message_get_args (message, error,
3264                               DBUS_TYPE_STRING, &iface,
3265                               DBUS_TYPE_INVALID))
3266     return FALSE;
3267
3268   /* We only implement Properties on /org/freedesktop/DBus so far. */
3269   ih = bus_driver_find_interface (iface, TRUE, error);
3270
3271   if (ih == NULL)
3272     return FALSE;
3273
3274   context = bus_transaction_get_context (transaction);
3275
3276   reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter);
3277
3278   if (reply == NULL)
3279     goto oom;
3280
3281   for (ph = ih->property_handlers; ph != NULL && ph->name != NULL; ph++)
3282     {
3283       DBusMessageIter entry_iter;
3284       DBusMessageIter var_iter;
3285
3286       if (!_dbus_asv_open_entry (&array_iter, &entry_iter, ph->name,
3287                                  ph->type, &var_iter))
3288         goto oom_abandon_message;
3289
3290       if (!ph->getter (context, &var_iter))
3291         {
3292           _dbus_asv_abandon_entry (&array_iter, &entry_iter, &var_iter);
3293           goto oom_abandon_message;
3294         }
3295
3296       if (!_dbus_asv_close_entry (&array_iter, &entry_iter, &var_iter))
3297         goto oom_abandon_message;
3298     }
3299
3300   if (!_dbus_asv_close (&reply_iter, &array_iter))
3301     goto oom;
3302
3303   if (!bus_transaction_send_from_driver (transaction, connection, reply))
3304     goto oom;
3305
3306   dbus_message_unref (reply);
3307   return TRUE;
3308
3309 oom_abandon_message:
3310   _dbus_asv_abandon (&reply_iter, &array_iter);
3311   /* fall through */
3312 oom:
3313   if (reply != NULL)
3314     dbus_message_unref (reply);
3315
3316   BUS_SET_OOM (error);
3317   return FALSE;
3318 }
3319
3320 static dbus_bool_t
3321 bus_driver_handle_set (DBusConnection *connection,
3322                        BusTransaction *transaction,
3323                        DBusMessage    *message,
3324                        DBusError      *error)
3325 {
3326   const InterfaceHandler *ih;
3327   const char *iface;
3328   const char *prop;
3329   const PropertyHandler *handler;
3330   DBusMessageIter iter;
3331
3332   /* We already checked this in bus_driver_handle_message() */
3333   _dbus_assert (dbus_message_has_signature (message, "ssv"));
3334
3335   if (!dbus_message_iter_init (message, &iter))
3336     _dbus_assert_not_reached ("Message type was already checked to be 'ssv'");
3337
3338   dbus_message_iter_get_basic (&iter, &iface);
3339
3340   if (!dbus_message_iter_next (&iter))
3341     _dbus_assert_not_reached ("Message type was already checked to be 'ssv'");
3342
3343   dbus_message_iter_get_basic (&iter, &prop);
3344
3345   /* We only implement Properties on /org/freedesktop/DBus so far. */
3346   ih = bus_driver_find_interface (iface, TRUE, error);
3347
3348   if (ih == NULL)
3349     return FALSE;
3350
3351   handler = interface_handler_find_property (ih, prop, error);
3352
3353   if (handler == NULL)
3354     return FALSE;
3355
3356   /* We don't implement any properties that can be set yet. */
3357   dbus_set_error (error, DBUS_ERROR_PROPERTY_READ_ONLY,
3358                   "Property '%s.%s' cannot be set", iface, prop);
3359   return FALSE;
3360 }