mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
run: allow connecting to capsule instances with --capsule=/-C
This commit is contained in:
@@ -17,11 +17,14 @@
|
||||
#include "bus-unit-util.h"
|
||||
#include "bus-wait-for-jobs.h"
|
||||
#include "calendarspec.h"
|
||||
#include "capsule-util.h"
|
||||
#include "chase.h"
|
||||
#include "env-util.h"
|
||||
#include "escape.h"
|
||||
#include "exit-status.h"
|
||||
#include "fd-util.h"
|
||||
#include "format-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "hostname-util.h"
|
||||
#include "main-func.h"
|
||||
#include "parse-argument.h"
|
||||
@@ -35,6 +38,7 @@
|
||||
#include "special.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "uid-classification.h"
|
||||
#include "unit-def.h"
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
@@ -265,6 +269,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "user", no_argument, NULL, ARG_USER },
|
||||
{ "system", no_argument, NULL, ARG_SYSTEM },
|
||||
{ "capsule", required_argument, NULL, 'C' },
|
||||
{ "scope", no_argument, NULL, ARG_SCOPE },
|
||||
{ "unit", required_argument, NULL, 'u' },
|
||||
{ "description", required_argument, NULL, ARG_DESCRIPTION },
|
||||
@@ -317,7 +322,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
/* Resetting to 0 forces the invocation of an internal initialization routine of getopt_long()
|
||||
* that checks for GNU extensions in optstring ('-' or '+' at the beginning). */
|
||||
optind = 0;
|
||||
while ((c = getopt_long(argc, argv, "+hrH:M:E:p:tPqGdSu:", options, NULL)) >= 0)
|
||||
while ((c = getopt_long(argc, argv, "+hrC:H:M:E:p:tPqGdSu:", options, NULL)) >= 0)
|
||||
|
||||
switch (c) {
|
||||
|
||||
@@ -339,6 +344,18 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
r = capsule_name_is_valid(optarg);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Unable to validate capsule name '%s': %m", optarg);
|
||||
if (r == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid capsule name: %s", optarg);
|
||||
|
||||
arg_host = optarg;
|
||||
arg_transport = BUS_TRANSPORT_CAPSULE;
|
||||
arg_runtime_scope = RUNTIME_SCOPE_USER;
|
||||
break;
|
||||
|
||||
case ARG_SCOPE:
|
||||
arg_scope = true;
|
||||
break;
|
||||
@@ -1603,6 +1620,28 @@ static void set_window_title(PTYForward *f) {
|
||||
(void) pty_forward_set_title_prefix(f, dot);
|
||||
}
|
||||
|
||||
static int chown_to_capsule(const char *path, const char *capsule) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(capsule);
|
||||
|
||||
p = path_join("/run/capsules/", capsule);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
struct stat st;
|
||||
r = chase_and_stat(p, /* root= */ NULL, CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS, /* ret_path= */ NULL, &st);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (uid_is_system(st.st_uid) || gid_is_system(st.st_gid)) /* paranoid safety check */
|
||||
return -EPERM;
|
||||
|
||||
return chmod_and_chown(path, 0600, st.st_uid, st.st_gid);
|
||||
}
|
||||
|
||||
static int start_transient_service(sd_bus *bus) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
@@ -1615,7 +1654,7 @@ static int start_transient_service(sd_bus *bus) {
|
||||
|
||||
if (arg_stdio == ARG_STDIO_PTY) {
|
||||
|
||||
if (arg_transport == BUS_TRANSPORT_LOCAL) {
|
||||
if (IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_CAPSULE)) {
|
||||
master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
|
||||
if (master < 0)
|
||||
return log_error_errno(errno, "Failed to acquire pseudo tty: %m");
|
||||
@@ -1624,6 +1663,14 @@ static int start_transient_service(sd_bus *bus) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine tty name: %m");
|
||||
|
||||
if (arg_transport == BUS_TRANSPORT_CAPSULE) {
|
||||
/* If we are in capsule mode, we must give the capsule UID/GID access to the PTY we just allocated first. */
|
||||
|
||||
r = chown_to_capsule(pty_path, arg_host);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to chown tty to capsule UID/GID: %m");
|
||||
}
|
||||
|
||||
if (unlockpt(master) < 0)
|
||||
return log_error_errno(errno, "Failed to unlock tty: %m");
|
||||
|
||||
@@ -2311,7 +2358,7 @@ static int run(int argc, char* argv[]) {
|
||||
* limited direct connection */
|
||||
if (arg_wait ||
|
||||
arg_stdio != ARG_STDIO_NONE ||
|
||||
(arg_runtime_scope == RUNTIME_SCOPE_USER && arg_transport != BUS_TRANSPORT_LOCAL))
|
||||
(arg_runtime_scope == RUNTIME_SCOPE_USER && !IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_CAPSULE)))
|
||||
r = bus_connect_transport(arg_transport, arg_host, arg_runtime_scope, &bus);
|
||||
else
|
||||
r = bus_connect_transport_systemd(arg_transport, arg_host, arg_runtime_scope, &bus);
|
||||
|
||||
Reference in New Issue
Block a user