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