]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
machined: allow running in --user mode
authorLennart Poettering <lennart@poettering.net>
Tue, 15 Jul 2025 10:15:19 +0000 (12:15 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 25 Sep 2025 20:43:59 +0000 (22:43 +0200)
15 files changed:
src/machine/image-dbus.c
src/machine/image-varlink.c
src/machine/machine-dbus.c
src/machine/machine-varlink.c
src/machine/machine.c
src/machine/machined-dbus.c
src/machine/machined-varlink.c
src/machine/machined.c
src/machine/machined.h
src/machine/meson.build
src/machine/org.freedesktop.machine1.service-for-session [new file with mode: 0644]
units/systemd-machined.service.in
units/user/meson.build
units/user/systemd-machined.service.in [new file with mode: 0644]
units/user/systemd-machined.socket [new file with mode: 0644]

index 8aa129fab7da79337b788ff9ac48ae43f7407bcd..41dfc8703edd9bd01147d9369a8e8f1221539d58 100644 (file)
@@ -40,22 +40,24 @@ int bus_image_method_remove(
         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");
@@ -101,23 +103,25 @@ int bus_image_method_rename(
         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)
@@ -150,23 +154,25 @@ int bus_image_method_clone(
         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");
@@ -208,23 +214,25 @@ int bus_image_method_mark_read_only(
         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)
@@ -251,22 +259,24 @@ int bus_image_method_set_limit(
         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)
index 8d61304741e86d633e6b96aeebbf8ea8498cf608..df9e765a6a5f8b09e7279dfe403833052482ee53 100644 (file)
@@ -66,15 +66,17 @@ int vl_method_update_image(sd_varlink *link, sd_json_variant *parameters, sd_var
         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);
@@ -139,16 +141,18 @@ int vl_method_clone_image(sd_varlink *link, sd_json_variant *parameters, sd_varl
         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");
@@ -207,15 +211,17 @@ int vl_method_remove_image(sd_varlink *link, sd_json_variant *parameters, sd_var
         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");
@@ -262,14 +268,16 @@ int vl_method_set_pool_limit(sd_varlink *link, sd_json_variant *parameters, sd_v
         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);
@@ -394,15 +402,17 @@ int vl_method_clean_pool(sd_varlink *link, sd_json_variant *parameters, sd_varli
         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);
index 388a584a12e2b967a3e0be56bdfa622ef4350e02..69159f4eb0e629c44790ff42070e1784dc27b090 100644 (file)
@@ -55,24 +55,26 @@ int bus_machine_method_unregister(sd_bus_message *message, void *userdata, sd_bu
 
         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)
@@ -87,24 +89,26 @@ int bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus
 
         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)
@@ -137,24 +141,26 @@ int bus_machine_method_kill(sd_bus_message *message, void *userdata, sd_bus_erro
         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)
@@ -260,23 +266,25 @@ int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_
 
         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)
@@ -302,24 +310,26 @@ int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bu
 
         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)
@@ -345,7 +355,6 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
         _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;
@@ -402,29 +411,32 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
         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)
@@ -470,25 +482,27 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
         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)
@@ -556,25 +570,27 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
         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");
 
@@ -602,23 +618,25 @@ int bus_machine_method_open_root_directory(sd_bus_message *message, void *userda
 
         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))
@@ -862,7 +880,7 @@ int machine_send_signal(Machine *m, bool new_machine) {
                 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",
index 5a2f67129e1c02554f3f8a698dd513ada2877cbc..1551608a68dcb21cafba31062295c483f8edadd7 100644 (file)
@@ -155,15 +155,17 @@ int vl_method_register(sd_varlink *link, sd_json_variant *parameters, sd_varlink
         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);
@@ -306,17 +308,19 @@ int vl_method_unregister_internal(sd_varlink *link, sd_json_variant *parameters,
         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)
@@ -330,17 +334,19 @@ int vl_method_terminate_internal(sd_varlink *link, sd_json_variant *parameters,
         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)
@@ -400,17 +406,19 @@ int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
                         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)
@@ -509,8 +517,8 @@ int vl_method_open(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
         };
         _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;
 
@@ -543,17 +551,21 @@ int vl_method_open(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
         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))
@@ -824,18 +836,20 @@ int vl_method_bind_mount(sd_varlink *link, sd_json_variant *parameters, sd_varli
         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)
@@ -936,18 +950,20 @@ int vl_method_copy_internal(sd_varlink *link, sd_json_variant *parameters, sd_va
         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);
@@ -967,15 +983,17 @@ int vl_method_open_root_directory_internal(sd_varlink *link, sd_json_variant *pa
         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))
index e651026fa9d5eb5a24fa44e0493f5cc52c70e90d..ff376c7047cee8a11ab8aaab7671c4f0760b1212 100644 (file)
@@ -88,7 +88,7 @@ int machine_link(Manager *manager, Machine *machine) {
                 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;
 
@@ -170,14 +170,14 @@ int machine_save(Machine *m) {
 
         _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;
@@ -267,7 +267,7 @@ static void machine_unlink(Machine *m) {
         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);
         }
 
@@ -438,7 +438,7 @@ static int machine_start_scope(
                 return log_oom();
 
         r = bus_message_new_method_call(
-                        machine->manager->bus,
+                        machine->manager->api_bus,
                         &m,
                         bus_systemd_mgr,
                         "StartTransientUnit");
@@ -920,7 +920,7 @@ int machine_start_getty(Machine *m, const char *ptmx_name, sd_bus_error *error)
         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");
@@ -966,7 +966,7 @@ int machine_start_shell(
         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;
index 182d3dd447f4c0d57c08d56d6c519a09bbda0b17..ec34cbac3658697c0c0eb452a9cb0daabc67eee0 100644 (file)
@@ -278,22 +278,24 @@ static int machine_add_from_params(
                         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)
@@ -697,7 +699,18 @@ static int method_register_machine(sd_bus_message *message, void *userdata, sd_b
         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",
@@ -983,22 +996,24 @@ static int method_clean_pool(sd_bus_message *message, void *userdata, sd_bus_err
         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)
@@ -1022,21 +1037,23 @@ static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus
         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);
@@ -1534,7 +1551,7 @@ int manager_unref_unit(
         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) {
@@ -1544,7 +1561,7 @@ int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, c
         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)) {
@@ -1582,9 +1599,9 @@ int manager_kill_unit(Manager *manager, const char *unit, const char *subgroup,
         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) {
@@ -1602,7 +1619,7 @@ int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *ret
                 return -ENOMEM;
 
         r = sd_bus_get_property(
-                        manager->bus,
+                        manager->api_bus,
                         "org.freedesktop.systemd1",
                         path,
                         "org.freedesktop.systemd1.Unit",
@@ -1638,7 +1655,7 @@ int manager_job_is_active(Manager *manager, const char *path, sd_bus_error *rete
         assert(path);
 
         r = sd_bus_get_property(
-                        manager->bus,
+                        manager->api_bus,
                         "org.freedesktop.systemd1",
                         path,
                         "org.freedesktop.systemd1.Job",
index 52b1fc12d290cdf7d32c85bf1ded906e6964e381..0756d985df263a508bc2fcc96d2f3433264a330a 100644 (file)
@@ -18,6 +18,7 @@
 #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"
@@ -733,6 +734,8 @@ static int manager_varlink_init_userdb(Manager *m) {
 
         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)
@@ -817,11 +820,20 @@ static int manager_varlink_init_machine(Manager *m) {
         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");
         }
index ea83f97ad96208a3d8fc7eacaa03ea6b83378f32..c6b13e6cbabc658fe9b3d52350924721a2ca0dce 100644 (file)
@@ -27,6 +27,7 @@
 #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"
@@ -38,7 +39,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_unref);
 
 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;
 
@@ -49,9 +50,13 @@ static int manager_new(Manager **ret) {
                 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;
@@ -105,9 +110,12 @@ static Manager* manager_unref(Manager *m) {
 
         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);
 }
 
@@ -118,6 +126,8 @@ static int manager_add_host_machine(Manager *m) {
         Machine *t;
         int r;
 
+        if (m->runtime_scope != RUNTIME_SCOPE_SYSTEM)
+                return 0;
         if (m->host_machine)
                 return 0;
 
@@ -174,12 +184,12 @@ static int manager_enumerate_machines(Manager *m) {
                 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) {
@@ -214,26 +224,45 @@ static int manager_connect_bus(Manager *m) {
         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,
@@ -243,26 +272,22 @@ static int manager_connect_bus(Manager *m) {
         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;
 }
 
@@ -315,6 +340,7 @@ static bool check_idle(void *userdata) {
 
 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);
@@ -324,7 +350,7 @@ static int run(int argc, char *argv[]) {
                                "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;
@@ -334,11 +360,12 @@ static int run(int argc, char *argv[]) {
         /* 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");
 
@@ -352,7 +379,7 @@ static int run(int argc, char *argv[]) {
 
         r = bus_event_loop_with_idle(
                         m->event,
-                        m->bus,
+                        m->api_bus,
                         "org.freedesktop.machine1",
                         DEFAULT_EXIT_USEC,
                         check_idle, m);
index d03577be3cbbae6ae9fb584d82c45f993b2de73b..483d41abedd623976a67a50415822783d90101a4 100644 (file)
@@ -7,7 +7,8 @@
 
 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
@@ -32,7 +33,8 @@ typedef struct Manager {
         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);
index 9370077fdccc1965ad0646f7c66a6a3cb848eb3c..8de7d7d2aea0c577c0408dec86498be48b3b3ada 100644 (file)
@@ -49,5 +49,8 @@ install_data('org.freedesktop.machine1.conf',
              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)
diff --git a/src/machine/org.freedesktop.machine1.service-for-session b/src/machine/org.freedesktop.machine1.service-for-session
new file mode 100644 (file)
index 0000000..44c2e24
--- /dev/null
@@ -0,0 +1,13 @@
+#  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
index 47aa5deeedc5f4399b970a91a54f7f58bb44b8bc..2dac42a673d8b974c6cea89305d107a60ba6540f 100644 (file)
@@ -11,7 +11,6 @@
 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
index d8d3d9fdac57427024f1ba1b33fe750e6d9571a8..7f04cf191cb3de805cf4cb0fa23b81ef706aa670 100644 (file)
@@ -18,6 +18,16 @@ units = [
           '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' },
diff --git a/units/user/systemd-machined.service.in b/units/user/systemd-machined.service.in
new file mode 100644 (file)
index 0000000..9f4208e
--- /dev/null
@@ -0,0 +1,28 @@
+#  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}}
diff --git a/units/user/systemd-machined.socket b/units/user/systemd-machined.socket
new file mode 100644 (file)
index 0000000..d368215
--- /dev/null
@@ -0,0 +1,18 @@
+#  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