mirror of
https://github.com/systemd/systemd.git
synced 2026-06-30 19:57:29 +00:00
machined: allow privileged users to register other users machines
If a user is authenticated by polkit as admin then it should be
able to manage any resource on the system.
Follow-up for 119d332d9c
This commit is contained in:
@@ -126,6 +126,7 @@ static int machine_cid(const char *name, sd_json_variant *variant, sd_json_dispa
|
||||
int vl_method_register(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
Manager *manager = ASSERT_PTR(userdata);
|
||||
_cleanup_(machine_freep) Machine *machine = NULL;
|
||||
bool sender_is_admin = false;
|
||||
int r;
|
||||
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
@@ -160,13 +161,16 @@ int vl_method_register(sd_varlink *link, sd_json_variant *parameters, sd_varlink
|
||||
return sd_varlink_error_invalid_parameter_name(link, "class");
|
||||
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
r = varlink_verify_polkit_async(
|
||||
r = varlink_verify_polkit_async_full(
|
||||
link,
|
||||
manager->system_bus,
|
||||
machine->allocate_unit ? "org.freedesktop.machine1.create-machine" : "org.freedesktop.machine1.register-machine",
|
||||
(const char**) STRV_MAKE("name", machine->name,
|
||||
"class", machine_class_to_string(machine->class)),
|
||||
&manager->polkit_registry);
|
||||
/* good_user= */ UID_INVALID,
|
||||
/* flags= */ 0,
|
||||
&manager->polkit_registry,
|
||||
&sender_is_admin);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
@@ -196,7 +200,7 @@ int vl_method_register(sd_varlink *link, sd_json_variant *parameters, sd_varlink
|
||||
/* In system scope, ensure an unprivileged user cannot claim any process they don't
|
||||
* control as their own machine. In user scope the varlink socket is already
|
||||
* protected by $XDG_RUNTIME_DIR permissions. */
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER && machine->uid != 0) {
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER && machine->uid != 0 && !sender_is_admin) {
|
||||
r = process_is_owned_by_uid(&machine->leader, machine->uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -279,12 +279,33 @@ static int machine_add_from_params(
|
||||
/* Ensure an unprivileged user cannot claim any process they don't control as their own machine */
|
||||
switch (manager->runtime_scope) {
|
||||
|
||||
case RUNTIME_SCOPE_SYSTEM:
|
||||
/* In system mode root may register anything */
|
||||
if (uid == 0)
|
||||
case RUNTIME_SCOPE_SYSTEM: {
|
||||
const char *details[] = {
|
||||
"name", name,
|
||||
"class", machine_class_to_string(c),
|
||||
NULL
|
||||
};
|
||||
bool sender_is_admin = false;
|
||||
|
||||
r = bus_verify_polkit_async_full(
|
||||
message,
|
||||
polkit_action,
|
||||
details,
|
||||
/* good_user= */ UID_INVALID,
|
||||
/* flags= */ 0,
|
||||
&manager->polkit_registry,
|
||||
&sender_is_admin,
|
||||
error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 0; /* Will call us back */
|
||||
|
||||
/* In system mode root/admin may register anything */
|
||||
if (uid == 0 || sender_is_admin)
|
||||
break;
|
||||
|
||||
/* And non-root may only register things if they own the userns */
|
||||
/* And non-root/admin may only register things if they own the userns */
|
||||
r = process_is_owned_by_uid(leader_pidref, uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -292,7 +313,8 @@ static int machine_add_from_params(
|
||||
break;
|
||||
|
||||
/* Nothing else may */
|
||||
return sd_bus_error_set(error, SD_BUS_ERROR_ACCESS_DENIED, "Only root may register machines for other users");
|
||||
return sd_bus_error_set(error, SD_BUS_ERROR_ACCESS_DENIED, "Only privileged users may register machines for other users");
|
||||
}
|
||||
|
||||
case RUNTIME_SCOPE_USER:
|
||||
/* In user mode the user owning our instance may register anything. */
|
||||
@@ -306,23 +328,6 @@ static int machine_add_from_params(
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
const char *details[] = {
|
||||
"name", name,
|
||||
"class", machine_class_to_string(c),
|
||||
NULL
|
||||
};
|
||||
|
||||
r = bus_verify_polkit_async(
|
||||
message,
|
||||
polkit_action,
|
||||
details,
|
||||
&manager->polkit_registry,
|
||||
error);
|
||||
if (r <= 0)
|
||||
return r; /* 0 means Polkit will call us back, see method_create_machine() */
|
||||
}
|
||||
|
||||
r = manager_add_machine(manager, name, &m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user