summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--src/core/dbus-manager.c36
-rw-r--r--src/hostname/hostnamed.c10
-rw-r--r--src/libsystemd-bus/bus-internal.h1
-rw-r--r--src/libsystemd-bus/bus-introspect.c5
-rw-r--r--src/libsystemd-bus/bus-objects.c85
-rw-r--r--src/libsystemd-bus/libsystemd-bus.sym1
-rw-r--r--src/libsystemd-bus/sd-bus.c18
-rw-r--r--src/locale/localed.c6
-rw-r--r--src/login/logind-dbus.c61
-rw-r--r--src/login/logind-seat-dbus.c5
-rw-r--r--src/login/logind-session-dbus.c19
-rw-r--r--src/login/logind-user-dbus.c6
-rw-r--r--src/login/org.freedesktop.login1.conf8
-rw-r--r--src/machine/machined-dbus.c11
-rw-r--r--src/machine/org.freedesktop.machine1.conf4
-rw-r--r--src/systemd/sd-bus-vtable.h28
-rw-r--r--src/systemd/sd-bus.h1
-rw-r--r--src/timedate/timedatectl.c4
-rw-r--r--src/timedate/timedated.c10
20 files changed, 217 insertions, 104 deletions
diff --git a/TODO b/TODO
index 253d0bf1b2..dac44e0c6a 100644
--- a/TODO
+++ b/TODO
@@ -112,8 +112,6 @@ Features:
ReadOnlyDirectories=... for whitelisting files for a service.
* libsystemd-bus:
- - default policy (allow uid == 0 and our own uid)
- - access policy as vtable flag
- when kdbus doesn't take our message without memfds, try again with memfds
- implement translator service
- implement monitor logic
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index a2707ee9b7..9c2194b0e5 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -1566,9 +1566,9 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
- SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, 0),
- SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, 0),
- SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, 0),
+ SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, 0),
SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, 0),
SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, 0),
@@ -1577,34 +1577,34 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, 0),
SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, 0),
SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, 0),
- SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, 0),
+ SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, 0),
SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, 0),
SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, 0),
- SD_BUS_METHOD("GetJob", "u", "o", method_get_job, 0),
+ SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, 0),
SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
- SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, 0),
- SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, 0),
- SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, 0),
- SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, 0),
- SD_BUS_METHOD("Dump", NULL, "s", method_dump, 0),
+ SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
SD_BUS_METHOD("Reload", NULL, NULL, method_reload, 0),
SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, 0),
SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
- SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, 0),
- SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, 0),
- SD_BUS_METHOD("Halt", NULL, NULL, method_halt, 0),
- SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, 0),
- SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, 0),
+ SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
+ SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
+ SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
+ SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
+ SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, 0),
SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, 0),
SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
- SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, 0),
- SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, 0),
+ SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, 0),
SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, 0),
SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
@@ -1613,7 +1613,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
- SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, 0),
+ SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL("UnitNew", "so", 0),
SD_BUS_SIGNAL("UnitRemoved", "so", 0),
diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
index 9082966057..f7ae50dcd8 100644
--- a/src/hostname/hostnamed.c
+++ b/src/hostname/hostnamed.c
@@ -546,11 +546,11 @@ static const sd_bus_vtable hostname_vtable[] = {
SD_BUS_PROPERTY("PrettyHostname", "s", NULL, offsetof(Context, data) + sizeof(char*) * PROP_PRETTY_HOSTNAME, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IconName", "s", property_get_icon_name, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Chassis", "s", property_get_chassis, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_METHOD("SetHostname", "sb", NULL, method_set_hostname, 0),
- SD_BUS_METHOD("SetStaticHostname", "sb", NULL, method_set_static_hostname, 0),
- SD_BUS_METHOD("SetPrettyHostname", "sb", NULL, method_set_pretty_hostname, 0),
- SD_BUS_METHOD("SetIconName", "sb", NULL, method_set_icon_name, 0),
- SD_BUS_METHOD("SetChassis", "sb", NULL, method_set_chassis, 0),
+ SD_BUS_METHOD("SetHostname", "sb", NULL, method_set_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetStaticHostname", "sb", NULL, method_set_static_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetPrettyHostname", "sb", NULL, method_set_pretty_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetIconName", "sb", NULL, method_set_icon_name, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetChassis", "sb", NULL, method_set_chassis, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END,
};
diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h
index 4881e0427c..1be7488ab9 100644
--- a/src/libsystemd-bus/bus-internal.h
+++ b/src/libsystemd-bus/bus-internal.h
@@ -159,6 +159,7 @@ struct sd_bus {
bool match_callbacks_modified:1;
bool filter_callbacks_modified:1;
bool nodes_modified:1;
+ bool trusted:1;
int use_memfd;
diff --git a/src/libsystemd-bus/bus-introspect.c b/src/libsystemd-bus/bus-introspect.c
index 115b3ceae8..8bec017d63 100644
--- a/src/libsystemd-bus/bus-introspect.c
+++ b/src/libsystemd-bus/bus-introspect.c
@@ -77,7 +77,7 @@ static void introspect_write_flags(struct introspect *i, int type, int flags) {
if (flags & SD_BUS_VTABLE_DEPRECATED)
fputs(" <annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n", i->f);
- if (type == _SD_BUS_VTABLE_METHOD && flags & SD_BUS_VTABLE_METHOD_NO_REPLY)
+ if (type == _SD_BUS_VTABLE_METHOD && (flags & SD_BUS_VTABLE_METHOD_NO_REPLY))
fputs(" <annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>\n", i->f);
if (type == _SD_BUS_VTABLE_PROPERTY || type == _SD_BUS_VTABLE_WRITABLE_PROPERTY) {
@@ -86,6 +86,9 @@ static void introspect_write_flags(struct introspect *i, int type, int flags) {
else if (flags & SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY)
fputs(" <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"invalidates\"/>\n", i->f);
}
+
+ if ((type == _SD_BUS_VTABLE_METHOD || type == _SD_BUS_VTABLE_WRITABLE_PROPERTY) && (flags & SD_BUS_VTABLE_UNPRIVILEGED))
+ fputs(" <annotation name=\"org.freedesktop.systemd1.Unprivileged\" value=\"true\"/>\n", i->f);
}
static int introspect_write_arguments(struct introspect *i, const char *signature, const char *direction) {
diff --git a/src/libsystemd-bus/bus-objects.c b/src/libsystemd-bus/bus-objects.c
index 7cd34c991b..941c2810d8 100644
--- a/src/libsystemd-bus/bus-objects.c
+++ b/src/libsystemd-bus/bus-objects.c
@@ -19,6 +19,8 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sys/capability.h>
+
#include "strv.h"
#include "set.h"
#include "bus-internal.h"
@@ -264,6 +266,64 @@ static int node_callbacks_run(
return 0;
}
+#define CAPABILITY_SHIFT(x) (((x) >> __builtin_ctzll(_SD_BUS_VTABLE_CAPABILITY_MASK)) & 0xFFFF)
+
+static int check_access(sd_bus *bus, sd_bus_message *m, struct vtable_member *c, sd_bus_error *error) {
+ _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+ uint64_t cap;
+ uid_t uid;
+ int r;
+
+ assert(bus);
+ assert(m);
+ assert(c);
+
+ /* If the entire bus is trusted let's grant access */
+ if (bus->trusted)
+ return 0;
+
+ /* If the member is marked UNPRIVILEGED let's grant access */
+ if (c->vtable->flags & SD_BUS_VTABLE_UNPRIVILEGED)
+ return 0;
+
+ /* If we are not connected to kdbus we cannot retrieve the
+ * effective capability set without race. Since we need this
+ * for a security decision we cannot use racy data, hence
+ * don't request it. */
+ if (bus->is_kernel)
+ r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
+ else
+ r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
+ if (r < 0)
+ return r;
+
+ /* Check have the caller has the requested capability
+ * set. Note that the flags value contains the capability
+ * number plus one, which we need to subtract here. We do this
+ * so that we have 0 as special value for "default
+ * capability". */
+ cap = CAPABILITY_SHIFT(c->vtable->flags);
+ if (cap == 0)
+ cap = CAPABILITY_SHIFT(c->parent->vtable[0].flags);
+ if (cap == 0)
+ cap = CAP_SYS_ADMIN;
+ else
+ cap --;
+
+ r = sd_bus_creds_has_effective_cap(creds, cap);
+ if (r > 0)
+ return 1;
+
+ /* Caller has same UID as us, then let's grant access */
+ r = sd_bus_creds_get_uid(creds, &uid);
+ if (r >= 0) {
+ if (uid == getuid())
+ return 1;
+ }
+
+ return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Access to %s.%s() not permitted.", c->interface, c->member);
+}
+
static int method_callbacks_run(
sd_bus *bus,
sd_bus_message *m,
@@ -284,6 +344,10 @@ static int method_callbacks_run(
if (require_fallback && !c->parent->is_fallback)
return 0;
+ r = check_access(bus, m, c, &error);
+ if (r < 0)
+ return bus_maybe_reply_error(m, r, &error);
+
r = node_vtable_get_userdata(bus, m->path, c->parent, &u, &error);
if (r <= 0)
return bus_maybe_reply_error(m, r, &error);
@@ -498,6 +562,11 @@ static int property_get_set_callbacks_run(
if (r < 0)
return r;
+ /* Note that we do not do an access check here. Read
+ * access to properties is always unrestricted, since
+ * PropertiesChanged signals broadcast contents
+ * anyway. */
+
r = invoke_property_get(bus, c->vtable, m->path, c->interface, c->member, reply, u, &error);
if (r < 0)
return bus_maybe_reply_error(m, r, &error);
@@ -525,6 +594,10 @@ static int property_get_set_callbacks_run(
if (r < 0)
return r;
+ r = check_access(bus, m, c, &error);
+ if (r < 0)
+ return bus_maybe_reply_error(m, r, &error);
+
r = invoke_property_set(bus, c->vtable, m->path, c->interface, c->member, m, u, &error);
if (r < 0)
return bus_maybe_reply_error(m, r, &error);
@@ -1199,12 +1272,12 @@ int bus_process_object(sd_bus *bus, sd_bus_message *m) {
if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
return 0;
- if (!m->path)
- return 0;
-
if (hashmap_isempty(bus->nodes))
return 0;
+ assert(m->path);
+ assert(m->member);
+
pl = strlen(m->path);
do {
char prefix[pl+1];
@@ -1636,7 +1709,8 @@ static int add_object_vtable_internal(
!signature_is_single(v->x.property.signature, false) ||
!(v->x.property.get || bus_type_is_basic(v->x.property.signature[0]) || streq(v->x.property.signature, "as")) ||
v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY ||
- (v->flags & SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY && !(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE))) {
+ (v->flags & SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY && !(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE)) ||
+ (v->flags & SD_BUS_VTABLE_UNPRIVILEGED && v->type == _SD_BUS_VTABLE_PROPERTY)) {
r = -EINVAL;
goto fail;
}
@@ -1666,7 +1740,8 @@ static int add_object_vtable_internal(
case _SD_BUS_VTABLE_SIGNAL:
if (!member_name_is_valid(v->x.signal.member) ||
- !signature_is_valid(strempty(v->x.signal.signature), false)) {
+ !signature_is_valid(strempty(v->x.signal.signature), false) ||
+ v->flags & SD_BUS_VTABLE_UNPRIVILEGED) {
r = -EINVAL;
goto fail;
}
diff --git a/src/libsystemd-bus/libsystemd-bus.sym b/src/libsystemd-bus/libsystemd-bus.sym
index 389efc3273..7bc1ef9ad2 100644
--- a/src/libsystemd-bus/libsystemd-bus.sym
+++ b/src/libsystemd-bus/libsystemd-bus.sym
@@ -25,6 +25,7 @@ global:
sd_bus_set_bus_client;
sd_bus_set_server;
sd_bus_set_anonymous;
+ sd_bus_set_trusted;
sd_bus_negotiate_fds;
sd_bus_negotiate_attach_timestamp;
sd_bus_negotiate_attach_creds;
diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index fef122bf3e..81bfe0d922 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -318,6 +318,15 @@ _public_ int sd_bus_set_anonymous(sd_bus *bus, int b) {
return 0;
}
+_public_ int sd_bus_set_trusted(sd_bus *bus, int b) {
+ assert_return(bus, -EINVAL);
+ assert_return(bus->state == BUS_UNSET, -EPERM);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
+
+ bus->trusted = !!b;
+ return 0;
+}
+
static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
const char *s;
int r;
@@ -1005,6 +1014,11 @@ _public_ int sd_bus_open_system(sd_bus **ret) {
b->bus_client = true;
+ /* Let's do per-method access control on the system bus. We
+ * need the caller's UID and capability set for that. */
+ b->trusted = false;
+ b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
+
r = sd_bus_start(b);
if (r < 0)
goto fail;
@@ -1065,6 +1079,10 @@ _public_ int sd_bus_open_user(sd_bus **ret) {
b->bus_client = true;
+ /* We don't do any per-method access control on the user
+ * bus. */
+ b->trusted = true;
+
r = sd_bus_start(b);
if (r < 0)
goto fail;
diff --git a/src/locale/localed.c b/src/locale/localed.c
index 0382232167..abb610d332 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -1068,9 +1068,9 @@ static const sd_bus_vtable locale_vtable[] = {
SD_BUS_PROPERTY("X11Options", "s", NULL, offsetof(Context, x11_options), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("VConsoleKeymap", "s", NULL, offsetof(Context, vc_keymap), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("VConsoleKeymapToggle", "s", NULL, offsetof(Context, vc_keymap_toggle), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_METHOD("SetLocale", "asb", NULL, method_set_locale, 0),
- SD_BUS_METHOD("SetVConsoleKeyboard", "ssbb", NULL, method_set_vc_keyboard, 0),
- SD_BUS_METHOD("SetX11Keyboard", "ssssbb", NULL, method_set_x11_keyboard, 0),
+ SD_BUS_METHOD("SetLocale", "asb", NULL, method_set_locale, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetVConsoleKeyboard", "ssbb", NULL, method_set_vc_keyboard, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetX11Keyboard", "ssssbb", NULL, method_set_x11_keyboard, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 0461d1877e..2568eb0364 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <unistd.h>
#include <pwd.h>
+#include <sys/capability.h>
#include "sd-id128.h"
#include "sd-messages.h"
@@ -1879,42 +1880,42 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
- SD_BUS_METHOD("GetSession", "s", "o", method_get_session, 0),
- SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, 0),
- SD_BUS_METHOD("GetUser", "u", "o", method_get_user, 0),
- SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, 0),
- SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, 0),
- SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, 0),
- SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, 0),
- SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, 0),
- SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, 0),
+ SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshusub", method_create_session, 0),
SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
- SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, 0),
- SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, 0),
+ SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0),
SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0),
SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0),
SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0),
- SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, 0),
- SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, 0),
- SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, 0),
- SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, 0),
- SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, 0),
- SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, 0),
- SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, 0),
- SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, 0),
- SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, 0),
- SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, 0),
- SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, 0),
- SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, 0),
- SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, 0),
- SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, 0),
- SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, 0),
- SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, 0),
- SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, 0),
- SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, 0),
- SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, 0),
+ SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+ SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+ SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+ SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+ SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+ SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL("SessionNew", "so", 0),
SD_BUS_SIGNAL("SessionRemoved", "so", 0),
diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c
index 23f975bca7..9271bcf81c 100644
--- a/src/login/logind-seat-dbus.c
+++ b/src/login/logind-seat-dbus.c
@@ -21,6 +21,7 @@
#include <errno.h>
#include <string.h>
+#include <sys/capability.h>
#include "util.h"
#include "bus-util.h"
@@ -248,8 +249,8 @@ const sd_bus_vtable seat_vtable[] = {
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, 0),
- SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, 0),
+ SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+ SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
index 4bbe75e428..8595809396 100644
--- a/src/login/logind-session-dbus.c
+++ b/src/login/logind-session-dbus.c
@@ -21,6 +21,7 @@
#include <errno.h>
#include <string.h>
+#include <sys/capability.h>
#include "util.h"
#include "strv.h"
@@ -455,17 +456,17 @@ const sd_bus_vtable session_vtable[] = {
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, 0),
- SD_BUS_METHOD("Activate", NULL, NULL, method_activate, 0),
+ SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+ SD_BUS_METHOD("Activate", NULL, NULL, method_activate, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Lock", NULL, NULL, method_lock, 0),
SD_BUS_METHOD("Unlock", NULL, NULL, method_lock, 0),
- SD_BUS_METHOD("SetIdleHint", "b", NULL, method_set_idle_hint, 0),
- SD_BUS_METHOD("Kill", "si", NULL, method_kill, 0),
- SD_BUS_METHOD("TakeControl", "b", NULL, method_take_control, 0),
- SD_BUS_METHOD("ReleaseControl", NULL, NULL, method_release_control, 0),
- SD_BUS_METHOD("TakeDevice", "uu", "hb", method_take_device, 0),
- SD_BUS_METHOD("ReleaseDevice", "uu", NULL, method_release_device, 0),
- SD_BUS_METHOD("PauseDeviceComplete", "uu", NULL, method_pause_device_complete, 0),
+ SD_BUS_METHOD("SetIdleHint", "b", NULL, method_set_idle_hint, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Kill", "si", NULL, method_kill, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+ SD_BUS_METHOD("TakeControl", "b", NULL, method_take_control, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ReleaseControl", NULL, NULL, method_release_control, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("TakeDevice", "uu", "hb", method_take_device, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ReleaseDevice", "uu", NULL, method_release_device, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("PauseDeviceComplete", "uu", NULL, method_pause_device_complete, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL("PauseDevice", "uus", 0),
SD_BUS_SIGNAL("ResumeDevice", "uuh", 0),
diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c
index b034515203..817bbb87e7 100644
--- a/src/login/logind-user-dbus.c
+++ b/src/login/logind-user-dbus.c
@@ -21,10 +21,10 @@
#include <errno.h>
#include <string.h>
+#include <sys/capability.h>
#include "strv.h"
#include "bus-util.h"
-
#include "logind.h"
#include "logind-user.h"
@@ -229,8 +229,8 @@ const sd_bus_vtable user_vtable[] = {
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Linger", "b", property_get_linger, 0, 0),
- SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, 0),
- SD_BUS_METHOD("Kill", "i", NULL, method_kill, 0),
+ SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+ SD_BUS_METHOD("Kill", "i", NULL, method_kill, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
SD_BUS_VTABLE_END
};
diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf
index 04e735eb59..d677f61f1d 100644
--- a/src/login/org.freedesktop.login1.conf
+++ b/src/login/org.freedesktop.login1.conf
@@ -50,19 +50,19 @@
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
- send_member="GetSeat"/>
+ send_member="GetUserByPID"/>
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
- send_member="ListSessions"/>
+ send_member="GetSeat"/>
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
- send_member="ListUsers"/>
+ send_member="ListSessions"/>
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
- send_member="ListMachines"/>
+ send_member="ListUsers"/>
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 726cc4cbc7..1087a1bc4f 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <unistd.h>
#include <pwd.h>
+#include <sys/capability.h>
#include "sd-id128.h"
#include "sd-messages.h"
@@ -342,12 +343,12 @@ static int method_kill_machine(sd_bus *bus, sd_bus_message *message, void *userd
const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_START(0),
- SD_BUS_METHOD("GetMachine", "s", "o", method_get_machine, 0),
- SD_BUS_METHOD("GetMachineByPID", "u", "o", method_get_machine_by_pid, 0),
- SD_BUS_METHOD("ListMachines", NULL, "a(ssso)", method_list_machines, 0),
+ SD_BUS_METHOD("GetMachine", "s", "o", method_get_machine, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetMachineByPID", "u", "o", method_get_machine_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ListMachines", NULL, "a(ssso)", method_list_machines, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CreateMachine", "sayssusa(sv)", "o", method_create_machine, 0),
- SD_BUS_METHOD("KillMachine", "ssi", NULL, method_kill_machine, 0),
- SD_BUS_METHOD("TerminateMachine", "s", NULL, method_terminate_machine, 0),
+ SD_BUS_METHOD("KillMachine", "ssi", NULL, method_kill_machine, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+ SD_BUS_METHOD("TerminateMachine", "s", NULL, method_terminate_machine, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
SD_BUS_SIGNAL("MachineNew", "so", 0),
SD_BUS_SIGNAL("MachineRemoved", "so", 0),
SD_BUS_VTABLE_END
diff --git a/src/machine/org.freedesktop.machine1.conf b/src/machine/org.freedesktop.machine1.conf
index b2d6df3121..970ccd8d69 100644
--- a/src/machine/org.freedesktop.machine1.conf
+++ b/src/machine/org.freedesktop.machine1.conf
@@ -44,6 +44,10 @@
send_interface="org.freedesktop.machine1.Manager"
send_member="GetMachine"/>
+ <allow send_destination="org.freedesktop.machine1"
+ send_interface="org.freedesktop.machine1.Manager"
+ send_member="GetMachineByPID"/>
+
<allow receive_sender="org.freedesktop.machine1"/>
</policy>
diff --git a/src/systemd/sd-bus-vtable.h b/src/systemd/sd-bus-vtable.h
index 18fc30bd20..e6e0a72f8a 100644
--- a/src/systemd/sd-bus-vtable.h
+++ b/src/systemd/sd-bus-vtable.h
@@ -31,28 +31,32 @@ typedef struct sd_bus_vtable sd_bus_vtable;
#include "sd-bus.h"
enum {
- _SD_BUS_VTABLE_START = '<',
- _SD_BUS_VTABLE_END = '>',
- _SD_BUS_VTABLE_METHOD = 'M',
- _SD_BUS_VTABLE_SIGNAL = 'S',
- _SD_BUS_VTABLE_PROPERTY = 'P',
+ _SD_BUS_VTABLE_START = '<',
+ _SD_BUS_VTABLE_END = '>',
+ _SD_BUS_VTABLE_METHOD = 'M',
+ _SD_BUS_VTABLE_SIGNAL = 'S',
+ _SD_BUS_VTABLE_PROPERTY = 'P',
_SD_BUS_VTABLE_WRITABLE_PROPERTY = 'W',
- _SD_BUS_VTABLE_CHILDREN = 'C'
+ _SD_BUS_VTABLE_CHILDREN = 'C',
};
enum {
- SD_BUS_VTABLE_DEPRECATED = 1,
- SD_BUS_VTABLE_METHOD_NO_REPLY = 2,
- SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE = 4,
- SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY = 8,
+ SD_BUS_VTABLE_DEPRECATED = 1ULL << 0,
+ SD_BUS_VTABLE_METHOD_NO_REPLY = 1ULL << 1,
+ SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE = 1ULL << 2,
+ SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY = 1ULL << 3,
+ SD_BUS_VTABLE_UNPRIVILEGED = 1ULL << 4,
+ _SD_BUS_VTABLE_CAPABILITY_MASK = 0xFFFFULL << 40
};
+#define SD_BUS_VTABLE_CAPABILITY(x) ((uint64_t) (((x)+1) & 0xFFFF) << 40)
+
struct sd_bus_vtable {
/* Please do not initialize this structure directly, use the
* macros below instead */
- int type;
- int flags;
+ uint8_t type:8;
+ uint64_t flags:56;
union {
struct {
size_t element_size;
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 1c0d12a0cc..402fc55f93 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -103,6 +103,7 @@ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]);
int sd_bus_set_bus_client(sd_bus *bus, int b);
int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id);
int sd_bus_set_anonymous(sd_bus *bus, int b);
+int sd_bus_set_trusted(sd_bus *bus, int b);
int sd_bus_negotiate_fds(sd_bus *bus, int b);
int sd_bus_negotiate_attach_timestamp(sd_bus *bus, int b);
int sd_bus_negotiate_attach_creds(sd_bus *bus, uint64_t creds_mask);
diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
index 6e0bc3cf83..9b81513c75 100644
--- a/src/timedate/timedatectl.c
+++ b/src/timedate/timedatectl.c
@@ -214,8 +214,10 @@ static int show_status(sd_bus *bus, char **args, unsigned n) {
"/org/freedesktop/timedate1",
map,
&info);
- if (r < 0)
+ if (r < 0) {
+ log_error("Failed to query server: %s", strerror(-r));
goto fail;
+ }
print_status_info(&info);
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
index 0641f39551..6d4388c70c 100644
--- a/src/timedate/timedated.c
+++ b/src/timedate/timedated.c
@@ -750,6 +750,8 @@ static int method_set_ntp(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus
return sd_bus_reply_method_return(m, NULL);
}
+#include <sys/capability.h>
+
static const sd_bus_vtable timedate_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Timezone", "s", NULL, offsetof(Context, zone), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
@@ -759,10 +761,10 @@ static const sd_bus_vtable timedate_vtable[] = {
SD_BUS_PROPERTY("NTPSynchronized", "b", property_get_ntp_sync, 0, 0),
SD_BUS_PROPERTY("TimeUSec", "t", property_get_time, 0, 0),
SD_BUS_PROPERTY("RTCTimeUSec", "t", property_get_rtc_time, 0, 0),
- SD_BUS_METHOD("SetTime", "xbb", NULL, method_set_time, 0),
- SD_BUS_METHOD("SetTimezone", "sb", NULL, method_set_timezone, 0),
- SD_BUS_METHOD("SetLocalRTC", "bbb", NULL, method_set_local_rtc, 0),
- SD_BUS_METHOD("SetNTP", "bb", NULL, method_set_ntp, 0),
+ SD_BUS_METHOD("SetTime", "xbb", NULL, method_set_time, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetTimezone", "sb", NULL, method_set_timezone, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetLocalRTC", "bbb", NULL, method_set_local_rtc, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetNTP", "bb", NULL, method_set_ntp, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END,
};