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