diff options
| -rw-r--r-- | ChangeLog | 9 | ||||
| -rw-r--r-- | bus/dispatch.c | 136 | ||||
| -rw-r--r-- | bus/driver.c | 78 | ||||
| -rw-r--r-- | dbus/dbus-bus.c | 73 | ||||
| -rw-r--r-- | dbus/dbus-bus.h | 3 | ||||
| -rw-r--r-- | doc/dbus-specification.xml | 51 | 
6 files changed, 350 insertions, 0 deletions
@@ -1,3 +1,12 @@ +2004-06-28  Kay Sievers <kay.sievers@vrfy.org> + +	* bus/driver.c (bus_driver_handle_get_connection_unix_user) +	* dbus/bus.c (dbus_bus_get_unix_user) +	* doc/dbus-specification.xml: implement GetConnectionUnixUser +	method of org.freedesktop.DBus interface. + +	* bus/dispatch.c: test case +  2004-06-23  John (J5) Palmieri  <johnp@redhat.com>  	* python/Makefile.am: switched include directory from glib/ to dbus/ diff --git a/bus/dispatch.c b/bus/dispatch.c index b7191d7e..f38a9904 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -924,6 +924,142 @@ check_hello_message (BusContext     *context,   * but the correct thing may include OOM errors.   */  static dbus_bool_t +check_get_connection_unix_user (BusContext     *context, +                                DBusConnection *connection) +{ +  DBusMessage *message; +  dbus_uint32_t serial; +  dbus_bool_t retval; +  DBusError error; +  const char *base_service_name; +  dbus_uint32_t uid; + +  retval = FALSE; +  dbus_error_init (&error); +  message = NULL; + +  _dbus_verbose ("check_get_connection_unix_user for %p\n", connection); +   +  message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, +                                          DBUS_PATH_ORG_FREEDESKTOP_DBUS, +                                          DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, +                                          "GetConnectionUnixUser"); + +  if (message == NULL) +    return TRUE; + +  base_service_name = dbus_bus_get_base_service (connection); + +  if (!dbus_message_append_args (message,  +                                 DBUS_TYPE_STRING, base_service_name, +                                 DBUS_TYPE_INVALID)) +    { +      dbus_message_unref (message); +      return TRUE; +    } + +  if (!dbus_connection_send (connection, message, &serial)) +    { +      dbus_message_unref (message); +      return TRUE; +    } + +  /* send our message */ +  bus_test_run_clients_loop (TRUE); + +  dbus_message_unref (message); +  message = NULL; + +  dbus_connection_ref (connection); /* because we may get disconnected */ +  block_connection_until_message_from_bus (context, connection); + +  if (!dbus_connection_get_is_connected (connection)) +    { +      _dbus_verbose ("connection was disconnected\n"); +       +      dbus_connection_unref (connection); +       +      return TRUE; +    } + +  dbus_connection_unref (connection); + +  message = pop_message_waiting_for_memory (connection); +  if (message == NULL) +    { +      _dbus_warn ("Did not receive a reply to %s %d on %p\n", +                  "GetConnectionUnixUser", serial, connection); +      goto out; +    } + +  verbose_message_received (connection, message); + +  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) +    { +      if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY)) +        { +          ; /* good, this is a valid response */ +        } +      else +        { +          warn_unexpected (connection, message, "not this error"); + +          goto out; +        } +    } +  else +    { +      if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) +        { +          ; /* good, expected */ +        } +      else +        { +          warn_unexpected (connection, message, +	                   "method_return for GetConnectionUnixUser"); + +          goto out; +        } + +    retry_get_property: + +      if (!dbus_message_get_args (message, &error, +                                  DBUS_TYPE_UINT32, &uid, +                                  DBUS_TYPE_INVALID)) +        { +          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) +            { +              _dbus_verbose ("no memory to get uid by GetProperty\n"); +              dbus_error_free (&error); +              _dbus_wait_for_memory (); +              goto retry_get_property; +            } +          else +            { +              _dbus_assert (dbus_error_is_set (&error)); +              _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetProperty\n"); +              goto out; +            } +        } +    } + +  if (!check_no_leftovers (context)) +    goto out; + +  retval = TRUE; + + out: +  dbus_error_free (&error); +   +  if (message) +    dbus_message_unref (message); +   +  return retval; +} +/* returns TRUE if the correct thing happens, + * but the correct thing may include OOM errors. + */ +static dbus_bool_t  check_add_match_all (BusContext     *context,                       DBusConnection *connection)  { diff --git a/bus/driver.c b/bus/driver.c index 2b65a4c2..84e1d6b6 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -830,6 +830,83 @@ bus_driver_handle_get_service_owner (DBusConnection *connection,  }  static dbus_bool_t +bus_driver_handle_get_connection_unix_user (DBusConnection *connection, +                                            BusTransaction *transaction, +                                            DBusMessage    *message, +                                            DBusError      *error) +{ +  char *service; +  DBusString str; +  BusRegistry *registry; +  BusService *serv; +  DBusConnection *conn; +  DBusMessage *reply; +  unsigned long uid; +  const char *base_name; + +  _DBUS_ASSERT_ERROR_IS_CLEAR (error); + +  registry = bus_connection_get_registry (connection); + +  service = NULL; +  reply = NULL; + +  if (! dbus_message_get_args (message, error, +			       DBUS_TYPE_STRING, &service, +			       DBUS_TYPE_INVALID)) +      goto failed; + +  _dbus_verbose ("asked for UID of connection %s\n", service); + +  _dbus_string_init_const (&str, service); +  serv = bus_registry_lookup (registry, &str); +  if (serv == NULL) +    { +      dbus_set_error (error,  +		      DBUS_ERROR_SERVICE_HAS_NO_OWNER, +		      "Could not get owner of service '%s': no such service", service); +      goto failed; +    } + +  conn = bus_service_get_primary_owner (serv); + +  reply = dbus_message_new_method_return (message); +  if (reply == NULL) +    goto oom; + +  if (!dbus_connection_get_unix_user (conn, &uid)) +    { +      dbus_set_error (error, +                      DBUS_ERROR_FAILED, +                      "Could not determine UID for '%s'", service); +      goto failed; +    } + +  if (! dbus_message_append_args (reply, +                                  DBUS_TYPE_UINT32, (dbus_uint32_t) uid, +                                  DBUS_TYPE_INVALID)) +    goto oom; + +  if (! bus_transaction_send_from_driver (transaction, connection, reply)) +    goto oom; + +  dbus_message_unref (reply); +  dbus_free (service); + +  return TRUE; + + oom: +  BUS_SET_OOM (error); + + failed: +  _DBUS_ASSERT_ERROR_IS_SET (error); +  if (reply) +    dbus_message_unref (reply); +  dbus_free (service); +  return FALSE; +} + +static dbus_bool_t  bus_driver_handle_reload_config (DBusConnection *connection,  				 BusTransaction *transaction,  				 DBusMessage    *message, @@ -875,6 +952,7 @@ struct    { "AddMatch", bus_driver_handle_add_match },    { "RemoveMatch", bus_driver_handle_remove_match },    { "GetServiceOwner", bus_driver_handle_get_service_owner }, +  { "GetConnectionUnixUser", bus_driver_handle_get_connection_unix_user },    { "ReloadConfig", bus_driver_handle_reload_config }  }; diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c index 7dfe5264..7b609d67 100644 --- a/dbus/dbus-bus.c +++ b/dbus/dbus-bus.c @@ -546,6 +546,79 @@ dbus_bus_get_base_service (DBusConnection *connection)  }  /** + * Asks the bus to return the uid of a service. + * + * @param connection the connection + * @param service_name the service name + * @param error location to store the error + * @returns a result code, -1 if error is set + */  +unsigned long +dbus_bus_get_unix_user (DBusConnection *connection, +                        const char     *service, +                        DBusError      *error) +{ +  DBusMessage *message, *reply; +  dbus_uint32_t uid; + +  _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET); +  _dbus_return_val_if_fail (service != NULL, DBUS_UID_UNSET); +  _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET); +   +  message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, +                                          DBUS_PATH_ORG_FREEDESKTOP_DBUS, +                                          DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, +                                          "GetConnectionUnixUser"); + +  if (message == NULL) +    { +      _DBUS_SET_OOM (error); +      return DBUS_UID_UNSET; +    } +  +  if (!dbus_message_append_args (message, +				 DBUS_TYPE_STRING, service, +				 DBUS_TYPE_INVALID)) +    { +      dbus_message_unref (message); +      _DBUS_SET_OOM (error); +      return DBUS_UID_UNSET; +    } +   +  reply = dbus_connection_send_with_reply_and_block (connection, message, -1, +                                                     error); +   +  dbus_message_unref (message); +   +  if (reply == NULL) +    { +      _DBUS_ASSERT_ERROR_IS_SET (error); +      return DBUS_UID_UNSET; +    }   + +  if (dbus_set_error_from_message (error, reply)) +    { +      _DBUS_ASSERT_ERROR_IS_SET (error); +      dbus_message_unref (reply); +      return DBUS_UID_UNSET; +    } +   +  if (!dbus_message_get_args (reply, error, +                              DBUS_TYPE_UINT32, &uid, +                              DBUS_TYPE_INVALID)) +    { +      _DBUS_ASSERT_ERROR_IS_SET (error); +      dbus_message_unref (reply); +      return DBUS_UID_UNSET; +    } + +  dbus_message_unref (reply); +   +  return (unsigned long) uid; +} + + +/**   * Asks the bus to try to acquire a certain service.   *   * @todo these docs are not complete, need to document the diff --git a/dbus/dbus-bus.h b/dbus/dbus-bus.h index dd5e5eb7..536f5014 100644 --- a/dbus/dbus-bus.h +++ b/dbus/dbus-bus.h @@ -38,6 +38,9 @@ dbus_bool_t     dbus_bus_register         (DBusConnection *connection,  dbus_bool_t     dbus_bus_set_base_service (DBusConnection *connection,  					   const char     *base_service);  const char*     dbus_bus_get_base_service (DBusConnection *connection); +unsigned long   dbus_bus_get_unix_user    (DBusConnection *connection, +			                   const char     *service, +                                           DBusError      *error);  int             dbus_bus_acquire_service  (DBusConnection *connection,  					   const char     *service_name,  					   unsigned int    flags, diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml index 94f72bf8..f0d1727e 100644 --- a/doc/dbus-specification.xml +++ b/doc/dbus-specification.xml @@ -2497,6 +2497,57 @@         </para>        </sect3> +      <sect3 id="bus-messages-get-connection-unix-user"> +        <title><literal>org.freedesktop.DBus.GetConnectionUnixUser</literal></title> +        <para> +          As a method: +          <programlisting> +            UINT32 GetConnectionUnixUser (in STRING connection_name) +          </programlisting> +          Message arguments: +          <informaltable> +            <tgroup cols="3"> +              <thead> +                <row> +                  <entry>Argument</entry> +                  <entry>Type</entry> +                  <entry>Description</entry> +                </row> +              </thead> +              <tbody> +                <row> +                  <entry>0</entry> +                  <entry>STRING</entry> +                  <entry>Name of the connection/service to query</entry> +                </row> +              </tbody> +            </tgroup> +          </informaltable> +        Reply arguments: +        <informaltable> +          <tgroup cols="3"> +            <thead> +              <row> +                <entry>Argument</entry> +                <entry>Type</entry> +                <entry>Description</entry> +              </row> +            </thead> +            <tbody> +              <row> +                <entry>0</entry> +                <entry>UINT32</entry> +                <entry>unix user id</entry> +              </row> +            </tbody> +          </tgroup> +        </informaltable> +        Returns the unix uid of the process connected to the server. If unable to +	determine it, a <literal>org.freedesktop.DBus.Error.Failed</literal> +	error is returned. +       </para> +      </sect3> +        <sect3 id="bus-messages-out-of-memory">          <title><literal>org.freedesktop.DBus.Error.NoMemory</literal></title>          <para>  | 
