I expressed the issue I have with parse_tristate_argument()
in #37751: it doesn't add any value to direct use of parse_tristate();
on the contrary, it doesn't support means to reset the arg to "auto"/-1 state.
The mere reason it existed is that we need a int type ret param.
Since the previous attempt to address this mess failed, let's
try to make the function more useful by making it accept "auto".
I figure this is useful on its own.
As requested in
https://github.com/systemd/systemd/pull/40652#discussion_r2831833996,
the function name is suffixed with _with_auto() to establish
that "auto" is handled internally.
For many use cases DynamicUser= just doesn't cut it. Specifically lots
of stuff wants to run as root. Let's support this use case by relaxing
our checks for capsules a bit.
This got split in 5cabeed80b
to accommodate --empower, and later --empower received
dedicated handling again (c36942916b).
I think the new naming makes more sense - --empower is privileged
after all, just with uid left unchanged. Hence merge
privileged_execution back into it.
Follow-up for 4f6ef13f43
Special casing --area= rather than --empower makes the code
self-explanatory, as --area= is about alternative home dir
after all. On top of that this ensures when --area= and
--empower are specified in combination we honor the home dir
switch, too.
Also, unless --same-root-dir was specified, don't make the executable
absolute if we're running in a chroot. Situations like this are still iffy,
but we might as well handle them a little more gracefully.
When in --empower mode, all created files will be owned by the current
user, which could be problematic when creating files outside of the
current user's home directory, as other processes running as the same
user would be able to edit those files.
While this is a bit of an edge case since users already have to go through
the effort of writing --empower to indicate they want a privileged session
as the current user, it's not unphatomable to think they could start an
empowered session which they later return to and continue using. Currently,
it's not easy to differentiate a regular run0 session and an empowered session
at a glance, so users might think they're using a regular run0 session when
they're actually using an empowered session.
To address this problem, let's give empowered session their own identify, by
making the background orange, using the pumpkin emoji as the shell prompt
prefix and giving them an orange circle as the PTY title.
```
==19541== 8 bytes in 1 blocks are still reachable in loss record 1 of 3
==19541== at 0x4841744: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19541== by 0x50125C9: strdup (strdup.c:42)
==19541== by 0x4C55925: getusername_malloc (user-util.c:154)
==19541== by 0x1121D6: parse_argv_sudo_mode (run.c:1098)
==19541== by 0x123B13: run (run.c:3032)
==19541== by 0x124198: main (run.c:3100)
==19541==
==19541== 11 bytes in 1 blocks are still reachable in loss record 2 of 3
==19541== at 0x4841744: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19541== by 0x50125C9: strdup (strdup.c:42)
==19541== by 0x112A9C: parse_argv_sudo_mode (run.c:1182)
==19541== by 0x123B13: run (run.c:3032)
==19541== by 0x124198: main (run.c:3100)
```
Before:
$ sudo build/systemd-run --scope --uid=asdf whoami
Failed to resolve user asdf: No such process
Now:
$ sudo build/systemd-run --scope --uid=asdf whoami
Failed to resolve user 'asdf': Unknown user
This enables running something like
"mkosi box -- run0 --empower --same-root-dir -E PATH" to get an
empowered session as the current user within the "mkosi box" environment.
A --empower session is effectively root without being UID 0, so it
doesn't make sense to enforce polkit authentication in those. Let's
add the empower group, add --empower sessions to that group and ship
a polkit rule to skip authentication for all users in the empower
group.
(As a side-effect this will also allow users to add themselves to this
group outside of 'run0 --empower' to mimick NOPASSWD from sudo)
RootDirectory= but via a open_tree() file descriptor. This allows
setting up the execution environment for a service by the client in
a mount namespace and then starting a transient unit in that execution
environment using the new property.
We also add --root-directory= and --same-root-dir= to systemd-run to
have it run services within the given root directory. As systemd-run
might be invoked from a different mount namespace than what systemd is
running in, systemd-run opens the given path with open_tree() and then
sends it to systemd using the new RootDirectoryFileDescriptor= property.
--empower gives full privileges to a non-root user. Currently this
includes all capabilities but we leave the option open to add more
privileges via this option in the future.
Why is this useful? When running privileged development or debugging
commands from your home directory (think bpftrace, strace and such),
you want any files written by these tools to be owned by your current
user, and not by the root user. run0 --empower will allow you to run
all privileged operations (assuming the tools check for capabilities
and not UIDs), while any files written by the tools will still be owned
by the current user.
Check whether the argument of the `--background` option of
`systemd-run`, `run0`, `systemd-nspawn`, `systemd-vmspawn`, and
`systemd-pty-forward` is either empty or looks like an ANSI color code,
and reject invalid values when parsing arguments.
We consider a string to look like an ANSI color code if it consists of
one or more sequences of ASCII digits separated by semicolons. This
permits every valid ANSI color code, and should reject anything that
results in garbled output.
By giving priority to --background= we prevent users from opting
out of coloring if an explicit color is chosen by a tool wrapping
one of our own tools. Instead, let's give priority to the environment
variable, so that even if our tools are wrapped by another tool with
a different background, users can still opt out of coloring just by
setting the environment variable, which has a high chance of being
forwarded to the invocation of our own tools which makes it easy to
use to disable color tinting globally if requested by the user.
This partially reverts 9adb4685df.
For the case that sys/stat.h is not included indirectly by other headers.
Fixes the following error:
```
../src/run/run.c: In function 'fchown_to_capsule':
../src/run/run.c:2128:21: error: storage size of 'st' isn't known
2128 | struct stat st;
| ^~
```
drained() checks PTYForward.master_readable flag, but it may be
tentatively unset due to a tentative error like EAGAIN in the previous
IO event. Let's try to call shovel() one more time, which re-read the
master and call drained() at the end. Otherwise, we may lost some data.
These source files uses symbols provided by sys/stat.h, e.g. struct stat,
S_IFREG, S_IFBLK, and so on. Let's explicitly include sys/stat.h where
necessary.
Glibc's fcntl.h includes bits/stat.h, which provides these symbols, so
these symbols can be used without explicitly including sys/stat.h. But,
based on the discussion in #37922, we should explicitly include relevant
headers, and should not rely on the indirect inclusion.
Similar to 4f18ff2e29, but for sys/stat.h.
We use symbols provided by unistd.h without including it. E.g.
open(), close(), read(), write(), access(), symlink(), unlink(), rmdir(),
fsync(), syncfs(), lseek(), ftruncate(), fchown(), dup2(), pipe2(),
getuid(), getgid(), gettid(), getppid(), pipe2(), execv(), _exit(),
environ, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, F_OK, and their
friends and variants, so on.
Currently, unistd.h is indirectly included mainly in the following two paths:
- through missing_syscall.h, which is planned to covert to .c file.
- through signal.h -> bits/sigstksz.h, which is new since glibc-2.34.
Note, signal.h is included by sd-eevent.h. So, many source files
indirectly include unistd.h if newer glibc is used.
Currently, our baseline on glibc is 2.31. We need to support glibc older
than 2.34, but unfortunately, we do not have any CI environments with
such old glibc. CIFuzz uses glibc-2.31, but it builds only fuzzers, and
many files are even not compiled.
[1] says:
> Since 0.60.0 the name argument is optional and defaults to the basename of
> the first output
We specify >= 0.62 as the supported version, so drop the duplicate name in all cases
where it is the same as outputs[0], i.e. almost all cases.
[1] https://mesonbuild.com/Reference-manual_functions.html#custom_target
Let's be compatible with sd-bus' logic to talk to machine, and support
the usual user@host syntax. We only want the host part, hence chop if
off before passing it to OpenMachinePTY().
Fixes: #32997
This commit cleans up the includes for all the small tools across
the tree.
A few cases of returning EXIT_SUCCESS are replaced with returning
0 to avoid including <stdlib.h>.
Split out of #37344.
Follow-up for f44e7a8c11
This breaks the rule stated at the beginning of help_sudo_mode():
> 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.
parse_path_argument() unconditionally makes the passed path absolute,
without handling '~' of any sort. I think this generally makes sense
in most tools, since ~ expansion is typically done by the shell
and we wouldn't be seeing them in the first place and hence special
casing is not worth it. But in run0 let's explicit enable '~'.
Let's move some logic from _DEFINE_MAIN_FUNCTION() and other places
in main-func.h into functions that we implement in main-func.c to
allow moving some included headers from the header to the .c file.