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(" \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(" \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(" \n", i->f); } + + if ((type == _SD_BUS_VTABLE_METHOD || type == _SD_BUS_VTABLE_WRITABLE_PROPERTY) && (flags & SD_BUS_VTABLE_UNPRIVILEGED)) + fputs(" \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 . ***/ +#include + #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 #include #include +#include #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 #include +#include #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 #include +#include #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 #include +#include #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 @@ -48,6 +48,10 @@ send_interface="org.freedesktop.login1.Manager" send_member="GetUser"/> + + @@ -60,10 +64,6 @@ send_interface="org.freedesktop.login1.Manager" send_member="ListUsers"/> - - 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 #include #include +#include #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"/> + + 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 + 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, };