diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2015-01-08 14:48:59 +0000 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2015-02-24 11:14:46 +0000 |
commit | e3f117e7610b0e0a91dfe5bff7bf2e217c129a86 (patch) | |
tree | 1126d495a584e95dc00e2017521affa63239e436 /dbus | |
parent | f6a2b907ec528968f8ef3936be422b346d745d09 (diff) | |
download | dbus-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.c | 64 |
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; |