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> |