diff --git a/src/core/dbus.c b/src/core/dbus.c index 260775cd85..2f313adec7 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -1193,18 +1193,18 @@ int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l) { } int bus_verify_manage_unit_async(Manager *m, sd_bus_message *call, sd_bus_error *error) { - return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-units", false, &m->polkit_registry, error); + return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-units", false, UID_INVALID, &m->polkit_registry, error); } /* Same as bus_verify_manage_unit_async(), but checks for CAP_KILL instead of CAP_SYS_ADMIN */ int bus_verify_manage_unit_async_for_kill(Manager *m, sd_bus_message *call, sd_bus_error *error) { - return bus_verify_polkit_async(call, CAP_KILL, "org.freedesktop.systemd1.manage-units", false, &m->polkit_registry, error); + return bus_verify_polkit_async(call, CAP_KILL, "org.freedesktop.systemd1.manage-units", false, UID_INVALID, &m->polkit_registry, error); } int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error) { - return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-unit-files", false, &m->polkit_registry, error); + return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-unit-files", false, UID_INVALID, &m->polkit_registry, error); } int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error) { - return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.reload-daemon", false, &m->polkit_registry, error); + return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.reload-daemon", false, UID_INVALID, &m->polkit_registry, error); } diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 7cd4a1d001..ede8185788 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -427,7 +427,14 @@ static int method_set_hostname(sd_bus *bus, sd_bus_message *m, void *userdata, s if (streq_ptr(name, c->data[PROP_HOSTNAME])) return sd_bus_reply_method_return(m, NULL); - r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-hostname", interactive, &c->polkit_registry, error); + r = bus_verify_polkit_async( + m, + CAP_SYS_ADMIN, + "org.freedesktop.hostname1.set-hostname", + interactive, + UID_INVALID, + &c->polkit_registry, + error); if (r < 0) return r; if (r == 0) @@ -469,7 +476,14 @@ static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *user if (streq_ptr(name, c->data[PROP_STATIC_HOSTNAME])) return sd_bus_reply_method_return(m, NULL); - r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-static-hostname", interactive, &c->polkit_registry, error); + r = bus_verify_polkit_async( + m, + CAP_SYS_ADMIN, + "org.freedesktop.hostname1.set-static-hostname", + interactive, + UID_INVALID, + &c->polkit_registry, + error); if (r < 0) return r; if (r == 0) @@ -534,10 +548,14 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop * same time as the static one, use the same policy action for * both... */ - r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, - prop == PROP_PRETTY_HOSTNAME ? - "org.freedesktop.hostname1.set-static-hostname" : - "org.freedesktop.hostname1.set-machine-info", interactive, &c->polkit_registry, error); + r = bus_verify_polkit_async( + m, + CAP_SYS_ADMIN, + prop == PROP_PRETTY_HOSTNAME ? "org.freedesktop.hostname1.set-static-hostname" : "org.freedesktop.hostname1.set-machine-info", + interactive, + UID_INVALID, + &c->polkit_registry, + error); if (r < 0) return r; if (r == 0) diff --git a/src/import/importd.c b/src/import/importd.c index 1222bf3cd2..2eef476015 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -661,6 +661,7 @@ static int method_pull_tar_or_raw(sd_bus *bus, sd_bus_message *msg, void *userda CAP_SYS_ADMIN, "org.freedesktop.import1.pull", false, + UID_INVALID, &m->polkit_registry, error); if (r < 0) @@ -736,6 +737,7 @@ static int method_pull_dkr(sd_bus *bus, sd_bus_message *msg, void *userdata, sd_ CAP_SYS_ADMIN, "org.freedesktop.import1.pull", false, + UID_INVALID, &m->polkit_registry, error); if (r < 0) @@ -865,6 +867,7 @@ static int method_cancel(sd_bus *bus, sd_bus_message *msg, void *userdata, sd_bu CAP_SYS_ADMIN, "org.freedesktop.import1.pull", false, + UID_INVALID, &t->manager->polkit_registry, error); if (r < 0) @@ -894,6 +897,7 @@ static int method_cancel_transfer(sd_bus *bus, sd_bus_message *msg, void *userda CAP_SYS_ADMIN, "org.freedesktop.import1.pull", false, + UID_INVALID, &m->polkit_registry, error); if (r < 0) diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c index 52d4ebe611..3bd6b8db9a 100644 --- a/src/libsystemd/sd-bus/bus-util.c +++ b/src/libsystemd/sd-bus/bus-util.c @@ -190,11 +190,33 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) { return has_owner; } +static int check_good_user(sd_bus_message *m, uid_t good_user) { + _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; + uid_t sender_uid; + int r; + + assert(m); + + if (good_user == UID_INVALID) + return 0; + + r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_EUID, &creds); + if (r < 0) + return r; + + r = sd_bus_creds_get_euid(creds, &sender_uid); + if (r < 0) + return r; + + return sender_uid == good_user; +} + int bus_verify_polkit( sd_bus_message *call, int capability, const char *action, bool interactive, + uid_t good_user, bool *_challenge, sd_bus_error *e) { @@ -203,6 +225,10 @@ int bus_verify_polkit( assert(call); assert(action); + r = check_good_user(call, good_user); + if (r != 0) + return r; + r = sd_bus_query_sender_privilege(call, capability); if (r < 0) return r; @@ -330,6 +356,7 @@ int bus_verify_polkit_async( int capability, const char *action, bool interactive, + uid_t good_user, Hashmap **registry, sd_bus_error *error) { @@ -347,6 +374,10 @@ int bus_verify_polkit_async( assert(action); assert(registry); + r = check_good_user(call, good_user); + if (r != 0) + return r; + #ifdef ENABLE_POLKIT q = hashmap_get(*registry, call); if (q) { diff --git a/src/libsystemd/sd-bus/bus-util.h b/src/libsystemd/sd-bus/bus-util.h index e8a97cef9e..e9efa3597c 100644 --- a/src/libsystemd/sd-bus/bus-util.h +++ b/src/libsystemd/sd-bus/bus-util.h @@ -70,9 +70,9 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error); int bus_check_peercred(sd_bus *c); -int bus_verify_polkit(sd_bus_message *call, int capability, const char *action, bool interactive, bool *_challenge, sd_bus_error *e); +int bus_verify_polkit(sd_bus_message *call, int capability, const char *action, bool interactive, uid_t good_user, bool *_challenge, sd_bus_error *e); -int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, bool interactive, Hashmap **registry, sd_bus_error *error); +int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, bool interactive, uid_t good_user, Hashmap **registry, sd_bus_error *error); void bus_verify_polkit_async_registry_free(Hashmap *registry); int bus_open_system_systemd(sd_bus **_bus); diff --git a/src/locale/localed.c b/src/locale/localed.c index d1c90d613a..5119fcd9b6 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -949,7 +949,14 @@ static int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata, sd_ if (modified) { _cleanup_strv_free_ char **settings = NULL; - r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-locale", interactive, &c->polkit_registry, error); + r = bus_verify_polkit_async( + m, + CAP_SYS_ADMIN, + "org.freedesktop.locale1.set-locale", + interactive, + UID_INVALID, + &c->polkit_registry, + error); if (r < 0) return r; if (r == 0) @@ -1027,7 +1034,14 @@ static int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata (keymap_toggle && (!filename_is_valid(keymap_toggle) || !string_is_safe(keymap_toggle)))) return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keymap data"); - r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error); + r = bus_verify_polkit_async( + m, + CAP_SYS_ADMIN, + "org.freedesktop.locale1.set-keyboard", + interactive, + UID_INVALID, + &c->polkit_registry, + error); if (r < 0) return r; if (r == 0) @@ -1146,7 +1160,14 @@ static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdat (options && !string_is_safe(options))) return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keyboard data"); - r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error); + r = bus_verify_polkit_async( + m, + CAP_SYS_ADMIN, + "org.freedesktop.locale1.set-keyboard", + interactive, + UID_INVALID, + &c->polkit_registry, + error); if (r < 0) return r; if (r == 0) diff --git a/src/login/loginctl.c b/src/login/loginctl.c index b0eede9a34..13b8102483 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -869,7 +869,7 @@ static int activate(int argc, char *argv[], void *userdata) { for (i = 1; i < argc; i++) { - r = sd_bus_call_method ( + r = sd_bus_call_method( bus, "org.freedesktop.login1", "/org/freedesktop/login1", @@ -904,7 +904,7 @@ static int kill_session(int argc, char *argv[], void *userdata) { for (i = 1; i < argc; i++) { - r = sd_bus_call_method ( + r = sd_bus_call_method( bus, "org.freedesktop.login1", "/org/freedesktop/login1", @@ -954,7 +954,7 @@ static int enable_linger(int argc, char *argv[], void *userdata) { return log_error_errno(r, "Failed to look up user %s: %m", argv[i]); } - r = sd_bus_call_method ( + r = sd_bus_call_method( bus, "org.freedesktop.login1", "/org/freedesktop/login1", @@ -988,7 +988,7 @@ static int terminate_user(int argc, char *argv[], void *userdata) { if (r < 0) return log_error_errno(r, "Failed to look up user %s: %m", argv[i]); - r = sd_bus_call_method ( + r = sd_bus_call_method( bus, "org.freedesktop.login1", "/org/freedesktop/login1", @@ -1025,7 +1025,7 @@ static int kill_user(int argc, char *argv[], void *userdata) { if (r < 0) return log_error_errno(r, "Failed to look up user %s: %m", argv[i]); - r = sd_bus_call_method ( + r = sd_bus_call_method( bus, "org.freedesktop.login1", "/org/freedesktop/login1", @@ -1054,7 +1054,7 @@ static int attach(int argc, char *argv[], void *userdata) { for (i = 2; i < argc; i++) { - r = sd_bus_call_method ( + r = sd_bus_call_method( bus, "org.freedesktop.login1", "/org/freedesktop/login1", @@ -1082,7 +1082,7 @@ static int flush_devices(int argc, char *argv[], void *userdata) { polkit_agent_open_if_enabled(); - r = sd_bus_call_method ( + r = sd_bus_call_method( bus, "org.freedesktop.login1", "/org/freedesktop/login1", @@ -1375,6 +1375,8 @@ int main(int argc, char *argv[]) { goto finish; } + sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); + r = loginctl_main(argc, argv, bus); finish: diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 8b0bafd49e..5d61edbd46 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -854,11 +854,7 @@ static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *u if (r < 0) return r; - r = session_activate(session); - if (r < 0) - return r; - - return sd_bus_reply_method_return(message, NULL); + return bus_session_method_activate(bus, message, session, error); } static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -915,11 +911,7 @@ static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userd if (r < 0) return r; - r = session_send_lock(session, streq(sd_bus_message_get_member(message), "LockSession")); - if (r < 0) - return r; - - return sd_bus_reply_method_return(message, NULL); + return bus_session_method_lock(bus, message, session, error); } static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -930,6 +922,19 @@ static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *user assert(message); assert(m); + r = bus_verify_polkit_async( + message, + CAP_SYS_ADMIN, + "org.freedesktop.login1.lock-sessions", + false, + UID_INVALID, + &m->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Will call us back */ + r = session_send_lock_all(m, streq(sd_bus_message_get_member(message), "LockSessions")); if (r < 0) return r; @@ -938,47 +943,29 @@ static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *user } static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { - const char *name, *swho; + const char *name; Manager *m = userdata; Session *session; - int32_t signo; - KillWho who; int r; assert(bus); assert(message); assert(m); - r = sd_bus_message_read(message, "ssi", &name, &swho, &signo); + r = sd_bus_message_read(message, "s", &name); if (r < 0) return r; - if (isempty(swho)) - who = KILL_ALL; - else { - who = kill_who_from_string(swho); - if (who < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho); - } - - if (signo <= 0 || signo >= _NSIG) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo); - r = manager_get_session_from_creds(m, message, name, error, &session); if (r < 0) return r; - r = session_kill(session, who, signo); - if (r < 0) - return r; - - return sd_bus_reply_method_return(message, NULL); + return bus_session_method_kill(bus, message, session, error); } static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { Manager *m = userdata; uint32_t uid; - int32_t signo; User *user; int r; @@ -986,22 +973,15 @@ static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata assert(message); assert(m); - r = sd_bus_message_read(message, "ui", &uid, &signo); + r = sd_bus_message_read(message, "u", &uid); if (r < 0) return r; - if (signo <= 0 || signo >= _NSIG) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo); - r = manager_get_user_from_creds(m, message, uid, error, &user); if (r < 0) return r; - r = user_kill(user, signo); - if (r < 0) - return r; - - return sd_bus_reply_method_return(message, NULL); + return bus_user_method_kill(bus, message, user, error); } static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -1022,11 +1002,7 @@ static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void * if (r < 0) return r; - r = session_stop(session, true); - if (r < 0) - return r; - - return sd_bus_reply_method_return(message, NULL); + return bus_session_method_terminate(bus, message, session, error); } static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -1047,11 +1023,7 @@ static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *use if (r < 0) return r; - r = user_stop(user, true); - if (r < 0) - return r; - - return sd_bus_reply_method_return(message, NULL); + return bus_user_method_terminate(bus, message, user, error); } static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -1072,11 +1044,7 @@ static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *use if (r < 0) return r; - r = seat_stop_sessions(seat, true); - if (r < 0) - return r; - - return sd_bus_reply_method_return(message, NULL); + return bus_seat_method_terminate(bus, message, seat, error); } static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -1119,6 +1087,7 @@ static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *us CAP_SYS_ADMIN, "org.freedesktop.login1.set-user-linger", interactive, + UID_INVALID, &m->polkit_registry, error); if (r < 0) @@ -1291,6 +1260,7 @@ static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *user CAP_SYS_ADMIN, "org.freedesktop.login1.attach-device", interactive, + UID_INVALID, &m->polkit_registry, error); if (r < 0) @@ -1322,6 +1292,7 @@ static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *user CAP_SYS_ADMIN, "org.freedesktop.login1.flush-devices", interactive, + UID_INVALID, &m->polkit_registry, error); if (r < 0) @@ -1619,7 +1590,7 @@ static int method_do_shutdown_or_sleep( blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL); if (multiple_sessions) { - r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, &m->polkit_registry, error); + r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -1627,7 +1598,7 @@ static int method_do_shutdown_or_sleep( } if (blocked) { - r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, &m->polkit_registry, error); + r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -1635,7 +1606,7 @@ static int method_do_shutdown_or_sleep( } if (!multiple_sessions && !blocked) { - r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, &m->polkit_registry, error); + r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -1772,7 +1743,7 @@ static int method_can_shutdown_or_sleep( blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL); if (multiple_sessions) { - r = bus_verify_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, false, &challenge, error); + r = bus_verify_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, false, UID_INVALID, &challenge, error); if (r < 0) return r; @@ -1785,7 +1756,7 @@ static int method_can_shutdown_or_sleep( } if (blocked) { - r = bus_verify_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, false, &challenge, error); + r = bus_verify_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, false, UID_INVALID, &challenge, error); if (r < 0) return r; @@ -1801,7 +1772,7 @@ static int method_can_shutdown_or_sleep( /* If neither inhibit nor multiple sessions * apply then just check the normal policy */ - r = bus_verify_polkit(message, CAP_SYS_BOOT, action, false, &challenge, error); + r = bus_verify_polkit(message, CAP_SYS_BOOT, action, false, UID_INVALID, &challenge, error); if (r < 0) return r; @@ -1921,15 +1892,20 @@ static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, if (m->action_what & w) return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running"); - r = bus_verify_polkit_async(message, CAP_SYS_BOOT, - w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") : - w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") : - w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" : - w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" : - w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" : - w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" : - "org.freedesktop.login1.inhibit-handle-lid-switch", - false, &m->polkit_registry, error); + r = bus_verify_polkit_async( + message, + CAP_SYS_BOOT, + w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") : + w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") : + w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" : + w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" : + w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" : + w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" : + "org.freedesktop.login1.inhibit-handle-lid-switch", + false, + UID_INVALID, + &m->polkit_registry, + error); if (r < 0) return r; if (r == 0) @@ -2025,15 +2001,15 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 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, 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("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED), 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), diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c index 50b0b8842f..f50ee8d759 100644 --- a/src/login/logind-seat-dbus.c +++ b/src/login/logind-seat-dbus.c @@ -193,7 +193,7 @@ static int property_get_idle_since_hint( return sd_bus_message_append(reply, "t", u); } -static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { +int bus_seat_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { Seat *s = userdata; int r; @@ -201,6 +201,19 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata assert(message); assert(s); + r = bus_verify_polkit_async( + message, + CAP_KILL, + "org.freedesktop.login1.manage", + false, + UID_INVALID, + &s->manager->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Will call us back */ + r = seat_stop_sessions(s, true); if (r < 0) return r; @@ -302,7 +315,7 @@ 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, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), + SD_BUS_METHOD("Terminate", NULL, NULL, bus_seat_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("SwitchTo", "u", NULL, method_switch_to, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("SwitchToNext", NULL, NULL, method_switch_to_next, SD_BUS_VTABLE_UNPRIVILEGED), diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h index 9e469d41c6..15f11b85ab 100644 --- a/src/login/logind-seat.h +++ b/src/login/logind-seat.h @@ -96,3 +96,5 @@ char *seat_bus_path(Seat *s); int seat_send_signal(Seat *s, bool new_seat); int seat_send_changed(Seat *s, const char *properties, ...) _sentinel_; + +int bus_seat_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 4e7edef52d..b119c8321b 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -180,7 +180,7 @@ static int property_get_idle_since_hint( return sd_bus_message_append(reply, "t", u); } -static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { +int bus_session_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { Session *s = userdata; int r; @@ -188,6 +188,19 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata assert(message); assert(s); + r = bus_verify_polkit_async( + message, + CAP_KILL, + "org.freedesktop.login1.manage", + false, + s->user->uid, + &s->manager->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Will call us back */ + r = session_stop(s, true); if (r < 0) return r; @@ -195,7 +208,7 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata return sd_bus_reply_method_return(message, NULL); } -static int method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { +int bus_session_method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { Session *s = userdata; int r; @@ -210,7 +223,7 @@ static int method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, return sd_bus_reply_method_return(message, NULL); } -static int method_lock(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { +int bus_session_method_lock(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { Session *s = userdata; int r; @@ -218,7 +231,20 @@ static int method_lock(sd_bus *bus, sd_bus_message *message, void *userdata, sd_ assert(message); assert(s); - r = session_send_lock(s, streq(sd_bus_message_get_member(message), "Lock")); + r = bus_verify_polkit_async( + message, + CAP_SYS_ADMIN, + "org.freedesktop.login1.lock-sessions", + false, + s->user->uid, + &s->manager->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Will call us back */ + + r = session_send_lock(s, strstr(sd_bus_message_get_member(message), "Lock")); if (r < 0) return r; @@ -255,7 +281,7 @@ static int method_set_idle_hint(sd_bus *bus, sd_bus_message *message, void *user return sd_bus_reply_method_return(message, NULL); } -static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { +int bus_session_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { Session *s = userdata; const char *swho; int32_t signo; @@ -281,6 +307,19 @@ static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_ if (signo <= 0 || signo >= _NSIG) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo); + r = bus_verify_polkit_async( + message, + CAP_KILL, + "org.freedesktop.login1.manage", + false, + s->user->uid, + &s->manager->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Will call us back */ + r = session_kill(s, who, signo); if (r < 0) return r; @@ -456,12 +495,12 @@ 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, 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("Terminate", NULL, NULL, bus_session_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Activate", NULL, NULL, bus_session_method_activate, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Lock", NULL, NULL, bus_session_method_lock, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Unlock", NULL, NULL, bus_session_method_lock, SD_BUS_VTABLE_UNPRIVILEGED), 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("Kill", "si", NULL, bus_session_method_kill, SD_BUS_VTABLE_UNPRIVILEGED), 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), diff --git a/src/login/logind-session.h b/src/login/logind-session.h index a007fb5e84..3ec9d84f96 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -179,3 +179,8 @@ void session_leave_vt(Session *s); bool session_is_controller(Session *s, const char *sender); int session_set_controller(Session *s, const char *sender, bool force); void session_drop_controller(Session *s); + +int bus_session_method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); +int bus_session_method_lock(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); +int bus_session_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); +int bus_session_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c index 5cfaac0d4f..f7af8ff9b2 100644 --- a/src/login/logind-user-dbus.c +++ b/src/login/logind-user-dbus.c @@ -171,7 +171,7 @@ static int property_get_linger( return sd_bus_message_append(reply, "b", r > 0); } -static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { +int bus_user_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { User *u = userdata; int r; @@ -179,6 +179,19 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata assert(message); assert(u); + r = bus_verify_polkit_async( + message, + CAP_KILL, + "org.freedesktop.login1.manage", + false, + u->uid, + &u->manager->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Will call us back */ + r = user_stop(u, true); if (r < 0) return r; @@ -186,7 +199,7 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata return sd_bus_reply_method_return(message, NULL); } -static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { +int bus_user_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { User *u = userdata; int32_t signo; int r; @@ -195,6 +208,19 @@ static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_ assert(message); assert(u); + r = bus_verify_polkit_async( + message, + CAP_KILL, + "org.freedesktop.login1.manage", + false, + u->uid, + &u->manager->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Will call us back */ + r = sd_bus_message_read(message, "i", &signo); if (r < 0) return r; @@ -227,8 +253,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, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), - SD_BUS_METHOD("Kill", "i", NULL, method_kill, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), + SD_BUS_METHOD("Terminate", NULL, NULL, bus_user_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Kill", "i", NULL, bus_user_method_kill, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_END }; diff --git a/src/login/logind-user.h b/src/login/logind-user.h index 4e0568fea9..2cb57e1675 100644 --- a/src/login/logind-user.h +++ b/src/login/logind-user.h @@ -92,3 +92,6 @@ int user_send_changed(User *u, const char *properties, ...) _sentinel_; const char* user_state_to_string(UserState s) _const_; UserState user_state_from_string(const char *s) _pure_; + +int bus_user_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); +int bus_user_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error); diff --git a/src/login/org.freedesktop.login1.policy.in b/src/login/org.freedesktop.login1.policy.in index 49094eeddb..35bb3907c6 100644 --- a/src/login/org.freedesktop.login1.policy.in +++ b/src/login/org.freedesktop.login1.policy.in @@ -270,4 +270,24 @@ org.freedesktop.login1.hibernate + + <_description>Manager active sessions, users and seats + <_message>Authentication is required for managing active sessions, users and seats. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Lock or unlock active sessions + <_message>Authentication is required for locking or unlocking active sessions. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c index 0d4ebde92b..ef1914e2b9 100644 --- a/src/machine/image-dbus.c +++ b/src/machine/image-dbus.c @@ -47,6 +47,7 @@ int bus_image_method_remove( CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-images", false, + UID_INVALID, &m->polkit_registry, error); if (r < 0) @@ -88,6 +89,7 @@ int bus_image_method_rename( CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-images", false, + UID_INVALID, &m->polkit_registry, error); if (r < 0) @@ -129,6 +131,7 @@ int bus_image_method_clone( CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-images", false, + UID_INVALID, &m->polkit_registry, error); if (r < 0) @@ -165,6 +168,7 @@ int bus_image_method_mark_read_only( CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-images", false, + UID_INVALID, &m->polkit_registry, error); if (r < 0) diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 405c072b90..116e711a78 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -133,6 +133,7 @@ int bus_machine_method_terminate(sd_bus *bus, sd_bus_message *message, void *use CAP_KILL, "org.freedesktop.machine1.manage-machines", false, + UID_INVALID, &m->manager->polkit_registry, error); if (r < 0) @@ -178,6 +179,7 @@ int bus_machine_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata CAP_KILL, "org.freedesktop.machine1.manage-machines", false, + UID_INVALID, &m->manager->polkit_registry, error); if (r < 0) @@ -480,6 +482,7 @@ int bus_machine_method_open_login(sd_bus *bus, sd_bus_message *message, void *us CAP_SYS_ADMIN, "org.freedesktop.machine1.login", false, + UID_INVALID, &m->manager->polkit_registry, error); if (r < 0) @@ -583,6 +586,7 @@ int bus_machine_method_bind_mount(sd_bus *bus, sd_bus_message *message, void *us CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-machines", false, + UID_INVALID, &m->manager->polkit_registry, error); if (r < 0) @@ -841,6 +845,7 @@ int bus_machine_method_copy(sd_bus *bus, sd_bus_message *message, void *userdata CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-machines", false, + UID_INVALID, &m->manager->polkit_registry, error); if (r < 0) diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 753c3d1d65..23efe832a7 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -397,7 +397,14 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata, s if (streq_ptr(z, c->zone)) return sd_bus_reply_method_return(m, NULL); - r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-timezone", interactive, &c->polkit_registry, error); + r = bus_verify_polkit_async( + m, + CAP_SYS_TIME, + "org.freedesktop.timedate1.set-timezone", + interactive, + UID_INVALID, + &c->polkit_registry, + error); if (r < 0) return r; if (r == 0) @@ -458,7 +465,14 @@ static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata, if (lrtc == c->local_rtc) return sd_bus_reply_method_return(m, NULL); - r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-local-rtc", interactive, &c->polkit_registry, error); + r = bus_verify_polkit_async( + m, + CAP_SYS_TIME, + "org.freedesktop.timedate1.set-local-rtc", + interactive, + UID_INVALID, + &c->polkit_registry, + error); if (r < 0) return r; if (r == 0) @@ -563,7 +577,14 @@ static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bu } else timespec_store(&ts, (usec_t) utc); - r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-time", interactive, &c->polkit_registry, error); + r = bus_verify_polkit_async( + m, + CAP_SYS_TIME, + "org.freedesktop.timedate1.set-time", + interactive, + UID_INVALID, + &c->polkit_registry, + error); if (r < 0) return r; if (r == 0) @@ -603,7 +624,14 @@ static int method_set_ntp(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus if ((bool)ntp == c->use_ntp) return sd_bus_reply_method_return(m, NULL); - r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-ntp", interactive, &c->polkit_registry, error); + r = bus_verify_polkit_async( + m, + CAP_SYS_TIME, + "org.freedesktop.timedate1.set-ntp", + interactive, + UID_INVALID, + &c->polkit_registry, + error); if (r < 0) return r; if (r == 0)