1
0
mirror of https://github.com/systemd/systemd.git synced 2025-02-01 09:47:35 +03:00

Compare commits

...

46 Commits

Author SHA1 Message Date
Ivan Kruglov
b4dddd9cc3 machine: tests for io.systemd.Machine.{CopyFrom, CopyTo} methods 2024-11-13 11:49:34 +01:00
Ivan Kruglov
1951208605 machine: introduce io.system.Machine.{CopyFrom, CopyTo} methods 2024-11-13 11:49:34 +01:00
Ivan Kruglov
85ce75f4ad machine: adjust operation callback logic for varlink
This is to simplyfy varlink callback. There is no use of this logic atm.
So, no harm.
2024-11-13 11:49:34 +01:00
Yu Watanabe
b4dc8b6415
sd-boot/sd-stub: two log message fixes (#35143)
Fixes: #35033
Fixes: #35100
2024-11-13 10:09:05 +09:00
Yu Watanabe
d762b14e38
audit-util: return -ENODATA from audit_{session|loginuid}_from_pid() if invoked in a container (#35072)
The auditing subsystem is still not virtualized for containers, hence
the two values don't really make sense inside them, they will just leak
information from outside into the container. Hence don't make use of the
data if we detect we are run inside of a container.

This has visible effects: logind will no longer try to reuse the
auditing session ids as its own session ids when run inside a container.

While are at it, modernize the calls in more ways:

1. switch to pidref behaviour, all but one of our uses are using pidref
anyway already.
2. use read_virtual_file() + proc_mounted()
3. reasonably distinguish ENOENT errors when reading the process proc
files: distinguish the case where /proc is not mounted, from the case
where the process is already gone, from where auditing is not enabled in
the kernel build.
2024-11-13 10:08:29 +09:00
Lennart Poettering
ead9ef5027 ptyfwd: ellipsize overly long window titles
Apparently some terminal emulators have problems with overly long
titles, hence truncate them at some safe length (128).

Also, when parsing ANSI sequences ourselves accept longer sequences
(192), after all we should be fine when parsing our own title sequences.

Fixes: #35104
2024-11-13 10:07:25 +09:00
Mike Yuan
e2f82f6151 various: check meson feature flag early
Prompted by https://github.com/systemd/systemd/pull/35110#discussion_r1835885340
2024-11-13 08:21:33 +09:00
Lennart Poettering
f2b4f19881 pe: use PE_SECTION_VECTOR_IS_SET() macro where appropriate 2024-11-12 23:45:15 +01:00
Lennart Poettering
557d9fd5d1 pe: remove unnecessary log message about DT/HWID
Fixes: #35100
2024-11-12 23:45:14 +01:00
Lennart Poettering
1991ffa912 efi: don't log if EFI RNG isn't ready
Apparently this happens IRL on some systems, let's handle this
gracefully and don't log.

Fixes: #35033
2024-11-12 23:44:59 +01:00
Lennart Poettering
c892816ceb run0: when changing privileges to non-root, do not show superhero emoji
Let's show an idcard logo instead, to indicate that we changed ids.
2024-11-12 23:09:21 +01:00
Lennart Poettering
4e0bdf950e dbus-manager: add missing word 'unit' to PK message 2024-11-12 23:09:01 +01:00
Lennart Poettering
dcf5e9a6bf
tree-wide: remove some dead code (#35137) 2024-11-12 23:08:45 +01:00
Lennart Poettering
7bf0149e9b process-util: more gracefully handle oom adjust parsing/setting
Who knows what kind of mount shenanigans people employ, let's gracefully
handle parse failures of proc files, like we alway do otherwsie.
2024-11-12 23:03:40 +01:00
Lennart Poettering
68c554f23a audit-util: modernize use_audit() a bit
Use ERRNO_IS_xyz() macros where appropriate.

Also, reduce indentation a bit by inverted early check.

And log in more error codepaths.
2024-11-12 23:03:40 +01:00
Lennart Poettering
7e02ee98d8 audit-util: return -ENODATA from audit_{session|loginuid}_from_pid() if invoked in a container
The auditing subsystem is still not virtualized for containers, hence the two
values don't really make sense inside them, they will just leak
information from outside into the container. Hence don't make use of the
data if we detect we are run inside of a container.

This has visible effects: logind will no longer try to reuse the
auditing session ids as its own session ids when run inside a container.

While are at it, modernize the calls in more ways:

1. switch to pidref behaviour, all but one of our uses are using pidref
   anyway already.
2. use read_virtual_file() + proc_mounted()
3. reasonable distinguish ENOENT errors when reading the process proc
   files: distinguish the case where /proc is not mounted, from the case
   where the process is already gone, from where auditing is not enabled
   in the kernel build.
2024-11-12 23:03:03 +01:00
Davide Cavalca
fa8a55a914 mkosi: ruff is not available on all distros
Refactor to only install ruff where it is available
2024-11-12 18:05:17 +00:00
Maanya Goenka
68a2a43c9b
TODO: Fix typo (#35138)
Replace confex with confext
2024-11-12 19:00:23 +01:00
Lennart Poettering
4aaabb55c7 nspawn: fix indentation of run_container() parameter list 2024-11-12 18:31:56 +01:00
Lennart Poettering
9c56a3629f mntwork: shorten code 2024-11-12 18:31:56 +01:00
Lennart Poettering
0557f82650 dissect-image: remove dead code 2024-11-12 18:31:56 +01:00
Lennart Poettering
e688097ce3 mountfsd: drop unused variable 2024-11-12 18:31:56 +01:00
Antonio Alvarez Feijoo
2a310c0ad6 sbsign: remove unused --no-pager option 2024-11-12 17:52:48 +01:00
Davide Cavalca
f2672f2c5d mkosi: Install tpm2-tss-devel to tools for CentOS and Fedora instead of tss2-devel
tss2-devel is the IBM TPM stack, we want the Intel TPM stack, so let's
use the correct package.
2024-11-12 22:45:25 +09:00
Yu Watanabe
5da7e9b208
Fix man page links broken due to incorrect volume numbers (#35122) 2024-11-12 18:23:47 +09:00
Antonio Alvarez Feijoo
05a0366381 man/systemd-keyutil: fix rendering typo 2024-11-12 17:54:07 +09:00
Štěpán Němec
62ec4798f2 man/systemd.special: fix a typo 2024-11-11 20:31:43 +01:00
Štěpán Němec
597c6cc119 man: fix incorrect volume numbers in internal man page references
Some ambiguity (e.g., same-named man pages in multiple volumes)
makes it impossible to fully automate this, but the following
Python snippet (run inside the man/ directory of the systemd repo)
helped to generate the sed command lines (which were subsequently
manually reviewed, run and the false positives reverted):

from pathlib import Path

import lxml
from lxml import etree as ET

man2vol: dict[str, str] = {}
man2citerefs: dict[str, list] = {}

for file in Path(".").glob("*.xml"):
    tree = ET.parse(file, lxml.etree.XMLParser(recover=True))
    meta = tree.find("refmeta")
    if meta is not None:
        title = meta.findtext("refentrytitle")
        if title is not None:
            vol = meta.findtext("manvolnum")
            if vol is not None:
                man2vol[title] = vol
            citerefs = list(tree.iter("citerefentry"))
            if citerefs:
                man2citerefs[title] = citerefs

for man, refs in man2citerefs.items():
    for ref in refs:
        title = ref.findtext("refentrytitle")
        if title is not None:
            has = ref.findtext("manvolnum")
            try:
                should_have = man2vol[title]
            except KeyError:  # Non-systemd man page reference?  Ignore.
                continue
            if has != should_have:
                print(
                    f"sed -i '\\|<citerefentry><refentrytitle>{title}"
                    f"</refentrytitle><manvolnum>{has}</manvolnum>"
                    f"</citerefentry>|s|<manvolnum>{has}</manvolnum>|"
                    f"<manvolnum>{should_have}</manvolnum>|' {man}.xml"
                )
2024-11-11 20:31:08 +01:00
Yu Watanabe
3304a029b8
network: forget IPv4 non-local routes when an interface went down (#35099)
Fixes #35047.
2024-11-12 01:07:43 +09:00
Lennart Poettering
67e003d7dd
Introduce systemd-keyutil to do various key/certificate operations (#35095)
Let's gather generic key/certificate operations in a new tool
systemd-keyutil instead of spreading them across various special purpose
tools.

Fixes #35087
2024-11-11 16:09:07 +01:00
Yu Watanabe
7f1b36a82a test-network: add test case for issue #35047 2024-11-11 13:59:41 +00:00
Yu Watanabe
688f166972 network/nexthop: also forget IPv4 nexthops when an interface went down
Similar to the previous commit, but for nexthop.
2024-11-11 13:59:41 +00:00
Yu Watanabe
6954c38cf8 network/route: forget IPv4 non-local routes when an interface went down
When an interface went down, IPv4 non-local routes are removed by the
kernel without any notifications. Let's forget the routes in that case.

Fixes #35047.
2024-11-11 13:59:41 +00:00
Yu Watanabe
fd2ea787bd network/nexthop: forget dependent routes without trying to remove
When a nexthop is removed, routes depend on the removed nexthop are
already removed. It is not necessary to remove them, as already
commented. Let's forget them without trying to remove.
2024-11-11 13:59:41 +00:00
Yu Watanabe
1ca180b994 network/nexthop: do not remove depending nexthops when a nexthop is removed
Previously, when a nexthop is removed, depending nexthops were removed, but
that's not necessary, as the kernel keeps them, at least with v6.11.
2024-11-11 13:59:41 +00:00
Yu Watanabe
422e418ab9 network/route: update reference of the route from nexthop
Follow-up for 6f09031e4d04727cc72164fefcbc763e37556493.

The function has been introduced by the commit, but it has never been used...
2024-11-11 13:59:41 +00:00
Luca Boccassi
2e33cd7110
network: further rework for reconfiguring interfaces (#35059)
Follow-ups for #35035.
Split-out of #34989.
Fixes #35092.
2024-11-11 12:59:31 +00:00
Yu Watanabe
82df2e0f04 network: make 'networkctl reconfigure' work safely even when KeepConfiguration=dhcp or yes
Previously, even if KeepConfiguration=dhcp or yes is specified in the
new .network file, dynamic configurations like DHCP address and routes
were dropped when 'networkctl reconfigure INTERFACE' is invoked.

If the setting is specified, let's gracefully handle the dynamic
configurations. Then, 'networkctl reconfigure' can be also used for
an interface that has critical connections.
2024-11-11 11:53:24 +09:00
Yu Watanabe
e8da735ceb network: drop static configs later
Follow-up for dd6d53a8dc58c5e6e310b09ba7f7a22600a87ba9.

Unnecessary static configs will be anyway dropped later in
link_configure() -> link_drop_unmanaged_config(). Hence, even if we are
reconfiguring an interface cleanly, it is not necessary to drop static
configs here.
2024-11-11 11:53:24 +09:00
Yu Watanabe
4e76c57c7f network/dhcp-pd: do not remove unreachable route when reconfiguring non-upstream interface
Unreachable routes are not owned by any interfaces, and its ifindex is
zero. Previously, if a non-upstream interface is reconfigured, all routes
including unreachable routes configured by the upstream interface are
removed.

This makes unreachable routes are always handled by the upstream interface,
and only removed when the delegated prefixes are changed or lost.
2024-11-11 11:53:24 +09:00
Yu Watanabe
42152390da network: reorder dropping dynamic configuration
Follow-up for 451c2baf30f50b95d73e648058c7c2348dbf0c31.
2024-11-11 11:53:24 +09:00
Yu Watanabe
130d66956f test-network: reconfigure interface cleanly to drop previous DHCP lease and friends
Follow-up for 451c2baf30f50b95d73e648058c7c2348dbf0c31.

With the commits, reloading .network files does not release previously
acquired DHCP lease and friends if possible.

On graceful reconfigure triggered by the reload, the interface may
acquire a new DHCPv4 lease earlier than DHCPv6 lease. In that case,
the check will fail as it is done with the new DHCPv4 lease and old
DHCPv6 lease, which does not contain any IPv6 DNS servers or so.
So, when switching from no -> yes, we need to wait a new lease with DNS
servers or so. To achieve that, we need to clean reconfigure the interface.
2024-11-11 11:53:24 +09:00
Yu Watanabe
52f46b77d7 network: reset 'configured' flags even if we keep DHCP lease and friends on reconfigure
Follow-up for 451c2baf30f50b95d73e648058c7c2348dbf0c31.

With the commits, reloading .network files does not release previously
acquired DHCP lease and friends if possible. If previously a DHCP client
was configured as not requesting DNS servers or so, then the previously
acquired lease might not contain any DNS servers. In that case, if the
new .network file enables UseDNS=, then the interface should enter the
configured state after a new lease is acquired. To achieve that, we need
to reset the flags.

With this change, the workaround applied to the test by the commit
451c2baf30f50b95d73e648058c7c2348dbf0c31 can be dropped.
2024-11-11 11:53:24 +09:00
Yu Watanabe
525a582ae8 network: drop unnecessary size specifier
It does not save any memory usage but increase code complexity.
2024-11-11 11:53:24 +09:00
Yu Watanabe
ed3bab7a0e netwrok: call link_drop_unmanaged_config() earlier in link_configure()
Otherwise, even if a link enters the configuring state at the beginning
of link_configure(), link_check_ready() may be called before
link_drop_unmanaged_config() is called, and the link may enter the
configured state.

Fixes #35092.
2024-11-11 11:53:24 +09:00
Daan De Meyer
4b1ad0398e Introduce systemd-keyutil to do various key/certificate operations
Let's gather generic key/certificate operations in a new tool
systemd-keyutil instead of spreading them across various special
purpose tools.

Fixes #35087
2024-11-08 15:00:21 +01:00
109 changed files with 1489 additions and 612 deletions

2
TODO
View File

@ -2050,7 +2050,7 @@ Features:
with other units https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/hw-vuln/core-scheduling.rst
- ExtensionImages= deduplication for services is currently only applied to disk images without GPT envelope.
This should be extended to work with proper DDIs too, as well as directory confext/sysext. Moreover,
system-wide confex/sysext should support this too.
system-wide confext/sysext should support this too.
- Pin the mount namespace via FD by sending it back from sd-exec to the manager, and use it
for live mounting, instead of doing it via PID

View File

@ -903,7 +903,7 @@
<term><option>tpm2-pcrlock=</option></term>
<listitem><para>Takes an absolute path to a TPM2 pcrlock policy file, as produced by the
<citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>8</manvolnum></citerefentry>
tool. This permits locking LUKS2 volumes to a local policy of allowed PCR values with
variants. See
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>

View File

@ -91,7 +91,7 @@
configures the time to wait for the connectivity to get restored. If the server is
not reachable over the network for the configured time, <command>systemd-journal-upload</command>
exits. Takes a value in seconds (or in other time units if suffixed with "ms", "min", "h", etc).
For details, see <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
For details, see <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
</para>
<xi:include href="version-info.xml" xpointer="v249"/></listitem>

View File

@ -82,7 +82,7 @@
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>libudev</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>libudev</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><ulink url="https://systemd.io/PORTABILITY_AND_STABILITY/">Interface Portability and Stability Promise</ulink></member>
</simplelist></para>

View File

@ -175,7 +175,7 @@ netgroup: nis</programlisting>
<member><citerefentry><refentrytitle>nss-myhostname</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>nss-mymachines</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>nsswitch.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.syntax</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.syntax</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>

View File

@ -259,7 +259,7 @@ node /org/freedesktop/hostname1 {
are not necessary. Use
<citerefentry project="man-pages"><refentrytitle>gethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
<filename>/etc/hostname</filename> (possibly with per-distribution fallbacks), and
<citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>3</manvolnum></citerefentry>
<citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for that. For more information on these files and syscalls see the respective man pages.</para>
<para><varname>KernelName</varname>, <varname>KernelRelease</varname>, and
@ -376,7 +376,7 @@ node /org/freedesktop/hostname1 {
<para>To properly handle name lookups with changing local hostnames without having to edit
<filename>/etc/hosts</filename>, we recommend using <filename>systemd-hostnamed</filename> in combination
with <citerefentry><refentrytitle>nss-myhostname</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
with <citerefentry><refentrytitle>nss-myhostname</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
</para>
<para>Here are some recommendations to follow when generating a static (internet) hostname from a pretty

View File

@ -1553,7 +1553,7 @@ node /org/freedesktop/systemd1 {
<para>Similarly, <function>PresetUnitFiles()</function> enables/disables one or more unit files
according to the preset policy. See
<citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>7</manvolnum></citerefentry> for more
<citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more
information.</para>
<para>Similarly, <function>MaskUnitFiles()</function> masks unit files and
@ -4740,7 +4740,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<para><varname>TimeoutStartUSec</varname>, <varname>TimeoutStopUSec</varname> and
<varname>TimeoutAbortUSec</varname> contain the start, stop and abort timeouts, in microseconds. Note
the slight difference in naming when compared to the matching unit file settings (see
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>7</manvolnum></citerefentry>):
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>):
these bus properties strictly use microseconds (and thus are suffixed <varname>…USec</varname>) while
the unit file settings default to a time unit of seconds (and thus are suffixed
<varname>…Sec</varname>), unless a different unit is explicitly specified. This reflects that fact that

View File

@ -992,6 +992,7 @@ manpages = [
'systemd-journald@.service',
'systemd-journald@.socket'],
''],
['systemd-keyutil', '1', [], ''],
['systemd-localed.service', '8', ['systemd-localed'], 'ENABLE_LOCALED'],
['systemd-logind.service', '8', ['systemd-logind'], 'ENABLE_LOGIND'],
['systemd-machine-id-commit.service', '8', [], ''],

View File

@ -289,7 +289,7 @@ int main(int argc, char **argv) {
<member><citerefentry><refentrytitle>sd_id128_get_machine</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para>

View File

@ -562,7 +562,7 @@
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd_bus_creds_new_from_pid</refentrytitle><manvolnum>2</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd_bus_creds_new_from_pid</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>fork</refentrytitle><manvolnum>2</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>execve</refentrytitle><manvolnum>2</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>credentials</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>

View File

@ -56,7 +56,7 @@
parameter. The signal will be sent to path <parameter>path</parameter>, on the interface
<parameter>interface</parameter>, member <parameter>member</parameter>. When this message is
sent, no reply is expected. See
<citerefentry><refentrytitle>sd_bus_message_new_method_call</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<citerefentry><refentrytitle>sd_bus_message_new_method_call</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for a short description of the meaning of the <parameter>path</parameter>,
<parameter>interface</parameter>, and <parameter>member</parameter> parameters.
</para>

View File

@ -40,7 +40,7 @@
current location in the message <parameter>m</parameter> matches the specified
<parameter>type</parameter> and <parameter>contents</parameter>. If non-zero, parameter
<parameter>type</parameter> must be one of the types specified in
<citerefentry><refentrytitle>sd_bus_message_append</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
<citerefentry><refentrytitle>sd_bus_message_append</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
If non-null, parameter <parameter>contents</parameter> must be a valid sequence of complete
types. If both <parameter>type</parameter> and <parameter>contents</parameter> are specified
<parameter>type</parameter> must be a container type.</para>

View File

@ -156,7 +156,7 @@
</variablelist>
<para>In addition, any error returned by
<citerefentry><refentrytitle>sd_bus_send</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<citerefentry><refentrytitle>sd_bus_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>
may be returned.</para>
</refsect2>
</refsect1>

View File

@ -111,7 +111,7 @@
</variablelist>
<para>In addition, any error returned by
<citerefentry><refentrytitle>sd_bus_send</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<citerefentry><refentrytitle>sd_bus_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>
may be returned.</para>
</refsect2>
</refsect1>

View File

@ -138,7 +138,7 @@
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-hwdb</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-hwdb</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-hwdb</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>

View File

@ -29,7 +29,7 @@
<para>Various OS components process SMBIOS Type 11 vendor strings that a virtual machine manager (VMM)
may set and a virtual machine (VM) receives. SMBIOS Type 11 vendor strings may play a similar role as
<citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry>
parameters but generally are under control of the VMM rather than the boot loader or UKI.</para>
<para>For details on SMBIOS Type 11 see the <ulink url="https://www.dmtf.org/standards/smbios/">System
@ -60,7 +60,7 @@
<listitem><para>This allows configuration of additional kernel command line options, and is read by
the kernel UEFI stub. For details see
<citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
<citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
</varlistentry>
@ -70,7 +70,7 @@
<listitem><para>This allows configuration of additional kernel command line options for Boot Loader
Specification Type 1 entries, and is read by <command>systemd-boot</command>. For details see
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>

View File

@ -628,7 +628,7 @@
<listitem><para>Configures a TPM2 pcrlock policy to bind encryption to. Expects a path to a pcrlock
policy file as generated by the
<citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>8</manvolnum></citerefentry>
tool. If a TPM2 device is enrolled and this option is not used but a file
<filename>pcrlock.json</filename> is found in <filename>/run/systemd/</filename> or
<filename>/var/lib/systemd/</filename> it is automatically used. Assign an empty string to turn this

105
man/systemd-keyutil.xml Normal file
View File

@ -0,0 +1,105 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="systemd-keyutil"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>systemd-keyutil</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>systemd-keyutil</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>systemd-keyutil</refname>
<refpurpose>Perform various operations on private keys and X.509 certificates</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>systemd-keyutil</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="req">COMMAND</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><command>systemd-keyutil</command> can be used to perform various operations on private keys and
X.509 certificates.</para>
</refsect1>
<refsect1>
<title>Commands</title>
<variablelist>
<varlistentry>
<term><option>validate</option></term>
<listitem><para>Checks that we can load the private key and certificate specified with
<option>--private-key=</option> and <option>--certificate=</option> respectively.</para>
<para>As a side effect, if the private key is loaded from a PIN-protected hardware token, this
command can be used to cache the PIN in the kernel keyring. The
<varname>$SYSTEMD_ASK_PASSWORD_KEYRING_TIMEOUT_SEC</varname> and
<varname>$SYSTEMD_ASK_PASSWORD_KEYRING_TYPE</varname> environment variables can be used to control
how long and in which kernel keyring the PIN is cached.</para>
<xi:include href="version-info.xml" xpointer="v257"/>
</listitem>
</varlistentry>
<varlistentry>
<term><command>public</command></term>
<listitem><para>This commands prints the public key in PEM format extracted from either the
certificate given with <option>--certificate=</option> or the private key given with
<option>--private-key=</option>.</para>
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Options</title>
<para>The following options are understood:</para>
<variablelist>
<varlistentry>
<term><option>--private-key=<replaceable>PATH/URI</replaceable></option></term>
<term><option>--private-key-source=<replaceable>TYPE</replaceable>[:<replaceable>NAME</replaceable>]</option></term>
<term><option>--certificate=<replaceable>PATH</replaceable></option></term>
<term><option>--certificate-source=<replaceable>TYPE</replaceable>[:<replaceable>NAME</replaceable>]</option></term>
<listitem><para>Set the private key and certificate to use. The <option>--certificate=</option>
option takes a path to a PEM encoded X.509 certificate or a URI that's passed to the OpenSSL provider
configured with <option>--certificate-source</option>. The <option>--certificate-source</option>
takes one of <literal>file</literal> or <literal>provider</literal>, with the latter being followed
by a specific provider identifier, separated with a colon, e.g. <literal>provider:pkcs11</literal>.
The <option>--private-key=</option> option can take a path or a URI that will be passed to the
OpenSSL engine or provider, as specified by <option>--private-key-source=</option> as a
<literal>type:name</literal> tuple, such as <literal>engine:pkcs11</literal>.</para>
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help"/>
<xi:include href="standard-options.xml" xpointer="version"/>
</variablelist>
</refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd-sbsign</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-measure</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry>

View File

@ -86,7 +86,7 @@
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-repart</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry project='url'><refentrytitle url='https://btrfs.readthedocs.io/en/latest/mkfs.btrfs.html'>mkfs.btrfs</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>

View File

@ -104,16 +104,6 @@
<xi:include href="version-info.xml" xpointer="v252"/></listitem>
</varlistentry>
<varlistentry>
<term><command>pcrpkey</command></term>
<listitem><para>This commands prints the public key either given with <option>--public-key=</option>,
or extracted from the certificate given with <option>--certificate=</option> or the private key given
with <option>--private-key=</option>.</para>
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -90,7 +90,7 @@
<member><citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>4</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-boot-random-seed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>

View File

@ -699,7 +699,7 @@ systemd-repart --make-ddi=sysext \
systemd-sysext refresh</programlisting>
<para>The DDI generated that way may be applied to the system with
<citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
<citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
</example>
</refsect1>

View File

@ -37,7 +37,7 @@
<varname>FailureAction=exit</varname> configured by default, thus ensuring that the system is shut down as soon as
the command completes. The exit status of the command line is propagated to the invoking container manager, if
this applies (which might propagate this further, to the calling shell — e.g.
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>7</manvolnum></citerefentry> does this). If
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry> does this). If
this option is used multiple times the unit file will contain multiple <varname>ExecStart=</varname> lines, to
execute all commands in order. The command is started as regular service, i.e. with
<varname>DefaultDependencies=</varname> on. </para>
@ -55,7 +55,7 @@
<title>Example</title>
<para>Use a command like the following to add a user to the user database inside a container run with
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>7</manvolnum></citerefentry>:</para>
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>:</para>
<programlisting># systemd-nspawn -D mycontainer -b systemd.run='"adduser test"'</programlisting>
<para>(Note the requirement for double quoting in the command line above. The first level of quoting ('') is
@ -72,7 +72,7 @@
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para>

View File

@ -49,22 +49,6 @@
<xi:include href="version-info.xml" xpointer="v257"/>
</listitem>
</varlistentry>
<varlistentry>
<term><option>validate-key</option></term>
<listitem><para>Checks that we can load the private key specified with
<option>--private-key=</option>. </para>
<para>As a side effect, if the private key is loaded from a PIN-protected hardware token, this
command can be used to cache the PIN in the kernel keyring. The
<varname>$SYSTEMD_ASK_PASSWORD_KEYRING_TIMEOUT_SEC</varname> and
<varname>$SYSTEMD_ASK_PASSWORD_KEYRING_TYPE</varname> environment variables can be used to control
how long and in which kernel keyring the PIN is cached.</para>
<xi:include href="version-info.xml" xpointer="v257"/>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
@ -101,7 +85,6 @@
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="no-pager"/>
<xi:include href="standard-options.xml" xpointer="help"/>
<xi:include href="standard-options.xml" xpointer="version"/>
</variablelist>

View File

@ -152,7 +152,7 @@
in the extension image.</para>
<para>The <command>systemd-confext</command> concept follows the same principle as the
<citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry>
functionality but instead of working on <filename>/usr</filename> and <filename>/opt</filename>,
<command>confext</command> will extend only <filename>/etc</filename>. Files and directories contained
in the confext images outside of the <filename>/etc/</filename> hierarchy are <emphasis>not</emphasis>

View File

@ -152,7 +152,7 @@
going to make use of any discovered swap device, regardless if the policy would allow that or not.</para>
<para>Use the <command>image-policy</command> command of the
<citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>8</manvolnum></citerefentry> tool
<citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry> tool
to analyze image policy strings, and determine what a specific policy string means for a specific
partition.</para>
</refsect1>
@ -184,7 +184,7 @@
<member><citerefentry><refentrytitle>systemd-dissect</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>

View File

@ -40,7 +40,7 @@
<para><filename>*.pcrlock</filename> files define expected TPM2 PCR measurements of components involved
in the boot
process. <citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>1</manvolnum></citerefentry>
process. <citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>8</manvolnum></citerefentry>
uses such pcrlock files to analyze and predict TPM2 PCR measurements. The pcrlock files are JSON arrays
that follow a subset of the <ulink
url="https://trustedcomputinggroup.org/resource/canonical-event-log-format/">TCG Canonical Event Log Format
@ -292,7 +292,7 @@
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>

View File

@ -409,7 +409,7 @@
<varlistentry>
<term><filename>initrd-fs.target</filename></term>
<listitem>
<para><citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
<para><citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
automatically adds dependencies of type <varname>Before=</varname> to
<filename>sysroot-usr.mount</filename> and all mount points found in
<filename>/etc/fstab</filename> that have the <option>x-initrd.mount</option> mount option set
@ -426,10 +426,10 @@
<listitem>
<para>A special initrd target unit that is reached when the root filesystem device is available, but before
it has been mounted.
<citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
automatically setup the appropriate dependencies to make this happen.
<citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
automatically set up the appropriate dependencies to make this happen.
</para>
<xi:include href="version-info.xml" xpointer="v230"/>
@ -438,7 +438,7 @@
<varlistentry>
<term><filename>initrd-root-fs.target</filename></term>
<listitem>
<para><citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
<para><citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
automatically adds dependencies of type <varname>Before=</varname> to the
<filename>sysroot.mount</filename> unit, which is generated from the kernel command line's
<varname>root=</varname> setting (or equivalent).</para>
@ -449,7 +449,7 @@
<varlistentry>
<term><filename>initrd-usr-fs.target</filename></term>
<listitem>
<para><citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
<para><citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
automatically adds dependencies of type <varname>Before=</varname> to the
<filename>sysusr-usr.mount</filename> unit, which is generated from the kernel command line's
<varname>usr=</varname> switch. Services may order themselves after this target unit in order to
@ -495,7 +495,7 @@
<varlistentry>
<term><filename>local-fs.target</filename></term>
<listitem>
<para><citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
<para><citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
automatically adds dependencies of type
<varname>Before=</varname> to all mount units that refer to
local mount points for this target unit. In addition, it
@ -625,7 +625,7 @@
<listitem>
<para>Similar to <filename>cryptsetup.target</filename>, but for encrypted
devices which are accessed over the network. It is used for
<citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>8</manvolnum></citerefentry>
<citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>5</manvolnum></citerefentry>
entries marked with <option>_netdev</option>.</para>
<xi:include href="version-info.xml" xpointer="v235"/>
@ -636,7 +636,7 @@
<listitem>
<para>Similar to <filename>veritysetup.target</filename>, but for verity
integrity protected devices which are accessed over the network. It is used for
<citerefentry><refentrytitle>veritytab</refentrytitle><manvolnum>8</manvolnum></citerefentry>
<citerefentry><refentrytitle>veritytab</refentrytitle><manvolnum>5</manvolnum></citerefentry>
entries marked with <option>_netdev</option>.</para>
<xi:include href="version-info.xml" xpointer="v248"/>
@ -1005,7 +1005,7 @@
devices after services that synthesize these block devices. In particular, this is intended to be
used with storage services (such as
<citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>/
<citerefentry><refentrytitle>systemd-veritysetup@.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
<citerefentry><refentrytitle>systemd-veritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>)
that allocate and manage a virtual block device. Storage services are ordered before an instance of
<filename>blockdev@.target</filename>, and the consumer units after it. The ordering is
particularly relevant during shutdown, as it ensures that the mount is deactivated first and the
@ -1304,7 +1304,7 @@
<para>There are four <literal>.slice</literal> units which form the basis of the hierarchy for
assignment of resources for services, users, and virtual machines or containers. See
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>7</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details about slice units.</para>
<variablelist>
@ -1501,7 +1501,7 @@ PartOf=graphical-session.target
<para>There are four <literal>.slice</literal> units which form the basis of the user hierarchy for
assignment of resources for user applications and services. See
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>7</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details about slice units and the documentation about
<ulink url="https://systemd.io/DESKTOP_ENVIRONMENTS">Desktop Environments</ulink>
for further information.</para>

View File

@ -184,7 +184,7 @@
Read by both
<citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>systemd-sysusers</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-sysusers</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
and only honoured if no root password has been configured before.</para>
<xi:include href="version-info.xml" xpointer="v252"/>
@ -198,7 +198,7 @@
both
<citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>systemd-sysusers</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-sysusers</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
and only honoured if no root shell has been configured before.</para>
<xi:include href="version-info.xml" xpointer="v252"/>

View File

@ -1141,7 +1141,7 @@
<para>Both settings take a time span with the default unit of seconds, but other units may be
specified, see
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
The default is <literal>infinity</literal> (job timeouts disabled), except for device units where
<varname>JobRunningTimeoutSec=</varname> defaults to <varname>DefaultDeviceTimeoutSec=</varname>.
</para>
@ -1185,7 +1185,7 @@
<para><replaceable>interval</replaceable> is a time span with the default unit of seconds, but other
units may be specified, see
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
The special value <literal>infinity</literal> can be used to limit the total number of start
attempts, even if they happen at large time intervals.
Defaults to <varname>DefaultStartLimitIntervalSec=</varname> in manager configuration file, and may

View File

@ -156,7 +156,7 @@
<member><citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-dissect</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-sysupdate</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-sysupdate</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>

View File

@ -84,7 +84,7 @@
to a different server.</para>
<para>Takes a time span value. The default unit is seconds, but other units may be specified, see
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
Defaults to 5 seconds.</para>
<xi:include href="version-info.xml" xpointer="v236"/></listitem>
@ -99,7 +99,7 @@
<para>Each setting takes a time span value. The default unit is seconds, but other units may be
specified, see
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
<varname>PollIntervalMinSec=</varname> defaults to 32 seconds and must not be smaller than
16 seconds. <varname>PollIntervalMaxSec=</varname> defaults to 34 min 8 s (2048 seconds) and must be
larger than <varname>PollIntervalMinSec=</varname>.</para>
@ -113,7 +113,7 @@
are made.</para>
<para>Takes a time span value. The default unit is seconds, but other units may be specified, see
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
Defaults to 30 seconds and must not be smaller than 1 second.</para>
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
@ -127,7 +127,7 @@
reboots.</para>
<para>Takes a time interval value. The default unit is seconds, but other units may be specified, see
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
Defaults to 60 seconds.</para>
<xi:include href="version-info.xml" xpointer="v250"/></listitem>

View File

@ -2378,6 +2378,7 @@ subdir('src/integritysetup')
subdir('src/journal')
subdir('src/journal-remote')
subdir('src/kernel-install')
subdir('src/keyutil')
subdir('src/locale')
subdir('src/login')
subdir('src/machine')
@ -2699,7 +2700,7 @@ endif
mkosi_depends = public_programs
foreach executable : ['systemd-journal-remote', 'systemd-measure']
foreach executable : ['systemd-journal-remote', 'systemd-measure', 'systemd-sbsign', 'systemd-keyutil']
if executable in executables_by_name
mkosi_depends += [executables_by_name[executable]]
endif

View File

@ -7,4 +7,3 @@ ToolsTreePackages=
meson
mypy
pkgconf
ruff

View File

@ -10,5 +10,6 @@ ToolsTreePackages=
libmicrohttpd
python-jinja
python-pytest
ruff
tpm2-tss
util-linux-libs

View File

@ -13,6 +13,6 @@ ToolsTreePackages=
pkgconfig(fdisk)
pkgconfig(libmicrohttpd)
pkgconfig(mount)
tss2-devel
tpm2-tss-devel
python3-jinja2
python3-pytest

View File

@ -0,0 +1,8 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
ToolsTreeDistribution=fedora
[Build]
ToolsTreePackages=
ruff

View File

@ -12,6 +12,7 @@ ToolsTreePackages=
pkgconfig(fdisk)
pkgconfig(libmicrohttpd)
pkgconfig(mount)
python3-ruff
tss2-devel
python3-jinja2
python3-pytest

View File

@ -15,27 +15,59 @@
#include "parse-util.h"
#include "process-util.h"
#include "socket-util.h"
#include "stat-util.h"
#include "user-util.h"
#include "virt.h"
int audit_session_from_pid(pid_t pid, uint32_t *id) {
_cleanup_free_ char *s = NULL;
const char *p;
uint32_t u;
static int audit_read_field(const PidRef *pid, const char *field, char **ret) {
int r;
assert(id);
assert(field);
assert(ret);
/* We don't convert ENOENT to ESRCH here, since we can't
* really distinguish between "audit is not available in the
* kernel" and "the process does not exist", both which will
* result in ENOENT. */
if (!pidref_is_set(pid))
return -ESRCH;
p = procfs_file_alloca(pid, "sessionid");
/* Auditing is currently not virtualized for containers. Let's hence not use the audit session ID or
* login UID for now, it will be leaked in from the host */
if (detect_container() > 0)
return -ENODATA;
r = read_one_line_file(p, &s);
const char *p = procfs_file_alloca(pid->pid, field);
_cleanup_free_ char *s = NULL;
bool enoent = false;
r = read_virtual_file(p, SIZE_MAX, &s, /* ret_size= */ NULL);
if (r == -ENOENT) {
if (proc_mounted() == 0)
return -ENOSYS;
enoent = true;
} else if (r < 0)
return r;
r = pidref_verify(pid);
if (r < 0)
return r;
if (enoent) /* We got ENOENT, but /proc/ was mounted and the PID still valid? In that case it appears
* auditing is not supported by the kernel. */
return -ENODATA;
delete_trailing_chars(s, NEWLINE);
*ret = TAKE_PTR(s);
return 0;
}
int audit_session_from_pid(const PidRef *pid, uint32_t *ret_id) {
_cleanup_free_ char *s = NULL;
int r;
r = audit_read_field(pid, "sessionid", &s);
if (r < 0)
return r;
uint32_t u;
r = safe_atou32(s, &u);
if (r < 0)
return r;
@ -43,32 +75,24 @@ int audit_session_from_pid(pid_t pid, uint32_t *id) {
if (!audit_session_is_valid(u))
return -ENODATA;
*id = u;
if (ret_id)
*ret_id = u;
return 0;
}
int audit_loginuid_from_pid(pid_t pid, uid_t *uid) {
int audit_loginuid_from_pid(const PidRef *pid, uid_t *ret_uid) {
_cleanup_free_ char *s = NULL;
const char *p;
uid_t u;
int r;
assert(uid);
p = procfs_file_alloca(pid, "loginuid");
r = read_one_line_file(p, &s);
r = audit_read_field(pid, "loginuid", &s);
if (r < 0)
return r;
r = parse_uid(s, &u);
if (r == -ENXIO) /* the UID was -1 */
if (streq(s, "4294967295")) /* loginuid as 4294967295 means not part of any session. */
return -ENODATA;
if (r < 0)
return r;
*uid = u;
return 0;
return parse_uid(s, ret_uid);
}
static int try_audit_request(int fd) {
@ -113,33 +137,32 @@ bool use_audit(void) {
static int cached_use = -1;
int r;
if (cached_use < 0) {
int fd;
if (cached_use >= 0)
return cached_use;
fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_AUDIT);
if (fd < 0) {
cached_use = !IN_SET(errno, EAFNOSUPPORT, EPROTONOSUPPORT, EPERM);
if (!cached_use)
log_debug_errno(errno, "Won't talk to audit: %m");
} else {
/* If we try and use the audit fd but get -ECONNREFUSED, it is because
* we are not in the initial user namespace, and the kernel does not
* have support for audit outside of the initial user namespace
* (see https://elixir.bootlin.com/linux/latest/C/ident/audit_netlink_ok).
*
* If we receive any other error, do not disable audit because we are not
* sure that the error indicates that audit will not work in general. */
r = try_audit_request(fd);
if (r < 0) {
cached_use = r != -ECONNREFUSED;
log_debug_errno(r, cached_use ?
"Failed to make request on audit fd, ignoring: %m" :
"Won't talk to audit: %m");
} else
cached_use = true;
safe_close(fd);
}
_cleanup_close_ int fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_AUDIT);
if (fd < 0) {
cached_use = !ERRNO_IS_PRIVILEGE(errno) && !ERRNO_IS_NOT_SUPPORTED(errno);
if (cached_use)
log_debug_errno(errno, "Unexpected error while creating audit socket, proceeding with its use: %m");
else
log_debug_errno(errno, "Won't talk to audit, because feature or privilege absent: %m");
} else {
/* If we try and use the audit fd but get -ECONNREFUSED, it is because we are not in the
* initial user namespace, and the kernel does not have support for audit outside of the
* initial user namespace (see
* https://elixir.bootlin.com/linux/latest/C/ident/audit_netlink_ok).
*
* If we receive any other error, do not disable audit because we are not sure that the error
* indicates that audit will not work in general. */
r = try_audit_request(fd);
if (r < 0) {
cached_use = r != -ECONNREFUSED;
log_debug_errno(r, cached_use ?
"Failed to make request on audit fd, ignoring: %m" :
"Won't talk to audit: %m");
} else
cached_use = true;
}
return cached_use;

View File

@ -5,10 +5,12 @@
#include <stdint.h>
#include <sys/types.h>
#include "pidref.h"
#define AUDIT_SESSION_INVALID UINT32_MAX
int audit_session_from_pid(pid_t pid, uint32_t *id);
int audit_loginuid_from_pid(pid_t pid, uid_t *uid);
int audit_session_from_pid(const PidRef *pid, uint32_t *id);
int audit_loginuid_from_pid(const PidRef *pid, uid_t *uid);
bool use_audit(void);

View File

@ -81,6 +81,7 @@ const char* special_glyph_full(SpecialGlyph code, bool force_utf) {
[SPECIAL_GLYPH_BLUE_CIRCLE] = "o",
[SPECIAL_GLYPH_GREEN_CIRCLE] = "o",
[SPECIAL_GLYPH_SUPERHERO] = "S",
[SPECIAL_GLYPH_IDCARD] = "@",
},
/* UTF-8 */
@ -151,6 +152,7 @@ const char* special_glyph_full(SpecialGlyph code, bool force_utf) {
[SPECIAL_GLYPH_BLUE_CIRCLE] = u8"🔵",
[SPECIAL_GLYPH_GREEN_CIRCLE] = u8"🟢",
[SPECIAL_GLYPH_SUPERHERO] = u8"🦸",
[SPECIAL_GLYPH_IDCARD] = u8"🪪",
},
};

View File

@ -56,6 +56,7 @@ typedef enum SpecialGlyph {
SPECIAL_GLYPH_BLUE_CIRCLE,
SPECIAL_GLYPH_GREEN_CIRCLE,
SPECIAL_GLYPH_SUPERHERO,
SPECIAL_GLYPH_IDCARD,
_SPECIAL_GLYPH_MAX,
_SPECIAL_GLYPH_INVALID = -EINVAL,
} SpecialGlyph;

View File

@ -1815,6 +1815,9 @@ int namespace_fork(
int set_oom_score_adjust(int value) {
char t[DECIMAL_STR_MAX(int)];
if (!oom_score_adjust_is_valid(value))
return -EINVAL;
xsprintf(t, "%i", value);
return write_string_file("/proc/self/oom_score_adj", t,
@ -1831,11 +1834,16 @@ int get_oom_score_adjust(int *ret) {
delete_trailing_chars(t, WHITESPACE);
assert_se(safe_atoi(t, &a) >= 0);
assert_se(oom_score_adjust_is_valid(a));
r = safe_atoi(t, &a);
if (r < 0)
return r;
if (!oom_score_adjust_is_valid(a))
return -ENODATA;
if (ret)
*ret = a;
return 0;
}

View File

@ -1,17 +1,18 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('ENABLE_BINFMT') != 1
subdir_done()
endif
executables += [
libexec_template + {
'name' : 'systemd-binfmt',
'public' : true,
'conditions' : ['ENABLE_BINFMT'],
'sources' : files('binfmt.c'),
},
]
if conf.get('ENABLE_BINFMT') == 1
install_emptydir(binfmtdir)
if install_sysconfdir
install_emptydir(sysconfdir / 'binfmt.d')
endif
install_emptydir(binfmtdir)
if install_sysconfdir
install_emptydir(sysconfdir / 'binfmt.d')
endif

View File

@ -27,6 +27,7 @@ _gnu_printf_(3, 4) EFI_STATUS log_internal(EFI_STATUS status, uint8_t text_color
log_internal(status, text_color, "%s:%i@%s: " format, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
#define log_debug(...) log_full(EFI_SUCCESS, EFI_LIGHTGRAY, __VA_ARGS__)
#define log_info(...) log_full(EFI_SUCCESS, EFI_WHITE, __VA_ARGS__)
#define log_warning_status(status, ...) log_full(status, EFI_YELLOW, __VA_ARGS__)
#define log_error_status(status, ...) log_full(status, EFI_LIGHTRED, __VA_ARGS__)
#define log_error(...) log_full(EFI_INVALID_PARAMETER, EFI_LIGHTRED, __VA_ARGS__)
#define log_oom() log_full(EFI_OUT_OF_RESOURCES, EFI_LIGHTRED, "Out of memory.")

View File

@ -320,7 +320,7 @@ static void pe_locate_sections(
/* device */ NULL,
&hwids_section);
if (hwids_section.memory_offset != 0) {
if (PE_SECTION_VECTOR_IS_SET(&hwids_section)) {
hwids = (const uint8_t *) SIZE_TO_PTR(validate_base) + hwids_section.memory_offset;
EFI_STATUS err = chid_match(hwids, hwids_section.memory_size, &device);
@ -328,8 +328,7 @@ static void pe_locate_sections(
log_error_status(err, "HWID matching failed, no DT blob will be selected: %m");
hwids = NULL;
}
} else
log_info("HWIDs section is missing, no DT blob will be selected");
}
}
return pe_locate_sections_internal(
@ -359,7 +358,7 @@ static uint32_t get_compatibility_entry_address(const DosFileHeader *dos, const
PTR_TO_SIZE(dos),
&vector);
if (vector.memory_size == 0) /* not found */
if (!PE_SECTION_VECTOR_IS_SET(&vector)) /* not found */
return 0;
typedef struct {

View File

@ -43,8 +43,11 @@ static EFI_STATUS acquire_rng(void *ret, size_t size) {
return EFI_UNSUPPORTED;
err = rng->GetRNG(rng, NULL, size, ret);
/* On some systems the RNG might not be ready during early boot, handle gracefully and don't log. */
if (err == EFI_NOT_READY)
return err;
if (err != EFI_SUCCESS)
return log_error_status(err, "Failed to acquire RNG data: %m");
return log_warning_status(err, "Failed to acquire RNG data, proceeding without: %m");
return EFI_SUCCESS;
}

View File

@ -1088,7 +1088,7 @@ static int method_start_transient_unit(sd_bus_message *message, void *userdata,
m,
name,
"start",
N_("Authentication is required to start transient '$(unit)'."),
N_("Authentication is required to start transient unit '$(unit)'."),
message,
error);
if (r < 0)

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBCRYPTSETUP') != 1
subdir_done()
endif
systemd_cryptenroll_sources = files(
'cryptenroll-list.c',
'cryptenroll-password.c',
@ -24,7 +28,6 @@ executables += [
executable_template + {
'name' : 'systemd-cryptenroll',
'public' : true,
'conditions' : ['HAVE_LIBCRYPTSETUP'],
'sources' : systemd_cryptenroll_sources,
'dependencies' : [
libcryptsetup,

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBCRYPTSETUP') != 1
subdir_done()
endif
subdir('cryptsetup-tokens')
systemd_cryptsetup_sources = files(
@ -15,7 +19,6 @@ executables += [
executable_template + {
'name' : 'systemd-cryptsetup',
'public' : true,
'conditions' : ['HAVE_LIBCRYPTSETUP'],
'sources' : systemd_cryptsetup_sources,
'dependencies' : [
libcryptsetup,
@ -25,14 +28,11 @@ executables += [
},
generator_template + {
'name' : 'systemd-cryptsetup-generator',
'conditions' : ['HAVE_LIBCRYPTSETUP'],
'sources' : files('cryptsetup-generator.c'),
},
]
if conf.get('HAVE_LIBCRYPTSETUP') == 1
# symlink for backwards compatibility after rename
meson.add_install_script(sh, '-c',
ln_s.format(bindir / 'systemd-cryptsetup',
libexecdir / 'systemd-cryptsetup'))
endif
# symlink for backwards compatibility after rename
meson.add_install_script(sh, '-c',
ln_s.format(bindir / 'systemd-cryptsetup',
libexecdir / 'systemd-cryptsetup'))

View File

@ -1,17 +1,18 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_BLKID') != 1
subdir_done()
endif
executables += [
executable_template + {
'name' : 'systemd-dissect',
'public' : true,
'conditions' : ['HAVE_BLKID'],
'sources' : files('dissect.c'),
},
]
if conf.get('HAVE_BLKID') == 1
install_emptydir(sbindir)
meson.add_install_script(sh, '-c',
ln_s.format(bindir / 'systemd-dissect',
sbindir / 'mount.ddi'))
endif
install_emptydir(sbindir)
meson.add_install_script(sh, '-c',
ln_s.format(bindir / 'systemd-dissect',
sbindir / 'mount.ddi'))

View File

@ -1,17 +1,18 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('ENABLE_ENVIRONMENT_D') != 1
subdir_done()
endif
executables += [
executable_template + {
'name' : '30-systemd-environment-d-generator',
'conditions' : ['ENABLE_ENVIRONMENT_D'],
'sources' : files('environment-d-generator.c'),
'install_dir' : userenvgeneratordir,
},
]
if conf.get('ENABLE_ENVIRONMENT_D') == 1
install_emptydir(environmentdir)
meson.add_install_script(sh, '-c',
ln_s.format(sysconfdir / 'environment',
environmentdir / '99-environment.conf'))
endif
install_emptydir(environmentdir)
meson.add_install_script(sh, '-c',
ln_s.format(sysconfdir / 'environment',
environmentdir / '99-environment.conf'))

View File

@ -1,9 +1,12 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('ENABLE_HIBERNATE') != 1
subdir_done()
endif
executables += [
generator_template + {
'name' : 'systemd-hibernate-resume-generator',
'conditions' : ['ENABLE_HIBERNATE'],
'sources' : files(
'hibernate-resume-generator.c',
'hibernate-resume-config.c',
@ -11,7 +14,6 @@ executables += [
},
libexec_template + {
'name' : 'systemd-hibernate-resume',
'conditions' : ['ENABLE_HIBERNATE'],
'sources' : files(
'hibernate-resume.c',
'hibernate-resume-config.c',

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('ENABLE_HOMED') != 1
subdir_done()
endif
systemd_homework_sources = files(
'home-util.c',
'homework-blob.c',
@ -64,7 +68,6 @@ pam_systemd_home_sources = files(
executables += [
libexec_template + {
'name' : 'systemd-homework',
'conditions' : ['ENABLE_HOMED'],
'sources' : systemd_homework_sources,
'link_with' : [
libshared,
@ -82,7 +85,6 @@ executables += [
libexec_template + {
'name' : 'systemd-homed',
'dbus' : true,
'conditions' : ['ENABLE_HOMED'],
'sources' : systemd_homed_sources,
'include_directories' : includes +
include_directories('.'),
@ -96,7 +98,6 @@ executables += [
executable_template + {
'name' : 'homectl',
'public' : true,
'conditions' : ['ENABLE_HOMED'],
'sources' : homectl_sources,
'dependencies' : [
libcrypt,
@ -108,7 +109,6 @@ executables += [
},
test_template + {
'sources' : files('test-homed-regression-31896.c'),
'conditions' : ['ENABLE_HOMED'],
'type' : 'manual',
},
]
@ -116,10 +116,7 @@ executables += [
modules += [
pam_template + {
'name' : 'pam_systemd_home',
'conditions' : [
'ENABLE_HOMED',
'HAVE_PAM',
],
'conditions' : ['HAVE_PAM'],
'sources' : pam_systemd_home_sources,
'dependencies' : [
libcrypt,
@ -131,20 +128,18 @@ modules += [
},
]
if conf.get('ENABLE_HOMED') == 1
install_data('org.freedesktop.home1.conf',
install_dir : dbuspolicydir)
install_data('org.freedesktop.home1.service',
install_dir : dbussystemservicedir)
install_data('org.freedesktop.home1.policy',
install_dir : polkitpolicydir)
install_data('org.freedesktop.home1.conf',
install_dir : dbuspolicydir)
install_data('org.freedesktop.home1.service',
install_dir : dbussystemservicedir)
install_data('org.freedesktop.home1.policy',
install_dir : polkitpolicydir)
if install_sysconfdir_samples
install_data('homed.conf',
install_dir : pkgconfigfiledir)
endif
meson.add_install_script(sh, '-c',
ln_s.format(bindir / 'homectl',
bindir / 'systemd-home-fallback-shell'))
if install_sysconfdir_samples
install_data('homed.conf',
install_dir : pkgconfigfiledir)
endif
meson.add_install_script(sh, '-c',
ln_s.format(bindir / 'homectl',
bindir / 'systemd-home-fallback-shell'))

View File

@ -1,25 +1,25 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('ENABLE_HOSTNAMED') != 1
subdir_done()
endif
executables += [
libexec_template + {
'name' : 'systemd-hostnamed',
'dbus' : true,
'conditions' : ['ENABLE_HOSTNAMED'],
'sources' : files('hostnamed.c'),
},
executable_template + {
'name' : 'hostnamectl',
'public' : true,
'conditions' : ['ENABLE_HOSTNAMED'],
'sources' : files('hostnamectl.c'),
},
]
if conf.get('ENABLE_HOSTNAMED') == 1
install_data('org.freedesktop.hostname1.conf',
install_dir : dbuspolicydir)
install_data('org.freedesktop.hostname1.service',
install_dir : dbussystemservicedir)
install_data('org.freedesktop.hostname1.policy',
install_dir : polkitpolicydir)
endif
install_data('org.freedesktop.hostname1.conf',
install_dir : dbuspolicydir)
install_data('org.freedesktop.hostname1.service',
install_dir : dbussystemservicedir)
install_data('org.freedesktop.hostname1.policy',
install_dir : polkitpolicydir)

View File

@ -1,9 +1,12 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBCRYPTSETUP') != 1
subdir_done()
endif
executables += [
libexec_template + {
'name' : 'systemd-integritysetup',
'conditions' : ['HAVE_LIBCRYPTSETUP'],
'sources' : files(
'integrity-util.c',
'integritysetup.c',
@ -12,7 +15,6 @@ executables += [
},
generator_template + {
'name' : 'systemd-integritysetup-generator',
'conditions' : ['HAVE_LIBCRYPTSETUP'],
'sources' : files(
'integrity-util.c',
'integritysetup-generator.c',

View File

@ -526,8 +526,8 @@ static void client_context_really_refresh(
client_context_read_basic(c);
(void) client_context_read_label(c, label, label_size);
(void) audit_session_from_pid(c->pid, &c->auditid);
(void) audit_loginuid_from_pid(c->pid, &c->loginuid);
(void) audit_session_from_pid(&PIDREF_MAKE_FROM_PID(c->pid), &c->auditid);
(void) audit_loginuid_from_pid(&PIDREF_MAKE_FROM_PID(c->pid), &c->loginuid);
(void) client_context_read_cgroup(s, c, unit_id);
(void) client_context_read_invocation_id(s, c);

292
src/keyutil/keyutil.c Normal file
View File

@ -0,0 +1,292 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <getopt.h>
#include <unistd.h>
#include "alloc-util.h"
#include "ask-password-api.h"
#include "build.h"
#include "fd-util.h"
#include "main-func.h"
#include "memstream-util.h"
#include "openssl-util.h"
#include "parse-argument.h"
#include "pretty-print.h"
#include "verbs.h"
static char *arg_private_key = NULL;
static KeySourceType arg_private_key_source_type = OPENSSL_KEY_SOURCE_FILE;
static char *arg_private_key_source = NULL;
static char *arg_certificate = NULL;
static char *arg_certificate_source = NULL;
static CertificateSourceType arg_certificate_source_type = OPENSSL_CERTIFICATE_SOURCE_FILE;
STATIC_DESTRUCTOR_REGISTER(arg_private_key, freep);
STATIC_DESTRUCTOR_REGISTER(arg_private_key_source, freep);
STATIC_DESTRUCTOR_REGISTER(arg_certificate, freep);
STATIC_DESTRUCTOR_REGISTER(arg_certificate_source, freep);
static int help(int argc, char *argv[], void *userdata) {
_cleanup_free_ char *link = NULL;
int r;
r = terminal_urlify_man("systemd-keyutil", "1", &link);
if (r < 0)
return log_oom();
printf("%1$s [OPTIONS...] COMMAND ...\n"
"\n%5$sPerform various operations on private keys and certificates.%6$s\n"
"\n%3$sCommands:%4$s\n"
" validate Load and validate the given certificate and private key\n"
" public Extract a public key\n"
"\n%3$sOptions:%4$s\n"
" -h --help Show this help\n"
" --version Print version\n"
" --private-key=KEY Private key in PEM format\n"
" --private-key-source=file|provider:PROVIDER|engine:ENGINE\n"
" Specify how to use KEY for --private-key=. Allows\n"
" an OpenSSL engine/provider to be used for signing\n"
" --certificate=PATH|URI\n"
" PEM certificate to use for signing, or a provider\n"
" specific designation if --certificate-source= is used\n"
" --certificate-source=file|provider:PROVIDER\n"
" Specify how to interpret the certificate from\n"
" --certificate=. Allows the certificate to be loaded\n"
" from an OpenSSL provider\n"
"\nSee the %2$s for details.\n",
program_invocation_short_name,
link,
ansi_underline(),
ansi_normal(),
ansi_highlight(),
ansi_normal());
return 0;
}
static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
ARG_PRIVATE_KEY,
ARG_PRIVATE_KEY_SOURCE,
ARG_CERTIFICATE,
ARG_CERTIFICATE_SOURCE,
};
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{ "private-key", required_argument, NULL, ARG_PRIVATE_KEY },
{ "private-key-source", required_argument, NULL, ARG_PRIVATE_KEY_SOURCE },
{ "certificate", required_argument, NULL, ARG_CERTIFICATE },
{ "certificate-source", required_argument, NULL, ARG_CERTIFICATE_SOURCE },
{}
};
int c, r;
assert(argc >= 0);
assert(argv);
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
switch (c) {
case 'h':
help(0, NULL, NULL);
return 0;
case ARG_VERSION:
return version();
case ARG_PRIVATE_KEY:
r = free_and_strdup_warn(&arg_private_key, optarg);
if (r < 0)
return r;
break;
case ARG_PRIVATE_KEY_SOURCE:
r = parse_openssl_key_source_argument(
optarg,
&arg_private_key_source,
&arg_private_key_source_type);
if (r < 0)
return r;
break;
case ARG_CERTIFICATE:
r = free_and_strdup_warn(&arg_certificate, optarg);
if (r < 0)
return r;
break;
case ARG_CERTIFICATE_SOURCE:
r = parse_openssl_certificate_source_argument(
optarg,
&arg_certificate_source,
&arg_certificate_source_type);
if (r < 0)
return r;
break;
case '?':
return -EINVAL;
default:
assert_not_reached();
}
if (arg_private_key_source && !arg_certificate)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "When using --private-key-source=, --certificate= must be specified.");
return 1;
}
static int verb_validate(int argc, char *argv[], void *userdata) {
_cleanup_(X509_freep) X509 *certificate = NULL;
_cleanup_(openssl_ask_password_ui_freep) OpenSSLAskPasswordUI *ui = NULL;
_cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = NULL;
int r;
if (!arg_certificate)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"No certificate specified, use --certificate=");
if (!arg_private_key)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"No private key specified, use --private-key=.");
if (arg_certificate_source_type == OPENSSL_CERTIFICATE_SOURCE_FILE) {
r = parse_path_argument(arg_certificate, /*suppress_root=*/ false, &arg_certificate);
if (r < 0)
return r;
}
r = openssl_load_x509_certificate(
arg_certificate_source_type,
arg_certificate_source,
arg_certificate,
&certificate);
if (r < 0)
return log_error_errno(r, "Failed to load X.509 certificate from %s: %m", arg_certificate);
if (arg_private_key_source_type == OPENSSL_KEY_SOURCE_FILE) {
r = parse_path_argument(arg_private_key, /* suppress_root= */ false, &arg_private_key);
if (r < 0)
return log_error_errno(r, "Failed to parse private key path %s: %m", arg_private_key);
}
r = openssl_load_private_key(
arg_private_key_source_type,
arg_private_key_source,
arg_private_key,
&(AskPasswordRequest) {
.id = "keyutil-private-key-pin",
.keyring = arg_private_key,
.credential = "keyutil.private-key-pin",
},
&private_key,
&ui);
if (r < 0)
return log_error_errno(r, "Failed to load private key from %s: %m", arg_private_key);
puts("OK");
return 0;
}
static int verb_public(int argc, char *argv[], void *userdata) {
_cleanup_(EVP_PKEY_freep) EVP_PKEY *public_key = NULL;
int r;
if (arg_certificate) {
_cleanup_(X509_freep) X509 *certificate = NULL;
if (arg_certificate_source_type == OPENSSL_CERTIFICATE_SOURCE_FILE) {
r = parse_path_argument(arg_certificate, /*suppress_root=*/ false, &arg_certificate);
if (r < 0)
return r;
}
r = openssl_load_x509_certificate(
arg_certificate_source_type,
arg_certificate_source,
arg_certificate,
&certificate);
if (r < 0)
return log_error_errno(r, "Failed to load X.509 certificate from %s: %m", arg_certificate);
public_key = X509_get_pubkey(certificate);
if (!public_key)
return log_error_errno(
SYNTHETIC_ERRNO(EIO),
"Failed to extract public key from certificate %s.",
arg_certificate);
} else if (arg_private_key) {
_cleanup_(openssl_ask_password_ui_freep) OpenSSLAskPasswordUI *ui = NULL;
_cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = NULL;
if (arg_private_key_source_type == OPENSSL_KEY_SOURCE_FILE) {
r = parse_path_argument(arg_private_key, /* suppress_root= */ false, &arg_private_key);
if (r < 0)
return log_error_errno(r, "Failed to parse private key path %s: %m", arg_private_key);
}
r = openssl_load_private_key(
arg_private_key_source_type,
arg_private_key_source,
arg_private_key,
&(AskPasswordRequest) {
.id = "keyutil-private-key-pin",
.keyring = arg_private_key,
.credential = "keyutil.private-key-pin",
},
&private_key,
&ui);
if (r < 0)
return log_error_errno(r, "Failed to load private key from %s: %m", arg_private_key);
_cleanup_(memstream_done) MemStream m = {};
FILE *tf = memstream_init(&m);
if (!tf)
return log_oom();
if (i2d_PUBKEY_fp(tf, private_key) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to extract public key from private key file '%s'.", arg_private_key);
fflush(tf);
rewind(tf);
if (!d2i_PUBKEY_fp(tf, &public_key))
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to parse extracted public key of private key file '%s'.", arg_private_key);
} else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "One of --certificate=, or --private-key= must be specified");
if (PEM_write_PUBKEY(stdout, public_key) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key to stdout");
return 0;
}
static int run(int argc, char *argv[]) {
static const Verb verbs[] = {
{ "help", VERB_ANY, VERB_ANY, 0, help },
{ "validate", VERB_ANY, 1, 0, verb_validate },
{ "public", VERB_ANY, 1, 0, verb_public },
{}
};
int r;
log_setup();
r = parse_argv(argc, argv);
if (r <= 0)
return r;
return dispatch_verb(argc, argv, verbs, NULL);
}
DEFINE_MAIN_FUNCTION(run);

12
src/keyutil/meson.build Normal file
View File

@ -0,0 +1,12 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
executables += [
libexec_template + {
'name' : 'systemd-keyutil',
'conditions' : [
'HAVE_OPENSSL',
],
'sources' : files('keyutil.c'),
'dependencies' : libopenssl,
},
]

View File

@ -1118,7 +1118,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, PidRef *pidref, pid_t tid
}
if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
r = audit_session_from_pid(pidref->pid, &c->audit_session_id);
r = audit_session_from_pid(pidref, &c->audit_session_id);
if (r == -ENODATA) {
/* ENODATA means: no audit session id assigned */
c->audit_session_id = AUDIT_SESSION_INVALID;
@ -1131,7 +1131,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, PidRef *pidref, pid_t tid
}
if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
r = audit_loginuid_from_pid(pidref->pid, &c->audit_login_uid);
r = audit_loginuid_from_pid(pidref, &c->audit_login_uid);
if (r == -ENODATA) {
/* ENODATA means: no audit login uid assigned */
c->audit_login_uid = UID_INVALID;

View File

@ -1006,7 +1006,7 @@ static int create_session(
"Maximum number of sessions (%" PRIu64 ") reached, refusing further sessions.",
m->sessions_max);
(void) audit_session_from_pid(leader.pid, &audit_id);
(void) audit_session_from_pid(&leader, &audit_id);
if (audit_session_is_valid(audit_id)) {
/* Keep our session IDs and the audit session IDs in sync */

View File

@ -254,7 +254,7 @@ int session_set_leader_consume(Session *s, PidRef _leader) {
s->leader_fd_saved = true;
}
(void) audit_session_from_pid(s->leader.pid, &s->audit_id);
(void) audit_session_from_pid(&s->leader, &s->audit_id);
return 1;
}

View File

@ -7,6 +7,7 @@
#include "sd-varlink.h"
#include "bus-polkit.h"
#include "copy.h"
#include "fd-util.h"
#include "hostname-util.h"
#include "json-util.h"
@ -570,3 +571,191 @@ int vl_method_open(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
return sd_varlink_reply(link, v);
}
typedef struct MachineCopyParameters {
const char *name;
PidRef pidref;
char *src, *dest;
bool replace;
} MachineCopyParameters;
static void machine_copy_paramaters_done(MachineCopyParameters *p) {
assert(p);
pidref_done(&p->pidref);
free(p->src);
free(p->dest);
}
static int copy_done(Operation *operation, int ret, sd_bus_error *error) {
assert(operation);
assert(operation->link);
// TODO(ikruglov): maybe just leaving a plain errno in response?
if (ret == -EPERM || ret == -EACCES)
return sd_varlink_error(operation->link, SD_VARLINK_ERROR_PERMISSION_DENIED, NULL);
if (ERRNO_IS_NEG_NOT_SUPPORTED(ret))
return sd_varlink_error(operation->link, "io.systemd.Machine.NotSupported", NULL);
if (ret == -ENOENT)
return sd_varlink_error(operation->link, "io.systemd.Machine.NoSuchFile", NULL);
if (ret == -EEXIST)
return sd_varlink_error(operation->link, "io.systemd.Machine.FileExists", NULL);
if (ret < 0)
return sd_varlink_error_errno(operation->link, ret);
return sd_varlink_reply(operation->link, NULL);
}
int vl_method_copy_internal(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata, bool copy_from) {
static const sd_json_dispatch_field dispatch_table[] = {
VARLINK_DISPATCH_MACHINE_LOOKUP_FIELDS(MachineCopyParameters),
{ "source", SD_JSON_VARIANT_STRING, json_dispatch_path, offsetof(MachineCopyParameters, src), SD_JSON_MANDATORY },
{ "destination", SD_JSON_VARIANT_STRING, json_dispatch_path, offsetof(MachineCopyParameters, dest), 0 },
{ "replace", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(MachineCopyParameters, replace), 0 },
VARLINK_DISPATCH_POLKIT_FIELD,
{}
};
Manager *manager = ASSERT_PTR(userdata);
_cleanup_close_ int hostfd = -EBADF, mntns_fd = -EBADF;
_cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
_cleanup_(machine_copy_paramaters_done) MachineCopyParameters p = { .pidref = PIDREF_NULL };
_cleanup_free_ char *host_basename = NULL, *container_basename = NULL;
CopyFlags copy_flags = COPY_REFLINK|COPY_MERGE|COPY_HARDLINKS;
uid_t uid_shift;
pid_t child;
int r;
assert(link);
assert(parameters);
if (manager->n_operations >= OPERATIONS_MAX)
return sd_varlink_error(link, "io.systemd.MachineImage.TooManyOperations", NULL);
r = sd_varlink_dispatch(link, parameters, dispatch_table, &p);
if (r != 0)
return r;
/* There is no need for extra validation since path_is_absolute() does path_is_valid() and path_is_absolute().*/
const char *dest = p.dest ?: p.src;
const char *container_path = copy_from ? p.src : dest;
const char *host_path = copy_from ? dest : p.src;
copy_flags |= p.replace ? COPY_REPLACE : 0;
Machine *machine;
r = lookup_machine_by_name_or_pidref(link, manager, p.name, &p.pidref, &machine);
if (r == -ESRCH)
return sd_varlink_error(link, "io.systemd.Machine.NoSuchMachine", NULL);
if (r != 0)
return r;
if (machine->class != MACHINE_CONTAINER)
return sd_varlink_error(link, "io.systemd.Machine.NotSupported", NULL);
r = varlink_verify_polkit_async(
link,
manager->bus,
"org.freedesktop.machine1.manage-machines",
(const char**) STRV_MAKE("name", machine->name,
"verb", "copy",
"src", p.src,
"dest", dest),
&manager->polkit_registry);
if (r <= 0)
return r;
r = path_extract_filename(host_path, &host_basename);
if (r < 0)
return log_debug_errno(r, "Failed to extract file name of '%s' path: %m", host_path);
r = path_extract_filename(container_path, &container_basename);
if (r < 0)
return log_debug_errno(r, "Failed to extract file name of '%s' path: %m", container_path);
hostfd = open_parent(host_path, O_CLOEXEC, 0);
if (hostfd < 0)
return log_debug_errno(hostfd, "Failed to open host directory %s: %m", host_path);
r = machine_get_uid_shift(machine, &uid_shift);
if (r < 0)
return log_debug_errno(r, "Failed to get machine UID shift: %m");
r = pidref_namespace_open(&machine->leader,
/* ret_pidns_fd = */ NULL,
&mntns_fd,
/* ret_netns_fd = */ NULL,
/* ret_userns_fd = */ NULL,
/* ret_root_fd = */ NULL);
if (r < 0)
return log_debug_errno(r, "Failed to open namespace: %m");
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return log_debug_errno(errno, "Failed to create pipe: %m");
r = namespace_fork("(sd-copyns)",
"(sd-copy)",
/* except_fds = */ NULL,
/* n_except_fds = */ 0,
FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL,
/* pidns_fd = */ -1,
mntns_fd,
/* netns_fd = */ -1,
/* userns_fd = */ -1,
/* root_fd = */ -1,
&child);
if (r < 0)
return log_debug_errno(r, "Failed to fork(): %m");
if (r == 0) {
errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
_cleanup_close_ int containerfd = -EBADF;
containerfd = open_parent(container_path, O_CLOEXEC, 0);
if (containerfd < 0) {
log_error_errno(containerfd, "Failed to open destination directory: %m");
report_errno_and_exit(errno_pipe_fd[1], containerfd);
}
/* Run the actual copy operation. Note that when a UID shift is set we'll either clamp the UID/GID to */
/* 0 or to the actual UID shift depending on the direction we copy. If no UID shift is set we'll copy */
/* the UID/GIDs as they are. */
r = copy_from ? copy_tree_at(
containerfd,
container_basename,
hostfd,
host_basename,
uid_shift == 0 ? UID_INVALID : 0,
uid_shift == 0 ? GID_INVALID : 0,
copy_flags,
/* denylist = */ NULL,
/* subvolumes = */ NULL)
: copy_tree_at(
hostfd,
host_basename,
containerfd,
container_basename,
uid_shift == 0 ? UID_INVALID : uid_shift,
uid_shift == 0 ? GID_INVALID : uid_shift,
copy_flags,
/* denylist = */ NULL,
/* subvolumes = */ NULL);
if (r < 0)
log_error_errno(r, "Failed to copy tree: %m");
report_errno_and_exit(errno_pipe_fd[1], r);
}
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
Operation *operation;
r = operation_new_with_varlink_reply(manager, machine, child, link, errno_pipe_fd[0], &operation);
if (r < 0) {
sigkill_wait(child);
return r;
}
operation->done = copy_done;
TAKE_FD(errno_pipe_fd[0]);
return 1;
}

View File

@ -25,3 +25,4 @@ int vl_method_unregister_internal(sd_varlink *link, sd_json_variant *parameters,
int vl_method_terminate_internal(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_open(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_copy_internal(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata, bool copy_from);

View File

@ -590,6 +590,13 @@ static int vl_method_terminate(sd_varlink *link, sd_json_variant *parameters, sd
return lookup_machine_and_call_method(link, parameters, flags, userdata, vl_method_terminate_internal);
}
static int vl_method_copy_from(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
return vl_method_copy_internal(link, parameters, flags, userdata, /* copy_from = */ true);
}
static int vl_method_copy_to(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
return vl_method_copy_internal(link, parameters, flags, userdata, /* copy_from = */ false);
}
static int list_image_one_and_maybe_read_metadata(sd_varlink *link, Image *image, bool more, AcquireMetadata am) {
int r;
@ -774,6 +781,8 @@ static int manager_varlink_init_machine(Manager *m) {
"io.systemd.Machine.Terminate", vl_method_terminate,
"io.systemd.Machine.Kill", vl_method_kill,
"io.systemd.Machine.Open", vl_method_open,
"io.systemd.Machine.CopyFrom", vl_method_copy_from,
"io.systemd.Machine.CopyTo", vl_method_copy_to,
"io.systemd.MachineImage.List", vl_method_list_images,
"io.systemd.MachineImage.Update", vl_method_update_image,
"io.systemd.MachineImage.Clone", vl_method_clone_image,

View File

@ -46,10 +46,13 @@ static int operation_done(sd_event_source *s, const siginfo_t *si, void *userdat
if (r < 0)
log_debug_errno(r, "Operation failed: %m");
/* If a completion routine (o->done) is set for this operation, call it. It sends a response, but can return an error in which case it expect us to reply.
* Otherwise, the default action is to simply return an error on failure or an empty success message on success. */
if (o->message) {
/* If a completion routine (o->done) is set for this operation,
* call it. It sends a response, but can return an error in
* which case it expect us to reply. Otherwise, the default
* action is to simply return an error on failure or an empty
* success message on success. */
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
if (o->done)
r = o->done(o, r, &error);
@ -68,13 +71,13 @@ static int operation_done(sd_event_source *s, const siginfo_t *si, void *userdat
log_error_errno(r, "Failed to reply to dbus message: %m");
}
} else if (o->link) {
/* If a completion routine (o->done) is set for this operation,
* then it's completely response for sending a response */
if (o->done)
r = o->done(o, r, /* error = */ NULL);
if (r < 0)
(void) o->done(o, r, /* error = */ NULL);
else if (r < 0)
(void) sd_varlink_error_errno(o->link, r);
else if (!o->done)
/* when o->done set it's responsible for sending reply in a happy-path case */
else
(void) sd_varlink_reply(o->link, NULL);
} else
assert_not_reached();

View File

@ -77,7 +77,6 @@ static int help(int argc, char *argv[], void *userdata) {
" status Show current PCR values\n"
" calculate Calculate expected PCR values\n"
" sign Calculate and sign expected PCR values\n"
" pcrpkey Extract the PCR public key\n"
"\n%3$sOptions:%4$s\n"
" -h --help Show this help\n"
" --version Print version\n"
@ -1174,100 +1173,12 @@ static int verb_status(int argc, char *argv[], void *userdata) {
return 0;
}
static int verb_pcrpkey(int argc, char *argv[], void *userdata) {
_cleanup_(EVP_PKEY_freep) EVP_PKEY *public_key = NULL;
int r;
if (arg_public_key) {
_cleanup_fclose_ FILE *public_keyf = NULL;
public_keyf = fopen(arg_public_key, "re");
if (!public_keyf)
return log_error_errno(errno, "Failed to open public key file '%s': %m", arg_public_key);
public_key = PEM_read_PUBKEY(public_keyf, NULL, NULL, NULL);
if (!public_key)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key '%s'.", arg_public_key);
} else if (arg_certificate) {
_cleanup_(X509_freep) X509 *certificate = NULL;
if (arg_certificate_source_type == OPENSSL_CERTIFICATE_SOURCE_FILE) {
r = parse_path_argument(arg_certificate, /*suppress_root=*/ false, &arg_certificate);
if (r < 0)
return r;
}
r = openssl_load_x509_certificate(
arg_certificate_source_type,
arg_certificate_source,
arg_certificate,
&certificate);
if (r < 0)
return log_error_errno(r, "Failed to load X.509 certificate from %s: %m", arg_certificate);
public_key = X509_get_pubkey(certificate);
if (!public_key)
return log_error_errno(
SYNTHETIC_ERRNO(EIO),
"Failed to extract public key from certificate %s.",
arg_certificate);
} else if (arg_private_key) {
_cleanup_(openssl_ask_password_ui_freep) OpenSSLAskPasswordUI *ui = NULL;
_cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = NULL;
if (arg_private_key_source_type == OPENSSL_KEY_SOURCE_FILE) {
r = parse_path_argument(arg_private_key, /* suppress_root= */ false, &arg_private_key);
if (r < 0)
return log_error_errno(r, "Failed to parse private key path %s: %m", arg_private_key);
}
r = openssl_load_private_key(
arg_private_key_source_type,
arg_private_key_source,
arg_private_key,
&(AskPasswordRequest) {
.id = "measure-private-key-pin",
.keyring = arg_private_key,
.credential = "measure.private-key-pin",
},
&private_key,
&ui);
if (r < 0)
return log_error_errno(r, "Failed to load private key from %s: %m", arg_private_key);
_cleanup_(memstream_done) MemStream m = {};
FILE *tf = memstream_init(&m);
if (!tf)
return log_oom();
if (i2d_PUBKEY_fp(tf, private_key) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to extract public key from private key file '%s'.", arg_private_key);
fflush(tf);
rewind(tf);
if (!d2i_PUBKEY_fp(tf, &public_key))
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to parse extracted public key of private key file '%s'.", arg_private_key);
} else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "One of --public-key=, --certificate=, or --private-key= must be specified");
if (PEM_write_PUBKEY(stdout, public_key) == 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key to stdout");
return 0;
}
static int measure_main(int argc, char *argv[]) {
static const Verb verbs[] = {
{ "help", VERB_ANY, VERB_ANY, 0, help },
{ "status", VERB_ANY, 1, VERB_DEFAULT, verb_status },
{ "calculate", VERB_ANY, 1, 0, verb_calculate },
{ "sign", VERB_ANY, 1, 0, verb_sign },
{ "pcrpkey", VERB_ANY, 1, 0, verb_pcrpkey },
{}
};

View File

@ -1,17 +1,18 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_KMOD') != 1
subdir_done()
endif
executables += [
libexec_template + {
'name' : 'systemd-modules-load',
'conditions' : ['HAVE_KMOD'],
'sources' : files('modules-load.c'),
'dependencies' : libkmod_cflags,
},
]
if conf.get('HAVE_KMOD') == 1
install_emptydir(modulesloaddir)
if install_sysconfdir
install_emptydir(sysconfdir / 'modules-load.d')
endif
install_emptydir(modulesloaddir)
if install_sysconfdir
install_emptydir(sysconfdir / 'modules-load.d')
endif

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('ENABLE_MOUNTFSD') != 1
subdir_done()
endif
systemd_mountwork_sources = files(
'mountwork.c',
)
@ -12,12 +16,10 @@ systemd_mountfsd_sources = files(
executables += [
libexec_template + {
'name' : 'systemd-mountfsd',
'conditions' : ['ENABLE_MOUNTFSD'],
'sources' : systemd_mountfsd_sources,
},
libexec_template + {
'name' : 'systemd-mountwork',
'conditions' : ['ENABLE_MOUNTFSD'],
'sources' : systemd_mountwork_sources,
},
]

View File

@ -276,7 +276,6 @@ static int vl_method_mount_image(
Hashmap **polkit_registry = ASSERT_PTR(userdata);
_cleanup_free_ char *ps = NULL;
bool image_is_trusted = false;
uid_t peer_uid;
int r;
assert(link);
@ -284,10 +283,6 @@ static int vl_method_mount_image(
sd_json_variant_sensitive(parameters); /* might contain passwords */
r = sd_varlink_get_peer_uid(link, &peer_uid);
if (r < 0)
return log_debug_errno(r, "Failed to get client UID: %m");
r = sd_varlink_dispatch(link, parameters, dispatch_table, &p);
if (r != 0)
return r;
@ -527,17 +522,13 @@ static int vl_method_mount_image(
loop_device_relinquish(loop);
r = sd_varlink_replybo(
return sd_varlink_replybo(
link,
SD_JSON_BUILD_PAIR("partitions", SD_JSON_BUILD_VARIANT(aj)),
SD_JSON_BUILD_PAIR("imagePolicy", SD_JSON_BUILD_STRING(ps)),
SD_JSON_BUILD_PAIR("imageSize", SD_JSON_BUILD_INTEGER(di->image_size)),
SD_JSON_BUILD_PAIR("sectorSize", SD_JSON_BUILD_INTEGER(di->sector_size)),
SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(di->image_uuid), "imageUuid", SD_JSON_BUILD_UUID(di->image_uuid)));
if (r < 0)
return r;
return r;
}
static int process_connection(sd_varlink_server *server, int _fd) {

View File

@ -613,8 +613,49 @@ static int dhcp_pd_finalize(Link *link) {
return 0;
}
void dhcp_pd_prefix_lost(Link *uplink) {
static void dhcp_pd_mark_unreachable_route(Manager *manager, NetworkConfigSource source) {
assert(manager);
Route *route;
SET_FOREACH(route, manager->routes) {
if (route->source != source)
continue;
if (route->family != AF_INET6)
continue;
if (route->nexthop.ifindex != 0) /* IPv6 unreachable has 0 ifindex. */
continue;
if (!route_type_is_reject(route->type))
continue;
route_mark(route);
}
}
static int dhcp_pd_remove_unreachable_route(Manager *manager, NetworkConfigSource source, bool only_marked) {
int ret = 0;
assert(manager);
Route *route;
SET_FOREACH(route, manager->routes) {
if (route->source != source)
continue;
if (route->family != AF_INET6)
continue;
if (route->nexthop.ifindex != 0) /* IPv6 unreachable has 0 ifindex. */
continue;
if (!route_type_is_reject(route->type))
continue;
if (only_marked && !route_is_marked(route))
continue;
RET_GATHER(ret, route_remove_and_cancel(route, manager));
}
return ret;
}
static void dhcp_pd_prefix_lost(Link *uplink, NetworkConfigSource source) {
Link *link;
int r;
@ -630,22 +671,7 @@ void dhcp_pd_prefix_lost(Link *uplink) {
link_enter_failed(link);
}
SET_FOREACH(route, uplink->manager->routes) {
if (!IN_SET(route->source, NETWORK_CONFIG_SOURCE_DHCP4, NETWORK_CONFIG_SOURCE_DHCP6))
continue;
if (route->family != AF_INET6)
continue;
if (route->type != RTN_UNREACHABLE)
continue;
if (!set_contains(uplink->dhcp_pd_prefixes,
&(struct in_addr_prefix) {
.family = AF_INET6,
.prefixlen = route->dst_prefixlen,
.address = route->dst }))
continue;
(void) route_remove_and_cancel(route, uplink->manager);
}
(void) dhcp_pd_remove_unreachable_route(uplink->manager, source, /* only_marked = */ false);
set_clear(uplink->dhcp_pd_prefixes);
}
@ -653,13 +679,20 @@ void dhcp_pd_prefix_lost(Link *uplink) {
void dhcp4_pd_prefix_lost(Link *uplink) {
Link *tunnel;
dhcp_pd_prefix_lost(uplink);
assert(uplink);
assert(uplink->manager);
dhcp_pd_prefix_lost(uplink, NETWORK_CONFIG_SOURCE_DHCP4);
if (uplink->dhcp4_6rd_tunnel_name &&
link_get_by_name(uplink->manager, uplink->dhcp4_6rd_tunnel_name, &tunnel) >= 0)
(void) link_remove(tunnel);
}
void dhcp6_pd_prefix_lost(Link *uplink) {
dhcp_pd_prefix_lost(uplink, NETWORK_CONFIG_SOURCE_DHCP6);
}
static int dhcp4_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
int r;
@ -1005,9 +1038,11 @@ int dhcp4_pd_prefix_acquired(Link *uplink) {
return r;
/* Request unreachable route */
dhcp_pd_mark_unreachable_route(uplink->manager, NETWORK_CONFIG_SOURCE_DHCP4);
r = dhcp4_request_unreachable_route(uplink, &pd_prefix, pd_prefixlen, lifetime_usec, &server_address);
if (r < 0)
return r;
(void) dhcp_pd_remove_unreachable_route(uplink->manager, NETWORK_CONFIG_SOURCE_DHCP4, /* only_marked = */ true);
/* Create or update 6rd SIT tunnel device. */
r = dhcp4_pd_create_6rd_tunnel(uplink, dhcp4_pd_6rd_tunnel_create_handler);
@ -1085,11 +1120,14 @@ int dhcp6_pd_prefix_acquired(Link *uplink) {
assert(uplink);
assert(uplink->dhcp6_lease);
assert(uplink->manager);
r = sd_dhcp6_lease_get_server_address(uplink->dhcp6_lease, &server_address.in6);
if (r < 0)
return log_link_warning_errno(uplink, r, "Failed to get server address of DHCPv6 lease: %m");
dhcp_pd_mark_unreachable_route(uplink->manager, NETWORK_CONFIG_SOURCE_DHCP6);
/* First, logs acquired prefixes and request unreachable routes. */
FOREACH_DHCP6_PD_PREFIX(uplink->dhcp6_lease) {
usec_t lifetime_valid_usec;
@ -1120,6 +1158,8 @@ int dhcp6_pd_prefix_acquired(Link *uplink) {
return r;
}
(void) dhcp_pd_remove_unreachable_route(uplink->manager, NETWORK_CONFIG_SOURCE_DHCP6, /* only_marked = */ true);
/* Then, assign subnet prefixes. */
HASHMAP_FOREACH(link, uplink->manager->links_by_index) {
if (!dhcp_pd_is_uplink(link, uplink, /* accept_auto = */ true))
@ -1254,14 +1294,21 @@ int dhcp_request_prefix_delegation(Link *link) {
int link_drop_dhcp_pd_config(Link *link, Network *network) {
assert(link);
assert(network);
assert(link->network);
if (!link_dhcp_pd_is_enabled(link))
if (link->network == network)
return 0; /* .network file is unchanged. It is not necessary to reconfigure the client. */
if (!link_dhcp_pd_is_enabled(link)) /* Disabled now, drop all configs. */
return dhcp_pd_remove(link, /* only_marked = */ false);
/* If previously explicitly disabled, then there is nothing we need to drop.
* If this is called on start up, we do not know the previous settings, assume nothing changed. */
if (!network || !network->dhcp_pd)
return 0;
/* If will be disabled or at least one config is changed, then drop all configurations. */
if (!network->dhcp_pd ||
link->network->dhcp_pd_assign != network->dhcp_pd_assign ||
/* If at least one setting is changed, then drop all configurations. */
if (link->network->dhcp_pd_assign != network->dhcp_pd_assign ||
(link->network->dhcp_pd_assign &&
(link->network->dhcp_pd_manage_temporary_address != network->dhcp_pd_manage_temporary_address ||
!set_equal(link->network->dhcp_pd_tokens, network->dhcp_pd_tokens))) ||

View File

@ -20,8 +20,8 @@ int dhcp_request_prefix_delegation(Link *link);
int link_drop_dhcp_pd_config(Link *link, Network *network);
int dhcp4_pd_prefix_acquired(Link *uplink);
int dhcp6_pd_prefix_acquired(Link *uplink);
void dhcp_pd_prefix_lost(Link *uplink);
void dhcp4_pd_prefix_lost(Link *uplink);
void dhcp6_pd_prefix_lost(Link *uplink);
int dhcp_pd_reconfigure_address(Address *address, Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_pd_subnet_id);

View File

@ -247,7 +247,7 @@ static int dhcp4_remove_address_and_routes(Link *link, bool only_marked) {
SET_FOREACH(route, link->manager->routes) {
if (route->source != NETWORK_CONFIG_SOURCE_DHCP4)
continue;
if (route->nexthop.ifindex != 0 && route->nexthop.ifindex != link->ifindex)
if (route->nexthop.ifindex != link->ifindex)
continue;
if (only_marked && !route_is_marked(route))
continue;
@ -1837,15 +1837,22 @@ int link_drop_dhcp4_config(Link *link, Network *network) {
int ret = 0;
assert(link);
assert(network);
assert(link->network);
if (!link_dhcp4_enabled(link))
return 0; /* Currently DHCPv4 client is not enabled, there is nothing we need to drop. */
if (link->network == network)
return 0; /* .network file is unchanged. It is not necessary to reconfigure the client. */
if (!FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV4))
/* Currently enabled but will be disabled. Stop the client and drop the lease. */
if (!link_dhcp4_enabled(link)) {
/* DHCP client is disabled. Stop the client if it is running and drop the lease. */
ret = sd_dhcp_client_stop(link->dhcp_client);
/* Also explicitly drop DHCPv4 address and routes. Why? This is for the case when the DHCPv4
* client was enabled on the previous invocation of networkd, but when it is restarted, a new
* .network file may match to the interface, and DHCPv4 client may be disabled. In that case,
* the DHCPv4 client is not running, hence sd_dhcp_client_stop() in the above does nothing. */
RET_GATHER(ret, dhcp4_remove_address_and_routes(link, /* only_marked = */ false));
}
/* Even if the client is currently enabled and also enabled in the new .network file, detailed
* settings for the client may be different. Let's unref() the client. But do not unref() the lease.
* it will be unref()ed later when a new lease is acquired. */

View File

@ -307,7 +307,6 @@ static int dhcp6_lease_ip_acquired(sd_dhcp6_client *client, Link *link) {
int r;
link_mark_addresses(link, NETWORK_CONFIG_SOURCE_DHCP6);
manager_mark_routes(link->manager, NULL, NETWORK_CONFIG_SOURCE_DHCP6);
r = sd_dhcp6_client_get_lease(client, &lease);
if (r < 0)
@ -330,7 +329,7 @@ static int dhcp6_lease_ip_acquired(sd_dhcp6_client *client, Link *link) {
return r;
} else if (sd_dhcp6_lease_has_pd_prefix(lease_old))
/* When we had PD prefixes but not now, we need to remove them. */
dhcp_pd_prefix_lost(link);
dhcp6_pd_prefix_lost(link);
if (link->dhcp6_messages == 0) {
link->dhcp6_configured = true;
@ -377,7 +376,7 @@ static int dhcp6_lease_lost(Link *link) {
log_link_info(link, "DHCPv6 lease lost");
if (sd_dhcp6_lease_has_pd_prefix(link->dhcp6_lease))
dhcp_pd_prefix_lost(link);
dhcp6_pd_prefix_lost(link);
link->dhcp6_lease = sd_dhcp6_lease_unref(link->dhcp6_lease);
@ -845,15 +844,19 @@ int link_drop_dhcp6_config(Link *link, Network *network) {
int ret = 0;
assert(link);
assert(network);
assert(link->network);
if (!link_dhcp6_enabled(link))
return 0; /* Currently DHCPv6 client is not enabled, there is nothing we need to drop. */
if (link->network == network)
return 0; /* .network file is unchanged. It is not necessary to reconfigure the client. */
if (!FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV6))
/* Currently enabled but will be disabled. Stop the client and drop the lease. */
if (!link_dhcp6_enabled(link)) {
/* DHCPv6 client is disabled. Stop the client if it is running and drop the lease. */
ret = sd_dhcp6_client_stop(link->dhcp6_client);
/* Also explicitly drop DHCPv6 addresses and routes. See also link_drop_dhcp4_config(). */
RET_GATHER(ret, dhcp6_remove(link, /* only_marked = */ false));
}
/* Even if the client is currently enabled and also enabled in the new .network file, detailed
* settings for the client may be different. Let's unref() the client. But do not unref() the lease.
* it will be unref()ed later when a new lease is acquired. */

View File

@ -206,7 +206,7 @@ int ipv4ll_configure(Link *link) {
return 0;
if (link->ipv4ll)
return -EBUSY;
return 0;
r = sd_ipv4ll_new(&link->ipv4ll);
if (r < 0)
@ -246,19 +246,27 @@ int link_drop_ipv4ll_config(Link *link, Network *network) {
int ret = 0;
assert(link);
assert(network);
assert(link->network);
if (!link_ipv4ll_enabled(link))
return 0;
if (link->network == network)
return 0; /* .network file is unchanged. It is not necessary to reconfigure the client. */
Network *saved = link->network;
link->network = network;
bool enabled = link_ipv4ll_enabled(link);
link->network = saved;
if (!enabled)
if (!link_ipv4ll_enabled(link)) {
/* The client is disabled. Stop if it is running, and drop the address. */
ret = sd_ipv4ll_stop(link->ipv4ll);
/* Also, explicitly drop the address for the case that this is called on start up.
* See also comments in link_drop_dhcp4_config(). */
Address *a;
SET_FOREACH(a, link->addresses) {
if (a->source != NETWORK_CONFIG_SOURCE_IPV4LL)
continue;
assert(a->family == AF_INET);
RET_GATHER(ret, address_remove_and_cancel(a, link));
}
}
link->ipv4ll = sd_ipv4ll_unref(link->ipv4ll);
return ret;
}

View File

@ -1121,21 +1121,30 @@ static int link_drop_dynamic_config(Link *link, Network *network) {
int r;
assert(link);
assert(network);
assert(link->network);
/* Drop unnecessary dynamic configurations gracefully, e.g. drop DHCP lease in the case that
* previously DHCP=yes and now DHCP=no, but keep DHCP lease when DHCP setting is unchanged. */
r = link_drop_ndisc_config(link, network);
RET_GATHER(r, link_drop_radv_config(link, network));
RET_GATHER(r, link_drop_radv_config(link, network)); /* Stop before dropping DHCP-PD prefixes. */
RET_GATHER(r, link_drop_ipv4ll_config(link, network)); /* Stop before DHCPv4 client. */
RET_GATHER(r, link_drop_dhcp4_config(link, network));
RET_GATHER(r, link_drop_dhcp6_config(link, network));
RET_GATHER(r, link_drop_dhcp_pd_config(link, network));
RET_GATHER(r, link_drop_ipv4ll_config(link, network));
link->dhcp_server = sd_dhcp_server_unref(link->dhcp_server);
link->lldp_rx = sd_lldp_rx_unref(link->lldp_rx); /* TODO: keep the received neighbors. */
link->lldp_tx = sd_lldp_tx_unref(link->lldp_tx);
/* Even if we do not release DHCP lease or so, reset 'configured' flags. Otherwise, e.g. if
* previously UseDNS= was disabled but is now enabled, link will enter configured state before
* expected DNS servers being acquired. */
link->ipv4ll_address_configured = false;
link->dhcp4_configured = false;
link->dhcp6_configured = false;
link->dhcp_pd_configured = false;
link->ndisc_configured = false;
return r;
}
@ -1148,6 +1157,10 @@ static int link_configure(Link *link) {
link_set_state(link, LINK_STATE_CONFIGURING);
r = link_drop_unmanaged_config(link);
if (r < 0)
return r;
r = link_new_bound_to_list(link);
if (r < 0)
return r;
@ -1253,10 +1266,6 @@ static int link_configure(Link *link) {
if (r < 0)
return r;
r = link_drop_unmanaged_config(link);
if (r < 0)
return r;
r = link_request_static_configs(link);
if (r < 0)
return r;
@ -1385,29 +1394,7 @@ int link_reconfigure_impl(Link *link, LinkReconfigurationFlag flags) {
joined,
isempty(joined) ? "" : ")");
/* Dropping old .network file */
if (FLAGS_SET(flags, LINK_RECONFIGURE_CLEANLY)) {
/* Remove all static configurations. Note, dynamic configurations are dropped by
* link_stop_engines(), and foreign configurations will be removed later by
* link_configure() -> link_drop_unmanaged_config(). */
r = link_drop_static_config(link);
if (r < 0)
return r;
/* Stop DHCP client and friends, and drop dynamic configurations like DHCP address. */
r = link_stop_engines(link, /* may_keep_dhcp = */ false);
if (r < 0)
return r;
/* Free DHCP client and friends. */
link_free_engines(link);
} else {
r = link_drop_dynamic_config(link, network);
if (r < 0)
return r;
}
/* Dropping configurations based on the old .network file. */
r = link_drop_requests(link);
if (r < 0)
return r;
@ -1418,10 +1405,30 @@ int link_reconfigure_impl(Link *link, LinkReconfigurationFlag flags) {
* map here, as it depends on .network files assigned to other links. */
link_free_bound_to_list(link);
link->network = network_unref(link->network);
_cleanup_(network_unrefp) Network *old_network = TAKE_PTR(link->network);
/* Then, apply new .network file */
link->network = network_ref(network);
if (FLAGS_SET(network->keep_configuration, KEEP_CONFIGURATION_DHCP) ||
!FLAGS_SET(flags, LINK_RECONFIGURE_CLEANLY)) {
/* To make 'networkctl reconfigure INTERFACE' work safely for an interface whose new .network
* file has KeepConfiguration=dhcp or yes, even if a clean reconfiguration is requested,
* drop only unnecessary or possibly being changed dynamic configurations here. */
r = link_drop_dynamic_config(link, old_network);
if (r < 0)
return r;
} else {
/* Otherwise, stop DHCP client and friends unconditionally, and drop all dynamic
* configurations like DHCP address and routes. */
r = link_stop_engines(link, /* may_keep_dhcp = */ false);
if (r < 0)
return r;
/* Free DHCP client and friends. */
link_free_engines(link);
}
link_update_operstate(link, true);
link_dirty(link);
@ -1888,6 +1895,9 @@ static int link_admin_state_up(Link *link) {
static int link_admin_state_down(Link *link) {
assert(link);
link_forget_nexthops(link);
link_forget_routes(link);
if (!link->network)
return 0;

View File

@ -179,7 +179,7 @@ typedef struct Link {
Set *ndisc_dnr;
uint32_t ndisc_mtu;
unsigned ndisc_messages;
bool ndisc_configured:1;
bool ndisc_configured;
sd_radv *radv;

View File

@ -2672,28 +2672,39 @@ int link_drop_ndisc_config(Link *link, Network *network) {
int r, ret = 0;
assert(link);
assert(network);
assert(link->network);
if (!link_ndisc_enabled(link))
return 0; /* Currently DHCPv4 client is not enabled, there is nothing we need to drop. */
if (link->network == network)
return 0; /* .network file is unchanged. It is not necessary to reconfigure the client. */
Network *current = link->network;
link->network = network;
bool enabled = link_ndisc_enabled(link);
link->network = current;
if (!enabled) {
/* Currently enabled but will be disabled. Stop the client and flush configs. */
if (!link_ndisc_enabled(link)) {
/* NDisc is disabled. Stop the client if it is running and flush configs. */
ret = ndisc_stop(link);
ndisc_flush(link);
link->ndisc = sd_ndisc_unref(link->ndisc);
return ret;
}
/* Even if the client is currently enabled and also enabled in the new .network file, detailed
/* Even if the client was previously enabled and also enabled in the new .network file, detailed
* settings for the client may be different. Let's unref() the client. */
link->ndisc = sd_ndisc_unref(link->ndisc);
/* Get if NDisc was enabled or not. */
Network *current = link->network;
link->network = network;
bool enabled = link_ndisc_enabled(link);
link->network = current;
/* If previously explicitly disabled, there should be nothing to drop.
* If we do not know the previous setting of the client, e.g. when networkd is restarted, in that
* case we do not have the previous .network file assigned to the interface, then let's assume no
* detailed configuration is changed. Hopefully, unmatching configurations will be dropped after
* their lifetime. */
if (!enabled)
return 0;
assert(network);
/* Redirect messages will be ignored. Drop configurations based on the previously received redirect
* messages. */
if (!network->ndisc_use_redirect)

View File

@ -485,31 +485,23 @@ static void log_nexthop_debug(const NextHop *nexthop, const char *str, Manager *
yes_no(nexthop->blackhole), strna(group), strna(flags));
}
static int nexthop_remove_dependents(NextHop *nexthop, Manager *manager) {
int r = 0;
static void nexthop_forget_dependents(NextHop *nexthop, Manager *manager) {
assert(nexthop);
assert(manager);
/* If a nexthop is removed, the kernel silently removes nexthops and routes that depend on the
* removed nexthop. Let's remove them for safety (though, they are already removed in the kernel,
* hence that should fail), and forget them. */
void *id;
SET_FOREACH(id, nexthop->nexthops) {
NextHop *nh;
if (nexthop_get_by_id(manager, PTR_TO_UINT32(id), &nh) < 0)
continue;
RET_GATHER(r, nexthop_remove(nh, manager));
}
/* If a nexthop is removed, the kernel silently removes routes that depend on the removed nexthop.
* Let's forget them. */
Route *route;
SET_FOREACH(route, nexthop->routes)
RET_GATHER(r, route_remove(route, manager));
SET_FOREACH(route, nexthop->routes) {
Request *req;
if (route_get_request(manager, route, &req) >= 0)
route_enter_removed(req->userdata);
return r;
route_enter_removed(route);
log_route_debug(route, "Forgetting silently removed", manager);
route_detach(route);
}
}
static int nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, RemoveRequest *rreq) {
@ -527,7 +519,7 @@ static int nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Remov
(r == -ENOENT || !nexthop->manager) ? LOG_DEBUG : LOG_WARNING,
r, "Could not drop nexthop, ignoring");
(void) nexthop_remove_dependents(nexthop, manager);
nexthop_forget_dependents(nexthop, manager);
if (nexthop->manager) {
/* If the nexthop cannot be removed, then assume the nexthop is already removed. */
@ -925,6 +917,61 @@ int link_drop_nexthops(Link *link, bool only_static) {
return r;
}
static void nexthop_forget_one(NextHop *nexthop) {
assert(nexthop);
assert(nexthop->manager);
Request *req;
if (nexthop_get_request_by_id(nexthop->manager, nexthop->id, &req) >= 0)
route_enter_removed(req->userdata);
nexthop_enter_removed(nexthop);
log_nexthop_debug(nexthop, "Forgetting silently removed", nexthop->manager);
nexthop_forget_dependents(nexthop, nexthop->manager);
nexthop_detach(nexthop);
}
void link_forget_nexthops(Link *link) {
assert(link);
assert(link->manager);
assert(link->ifindex > 0);
assert(!FLAGS_SET(link->flags, IFF_UP));
/* See comments in link_forget_routes(). */
/* Remove all IPv4 nexthops. */
NextHop *nexthop;
HASHMAP_FOREACH(nexthop, link->manager->nexthops_by_id) {
if (nexthop->ifindex != link->ifindex)
continue;
if (nexthop->family != AF_INET)
continue;
nexthop_forget_one(nexthop);
}
/* Remove all group nexthops their all members are removed in the above. */
HASHMAP_FOREACH(nexthop, link->manager->nexthops_by_id) {
if (hashmap_isempty(nexthop->group))
continue;
/* Update group members. */
struct nexthop_grp *nhg;
HASHMAP_FOREACH(nhg, nexthop->group) {
if (nexthop_get_by_id(nexthop->manager, nhg->id, NULL) >= 0)
continue;
assert_se(hashmap_remove(nexthop->group, UINT32_TO_PTR(nhg->id)) == nhg);
free(nhg);
}
if (!hashmap_isempty(nexthop->group))
continue; /* At least one group member still exists. */
nexthop_forget_one(nexthop);
}
}
static int nexthop_update_group(NextHop *nexthop, sd_netlink_message *message) {
_cleanup_hashmap_free_free_ Hashmap *h = NULL;
_cleanup_free_ struct nexthop_grp *group = NULL;
@ -1032,7 +1079,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
if (nexthop) {
nexthop_enter_removed(nexthop);
log_nexthop_debug(nexthop, "Forgetting removed", m);
(void) nexthop_remove_dependents(nexthop, m);
nexthop_forget_dependents(nexthop, m);
nexthop_detach(nexthop);
} else
log_nexthop_debug(&(const NextHop) { .id = id }, "Kernel removed unknown", m);

View File

@ -60,6 +60,7 @@ static inline int link_drop_unmanaged_nexthops(Link *link) {
static inline int link_drop_static_nexthops(Link *link) {
return link_drop_nexthops(link, /* only_static = */ true);
}
void link_forget_nexthops(Link *link);
int link_request_static_nexthops(Link *link, bool only_ipv4);

View File

@ -649,10 +649,10 @@ int link_drop_radv_config(Link *link, Network *network) {
int ret = 0;
assert(link);
assert(network);
assert(link->network);
if (!link_radv_enabled(link))
return 0;
if (link->network == network)
return 0; /* .network file is unchanged. It is not necessary to reconfigure the server. */
// FIXME: check detailed settings and do not stop if nothing changed.
// FIXME: save dynamic prefixes acquired by DHCP-PD.

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <linux/if.h>
#include <linux/ipv6_route.h>
#include <linux/nexthop.h>
@ -47,7 +48,7 @@ static Route* route_detach_impl(Route *route) {
return NULL;
}
static void route_detach(Route *route) {
void route_detach(Route *route) {
route_unref(route_detach_impl(route));
}
@ -1138,6 +1139,8 @@ static int process_route_one(
}
}
route_attach_to_nexthop(route);
route_enter_configured(route);
log_route_debug(route, is_new ? "Received new" : "Received remembered", manager);
@ -1538,6 +1541,37 @@ int link_drop_routes(Link *link, bool only_static) {
return r;
}
void link_forget_routes(Link *link) {
assert(link);
assert(link->ifindex > 0);
assert(!FLAGS_SET(link->flags, IFF_UP));
/* When an interface went down, IPv4 non-local routes bound to the interface are silently removed by
* the kernel, without any notifications. Let's forget them in that case. Otherwise, when the link
* goes up later, the configuration order of routes may be confused by the nonexistent routes.
* See issue #35047. */
Route *route;
SET_FOREACH(route, link->manager->routes) {
// TODO: handle multipath routes
if (route->nexthop.ifindex != link->ifindex)
continue;
if (route->family != AF_INET)
continue;
// TODO: check RTN_NAT and RTN_XRESOLVE
if (!IN_SET(route->type, RTN_UNICAST, RTN_BROADCAST, RTN_ANYCAST, RTN_MULTICAST))
continue;
Request *req;
if (route_get_request(link->manager, route, &req) >= 0)
route_enter_removed(req->userdata);
route_enter_removed(route);
log_route_debug(route, "Forgetting silently removed", link->manager);
route_detach(route);
}
}
int network_add_ipv4ll_route(Network *network) {
_cleanup_(route_unref_or_set_invalidp) Route *route = NULL;
unsigned section_line;

View File

@ -89,6 +89,8 @@ Route* route_ref(Route *route);
Route* route_unref(Route *route);
DEFINE_SECTION_CLEANUP_FUNCTIONS(Route, route_unref);
void route_detach(Route *route);
int route_new(Route **ret);
int route_new_static(Network *network, const char *filename, unsigned section_line, Route **ret);
int route_dup(const Route *src, const RouteNextHop *nh, Route **ret);
@ -109,6 +111,7 @@ static inline int link_drop_static_routes(Link *link) {
static inline int link_drop_unmanaged_routes(Link *link) {
return link_drop_routes(link, false);
}
void link_forget_routes(Link *link);
int link_request_route(
Link *link,

View File

@ -5106,15 +5106,15 @@ static int load_oci_bundle(void) {
}
static int run_container(
DissectedImage *dissected_image,
int userns_fd,
FDSet *fds,
char veth_name[IFNAMSIZ],
bool *veth_created,
struct ExposeArgs *expose_args,
int *master,
pid_t *pid,
int *ret) {
DissectedImage *dissected_image,
int userns_fd,
FDSet *fds,
char veth_name[IFNAMSIZ],
bool *veth_created,
struct ExposeArgs *expose_args,
int *master,
pid_t *pid,
int *ret) {
static const struct sigaction sa = {
.sa_handler = nop_signal_handler,

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('ENABLE_NSRESOURCED') != 1
subdir_done()
endif
subdir('bpf/userns_restrict')
systemd_nsresourcework_sources = files(
@ -24,7 +28,7 @@ if conf.get('HAVE_VMLINUX_H') == 1
executables += [
test_template + {
'sources' : files('test-userns-restrict.c', 'userns-restrict.c') + userns_restrict_skel_h,
'conditions' : ['ENABLE_NSRESOURCED', 'HAVE_VMLINUX_H'],
'conditions' : ['HAVE_VMLINUX_H'],
'include_directories' : [ includes, userns_restrict_include ],
},
]
@ -33,14 +37,12 @@ endif
executables += [
libexec_template + {
'name' : 'systemd-nsresourcework',
'conditions' : ['ENABLE_NSRESOURCED'],
'sources' : systemd_nsresourcework_sources,
'dependencies' : threads,
'include_directories' : [ includes, userns_restrict_include ],
},
libexec_template + {
'name' : 'systemd-nsresourced',
'conditions' : ['ENABLE_NSRESOURCED'],
'sources' : systemd_nsresourced_sources,
'dependencies' : threads,
'include_directories' : [ includes, userns_restrict_include ],

View File

@ -1,12 +1,12 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_OPENSSL') != 1 or conf.get('HAVE_TPM2') != 1
subdir_done()
endif
executables += [
libexec_template + {
'name' : 'systemd-pcrlock',
'conditions' : [
'HAVE_OPENSSL',
'HAVE_TPM2'
],
'sources' : files(
'pcrlock.c',
'pcrlock-firmware.c',
@ -19,18 +19,16 @@ executables += [
},
]
if conf.get('HAVE_OPENSSL') == 1 and conf.get('HAVE_TPM2') == 1
install_data('pcrlock.d/350-action-efi-application.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/400-secureboot-separator.pcrlock.d/300-0x00000000.pcrlock', install_dir : pcrlockdir / '400-secureboot-separator.pcrlock.d')
install_data('pcrlock.d/400-secureboot-separator.pcrlock.d/600-0xffffffff.pcrlock', install_dir : pcrlockdir / '400-secureboot-separator.pcrlock.d')
install_data('pcrlock.d/500-separator.pcrlock.d/300-0x00000000.pcrlock', install_dir : pcrlockdir / '500-separator.pcrlock.d')
install_data('pcrlock.d/500-separator.pcrlock.d/600-0xffffffff.pcrlock', install_dir : pcrlockdir / '500-separator.pcrlock.d')
install_data('pcrlock.d/700-action-efi-exit-boot-services.pcrlock.d/300-present.pcrlock', install_dir : pcrlockdir / '700-action-efi-exit-boot-services.pcrlock.d')
install_data('pcrlock.d/700-action-efi-exit-boot-services.pcrlock.d/600-absent.pcrlock', install_dir : pcrlockdir / '700-action-efi-exit-boot-services.pcrlock.d')
install_data('pcrlock.d/750-enter-initrd.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/800-leave-initrd.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/850-sysinit.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/900-ready.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/950-shutdown.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/990-final.pcrlock', install_dir : pcrlockdir)
endif
install_data('pcrlock.d/350-action-efi-application.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/400-secureboot-separator.pcrlock.d/300-0x00000000.pcrlock', install_dir : pcrlockdir / '400-secureboot-separator.pcrlock.d')
install_data('pcrlock.d/400-secureboot-separator.pcrlock.d/600-0xffffffff.pcrlock', install_dir : pcrlockdir / '400-secureboot-separator.pcrlock.d')
install_data('pcrlock.d/500-separator.pcrlock.d/300-0x00000000.pcrlock', install_dir : pcrlockdir / '500-separator.pcrlock.d')
install_data('pcrlock.d/500-separator.pcrlock.d/600-0xffffffff.pcrlock', install_dir : pcrlockdir / '500-separator.pcrlock.d')
install_data('pcrlock.d/700-action-efi-exit-boot-services.pcrlock.d/300-present.pcrlock', install_dir : pcrlockdir / '700-action-efi-exit-boot-services.pcrlock.d')
install_data('pcrlock.d/700-action-efi-exit-boot-services.pcrlock.d/600-absent.pcrlock', install_dir : pcrlockdir / '700-action-efi-exit-boot-services.pcrlock.d')
install_data('pcrlock.d/750-enter-initrd.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/800-leave-initrd.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/850-sysinit.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/900-ready.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/950-shutdown.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/990-final.pcrlock', install_dir : pcrlockdir)

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('ENABLE_PORTABLED') != 1
subdir_done()
endif
systemd_portabled_sources = files(
'portable.c',
'portabled-bus.c',
@ -22,7 +26,6 @@ executables += [
libexec_template + {
'name' : 'systemd-portabled',
'dbus' : true,
'conditions' : ['ENABLE_PORTABLED'],
'sources' : systemd_portabled_sources,
'link_with' : portabled_link_with,
'dependencies' : [
@ -33,23 +36,20 @@ executables += [
executable_template + {
'name' : 'portablectl',
'public' : true,
'conditions' : ['ENABLE_PORTABLED'],
'sources' : files('portablectl.c'),
'link_with' : portabled_link_with,
'dependencies' : threads,
},
]
if conf.get('ENABLE_PORTABLED') == 1
install_data('org.freedesktop.portable1.conf',
install_dir : dbuspolicydir)
install_data('org.freedesktop.portable1.service',
install_dir : dbussystemservicedir)
install_data('org.freedesktop.portable1.policy',
install_dir : polkitpolicydir)
install_data('org.freedesktop.portable1.conf',
install_dir : dbuspolicydir)
install_data('org.freedesktop.portable1.service',
install_dir : dbussystemservicedir)
install_data('org.freedesktop.portable1.policy',
install_dir : polkitpolicydir)
install_data('profile/default/service.conf', install_dir : profiledir / 'default')
install_data('profile/nonetwork/service.conf', install_dir : profiledir / 'nonetwork')
install_data('profile/strict/service.conf', install_dir : profiledir / 'strict')
install_data('profile/trusted/service.conf', install_dir : profiledir / 'trusted')
endif
install_data('profile/default/service.conf', install_dir : profiledir / 'default')
install_data('profile/nonetwork/service.conf', install_dir : profiledir / 'nonetwork')
install_data('profile/strict/service.conf', install_dir : profiledir / 'strict')
install_data('profile/trusted/service.conf', install_dir : profiledir / 'trusted')

View File

@ -1,9 +1,12 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('ENABLE_PSTORE') != 1
subdir_done()
endif
executables += [
libexec_template + {
'name' : 'systemd-pstore',
'conditions' : ['ENABLE_PSTORE'],
'sources' : files('pstore.c'),
'dependencies' : [
libacl,
@ -15,7 +18,7 @@ executables += [
},
]
if conf.get('ENABLE_PSTORE') == 1 and install_sysconfdir_samples
if install_sysconfdir_samples
install_data('pstore.conf',
install_dir : pkgconfigfiledir)
endif

View File

@ -1,10 +1,13 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('ENABLE_REPART') != 1
subdir_done()
endif
executables += [
executable_template + {
'name' : 'systemd-repart',
'public' : true,
'conditions' : ['ENABLE_REPART'],
'sources' : files('repart.c'),
'link_with' : [
libshared,
@ -20,7 +23,6 @@ executables += [
executable_template + {
'name' : 'systemd-repart.standalone',
'public' : have_standalone_binaries,
'conditions' : ['ENABLE_REPART'],
'sources' : files('repart.c'),
'c_args' : '-DSTANDALONE',
'link_with' : [
@ -40,14 +42,12 @@ executables += [
},
]
if conf.get('ENABLE_REPART') == 1
install_data('definitions/confext.repart.d/10-root.conf', install_dir : repartdefinitionsdir / 'confext.repart.d')
install_data('definitions/confext.repart.d/20-root-verity.conf', install_dir : repartdefinitionsdir / 'confext.repart.d')
install_data('definitions/confext.repart.d/30-root-verity-sig.conf', install_dir : repartdefinitionsdir / 'confext.repart.d')
install_data('definitions/portable.repart.d/10-root.conf', install_dir : repartdefinitionsdir / 'portable.repart.d')
install_data('definitions/portable.repart.d/20-root-verity.conf', install_dir : repartdefinitionsdir / 'portable.repart.d')
install_data('definitions/portable.repart.d/30-root-verity-sig.conf', install_dir : repartdefinitionsdir / 'portable.repart.d')
install_data('definitions/sysext.repart.d/10-root.conf', install_dir : repartdefinitionsdir / 'sysext.repart.d')
install_data('definitions/sysext.repart.d/20-root-verity.conf', install_dir : repartdefinitionsdir / 'sysext.repart.d')
install_data('definitions/sysext.repart.d/30-root-verity-sig.conf', install_dir : repartdefinitionsdir / 'sysext.repart.d')
endif
install_data('definitions/confext.repart.d/10-root.conf', install_dir : repartdefinitionsdir / 'confext.repart.d')
install_data('definitions/confext.repart.d/20-root-verity.conf', install_dir : repartdefinitionsdir / 'confext.repart.d')
install_data('definitions/confext.repart.d/30-root-verity-sig.conf', install_dir : repartdefinitionsdir / 'confext.repart.d')
install_data('definitions/portable.repart.d/10-root.conf', install_dir : repartdefinitionsdir / 'portable.repart.d')
install_data('definitions/portable.repart.d/20-root-verity.conf', install_dir : repartdefinitionsdir / 'portable.repart.d')
install_data('definitions/portable.repart.d/30-root-verity-sig.conf', install_dir : repartdefinitionsdir / 'portable.repart.d')
install_data('definitions/sysext.repart.d/10-root.conf', install_dir : repartdefinitionsdir / 'sysext.repart.d')
install_data('definitions/sysext.repart.d/20-root-verity.conf', install_dir : repartdefinitionsdir / 'sysext.repart.d')
install_data('definitions/sysext.repart.d/30-root-verity-sig.conf', install_dir : repartdefinitionsdir / 'sysext.repart.d')

View File

@ -1038,7 +1038,7 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
if (!arg_shell_prompt_prefix)
return log_oom();
} else if (emoji_enabled()) {
arg_shell_prompt_prefix = strjoin(special_glyph(SPECIAL_GLYPH_SUPERHERO), " ");
arg_shell_prompt_prefix = strjoin(special_glyph(privileged_execution() ? SPECIAL_GLYPH_SUPERHERO : SPECIAL_GLYPH_IDCARD), " ");
if (!arg_shell_prompt_prefix)
return log_oom();
}

View File

@ -18,7 +18,6 @@
#include "tmpfile-util.h"
#include "verbs.h"
static PagerFlags arg_pager_flags = 0;
static char *arg_output = NULL;
static char *arg_certificate = NULL;
static CertificateSourceType arg_certificate_source_type = OPENSSL_CERTIFICATE_SOURCE_FILE;
@ -45,11 +44,9 @@ static int help(int argc, char *argv[], void *userdata) {
"\n%5$sSign binaries for EFI Secure Boot%6$s\n"
"\n%3$sCommands:%4$s\n"
" sign EXEFILE Sign the given binary for EFI Secure Boot\n"
" validate-key Load and validate the given certificate and private key\n"
"\n%3$sOptions:%4$s\n"
" -h --help Show this help\n"
" --version Print version\n"
" --no-pager Do not pipe output into a pager\n"
" --output Where to write the signed PE binary\n"
" --certificate=PATH|URI\n"
" PEM certificate to use for signing, or a provider\n"
@ -76,7 +73,6 @@ static int help(int argc, char *argv[], void *userdata) {
static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
ARG_NO_PAGER,
ARG_OUTPUT,
ARG_CERTIFICATE,
ARG_CERTIFICATE_SOURCE,
@ -86,7 +82,6 @@ static int parse_argv(int argc, char *argv[]) {
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "version", no_argument, NULL, ARG_VERSION },
{ "output", required_argument, NULL, ARG_OUTPUT },
{ "certificate", required_argument, NULL, ARG_CERTIFICATE },
@ -111,10 +106,6 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_VERSION:
return version();
case ARG_NO_PAGER:
arg_pager_flags |= PAGER_DISABLE;
break;
case ARG_OUTPUT:
r = parse_path_argument(optarg, /*suppress_root=*/ false, &arg_output);
if (r < 0)
@ -498,63 +489,10 @@ static int verb_sign(int argc, char *argv[], void *userdata) {
return 0;
}
static int verb_validate_key(int argc, char *argv[], void *userdata) {
_cleanup_(X509_freep) X509 *certificate = NULL;
_cleanup_(openssl_ask_password_ui_freep) OpenSSLAskPasswordUI *ui = NULL;
_cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = NULL;
int r;
if (!arg_certificate)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"No certificate specified, use --certificate=");
if (!arg_private_key)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"No private key specified, use --private-key=.");
if (arg_certificate_source_type == OPENSSL_CERTIFICATE_SOURCE_FILE) {
r = parse_path_argument(arg_certificate, /*suppress_root=*/ false, &arg_certificate);
if (r < 0)
return r;
}
r = openssl_load_x509_certificate(
arg_certificate_source_type,
arg_certificate_source,
arg_certificate,
&certificate);
if (r < 0)
return log_error_errno(r, "Failed to load X.509 certificate from %s: %m", arg_certificate);
if (arg_private_key_source_type == OPENSSL_KEY_SOURCE_FILE) {
r = parse_path_argument(arg_private_key, /* suppress_root= */ false, &arg_private_key);
if (r < 0)
return log_error_errno(r, "Failed to parse private key path %s: %m", arg_private_key);
}
r = openssl_load_private_key(
arg_private_key_source_type,
arg_private_key_source,
arg_private_key,
&(AskPasswordRequest) {
.id = "sbsign-private-key-pin",
.keyring = arg_private_key,
.credential = "sbsign.private-key-pin",
},
&private_key,
&ui);
if (r < 0)
return log_error_errno(r, "Failed to load private key from %s: %m", arg_private_key);
puts("OK");
return 0;
}
static int run(int argc, char *argv[]) {
static const Verb verbs[] = {
{ "help", VERB_ANY, VERB_ANY, 0, help },
{ "sign", 2, 2, 0, verb_sign },
{ "validate-key", VERB_ANY, 1, 0, verb_validate_key },
{}
};
int r;

View File

@ -4271,7 +4271,6 @@ int mountfsd_mount_image(
_cleanup_close_ int image_fd = -EBADF;
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
_cleanup_free_ char *ps = NULL;
unsigned max_fd = UINT_MAX;
const char *error_id;
int r;
@ -4365,9 +4364,6 @@ int mountfsd_mount_image(
return log_error_errno(r, "Failed to parse partition data: %m");
if (pp.fsmount_fd_idx != UINT_MAX) {
if (max_fd == UINT_MAX || pp.fsmount_fd_idx > max_fd)
max_fd = pp.fsmount_fd_idx;
fsmount_fd = sd_varlink_take_fd(vl, pp.fsmount_fd_idx);
if (fsmount_fd < 0)
return fsmount_fd;

View File

@ -42,6 +42,11 @@ typedef enum AnsiColorState {
_ANSI_COLOR_STATE_INVALID = -EINVAL,
} AnsiColorState;
#define ANSI_SEQUENCE_LENGTH_MAX 192U
#define ANSI_SEQUENCE_WINDOW_TITLE_MAX 128U
assert_cc(ANSI_SEQUENCE_LENGTH_MAX > ANSI_SEQUENCE_WINDOW_TITLE_MAX);
struct PTYForward {
sd_event *event;
@ -463,7 +468,7 @@ static int pty_forward_ansi_process(PTYForward *f, size_t offset) {
/* If this is a "parameter" or "intermediary" byte (i.e. ranges 0x20…0x2F and
* 0x300x3F) then we are still in the CSI sequence */
if (strlen_ptr(f->csi_sequence) >= 64) {
if (strlen_ptr(f->csi_sequence) >= ANSI_SEQUENCE_LENGTH_MAX) {
/* Safety check: lets not accept unbounded CSI sequences */
f->csi_sequence = mfree(f->csi_sequence);
@ -498,7 +503,7 @@ static int pty_forward_ansi_process(PTYForward *f, size_t offset) {
case ANSI_COLOR_STATE_OSC_SEQUENCE:
if ((uint8_t) c >= ' ') {
if (strlen_ptr(f->osc_sequence) >= 64) {
if (strlen_ptr(f->osc_sequence) >= ANSI_SEQUENCE_LENGTH_MAX) {
/* Safety check: lets not accept unbounded OSC sequences */
f->osc_sequence = mfree(f->osc_sequence);
break;
@ -1115,7 +1120,18 @@ int pty_forward_set_title(PTYForward *f, const char *title) {
if (f->out_buffer_size > 0)
return -EBUSY;
return free_and_strdup(&f->title, title);
if (!title) {
f->title = mfree(f->title);
return 0;
}
/* Truncate the title to 128 chars, since some terminal emulators really don't like overly long ANSI
* sequences */
_cleanup_free_ char *ellipsized = ellipsize(title, ANSI_SEQUENCE_WINDOW_TITLE_MAX, 66);
if (!ellipsized)
return -ENOMEM;
return free_and_replace(f->title, ellipsized);
}
int pty_forward_set_titlef(PTYForward *f, const char *format, ...) {
@ -1135,7 +1151,7 @@ int pty_forward_set_titlef(PTYForward *f, const char *format, ...) {
if (r < 0)
return -ENOMEM;
return free_and_replace(f->title, title);
return pty_forward_set_title(f, title);
}
int pty_forward_set_title_prefix(PTYForward *f, const char *title_prefix) {

View File

@ -121,9 +121,30 @@ static SD_VARLINK_DEFINE_METHOD(
SD_VARLINK_DEFINE_OUTPUT(ptyFileDescriptor, SD_VARLINK_INT, 0),
SD_VARLINK_FIELD_COMMENT("Path to the allocated pseudo TTY"),
SD_VARLINK_DEFINE_OUTPUT(ptyPath, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_METHOD(
CopyFrom,
VARLINK_DEFINE_MACHINE_LOOKUP_AND_POLKIT_INPUT_FIELDS,
SD_VARLINK_FIELD_COMMENT("A source directory in the container"),
SD_VARLINK_DEFINE_INPUT(source, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("A destination directory in the container. If null, it's equal to 'source'"),
SD_VARLINK_DEFINE_INPUT(destination, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("If true the destination will be replaced"),
SD_VARLINK_DEFINE_INPUT(replace, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_METHOD(
CopyTo,
VARLINK_DEFINE_MACHINE_LOOKUP_AND_POLKIT_INPUT_FIELDS,
SD_VARLINK_FIELD_COMMENT("A source directory on the host"),
SD_VARLINK_DEFINE_INPUT(source, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("A destination directory in the container. If null, it's equal to 'source'"),
SD_VARLINK_DEFINE_INPUT(destination, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("If true the destination will be replaced"),
SD_VARLINK_DEFINE_INPUT(replace, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_ERROR(NoSuchMachine);
static SD_VARLINK_DEFINE_ERROR(MachineExists);
static SD_VARLINK_DEFINE_ERROR(NoSuchFile);
static SD_VARLINK_DEFINE_ERROR(FileExists);
static SD_VARLINK_DEFINE_ERROR(NoPrivateNetworking);
static SD_VARLINK_DEFINE_ERROR(NoOSReleaseInformation);
static SD_VARLINK_DEFINE_ERROR(NoUIDShift);
@ -154,9 +175,17 @@ SD_VARLINK_DEFINE_INTERFACE(
&vl_type_MachineOpenMode,
SD_VARLINK_SYMBOL_COMMENT("Allocates a pseudo TTY in the container in various modes"),
&vl_method_Open,
SD_VARLINK_SYMBOL_COMMENT("Copy files or directories from a container into the host"),
&vl_method_CopyFrom,
SD_VARLINK_SYMBOL_COMMENT("Copy files or directories from the host into a container"),
&vl_method_CopyTo,
SD_VARLINK_SYMBOL_COMMENT("No matching machine currently running"),
&vl_error_NoSuchMachine,
&vl_error_MachineExists,
SD_VARLINK_SYMBOL_COMMENT("No such file"),
&vl_error_NoSuchFile,
SD_VARLINK_SYMBOL_COMMENT("File exists"),
&vl_error_FileExists,
SD_VARLINK_SYMBOL_COMMENT("Machine does not use private networking"),
&vl_error_NoPrivateNetworking,
SD_VARLINK_SYMBOL_COMMENT("Machine does not contain OS release information"),

View File

@ -1,16 +1,18 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('ENABLE_SYSUSERS') != 1
subdir_done()
endif
executables += [
executable_template + {
'name' : 'systemd-sysusers',
'public' : true,
'conditions' : ['ENABLE_SYSUSERS'],
'sources' : files('sysusers.c'),
},
executable_template + {
'name' : 'systemd-sysusers.standalone',
'public' : have_standalone_binaries,
'conditions' : ['ENABLE_SYSUSERS'],
'sources' : files('sysusers.c'),
'c_args' : '-DSTANDALONE',
'link_with' : [

View File

@ -46,6 +46,7 @@ simple_tests += files(
'test-alloc-util.c',
'test-architecture.c',
'test-argv-util.c',
'test-audit-util.c',
'test-barrier.c',
'test-bitfield.c',
'test-bitmap.c',

View File

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "audit-util.h"
#include "tests.h"
TEST(audit_loginuid_from_pid) {
_cleanup_(pidref_done) PidRef self = PIDREF_NULL, pid1 = PIDREF_NULL;
int r;
assert_se(pidref_set_self(&self) >= 0);
assert_se(pidref_set_pid(&pid1, 1) >= 0);
uid_t uid;
r = audit_loginuid_from_pid(&self, &uid);
assert_se(r >= 0 || r == -ENODATA);
if (r >= 0)
log_info("self audit login uid: " UID_FMT, uid);
assert_se(audit_loginuid_from_pid(&pid1, &uid) == -ENODATA);
uint32_t sessionid;
r = audit_session_from_pid(&self, &sessionid);
assert_se(r >= 0 || r == -ENODATA);
if (r >= 0)
log_info("self audit session id: %" PRIu32, sessionid);
assert_se(audit_session_from_pid(&pid1, &sessionid) == -ENODATA);
}
static int intro(void) {
log_show_color(true);
return EXIT_SUCCESS;
}
DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro);

View File

@ -82,7 +82,7 @@ TEST(keymaps) {
#define dump_glyph(x) log_info(STRINGIFY(x) ": %s", special_glyph(x))
TEST(dump_special_glyphs) {
assert_cc(SPECIAL_GLYPH_SUPERHERO + 1 == _SPECIAL_GLYPH_MAX);
assert_cc(SPECIAL_GLYPH_IDCARD + 1 == _SPECIAL_GLYPH_MAX);
log_info("is_locale_utf8: %s", yes_no(is_locale_utf8()));
@ -134,6 +134,7 @@ TEST(dump_special_glyphs) {
dump_glyph(SPECIAL_GLYPH_BLUE_CIRCLE);
dump_glyph(SPECIAL_GLYPH_GREEN_CIRCLE);
dump_glyph(SPECIAL_GLYPH_SUPERHERO);
dump_glyph(SPECIAL_GLYPH_IDCARD);
}
DEFINE_TEST_MAIN(LOG_INFO);

View File

@ -13,7 +13,6 @@ executables += [
libopenssl,
],
},
generator_template + {
'name' : 'systemd-tpm2-generator',
'sources' : files('tpm2-generator.c'),

View File

@ -1016,8 +1016,8 @@ def make_uki(opts: UkifyConfig) -> None:
pcrpkey: Union[bytes, Path, None] = opts.pcrpkey
if pcrpkey is None:
measure_tool = find_tool('systemd-measure', '/usr/lib/systemd/systemd-measure')
cmd = [measure_tool, 'pcrpkey']
measure_tool = find_tool('systemd-keyutil', '/usr/lib/systemd/systemd-keyutil')
cmd = [measure_tool, 'public']
if opts.pcr_public_keys and len(opts.pcr_public_keys) == 1:
# If we're using an engine or provider, the public key will be an X.509 certificate.
@ -1025,11 +1025,11 @@ def make_uki(opts: UkifyConfig) -> None:
cmd += ['--certificate', opts.pcr_public_keys[0]]
if opts.certificate_provider:
cmd += ['--certificate-source', f'provider:{opts.certificate_provider}']
else:
cmd += ['--public-key', opts.pcr_public_keys[0]]
print('+', shell_join(cmd))
pcrpkey = subprocess.check_output(cmd)
print('+', shell_join(cmd))
pcrpkey = subprocess.check_output(cmd)
else:
pcrpkey = Path(opts.pcr_public_keys[0])
elif opts.pcr_private_keys and len(opts.pcr_private_keys) == 1:
cmd += ['--private-key', Path(opts.pcr_private_keys[0])]

Some files were not shown because too many files have changed in this diff Show More