2004-07-24 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / dbus / dbus-connection.c
index 524cef6..91a2100 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <config.h>
+#include "dbus-shared.h"
 #include "dbus-connection.h"
 #include "dbus-list.h"
 #include "dbus-timeout.h"
@@ -37,6 +38,7 @@
 #include "dbus-string.h"
 #include "dbus-pending-call.h"
 #include "dbus-object-tree.h"
+#include "dbus-marshal.h"
 
 #if 0
 #define CONNECTION_LOCK(connection)   do {                      \
@@ -2951,6 +2953,37 @@ dbus_connection_set_dispatch_status_function (DBusConnection             *connec
 }
 
 /**
+ * Get the UNIX file descriptor of the connection, if any.  This can
+ * be used for SELinux access control checks with getpeercon() for
+ * example. DO NOT read or write to the file descriptor, or try to
+ * select() on it; use DBusWatch for main loop integration. Not all
+ * connections will have a file descriptor. So for adding descriptors
+ * to the main loop, use dbus_watch_get_fd() and so forth.
+ *
+ * @param connection the connection
+ * @param fd return location for the file descriptor.
+ * @returns #TRUE if fd is successfully obtained.
+ */
+dbus_bool_t
+dbus_connection_get_unix_fd (DBusConnection *connection,
+                             int            *fd)
+{
+  dbus_bool_t retval;
+
+  _dbus_return_val_if_fail (connection != NULL, FALSE);
+  _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
+  
+  CONNECTION_LOCK (connection);
+  
+  retval = _dbus_transport_get_unix_fd (connection->transport,
+                                        fd);
+
+  CONNECTION_UNLOCK (connection);
+
+  return retval;
+}
+
+/**
  * Gets the UNIX user ID of the connection if any.
  * Returns #TRUE if the uid is filled in.
  * Always returns #FALSE on non-UNIX platforms.
@@ -2983,6 +3016,37 @@ dbus_connection_get_unix_user (DBusConnection *connection,
 }
 
 /**
+ * Gets the process ID of the connection if any.
+ * Returns #TRUE if the uid is filled in.
+ * Always returns #FALSE prior to authenticating the
+ * connection.
+ *
+ * @param connection the connection
+ * @param pid return location for the process ID
+ * @returns #TRUE if uid is filled in with a valid process ID
+ */
+dbus_bool_t
+dbus_connection_get_unix_process_id (DBusConnection *connection,
+                                    unsigned long  *pid)
+{
+  dbus_bool_t result;
+
+  _dbus_return_val_if_fail (connection != NULL, FALSE);
+  _dbus_return_val_if_fail (pid != NULL, FALSE);
+  
+  CONNECTION_LOCK (connection);
+
+  if (!_dbus_transport_get_is_authenticated (connection->transport))
+    result = FALSE;
+  else
+    result = _dbus_transport_get_unix_process_id (connection->transport,
+                                                 pid);
+  CONNECTION_UNLOCK (connection);
+
+  return result;
+}
+
+/**
  * Sets a predicate function used to determine whether a given user ID
  * is allowed to connect. When an incoming connection has
  * authenticated with a particular user ID, this function is called;
@@ -3151,33 +3215,39 @@ dbus_connection_remove_filter (DBusConnection            *connection,
  *
  *
  * @param connection the connection
- * @param path #NULL-terminated array of path elements
+ * @param path a '/' delimited string of path elements
  * @param vtable the virtual table
  * @param user_data data to pass to functions in the vtable
  * @returns #FALSE if not enough memory
  */
 dbus_bool_t
 dbus_connection_register_object_path (DBusConnection              *connection,
-                                      const char                 **path,
+                                      const char                  *path,
                                       const DBusObjectPathVTable  *vtable,
                                       void                        *user_data)
 {
+  char **decomposed_path;
   dbus_bool_t retval;
   
   _dbus_return_val_if_fail (connection != NULL, FALSE);
   _dbus_return_val_if_fail (path != NULL, FALSE);
-  _dbus_return_val_if_fail (path[0] != NULL, FALSE);
+  _dbus_return_val_if_fail (path[0] == '/', FALSE);
   _dbus_return_val_if_fail (vtable != NULL, FALSE);
 
+  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
+    return FALSE;
+
   CONNECTION_LOCK (connection);
 
   retval = _dbus_object_tree_register (connection->objects,
                                        FALSE,
-                                       path, vtable,
+                                       (const char **) decomposed_path, vtable,
                                        user_data);
 
   CONNECTION_UNLOCK (connection);
 
+  dbus_free_string_array (decomposed_path);
+
   return retval;
 }
 
@@ -3188,33 +3258,39 @@ dbus_connection_register_object_path (DBusConnection              *connection,
  * policy for a whole "subdirectory."
  *
  * @param connection the connection
- * @param path #NULL-terminated array of path elements
+ * @param path a '/' delimited string of path elements
  * @param vtable the virtual table
  * @param user_data data to pass to functions in the vtable
  * @returns #FALSE if not enough memory
  */
 dbus_bool_t
 dbus_connection_register_fallback (DBusConnection              *connection,
-                                   const char                 **path,
+                                   const char                  *path,
                                    const DBusObjectPathVTable  *vtable,
                                    void                        *user_data)
 {
+  char **decomposed_path;
   dbus_bool_t retval;
   
   _dbus_return_val_if_fail (connection != NULL, FALSE);
   _dbus_return_val_if_fail (path != NULL, FALSE);
-  _dbus_return_val_if_fail (path[0] != NULL, FALSE);
+  _dbus_return_val_if_fail (path[0] == '/', FALSE);
   _dbus_return_val_if_fail (vtable != NULL, FALSE);
 
+  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
+    return FALSE;
+
   CONNECTION_LOCK (connection);
 
   retval = _dbus_object_tree_register (connection->objects,
                                        TRUE,
-                                       path, vtable,
+                                      (const char **) decomposed_path, vtable,
                                        user_data);
 
   CONNECTION_UNLOCK (connection);
 
+  dbus_free_string_array (decomposed_path);
+
   return retval;
 }
 
@@ -3224,19 +3300,29 @@ dbus_connection_register_fallback (DBusConnection              *connection,
  * Can unregister both fallback paths and object paths.
  *
  * @param connection the connection
- * @param path the #NULL-terminated array of path elements
+ * @param path a '/' delimited string of path elements
+ * @returns #FALSE if not enough memory
  */
-void
+dbus_bool_t
 dbus_connection_unregister_object_path (DBusConnection              *connection,
-                                        const char                 **path)
+                                        const char                  *path)
 {
-  _dbus_return_if_fail (connection != NULL);
-  _dbus_return_if_fail (path != NULL);
-  _dbus_return_if_fail (path[0] != NULL);
+  char **decomposed_path;
+
+  _dbus_return_val_if_fail (connection != NULL, FALSE);
+  _dbus_return_val_if_fail (path != NULL, FALSE);
+  _dbus_return_val_if_fail (path[0] == '/', FALSE);
+
+  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
+      return FALSE;
 
   CONNECTION_LOCK (connection);
 
-  _dbus_object_tree_unregister_and_unlock (connection->objects, path);
+  _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
+
+  dbus_free_string_array (decomposed_path);
+
+  return TRUE;
 }
 
 /**
@@ -3251,18 +3337,27 @@ dbus_connection_unregister_object_path (DBusConnection              *connection,
  */
 dbus_bool_t
 dbus_connection_list_registered (DBusConnection              *connection,
-                                 const char                 **parent_path,
+                                 const char                  *parent_path,
                                  char                      ***child_entries)
 {
+  char **decomposed_path;
+  dbus_bool_t retval;
   _dbus_return_val_if_fail (connection != NULL, FALSE);
   _dbus_return_val_if_fail (parent_path != NULL, FALSE);
+  _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
   _dbus_return_val_if_fail (child_entries != NULL, FALSE);
 
+  if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
+    return FALSE;
+
   CONNECTION_LOCK (connection);
 
-  return _dbus_object_tree_list_registered_and_unlock (connection->objects,
-                                                       parent_path,
-                                                       child_entries);
+  retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
+                                                        (const char **) decomposed_path,
+                                                        child_entries);
+  dbus_free_string_array (decomposed_path);
+
+  return retval;
 }
 
 static DBusDataSlotAllocator slot_allocator;