From cdda938ebbbf915a165bb87dcbf30d5f641b8e45 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 9 Feb 2015 17:44:53 +0000 Subject: [PATCH 4/7] 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 --- dbus/dbus-sysdeps-unix.c | 79 +++++++++++++++++++++++++++++++++++++++++++++--- dbus/dbus-sysdeps-unix.h | 4 +++ 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index dcfddd1..76e38e8 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" @@ -3842,6 +3843,69 @@ _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) + { + /* No XDG_RUNTIME_DIR. Not an error. */ + *supported = FALSE; + return TRUE; + } + + 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) + { + /* We have the XDG_RUNTIME_DIR, but no bus scoped to it. + * Not an error. */ + *supported = FALSE; + ret = TRUE; + goto out; + } + + if (stbuf.st_uid != getuid () || (stbuf.st_mode & S_IFMT) != S_IFSOCK) + { + /* We found the XDG_RUNTIME_DIR/bus but it isn't suitable: either + * it isn't ours (maybe we're under su), or it isn't a socket. + * Not an error. */ + *supported = FALSE; + ret = TRUE; + 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. @@ -3870,11 +3934,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 df9902d..7bf8fbf 100644 --- a/dbus/dbus-sysdeps-unix.h +++ b/dbus/dbus-sysdeps-unix.h @@ -87,6 +87,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 */ -- 2.1.4