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