summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2015-02-09 17:44:53 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2015-02-24 11:15:25 +0000
commitb9de1f5ef01874834aab4519cc58a29b866ca94a (patch)
tree955969627513bf27964e8f13b3baa79b9ff9cedb
parent326d342345908e12e71133a9c9e3a96cfbfa4493 (diff)
downloaddbus-b9de1f5ef01874834aab4519cc58a29b866ca94a.tar.gz
On Unix platforms, try $XDG_RUNTIME_DIR/bus before default address
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>
-rw-r--r--dbus/dbus-sysdeps-unix.c87
-rw-r--r--dbus/dbus-sysdeps-unix.h4
2 files changed, 87 insertions, 4 deletions
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index 8010df13..17f2f322 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -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
}
diff --git a/dbus/dbus-sysdeps-unix.h b/dbus/dbus-sysdeps-unix.h
index b26673cb..86813b5a 100644
--- a/dbus/dbus-sysdeps-unix.h
+++ b/dbus/dbus-sysdeps-unix.h
@@ -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 */