#include <libgen.h>
#undef basename
-#include "bus-util.h"
-#include "bus-label.h"
-#include "strv.h"
#include "bus-common-errors.h"
+#include "bus-internal.h"
+#include "bus-label.h"
+#include "bus-util.h"
#include "copy.h"
+#include "env-util.h"
+#include "fd-util.h"
#include "fileio.h"
+#include "formats-util.h"
#include "in-addr-util.h"
#include "local-addresses.h"
-#include "path-util.h"
-#include "mkdir.h"
-#include "bus-internal.h"
-#include "machine.h"
#include "machine-dbus.h"
-#include "formats-util.h"
+#include "machine.h"
+#include "mkdir.h"
+#include "path-util.h"
#include "process-util.h"
-#include "env-util.h"
+#include "strv.h"
+#include "terminal-util.h"
static int property_get_id(
sd_bus *bus,
message,
CAP_KILL,
"org.freedesktop.machine1.manage-machines",
+ NULL,
false,
UID_INVALID,
&m->manager->polkit_registry,
message,
CAP_KILL,
"org.freedesktop.machine1.manage-machines",
+ NULL,
false,
UID_INVALID,
&m->manager->polkit_registry,
r = wait_for_terminate(child, &si);
if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to wait for client: %m");
+ return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
- return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Client died abnormally.");
+ return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
break;
}
_exit(EXIT_FAILURE);
}
- r = copy_bytes(fd, pair[1], (off_t) -1, false);
+ r = copy_bytes(fd, pair[1], (uint64_t) -1, false);
if (r < 0)
_exit(EXIT_FAILURE);
r = wait_for_terminate(child, &si);
if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to wait for client: %m");
+ return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
- return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Client died abnormally.");
+ return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
break;
}
message,
CAP_SYS_ADMIN,
m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-open-pty" : "org.freedesktop.machine1.open-pty",
+ NULL,
false,
UID_INVALID,
&m->manager->polkit_registry,
if (master < 0)
return master;
- r = ptsname_malloc(master, &pty_name);
+ r = ptsname_namespace(master, &pty_name);
if (r < 0)
return r;
return sd_bus_send(NULL, reply, NULL);
}
-static int container_bus_new(Machine *m, sd_bus **ret) {
+static int container_bus_new(Machine *m, sd_bus_error *error, sd_bus **ret) {
int r;
assert(m);
bus->is_system = true;
r = sd_bus_start(bus);
+ if (r == -ENOENT)
+ return sd_bus_error_set_errnof(error, r, "There is no system bus in container %s.", m->name);
if (r < 0)
return r;
message,
CAP_SYS_ADMIN,
m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-login" : "org.freedesktop.machine1.login",
+ NULL,
false,
UID_INVALID,
&m->manager->polkit_registry,
if (master < 0)
return master;
- r = ptsname_malloc(master, &pty_name);
+ r = ptsname_namespace(master, &pty_name);
if (r < 0)
return r;
if (!p)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "PTS name %s is invalid", pty_name);
- if (unlockpt(master) < 0)
- return -errno;
-
- r = container_bus_new(m, &allocated_bus);
+ r = container_bus_new(m, error, &allocated_bus);
if (r < 0)
return r;
_cleanup_free_ char *pty_name = NULL;
_cleanup_bus_flush_close_unref_ sd_bus *allocated_bus = NULL;
sd_bus *container_bus = NULL;
- _cleanup_close_ int master = -1;
+ _cleanup_close_ int master = -1, slave = -1;
_cleanup_strv_free_ char **env = NULL, **args = NULL;
Machine *m = userdata;
const char *p, *unit, *user, *path, *description, *utmp_id;
message,
CAP_SYS_ADMIN,
m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-shell" : "org.freedesktop.machine1.shell",
+ NULL,
false,
UID_INVALID,
&m->manager->polkit_registry,
if (master < 0)
return master;
- r = ptsname_malloc(master, &pty_name);
+ r = ptsname_namespace(master, &pty_name);
if (r < 0)
return r;
p = path_startswith(pty_name, "/dev/pts/");
- if (!p)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "PTS name %s is invalid", pty_name);
+ assert(p);
+
+ slave = machine_open_terminal(m, pty_name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+ if (slave < 0)
+ return slave;
utmp_id = path_startswith(pty_name, "/dev/");
assert(utmp_id);
- if (unlockpt(master) < 0)
- return -errno;
-
- r = container_bus_new(m, &allocated_bus);
+ r = container_bus_new(m, error, &allocated_bus);
if (r < 0)
return r;
description = strjoina("Shell for User ", isempty(user) ? "root" : user);
r = sd_bus_message_append(tm,
- "(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)",
+ "(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)",
"Description", "s", description,
- "StandardInput", "s", "tty",
- "StandardOutput", "s", "tty",
- "StandardError", "s", "tty",
- "TTYPath", "s", pty_name,
+ "StandardInputFileDescriptor", "h", slave,
+ "StandardOutputFileDescriptor", "h", slave,
+ "StandardErrorFileDescriptor", "h", slave,
"SendSIGHUP", "b", true,
"IgnoreSIGPIPE", "b", false,
"KillMode", "s", "mixed",
- "TTYVHangup", "b", true,
"TTYReset", "b", true,
"UtmpIdentifier", "s", utmp_id,
"UtmpMode", "s", "user",
- "PAMName", "s", "login");
+ "PAMName", "s", "login",
+ "WorkingDirectory", "s", "-~");
if (r < 0)
return r;
if (r < 0)
return r;
+ slave = safe_close(slave);
+
r = sd_bus_message_new_method_return(message, &reply);
if (r < 0)
return r;
message,
CAP_SYS_ADMIN,
"org.freedesktop.machine1.manage-machines",
+ NULL,
false,
UID_INVALID,
&m->manager->polkit_registry,
r = wait_for_terminate(child, &si);
if (r < 0) {
- r = sd_bus_error_set_errnof(error, r, "Failed to wait for client: %m");
+ r = sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
goto finish;
}
if (si.si_code != CLD_EXITED) {
- r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Client died abnormally.");
+ r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
goto finish;
}
if (si.si_status != EXIT_SUCCESS) {
if (read(errno_pipe_fd[0], &r, sizeof(r)) == sizeof(r))
r = sd_bus_error_set_errnof(error, r, "Failed to mount: %m");
else
- r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Client failed.");
+ r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child failed.");
goto finish;
}
o->pid = 0;
if (si->si_code != CLD_EXITED) {
- r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Client died abnormally.");
+ r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
goto fail;
}
if (read(o->errno_fd, &r, sizeof(r)) == sizeof(r))
r = sd_bus_error_set_errnof(&error, r, "%m");
else
- r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Client failed.");
+ r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Child failed.");
goto fail;
}
message,
CAP_SYS_ADMIN,
"org.freedesktop.machine1.manage-machines",
+ NULL,
false,
UID_INVALID,
&m->manager->polkit_registry,