From b9de1f5ef01874834aab4519cc58a29b866ca94a Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 9 Feb 2015 17:44:53 +0000 Subject: [PATCH] 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 --- dbus/dbus-sysdeps-unix.c | 87 +++++++++++++++++++++++++++++++++++++++++++++--- dbus/dbus-sysdeps-unix.h | 4 +++ 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 8010df1..17f2f32 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 b26673c..86813b5 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 */ -- 2.7.4