diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2015-02-09 17:44:53 +0000 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2015-02-24 11:15:25 +0000 |
commit | b9de1f5ef01874834aab4519cc58a29b866ca94a (patch) | |
tree | 955969627513bf27964e8f13b3baa79b9ff9cedb | |
parent | 326d342345908e12e71133a9c9e3a96cfbfa4493 (diff) | |
download | dbus-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.c | 87 | ||||
-rw-r--r-- | 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 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 */ |