diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index c096a012d8..a9d15ca5f7 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -247,6 +247,25 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s assert(message); + if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) { + const char *details[] = { + "machine", m->name, + "verb", "get_os_release", + NULL + }; + + r = bus_verify_polkit_async( + message, + "org.freedesktop.machine1.inspect-machines", + details, + &m->manager->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Will call us back */ + } + r = machine_get_os_release(m, &l); if (r == -ENONET) return sd_bus_error_set(error, SD_BUS_ERROR_FAILED, "Machine does not contain OS release information."); diff --git a/src/machine/machined-varlink.c b/src/machine/machined-varlink.c index 4ab68a77f9..acc2137f83 100644 --- a/src/machine/machined-varlink.c +++ b/src/machine/machined-varlink.c @@ -535,6 +535,17 @@ static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varl if (r != 0) return r; + if (m->runtime_scope != RUNTIME_SCOPE_USER && should_acquire_metadata(p.acquire_metadata)) { + r = varlink_verify_polkit_async( + link, + m->system_bus, + "org.freedesktop.machine1.inspect-machines", + (const char**) STRV_MAKE("name", strna(p.name)), + &m->polkit_registry); + if (r <= 0) + return r; + } + r = sd_varlink_set_sentinel(link, VARLINK_ERROR_MACHINE_NO_SUCH_MACHINE); if (r < 0) return r; @@ -682,6 +693,17 @@ static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters, if (r != 0) return r; + if (m->runtime_scope != RUNTIME_SCOPE_USER && should_acquire_metadata(p.acquire_metadata)) { + r = varlink_verify_polkit_async( + link, + m->system_bus, + "org.freedesktop.machine1.inspect-images", + (const char**) STRV_MAKE("name", strna(p.image_name)), + &m->polkit_registry); + if (r <= 0) + return r; + } + r = sd_varlink_set_sentinel(link, VARLINK_ERROR_MACHINE_IMAGE_NO_SUCH_IMAGE); if (r < 0) return r; diff --git a/src/machine/org.freedesktop.machine1.policy b/src/machine/org.freedesktop.machine1.policy index d5b8d83d2a..f8f498f8cf 100644 --- a/src/machine/org.freedesktop.machine1.policy +++ b/src/machine/org.freedesktop.machine1.policy @@ -88,7 +88,17 @@ auth_admin auth_admin_keep - org.freedesktop.login1.shell org.freedesktop.login1.login + org.freedesktop.login1.shell org.freedesktop.login1.login org.freedesktop.machine1.inspect-machines + + + + Inspect local virtual machines and containers + Authentication is required to inspect local virtual machines and containers. + + auth_admin + auth_admin + auth_admin_keep + @@ -120,6 +130,17 @@ auth_admin auth_admin_keep + org.freedesktop.machine1.inspect-images + + + + Inspect local virtual machine and container images + Authentication is required to inspect local virtual machine and container images. + + auth_admin + auth_admin + auth_admin_keep + diff --git a/test/units/TEST-13-NSPAWN.unpriv.sh b/test/units/TEST-13-NSPAWN.unpriv.sh index 75a9c1aac0..e0516449c7 100755 --- a/test/units/TEST-13-NSPAWN.unpriv.sh +++ b/test/units/TEST-13-NSPAWN.unpriv.sh @@ -23,6 +23,8 @@ at_exit() { rm -rf /home/testuser/.local/state/machines/inodetest2 ||: rm -rf /home/testuser/.local/state/machines/mangletest ||: machinectl terminate zurps ||: + machinectl terminate exfiltrate ||: + systemctl --user --machine testuser@ stop exfiltrate.service ||: rm -f /etc/polkit-1/rules.d/registermachinetest.rules machinectl terminate nurps ||: machinectl terminate kurps ||: @@ -163,6 +165,28 @@ run0 -u testuser \ systemctl --user --machine testuser@ stop sleep.service test ! -f /shouldnotwork +echo FOO=bar >/tmp/foo +chmod 600 /tmp/foo +run0 -u testuser \ + systemd-run --unit exfiltrate.service --service-type notify --property NotifyAccess=all --user \ + unshare --map-root-user --user --mount \ + bash -c 'mount --bind /tmp/foo /usr/lib/os-release; systemd-notify --ready; exec sleep infinity' +exfiltrate_pid="$(systemctl --machine testuser@.host show --user -P MainPID exfiltrate.service)" +run0 -u testuser \ + varlinkctl \ + call \ + /run/systemd/machine/io.systemd.Machine \ + io.systemd.Machine.Register \ + "{\"name\":\"exfiltrate\", \"class\":\"container\", \"leader\": $exfiltrate_pid}" +exfiltrate_output="$(run0 -u testuser \ + varlinkctl \ + call \ + /run/systemd/machine/io.systemd.Machine io.systemd.Machine.List \ + "{\"name\":\"exfiltrate\",\"acquireMetadata\":\"graceful\"}" 2>&1)" || true +(! echo "$exfiltrate_output" | grep '"name".*"exfiltrate"' >/dev/null) +(! echo "$exfiltrate_output" | grep "FOO=bar" >/dev/null) +systemctl --user --machine testuser@ stop exfiltrate.service + run0 -u testuser mkdir /var/tmp/image-tar run0 -u testuser importctl --user export-tar zurps /var/tmp/image-tar/kurps.tar.gz -m run0 -u testuser importctl --user import-tar /var/tmp/image-tar/kurps.tar.gz -m