mirror of
https://github.com/systemd/systemd
synced 2026-03-25 08:14:54 +01:00
Compare commits
No commits in common. "9e418cd075aa29fb595b7a1ad5aaeb9f13f9c61e" and "90f4c0473a70e83ace55c56bbc182fdd3c5c5944" have entirely different histories.
9e418cd075
...
90f4c0473a
@ -1 +1,339 @@
|
||||
[This content has moved to the UAPI group website](https://uapi-group.org/specifications/specs/osc_context/)
|
||||
---
|
||||
title: OSC 3008: Hierarchical Context Signalling
|
||||
category: Interfaces
|
||||
layout: default
|
||||
SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
---
|
||||
|
||||
# OSC 3008: Hierarchical Context Signalling
|
||||
|
||||
A terminal connects a user with programs. Control of the program side of
|
||||
terminals is typically passed around to various different components while the
|
||||
user is active: a shell might pass control to a process it invokes. If that
|
||||
process is `run0` then primary control is passed to the privileged session of
|
||||
the target user. If `systemd-nspawn` is invoked to start a container, primary
|
||||
control is passed to that container, and so on.
|
||||
|
||||
A terminal emulator might be interested to know which component is currently in
|
||||
primary control of the program side of a terminal. OSC 3008 is a mechanism to
|
||||
inform it about such contexts. Each component taking over control can inform
|
||||
the terminal emulators that a new context begins now, and then use the terminal
|
||||
or pass control down to further apps, which can introduce contexts. Each
|
||||
context may carry various descriptive metadata fields.
|
||||
|
||||
## Status
|
||||
|
||||
This OSC sequence has been invented by the systemd project and is generated by
|
||||
systemd. Currently, no terminal application is known that consumes these
|
||||
sequences.
|
||||
|
||||
## Use Cases
|
||||
|
||||
Terminal emulators can use hierarchical context information:
|
||||
|
||||
1. To introduce markers/bookmarks in the output that the user can jump between.
|
||||
|
||||
2. To visually identify output from different contexts. For example the
|
||||
background of the associated output can be tinted in a reddish tone when
|
||||
privileges are acquired, and similar.
|
||||
|
||||
3. Meta information on specific output can be shown in a tooltip or similar
|
||||
|
||||
4. Programs (and all subcontexts) can be killed via a right-click menu on the
|
||||
output they generate.
|
||||
|
||||
5. Similar, a right-click menu might offer an item to offer opening a new
|
||||
interactive shell in the same working directory that was current on the
|
||||
selected context.
|
||||
|
||||
6. Failed commands or aborted sessions can be marked requesting user attention.
|
||||
|
||||
## Context Types
|
||||
|
||||
There are various types of contexts defined by this specification:
|
||||
|
||||
1. `boot` → a booted system initiates this context early at boot. (systemd's
|
||||
PID 1 generates this on `/dev/console`.)
|
||||
|
||||
2. `container` → a container manager initialized an interactive connection to a
|
||||
container. (`systemd-nspawn` generates this when interactively invoking a
|
||||
container. `machinectl login`, `machinectl shell` do this too.)
|
||||
|
||||
3. `vm` → a VM manager initialized a terminal connection to a
|
||||
VM. (`systemd-vmspawn` generates this when interactively invoking a VM, as
|
||||
one example.)
|
||||
|
||||
4. `elevate` → when the user interactively acquired higher privileges. (`run0`
|
||||
initiates a context of this type whenever the user invokes it to acquire
|
||||
root privileges.)
|
||||
|
||||
5. `chpriv` → similar, but when the user acquired *different* privileges, not
|
||||
necessarily higher ones. (`run0` initiates a context of this type whenever
|
||||
the user invokes it to acquire non-root privileges of another user.)
|
||||
|
||||
5. `subcontext` → similar, but the source and target privileges where
|
||||
identical. (`run0` initiates a context of this type whenever the user
|
||||
invokes it to acquire privileges of the user itself.)
|
||||
|
||||
6. `remote` → a user invoked a tool such as `ssh` to connect to a remote
|
||||
system.
|
||||
|
||||
7. `shell` → an interactive terminal shell initiates this context
|
||||
|
||||
8. `command` → a shell interactively invokes a new program.
|
||||
|
||||
9. `app` → an interactive program may initiate this context.
|
||||
|
||||
10. `service` → the service manager invokes an interactive service on the terminal
|
||||
|
||||
11. `session` → a login session of the user is initialized.
|
||||
|
||||
## Semantics
|
||||
|
||||
Contexts in the sense of OSC 3008 are hierarchical, and describe a tree
|
||||
structure: whenever a new context is opened it becomes the new active context,
|
||||
and the previously active context becomes its parent (if there is one). Only
|
||||
one context is currently active, but previously opened contexts remain valid in
|
||||
the background. Any other data written or read should be considered associated
|
||||
with the currently active context.
|
||||
|
||||
Each context carries an identifier, chosen by the component opening the
|
||||
context. The identifier can chosen freely, but must not be longer than 64
|
||||
characters. The characters may be in the 32…126 byte range. Identifiers should
|
||||
be universally unique, for example randomly generated. A freshly generated UUID
|
||||
would work well for this, but this could also be something like the Linux boot
|
||||
ID combined with the 64bit inode number of Linux pidfds, or something hashed
|
||||
from it.
|
||||
|
||||
Fundamentally, there are two OSC 3008 commands defined:
|
||||
|
||||
1. OSC "`3008;start=`" … (the *start sequence*) → this initiates, updates or
|
||||
indicates a return to a context. It carries a context identifier, and
|
||||
typically some metadata. This may be sent to first initiate a context. If
|
||||
sent again for the same context ID that was initiated already this indicates
|
||||
an update of the existing context. In this case, *any* previously set
|
||||
metadata fields for the context are flushed out, reset to their defaults,
|
||||
and then reinitialized from the newly supplied data. Also, in this case any
|
||||
subcontexts of the contexts are implicitly terminated.
|
||||
|
||||
2. OSC "`3008;end=`" … (the *end sequence*) → this terminates a context. It
|
||||
carries a context identifier to close, initiated before with OSC
|
||||
"`3008;start=`". It may also carry additional metadata.
|
||||
|
||||
## General Syntax
|
||||
|
||||
This builds on ECMA-48, and reuses the OSC and ST concepts introduced there.
|
||||
|
||||
For sequences following this specification it is recommended to encode OSC as
|
||||
0x1B 0x5D, and ST as 0x1B 0x5C.
|
||||
|
||||
ECMA-48 only allows characters from the range 0x20…0x7e (i.e. 32…126) inside
|
||||
OSC sequences. However, most terminal emulators nowadays allow the ASCII byte
|
||||
range > 0x7f in the OSC sequences they process, and so does this
|
||||
specification. Control characters (< 0x20 and 0x7f) are not allowed. The
|
||||
semicolon character ("`;`") – which is used as field separator by this
|
||||
specification – shall be replaced by "`\x3b`" and the backslash character
|
||||
("`\`") shall be replaced by "`\x5c`". All textual fields must be encoded in
|
||||
UTF-8, and then escaped with these two replacements.
|
||||
|
||||
The start sequence begins with OSC, followed by the string `3008;start=`,
|
||||
followed by the context ID. This is then followed by any number of metadata
|
||||
fields, including none. Metadata fields begin with a semicolon (`;`) followed
|
||||
by in a string identifying the type of field, followed by an equal sign (`=`),
|
||||
and the field value. The sequence ends in ST.
|
||||
|
||||
The end sequence begins with OSC, followed by the string `3008;end=`, followed
|
||||
by the context ID, and a series of metadata fields in the same syntax as for
|
||||
the start sequence. The sequence ends in ST.
|
||||
|
||||
## Metadata Fields
|
||||
|
||||
The following fields are currently defined for the start sequence:
|
||||
|
||||
| Field | Context Types | Description |
|
||||
|---------------|---------------|-------------------------------------------------------------------------------------------------------------|
|
||||
| `type=` | *all* | Declares the context type, one of the types described above |
|
||||
| `user=` | *all* | UNIX user name the process issuing the sequence runs as |
|
||||
| `hostname=` | *all* | UNIX host name of the system the process issuing the sequence runs on |
|
||||
| `machineid=` | *all* | The machine ID (i.e. `/etc/machine-id`) of the system the process issuing the sequence runs on |
|
||||
| `bootid=` | *all* | The boot ID (i.e. `/proc/sys/kernel/random/boot_id`) of the system the process issuing the sequence runs on |
|
||||
| `pid=` | *all* | The numeric PID of the process issuing the sequence, in decimal notation |
|
||||
| `pidfdid=` | *all* | The 64bit inode number of the pidfd of the process issuing the sequence, in decimal notation |
|
||||
| `comm=` | *all* | The process name (i.e. `/proc/$PID/comm`, `PR_GET_NAME`) of the process issuing the sequence |
|
||||
| `cwd=` | `shell`, `command` | The current working directory |
|
||||
| `cmdline=` | `command` | The full command line of the invoked command |
|
||||
| `vm=` | `vm` | The name of the VM being invoked |
|
||||
| `container=` | `container` | The name of the container being invoked |
|
||||
| `targetuser=` | `elevate`, `chpriv`, `vm`, `container`, `remote`, `session` | Target UNIX user name |
|
||||
| `targethost=` | `remote` | Target UNIX, DNS host name, or IP address |
|
||||
| `sessionid=` | `session` | New allocated session ID |
|
||||
|
||||
The following fields are currently defined for the end sequence:
|
||||
|
||||
| Field | Context Types | Description |
|
||||
|---------------|---------------|-------------------------------------------------------------------------------------------------------------|
|
||||
| `exit=` | `command` | One of `success`, `failure`, `crash`, `interrupt`, indicating how the program terminated |
|
||||
| `status=` | `command` | The command's numeric exit status, i.e. the 0…255 value a program returns |
|
||||
| `signal=` | `command` | The termination signal of the command, if it died abnormally. A symbolic signal name. (`SIGKILL`, …) |
|
||||
|
||||
All fields are optional, including the context type. However, it is generally
|
||||
recommended to always include the first 7 fields listed above, to make it easy
|
||||
to pinpoint the origin of a context in a race-free fashion, without any
|
||||
ambiguities.
|
||||
|
||||
The order of the metadata fields is undefined, they may appear in any order
|
||||
(including that `type=` is specified at the very end or in the middle!). Note
|
||||
that `start=` and `end=` are not considered metadata fields but part of the
|
||||
start sequence, and hence must always appear right after OSC.
|
||||
|
||||
## Processing, Limits, Security
|
||||
|
||||
All context information provided like this should be considered auxiliary and –
|
||||
to some degree – redundant information. Hence, it would be wise for a terminal
|
||||
to enforce limits on various resources, dropping additional data once these
|
||||
limits are hit. Most importantly, a maximum stacking depth should probably
|
||||
enforced: any attempts to initiate further contexts should be ignored once the
|
||||
stack limit is hit (i.e. the earlier contexts should be kept, the later
|
||||
contexts be discarded, not the opposite). Overly long fields should be
|
||||
discarded (or potentially truncated, depending on the field type). This
|
||||
specification does not recommend any specific stack or string limits for now.
|
||||
|
||||
The usual terminal reset sequences should *not* affect the stack of contexts
|
||||
(this is a safety feature: a program down the stack should not be able to
|
||||
affect the stack further up, possibly hiding relevant information). A temporary
|
||||
TTY hangup (`vhangup()`) should result in a full reset of the stack.
|
||||
|
||||
All provided data should be processed in a lenient, graceful fashion: if a
|
||||
sequence contains invalid fields, those fields should be ignored, but the rest
|
||||
of the fields should still be used. In particular, unknown fields should be
|
||||
ignored.
|
||||
|
||||
The fields provided in these sequences should not contain sensitive
|
||||
information. Context IDs should not be considered confidential, but it is
|
||||
strongly recommended to generate them in a fashion that guarantees their
|
||||
sufficient uniqueness and avoids accidental or intended clashes with other
|
||||
contents.
|
||||
|
||||
## Examples
|
||||
|
||||
1. A new container `foobar` has been invoked by user `lennart` on host `zeta`:
|
||||
`OSC "3008;start=bed86fab93af4328bbed0a1224af6d40;type=container;user=lennart;hostname=zeta;machineid=3deb5353d3ba43d08201c136a47ead7b;bootid=d4a3d0fdf2e24fdea6d971ce73f4fbf2;pid=1062862;pidfdid=1063162;comm=systemd-nspawn;container=foobar" ST`
|
||||
|
||||
2. This context ends: `OSC "3008;end=bed86fab93af4328bbed0a1224af6d40" ST`
|
||||
|
||||
## Syntax in ABNF
|
||||
|
||||
```abnf
|
||||
OSC = %x1B %x5D
|
||||
ST = %x1B %x5C
|
||||
|
||||
DECIMAL = "0"-"9"
|
||||
HEX = "0"-"9" / "A"-"F" / "a-f"
|
||||
ID128 = 32*36(HEX / "-")
|
||||
UINT64 = 1*20DECIMAL
|
||||
ESCSEMICOLON = "\x3b"
|
||||
ESCBACKSLASH = "\x5c"
|
||||
SAFE = %x20-3a / %x3c-5b / %x5d-7e / ESCSEMICOLON / ESCBACKSLASH
|
||||
|
||||
CTXID = 1*64SAFE
|
||||
TYPEENUM = "service" / "session" / "shell" / "command" / "vm" / "container" / "elevate" / "chpriv" / "subcontext" / "remote" / "boot" / "app"
|
||||
|
||||
TYPE = "type=" TYPEENUM
|
||||
USER = "user=" 1*255SAFE
|
||||
HOSTNAME = "hostname=" 1*255SAFE
|
||||
MACHINEID = "machineid=" 1D128
|
||||
BOOTID = "bootid=" ID128
|
||||
PID = "pid=" UINT64
|
||||
PIDFDID = "pidfdid=" UINT64
|
||||
COMM = "comm=" 1*255SAFE
|
||||
CWD = "cwd=" 1*255SAFE
|
||||
CMDLINE = "cmdline=" *255SAFE
|
||||
VM = "vm=" 1*255SAFE
|
||||
CONTAINER = "container=" 1*255SAFE
|
||||
TARGETUSER = "targetuser=" 1*255SAFE
|
||||
TARGETHOST = "targethost=" 1*255SAFE
|
||||
SESSIONID = "sessionid=" 1*255SAFE
|
||||
|
||||
STARTFIELD = TYPE / USER / HOSTNAME / MACHINEID / BOOTID / PID / PIDFDID / COMM / CWD / CMDLINE / VM / CONTAINER / TARGETUSER / TARGETHOST / SESSIONID
|
||||
STARTSEQ = OSC "3008;start=" CTXID *(";" STARTFIELD) ST
|
||||
|
||||
EXITENUM = "success" / "failure" / "crash" / "interrupt"
|
||||
SIGNALENUM = "SIGBUS" / "SIGTRAP" / "SIGABRT" / "SIGSEGV" / …
|
||||
|
||||
EXIT = "exit=" EXITENUM
|
||||
STATUS = "status=" UINT64
|
||||
SIGNAL = "signal=" SIGNALENUM
|
||||
|
||||
ENDFIELD = EXIT / STATUS / SIGNAL
|
||||
ENDSEQ = OSC "3008;end=" CTXID *(";" ENDFIELD) ST
|
||||
```
|
||||
|
||||
## Known OSC Prefixes
|
||||
|
||||
Here's a list of OSC prefixes used by the various sequences currently in public
|
||||
use in various terminal emulators. It's not going to be complete, but I tried
|
||||
to do some reasonably thorough research to avoid conflicts with the new OSC
|
||||
sequence defined above.
|
||||
|
||||
| OSC Prefix | Purpose |
|
||||
|----------------:|------------------------------------------------------------|
|
||||
| `OSC "0;…"` | Icon name + window title |
|
||||
| `OSC "1;…"` | Icon name |
|
||||
| `OSC "2;…"` | Window title |
|
||||
| `OSC "3;…"` | X11 property |
|
||||
| `OSC "4;…"` | Palette |
|
||||
| `OSC "5;…"` | Special palette |
|
||||
| `OSC "6;…"` | Disable special color |
|
||||
| `OSC "7;…"` | Report cwd |
|
||||
| `OSC "8;…"` | Hyperlink |
|
||||
| `OSC "9;…"` | Progress bar (conemu) [conflict: also growl notifications] |
|
||||
| `OSC "10;…"` | Change colors |
|
||||
| `OSC "11;…"` | " |
|
||||
| `OSC "12;…"` | " |
|
||||
| `OSC "13;…"` | " |
|
||||
| `OSC "14;…"` | " |
|
||||
| `OSC "15;…"` | " |
|
||||
| `OSC "16;…"` | " |
|
||||
| `OSC "17;…"` | " |
|
||||
| `OSC "18;…"` | " |
|
||||
| `OSC "19;…"` | " |
|
||||
| `OSC "21;…"` | Query colors (kitty) |
|
||||
| `OSC "22;…"` | Cursor shape |
|
||||
| `OSC "46;…"` | Log file |
|
||||
| `OSC "50;…"` | Set font |
|
||||
| `OSC "51;…"` | Emacs shell |
|
||||
| `OSC "52;…"` | Manipulate selection data (aka clipboard) |
|
||||
| `OSC "60;…"` | Query allowed |
|
||||
| `OSC "61;…"` | Query disallowed |
|
||||
| `OSC "99;…"` | Notifications (kitty) |
|
||||
| `OSC "104;…"` | Reset color |
|
||||
| `OSC "105;…"` | Enable/disable special color |
|
||||
| `OSC "110;…"` | Reset colors |
|
||||
| `OSC "111;…"` | " |
|
||||
| `OSC "112;…"` | " |
|
||||
| `OSC "113;…"` | " |
|
||||
| `OSC "114;…"` | " |
|
||||
| `OSC "115;…"` | " |
|
||||
| `OSC "116;…"` | " |
|
||||
| `OSC "117;…"` | " |
|
||||
| `OSC "118;…"` | " |
|
||||
| `OSC "119;…"` | " |
|
||||
| `OSC "133;…"` | Prompt/command begin/command end (finalterm/iterm2) |
|
||||
| `OSC "440;…"` | Audio (mintty) |
|
||||
| `OSC "633;…"` | vscode action (Windows Terminal) |
|
||||
| `OSC "666;…"` | "termprop" (vte) |
|
||||
| `OSC "701;…"` | Locale (mintty) |
|
||||
| `OSC "777;…"` | Notification (rxvt) |
|
||||
| `OSC "3008;…"` | This specification |
|
||||
| `OSC "7704;…"` | ANSI colors (mintty) |
|
||||
| `OSC "7750;…"` | Emoji style (mintty) |
|
||||
| `OSC "7770;…"` | Font size (mintty) |
|
||||
| `OSC "7771;…"` | Glyph coverage (mintty) |
|
||||
| `OSC "7721:…"` | Copy window title (mintty) |
|
||||
| `OSC "7777;…"` | Window size (mintty) |
|
||||
| `OSC "9001;…"` | Action (Windows Terminal) |
|
||||
| `OSC "1337;…"` | iterm2 multiplex seeuqnece |
|
||||
| `OSC "5522;…"` | Clipboard (kitty) |
|
||||
| `OSC "30001;…"` | Push color onto stack (kitty) |
|
||||
| `OSC "30101;…"` | Pop color from stack (kitty) |
|
||||
| `OSC "77119;…"` | Wide chars (mintty) |
|
||||
|
||||
@ -13,27 +13,24 @@ SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
4. Update hwdb (`ninja -C build update-hwdb`, `ninja -C build update-hwdb-autosuspend`, commit separately).
|
||||
5. Update syscall numbers (`ninja -C build update-syscall-tables update-syscall-header`).
|
||||
6. [RC1] Update library numbers in `meson.build`
|
||||
8. [RC1] Switch `versionrewrite-pattern` and `versionrewrite-replacement` to RC mode in https://build.opensuse.org/projects/system:systemd/packages/systemd/files/_service?expand=1
|
||||
9. Update version number in `meson.version` (e.g. from `256~devel` to `256~rc1` or from `256~rc3` to `256`). Note that this uses a tilde (\~) instead of a hyphen (-) because tildes sort lower in version comparisons according to the [UAPI.10 Version Format Specification](https://uapi-group.org/specifications/specs/version_format_specification/), and we want `255~rc1` to sort lower than `255`.
|
||||
10. Check dbus docs with `ninja -C build update-dbus-docs`
|
||||
11. Check manpages list with `ninja -C build update-man-rules`
|
||||
12. Update translation strings (`ninja -C build systemd-pot`, `ninja -C build systemd-update-po`) - drop the header comments from `systemd.pot` + re-add SPDX before committing. If the only change in a file is the 'POT-Creation-Date' field, then ignore that file.
|
||||
13. Tag the release: `version="v$(sed 's/~/-/g' meson.version)" && git tag -s "${version}" -m "systemd ${version}"` (tildes are replaced with hyphens, because git doesn't accept the former).
|
||||
14. Do `ninja -C build`
|
||||
15. Make sure that the version string and package string match: `build/systemctl --version`
|
||||
16. [FINAL] Close the github milestone and open a new one (https://github.com/systemd/systemd/milestones)
|
||||
17. "Draft" a new release on github (https://github.com/systemd/systemd/releases/new), mark "This is a pre-release" if appropriate.
|
||||
18. Check that announcement to systemd-devel, with a copy&paste from NEWS, was sent. This should happen automatically.
|
||||
19. Update IRC topic (`/msg chanserv TOPIC #systemd Version NNN released | Online resources https://systemd.io/`)
|
||||
20. [FINAL] Create an empty -stable branch: `git push systemd origin/main:refs/heads/v${version}-stable`.
|
||||
21. [FINAL] Build and upload the documentation (on the -stable branch): `ninja -C build doc-sync`
|
||||
22. [FINAL] Create a new `ci/v${version}-stable` branch for deb package builds on https://salsa.debian.org/systemd-team/systemd
|
||||
23. [FINAL] Switch `.semaphore/semaphore-runner.sh` and `mkosi/mkosi.pkgenv/mkosi.conf.d/debian-ubuntu.conf`
|
||||
to the new `ci/v${version}-stable` branch on the -stable branch
|
||||
24. [FINAL] Switch `versionrewrite-pattern` and `versionrewrite-replacement` to release mode in https://build.opensuse.org/projects/system:systemd/packages/systemd/files/_service?expand=1
|
||||
25. [FINAL] Change the Github Pages branch to the newly created branch (https://github.com/systemd/systemd/settings/pages) and set the 'Custom domain' to 'systemd.io'
|
||||
26. [FINAL] Update version number in `meson.version` to the devel version of the next release (e.g. from `256` to `257~devel`)
|
||||
27. [FINAL] Build and upload the documentation (on the main branch): `ninja -C build doc-sync`
|
||||
7. Update version number in `meson.version` (e.g. from `256~devel` to `256~rc1` or from `256~rc3` to `256`). Note that this uses a tilde (\~) instead of a hyphen (-) because tildes sort lower in version comparisons according to the [UAPI.10 Version Format Specification](https://uapi-group.org/specifications/specs/version_format_specification/), and we want `255~rc1` to sort lower than `255`.
|
||||
8. Check dbus docs with `ninja -C build update-dbus-docs`
|
||||
9. Check manpages list with `ninja -C build update-man-rules`
|
||||
10. Update translation strings (`ninja -C build systemd-pot`, `ninja -C build systemd-update-po`) - drop the header comments from `systemd.pot` + re-add SPDX before committing. If the only change in a file is the 'POT-Creation-Date' field, then ignore that file.
|
||||
11. Tag the release: `version="v$(sed 's/~/-/g' meson.version)" && git tag -s "${version}" -m "systemd ${version}"` (tildes are replaced with hyphens, because git doesn't accept the former).
|
||||
12. Do `ninja -C build`
|
||||
13. Make sure that the version string and package string match: `build/systemctl --version`
|
||||
14. [FINAL] Close the github milestone and open a new one (https://github.com/systemd/systemd/milestones)
|
||||
15. "Draft" a new release on github (https://github.com/systemd/systemd/releases/new), mark "This is a pre-release" if appropriate.
|
||||
16. Check that announcement to systemd-devel, with a copy&paste from NEWS, was sent. This should happen automatically.
|
||||
17. Update IRC topic (`/msg chanserv TOPIC #systemd Version NNN released | Online resources https://systemd.io/`)
|
||||
18. [FINAL] Create an empty -stable branch: `git push systemd origin/main:refs/heads/v${version}-stable`.
|
||||
19. [FINAL] Build and upload the documentation (on the -stable branch): `ninja -C build doc-sync`
|
||||
20. [FINAL] Create a new `ci/v${version}-stable` branch for deb package builds on https://salsa.debian.org/systemd-team/systemd
|
||||
21. [FINAL] Switch `.semaphore/semaphore-runner.sh` and `mkosi/mkosi.conf.d/debian-ubuntu/mkosi.conf.d/pkgenv.conf` to the new `ci/v${version}-stable` branch on the -stable branch
|
||||
22. [FINAL] Change the Github Pages branch to the newly created branch (https://github.com/systemd/systemd/settings/pages) and set the 'Custom domain' to 'systemd.io'
|
||||
23. [FINAL] Update version number in `meson.version` to the devel version of the next release (e.g. from `256` to `257~devel`)
|
||||
24. [FINAL] Build and upload the documentation (on the main branch): `ninja -C build doc-sync`
|
||||
|
||||
# Steps to a Successful Stable Release
|
||||
|
||||
|
||||
@ -141,17 +141,6 @@
|
||||
<xi:include href="version-info.xml" xpointer="v250"/></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<variablelist class='environment-variables'>
|
||||
<varlistentry>
|
||||
<term><varname>$SYSTEMD_NSS_RESOLVE_INTERFACE</varname></term>
|
||||
|
||||
<listitem><para>Takes an interface name or index as an argument. When specified, answers will only be
|
||||
obtained from name servers belonging to the specified interface.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v260"/></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
||||
@ -109,15 +109,13 @@
|
||||
<varlistentry>
|
||||
<term><option>--list</option></term>
|
||||
|
||||
<listitem><para>Lists all active inhibition locks instead of acquiring one. It can be filtered using
|
||||
<option>--what=</option>, <option>--who=</option>, <option>--why=</option>, or
|
||||
<option>--mode=</option>.</para></listitem>
|
||||
<listitem><para>Lists all active inhibition locks instead of
|
||||
acquiring one.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="no-ask-password" />
|
||||
<xi:include href="standard-options.xml" xpointer="no-pager" />
|
||||
<xi:include href="standard-options.xml" xpointer="no-legend" />
|
||||
<xi:include href="standard-options.xml" xpointer="json" />
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
|
||||
@ -90,10 +90,6 @@
|
||||
<entry><constant>ww</constant></entry>
|
||||
<entry>Wireless wide area network (WWAN)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>mc</constant></entry>
|
||||
<entry>Management Component Transport Protocol (MCTP)</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
@ -565,16 +561,6 @@
|
||||
<xi:include href="version-info.xml" xpointer="v259"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>v260</constant></term>
|
||||
|
||||
<listitem><para>MCTP interfaces are now assigned persistent names, using a <constant>mc</constant>
|
||||
prefix.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v260"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>Note that <constant>latest</constant> may be used to denote the latest scheme known (to this
|
||||
|
||||
@ -354,7 +354,6 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="no-ask-password" />
|
||||
<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" />
|
||||
|
||||
@ -9,5 +9,5 @@ Environment=
|
||||
GIT_URL=https://salsa.debian.org/systemd-team/systemd.git
|
||||
GIT_SUBDIR=debian
|
||||
GIT_BRANCH=debian/master
|
||||
GIT_COMMIT=6f15bdaae7014c233b662ac4a33d464893b81b36
|
||||
GIT_COMMIT=efdd7a6377c7251011ca2c1a59115d482d25fe61
|
||||
PKG_SUBDIR=debian
|
||||
|
||||
@ -10,10 +10,6 @@
|
||||
# the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This implements the UAPI.15 "OSC 3008: Hierarchical Context Signalling"
|
||||
# specification for the shell prompt. For details see:
|
||||
# https://uapi-group.org/specifications/specs/osc_context/
|
||||
|
||||
# Not bash?
|
||||
[ -n "${BASH_VERSION:-}" ] || return 0
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ _varlinkctl() {
|
||||
local i n verb comps
|
||||
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
local -A OPTS=(
|
||||
[STANDALONE]='-h --help --version --no-pager -q --quiet --no-ask-password
|
||||
[STANDALONE]='-h --help --version --no-pager -q --quiet
|
||||
--oneway --collect --more --exec -j -E'
|
||||
[ARG]='--graceful --timeout --push-fd --json'
|
||||
)
|
||||
|
||||
@ -3914,7 +3914,7 @@ int bus_exec_context_set_transient_property(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
|
||||
if (empty) {
|
||||
bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
|
||||
c->bind_mounts = NULL;
|
||||
c->n_bind_mounts = 0;
|
||||
@ -3959,7 +3959,7 @@ int bus_exec_context_set_transient_property(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
|
||||
if (empty) {
|
||||
temporary_filesystem_free_many(c->temporary_filesystems, c->n_temporary_filesystems);
|
||||
c->temporary_filesystems = NULL;
|
||||
c->n_temporary_filesystems = 0;
|
||||
|
||||
@ -348,7 +348,7 @@ static void service_start_watchdog(Service *s) {
|
||||
log_unit_warning_errno(UNIT(s), r, "Failed to install watchdog timer: %m");
|
||||
}
|
||||
|
||||
usec_t service_restart_usec_next(const Service *s) {
|
||||
usec_t service_restart_usec_next(Service *s) {
|
||||
unsigned n_restarts_next;
|
||||
|
||||
assert(s);
|
||||
|
||||
@ -266,7 +266,7 @@ extern const UnitVTable service_vtable;
|
||||
int service_set_socket_fd(Service *s, int fd, struct Socket *socket, struct SocketPeer *peer, bool selinux_context_net);
|
||||
void service_release_socket_fd(Service *s);
|
||||
|
||||
usec_t service_restart_usec_next(const Service *s) _pure_;
|
||||
usec_t service_restart_usec_next(Service *s);
|
||||
|
||||
int service_determine_exec_selinux_label(Service *s, char **ret);
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <fnmatch.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@ -19,7 +18,6 @@
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "pager.h"
|
||||
#include "parse-argument.h"
|
||||
#include "polkit-agent.h"
|
||||
#include "pretty-print.h"
|
||||
#include "process-util.h"
|
||||
@ -30,14 +28,13 @@
|
||||
#include "terminal-util.h"
|
||||
#include "user-util.h"
|
||||
|
||||
static const char *arg_what = NULL;
|
||||
static const char *arg_what = "idle:sleep:shutdown";
|
||||
static const char *arg_who = NULL;
|
||||
static const char *arg_why = NULL;
|
||||
static const char *arg_why = "Unknown reason";
|
||||
static const char *arg_mode = NULL;
|
||||
static bool arg_ask_password = true;
|
||||
static PagerFlags arg_pager_flags = 0;
|
||||
static bool arg_legend = true;
|
||||
static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF;
|
||||
|
||||
static enum {
|
||||
ACTION_INHIBIT,
|
||||
@ -66,8 +63,6 @@ static int print_inhibitors(sd_bus *bus) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
_cleanup_strv_free_ char **what_filter = NULL;
|
||||
|
||||
int r;
|
||||
|
||||
pager_open(arg_pager_flags);
|
||||
@ -88,12 +83,6 @@ static int print_inhibitors(sd_bus *bus) {
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
if (arg_what) {
|
||||
what_filter = strv_split(arg_what, ":");
|
||||
if (!what_filter)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *comm = NULL, *u = NULL;
|
||||
const char *what, *who, *why, *mode;
|
||||
@ -105,25 +94,6 @@ static int print_inhibitors(sd_bus *bus) {
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (what_filter) {
|
||||
bool skip = false;
|
||||
|
||||
STRV_FOREACH(op, what_filter)
|
||||
if (!string_contains_word(what, ":", *op)) {
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (skip)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg_who && !streq(who, arg_who))
|
||||
continue;
|
||||
|
||||
if (arg_why && fnmatch(arg_why, why, FNM_CASEFOLD) != 0)
|
||||
continue;
|
||||
|
||||
if (arg_mode && !streq(mode, arg_mode))
|
||||
continue;
|
||||
|
||||
@ -154,12 +124,12 @@ static int print_inhibitors(sd_bus *bus) {
|
||||
|
||||
table_set_header(table, arg_legend);
|
||||
|
||||
r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, arg_legend);
|
||||
r = table_print(table, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
return table_log_print_error(r);
|
||||
}
|
||||
|
||||
if (arg_legend && !sd_json_format_enabled(arg_json_format_flags)) {
|
||||
if (arg_legend) {
|
||||
if (table_isempty(table))
|
||||
printf("No inhibitors.\n");
|
||||
else
|
||||
@ -184,8 +154,6 @@ static int help(void) {
|
||||
" --no-ask-password Do not attempt interactive authorization\n"
|
||||
" --no-pager Do not pipe output into a pager\n"
|
||||
" --no-legend Do not show the headers and footers\n"
|
||||
" --json=pretty|short|off\n"
|
||||
" Generate JSON output\n"
|
||||
" --what=WHAT Operations to inhibit, colon separated list of:\n"
|
||||
" shutdown, sleep, idle, handle-power-key,\n"
|
||||
" handle-suspend-key, handle-hibernate-key,\n"
|
||||
@ -215,7 +183,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_NO_ASK_PASSWORD,
|
||||
ARG_NO_PAGER,
|
||||
ARG_NO_LEGEND,
|
||||
ARG_JSON,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@ -229,11 +196,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "list", no_argument, NULL, ARG_LIST },
|
||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||
{ "no-legend", no_argument, NULL, ARG_NO_LEGEND },
|
||||
{ "json", required_argument, NULL, ARG_JSON },
|
||||
{}
|
||||
};
|
||||
|
||||
int c, r;
|
||||
int c;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
@ -283,13 +249,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_legend = false;
|
||||
break;
|
||||
|
||||
case ARG_JSON:
|
||||
r = parse_json_argument(optarg, &arg_json_format_flags);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@ -335,9 +294,6 @@ static int run(int argc, char *argv[]) {
|
||||
/* Ignore SIGINT and allow the forked process to receive it */
|
||||
(void) ignore_signals(SIGINT);
|
||||
|
||||
if (!arg_what)
|
||||
arg_what = "idle:sleep:shutdown";
|
||||
|
||||
if (!arg_who) {
|
||||
w = strv_join(argv + optind, " ");
|
||||
if (!w)
|
||||
@ -346,9 +302,6 @@ static int run(int argc, char *argv[]) {
|
||||
arg_who = w;
|
||||
}
|
||||
|
||||
if (!arg_why)
|
||||
arg_why = "Unknown reason";
|
||||
|
||||
if (!arg_mode)
|
||||
arg_mode = "block";
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
#include "glyph-util.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "json-util.h"
|
||||
#include "netlink-util.h"
|
||||
#include "nss-util.h"
|
||||
#include "resolved-def.h"
|
||||
#include "signal-util.h"
|
||||
@ -189,23 +188,6 @@ static uint64_t query_flags(void) {
|
||||
query_flag("SYSTEMD_NSS_RESOLVE_NETWORK", 0, SD_RESOLVED_NO_NETWORK);
|
||||
}
|
||||
|
||||
static int query_ifindex(void) {
|
||||
int ifindex;
|
||||
const char *e;
|
||||
|
||||
e = secure_getenv("SYSTEMD_NSS_RESOLVE_INTERFACE");
|
||||
if (!e)
|
||||
return 0;
|
||||
|
||||
ifindex = rtnl_resolve_interface(/* rtnl= */ NULL, e);
|
||||
if (ifindex < 0) {
|
||||
log_debug_errno(ifindex, "Failed to resolve $SYSTEMD_NSS_RESOLVE_INTERFACE, ignoring: %m");
|
||||
ifindex = 0;
|
||||
}
|
||||
|
||||
return ifindex;
|
||||
}
|
||||
|
||||
enum nss_status _nss_resolve_gethostbyname4_r(
|
||||
const char *name,
|
||||
struct gaih_addrtuple **pat,
|
||||
@ -235,8 +217,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
|
||||
r = sd_json_buildo(
|
||||
&cparams,
|
||||
SD_JSON_BUILD_PAIR_STRING("name", name),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("ifindex", query_ifindex()));
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()));
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -405,8 +386,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
|
||||
&cparams,
|
||||
SD_JSON_BUILD_PAIR_STRING("name", name),
|
||||
SD_JSON_BUILD_PAIR_INTEGER("family", af),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("ifindex", query_ifindex()));
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()));
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -626,8 +606,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
|
||||
&cparams,
|
||||
SD_JSON_BUILD_PAIR_BYTE_ARRAY("address", addr, len),
|
||||
SD_JSON_BUILD_PAIR_INTEGER("family", af),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("ifindex", query_ifindex()));
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()));
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
|
||||
@ -158,14 +158,13 @@ static int verify_features(
|
||||
bool *ret_has_rk,
|
||||
bool *ret_has_client_pin,
|
||||
bool *ret_has_up,
|
||||
bool *ret_has_uv,
|
||||
bool *ret_has_always_uv) {
|
||||
bool *ret_has_uv) {
|
||||
|
||||
_cleanup_(fido_cbor_info_free_wrapper) fido_cbor_info_t *di = NULL;
|
||||
bool found_extension = false;
|
||||
char **e, **o;
|
||||
const bool *b;
|
||||
bool has_rk = false, has_client_pin = false, has_up = true, has_uv = false, has_always_uv = false; /* Defaults are per table in 5.4 in FIDO2 spec */
|
||||
bool has_rk = false, has_client_pin = false, has_up = true, has_uv = false; /* Defaults are per table in 5.4 in FIDO2 spec */
|
||||
size_t n;
|
||||
int r;
|
||||
|
||||
@ -206,8 +205,6 @@ static int verify_features(
|
||||
has_up = b[i];
|
||||
if (streq(o[i], "uv"))
|
||||
has_uv = b[i];
|
||||
if (streq(o[i], "alwaysUv"))
|
||||
has_always_uv = b[i];
|
||||
}
|
||||
|
||||
if (!found_extension)
|
||||
@ -218,13 +215,11 @@ static int verify_features(
|
||||
log_debug("Has rk ('Resident Key') support: %s\n"
|
||||
"Has clientPin support: %s\n"
|
||||
"Has up ('User Presence') support: %s\n"
|
||||
"Has uv ('User Verification') support: %s\n"
|
||||
"Has alwaysUv ('User Verification' required): %s\n",
|
||||
"Has uv ('User Verification') support: %s\n",
|
||||
yes_no(has_rk),
|
||||
yes_no(has_client_pin),
|
||||
yes_no(has_up),
|
||||
yes_no(has_uv),
|
||||
yes_no(has_always_uv));
|
||||
yes_no(has_uv));
|
||||
|
||||
if (ret_has_rk)
|
||||
*ret_has_rk = has_rk;
|
||||
@ -234,8 +229,6 @@ static int verify_features(
|
||||
*ret_has_up = has_up;
|
||||
if (ret_has_uv)
|
||||
*ret_has_uv = has_uv;
|
||||
if (ret_has_always_uv)
|
||||
*ret_has_always_uv = has_always_uv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -327,7 +320,7 @@ static int fido2_is_cred_in_specific_token(
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO),
|
||||
"Failed to open FIDO2 device %s: %s", path, sym_fido_strerr(r));
|
||||
|
||||
r = verify_features(d, path, LOG_ERR, /* ret_has_rk= */ NULL, /* ret_has_client_pin= */ NULL, &has_up, &has_uv, /* ret_has_always_uv= */ NULL);
|
||||
r = verify_features(d, path, LOG_ERR, NULL, NULL, &has_up, &has_uv);
|
||||
if (r == -ENODEV) { /* Not a FIDO2 device or lacking HMAC-SECRET extension */
|
||||
log_debug_errno(r, "%s is not a FIDO2 device, or it lacks the hmac-secret extension", path);
|
||||
return false;
|
||||
@ -439,7 +432,7 @@ static int fido2_use_hmac_hash_specific_token(
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO),
|
||||
"Failed to open FIDO2 device %s: %s", path, sym_fido_strerr(r));
|
||||
|
||||
r = verify_features(d, path, LOG_ERR, /* ret_has_rk= */ NULL, &has_client_pin, &has_up, &has_uv, /* ret_has_always_uv= */ NULL);
|
||||
r = verify_features(d, path, LOG_ERR, NULL, &has_client_pin, &has_up, &has_uv);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -752,7 +745,7 @@ int fido2_generate_hmac_hash(
|
||||
_cleanup_(fido_cred_free_wrapper) fido_cred_t *c = NULL;
|
||||
_cleanup_(fido_dev_free_wrapper) fido_dev_t *d = NULL;
|
||||
_cleanup_(erase_and_freep) char *used_pin = NULL;
|
||||
bool has_rk, has_client_pin, has_up, has_uv, has_always_uv;
|
||||
bool has_rk, has_client_pin, has_up, has_uv;
|
||||
_cleanup_free_ char *cid_copy = NULL;
|
||||
size_t cid_size, secret_size;
|
||||
const void *cid, *secret;
|
||||
@ -794,7 +787,7 @@ int fido2_generate_hmac_hash(
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO),
|
||||
"Failed to open FIDO2 device %s: %s", device, sym_fido_strerr(r));
|
||||
|
||||
r = verify_features(d, device, LOG_ERR, &has_rk, &has_client_pin, &has_up, &has_uv, &has_always_uv);
|
||||
r = verify_features(d, device, LOG_ERR, &has_rk, &has_client_pin, &has_up, &has_uv);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -814,19 +807,6 @@ int fido2_generate_hmac_hash(
|
||||
lock_with &= ~FIDO2ENROLL_UV;
|
||||
}
|
||||
|
||||
if (has_always_uv && !(FLAGS_SET(lock_with, FIDO2ENROLL_PIN) || FLAGS_SET(lock_with, FIDO2ENROLL_UV))) {
|
||||
if (has_uv) {
|
||||
log_notice("FIDO2 device %s enforces 'always user verification', forcing user verification.", device);
|
||||
lock_with |= FIDO2ENROLL_UV;
|
||||
} else if (has_client_pin) {
|
||||
log_notice("FIDO2 device %s enforces 'always user verification', but doesn't support user verification, forcing PIN.", device);
|
||||
lock_with |= FIDO2ENROLL_PIN;
|
||||
} else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"FIDO2 device %s enforces 'always user verification', but doesn't support user verification or PIN, cannot proceed.",
|
||||
device);
|
||||
}
|
||||
|
||||
c = sym_fido_cred_new();
|
||||
if (!c)
|
||||
return log_oom();
|
||||
@ -1144,8 +1124,7 @@ static int check_device_is_fido2_with_hmac_secret(
|
||||
bool *ret_has_rk,
|
||||
bool *ret_has_client_pin,
|
||||
bool *ret_has_up,
|
||||
bool *ret_has_uv,
|
||||
bool *ret_has_always_uv) {
|
||||
bool *ret_has_uv) {
|
||||
|
||||
_cleanup_(fido_dev_free_wrapper) fido_dev_t *d = NULL;
|
||||
int r;
|
||||
@ -1159,9 +1138,9 @@ static int check_device_is_fido2_with_hmac_secret(
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO),
|
||||
"Failed to open FIDO2 device %s: %s", path, sym_fido_strerr(r));
|
||||
|
||||
r = verify_features(d, path, LOG_DEBUG, ret_has_rk, ret_has_client_pin, ret_has_up, ret_has_uv, ret_has_always_uv);
|
||||
r = verify_features(d, path, LOG_DEBUG, ret_has_rk, ret_has_client_pin, ret_has_up, ret_has_uv);
|
||||
if (r == -ENODEV) { /* Not a FIDO2 device, or not implementing 'hmac-secret' */
|
||||
*ret_has_rk = *ret_has_client_pin = *ret_has_up = *ret_has_uv = *ret_has_always_uv = false;
|
||||
*ret_has_rk = *ret_has_client_pin = *ret_has_up = *ret_has_uv = false;
|
||||
return false;
|
||||
}
|
||||
if (r < 0)
|
||||
@ -1199,7 +1178,7 @@ int fido2_list_devices(void) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
t = table_new("path", "manufacturer", "product", "compatible", "rk", "clientpin", "up", "uv", "alwaysuv");
|
||||
t = table_new("path", "manufacturer", "product", "compatible", "rk", "clientpin", "up", "uv");
|
||||
if (!t) {
|
||||
r = log_oom();
|
||||
goto finish;
|
||||
@ -1207,7 +1186,7 @@ int fido2_list_devices(void) {
|
||||
|
||||
for (size_t i = 0; i < found; i++) {
|
||||
const fido_dev_info_t *entry;
|
||||
bool has_rk, has_client_pin, has_up, has_uv, has_always_uv;
|
||||
bool has_rk, has_client_pin, has_up, has_uv;
|
||||
|
||||
entry = sym_fido_dev_info_ptr(di, i);
|
||||
if (!entry) {
|
||||
@ -1216,7 +1195,7 @@ int fido2_list_devices(void) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = check_device_is_fido2_with_hmac_secret(sym_fido_dev_info_path(entry), &has_rk, &has_client_pin, &has_up, &has_uv, &has_always_uv);
|
||||
r = check_device_is_fido2_with_hmac_secret(sym_fido_dev_info_path(entry), &has_rk, &has_client_pin, &has_up, &has_uv);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
bool compatible = r > 0;
|
||||
@ -1230,8 +1209,7 @@ int fido2_list_devices(void) {
|
||||
TABLE_BOOLEAN_CHECKMARK, has_rk,
|
||||
TABLE_BOOLEAN_CHECKMARK, has_client_pin,
|
||||
TABLE_BOOLEAN_CHECKMARK, has_up,
|
||||
TABLE_BOOLEAN_CHECKMARK, has_uv,
|
||||
TABLE_BOOLEAN_CHECKMARK, has_always_uv);
|
||||
TABLE_BOOLEAN_CHECKMARK, has_uv);
|
||||
if (r < 0) {
|
||||
table_log_add_error(r);
|
||||
goto finish;
|
||||
@ -1249,8 +1227,7 @@ int fido2_list_devices(void) {
|
||||
"%1$sLegend: RK %2$s Resident key%3$s\n"
|
||||
"%1$s CLIENTPIN %2$s PIN request%3$s\n"
|
||||
"%1$s UP %2$s User presence%3$s\n"
|
||||
"%1$s UV %2$s User verification%3$s\n"
|
||||
"%1$s AlwaysUV %2$s User verification Required%3$s\n",
|
||||
"%1$s UV %2$s User verification%3$s\n",
|
||||
ansi_grey(),
|
||||
glyph(GLYPH_ARROW_RIGHT),
|
||||
ansi_normal());
|
||||
@ -1310,8 +1287,7 @@ int fido2_find_device_auto(char **ret) {
|
||||
/* ret_has_rk= */ NULL,
|
||||
/* ret_has_client_pin= */ NULL,
|
||||
/* ret_has_up= */ NULL,
|
||||
/* ret_has_uv= */ NULL,
|
||||
/* ret_has_always_uv= */ NULL);
|
||||
/* ret_has_uv= */ NULL);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
if (!r) {
|
||||
|
||||
@ -30,7 +30,6 @@ static const NamingScheme naming_schemes[] = {
|
||||
{ "v257", NAMING_V257 },
|
||||
{ "v258", NAMING_V258 },
|
||||
{ "v259", NAMING_V259 },
|
||||
{ "v260", NAMING_V260 },
|
||||
/* … add more schemes here, as the logic to name devices is updated … */
|
||||
|
||||
EXTRA_NET_NAMING_MAP
|
||||
|
||||
@ -43,7 +43,6 @@ typedef enum NamingSchemeFlags {
|
||||
NAMING_DEVICETREE_PORT_ALIASES = 1 << 19, /* Include aliases of OF nodes of a netdev itself, not just its parent. See PR #33958. */
|
||||
NAMING_USE_INTERFACE_PROPERTY = 1 << 20, /* Use INTERFACE udev property, rather than sysname, when no renaming is requested. */
|
||||
NAMING_DEVICETREE_ALIASES_WLAN = 1 << 21, /* Generate names from devicetree aliases for WLAN devices */
|
||||
NAMING_MCTP = 1 << 22, /* Use "mc" prefix for MCTP devices */
|
||||
|
||||
/* And now the masks that combine the features above */
|
||||
NAMING_V238 = 0,
|
||||
@ -66,7 +65,6 @@ typedef enum NamingSchemeFlags {
|
||||
NAMING_V257 = NAMING_V255 | NAMING_FIRMWARE_NODE_SUN | NAMING_DEVICETREE_PORT_ALIASES,
|
||||
NAMING_V258 = NAMING_V257 | NAMING_USE_INTERFACE_PROPERTY,
|
||||
NAMING_V259 = NAMING_V258 | NAMING_DEVICETREE_ALIASES_WLAN,
|
||||
NAMING_V260 = NAMING_V259 | NAMING_MCTP,
|
||||
|
||||
EXTRA_NET_NAMING_SCHEMES
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "bus-polkit.h"
|
||||
#include "varlink-io.systemd.sysext.h"
|
||||
|
||||
static SD_VARLINK_DEFINE_ENUM_TYPE(
|
||||
@ -20,28 +19,24 @@ static SD_VARLINK_DEFINE_METHOD(
|
||||
SD_VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_INPUT(force, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_INPUT(noReload, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_INPUT(noexec, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_POLKIT_INPUT);
|
||||
SD_VARLINK_DEFINE_INPUT(noexec, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
Unmerge,
|
||||
SD_VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_INPUT(noReload, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_POLKIT_INPUT);
|
||||
SD_VARLINK_DEFINE_INPUT(noReload, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
Refresh,
|
||||
SD_VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_INPUT(force, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_INPUT(noReload, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_INPUT(noexec, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_POLKIT_INPUT);
|
||||
SD_VARLINK_DEFINE_INPUT(noexec, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD_FULL(
|
||||
List,
|
||||
SD_VARLINK_REQUIRES_MORE,
|
||||
SD_VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, SD_VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_POLKIT_INPUT,
|
||||
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(Class, ImageClass, 0),
|
||||
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(Type, ImageType, 0),
|
||||
SD_VARLINK_DEFINE_OUTPUT(Name, SD_VARLINK_STRING, 0),
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> <!--*-nxml-*-->
|
||||
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"https://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
|
||||
|
||||
<!--
|
||||
SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
This file is part of systemd.
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
-->
|
||||
|
||||
<policyconfig>
|
||||
|
||||
<vendor>The systemd Project</vendor>
|
||||
<vendor_url>https://systemd.io</vendor_url>
|
||||
|
||||
<action id="io.systemd.sysext.manage">
|
||||
<description gettext-domain="systemd">Allow managing (merging, unmerging, ...) of system extension images.</description>
|
||||
<message gettext-domain="systemd">Authentication is required for an application to manage a system extension image.</message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin</allow_any>
|
||||
<allow_inactive>auth_admin</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="io.systemd.sysext.read">
|
||||
<description gettext-domain="systemd">Allow reading (listing, ...) of system extension images.</description>
|
||||
<message gettext-domain="systemd">Authentication is required for an application to list system extension images.</message>
|
||||
<defaults>
|
||||
<allow_any>yes</allow_any>
|
||||
<allow_inactive>yes</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="io.systemd.confext.manage">
|
||||
<description gettext-domain="systemd">Allow managing (merging, unmerging, ...) of configuration extension images.</description>
|
||||
<message gettext-domain="systemd">Authentication is required for an application to manage a configuration extension image.</message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin</allow_any>
|
||||
<allow_inactive>auth_admin</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="io.systemd.confext.read">
|
||||
<description gettext-domain="systemd">Allow reading (listing, ...) of configuration extension images.</description>
|
||||
<message gettext-domain="systemd">Authentication is required for an application to list configuration extension images.</message>
|
||||
<defaults>
|
||||
<allow_any>yes</allow_any>
|
||||
<allow_inactive>yes</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
</policyconfig>
|
||||
@ -18,7 +18,4 @@ if conf.get('ENABLE_SYSEXT') == 1
|
||||
install_symlink('systemd-confext',
|
||||
pointing_to : 'systemd-sysext',
|
||||
install_dir : bindir)
|
||||
|
||||
install_data('io.systemd.sysext.policy',
|
||||
install_dir : polkitpolicydir)
|
||||
endif
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
#include "blkid-util.h"
|
||||
#include "blockdev-util.h"
|
||||
#include "build.h"
|
||||
#include "bus-polkit.h"
|
||||
#include "bus-unit-util.h"
|
||||
#include "bus-util.h"
|
||||
#include "capability-util.h"
|
||||
@ -118,8 +117,6 @@ static const struct {
|
||||
const char *full_identifier;
|
||||
const char *short_identifier;
|
||||
const char *short_identifier_plural;
|
||||
const char *polkit_rw_action_id;
|
||||
const char *polkit_ro_action_id;
|
||||
const char *blurb;
|
||||
const char *dot_directory_name;
|
||||
const char *directory_name;
|
||||
@ -135,8 +132,6 @@ static const struct {
|
||||
.full_identifier = "systemd-sysext",
|
||||
.short_identifier = "sysext",
|
||||
.short_identifier_plural = "extensions",
|
||||
.polkit_rw_action_id = "io.systemd.sysext.manage",
|
||||
.polkit_ro_action_id = "io.systemd.sysext.read",
|
||||
.blurb = "Merge system extension images into /usr/ and /opt/.",
|
||||
.dot_directory_name = ".systemd-sysext",
|
||||
.level_env = "SYSEXT_LEVEL",
|
||||
@ -151,8 +146,6 @@ static const struct {
|
||||
.full_identifier = "systemd-confext",
|
||||
.short_identifier = "confext",
|
||||
.short_identifier_plural = "confexts",
|
||||
.polkit_rw_action_id = "io.systemd.confext.manage",
|
||||
.polkit_ro_action_id = "io.systemd.confext.read",
|
||||
.blurb = "Merge configuration extension images into /etc/.",
|
||||
.dot_directory_name = ".systemd-confext",
|
||||
.level_env = "CONFEXT_LEVEL",
|
||||
@ -630,16 +623,13 @@ static int vl_method_unmerge(sd_varlink *link, sd_json_variant *parameters, sd_v
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "class", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(MethodUnmergeParameters, class), 0 },
|
||||
{ "noReload", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(MethodUnmergeParameters, no_reload), 0 },
|
||||
VARLINK_DISPATCH_POLKIT_FIELD,
|
||||
{}
|
||||
};
|
||||
MethodUnmergeParameters p = {
|
||||
.no_reload = -1,
|
||||
};
|
||||
Hashmap **polkit_registry = ASSERT_PTR(userdata);
|
||||
_cleanup_strv_free_ char **hierarchies = NULL;
|
||||
ImageClass image_class = arg_image_class;
|
||||
bool no_reload;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -648,24 +638,13 @@ static int vl_method_unmerge(sd_varlink *link, sd_json_variant *parameters, sd_v
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
no_reload = p.no_reload >= 0 ? p.no_reload : arg_no_reload;
|
||||
|
||||
r = parse_image_class_parameter(link, p.class, &image_class, &hierarchies);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
/* bus= */ NULL,
|
||||
image_class_info[image_class].polkit_rw_action_id,
|
||||
(const char**) STRV_MAKE(
|
||||
"verb", "unmerge",
|
||||
"noReload", one_zero(no_reload)),
|
||||
polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = unmerge(image_class, hierarchies ?: arg_hierarchies, no_reload);
|
||||
r = unmerge(image_class,
|
||||
hierarchies ?: arg_hierarchies,
|
||||
p.no_reload >= 0 ? p.no_reload : arg_no_reload);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2282,7 +2261,6 @@ static int parse_merge_parameters(sd_varlink *link, sd_json_variant *parameters,
|
||||
{ "force", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(MethodMergeParameters, force), 0 },
|
||||
{ "noReload", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(MethodMergeParameters, no_reload), 0 },
|
||||
{ "noexec", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(MethodMergeParameters, noexec), 0 },
|
||||
VARLINK_DISPATCH_POLKIT_FIELD,
|
||||
{}
|
||||
};
|
||||
|
||||
@ -2294,7 +2272,6 @@ static int parse_merge_parameters(sd_varlink *link, sd_json_variant *parameters,
|
||||
}
|
||||
|
||||
static int vl_method_merge(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
Hashmap **polkit_registry = ASSERT_PTR(userdata);
|
||||
_cleanup_hashmap_free_ Hashmap *images = NULL;
|
||||
MethodMergeParameters p = {
|
||||
.force = -1,
|
||||
@ -2303,8 +2280,7 @@ static int vl_method_merge(sd_varlink *link, sd_json_variant *parameters, sd_var
|
||||
};
|
||||
_cleanup_strv_free_ char **hierarchies = NULL;
|
||||
ImageClass image_class = arg_image_class;
|
||||
bool force, no_reload;
|
||||
int r, noexec;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
@ -2316,23 +2292,6 @@ static int vl_method_merge(sd_varlink *link, sd_json_variant *parameters, sd_var
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
force = p.force >= 0 ? p.force : arg_force;
|
||||
no_reload = p.no_reload >= 0 ? p.no_reload : arg_no_reload;
|
||||
noexec = p.noexec >= 0 ? p.noexec : arg_noexec;
|
||||
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
/* bus= */ NULL,
|
||||
image_class_info[image_class].polkit_rw_action_id,
|
||||
(const char**) STRV_MAKE(
|
||||
"verb", "merge",
|
||||
"force", one_zero(force),
|
||||
"noReload", one_zero(no_reload),
|
||||
"noexec", one_zero(noexec > 0)),
|
||||
polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = image_discover_and_read_metadata(image_class, &images);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -2347,7 +2306,12 @@ static int vl_method_merge(sd_varlink *link, sd_json_variant *parameters, sd_var
|
||||
if (r > 0)
|
||||
return sd_varlink_errorbo(link, "io.systemd.sysext.AlreadyMerged", SD_JSON_BUILD_PAIR_STRING("hierarchy", which));
|
||||
|
||||
r = merge(image_class, hierarchies ?: arg_hierarchies, force, no_reload, noexec, images);
|
||||
r = merge(image_class,
|
||||
hierarchies ?: arg_hierarchies,
|
||||
p.force >= 0 ? p.force : arg_force,
|
||||
p.no_reload >= 0 ? p.no_reload : arg_no_reload,
|
||||
p.noexec >= 0 ? p.noexec : arg_noexec,
|
||||
images);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2417,11 +2381,9 @@ static int vl_method_refresh(sd_varlink *link, sd_json_variant *parameters, sd_v
|
||||
.no_reload = -1,
|
||||
.noexec = -1,
|
||||
};
|
||||
Hashmap **polkit_registry = ASSERT_PTR(userdata);
|
||||
_cleanup_strv_free_ char **hierarchies = NULL;
|
||||
ImageClass image_class = arg_image_class;
|
||||
bool force, no_reload;
|
||||
int r, noexec;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
@ -2433,24 +2395,11 @@ static int vl_method_refresh(sd_varlink *link, sd_json_variant *parameters, sd_v
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
force = p.force >= 0 ? p.force : arg_force;
|
||||
no_reload = p.no_reload >= 0 ? p.no_reload : arg_no_reload;
|
||||
noexec = p.noexec >= 0 ? p.noexec : arg_noexec;
|
||||
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
/* bus= */ NULL,
|
||||
image_class_info[image_class].polkit_rw_action_id,
|
||||
(const char**) STRV_MAKE(
|
||||
"verb", "refresh",
|
||||
"force", one_zero(force),
|
||||
"noReload", one_zero(no_reload),
|
||||
"noexec", one_zero(noexec > 0)),
|
||||
polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = refresh(image_class, hierarchies ?: arg_hierarchies, force, no_reload, noexec);
|
||||
r = refresh(image_class,
|
||||
hierarchies ?: arg_hierarchies,
|
||||
p.force >= 0 ? p.force : arg_force,
|
||||
p.no_reload >= 0 ? p.no_reload : arg_no_reload,
|
||||
p.noexec >= 0 ? p.noexec : arg_noexec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2496,11 +2445,9 @@ static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varl
|
||||
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "class", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, 0, 0 },
|
||||
VARLINK_DISPATCH_POLKIT_FIELD,
|
||||
{}
|
||||
};
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
Hashmap **polkit_registry = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -2515,15 +2462,6 @@ static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varl
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
/* bus= */ NULL,
|
||||
image_class_info[image_class].polkit_ro_action_id,
|
||||
(const char**) STRV_MAKE("verb", "list"),
|
||||
polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
_cleanup_hashmap_free_ Hashmap *images = NULL;
|
||||
r = image_discover(RUNTIME_SCOPE_SYSTEM, image_class, arg_root, &images);
|
||||
if (r < 0)
|
||||
@ -2789,14 +2727,10 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
if (arg_varlink) {
|
||||
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *varlink_server = NULL;
|
||||
_cleanup_hashmap_free_ Hashmap *polkit_registry = NULL;
|
||||
|
||||
/* Invocation as Varlink service */
|
||||
|
||||
r = varlink_server_new(
|
||||
&varlink_server,
|
||||
SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA,
|
||||
&polkit_registry);
|
||||
r = varlink_server_new(&varlink_server, SD_VARLINK_SERVER_ROOT_ONLY, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate Varlink server: %m");
|
||||
|
||||
|
||||
@ -1307,7 +1307,7 @@ static int get_ifname_prefix(sd_device *dev, const char **ret) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* handle only ARPHRD_ETHER, ARPHRD_SLIP, ARPHRD_INFINIBAND, and ARPHDR_MCTP devices */
|
||||
/* handle only ARPHRD_ETHER, ARPHRD_SLIP and ARPHRD_INFINIBAND devices */
|
||||
switch (iftype) {
|
||||
case ARPHRD_ETHER: {
|
||||
if (device_is_devtype(dev, "wlan") > 0)
|
||||
@ -1329,13 +1329,6 @@ static int get_ifname_prefix(sd_device *dev, const char **ret) {
|
||||
*ret = "sl";
|
||||
return 0;
|
||||
|
||||
case ARPHRD_MCTP:
|
||||
if (!naming_scheme_has(NAMING_MCTP))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
*ret = "mc";
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#include "sd-varlink.h"
|
||||
|
||||
#include "build.h"
|
||||
#include "bus-util.h"
|
||||
#include "env-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
@ -22,7 +21,6 @@
|
||||
#include "parse-argument.h"
|
||||
#include "parse-util.h"
|
||||
#include "pidfd-util.h"
|
||||
#include "polkit-agent.h"
|
||||
#include "pretty-print.h"
|
||||
#include "process-util.h"
|
||||
#include "string-util.h"
|
||||
@ -48,7 +46,6 @@ static char **arg_graceful = NULL;
|
||||
static usec_t arg_timeout = 0;
|
||||
static bool arg_exec = false;
|
||||
static PushFds arg_push_fds = {};
|
||||
static bool arg_ask_password = true;
|
||||
|
||||
static void push_fds_done(PushFds *p) {
|
||||
assert(p);
|
||||
@ -90,7 +87,6 @@ static int help(void) {
|
||||
"\n%3$sOptions:%4$s\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
" --no-ask-password Do not prompt for password\n"
|
||||
" --no-pager Do not pipe output into a pager\n"
|
||||
" --more Request multiple responses\n"
|
||||
" --collect Collect multiple responses in a JSON array\n"
|
||||
@ -130,23 +126,21 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_TIMEOUT,
|
||||
ARG_EXEC,
|
||||
ARG_PUSH_FD,
|
||||
ARG_NO_ASK_PASSWORD,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||
{ "more", no_argument, NULL, ARG_MORE },
|
||||
{ "oneway", no_argument, NULL, ARG_ONEWAY },
|
||||
{ "json", required_argument, NULL, ARG_JSON },
|
||||
{ "collect", no_argument, NULL, ARG_COLLECT },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "graceful", required_argument, NULL, ARG_GRACEFUL },
|
||||
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
|
||||
{ "exec", no_argument, NULL, ARG_EXEC },
|
||||
{ "push-fd", required_argument, NULL, ARG_PUSH_FD },
|
||||
{ "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||
{ "more", no_argument, NULL, ARG_MORE },
|
||||
{ "oneway", no_argument, NULL, ARG_ONEWAY },
|
||||
{ "json", required_argument, NULL, ARG_JSON },
|
||||
{ "collect", no_argument, NULL, ARG_COLLECT },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "graceful", required_argument, NULL, ARG_GRACEFUL },
|
||||
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
|
||||
{ "exec", no_argument, NULL, ARG_EXEC },
|
||||
{ "push-fd", required_argument, NULL, ARG_PUSH_FD },
|
||||
{},
|
||||
};
|
||||
|
||||
@ -259,10 +253,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
}
|
||||
|
||||
case ARG_NO_ASK_PASSWORD:
|
||||
arg_ask_password = false;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@ -629,8 +619,6 @@ static int verb_call(int argc, char *argv[], void *userdata) {
|
||||
if (arg_exec && (arg_collect || (arg_method_flags & (SD_VARLINK_METHOD_ONEWAY|SD_VARLINK_METHOD_MORE))) != 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--exec and --collect/--more/--oneway may not be combined.");
|
||||
|
||||
(void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password);
|
||||
|
||||
url = argv[1];
|
||||
method = argv[2];
|
||||
parameter = argc > 3 && !streq(argv[3], "-") ? argv[3] : NULL;
|
||||
|
||||
@ -811,33 +811,6 @@ grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file
|
||||
varlinkctl call /run/systemd/io.systemd.sysext io.systemd.sysext.Unmerge '{}'
|
||||
(! grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file )
|
||||
|
||||
# And again, but unprivileged, if we have pidfds and polkit support
|
||||
# Also check that the required policy is installed, as packages might be out of date with the test
|
||||
if systemd-analyze compare-versions "$(uname -r)" ge 6.5 && \
|
||||
systemd-analyze compare-versions "$(pkcheck --version | awk '{print $3}')" ge 124 && \
|
||||
test -f /usr/share/polkit-1/actions/io.systemd.sysext.policy; then
|
||||
mkdir -p /etc/polkit-1/rules.d
|
||||
cat >/etc/polkit-1/rules.d/sysext-unpriv.rules <<'EOF'
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (action.id == "io.systemd.sysext.manage" &&
|
||||
subject.user == "testuser") {
|
||||
return polkit.Result.YES;
|
||||
}
|
||||
});
|
||||
EOF
|
||||
systemctl try-reload-or-restart polkit.service
|
||||
run0 -u testuser varlinkctl call --more /run/systemd/io.systemd.sysext io.systemd.sysext.List '{}'
|
||||
(! grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file )
|
||||
run0 -u testuser varlinkctl call /run/systemd/io.systemd.sysext io.systemd.sysext.Merge '{"allowInteractiveAuthentication": true}'
|
||||
grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file
|
||||
run0 -u testuser varlinkctl call /run/systemd/io.systemd.sysext io.systemd.sysext.Refresh '{"allowInteractiveAuthentication": true}'
|
||||
grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file
|
||||
run0 -u testuser varlinkctl call /run/systemd/io.systemd.sysext io.systemd.sysext.Unmerge '{"allowInteractiveAuthentication": true}'
|
||||
(! grep -q -F "MARKER=1" /usr/lib/systemd/system/some_file )
|
||||
rm -f /etc/polkit-1/rules.d/sysext-unpriv.rules
|
||||
systemctl try-reload-or-restart polkit.service
|
||||
fi
|
||||
|
||||
# Check that extensions cannot contain os-release
|
||||
mkdir -p /run/extensions/app-reject/usr/lib/{extension-release.d/,systemd/system}
|
||||
echo "ID=_any" >/run/extensions/app-reject/usr/lib/extension-release.d/extension-release.app-reject
|
||||
|
||||
@ -26,8 +26,6 @@ at_exit() {
|
||||
|
||||
rm -rf "$IMAGE_DIR"
|
||||
|
||||
rm -f /etc/polkit-1/rules.d/sysext-unpriv.rules
|
||||
|
||||
loginctl disable-linger testuser
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ ConditionCapability=CAP_SYS_ADMIN
|
||||
[Socket]
|
||||
ListenStream=/run/systemd/io.systemd.sysext
|
||||
FileDescriptorName=varlink
|
||||
SocketMode=0666
|
||||
SocketMode=0600
|
||||
Accept=yes
|
||||
MaxConnectionsPerSource=16
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user