User authentication to services
Kay Sievers
kay.sievers at vrfy.org
Fri Jun 25 09:53:43 PDT 2004
On Fri, Jun 25, 2004 at 03:34:28PM +0200, Olivier Andrieu wrote:
> Kay Sievers [Thu, 24 Jun 2004]:
> > On Fri, Jun 18, 2004 at 04:25:14PM +0200, Olivier Andrieu wrote:
> > > Kay Sievers [Fri, 18 Jun 2004]:
> > > > > - the BaseName property replicates the functionality of
> > > > > the GetServiceOwner, so we need to decide between these two.
> > > >
> > > > I've replaced it by GetProperty and changed:
> > > > dbus/glib/dbus-gproxy.c:dbus_gproxy_new_for_service_owner() to call
> > > > it instead. (Hmm, needs to be tested if it still works)
> > > >
> > > > Is it ok, this way? If yes, I will change the spec too.
> > >
> > > What's wrong with having two different methods ? With a single
> > > GetProperty method the reply message carries either an INT32 or a
> > > STRING. That(s not very nice.
> > >
> > > > > - the name "GetServiceProperty" isn't a bit funny; it's a
> > > > > property of the connection, not the service.
> > > > > Suggest just "GetProperty"
> > >
> > > But the base name is a property of the service.
> >
> > Ok, here is a version that doesn't touch the existing code. It also
> > avoids the multiplexing method with the dynamic return type.
> > It just adds a "GetConnectionUnixUser" method similar to "GetServiceOwner".
> > The method is explained in the spec and a unit test in dispatch.c is
> > also added.
>
> Thanks. Personally, I prefer it that way.
>
> Nitpick: in bus_driver_handle_get_connection_unix_user in driver.c,
> you could initialize the char * service to NULL. It's OK here because
> the subsequent dbus_message_get_args has only one out argument, but if
> it had several you'd have to initialize them before.
Good point.
Here is a fixed version.
Thanks,
Kay
-------------- next part --------------
? dbus/dbus-glib-error-enum.h
Index: bus/dispatch.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/dispatch.c,v
retrieving revision 1.57
diff -u -r1.57 dispatch.c
--- bus/dispatch.c 16 Mar 2004 18:00:34 -0000 1.57
+++ bus/dispatch.c 25 Jun 2004 16:45:02 -0000
@@ -924,6 +924,142 @@
* 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_UINT 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)
{
Index: bus/driver.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/driver.c,v
retrieving revision 1.49
diff -u -r1.49 driver.c
--- bus/driver.c 9 Jun 2004 18:15:09 -0000 1.49
+++ bus/driver.c 25 Jun 2004 16:45:03 -0000
@@ -830,6 +830,83 @@
}
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 @@
{ "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 }
};
Index: dbus/dbus-bus.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-bus.c,v
retrieving revision 1.29
diff -u -r1.29 dbus-bus.c
--- dbus/dbus-bus.c 9 Jun 2004 18:15:09 -0000 1.29
+++ dbus/dbus-bus.c 25 Jun 2004 16:45:04 -0000
@@ -546,6 +546,79 @@
}
/**
+ * 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
Index: dbus/dbus-bus.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-bus.h,v
retrieving revision 1.10
diff -u -r1.10 dbus-bus.h
--- dbus/dbus-bus.h 20 Jun 2004 15:28:15 -0000 1.10
+++ dbus/dbus-bus.h 25 Jun 2004 16:45:04 -0000
@@ -38,6 +38,9 @@
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,
Index: doc/dbus-specification.xml
===================================================================
RCS file: /cvs/dbus/dbus/doc/dbus-specification.xml,v
retrieving revision 1.10
diff -u -r1.10 dbus-specification.xml
--- doc/dbus-specification.xml 2 Jun 2004 14:03:58 -0000 1.10
+++ doc/dbus-specification.xml 25 Jun 2004 16:45:06 -0000
@@ -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>
More information about the dbus
mailing list