From: Lennart Poettering Date: Sat, 11 May 2024 18:18:56 +0000 (+0200) Subject: machined: allow unprivileged registration of VMs/containers X-Git-Tag: v257-rc1~1062^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=38a7666df317b26a355a8c2e0332bd79312f30f6;p=thirdparty%2Fsystemd.git machined: allow unprivileged registration of VMs/containers Now that we have a concept of unprivileged VMs and containers, let's allow unprivileged clients to register with machined too – subject to Polkit permissions. --- diff --git a/src/machine/machine-varlink.c b/src/machine/machine-varlink.c index 6f437c06c4e..ea300d71dee 100644 --- a/src/machine/machine-varlink.c +++ b/src/machine/machine-varlink.c @@ -5,6 +5,7 @@ #include "sd-id128.h" #include "sd-json.h" +#include "bus-polkit.h" #include "hostname-util.h" #include "json-util.h" #include "machine-varlink.h" @@ -136,6 +137,7 @@ int vl_method_register(Varlink *link, sd_json_variant *parameters, VarlinkMethod { "vSockCid", SD_JSON_VARIANT_UNSIGNED, machine_cid, offsetof(Machine, vsock_cid), 0 }, { "sshAddress", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(Machine, ssh_address), SD_JSON_STRICT }, { "sshPrivateKeyPath", SD_JSON_VARIANT_STRING, json_dispatch_path, offsetof(Machine, ssh_private_key_path), 0 }, + VARLINK_DISPATCH_POLKIT_FIELD, {} }; @@ -147,6 +149,16 @@ int vl_method_register(Varlink *link, sd_json_variant *parameters, VarlinkMethod if (r != 0) return r; + r = varlink_verify_polkit_async( + link, + manager->bus, + "org.freedesktop.machine1.create-machine", + (const char**) STRV_MAKE("name", machine->name, + "class", machine_class_to_string(machine->class)), + &manager->polkit_registry); + if (r <= 0) + return r; + if (!pidref_is_set(&machine->leader)) { r = varlink_get_peer_pidref(link, &machine->leader); if (r < 0) diff --git a/src/machine/machined-varlink.c b/src/machine/machined-varlink.c index dc35877c497..bd092bb2827 100644 --- a/src/machine/machined-varlink.c +++ b/src/machine/machined-varlink.c @@ -433,7 +433,7 @@ static int manager_varlink_init_machine(Manager *m) { if (m->varlink_machine_server) return 0; - r = varlink_server_new(&s, VARLINK_SERVER_ROOT_ONLY|VARLINK_SERVER_INHERIT_USERDATA); + r = varlink_server_new(&s, VARLINK_SERVER_ACCOUNT_UID|VARLINK_SERVER_INHERIT_USERDATA); if (r < 0) return log_error_errno(r, "Failed to allocate varlink server object: %m"); diff --git a/src/machine/org.freedesktop.machine1.policy b/src/machine/org.freedesktop.machine1.policy index f031e4e4800..fe125ed0db3 100644 --- a/src/machine/org.freedesktop.machine1.policy +++ b/src/machine/org.freedesktop.machine1.policy @@ -91,6 +91,17 @@ org.freedesktop.login1.shell org.freedesktop.login1.login + + Create a local virtual machine or container + Authentication is required to create a local virtual machine or container. + + auth_admin + auth_admin + auth_admin_keep + + org.freedesktop.login1.shell org.freedesktop.login1.login + + Manage local virtual machine and container images Authentication is required to manage local virtual machine and container images. diff --git a/src/shared/varlink-io.systemd.Machine.c b/src/shared/varlink-io.systemd.Machine.c index 2d25a345d79..76eaf7d13c7 100644 --- a/src/shared/varlink-io.systemd.Machine.c +++ b/src/shared/varlink-io.systemd.Machine.c @@ -14,7 +14,9 @@ static VARLINK_DEFINE_METHOD( VARLINK_DEFINE_INPUT(ifIndices, VARLINK_INT, VARLINK_ARRAY|VARLINK_NULLABLE), VARLINK_DEFINE_INPUT(vSockCid, VARLINK_INT, VARLINK_NULLABLE), VARLINK_DEFINE_INPUT(sshAddress, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(sshPrivateKeyPath, VARLINK_STRING, VARLINK_NULLABLE)); + VARLINK_DEFINE_INPUT(sshPrivateKeyPath, VARLINK_STRING, VARLINK_NULLABLE), + VARLINK_FIELD_COMMENT("Whether to allow interactive authentication on this operation."), + VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, VARLINK_BOOL, VARLINK_NULLABLE)); static VARLINK_DEFINE_ERROR(MachineExists); diff --git a/src/vmspawn/vmspawn-register.c b/src/vmspawn/vmspawn-register.c index 2140bba9cd8..2130fd9108b 100644 --- a/src/vmspawn/vmspawn-register.c +++ b/src/vmspawn/vmspawn-register.c @@ -70,7 +70,8 @@ int register_machine( SD_JSON_BUILD_PAIR_CONDITION(VSOCK_CID_IS_REGULAR(cid), "vSockCid", SD_JSON_BUILD_UNSIGNED(cid)), SD_JSON_BUILD_PAIR_CONDITION(!!directory, "rootDirectory", SD_JSON_BUILD_STRING(directory)), SD_JSON_BUILD_PAIR_CONDITION(!!address, "sshAddress", SD_JSON_BUILD_STRING(address)), - SD_JSON_BUILD_PAIR_CONDITION(!!key_path, "sshPrivateKeyPath", SD_JSON_BUILD_STRING(key_path))); + SD_JSON_BUILD_PAIR_CONDITION(!!key_path, "sshPrivateKeyPath", SD_JSON_BUILD_STRING(key_path)), + SD_JSON_BUILD_PAIR_CONDITION(isatty(STDIN_FILENO), "allowInteractiveAuthentication", SD_JSON_BUILD_BOOLEAN(true))); } int unregister_machine(sd_bus *bus, const char *machine_name) { diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c index 73e165feadd..971844e10c7 100644 --- a/src/vmspawn/vmspawn.c +++ b/src/vmspawn/vmspawn.c @@ -2229,9 +2229,6 @@ static int verify_arguments(void) { if (!strv_isempty(arg_initrds) && !arg_linux) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --initrd= cannot be used without --linux=."); - if (arg_register && !arg_privileged) - return log_error_errno(SYNTHETIC_ERRNO(EPERM), "--register= requires root privileges, refusing."); - return 0; }