if (m->n_operations >= OPERATIONS_MAX)
return sd_bus_error_set(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");
- const char *details[] = {
- "image", image->name,
- "verb", "remove",
- NULL
- };
-
- r = bus_verify_polkit_async(
- message,
- "org.freedesktop.machine1.manage-images",
- details,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "image", image->name,
+ "verb", "remove",
+ NULL
+ };
+
+ r = bus_verify_polkit_async(
+ message,
+ "org.freedesktop.machine1.manage-images",
+ details,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
if (!image_name_is_valid(new_name))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
- const char *details[] = {
- "image", image->name,
- "verb", "rename",
- "new_name", new_name,
- NULL
- };
-
- r = bus_verify_polkit_async(
- message,
- "org.freedesktop.machine1.manage-images",
- details,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "image", image->name,
+ "verb", "rename",
+ "new_name", new_name,
+ NULL
+ };
+
+ r = bus_verify_polkit_async(
+ message,
+ "org.freedesktop.machine1.manage-images",
+ details,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
r = rename_image_and_update_cache(m, image, new_name);
if (r < 0)
if (!image_name_is_valid(new_name))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
- const char *details[] = {
- "image", image->name,
- "verb", "clone",
- "new_name", new_name,
- NULL
- };
-
- r = bus_verify_polkit_async(
- message,
- "org.freedesktop.machine1.manage-images",
- details,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "image", image->name,
+ "verb", "clone",
+ "new_name", new_name,
+ NULL
+ };
+
+ r = bus_verify_polkit_async(
+ message,
+ "org.freedesktop.machine1.manage-images",
+ details,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
if (r < 0)
return r;
- const char *details[] = {
- "image", image->name,
- "verb", "mark_read_only",
- "read_only", one_zero(read_only),
- NULL
- };
-
- r = bus_verify_polkit_async(
- message,
- "org.freedesktop.machine1.manage-images",
- details,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "image", image->name,
+ "verb", "mark_read_only",
+ "read_only", one_zero(read_only),
+ NULL
+ };
+
+ r = bus_verify_polkit_async(
+ message,
+ "org.freedesktop.machine1.manage-images",
+ details,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
r = image_read_only(image, read_only);
if (r < 0)
if (!FILE_SIZE_VALID_OR_INFINITY(limit))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range");
- const char *details[] = {
- "machine", image->name,
- "verb", "set_limit",
- NULL
- };
-
- r = bus_verify_polkit_async(
- message,
- "org.freedesktop.machine1.manage-images",
- details,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "machine", image->name,
+ "verb", "set_limit",
+ NULL
+ };
+
+ r = bus_verify_polkit_async(
+ message,
+ "org.freedesktop.machine1.manage-images",
+ details,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
r = image_set_limit(image, limit);
if (r < 0)
if (r < 0)
return r;
- r = varlink_verify_polkit_async(
- link,
- manager->bus,
- "org.freedesktop.machine1.manage-images",
- (const char**) STRV_MAKE("image", image->name,
- "verb", "update"),
- &manager->polkit_registry);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = varlink_verify_polkit_async(
+ link,
+ manager->system_bus,
+ "org.freedesktop.machine1.manage-images",
+ (const char**) STRV_MAKE("image", image->name,
+ "verb", "update"),
+ &manager->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
if (p.new_name) {
r = rename_image_and_update_cache(manager, image, p.new_name);
if (r < 0)
return r;
- r = varlink_verify_polkit_async(
- link,
- manager->bus,
- "org.freedesktop.machine1.manage-images",
- (const char**) STRV_MAKE("image", image->name,
- "verb", "clone",
- "new_name", p.new_name),
- &manager->polkit_registry);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = varlink_verify_polkit_async(
+ link,
+ manager->system_bus,
+ "org.freedesktop.machine1.manage-images",
+ (const char**) STRV_MAKE("image", image->name,
+ "verb", "clone",
+ "new_name", p.new_name),
+ &manager->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return log_debug_errno(errno, "Failed to open pipe: %m");
if (r < 0)
return r;
- r = varlink_verify_polkit_async(
- link,
- manager->bus,
- "org.freedesktop.machine1.manage-images",
- (const char**) STRV_MAKE("image", image->name,
- "verb", "remove"),
- &manager->polkit_registry);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = varlink_verify_polkit_async(
+ link,
+ manager->system_bus,
+ "org.freedesktop.machine1.manage-images",
+ (const char**) STRV_MAKE("image", image->name,
+ "verb", "remove"),
+ &manager->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return log_debug_errno(errno, "Failed to open pipe: %m");
if (!FILE_SIZE_VALID_OR_INFINITY(limit))
return sd_varlink_error_invalid_parameter_name(link, "limit");
- r = varlink_verify_polkit_async(
- link,
- manager->bus,
- "org.freedesktop.machine1.manage-images",
- (const char**) STRV_MAKE("verb", "set_pool_limit"),
- &manager->polkit_registry);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = varlink_verify_polkit_async(
+ link,
+ manager->system_bus,
+ "org.freedesktop.machine1.manage-images",
+ (const char**) STRV_MAKE("verb", "set_pool_limit"),
+ &manager->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
/* Set up the machine directory if necessary */
r = setup_machine_directory(/* error = */ NULL, /* use_btrfs_subvol= */ true, /* use_btrfs_quota= */ true);
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL);
- r = varlink_verify_polkit_async(
- link,
- manager->bus,
- "org.freedesktop.machine1.manage-images",
- (const char**) STRV_MAKE("mode", image_clean_pool_mode_to_string(mode),
- "verb", "clean_pool"),
- &manager->polkit_registry);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = varlink_verify_polkit_async(
+ link,
+ manager->system_bus,
+ "org.freedesktop.machine1.manage-images",
+ (const char**) STRV_MAKE("mode", image_clean_pool_mode_to_string(mode),
+ "verb", "clean_pool"),
+ &manager->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
Operation *op;
r = image_clean_pool_operation(manager, mode, &op);
assert(message);
- const char *details[] = {
- "machine", m->name,
- "verb", "unregister",
- NULL
- };
-
- r = bus_verify_polkit_async_full(
- message,
- "org.freedesktop.machine1.manage-machines",
- details,
- m->uid,
- /* flags= */ 0,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "machine", m->name,
+ "verb", "unregister",
+ NULL
+ };
+
+ r = bus_verify_polkit_async_full(
+ message,
+ "org.freedesktop.machine1.manage-machines",
+ details,
+ m->uid,
+ /* flags= */ 0,
+ &m->manager->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
r = machine_finalize(m);
if (r < 0)
assert(message);
- const char *details[] = {
- "machine", m->name,
- "verb", "terminate",
- NULL
- };
-
- r = bus_verify_polkit_async_full(
- message,
- "org.freedesktop.machine1.manage-machines",
- details,
- m->uid,
- /* flags= */ 0,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "machine", m->name,
+ "verb", "terminate",
+ NULL
+ };
+
+ r = bus_verify_polkit_async_full(
+ message,
+ "org.freedesktop.machine1.manage-machines",
+ details,
+ m->uid,
+ /* flags= */ 0,
+ &m->manager->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
r = machine_stop(m);
if (r < 0)
if (!SIGNAL_VALID(signo))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
- const char *details[] = {
- "machine", m->name,
- "verb", "kill",
- NULL
- };
-
- r = bus_verify_polkit_async_full(
- message,
- "org.freedesktop.machine1.manage-machines",
- details,
- m->uid,
- /* flags= */ 0,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "machine", m->name,
+ "verb", "kill",
+ NULL
+ };
+
+ r = bus_verify_polkit_async_full(
+ message,
+ "org.freedesktop.machine1.manage-machines",
+ details,
+ m->uid,
+ /* flags= */ 0,
+ &m->manager->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
r = machine_kill(m, whom, signo);
if (r < 0)
assert(message);
- const char *details[] = {
- "machine", m->name,
- NULL
- };
-
- r = bus_verify_polkit_async_full(
- message,
- m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-open-pty" : "org.freedesktop.machine1.open-pty",
- details,
- m->uid,
- /* flags= */ 0,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "machine", m->name,
+ NULL
+ };
+
+ r = bus_verify_polkit_async_full(
+ message,
+ m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-open-pty" : "org.freedesktop.machine1.open-pty",
+ details,
+ m->uid,
+ /* flags= */ 0,
+ &m->manager->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name);
if (master < 0)
assert(message);
- const char *details[] = {
- "machine", m->name,
- "verb", "login",
- NULL
- };
-
- r = bus_verify_polkit_async_full(
- message,
- m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-login" : "org.freedesktop.machine1.login",
- details,
- m->uid,
- /* flags= */ 0,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "machine", m->name,
+ "verb", "login",
+ NULL
+ };
+
+ r = bus_verify_polkit_async_full(
+ message,
+ m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-login" : "org.freedesktop.machine1.login",
+ details,
+ m->uid,
+ /* flags= */ 0,
+ &m->manager->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name);
if (master < 0)
_cleanup_free_ char *pty_name = NULL;
_cleanup_close_ int master = -EBADF;
_cleanup_strv_free_ char **env = NULL, **args_wire = NULL, **args = NULL;
- _cleanup_free_ char *command_line = NULL;
Machine *m = ASSERT_PTR(userdata);
const char *user, *path;
int r;
if (!strv_env_is_valid(env))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
- command_line = strv_join(args, " ");
- if (!command_line)
- return -ENOMEM;
- const char *details[] = {
- "machine", m->name,
- "user", user,
- "program", path,
- "command_line", command_line,
- NULL
- };
-
- r = bus_verify_polkit_async_full(
- message,
- m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-shell" : "org.freedesktop.machine1.shell",
- details,
- m->uid,
- /* flags= */ 0,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ _cleanup_free_ char *command_line = strv_join(args, " ");
+ if (!command_line)
+ return -ENOMEM;
+
+ const char *details[] = {
+ "machine", m->name,
+ "user", user,
+ "program", path,
+ "command_line", command_line,
+ NULL
+ };
+
+ r = bus_verify_polkit_async_full(
+ message,
+ m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-shell" : "org.freedesktop.machine1.shell",
+ details,
+ m->uid,
+ /* flags= */ 0,
+ &m->manager->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name);
if (master < 0)
else if (!path_is_absolute(dest) || !path_is_normalized(dest))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute and normalized.");
- const char *details[] = {
- "machine", m->name,
- "verb", "bind",
- "src", src,
- "dest", dest,
- NULL
- };
-
- /* NB: For now not opened up to owner of machine without auth */
- r = bus_verify_polkit_async(
- message,
- "org.freedesktop.machine1.manage-machines",
- details,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "machine", m->name,
+ "verb", "bind",
+ "src", src,
+ "dest", dest,
+ NULL
+ };
+
+ /* NB: For now not opened up to owner of machine without auth */
+ r = bus_verify_polkit_async(
+ message,
+ "org.freedesktop.machine1.manage-machines",
+ details,
+ &m->manager->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
r = machine_get_uid_shift(m, &uid);
if (r < 0)
else if (!path_is_absolute(dest))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute.");
- const char *details[] = {
- "machine", m->name,
- "verb", "copy",
- "src", src,
- "dest", dest,
- NULL
- };
-
- /* NB: For now not opened up to owner of machine without auth */
- r = bus_verify_polkit_async(
- message,
- "org.freedesktop.machine1.manage-machines",
- details,
- &manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "machine", m->name,
+ "verb", "copy",
+ "src", src,
+ "dest", dest,
+ NULL
+ };
+
+ /* NB: For now not opened up to owner of machine without auth */
+ r = bus_verify_polkit_async(
+ message,
+ "org.freedesktop.machine1.manage-machines",
+ details,
+ &manager->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
copy_from = strstr(sd_bus_message_get_member(message), "CopyFrom");
assert(message);
- const char *details[] = {
- "machine", m->name,
- "verb", "open_root_directory",
- NULL
- };
-
- /* NB: For now not opened up to owner of machine without auth */
- r = bus_verify_polkit_async(
- message,
- "org.freedesktop.machine1.manage-machines",
- details,
- &m->manager->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "machine", m->name,
+ "verb", "open_root_directory",
+ NULL
+ };
+
+ /* NB: For now not opened up to owner of machine without auth */
+ r = bus_verify_polkit_async(
+ message,
+ "org.freedesktop.machine1.manage-machines",
+ details,
+ &m->manager->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
fd = machine_open_root_directory(m);
if (ERRNO_IS_NEG_NOT_SUPPORTED(fd))
return -ENOMEM;
return sd_bus_emit_signal(
- m->manager->bus,
+ m->manager->api_bus,
"/org/freedesktop/machine1",
"org.freedesktop.machine1.Manager",
new_machine ? "MachineNew" : "MachineRemoved",
if (r != 0)
return r;
- r = varlink_verify_polkit_async(
- link,
- manager->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);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = varlink_verify_polkit_async(
+ 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);
+ if (r <= 0)
+ return r;
+ }
if (!pidref_is_set(&machine->leader)) {
r = varlink_get_peer_pidref(link, &machine->leader);
Manager *manager = ASSERT_PTR(machine->manager);
int r;
- r = varlink_verify_polkit_async_full(
- link,
- manager->bus,
- "org.freedesktop.machine1.manage-machines",
- (const char**) STRV_MAKE("name", machine->name,
- "verb", "unregister"),
- machine->uid,
- /* flags= */ 0,
- &manager->polkit_registry);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = varlink_verify_polkit_async_full(
+ link,
+ manager->system_bus,
+ "org.freedesktop.machine1.manage-machines",
+ (const char**) STRV_MAKE("name", machine->name,
+ "verb", "unregister"),
+ machine->uid,
+ /* flags= */ 0,
+ &manager->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
r = machine_finalize(machine);
if (r < 0)
Manager *manager = ASSERT_PTR(machine->manager);
int r;
- r = varlink_verify_polkit_async_full(
- link,
- manager->bus,
- "org.freedesktop.machine1.manage-machines",
- (const char**) STRV_MAKE("name", machine->name,
- "verb", "terminate"),
- machine->uid,
- /* flags= */ 0,
- &manager->polkit_registry);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = varlink_verify_polkit_async_full(
+ link,
+ manager->system_bus,
+ "org.freedesktop.machine1.manage-machines",
+ (const char**) STRV_MAKE("name", machine->name,
+ "verb", "terminate"),
+ machine->uid,
+ /* flags= */ 0,
+ &manager->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
r = machine_stop(machine);
if (r < 0)
return sd_varlink_error_invalid_parameter_name(link, "whom");
}
- r = varlink_verify_polkit_async_full(
- link,
- manager->bus,
- "org.freedesktop.machine1.manage-machines",
- (const char**) STRV_MAKE("name", machine->name,
- "verb", "kill"),
- machine->uid,
- /* flags= */ 0,
- &manager->polkit_registry);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = varlink_verify_polkit_async_full(
+ link,
+ manager->system_bus,
+ "org.freedesktop.machine1.manage-machines",
+ (const char**) STRV_MAKE("name", machine->name,
+ "verb", "kill"),
+ machine->uid,
+ /* flags= */ 0,
+ &manager->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
r = machine_kill(machine, whom, p.signo);
if (r < 0)
};
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
_cleanup_free_ char *ptmx_name = NULL, *command_line = NULL;
- _cleanup_strv_free_ char **polkit_details = NULL, **args = NULL;
const char *user = NULL, *path = NULL; /* gcc complains about uninitialized variables */
+ _cleanup_strv_free_ char **args = NULL;
Machine *machine;
int r, ptmx_fd_idx;
if (r < 0)
return r;
- polkit_details = machine_open_polkit_details(p.mode, machine->name, user, path, command_line);
- r = varlink_verify_polkit_async_full(
- link,
- manager->bus,
- machine_open_polkit_action(p.mode, machine->class),
- (const char**) polkit_details,
- machine->uid,
- /* flags= */ 0,
- &manager->polkit_registry);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ _cleanup_strv_free_ char **polkit_details = NULL;
+
+ polkit_details = machine_open_polkit_details(p.mode, machine->name, user, path, command_line);
+ r = varlink_verify_polkit_async_full(
+ link,
+ manager->system_bus,
+ machine_open_polkit_action(p.mode, machine->class),
+ (const char**) polkit_details,
+ machine->uid,
+ /* flags= */ 0,
+ &manager->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
ptmx_fd = machine_openpt(machine, O_RDWR|O_NOCTTY|O_CLOEXEC, &ptmx_name);
if (ERRNO_IS_NEG_NOT_SUPPORTED(ptmx_fd))
if (machine->class != MACHINE_CONTAINER)
return sd_varlink_error(link, VARLINK_ERROR_MACHINE_NOT_SUPPORTED, NULL);
- /* NB: For now not opened up to owner of machine without auth */
- r = varlink_verify_polkit_async(
- link,
- manager->bus,
- "org.freedesktop.machine1.manage-machines",
- (const char**) STRV_MAKE("name", machine->name,
- "verb", "bind",
- "src", p.src,
- "dest", dest),
- &manager->polkit_registry);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ /* NB: For now not opened up to owner of machine without auth */
+ r = varlink_verify_polkit_async(
+ link,
+ manager->system_bus,
+ "org.freedesktop.machine1.manage-machines",
+ (const char**) STRV_MAKE("name", machine->name,
+ "verb", "bind",
+ "src", p.src,
+ "dest", dest),
+ &manager->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
r = machine_get_uid_shift(machine, &uid_shift);
if (r < 0)
if (machine->class != MACHINE_CONTAINER)
return sd_varlink_error(link, VARLINK_ERROR_MACHINE_NOT_SUPPORTED, NULL);
- /* NB: For now not opened up to owner of machine without auth */
- r = varlink_verify_polkit_async(
- link,
- manager->bus,
- "org.freedesktop.machine1.manage-machines",
- (const char**) STRV_MAKE("name", machine->name,
- "verb", "copy",
- "src", p.src,
- "dest", dest),
- &manager->polkit_registry);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ /* NB: For now not opened up to owner of machine without auth */
+ r = varlink_verify_polkit_async(
+ link,
+ manager->system_bus,
+ "org.freedesktop.machine1.manage-machines",
+ (const char**) STRV_MAKE("name", machine->name,
+ "verb", "copy",
+ "src", p.src,
+ "dest", dest),
+ &manager->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
Operation *op;
r = machine_copy_from_to_operation(manager, machine, host_path, container_path, copy_from, copy_flags, &op);
int r;
/* NB: For now not opened up to owner of machine without auth */
- r = varlink_verify_polkit_async(
- link,
- manager->bus,
- "org.freedesktop.machine1.manage-machines",
- (const char**) STRV_MAKE("name", machine->name,
- "verb", "open_root_directory"),
- &manager->polkit_registry);
- if (r <= 0)
- return r;
+ if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
+ r = varlink_verify_polkit_async(
+ link,
+ manager->system_bus,
+ "org.freedesktop.machine1.manage-machines",
+ (const char**) STRV_MAKE("name", machine->name,
+ "verb", "open_root_directory"),
+ &manager->polkit_registry);
+ if (r <= 0)
+ return r;
+ }
fd = machine_open_root_directory(machine);
if (ERRNO_IS_NEG_NOT_SUPPORTED(fd))
return -EINVAL;
if (machine->class != MACHINE_HOST) {
- char *temp = path_join("/run/systemd/machines", machine->name);
+ char *temp = path_join(manager->state_dir, machine->name);
if (!temp)
return -ENOMEM;
_cleanup_(unlink_and_freep) char *sl = NULL; /* auto-unlink! */
if (m->unit && !m->subgroup) {
- sl = strjoin("/run/systemd/machines/unit:", m->unit);
+ sl = strjoin(m->manager->state_dir, "/unit:", m->unit);
if (!sl)
return log_oom();
}
- r = mkdir_safe_label("/run/systemd/machines", 0755, 0, 0, MKDIR_WARN_MODE);
+ r = mkdir_safe_label(m->manager->state_dir, 0755, 0, 0, MKDIR_WARN_MODE);
if (r < 0)
- return log_error_errno(r, "Failed to create /run/systemd/machines/: %m");
+ return log_error_errno(r, "Failed to create '%s': %m", m->manager->state_dir);
_cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
assert(m);
if (m->unit && !m->subgroup) {
- const char *sl = strjoina("/run/systemd/machines/unit:", m->unit);
+ const char *sl = strjoina(m->manager->state_dir, "/unit:", m->unit);
(void) unlink(sl);
}
return log_oom();
r = bus_message_new_method_call(
- machine->manager->bus,
+ machine->manager->api_bus,
&m,
bus_systemd_mgr,
"StartTransientUnit");
if (r < 0)
return log_debug_errno(r, "Failed to create DBus to machine: %m");
- container_bus = allocated_bus ?: m->manager->bus;
+ container_bus = allocated_bus ?: m->manager->system_bus;
getty = strjoina("container-getty@", p, ".service");
r = bus_call_method(container_bus, bus_systemd_mgr, "StartUnit", error, /* ret_reply = */ NULL, "ss", getty, "replace");
if (r < 0)
return log_debug_errno(r, "Failed to create DBus to machine: %m");
- container_bus = allocated_bus ?: m->manager->bus;
+ container_bus = allocated_bus ?: m->manager->system_bus;
r = bus_message_new_method_call(container_bus, &tm, bus_systemd_mgr, "StartTransientUnit");
if (r < 0)
return r;
return sd_bus_error_set(error, SD_BUS_ERROR_ACCESS_DENIED, "Only root may register machines for other users");
}
- 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;
- if (r == 0)
- return 0; /* Will call us back */
+ 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;
+ if (r == 0)
+ return 0; /* Will call us back */
+ }
r = manager_add_machine(manager, name, &m);
if (r < 0)
if (r == 0)
return 1; /* Will call us back */
- r = cg_pidref_get_unit_full(&m->leader, &m->unit, &m->subgroup);
+ switch (manager->runtime_scope) {
+ case RUNTIME_SCOPE_USER:
+ r = cg_pidref_get_user_unit_full(&m->leader, &m->unit, &m->subgroup);
+ break;
+
+ case RUNTIME_SCOPE_SYSTEM:
+ r = cg_pidref_get_unit_full(&m->leader, &m->unit, &m->subgroup);
+ break;
+
+ default:
+ assert_not_reached();
+ }
if (r < 0) {
r = sd_bus_error_set_errnof(error, r,
"Failed to determine unit of process "PID_FMT" : %m",
else
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mode '%s'.", mm);
- const char *details[] = {
- "verb", "clean_pool",
- "mode", mm,
- NULL
- };
-
- r = bus_verify_polkit_async(
- message,
- "org.freedesktop.machine1.manage-machines",
- details,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "verb", "clean_pool",
+ "mode", mm,
+ NULL
+ };
+
+ r = bus_verify_polkit_async(
+ message,
+ "org.freedesktop.machine1.manage-machines",
+ details,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
r = image_clean_pool_operation(m, mode, &operation);
if (r < 0)
if (!FILE_SIZE_VALID_OR_INFINITY(limit))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range");
- const char *details[] = {
- "verb", "set_pool_limit",
- NULL
- };
-
- r = bus_verify_polkit_async(
- message,
- "org.freedesktop.machine1.manage-machines",
- details,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* Will call us back */
+ if (m->runtime_scope != RUNTIME_SCOPE_USER) {
+ const char *details[] = {
+ "verb", "set_pool_limit",
+ NULL
+ };
+
+ r = bus_verify_polkit_async(
+ message,
+ "org.freedesktop.machine1.manage-machines",
+ details,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* Will call us back */
+ }
/* Set up the machine directory if necessary */
r = setup_machine_directory(error, /* use_btrfs_subvol= */ true, /* use_btrfs_quota= */ true);
assert(m);
assert(unit);
- return bus_call_method(m->bus, bus_systemd_mgr, "UnrefUnit", error, NULL, "s", unit);
+ return bus_call_method(m->api_bus, bus_systemd_mgr, "UnrefUnit", error, NULL, "s", unit);
}
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
assert(manager);
assert(unit);
- r = bus_call_method(manager->bus, bus_systemd_mgr, "StopUnit", error, &reply, "ss", unit, "fail");
+ r = bus_call_method(manager->api_bus, bus_systemd_mgr, "StopUnit", error, &reply, "ss", unit, "fail");
if (r < 0) {
if (sd_bus_error_has_names(error, BUS_ERROR_NO_SUCH_UNIT,
BUS_ERROR_LOAD_FAILED)) {
assert(unit);
if (empty_or_root(subgroup))
- return bus_call_method(manager->bus, bus_systemd_mgr, "KillUnit", reterr_error, NULL, "ssi", unit, "all", signo);
+ return bus_call_method(manager->api_bus, bus_systemd_mgr, "KillUnit", reterr_error, NULL, "ssi", unit, "all", signo);
- return bus_call_method(manager->bus, bus_systemd_mgr, "KillUnitSubgroup", reterr_error, NULL, "sssi", unit, "cgroup", subgroup, signo);
+ return bus_call_method(manager->api_bus, bus_systemd_mgr, "KillUnitSubgroup", reterr_error, NULL, "sssi", unit, "cgroup", subgroup, signo);
}
int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *reterr_error) {
return -ENOMEM;
r = sd_bus_get_property(
- manager->bus,
+ manager->api_bus,
"org.freedesktop.systemd1",
path,
"org.freedesktop.systemd1.Unit",
assert(path);
r = sd_bus_get_property(
- manager->bus,
+ manager->api_bus,
"org.freedesktop.systemd1",
path,
"org.freedesktop.systemd1.Job",
#include "machine-varlink.h"
#include "machined.h"
#include "machined-varlink.h"
+#include "path-lookup.h"
#include "string-util.h"
#include "strv.h"
#include "user-util.h"
if (m->varlink_userdb_server)
return 0;
+ if (m->runtime_scope != RUNTIME_SCOPE_SYSTEM) /* no userdb in per-user mode! */
+ return 0;
r = varlink_server_new(&s, SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA, m);
if (r < 0)
if (r < 0)
return log_error_errno(r, "Failed to bind to passed Varlink sockets: %m");
if (r == 0) {
- r = sd_varlink_server_listen_address(s, "/run/systemd/machine/io.systemd.Machine", 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
+ _cleanup_free_ char *socket_path = NULL;
+ r = runtime_directory_generic(m->runtime_scope, "systemd/machine/io.systemd.Machine", &socket_path);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine socket path: %m");
+
+ r = sd_varlink_server_listen_address(s, socket_path, runtime_scope_to_socket_mode(m->runtime_scope) | SD_VARLINK_SERVER_MODE_MKDIR_0755);
if (r < 0)
return log_error_errno(r, "Failed to bind to io.systemd.Machine varlink socket: %m");
- r = sd_varlink_server_listen_address(s, "/run/systemd/machine/io.systemd.MachineImage", 0666);
+ socket_path = mfree(socket_path);
+ r = runtime_directory_generic(m->runtime_scope, "systemd/machine/io.systemd.MachineImage", &socket_path);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine socket path: %m");
+ r = sd_varlink_server_listen_address(s, socket_path, runtime_scope_to_socket_mode(m->runtime_scope));
if (r < 0)
return log_error_errno(r, "Failed to bind to io.systemd.MachineImage varlink socket: %m");
}
#include "main-func.h"
#include "mkdir-label.h"
#include "operation.h"
+#include "path-lookup.h"
#include "service-util.h"
#include "signal-util.h"
#include "socket-util.h"
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(machine_hash_ops, char, string_hash_func, string_compare_func, Machine, machine_free);
-static int manager_new(Manager **ret) {
+static int manager_new(RuntimeScope scope, Manager **ret) {
_cleanup_(manager_unrefp) Manager *m = NULL;
int r;
return -ENOMEM;
*m = (Manager) {
- .runtime_scope = RUNTIME_SCOPE_SYSTEM,
+ .runtime_scope = scope,
};
+ r = runtime_directory_generic(scope, "systemd/machines", &m->state_dir);
+ if (r < 0)
+ return r;
+
m->machines = hashmap_new(&machine_hash_ops);
if (!m->machines)
return -ENOMEM;
manager_varlink_done(m);
- sd_bus_flush_close_unref(m->bus);
+ sd_bus_flush_close_unref(m->api_bus);
+ sd_bus_flush_close_unref(m->system_bus);
sd_event_unref(m->event);
+ free(m->state_dir);
+
return mfree(m);
}
Machine *t;
int r;
+ if (m->runtime_scope != RUNTIME_SCOPE_SYSTEM)
+ return 0;
if (m->host_machine)
return 0;
return r;
/* Read in machine data stored on disk */
- d = opendir("/run/systemd/machines");
+ d = opendir(m->state_dir);
if (!d) {
if (errno == ENOENT)
return 0;
- return log_error_errno(errno, "Failed to open %s: %m", "/run/systemd/machines");
+ return log_error_errno(errno, "Failed to open '%s': %m", m->state_dir);
}
FOREACH_DIRENT(de, d, return -errno) {
int r;
assert(m);
- assert(!m->bus);
+ assert(!m->system_bus);
+ assert(!m->api_bus);
- r = sd_bus_default_system(&m->bus);
+ r = sd_bus_default_system(&m->system_bus);
if (r < 0)
return log_error_errno(r, "Failed to connect to system bus: %m");
- r = bus_add_implementation(m->bus, &manager_object, m);
+ r = sd_bus_attach_event(m->system_bus, m->event, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to attach system bus to event loop: %m");
+
+ if (m->runtime_scope == RUNTIME_SCOPE_SYSTEM)
+ m->api_bus = sd_bus_ref(m->system_bus);
+ else {
+ assert(m->runtime_scope == RUNTIME_SCOPE_USER);
+
+ r = sd_bus_default_user(&m->api_bus);
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to user bus: %m");
+
+ r = sd_bus_attach_event(m->api_bus, m->event, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to attach user bus to event loop: %m");
+ }
+
+ r = bus_add_implementation(m->api_bus, &manager_object, m);
if (r < 0)
return r;
- r = bus_match_signal_async(m->bus, NULL, bus_systemd_mgr, "JobRemoved", match_job_removed, NULL, m);
+ r = bus_match_signal_async(m->api_bus, NULL, bus_systemd_mgr, "JobRemoved", match_job_removed, NULL, m);
if (r < 0)
return log_error_errno(r, "Failed to add match for JobRemoved: %m");
- r = bus_match_signal_async(m->bus, NULL, bus_systemd_mgr, "UnitRemoved", match_unit_removed, NULL, m);
+ r = bus_match_signal_async(m->api_bus, NULL, bus_systemd_mgr, "UnitRemoved", match_unit_removed, NULL, m);
if (r < 0)
return log_error_errno(r, "Failed to request match for UnitRemoved: %m");
r = sd_bus_match_signal_async(
- m->bus,
+ m->api_bus,
NULL,
"org.freedesktop.systemd1",
NULL,
if (r < 0)
return log_error_errno(r, "Failed to request match for PropertiesChanged: %m");
- r = bus_match_signal_async(m->bus, NULL, bus_systemd_mgr, "Reloading", match_reloading, NULL, m);
+ r = bus_match_signal_async(m->api_bus, NULL, bus_systemd_mgr, "Reloading", match_reloading, NULL, m);
if (r < 0)
return log_error_errno(r, "Failed to request match for Reloading: %m");
- r = bus_call_method_async(m->bus, NULL, bus_systemd_mgr, "Subscribe", NULL, NULL, NULL);
+ r = bus_call_method_async(m->api_bus, NULL, bus_systemd_mgr, "Subscribe", NULL, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Failed to enable subscription: %m");
- r = bus_log_control_api_register(m->bus);
+ r = bus_log_control_api_register(m->api_bus);
if (r < 0)
return r;
- r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.machine1", 0, NULL, NULL);
+ r = sd_bus_request_name_async(m->api_bus, NULL, "org.freedesktop.machine1", 0, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Failed to request name: %m");
- r = sd_bus_attach_event(m->bus, m->event, 0);
- if (r < 0)
- return log_error_errno(r, "Failed to attach bus to event loop: %m");
-
return 0;
}
static int run(int argc, char *argv[]) {
_cleanup_(manager_unrefp) Manager *m = NULL;
+ RuntimeScope scope = RUNTIME_SCOPE_SYSTEM;
int r;
log_set_facility(LOG_AUTH);
"Manage registrations of local VMs and containers.",
BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object),
- /* runtime_scope= */ NULL,
+ &scope,
argc, argv);
if (r <= 0)
return r;
/* Always create the directories people can create inotify watches in. Note that some applications might check
* for the existence of /run/systemd/machines/ to determine whether machined is available, so please always
* make sure this check stays in. */
- (void) mkdir_label("/run/systemd/machines", 0755);
+ if (scope == RUNTIME_SCOPE_SYSTEM)
+ (void) mkdir_label("/run/systemd/machines", 0755);
assert_se(sigprocmask_many(SIG_BLOCK, /* ret_old_mask= */ NULL, SIGCHLD) >= 0);
- r = manager_new(&m);
+ r = manager_new(scope, &m);
if (r < 0)
return log_error_errno(r, "Failed to allocate manager object: %m");
r = bus_event_loop_with_idle(
m->event,
- m->bus,
+ m->api_bus,
"org.freedesktop.machine1",
DEFAULT_EXIT_USEC,
check_idle, m);
typedef struct Manager {
sd_event *event;
- sd_bus *bus;
+ sd_bus *api_bus; /* this is where we offer our services */
+ sd_bus *system_bus; /* this is where we talk to system services on, for example PK or so */
Hashmap *machines;
Hashmap *machines_by_unit; /* This hashmap only tracks machines where a system-level encapsulates
sd_varlink_server *varlink_userdb_server;
sd_varlink_server *varlink_machine_server;
- RuntimeScope runtime_scope; /* for now: always RUNTIME_SCOPE_SYSTEM */
+ RuntimeScope runtime_scope;
+ char *state_dir;
} Manager;
int manager_add_machine(Manager *m, const char *name, Machine **ret);
install_dir : dbuspolicydir)
install_data('org.freedesktop.machine1.service',
install_dir : dbussystemservicedir)
+install_data('org.freedesktop.machine1.service-for-session',
+ install_dir : dbussessionservicedir,
+ rename : 'org.freedesktop.machine1.service')
install_data('org.freedesktop.machine1.policy',
install_dir : polkitpolicydir)
--- /dev/null
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[D-BUS Service]
+Name=org.freedesktop.machine1
+Exec=/bin/false
+SystemdService=dbus-org.freedesktop.machine1.service
Description=Virtual Machine and Container Registration Service
Documentation=man:systemd-machined.service(8)
Documentation=man:org.freedesktop.machine1(5)
-
Wants=machine.slice
After=machine.slice
RequiresMountsFor=/var/lib/machines
'file' : 'machines.target',
'conditions' : ['ENABLE_MACHINED'],
},
+ {
+ 'file' : 'systemd-machined.service.in',
+ 'conditions' : ['ENABLE_MACHINED'],
+ 'symlinks' : ['dbus-org.freedesktop.machine1.service'],
+ },
+ {
+ 'file' : 'systemd-machined.socket',
+ 'conditions' : ['ENABLE_MACHINED'],
+ 'symlinks' : ['sockets.target.wants/'],
+ },
{ 'file' : 'paths.target' },
{ 'file' : 'printer.target' },
{ 'file' : 'session.slice' },
--- /dev/null
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Virtual Machine and Container Registration Service
+Documentation=man:systemd-machined.service(8)
+Documentation=man:org.freedesktop.machine1(5)
+Wants=machine.slice
+After=machine.slice
+
+[Service]
+BusName=org.freedesktop.machine1
+ExecStart={{LIBEXECDIR}}/systemd-machined --user
+LockPersonality=yes
+MemoryDenyWriteExecute=yes
+NoNewPrivileges=yes
+RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
+RestrictRealtime=yes
+SystemCallArchitectures=native
+SystemCallErrorNumber=EPERM
+SystemCallFilter=@system-service @mount
+{{SERVICE_WATCHDOG}}
--- /dev/null
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Virtual Machine and Container Registration Service Socket
+Documentation=man:systemd-machined.service(8)
+
+[Socket]
+ListenStream=%t/systemd/machine/io.systemd.Machine
+ListenStream=%t/systemd/machine/io.systemd.MachineImage
+FileDescriptorName=varlink
+SocketMode=0600