manager_varlink_init_resolve_hook and manager_varlink_init_userdb are very
similar, but one didn't set a description and the other one had an error
message which didn't print the offending path.
Define constants for the paths, and also change other similar constants
to have slightly shorter names. (It's an "address" and "path", but we don't
need to have both parts in the name, esp. that it makes the name very long.)
This is a follow-up for 119d332d9c and
ensures the check only is applied to the system instance of machined. It
doesn't really apply to the per-user instance, because we never want to
permit differently privileged clients access anyway.
(The process_is_owned_by_uid() call might fail if invoked unpriv, hence
there's value in not calling it if machined runs in --user mode, it's
what makes machined actually work)
In all cases, everything that we list in 'extract', we also list in
'sources'. We can simplify things by automatically appending the first
list to the second.
In the listings, move 'extract' key right below 'sources', since now
they are both "sources", just with slightly different meanings.
We have dropped cgroup v1 support in v258. Let's drop legacy code.
Then, we can drop 'controller' argument from cg_pid_get_path() and
cg_pidref_get_path().
This basically implements nss-myhostname, but natively in
systemd-resolved, so that the logic becomes available also for clients
using the local DNS stub for resolution or the D-Bus or Varlink APIs.
Marking a whole directory tree OS image as read-only is difficult
privilege-wise, because so far we rely on the FS_IMMUTABLE_FL which is
not accessible to unpriv clients.
One fundamental place where we currently rely on marking images
read-only is for keeping pristine copies of the originally downloaded
image around, which we place in "hidden" image directories. This is
probably the most relevant usecase for the read-only flag. And moreover,
the only usecase for the hidden images are these read-only pristine
copies.
Hence, let's make this work reasonably in the unpriv case, and simply
imply the read-only flag for hidden images. This is strictly speaking a
change in behaviour, but effectively it shouldn't be, because for nspawn
containers that are executed we insist on names that are hostname
compatible, and hidden names aren't (because they start with a dot).
- Make sure forward headers have the iwyu pragma to always keep them
- Make sure we always include the daemon specific forward header
instead of shared-forward.h
- Remove shared-forward.h include where the daemon specific forward
header is already included
Let's not leak details from src/shared and src/libsystemd into
src/basic, even though you can't actually do anything useful with
just forward declarations from src/shared.
The sd-forward.h header is put in src/libsystemd/sd-common as we
don't have a directory for shared internal headers for libsystemd
yet.
Let's also rename forward.h to basic-forward.h to keep things
self-explanatory.
Now that we have landed several fixes, this should be safe to do
again, so allow logged in users to register machines without
authentication prompts
This reverts commit 65badde82e.
discover-image.[ch] largely already supports per-scope operations, let's
extend this however to also cover finding .nspawn settings files and
managing the pool dir.
We intend to make self-registering machines an unprivileged operation,
but currently that would allow an unprivileged user to register a
process they own in the root namespace, and then login as any
user they like, including root, which is not ideal.
Forbid non-root from shelling into a machine that is running in
the root user namespace.
Current methods take a numeric PID, but we know that is unreliable for
the usual reasons. Add variants that take a PIDFD instead, or a
PID + PIDFDID combination for remote users.
UID entry in the machine state file is introduced in v258,
hence when a host is upgraded to v258, the field does not exist in the
file, thus the variable 'uid' is NULL.
Follow-up for 276d200186.
Fixes#39061.
Registering a process as a machine means a caller can get machined
to send sigterm to it, and more. If an unpriv user is registering,
ensure the registered process is actually owned by the user.
Follow-up for adaff8eb35
Currently, pty_forward_set_ignore_vhangup() is only used for disabling
the flag. To make the function also disable PTY_FORWARD_IGNORE_INITIAL_VHANGUP
flag, this renames it to pty_forward_honor_vhangup().
Also, for consistency, pty_forward_get_ignore_vhangup() and
ignore_vhangup() are replaced with pty_forward_vhangup_honored().
So far, machined strictly tracked the "leader" process of a machine,
i.e. the topmost process that is actually the payload of the machine.
Its runtime also defines the runtime of the machine, and we can directly
interact with it if we need to, for example for containers to join the
namespaces, or kill it.
Let's optionally also track the "supervisor" process of a machine, i.e.
the host process that manages the payload if there is one. This is
generally useful info, but in particular is useful because we might need
to communicate with it to shutdown a machine without cooperation of the
payload. Traditionally we did this by simply stopping the unit of the
machine, but this is not doable now that the host machined can be used
to track per-user machines.
In the long run we probably want a more bespoke protocol between
machined and supervisors (so that we can execute other commands too,
such as request cooperative reboots/shutdowns), but that's for later.
Some environments call the concept "monitor" rather than "supervisor" or
use some other term. I stuck to "supervisor" because nspawn uses this,
and ultimately one name is as good as another.
And of course, in other implementations of VM managers of containers
there might not be a single process tracking each VM/container. Because
of this, the concept of a supervisor is optional.
The difference between these two operations are large: one is relatively
superficial: for "registration" all resources remain associated with the
invoking user, only the cgroup is reported to machined which then keeps
track of the machine, too. OTOH "creation" a scope is allocated in
system context, hence the invoked code will be owned by the system, and
its resource usage charged against the system.
Hence, use two distinct polkit actions for this, so that we can relax
access to registration, but keep access to creation tough.
Now that unpriv clients can register machines, let's register their UID
too. This allows us to do two things:
1. make sure the scope delegation is assigned to the right UID (so that
the unpriv user can actually create cgroups below the delegated
scope)
2. permit certain types of access (i.e. killing, or pty access) to the
client without auth if it owns the machine.
All other status output lines use tabs, use that for the ID shift line
too. otherwise output will appear unaligned if log viewers have fixed
tab stop positions.
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.