return -E2BIG;
}
- if (ucred.uid != 0)
+ if (ucred.uid != 0 && ucred.uid != geteuid())
return -EPERM;
return 1;
return 0;
}
-int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private, DBusError *error) {
- DBusConnection *bus;
+int bus_connect(DBusBusType t, DBusConnection **_bus, bool *_private, DBusError *error) {
+ DBusConnection *bus = NULL;
int r;
+ bool private = true;
assert(_bus);
- /* If we are root, then let's not go via the bus */
if (geteuid() == 0 && t == DBUS_BUS_SYSTEM) {
+ /* If we are root, then let's talk directly to the
+ * system instance, instead of going via the bus */
+
+ bus = dbus_connection_open_private("unix:path=/run/systemd/private", error);
+ if (!bus)
+ return -EIO;
+
+ } else {
+ if (t == DBUS_BUS_SESSION) {
+ const char *e;
+
+ /* If we are supposed to talk to the instance,
+ * try via XDG_RUNTIME_DIR first, then
+ * fallback to normal bus access */
- if (!(bus = dbus_connection_open_private("unix:path=/run/systemd/private", error))) {
-#ifndef LEGACY
- dbus_error_free(error);
+ e = getenv("XDG_RUNTIME_DIR");
+ if (e) {
+ char *p;
- /* Retry with the pre v21 socket name, to ease upgrades */
- if (!(bus = dbus_connection_open_private("unix:abstract=/org/freedesktop/systemd1/private", error)))
-#endif
+ if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0)
+ return -ENOMEM;
+
+ bus = dbus_connection_open_private(p, NULL);
+ free(p);
+ }
+ }
+
+ if (!bus) {
+ bus = dbus_bus_get_private(t, error);
+ if (!bus)
return -EIO;
+
+ private = false;
}
+ }
- dbus_connection_set_exit_on_disconnect(bus, FALSE);
+ dbus_connection_set_exit_on_disconnect(bus, FALSE);
+ if (private) {
if (bus_check_peercred(bus) < 0) {
dbus_connection_close(bus);
dbus_connection_unref(bus);
dbus_set_error_const(error, DBUS_ERROR_ACCESS_DENIED, "Failed to verify owner of bus.");
return -EACCES;
}
-
- if (private)
- *private = true;
-
- } else {
- if (!(bus = dbus_bus_get_private(t, error)))
- return -EIO;
-
- dbus_connection_set_exit_on_disconnect(bus, FALSE);
-
- if (private)
- *private = false;
}
- if ((r = sync_auth(bus, error)) < 0) {
+ r = sync_auth(bus, error);
+ if (r < 0) {
dbus_connection_close(bus);
dbus_connection_unref(bus);
return r;
}
+ if (_private)
+ *_private = private;
+
*_bus = bus;
return 0;
}
}
int bus_property_append_strv(DBusMessageIter *i, const char *property, void *data) {
- DBusMessageIter sub;
char **t = data;
assert(i);
assert(property);
- if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub))
- return -ENOMEM;
-
- STRV_FOREACH(t, t)
- if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, t))
- return -ENOMEM;
-
- if (!dbus_message_iter_close_container(i, &sub))
- return -ENOMEM;
-
- return 0;
+ return bus_append_strv_iter(i, t);
}
int bus_property_append_bool(DBusMessageIter *i, const char *property, void *data) {
return 0;
}
+
+int bus_append_strv_iter(DBusMessageIter *iter, char **l) {
+ DBusMessageIter sub;
+
+ assert(iter);
+
+ if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "s", &sub))
+ return -ENOMEM;
+
+ STRV_FOREACH(l, l)
+ if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, l))
+ return -ENOMEM;
+
+ if (!dbus_message_iter_close_container(iter, &sub))
+ return -ENOMEM;
+
+ return 0;
+}