chiark / gitweb /
bus: introduce "trusted" bus concept and encode access control in object vtables
authorLennart Poettering <lennart@poettering.net>
Tue, 10 Dec 2013 16:41:39 +0000 (16:41 +0000)
committerLennart Poettering <lennart@poettering.net>
Tue, 10 Dec 2013 16:52:49 +0000 (16:52 +0000)
Introduces a new concept of "trusted" vs. "untrusted" busses. For the
latter libsystemd-bus will automatically do per-method access control,
for the former all access is automatically granted. Per-method access
control is encoded in the vtables: by default all methods are only
accessible to privileged clients. If the SD_BUS_VTABLE_UNPRIVILEGED flag
is set for a method it is accessible to unprivileged clients too. By
default whether a client is privileged is determined via checking for
its CAP_SYS_ADMIN capability, but this can be altered via the
SD_BUS_VTABLE_CAPABILITY() macro that can be ORed into the flags field
of the method.

Writable properties are also subject to SD_BUS_VTABLE_UNPRIVILEGED and
SD_BUS_VTABLE_CAPABILITY() for controlling write access to them. Note
however that read access is unrestricted, as PropertiesChanged messages
might send out the values anyway as an unrestricted broadcast.

By default the system bus is set to "untrusted" and the user bus is
"trusted" since per-method access control on the latter is unnecessary.

On dbus1 busses we check the UID of the caller rather than the
configured capability since the capability cannot be determined without
race. On kdbus the capability is checked if possible from the attached
meta-data of a message and otherwise queried from the sending peer.

This also decorates the vtables of the various daemons we ship with
these flags.

20 files changed:
TODO
src/core/dbus-manager.c
src/hostname/hostnamed.c
src/libsystemd-bus/bus-internal.h
src/libsystemd-bus/bus-introspect.c
src/libsystemd-bus/bus-objects.c
src/libsystemd-bus/libsystemd-bus.sym
src/libsystemd-bus/sd-bus.c
src/locale/localed.c
src/login/logind-dbus.c
src/login/logind-seat-dbus.c
src/login/logind-session-dbus.c
src/login/logind-user-dbus.c
src/login/org.freedesktop.login1.conf
src/machine/machined-dbus.c
src/machine/org.freedesktop.machine1.conf
src/systemd/sd-bus-vtable.h
src/systemd/sd-bus.h
src/timedate/timedatectl.c
src/timedate/timedated.c

diff --git a/TODO b/TODO
index 253d0bf1b2ed94e1488b5c0662f4af4122b4cd65..dac44e0c6a6f875165ffecf053783828e8e4c89e 100644 (file)
--- 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
index a2707ee9b74aa438e06cfb1af1f73c0073974b05..9c2194b0e539ae209dd73376cc14dc03b568f995 100644 (file)
@@ -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),
index 908296605731507c26f50bbbd475b1cb77adb017..f7ae50dcd8a4aca9ed711bd2afe0caa9e9dee3e8 100644 (file)
@@ -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,
 };
 
index 4881e0427c9ae8bbec29377db6e325512f56bc27..1be7488ab93f8067a60a8fca622f4f83ec824a56 100644 (file)
@@ -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;
 
index 115b3ceae875fbb0d32c2efc7a0cd0f8b30357db..8bec017d639dd4fd95cff9019d6be3373c866905 100644 (file)
@@ -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) {
index 7cd34c991b004f389c06656e37d1e9eca20fb251..941c2810d877136750386adb1799f41c6adb15a4 100644 (file)
@@ -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;
                         }
index 389efc3273859b7409e33e23f95ea932830b6423..7bc1ef9ad20108fb6be8a3d005435a649da1e618 100644 (file)
@@ -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;
index fef122bf3ede6a2740178e8ed655d052533e7151..81bfe0d92202847420922e6a5c7f8080fe6bc633 100644 (file)
@@ -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;
index 0382232167ed1b3b2a74eaaa13cfc4f993523f40..abb610d33259f87e7aa382512c75c17406e31e57 100644 (file)
@@ -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
 };
 
index 0461d1877e7b2d22caa5588d6d2efa4adfbe41ce..2568eb0364c17787f1a281b4b527d43af83050e3 100644 (file)
@@ -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),
index 23f975bca7ebae9c5630644a0b42ca77fccfe54f..9271bcf81c5e1841fda9b82f9597ee3df633edc4 100644 (file)
@@ -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
 };
index 4bbe75e428cc7b5a5b8408fd96945c596cf324f0..85958093960aa8436c87fdf4c6210a06b44a1348 100644 (file)
@@ -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),
index b034515203465e548c6da9d9c8b4a95cd75130b1..817bbb87e7bb853527004017293d36312aa28a4a 100644 (file)
 
 #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
 };
index 04e735eb5913567af9175c57ea224f5c47b1ec1c..d677f61f1d4350ba24ed90aa326205c8001c3d07 100644 (file)
 
                 <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"
index 726cc4cbc73c52992168190f53dd91f9fada173c..1087a1bc4f1552a939dc5b9a2ccd76822fb03b24 100644 (file)
@@ -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
index b2d6df312165298d0a482b5ef7510f632f0158af..970ccd8d69d3a5fad72c1d804addce5df3cec5b4 100644 (file)
                        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>
 
index 18fc30bd209f8ddd34c3bf799394744c52800724..e6e0a72f8abe4ddf260a1b980221a872e77a7d8d 100644 (file)
@@ -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;
index 1c0d12a0cc24d8cc72e9a789664b8941271b0bb5..402fc55f93c3a41834ce6d34a6948885013cce95 100644 (file)
@@ -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);
index 6e0bc3cf831eb55241c8c9ae863830763b45921f..9b81513c75456664b2749c5898318b2a54e470d5 100644 (file)
@@ -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);
 
index 0641f3955167e0f008d5967848f977a1d9007ff9..6d4388c70c1ca77b84b00dc60360d42abaa31e2e 100644 (file)
@@ -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,
 };