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