summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bus-driverd/bus-driverd.c6
-rw-r--r--src/libsystemd/libsystemd.sym2
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c92
-rw-r--r--src/shared/cgroup-util.c18
-rw-r--r--src/systemd/sd-bus.h2
5 files changed, 107 insertions, 13 deletions
diff --git a/src/bus-driverd/bus-driverd.c b/src/bus-driverd/bus-driverd.c
index 319596a40b..acb5e6ba00 100644
--- a/src/bus-driverd/bus-driverd.c
+++ b/src/bus-driverd/bus-driverd.c
@@ -847,11 +847,7 @@ static int connect_bus(Context *c) {
assert(c);
- r = cg_pid_get_owner_uid(0, NULL);
- if (r < 0)
- r = sd_bus_default_system(&c->bus);
- else
- r = sd_bus_default_user(&c->bus);
+ r = sd_bus_default(&c->bus);
if (r < 0) {
log_error("Failed to create bus: %s", strerror(-r));
return r;
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 9416f223e2..a5aa1d1ca8 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -80,8 +80,10 @@ global:
/* Same order as in sd-bus.h should be used */
/* Connections */
+ sd_bus_default;
sd_bus_default_user;
sd_bus_default_system;
+ sd_bus_open;
sd_bus_open_user;
sd_bus_open_system;
sd_bus_open_system_remote;
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 9f8c244bf5..420393054c 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -35,6 +35,7 @@
#include "set.h"
#include "missing.h"
#include "def.h"
+#include "cgroup-util.h"
#include "sd-bus.h"
#include "bus-internal.h"
@@ -1052,6 +1053,60 @@ _public_ int sd_bus_start(sd_bus *bus) {
return bus_send_hello(bus);
}
+_public_ int sd_bus_open(sd_bus **ret) {
+ const char *e;
+ sd_bus *b;
+ int r;
+
+ assert_return(ret, -EINVAL);
+
+ /* Let's connect to the starter bus if it is set, and
+ * otherwise to the bus that is appropropriate for the scope
+ * we are running in */
+
+ e = secure_getenv("DBUS_STARTER_BUS_TYPE");
+ if (e) {
+ if (streq(e, "system"))
+ return sd_bus_open_system(ret);
+ else if (streq(e, "session") || streq(e, "user"))
+ return sd_bus_open_user(ret);
+ }
+
+ e = secure_getenv("DBUS_STARTER_ADDRESS");
+ if (!e) {
+ if (cg_pid_get_owner_uid(0, NULL) >= 0)
+ return sd_bus_open_user(ret);
+ else
+ return sd_bus_open_system(ret);
+ }
+
+ r = sd_bus_new(&b);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_set_address(b, e);
+ if (r < 0)
+ goto fail;
+
+ b->bus_client = true;
+
+ /* We don't know whether the bus is trusted or not, so better
+ * be safe, and authenticate everything */
+ b->trusted = false;
+ b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
+
+ r = sd_bus_start(b);
+ if (r < 0)
+ goto fail;
+
+ *ret = b;
+ return 0;
+
+fail:
+ bus_free(b);
+ return r;
+}
+
_public_ int sd_bus_open_system(sd_bus **ret) {
const char *e;
sd_bus *b;
@@ -2913,6 +2968,43 @@ _public_ int sd_bus_default_user(sd_bus **ret) {
return bus_default(sd_bus_open_user, &default_user_bus, ret);
}
+_public_ int sd_bus_default(sd_bus **ret) {
+
+ const char *e;
+
+ /* Let's try our best to reuse another cached connection. If
+ * the starter bus type is set, connect via our normal
+ * connection logic, ignoring $DBUS_STARTER_ADDRESS, so that
+ * we can share the connection with the user/system default
+ * bus. */
+
+ e = secure_getenv("DBUS_STARTER_BUS_TYPE");
+ if (e) {
+ if (streq(e, "system"))
+ return sd_bus_default_system(ret);
+ else if (streq(e, "user") || streq(e, "session"))
+ return sd_bus_default_user(ret);
+ }
+
+ /* No type is specified, so we have not other option than to
+ * use the starter address if it is set. */
+
+ e = secure_getenv("DBUS_STARTER_ADDRESS");
+ if (e) {
+ static thread_local sd_bus *default_starter_bus = NULL;
+
+ return bus_default(sd_bus_open, &default_starter_bus, ret);
+ }
+
+ /* Finally, if nothing is set use the cached connection for
+ * the right scope */
+
+ if (cg_pid_get_owner_uid(0, NULL) >= 0)
+ return sd_bus_default_user(ret);
+ else
+ return sd_bus_default_system(ret);
+}
+
_public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
assert_return(b, -EINVAL);
assert_return(tid, -EINVAL);
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 855c9cd160..4ce885601f 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -1332,11 +1332,10 @@ int cg_pid_get_machine_name(pid_t pid, char **machine) {
int cg_path_get_session(const char *path, char **session) {
const char *e, *n, *x;
- char *s, *r;
+ char *s;
size_t l;
assert(path);
- assert(session);
/* Skip slices, if there are any */
e = skip_slices(path);
@@ -1358,11 +1357,16 @@ int cg_path_get_session(const char *path, char **session) {
if (l <= 6)
return -ENOENT;
- r = strndup(x, l - 6);
- if (!r)
- return -ENOMEM;
+ if (session) {
+ char *r;
+
+ r = strndup(x, l - 6);
+ if (!r)
+ return -ENOMEM;
+
+ *session = r;
+ }
- *session = r;
return 0;
}
@@ -1370,8 +1374,6 @@ int cg_pid_get_session(pid_t pid, char **session) {
_cleanup_free_ char *cgroup = NULL;
int r;
- assert(session);
-
r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
if (r < 0)
return r;
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 52481c6fcf..94cb21c246 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -97,7 +97,9 @@ typedef int (*sd_bus_node_enumerator_t) (sd_bus *bus, const char *path, void *us
int sd_bus_default_user(sd_bus **ret);
int sd_bus_default_system(sd_bus **ret);
+int sd_bus_default(sd_bus **ret);
+int sd_bus_open(sd_bus **ret);
int sd_bus_open_user(sd_bus **ret);
int sd_bus_open_system(sd_bus **ret);
int sd_bus_open_system_remote(const char *host, sd_bus **ret);