#include "format-util.h"
#include "fs-util.h"
#include "in-addr-util.h"
-#include "io-util.h"
+#include "iovec-util.h"
#include "local-addresses.h"
#include "machine-dbus.h"
#include "machine.h"
r = bus_verify_polkit_async(
message,
- CAP_KILL,
"org.freedesktop.machine1.manage-machines",
details,
- false,
- UID_INVALID,
&m->manager->polkit_registry,
error);
if (r < 0)
r = bus_verify_polkit_async(
message,
- CAP_KILL,
"org.freedesktop.machine1.manage-machines",
details,
- false,
- UID_INVALID,
&m->manager->polkit_registry,
error);
if (r < 0)
r = bus_verify_polkit_async(
message,
- CAP_KILL,
"org.freedesktop.machine1.manage-machines",
details,
- false,
- UID_INVALID,
&m->manager->polkit_registry,
error);
if (r < 0)
}
case MACHINE_CONTAINER: {
- _cleanup_close_pair_ int pair[2] = { -1, -1 };
+ _cleanup_close_pair_ int pair[2] = EBADF_PAIR;
_cleanup_free_ char *us = NULL, *them = NULL;
- _cleanup_close_ int netns_fd = -1;
+ _cleanup_close_ int netns_fd = -EBADF;
const char *p;
pid_t child;
if (r < 0)
return r;
- p = procfs_file_alloca(m->leader, "ns/net");
+ p = procfs_file_alloca(m->leader.pid, "ns/net");
r = readlink_malloc(p, &them);
if (r < 0)
return r;
if (streq(us, them))
return sd_bus_error_setf(error, BUS_ERROR_NO_PRIVATE_NETWORKING, "Machine %s does not use private networking", m->name);
- r = namespace_open(m->leader, NULL, NULL, &netns_fd, NULL, NULL);
+ r = namespace_open(m->leader.pid,
+ /* ret_pidns_fd = */ NULL,
+ /* ret_mntns_fd = */ NULL,
+ &netns_fd,
+ /* ret_userns_fd = */ NULL,
+ /* ret_root_fd = */ NULL);
if (r < 0)
return r;
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
return -errno;
- r = namespace_fork("(sd-addrns)", "(sd-addr)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
+ r = namespace_fork("(sd-addrns)", "(sd-addr)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL,
-1, -1, netns_fd, -1, -1, &child);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
return sd_bus_send(NULL, reply, NULL);
}
+int bus_machine_method_get_ssh_info(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ Machine *m = ASSERT_PTR(userdata);
+ int r;
+
+ assert(message);
+
+ r = sd_bus_message_new_method_return(message, &reply);
+ if (r < 0)
+ return r;
+
+ if (!m->ssh_address || !m->ssh_private_key_path)
+ return -ENOENT;
+
+ r = sd_bus_message_append(reply, "ss", m->ssh_address, m->ssh_private_key_path);
+ if (r < 0)
+ return r;
+
+ return sd_bus_send(NULL, reply, NULL);
+}
+
#define EXIT_NOT_FOUND 2
int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) {
break;
case MACHINE_CONTAINER: {
- _cleanup_close_ int mntns_fd = -1, root_fd = -1, pidns_fd = -1;
- _cleanup_close_pair_ int pair[2] = { -1, -1 };
+ _cleanup_close_ int mntns_fd = -EBADF, root_fd = -EBADF, pidns_fd = -EBADF;
+ _cleanup_close_pair_ int pair[2] = EBADF_PAIR;
_cleanup_fclose_ FILE *f = NULL;
pid_t child;
- r = namespace_open(m->leader, &pidns_fd, &mntns_fd, NULL, NULL, &root_fd);
+ r = namespace_open(m->leader.pid,
+ &pidns_fd,
+ &mntns_fd,
+ /* ret_netns_fd = */ NULL,
+ /* ret_userns_fd = */ NULL,
+ &root_fd);
if (r < 0)
return r;
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
return -errno;
- r = namespace_fork("(sd-osrelns)", "(sd-osrel)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
+ r = namespace_fork("(sd-osrelns)", "(sd-osrel)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL,
pidns_fd, mntns_fd, -1, -1, root_fd,
&child);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
if (r == 0) {
- int fd = -1;
+ int fd = -EBADF;
pair[0] = safe_close(pair[0]);
int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *pty_name = NULL;
- _cleanup_close_ int master = -1;
+ _cleanup_close_ int master = -EBADF;
Machine *m = ASSERT_PTR(userdata);
int r;
r = bus_verify_polkit_async(
message,
- CAP_SYS_ADMIN,
m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-open-pty" : "org.freedesktop.machine1.open-pty",
details,
- false,
- UID_INVALID,
&m->manager->polkit_registry,
error);
if (r < 0)
if (r < 0)
return r;
- if (asprintf(&address, "x-machine-unix:pid=%" PID_PRI, m->leader) < 0)
+ if (asprintf(&address, "x-machine-unix:pid=%" PID_PRI, m->leader.pid) < 0)
return -ENOMEM;
bus->address = address;
bus->bus_client = true;
bus->trusted = false;
- bus->is_system = true;
+ bus->runtime_scope = RUNTIME_SCOPE_SYSTEM;
r = sd_bus_start(bus);
if (r == -ENOENT)
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *pty_name = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *allocated_bus = NULL;
- _cleanup_close_ int master = -1;
+ _cleanup_close_ int master = -EBADF;
sd_bus *container_bus = NULL;
Machine *m = ASSERT_PTR(userdata);
const char *p, *getty;
r = bus_verify_polkit_async(
message,
- CAP_SYS_ADMIN,
m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-login" : "org.freedesktop.machine1.login",
details,
- false,
- UID_INVALID,
&m->manager->polkit_registry,
error);
if (r < 0)
_cleanup_free_ char *pty_name = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *allocated_bus = NULL;
sd_bus *container_bus = NULL;
- _cleanup_close_ int master = -1, slave = -1;
+ _cleanup_close_ int master = -EBADF, slave = -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 *p, *unit, *user, *path, *description, *utmp_id;
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(
message,
- CAP_SYS_ADMIN,
m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-shell" : "org.freedesktop.machine1.shell",
details,
- false,
- UID_INVALID,
&m->manager->polkit_registry,
error);
if (r < 0)
r = bus_verify_polkit_async(
message,
- CAP_SYS_ADMIN,
"org.freedesktop.machine1.manage-machines",
details,
- false,
- UID_INVALID,
&m->manager->polkit_registry,
error);
if (r < 0)
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Can't bind mount on container with user namespacing applied.");
propagate_directory = strjoina("/run/systemd/nspawn/propagate/", m->name);
- r = bind_mount_in_namespace(m->leader,
- propagate_directory,
- "/run/host/incoming/",
- src, dest, read_only, make_file_or_directory);
+ r = bind_mount_in_namespace(
+ &m->leader,
+ propagate_directory,
+ "/run/host/incoming/",
+ src, dest,
+ read_only,
+ make_file_or_directory);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to mount %s on %s in machine's namespace: %m", src, dest);
int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *host_basename = NULL, *container_basename = NULL;
const char *src, *dest, *host_path, *container_path;
- _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
+ _cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
CopyFlags copy_flags = COPY_REFLINK|COPY_MERGE|COPY_HARDLINKS;
- _cleanup_close_ int hostfd = -1;
+ _cleanup_close_ int hostfd = -EBADF;
Machine *m = ASSERT_PTR(userdata);
bool copy_from;
pid_t child;
r = bus_verify_polkit_async(
message,
- CAP_SYS_ADMIN,
"org.freedesktop.machine1.manage-machines",
details,
- false,
- UID_INVALID,
&m->manager->polkit_registry,
error);
if (r < 0)
errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
- q = procfs_file_alloca(m->leader, "ns/mnt");
+ q = procfs_file_alloca(m->leader.pid, "ns/mnt");
mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC);
if (mntfd < 0) {
r = log_error_errno(errno, "Failed to open mount namespace of leader: %m");
goto child_fail;
}
- /* Run the actual copy operation. Note that when an UID shift is set we'll either clamp the UID/GID to
+ /* Run the actual copy operation. Note that when a UID shift is set we'll either clamp the UID/GID to
* 0 or to the actual UID shift depending on the direction we copy. If no UID shift is set we'll copy
* the UID/GIDs as they are. */
if (copy_from)
- r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, uid_shift == 0 ? UID_INVALID : 0, uid_shift == 0 ? GID_INVALID : 0, copy_flags, NULL);
+ r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, uid_shift == 0 ? UID_INVALID : 0, uid_shift == 0 ? GID_INVALID : 0, copy_flags, NULL, NULL);
else
- r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, uid_shift == 0 ? UID_INVALID : uid_shift, uid_shift == 0 ? GID_INVALID : uid_shift, copy_flags, NULL);
+ r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, uid_shift == 0 ? UID_INVALID : uid_shift, uid_shift == 0 ? GID_INVALID : uid_shift, copy_flags, NULL, NULL);
hostfd = safe_close(hostfd);
containerfd = safe_close(containerfd);
(void) sigkill_wait(child);
return r;
}
- errno_pipe_fd[0] = -1;
+ errno_pipe_fd[0] = -EBADF;
return 1;
}
int bus_machine_method_open_root_directory(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- _cleanup_close_ int fd = -1;
+ _cleanup_close_ int fd = -EBADF;
Machine *m = ASSERT_PTR(userdata);
int r;
r = bus_verify_polkit_async(
message,
- CAP_SYS_ADMIN,
"org.freedesktop.machine1.manage-machines",
details,
- false,
- UID_INVALID,
&m->manager->polkit_registry,
error);
if (r < 0)
break;
case MACHINE_CONTAINER: {
- _cleanup_close_ int mntns_fd = -1, root_fd = -1;
- _cleanup_close_pair_ int pair[2] = { -1, -1 };
+ _cleanup_close_ int mntns_fd = -EBADF, root_fd = -EBADF;
+ _cleanup_close_pair_ int pair[2] = EBADF_PAIR;
pid_t child;
- r = namespace_open(m->leader, NULL, &mntns_fd, NULL, NULL, &root_fd);
+ r = namespace_open(m->leader.pid,
+ /* ret_pidns_fd = */ NULL,
+ &mntns_fd,
+ /* ret_netns_fd = */ NULL,
+ /* ret_userns_fd = */ NULL,
+ &root_fd);
if (r < 0)
return r;
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
return -errno;
- r = namespace_fork("(sd-openrootns)", "(sd-openroot)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
+ r = namespace_fork("(sd-openrootns)", "(sd-openroot)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL,
-1, mntns_fd, -1, -1, root_fd, &child);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
if (r == 0) {
- _cleanup_close_ int dfd = -1;
+ _cleanup_close_ int dfd = -EBADF;
pair[0] = safe_close(pair[0]);
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Machine, service), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Unit", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
- SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader.pid), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Machine, class), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(Machine, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NetworkInterfaces", "ai", property_get_netif, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("VSockCID", "u", NULL, offsetof(Machine, vsock_cid), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("SSHAddress", "s", NULL, offsetof(Machine, ssh_address), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("SSHPrivateKeyPath", "s", NULL, offsetof(Machine, ssh_private_key_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
SD_BUS_METHOD("Terminate",
SD_BUS_RESULT("a(iay)", addresses),
bus_machine_method_get_addresses,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_ARGS("GetSSHInfo",
+ SD_BUS_NO_ARGS,
+ SD_BUS_RESULT("s", ssh_address, "s", ssh_private_key_path),
+ bus_machine_method_get_ssh_info,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("GetOSRelease",
SD_BUS_NO_ARGS,
SD_BUS_RESULT("a{ss}", fields),