1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-26 08:55:40 +03:00

Compare commits

...

7 Commits

Author SHA1 Message Date
Daan De Meyer
9af9a5cd14
Merge 44d1ad6d4f into 9d8f5e22f8 2024-10-25 16:29:33 +02:00
Lennart Poettering
9d8f5e22f8
Merge pull request #34891 from poettering/run0-pty
run0: add --pty and --pipe switches to force allocation of a pty or pipe
2024-10-25 16:25:01 +02:00
Lennart Poettering
6fb0c52295 ci: add some basic testing of the new --pty and --pipe switches 2024-10-25 14:14:26 +02:00
Lennart Poettering
edd10ab29c run0: add options to force allocation of PTY or of pipe use
Fixes: #33033
2024-10-25 14:14:26 +02:00
Lennart Poettering
988053eac3 tree-wide: use isatty_safe() everywhere 2024-10-25 14:09:38 +02:00
Lennart Poettering
a586f57eb2 update TODO 2024-10-25 13:57:44 +02:00
Daan De Meyer
44d1ad6d4f journal: Set +C if we create /var/log/journal
systemd-journal-flush.service runs before systemd-tmpfiles-setup.service
so we can't rely on tmpfiles setting +C for us, so let's make journald
set it itself if it creates /var/log/journal itself.
2024-04-30 12:07:16 +02:00
7 changed files with 84 additions and 8 deletions

5
TODO
View File

@ -129,6 +129,11 @@ Deprecations and removals:
Features:
* $LISTEN_PID, $MAINPID and $SYSTEMD_EXECPID env vars that the service manager
sets should be augmented with $LISTEN_PIDFDID, $MAINPIDFDID and
$SYSTEMD_EXECPIDFD (and similar for other env vars we might send). Also,
MAINPID= in sd_notify() should be augmented with MAINPIDFDID=, and so on.
* port copy.c over to use LabelOps for all labelling.
* port remaining getmntent() users over to libmount. There are subtle

View File

@ -192,6 +192,21 @@
</listitem>
</varlistentry>
<varlistentry>
<term><option>--pty</option></term>
<term><option>--pipe</option></term>
<listitem><para>Request allocation of a pseudo TTY for the <command>run0</command> session (in case
of <option>--pty</option>), or request passing the caller's STDIO file descriptors directly through
(in case of <option>--pipe</option>). If neither switch is specified, or if both switches are
specified, the mode will be picked automatically: if standard input, standard output and standard
error output are all connected to a TTY then a pseudo TTY is allocated, otherwise the relevant file
descriptors are passed through directly.</para>
<xi:include href="version-info.xml" xpointer="v257"/>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--machine=</option></term>

View File

@ -17,6 +17,7 @@
#include "alloc-util.h"
#include "audit-util.h"
#include "cgroup-util.h"
#include "chattr-util.h"
#include "conf-parser.h"
#include "creds-util.h"
#include "dirent-util.h"
@ -366,8 +367,18 @@ static int server_system_journal_open(
*
* If in persistent mode: create /var/log/journal and the machine path */
if (s->storage == STORAGE_PERSISTENT)
(void) mkdir_parents(s->system_storage.path, 0755);
if (s->storage == STORAGE_PERSISTENT) {
_cleanup_free_ char *parent = NULL;
r = path_extract_directory(s->system_storage.path, &parent);
if (r < 0)
log_warning_errno(r, "Failed to extract parent directory from %s, ignoring: %m",
s->system_storage.path);
else {
(void) mkdir_p(parent, 0755);
(void) chattr_path(parent, FS_NOCOW_FL, FS_NOCOW_FL, NULL);
}
}
(void) mkdir(s->system_storage.path, 0755);

View File

@ -290,7 +290,7 @@ static int handle_arg_console(const char *arg) {
else if (streq(arg, "passive"))
arg_console_mode = CONSOLE_PASSIVE;
else if (streq(arg, "pipe")) {
if (isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO))
if (isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO))
log_full(arg_quiet ? LOG_DEBUG : LOG_NOTICE,
"Console mode 'pipe' selected, but standard input/output are connected to an interactive TTY. "
"Most likely you want to use 'interactive' console mode for proper interactivity and shell job control. "
@ -298,7 +298,7 @@ static int handle_arg_console(const char *arg) {
arg_console_mode = CONSOLE_PIPE;
} else if (streq(arg, "autopipe")) {
if (isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO))
if (isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO))
arg_console_mode = CONSOLE_INTERACTIVE;
else
arg_console_mode = CONSOLE_PIPE;
@ -5981,7 +5981,7 @@ static int run(int argc, char *argv[]) {
umask(0022);
if (arg_console_mode < 0)
arg_console_mode = isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO) ?
arg_console_mode = isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO) ?
CONSOLE_INTERACTIVE : CONSOLE_READ_ONLY;
if (arg_console_mode == CONSOLE_PIPE) /* if we pass STDERR on to the container, don't add our own logs into it too */

View File

@ -171,6 +171,10 @@ static int help_sudo_mode(void) {
if (r < 0)
return log_oom();
/* NB: Let's not go overboard with short options: we try to keep a modicum of compatibility with
* sudo's short switches, hence please do not introduce new short switches unless they have a roughly
* equivalent purpose on sudo. Use long options for everything private to run0. */
printf("%s [OPTIONS...] COMMAND [ARGUMENTS...]\n"
"\n%sElevate privileges interactively.%s\n\n"
" -h --help Show this help\n"
@ -188,6 +192,8 @@ static int help_sudo_mode(void) {
" -D --chdir=PATH Set working directory\n"
" --setenv=NAME[=VALUE] Set environment variable\n"
" --background=COLOR Set ANSI color for background\n"
" --pty Request allocation of a pseudo TTY for stdio\n"
" --pipe Request direct pipe for stdio\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
ansi_highlight(),
@ -674,7 +680,7 @@ static int parse_argv(int argc, char *argv[]) {
/* If we both --pty and --pipe are specified we'll automatically pick --pty if we are connected fully
* to a TTY and pick direct fd passing otherwise. This way, we automatically adapt to usage in a shell
* pipeline, but we are neatly interactive with tty-level isolation otherwise. */
arg_stdio = isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) ?
arg_stdio = isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO) && isatty_safe(STDERR_FILENO) ?
ARG_STDIO_PTY :
ARG_STDIO_DIRECT;
@ -770,6 +776,8 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
ARG_NICE,
ARG_SETENV,
ARG_BACKGROUND,
ARG_PTY,
ARG_PIPE,
};
/* If invoked as "run0" binary, let's expose a more sudo-like interface. We add various extensions
@ -791,6 +799,8 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
{ "chdir", required_argument, NULL, 'D' },
{ "setenv", required_argument, NULL, ARG_SETENV },
{ "background", required_argument, NULL, ARG_BACKGROUND },
{ "pty", no_argument, NULL, ARG_PTY },
{ "pipe", no_argument, NULL, ARG_PIPE },
{},
};
@ -883,6 +893,20 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
break;
case ARG_PTY:
if (IN_SET(arg_stdio, ARG_STDIO_DIRECT, ARG_STDIO_AUTO)) /* if --pipe is already used, upgrade to auto mode */
arg_stdio = ARG_STDIO_AUTO;
else
arg_stdio = ARG_STDIO_PTY;
break;
case ARG_PIPE:
if (IN_SET(arg_stdio, ARG_STDIO_PTY, ARG_STDIO_AUTO)) /* If --pty is already used, upgrade to auto mode */
arg_stdio = ARG_STDIO_AUTO;
else
arg_stdio = ARG_STDIO_DIRECT;
break;
case '?':
return -EINVAL;
@ -913,7 +937,9 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
arg_wait = true;
arg_aggressive_gc = true;
arg_stdio = isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) ? ARG_STDIO_PTY : ARG_STDIO_DIRECT;
if (IN_SET(arg_stdio, ARG_STDIO_NONE, ARG_STDIO_AUTO))
arg_stdio = isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO) && isatty_safe(STDERR_FILENO) ? ARG_STDIO_PTY : ARG_STDIO_DIRECT;
arg_expand_environment = false;
arg_send_sighup = true;
@ -1181,7 +1207,7 @@ static int transient_service_set_properties(sd_bus_message *m, const char *pty_p
if (r < 0)
return bus_log_create_error(r);
send_term = isatty_safe(STDIN_FILENO) || isatty(STDOUT_FILENO) || isatty(STDERR_FILENO);
send_term = isatty_safe(STDIN_FILENO) || isatty_safe(STDOUT_FILENO) || isatty_safe(STDERR_FILENO);
}
if (send_term) {

View File

@ -261,4 +261,14 @@ if [[ -e /usr/lib/pam.d/systemd-run0 ]] || [[ -e /etc/pam.d/systemd-run0 ]]; the
assert_eq "$(run0 -D / pwd)" "/"
assert_eq "$(run0 --user=testuser pwd)" "/home/testuser"
assert_eq "$(run0 -D / --user=testuser pwd)" "/"
# Verify that all combinations of --pty/--pipe come to the sam results
assert_eq "$(run0 echo -n foo)" "foo"
assert_eq "$(run0 --pty echo -n foo)" "foo"
assert_eq "$(run0 --pipe echo -n foo)" "foo"
assert_eq "$(run0 --pipe --pty echo -n foo)" "foo"
# Validate when we invoke run0 without a tty, that depending on --pty it either allocates a tty or not
assert_neq "$(run0 --pty tty < /dev/null)" "not a tty"
assert_eq "$(run0 --pipe tty < /dev/null)" "not a tty"
fi

View File

@ -39,6 +39,15 @@ assert_eq() {(
fi
)}
assert_neq() {(
set +ex
if [[ "${1?}" = "${2?}" ]]; then
echo "FAIL: not expected: '$2' actual: '$1'" >&2
exit 1
fi
)}
assert_le() {(
set +ex