summaryrefslogtreecommitdiff
path: root/dbus
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2015-01-08 14:48:59 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2015-02-24 11:14:46 +0000
commite3f117e7610b0e0a91dfe5bff7bf2e217c129a86 (patch)
tree1126d495a584e95dc00e2017521affa63239e436 /dbus
parentf6a2b907ec528968f8ef3936be422b346d745d09 (diff)
downloaddbus-e3f117e7610b0e0a91dfe5bff7bf2e217c129a86.tar.gz
Add support for unix:runtime=yes as an address mode
This is not used by default, but can be configured by OS builders (or regression-test environments) if desired. If used, this listens on $XDG_RUNTIME_DIR/bus, or fails if $XDG_RUNTIME_DIR is not set. Fallback behaviour is unnecessary, because it is already possible to use a string of semicolon-separated addresses like <listen>unix:runtime=yes;unix:tmpdir=/tmp</listen>, resulting in listening on either $XDG_RUNTIME_DIR/bus or /tmp/something. We use a non-abstract socket here, because that is desirable for use with Linux containers: abstract sockets are attached to the network namespace, whereas non-abstract sockets are part of the filesystem and can be bind-mounted between domains if necessary. The major advantage of abstract sockets is that they do not need cleanup, but the specification of XDG_RUNTIME_DIR guarantees to provide cleanup anyway. Based on prior work by Simon McVittie, Colin Walters and Alexander Larsson. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=61303 Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbus-server-unix.c64
1 files changed, 57 insertions, 7 deletions
diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c
index d9952404..fcfe27f7 100644
--- a/dbus/dbus-server-unix.c
+++ b/dbus/dbus-server-unix.c
@@ -66,25 +66,75 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
const char *path = dbus_address_entry_get_value (entry, "path");
const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir");
const char *abstract = dbus_address_entry_get_value (entry, "abstract");
+ const char *runtime = dbus_address_entry_get_value (entry, "runtime");
+ int mutually_exclusive_modes = 0;
- if (path == NULL && tmpdir == NULL && abstract == NULL)
+ mutually_exclusive_modes = (path != NULL) + (tmpdir != NULL) +
+ (abstract != NULL) + (runtime != NULL);
+
+ if (mutually_exclusive_modes < 1)
{
_dbus_set_bad_address(error, "unix",
- "path or tmpdir or abstract",
+ "path or tmpdir or abstract or runtime",
NULL);
return DBUS_SERVER_LISTEN_BAD_ADDRESS;
}
- if ((path && tmpdir) ||
- (path && abstract) ||
- (tmpdir && abstract))
+ if (mutually_exclusive_modes > 1)
{
_dbus_set_bad_address(error, NULL, NULL,
- "cannot specify two of \"path\" and \"tmpdir\" and \"abstract\" at the same time");
+ "cannot specify two of \"path\", \"tmpdir\", \"abstract\" and \"runtime\" at the same time");
return DBUS_SERVER_LISTEN_BAD_ADDRESS;
}
- if (tmpdir != NULL)
+ if (runtime != NULL)
+ {
+ DBusString full_path;
+ DBusString filename;
+ const char *runtimedir;
+
+ if (strcmp (runtime, "yes") != 0)
+ {
+ _dbus_set_bad_address(error, NULL, NULL,
+ "if given, the only value allowed for \"runtime\" is \"yes\"");
+ return DBUS_SERVER_LISTEN_BAD_ADDRESS;
+ }
+
+ runtimedir = _dbus_getenv ("XDG_RUNTIME_DIR");
+
+ if (runtimedir == NULL)
+ {
+ dbus_set_error (error,
+ DBUS_ERROR_NOT_SUPPORTED, "\"XDG_RUNTIME_DIR\" is not set");
+ return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
+ }
+
+ _dbus_string_init_const (&filename, "bus");
+
+ if (!_dbus_string_init (&full_path))
+ {
+ _DBUS_SET_OOM (error);
+ return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
+ }
+
+ if (!_dbus_string_append (&full_path, runtimedir) ||
+ !_dbus_concat_dir_and_file (&full_path, &filename))
+ {
+ _dbus_string_free (&full_path);
+ _DBUS_SET_OOM (error);
+ return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
+ }
+
+ /* We can safely use filesystem sockets in the runtime directory,
+ * and they are preferred because they can be bind-mounted between
+ * Linux containers. */
+ *server_p = _dbus_server_new_for_domain_socket (
+ _dbus_string_get_const_data (&full_path),
+ FALSE, error);
+
+ _dbus_string_free (&full_path);
+ }
+ else if (tmpdir != NULL)
{
DBusString full_path;
DBusString filename;