logind: open up most bus calls for unpriviliged processes, using PolicyKit

Also, allow clients to alter their own objects without any further
priviliges. i.e. this allows clients to kill and lock their own sessions
without involving PK.
This commit is contained in:
Lennart Poettering 2015-02-18 12:55:25 +01:00
parent 2723b3b51d
commit c529695e7a
18 changed files with 318 additions and 121 deletions

View File

@ -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);
}

View File

@ -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)

View File

@ -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)

View File

@ -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) {

View File

@ -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);

View File

@ -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)

View File

@ -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:

View File

@ -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),

View File

@ -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),

View File

@ -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);

View File

@ -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),

View File

@ -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);

View File

@ -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
};

View File

@ -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);

View File

@ -270,4 +270,24 @@
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.hibernate</annotate>
</action>
<action id="org.freedesktop.login1.manage">
<_description>Manager active sessions, users and seats</_description>
<_message>Authentication is required for managing active sessions, users and seats.</_message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="org.freedesktop.login1.lock-sessions">
<_description>Lock or unlock active sessions</_description>
<_message>Authentication is required for locking or unlocking active sessions.</_message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
</policyconfig>

View File

@ -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)

View File

@ -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)

View File

@ -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)