33 Commits
Author SHA1 Message Date
Pierre Warnier e33793cc74 release: 0.4.0 (#289)
gpasswd is a fifteenth tool, so a minor bump rather than a patch.

Also corrects the three static-musl sections for it. gpasswd is setuid
and authenticates a group administrator against the group password
through crypt(3) rather than PAM, so unlike chfn and chsh it keeps
working in the musl build; it resolves the caller through getpwuid_r, so
it joins the five tools that do not see directory users there; and it can
neither verify nor set a yescrypt group password. The counts around those
paragraphs were left at fourteen tools.

The README's multicall paragraph still named four setuid applets.
2026-09-06 11:47:43 +02:00
Jocelyn Le SageandPierre Warnier 8361bf512b gpasswd: added implementation of gpasswd (#282)
* gpasswd: added implementation of gpasswd

* gpasswd: rebase onto main and port to the current APIs

Rebases jlesage's implementation onto a main that moved a long way under
it, and carries it onto the interfaces that landed since the branch was
cut. The tool's behaviour is unchanged and still matches GNU on every
path probed.

What the rebase had to resolve:

  - shadow-rs.spec and debian/ were revived by the merge; both were
    deleted because neither could build.
  - The standalone dispatch() and hand-written --list predate the single
    applets() table, which now drives both. gpasswd joins the table.
  - The five shadow-core parser features it asked for no longer exist.
  - The fourteen [[test]] targets are one; test_gpasswd joins it.
  - README, Makefile and PLATFORM-SUPPORT described the pre-#239
    privilege model, in which every applet ran with euid 0.

What changed beyond the rebase:

  - gpasswd keeps its privilege in the multicall build. It is setuid in
    GNU and the branch marks it setuid for the per-tool install, but
    SETUID_APPLETS still listed four names, so the multicall build would
    have dropped privilege and no group administrator could have used it
    -- silently.
  - Comments in /etc/group survive. It read entries only and wrote them
    back, which erases every comment, blank line and NIS compatibility
    line in the file. The locked-file transaction keeps them, and commits
    group and gshadow together so a bad value cannot leave the pair
    disagreeing.
  - The duplicated EchoGuard and password reader are gone, replaced by
    shadow_core::tty, which blocks interrupts for the read so Ctrl-C at
    the prompt cannot leave the terminal with echo off.
  - The print macros are replaced. They panic when the stream is closed,
    which a setuid-root tool must not do part way through a change.
    These were the only five in the repository and no lint caught them,
    so clippy::print_stdout and print_stderr are now denied
    workspace-wide, with the test crate exempt.

The GNU comparison suite gains gpasswd: the unknown-group, unknown-user
and non-member exit codes, all three of which match.

CONTRIBUTING's licence list also said ISC, BSD-2-Clause, CC0-1.0, Zlib
and MPL-2.0 were acceptable, which stopped being true when deny.toml was
narrowed to the graph. It now says what deny.toml enforces.

---------

Co-authored-by: Pierre Warnier <pierre@warnier.net>
2026-09-06 11:03:53 +02:00
Pierre Warnier e09e4bccac release: build the glibc archives on 22.04, and drop a test that could hang (#284)
Two defects in what shipped yesterday.

0.3.0's glibc archives require GLIBC_2.39 and will not start on Debian
12, Ubuntu 22.04 or RHEL 9 -- all of which ran 0.2.2. Pinning the release
runner to Ubuntu 24.04 in #272 let Rust's std link pidfd_spawnp and
pidfd_getpid; those two are the only symbols in the binary above 2.34.
The build now happens inside an ubuntu:22.04 container on the same
runner, which is where the container support in dist earns its keep: the
runner stays current while the floor goes back to GLIBC_2.34, exactly
what 0.2.2 required. Verified by building in that container and dumping
the versioned symbols, and by running the result on a glibc 2.35 host
where the 0.3.0 archive refuses to start. The static musl archive was
never affected.

The PAM test for an unconfigured service could hang rather than fail. On
Debian /etc/pam.d/other falls through to common-auth, which is pam_unix,
so it prompts: the conversation then blocks reading stdin. CI never saw
it because its stdin is not a terminal, but `make check` on a developer's
machine hung indefinitely. The test is removed with a note saying why,
and the permit and deny tests -- which are the ones that matter and which
never converse -- stay.
2026-09-05 14:51:02 +02:00
Pierre Warnier 84402354a4 release: 0.3.0 (#283)
Thirty-eight commits since 0.2.2, none of them in the changelog: the
Unreleased section described the musl archive and nothing else. It now
covers the lot, under the headings the file already uses.

The release itself is the reason to do this now. The aarch64 archive
support merged on Friday and has never run: the configuration is
verified and dist plan lists all three archives, but no tag has yet
driven the pipeline.

Highlights, all documented in full in the changelog:

  - --root performs a real chroot(2) in every tool, where eight of the
    thirteen treated it as a path prefix.
  - passwd -l is idempotent, and chage -l prints what chage(1) prints.
  - chpasswd takes its hashing scheme from ENCRYPT_METHOD.
  - chsh no longer answers differently for a path that exists and one
    that does not, which made a setuid-root tool a filesystem oracle.
  - login.defs numbers are read in octal and hexadecimal as documented.
  - ID allocation consults the name service.
  - An aarch64 archive, and the user-facing tools install into bin.
2026-09-05 14:18:20 +02:00
Pierre Warnier 3a56b6107e ci: run the root suite on pull requests, fix the trace guard's false positives (#259)
* ci: run the root test suite on pull requests, restrict token permissions

About three quarters of the integration suite is root-only and returns
silently when not root, reported as ok. The only job that runs as root was
the Docker matrix, gated on push, so a pull request effectively tested a
quarter of the suite and regressions surfaced only after merge. The matrix
now runs on pull requests too; each distro takes a couple of minutes.

The MSRV job checks --all-targets, so the test code is covered by the
minimum supported version too, and both workflows declare least-privilege
token permissions instead of inheriting the default scope.

* ci: word-boundary the tooling-artifact patterns and cover two more forms

The script's own comment claimed the patterns were word-boundaried; they
were not, so several of them matched as substrings inside ordinary
identifiers and English words, failing any change that happened to touch
one. The alternation is now anchored with \b.

Two forms that slipped through are added: a model name carrying a version
suffix, and the co-author trailer a bot appends to a commit.

CONTRIBUTING.md becomes exempt from the added-lines scan, because it
states the project's policy on such tools and therefore has to be able to
name them; the CI workflow no longer needs an exemption, since nothing in
it matches.

* deps: drop the unused clap derive feature, tighten the license policy

Nothing in the tree derives clap's Parser/Args/Subcommand/ValueEnum, so
the derive feature only pulled clap_derive and heck into the build graph.
It is not the cause of the syn 2/3 duplicate: syn 3 arrives through
uucore -> fluent -> displaydoc and syn 2 through landlock -> enumflags2,
neither of which is ours to move. The deny skip now records that, and
matches any 2.x rather than one stale patch version that no longer exists
in the lockfile.

MPL-2.0 leaves the license allowlist -- it is file-level copyleft and this
project ships MIT only, so a dependency needing it should be a decision
rather than a default -- and a crate from outside crates.io is now denied
instead of warned about.
2026-09-04 11:55:11 +02:00
Pierre Warnier beef0b0a88 chore: release 0.2.2 (#230)
First release to ship prebuilt binaries, and the first to carry a
working passwd in them: 0.2.1 and earlier had no assets at all, and the
archive the new pipeline first produced was built without PAM.

Closes #221.
2026-09-03 13:38:23 +02:00
renovate[bot] bada8f7d46 chore(deps): update rust crate uucore to 0.11 2026-09-01 15:58:33 +02:00
xtqqczze e374d7a141 chore(deps): update rust crates 2026-08-21 10:08:16 +02:00
renovate[bot] c76db40af1 chore(deps): update rust crate clap_complete to v4.6.9 2026-08-12 08:11:19 +02:00
renovate[bot] cfb1bbe236 chore(deps): update rust crate thiserror to v2.0.20 2026-08-08 13:06:15 +02:00
renovate[bot] 6da5b8d2d7 chore(deps): update rust crate clap to v4.6.6 2026-08-07 09:49:16 +02:00
renovate[bot] 5e6a681c52 chore(deps): update rust crate uucore to 0.10 2026-08-06 08:13:45 +02:00
Sylvestre Ledru 0f4bc97ce0 prepare version 0.2.1 2026-08-05 23:09:22 +02:00
Sylvestre Ledru 96a709fce3 prepare version 0.2.1 2026-08-05 22:59:23 +02:00
Sylvestre Ledru cb8ce5ebd2 cargo: rename package to uu_shadow. shadow-rs is already used
https://crates.io/crates/uu_grep is a precedent
2026-08-02 21:31:25 +02:00
renovate[bot] 615c6895ef chore(deps): update rust crate clap to v4.6.5 2026-08-01 07:07:14 +02:00
renovate[bot] 641f4772a2 chore(deps): update rust crate landlock to v0.4.7 2026-07-28 08:02:03 +02:00
renovate[bot] 14fecfc98e chore(deps): update rust crate clap_complete to v4.6.8 2026-07-28 07:59:10 +02:00
Pierre Warnier 750c9bc0d5 deps: update clap to 4.6.4 (with syn 3.0.3) (#201)
Renovate's single-package update (#198) could not land this: clap_derive
4.6.4 requires syn >=3.0.2 while the lockfile pinned syn 3.0.0 (via
thiserror-impl), so the conservative 'cargo update -p clap --precise'
had no solvable resolution. Update both together (clap 4.6.3 -> 4.6.4,
syn 3.0.0 -> 3.0.3). cargo deny check passes with the syn skip added in
#194.
2026-07-27 13:58:06 +02:00
Daniel Hofstetter a31ffacc2f Bump thiserror & adapt deny.toml (#194)
* Bump thiserror from 2.0.18 to 2.0.19

* deny.toml: add syn to skip list

* deny.toml: remove windows-sys from skip list
2026-07-27 13:39:58 +02:00
renovate[bot] 6da85b4e5c chore(deps): update rust crate landlock to v0.4.6 2026-07-26 10:29:11 +02:00
renovate[bot] d0491c7778 chore(deps): update rust crate libc to v0.2.189 2026-07-22 08:01:16 +02:00
renovate[bot] d973f25555 chore(deps): update rust crate libc to v0.2.188 2026-07-21 15:54:06 +02:00
renovate[bot] 0d4666c7d5 chore(deps): update rust crate clap to v4.6.3 2026-07-21 08:11:48 +02:00
renovate[bot] 3b71b4afe2 chore(deps): update rust crate libc to v0.2.187 2026-07-21 08:04:02 +02:00