]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
On Unix platforms, try $XDG_RUNTIME_DIR/bus before default address
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Mon, 9 Feb 2015 17:44:53 +0000 (17:44 +0000)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Tue, 24 Feb 2015 11:15:25 +0000 (11:15 +0000)
This is safe to do even on systems where there is a per-login-session
bus: the $XDG_RUNTIME_DIR/bus would just not exist there. This means
that OS builders can enable a per-user-session bus by merely providing
configuration to start it, without needing to rebuild the client library.

Based on a patch by Colin Walters, with these changes:

- factor out the actual XDG_RUNTIME_DIR bit into a function
- set error correctly on OOM
- do not try to use an XDG_RUNTIME_DIR/bus that belongs to a
  different uid or is not a socket
- escape the path if it contains inconvenient characters
- coding style adjustments

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=61301
Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
dbus/dbus-sysdeps-unix.c
dbus/dbus-sysdeps-unix.h

index 8010df1341c08088db3d60fba1c23a397d908231..17f2f32266fb72726dda8933d92fa17c858a9adc 100644 (file)
@@ -29,6 +29,7 @@
 #include "dbus-sysdeps-unix.h"
 #include "dbus-threads.h"
 #include "dbus-protocol.h"
+#include "dbus-file.h"
 #include "dbus-transport.h"
 #include "dbus-string.h"
 #include "dbus-userdb.h"
@@ -3947,6 +3948,77 @@ _dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
 }
 #endif
 
+dbus_bool_t
+_dbus_lookup_user_bus (dbus_bool_t *supported,
+                       DBusString  *address,
+                       DBusError   *error)
+{
+  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
+  dbus_bool_t ret = FALSE;
+  struct stat stbuf;
+  DBusString user_bus_path;
+
+  if (runtime_dir == NULL)
+    {
+      _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
+      *supported = FALSE;
+      return TRUE;        /* Cannot use it, but not an error */
+    }
+
+  if (!_dbus_string_init (&user_bus_path))
+    {
+      _DBUS_SET_OOM (error);
+      return FALSE;
+    }
+
+  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
+    {
+      _DBUS_SET_OOM (error);
+      goto out;
+    }
+
+  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
+    {
+      _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
+                     _dbus_strerror (errno));
+      *supported = FALSE;
+      ret = TRUE;       /* Cannot use it, but not an error */
+      goto out;
+    }
+
+  if (stbuf.st_uid != getuid ())
+    {
+      _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
+                     (long) stbuf.st_uid, (long) getuid ());
+      *supported = FALSE;
+      ret = TRUE;       /* Cannot use it, but not an error */
+      goto out;
+    }
+
+  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
+    {
+      _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
+                     (long) stbuf.st_mode);
+      *supported = FALSE;
+      ret = TRUE;       /* Cannot use it, but not an error */
+      goto out;
+    }
+
+  if (!_dbus_string_append (address, "unix:path=") ||
+      !_dbus_address_append_escaped (address, &user_bus_path))
+    {
+      _DBUS_SET_OOM (error);
+      goto out;
+    }
+
+  *supported = TRUE;
+  ret = TRUE;
+
+out:
+  _dbus_string_free (&user_bus_path);
+  return ret;
+}
+
 /**
  * Determines the address of the session bus by querying a
  * platform-specific method.
@@ -3975,11 +4047,18 @@ _dbus_lookup_session_address (dbus_bool_t *supported,
   *supported = TRUE;
   return _dbus_lookup_session_address_launchd (address, error);
 #else
-  /* On non-Mac Unix platforms, if the session address isn't already
-   * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
-   * fall back to the autolaunch: global default; see
-   * init_session_address in dbus/dbus-bus.c. */
   *supported = FALSE;
+
+  if (!_dbus_lookup_user_bus (supported, address, error))
+    return FALSE;
+  else if (*supported)
+    return TRUE;
+
+  /* On non-Mac Unix platforms, if the session address isn't already
+   * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
+   * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
+   * autolaunch: global default; see init_session_address in
+   * dbus/dbus-bus.c. */
   return TRUE;
 #endif
 }
index b26673cb29faa914caceedd86421bfadff33d79e..86813b5adb93b46c27b4d05a401135a3f4f008f8 100644 (file)
@@ -90,6 +90,10 @@ dbus_bool_t _dbus_lookup_launchd_socket (DBusString *socket_path,
                                          const char *launchd_env_var,
                                          DBusError  *error);
 
+dbus_bool_t _dbus_lookup_user_bus (dbus_bool_t *supported,
+                                   DBusString  *address,
+                                   DBusError   *error);
+
 /** Information about a UNIX user */
 typedef struct DBusUserInfo  DBusUserInfo;
 /** Information about a UNIX group */