Commit Graph
977 Commits
Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek 7670c20c6e verbs: add PagerFlags pointer to all CommandDescription's
Before this series, many help() functions opened the pager. This got lost
in the translation. Starting the pager requires access to arg_pager_flags.
While we could pipe this through in case when command_print_help() is
called directly, but this hard in the case when verb_help_auto() or
VERB_COMMON_HELP_AUTO/VERB_COMMON_HELP_AUTO_HIDDEN are used. Let's instead
extend the (const static) CommandDescription structure with a pointer to
the arg_pager_flags variable. This restores the pager functionality in a
uniform fashion with a one-line change in the individual binaries.
2026-08-13 13:46:08 +02:00
Zbigniew Jędrzejewski-Szmek 1a54ce154c various: add --introspect-cli 2026-08-13 13:23:05 +02:00
Zbigniew Jędrzejewski-Szmek 6566264405 homectl: convert to VERB_COMMAND 2026-08-13 13:23:05 +02:00
Yu Watanabe d20313d086 homed/fscrypt: default new homes to v2 policies (#18280) (#42397)
## Summary

Closes #18280.

`systemd-homed` currently writes fscrypt v1 policies, which bind the
master key to the calling process's keyring. This means files in a
homed-managed directory aren't readable when accessed through a
container bind mount, a different mount namespace, or by any process
other than the one that first unlocked the home. Reading the file from a
context that has the key first warms the page cache, but the underlying
problem remains.

v2 policies (Linux 5.4+) route the master key through the filesystem
keyring, via `FS_IOC_ADD_ENCRYPTION_KEY` /
`FS_IOC_REMOVE_ENCRYPTION_KEY`, so the key is visible to every process
accessing the filesystem.

This PR switches `systemd-homed` to v2 by default and keeps existing v1
homes working.

## Changes

**`shared/crypto-util`**: Add `kdf_hkdf_derive` (HKDF, RFC 5869) wrapper
around OpenSSL's `EVP_KDF` "HKDF", alongside the existing SSKDF/KBKDF
helpers.

**`homed/fscrypt`**:
- Read the existing policy via `FS_IOC_GET_ENCRYPTION_POLICY_EX`,
falling back to the legacy ioctl on pre-5.4 kernels.
- `HomeSetup` now carries a full `struct fscrypt_key_specifier` instead
of a bare 8-byte descriptor. Slot decryption derives either the v1
descriptor (double SHA-512) or the v2 identifier (HKDF-SHA512 with the
kernel's info string) from the unwrapped volume key and compares against
the policy.
- Install the master key the right way per version: `add_key("logon",
...)` to thread+user keyrings for v1, `FS_IOC_ADD_ENCRYPTION_KEY` for
v2.
- `home_flush_keyring_fscrypt` opens the image directory, reads the
policy version, and either calls `FS_IOC_REMOVE_ENCRYPTION_KEY` (v2) or
walks the user keyring (v1).
- New homes default to v2; fall back to v1 only when the kernel rejects
v2.

The on-disk slot xattr format is unchanged - the volume key is the same,
only how it binds to the directory changes. There is no v1 -> v2
migration; existing v1 homes continue to unlock, rekey, and deactivate
as before.
2026-07-25 19:36:35 +09:00
Luca Boccassi 765dc96746 homed: verify privileged worker changes
Workers may return a newer embedded identity while processing
an owner update. Accept self-modifiable changes, but require
privileged changes to carry a trusted signature.

Follow-up for 70a5db5822
2026-07-22 17:11:08 +02:00
Yu Watanabe cc594a83f4 home: insert a space before '=' 2026-07-21 23:38:40 +09:00
Ananth Bhaskararaman 571253fdbe homed/fscrypt: default new homes to v2 policies
fscrypt v1 policies bind master keys to the calling process's keyring,
which means files in a homed-managed directory aren't readable when
accessed through a container bind mount, a different mount namespace,
or by any process other than the one that first unlocked the home.
Reading a file from outside such a context first warms the buffer cache
and papers over the symptom (#18280), but the underlying problem (the
key not flowing across keyrings) remains.

v2 policies (Linux 5.4+) route master keys through the filesystem
keyring via FS_IOC_ADD_ENCRYPTION_KEY / FS_IOC_REMOVE_ENCRYPTION_KEY,
so the key is visible to every process accessing the filesystem.

Switch homed to v2:

- Read the existing policy via FS_IOC_GET_ENCRYPTION_POLICY_EX, which
  reports both v1 and v2 policies. The ioctl is available since Linux
  5.4, i.e. on every kernel we support (our baseline is 5.10), so no
  fallback to the v1-only FS_IOC_GET_ENCRYPTION_POLICY is needed.
- Drive slot matching off a full fscrypt_key_specifier (HomeSetup now
  carries that instead of a bare 8-byte descriptor). Slot decryption
  derives either the v1 descriptor (SHA-512 double hash) or the v2
  identifier (HKDF-SHA512 with the kernel's info string), and compares
  against the policy.
- Install the master key the right way per version: add_key("logon", ...)
  to thread+user keyrings for v1, FS_IOC_ADD_ENCRYPTION_KEY for v2.
- home_flush_keyring_fscrypt opens the image directory, looks up the
  policy, and either calls FS_IOC_REMOVE_ENCRYPTION_KEY (v2) or walks
  the user keyring (v1).
- New homes default to v2; fall back to v1 only if the kernel rejects
  FS_IOC_ADD_ENCRYPTION_KEY with ENOTTY/EOPNOTSUPP. The v2 create path
  derives the identifier locally first, passes it to ADD_KEY as
  expected_identifier, and cleans up via REMOVE_KEY if SET_POLICY then
  fails, so the v1 fallback never sees a stranded key. Existing v1
  homes continue to unlock, rekey, and deactivate as before.
- A v2 master key installed to work on an inactive home is always
  removed again unless that home ends up activated. v2 keys persist in
  the filesystem keyring until removed explicitly (v1 keys instead died
  with the homework process' keyring), so a key left behind would leave
  a home nobody activated readable until the next deactivation or reboot.
  home_setup_fscrypt() and home_create_fscrypt() therefore arm a rollback
  right after installing the key; the activation path disarms it once the
  mount is in place (the live home owns the key), while every other path
  -- create, and passwd/update/resize of an inactive home, plus all error
  paths -- rolls it back via home_setup_done(). Activation reinstalls the
  key.

The v1 and v2 on-disk policy formats differ (v1: 8-byte descriptor;
v2: 16-byte identifier) and fscrypt has no in-place upgrade path, so
a v1 home is always unlocked via the v1 code path and a v2 home is
always unlocked via the v2 code path, regardless of kernel version.

Slot xattr format is unchanged: the master key is the same, only how it
binds to the directory changes.

Fixes #18280.

Ananth Bhaskararaman antsub@gmail.com
2026-07-21 10:18:06 +05:30
Yu Watanabe 661ab8b6fd tree-wide: drop DLOPEN_FOO() macros
Since 4c0d8d9673, most dlopen notes are
set at the beginning of the executables. Let's manage all dlopen notes
there, rather than setting them where dlopen is called.

Note that the only exceptions are the LIBBPF_NOTE for networkd and
nsresource. Since dlopen_bpf() is wrapped in an `#if` guard, the notes
are instead set within the corresponding functionality.

As a result, the DLOPEN_FOO() wrapper macros are no longer needed and
can be dropped completely.
2026-07-18 04:56:32 +09:00
Luca Boccassi 0755bb125c homed: fix verification of local identity file
Follow-up for 70a5db5822
2026-07-16 14:24:18 +02:00
Lennart Poettering 231cde8089 Assorted basic/shared/home/import hardening fixes flagged by kres (#42950) 2026-07-14 23:31:53 +02:00
Yu Watanabe 01e1303f9c Rename basic-forward.h, sd-forward.h, and shared-forward.h to forward.h
Follow-up for 74d392ed1b.
2026-07-15 02:18:05 +09:00
Luca Boccassi 41fc062c49 homework-luks: add new key slots before destroying old ones
home_passwd_luks() rotates the LUKS key slots with a single loop that
destroys slot i before adding its replacement at the same index. If
adding the replacement fails (e.g.: argon2 OOMs), slot i is left
destroyed with no replacement and no rollback. If the user has only
one password, its only key slot is now gone and the home directory can
no longer be unlocked.

Rotate in two passes instead: first add every new password into a free
slot (CRYPT_ANY_SLOT), and only once all adds succeed, destroy the old
slots. If an add fails, roll back the slots added so far and return
with the pre-existing slots untouched, so at least one valid key slot
always remains for each password the user holds.

Follow-up for 70a5db5822
2026-07-14 16:57:14 +01:00
Lennart Poettering e3876f7559 homed: set user.userdb xattrs on homed's userdb socket
We can't make a lot of restrictions here, since users are allowed to
basically freely pick their user names and UIDs too. But let's at least
exclude system UID ranges and those beyond the 16bit range.
2026-07-12 23:09:01 +02:00
Yu Watanabe 4c0d8d9673 tree-wide: embed dlopen notes into individual executables
Previously, when a library was dynamically loaded via a helper function
inside libsystemd-shared.so, the resulting dlopen ELF note was not
propagated to the invoking executable's ELF metadata.

This commit explicitly annotates each executable with the relevant
dlopen ELF notes for any optional dependencies it might potentially
load. This ensures that package managers and build systems can properly
discover runtime dependencies that are triggered indirectly.
2026-07-10 16:35:19 +09:00
Yu Watanabe a74b3e1778 dlopen-note: move all dlopen notes to dlopen-note.h
This also switches all these notes to be defined via SD_ELF_NOTE_DLOPEN_ANCHORED().
Consequently, any notes added within unreachable or unused functions will be
automatically garbage-collected by the linker (--gc-sections) instead of
bloating the final binary.

E.g. unused p11-kit library dependency is now dropped from
systemd-repart.standalone binary.

Before:
```
$ systemd-analyze dlopen-metadata build/systemd-repart.standalone
FEATURE    DESCRIPTION                                                SONAME                        PRIORITY
cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12           recommended
blkid      Support for block device identification                    libblkid.so.1                 required
libcrypto  Support for cryptographic operations                       libcrypto.so.4 libcrypto.so.3 recommended
mount      Support for mount enumeration                              libmount.so.1                 required
fdisk      Support for reading and writing partition tables           libfdisk.so.1                 required
blkid      Support for block device identification                    libblkid.so.1                 recommended
libcrypto  Support for cryptographic operations                       libcrypto.so.4 libcrypto.so.3 suggested
cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12           suggested
fdisk      Support for reading and writing partition tables           libfdisk.so.1                 suggested
idn        Support for internationalized domain names                 libidn2.so.0                  suggested
mount      Support for mount enumeration                              libmount.so.1                 recommended
selinux    Support for SELinux                                        libselinux.so.1               recommended
tpm        Support for TPM                                            libtss2-esys.so.0             suggested
tpm        Support for TPM                                            libtss2-rc.so.0               suggested
tpm        Support for TPM                                            libtss2-mu.so.0               suggested
tpm        Support for TPM                                            libtss2-tcti-device.so.0      suggested
p11-kit    Support for PKCS11 hardware tokens                         libp11-kit.so.0               suggested
```

After:
```
$ systemd-analyze dlopen-metadata build/systemd-repart.standalone
FEATURE    DESCRIPTION                                                SONAME                        PRIORITY
cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12           recommended
blkid      Support for block device identification                    libblkid.so.1                 required
libcrypto  Support for cryptographic operations                       libcrypto.so.4 libcrypto.so.3 recommended
mount      Support for mount enumeration                              libmount.so.1                 required
fdisk      Support for reading and writing partition tables           libfdisk.so.1                 required
blkid      Support for block device identification                    libblkid.so.1                 recommended
libcrypto  Support for cryptographic operations                       libcrypto.so.4 libcrypto.so.3 suggested
cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12           suggested
fdisk      Support for reading and writing partition tables           libfdisk.so.1                 suggested
mount      Support for mount enumeration                              libmount.so.1                 recommended
selinux    Support for SELinux                                        libselinux.so.1               recommended
tpm        Support for TPM                                            libtss2-esys.so.0             suggested
tpm        Support for TPM                                            libtss2-rc.so.0               suggested
tpm        Support for TPM                                            libtss2-mu.so.0               suggested
tpm        Support for TPM                                            libtss2-tcti-device.so.0      suggested
```
2026-07-10 16:34:26 +09:00
Zbigniew Jędrzejewski-Szmek aad1e61010 meson: adjust naming of '*extract*' variables 2026-07-07 13:40:13 +02:00
Zbigniew Jędrzejewski-Szmek f00ccf93b7 meson: rename extract+objects to export+import
We have two concepts: a list of files that should be extracted from an
intermediate build artifact to be used in a later build artifact, and for a
given artifact, a list "donors". The first list was called "extract", because
it is passed to the .extract_objects() meson function, and the second was
called "objects", because that is the meson parameter to specify pre-built
objects files (6350d2dbd9). But this naming is
confusing: we don't care about the 'extract' step, this is something internal
to the build machinery. And 'objects' is a very generic term.

Let's use 'export' for the stuff that is "exported" for other binaries to use,
and 'import' to say where to import from. Those terms are symmetrical and the
association between them should be intuitive. (If you think the terms are
actually assymetrical, there are precedents for confusing the import with the
import sources. E.g. in modern English, turkeys are called so because they were
imported from the Americas and guineafowls were imported from Africa via
Türkiye and all that foreign stuff is alike.)
2026-07-07 13:40:13 +02:00
Yu Watanabe 5280cd7bdb tree-wide: check if necessary cflags dependencies are set
This makes each `foo_cflags` dependency define a `SYSTEMD_CFLAGS_MARKER_FOO`
macro, and checks if the macro is set when headers provided by external
libraries are included.

With this, we can fail fast at compile time if necessary `_cflags`
dependencies are omitted in meson.build. Missing dependencies found by this
mechanism have been added across the tree.
2026-07-03 21:50:45 +09:00
Michael Vogt 896fd702ba firstboot: add new systemd.firstboot=headless mode
This adds a new systemd.firstboot=headless mode. It differs from the
existing systemd.firstboot=no mode in that it still performs the
non-interactive auto-configuration that requires no user input (such
as selecting the only installed locale, or applying settings provided
via credentials), and only skips the prompts that would otherwise
block waiting for user input. In contrast, =no disables that
auto-configuration along with the prompts.

The option is also honoured by homectls firstboot logic and
systemd-cryptenroll, where headless behaves the same as no
(because the is no auto-configuration).
2026-07-02 09:52:21 +01:00
Yu Watanabe 25714364a9 locale-util: drop libintl dependency
Both glibc and musl provides dgettext(). Hence it is not necessary to
use libintl.so provided by gettext.

This partially reverts 590e226437,
fully reverts commit e6e65dc261 and
bd19ffd9cb.

Then, introduce minimal libintl.h for musl build, to avoid using
libintl.h by gettext, which is typically installed on musl-based
build systems.
2026-06-29 23:22:41 +09:00
Lennart Poettering 39d08de81b cryptenroll: collect all enrollment parameters in an EnrollContext
Introduce an EnrollContext structure that carries everything the enrollment
and unlocking helpers need, and route all enroll_*()/load_volume_key_*()/
wipe_slots() calls through it. The command line still populates the existing
arg_* globals as before; once parsing is complete they are copied into a
self-contained EnrollContext (which owns its strings/arrays) and the rest of
the code only ever reads from the context.

This is preparation for the upcoming varlinkification of systemd-cryptenroll:
a Varlink dispatcher (and later an interactive first-boot wizard) can populate
the very same EnrollContext without going through the arg_* parsing layer.

To support non-interactive (e.g. Varlink) callers, the context carries an
'interactive' flag: when false, every credential prompt is disabled and the
helpers fail with -ENOPKG (the established "querying disabled via headless"
code) instead of blocking on a tty. Passwords, FIDO2 PINs and PKCS#11 PINs are
all covered, and an optional FIDO2 PIN can be supplied directly via the
context. enroll_recovery() additionally grows a quiet mode that returns the
recovery key instead of printing it.

This also adds one new field to EnrollContext which didn't exist before:
the unlock_password is useful for the Varlink hookup later.

No change in command line behaviour.
2026-06-27 17:28:39 +02:00
dongshengyuan f301d07ac6 homed: fix home_unlocking_finish reporting success as failure
In home_unlocking_finish(), the success path calls operation_result_unref()
with the local variable r and the uninitialized error object. If either
user_record_good_authentication() or home_save_record() fails (both are
logged as "ignoring"), r is left negative and the D-Bus caller receives
an error reply despite the home having been unlocked successfully.

This causes PAM to reject the session even though the home directory is
mounted and accessible.

Fix by passing 0 and NULL — consistent with every other success path in
the file (home_locking_finish(), home_activation_finish(), etc.).

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-06-25 17:14:23 +02:00
Luca Boccassi 39863e2b1e homectl: retry DeactivateHome on transient busy errors
When 'homectl deactivate' is called immediately after a preceding
operation, the umount inside systemd-homework can fail with EBUSY
because something briefly holds a reference to the home mount (e.g. a
concurrent inspect). systemd-homed already handles this gracefully
by moving the home into the 'lingering' state and retrying deactivation
after 15 seconds, but the bus reply for the original DeactivateHome
call returns the org.freedesktop.home1.HomeBusy error immediately,
which makes TEST-46-HOMED flaky.

Fix homectl to follow homed and retry for up to 30 seconds on HomeBusy
and add a test case trying to make the issue more reproducible.
2026-06-25 13:53:57 +01:00
Luca Boccassi 5ce1786227 polkit: check if user authenticated as admin
The new polkit will return a new detail regarding a successful
authentication: the actual result type, which we can use to
see whether the user authenticated as admin. This can be used
to grant additional privileges.
2026-06-25 10:39:11 +01:00
dongshengyuan 294458fd00 homed: fix min_free tracking in manager_rebalance_calculate()
min_free is supposed to track the minimum free space across all home
directories to scale the next rebalance interval. However, it was
incorrectly assigned h->rebalance_size (the home's current total
allocation) instead of new_free (the remaining allocatable space).

This caused the rebalance interval to be computed from allocation sizes
rather than free space, so a nearly-full home would not trigger the
shorter intervals it should, delaying response to low-space conditions.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-06-22 22:06:05 +02:00
Daan De Meyer 6b158b72f5 tree-wide: Beef up openssl logging
Let's translate openssl's errors to proper errnos 
where we can instead of returning EIO for everything.
Let's also make log_openssl_errors() public so we can
use it everywhere and migrate the rest of the codebase
to use it.
2026-06-22 11:40:57 +02:00
Lennart Poettering 76ef4902d3 homectl: actually honour --mute-console= (#42617) 2026-06-16 17:13:29 +02:00
Luca Boccassi b0ede9f9ee tree-wide: convert dlopen_*() callers to DLOPEN_* wrapper macros
Switch the executable-owned call sites from the plain dlopen_<lib>()
helpers to the new DLOPEN_<LIB>() macros, so that each binary that loads
an optional library at runtime now carries its own .note.dlopen note
instead of relying solely on libsystemd-shared. Each call site passes a
priority reflecting whether it hard-depends on the library (required) or
degrades gracefully without it (recommended).

Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 18:46:24 +01:00
Luca Boccassi 3fb520f010 pkcs11: switch to RSA-OAEP SHA-256/SHA-1
RSA PKCS#1 v1.5 is vulnerable to Bleichenbacher-style padding oracle
attacks, albeit very difficult and unlikely to actually happen in the
real world. Still for hardedning, switch new enrollments to RSA-OAEP,
with SHA-256 preferred and SHA-1 as fallback (probed at enrollment time,
since e.g. SoftHSM only accepts SHA-1, and older token might as well).

The actual padding scheme used to wrap a given key is recorded as a new
optional 'pkcs11-padding' / 'padding' field in the LUKS2 token JSON and
the homed user record. Decryption defaults to PKCS#1 v1.5 when absent so
existing enrollments keep working.
2026-05-22 14:09:16 +01:00
Lennart Poettering 85d47bfa92 firstboot: make clear where the full screen console wizards end
The three first boot screens are visually separated from the console
output before them via the "chome" and welcome strings and sufficient
whitespace. But so far they weren't from the output after them. This is
sometimes a big confusing. Let's add a bit of a separator between the
end and what comes next, too.

Just cosmetics, nothing else.
2026-05-21 09:09:38 +09:00
Lennart Poettering a80024e96d ask-string: support prefilling a string query with an explicit string 2026-05-20 16:34:21 +02:00
Luca Boccassi 4a82fc67c6 homed/fscrypt: add new xattr format hardening key sealing
The current key sealing format has some less-than-ideal weaknesses:

- PBKDF2 with only 65k iterations, where recommendations are ~200k
- AES with null IV, relying on salt for uniqueness
- lack of AES MAC/AEAD

However improbable, it is at least theorically possible that with
a lot of resources an offline bruteforce could be attempted.

Add a v2 sealing format, keeping unsealing compatibility with
the current format:

 v2:<iterations>:<salt>:<IV>:<ciphertext>:<aes tag>

and use 600k iterations for the PBKDF2 sha512
2026-05-19 13:35:19 +01:00
Daan De Meyer bdbcff6530 Various dlopen/linking cleanups from #42100 (#42166)
- **bpf-util: rename from bpf-dlopen, unify version-specific symbol
handling**
- **cryptsetup: dlopen libcryptsetup in tokens**
- **tree-wide: dlopen libpam in pam plugins**
- **test-bus-marshal: dlopen() glib and libdbus instead of linking
directly**
- **lock-util: Simplify timeout for lock_generic_with_timeout()**
- **color-util: simplify hsv_to_rgb, fix rgb_to_hsv negative-hue wrap**
- **tree-wide: Use our own macros instead of fabs()/fmax()/fmin()**
- **locale-util: dlopen() libintl instead of linking against it**
- **home: Use log2u64() over log2()**
- **meson: drop libdl, threads, and librt dependencies**
- **libc: Use dlsym() from a constructor instead of weak symbols**
- **libc: Make sure C23 versions of strtol(), sscanf() are not used**
2026-05-19 08:54:27 +02:00
Daan De Meyer a14adac423 meson: drop libdl, threads, and librt dependencies
Our baseline glibc is 2.34, which merged libdl, libpthread (the
dependency('threads') target), and librt into libc. Empty .so/.a stubs
remain for backward compatibility with old binaries, but new builds
resolve dl_*, pthread_*, mq_*, timer_*, etc. directly from libc.
On musl the same libraries are likewise empty stubs.

Drop the libdl, threads, and librt entries from every meson.build, and
remove the now-stale 'Libs.private: -lrt -pthread' from libudev.pc.in
since both flags resolve to empty link-time stubs on glibc 2.34+ and
musl.

Verified with readelf -d that libsystemd.so, libudev.so, and systemd no
longer carry DT_NEEDED entries for libdl/libpthread/librt.
2026-05-18 21:17:38 +00:00
Daan De Meyer 5a1644de34 home: Use log2u64() over log2()
And drop the libm dependency.
2026-05-18 21:17:38 +00:00
Daan De Meyer e6e65dc261 locale-util: dlopen() libintl instead of linking against it
dgettext() lives in libc on glibc and in libintl.so.8 on musl with
gettext. Resolve it via dlsym() so neither configuration produces a
hard link-time dependency on libintl: try libintl.so.8 first and fall
back to RTLD_DEFAULT (which finds dgettext in libc on glibc).

The _() macro now expands to a runtime check that returns the
untranslated string if dlopen_libintl() has not run successfully, so
callers don't have to gate every translatable message on a runtime
check. pam_systemd_home — currently the only consumer of _() — calls
dlopen_libintl() best-effort from each PAM entry point.

The meson find_library('intl') dance is replaced with a has_header()
check; the only thing we need at build time is the prototype.
2026-05-18 21:17:38 +00:00
Daan De Meyer 62053ee289 tree-wide: dlopen libpam in pam plugins
Same reasoning as for cryptsetup tokens. It means we can include
the pam plugins in the main systemd package without the package 
manager introducing a dependency on libpam. It also makes things
more consistent and makes writing the upcoming linking test script
a lot simpler.

At the same time, we get rid of the libpam_misc dependency as the
one symbol we were using from it is trivial to reimplement ourselves.
2026-05-18 21:17:38 +00:00
Lennart Poettering cd6609499a tree-wide: make use of sd_json_parse_fd() where appropriate 2026-05-18 10:39:04 +01:00
Lennart Poettering 3d88e78927 homed: port one over one sd_json_parse_file() invocation to SD_JSON_PARSE_SEEK0 2026-05-18 08:51:09 +02:00
Zbigniew Jędrzejewski-Szmek 39a3647539 tree-wide: get rid of old dispatch_verb
Also rename dispatch_verb_with_args to dispatch_verb.
2026-05-16 18:37:10 +02:00
Zbigniew Jędrzejewski-Szmek 3b5495c041 homectl: fix unlocking of multiple homes
Fixes 4aa0a8ac3e.
2026-05-15 18:52:01 +02:00
Zbigniew Jędrzejewski-Szmek 6cadf7b108 homectl: convert verbs to VERB macros
--help looks pretty much the same. "[list]" is shown in parentheses
because it's the default.

Co-developed-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:51:58 +02:00
Zbigniew Jędrzejewski-Szmek 9a7b2d0d87 homectl: convert parse_argv to OPTION macros
Rewrite help() with help-util.h primitives + option_parser_get_help_table_group
for each User Record Properties section. The verbs[] table stays
unchanged for now; run() switches from dispatch_verb() (which depended
on the global optind) to _dispatch_verb_with_args() fed by
option_parser_get_args().

Explanations are improved for --birth-date[=DATE] (correct placement of
'['), --skel=, --shell= (short options listed). Some minor rewordings
for other options. The explanation for -E and -EE is split.
(OPTION_HELP_ENTRY_VERBATIM is used for -EE.)

Co-developed-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:51:56 +02:00
Zbigniew Jędrzejewski-Szmek feb1078462 homectl: reorder cases in parse_argv() to match order in --help
Display options --no-pager, --no-legend, --no-ask-password are placed at
the end, after --mute-console=yes, rather than near the top.

Co-developed-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:47:11 +02:00
Zbigniew Jędrzejewski-Szmek 321c894828 homectl: reorder verb functions to match order in --help
Just a hand-crafted moving of blocks of code up and down, no other
changes. The net diff is -2 because add_signing_keys_from_credentials
forward declaration was dropped.
2026-05-15 18:08:20 +02:00
Zbigniew Jędrzejewski-Szmek 587c522487 various: fix duplicated logging from parse_path_argument
As pointed out in review, parse_path_argument can fail for non-oom reasons.
But the function already logs, so the correct thing to do is to just
propagate the error.
2026-05-14 14:15:55 +02:00
Zbigniew Jędrzejewski-Szmek 88d7e44392 Add json_variant_unref_and_replace and use it where appropriate
JSON_VARIANT_REPLACE is similar, but doesn't try to nullify the second
arg, so it can be used with an inline expression.
2026-05-08 11:36:43 +02:00
Zbigniew Jędrzejewski-Szmek c379621426 homectl: drop redunant sort
Claude points out that prompt_groups() already does the sort
in every loop, including the last.
2026-05-05 22:08:19 +02:00
Zbigniew Jędrzejewski-Szmek 392846b370 test-homectl-prompts: add manual test to exercise prompt functionality
The prompt for groups is nice. The prompt for a shell could use some
love. Looking at this is much easier if we can invoke the code outside
in isolation.

I wrote this when looking at https://github.com/systemd/systemd/pull/41947,
where I wanted to see how the homectl prompt works with the changes.
2026-05-05 22:06:41 +02:00
Zbigniew Jędrzejewski-Szmek 764d9d5ddb homectl: split out two prompt functions
homectl.c is too long…
2026-05-05 20:53:23 +02:00