User authentication to services

Kay Sievers kay.sievers at vrfy.org
Thu Jun 17 02:13:56 PDT 2004


On Thu, Jun 17, 2004 at 12:46:21AM -0400, Havoc Pennington wrote:
> On Wed, 2004-06-16 at 20:49, Kay Sievers wrote:
> > Is there any better way to find the connection by its name?
> 
> Yep, I even suggested it in the thread you're replying to ;-)
> 
> http://freedesktop.org/pipermail/dbus/2004-May/001166.html
> 
> Look at bus_driver_handle_get_service_owner()

Yeah, there is a light at the end of the tunnel :)

Here is the next try, which implements a 'GetServiceProperty' method.
The method expects the service string and a the name of the property to
return. Depending on the property asked for it returns for:
  'Uid':      the uid of the user owning the service
  'BaseName': the "base service name"

The functionality of the 'GetServiceOwner' method, on which the
'GetServiceProperty' method is based, is included.

dbus/dbus-bus.c:dbus_bus_get_service_uid() can be used to get the uid of a
message's sender by:
  sender = dbus_message_get_sender (message);
  uid = dbus_bus_get_service_uid (connection, sender, NULL);

Thanks,
Kay
-------------- next part --------------
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	17 Jun 2004 08:59:36 -0000
@@ -830,6 +830,114 @@
 }
 
 static dbus_bool_t
+bus_driver_handle_get_service_property (DBusConnection *connection,
+				        BusTransaction *transaction,
+				        DBusMessage    *message,
+				        DBusError      *error)
+{
+  char *service = NULL;
+  char *property = NULL;
+  DBusString str;
+  BusRegistry *registry;
+  BusService *serv;
+  DBusConnection *conn;
+  DBusMessage *reply = NULL;
+  unsigned long uid;
+  const char *base_name;
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+  registry = bus_connection_get_registry (connection);
+
+  if (! dbus_message_get_args (message, error,
+			       DBUS_TYPE_STRING, &service,
+			       DBUS_TYPE_STRING, &property,
+			       DBUS_TYPE_INVALID))
+      goto failed;
+
+  _dbus_verbose ("asked for %s on %s\n", property, 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 (strcmp ("Uid", property) == 0)
+    {
+
+      if (!dbus_connection_get_unix_user (conn, &uid))
+        {
+          dbus_set_error (error,
+                          DBUS_ERROR_FAILED,
+                          "Could not determine uid for '%s'", service);
+          goto failed;
+        }
+    
+      _dbus_verbose (" found uid=%i\n", (dbus_uint32_t) uid);
+      if (! dbus_message_append_args (reply,
+                                      DBUS_TYPE_UINT32, (dbus_uint32_t) uid,
+                                      DBUS_TYPE_INVALID))
+        goto oom;
+    }
+  else if (strcmp ("BaseName", property) == 0)
+    {
+      base_name = bus_connection_get_name (conn);
+      if (base_name == NULL)
+        {
+          dbus_set_error (error,
+                          DBUS_ERROR_FAILED,
+                          "Could not determine base name for '%s'", service);
+          goto failed;
+        }
+      _dbus_assert (*base_name == ':');
+      
+      _dbus_verbose (" found base_name=%s\n", base_name);
+      if (! dbus_message_append_args (reply,
+                                      DBUS_TYPE_STRING, base_name,
+                                      DBUS_TYPE_INVALID))
+        goto oom;
+    }
+  else
+    {
+        dbus_set_error (error,
+                        DBUS_ERROR_FAILED,
+                        "Unknown property '%s'", property);
+        goto failed;
+    }  
+
+  if (! bus_transaction_send_from_driver (transaction, connection, reply))
+    goto oom;
+
+  dbus_message_unref (reply);
+  dbus_free (service);
+  dbus_free (property);
+
+  return TRUE;
+
+ oom:
+  BUS_SET_OOM (error);
+
+ failed:
+  _DBUS_ASSERT_ERROR_IS_SET (error);
+  if (reply)
+    dbus_message_unref (reply);
+  dbus_free (service);
+  dbus_free (property);
+  return FALSE;
+}
+
+static dbus_bool_t
 bus_driver_handle_reload_config (DBusConnection *connection,
 				 BusTransaction *transaction,
 				 DBusMessage    *message,
@@ -875,6 +983,7 @@
   { "AddMatch", bus_driver_handle_add_match },
   { "RemoveMatch", bus_driver_handle_remove_match },
   { "GetServiceOwner", bus_driver_handle_get_service_owner },
+  { "GetServiceProperty", bus_driver_handle_get_service_property },
   { "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	17 Jun 2004 08:59:37 -0000
@@ -627,6 +627,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
+ */ 
+dbus_uint32_t
+dbus_bus_get_service_uid (DBusConnection *connection,
+                          const char     *service,
+			  DBusError      *error)
+{
+  DBusMessage *message, *reply;
+  dbus_uint32_t uid;  
+
+  _dbus_return_val_if_fail (connection != NULL, -1);
+  _dbus_return_val_if_fail (service != NULL, -1);
+  _dbus_return_val_if_error_is_set (error, -1);
+  
+  message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
+                                          DBUS_PATH_ORG_FREEDESKTOP_DBUS,
+                                          DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+                                          "GetServiceProperty");
+
+  if (message == NULL)
+    {
+      _DBUS_SET_OOM (error);
+      return -1;
+    }
+ 
+  if (!dbus_message_append_args (message,
+				 DBUS_TYPE_STRING, service,
+				 DBUS_TYPE_STRING, "Uid",
+				 DBUS_TYPE_INVALID))
+    {
+      dbus_message_unref (message);
+      _DBUS_SET_OOM (error);
+      return -1;
+    }
+  
+  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 -1;
+    }  
+
+  if (dbus_set_error_from_message (error, reply))
+    {
+      _DBUS_ASSERT_ERROR_IS_SET (error);
+      dbus_message_unref (reply);
+      return -1;
+    }
+  
+  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 -1;
+    }
+
+  dbus_message_unref (reply);
+  
+  return uid;
+}
+
+/**
  * Checks whether a certain service exists.
  *
  * @param connection the connection
Index: dbus/dbus-bus.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-bus.h,v
retrieving revision 1.9
diff -u -r1.9 dbus-bus.h
--- dbus/dbus-bus.h	2 Dec 2003 10:44:21 -0000	1.9
+++ dbus/dbus-bus.h	17 Jun 2004 08:59:37 -0000
@@ -45,6 +45,9 @@
 dbus_bool_t     dbus_bus_set_base_service (DBusConnection *connection,
 					   const char     *base_service);
 const char*     dbus_bus_get_base_service (DBusConnection *connection);
+dbus_uint32_t   dbus_bus_get_service_uid  (DBusConnection *connection,
+			                   const char     *service,
+                                           DBusError      *error);
 int             dbus_bus_acquire_service  (DBusConnection *connection,
 					   const char     *service_name,
 					   unsigned int    flags,


More information about the dbus mailing list