Pierre Warnier
e1cf43502a
Merge pull request #107 from shadow-utils-rs/feat/integration-tests-release
...
tests: integration tests for all 14 tools + CHANGELOG for v0.1.0
v0.1.0
2026-03-24 16:07:46 +01:00
Pierre Warnier
7bd47ff3d0
tests: add integration tests for all 14 tools, add CHANGELOG
...
Add integration tests for the 8 remaining tools:
- useradd, userdel, usermod (user management)
- groupadd, groupdel, groupmod (group management)
- pwck, grpck (file consistency checkers)
101 new tests covering clap parsing, flag conflicts, error paths,
and root-only file mutation operations with synthetic /etc/ files.
Total test count: 461 → 562.
Also adds CHANGELOG.md for v0.1.0 release.
2026-03-24 15:59:04 +01:00
Pierre Warnier
caac89485d
Merge pull request #105 from shadow-utils-rs/fix/93-104-prod-ready
...
prod: 11 production-readiness fixes
2026-03-24 15:45:16 +01:00
Pierre Warnier
5d8ac9587d
review: address all 13 Copilot review comments
...
- Fix cargo build --release --workspace in test scripts
- Document setuid-on-symlinks as intentional in Makefile
- Warn (not abort) on subid allocation failure in useradd
- Propagate subid file read errors instead of unwrap_or_default
- Update SELinux docs to describe best-effort behavior
- Add env_clear() to getfattr subprocess in selinux.rs
- Use hardening::sanitized_env() in nscd.rs instead of local reimpl
- Create testuser in pam-e2e.sh, add cleanup
- Document su-as-root limitation in pam-e2e.sh
- Fix set -e exit code capture in gnu-compat.sh
- Add 5 date validation unit tests in chage
- Wire audit::log_user_event into all 7 tools
2026-03-24 15:42:08 +01:00
Pierre Warnier
3fbeaf448c
chore: remove Cargo.lock from tracking (library convention)
2026-03-24 15:25:11 +01:00
Pierre Warnier
dddd5713ac
deps: upgrade nix 0.29 → 0.30 to unify with uucore
...
Eliminates duplicate nix crate that caused cargo-deny ban failure.
Adapts to nix 0.30 API: fsync/fcntl/fchownat now take AsFd instead
of raw i32 file descriptors; use AT_FDCWD for fchownat.
2026-03-24 15:24:54 +01:00
Pierre Warnier
83080f53dd
CI: upgrade cargo-deny-action to v2 for edition 2024 support
...
The v1 action bundles an old Cargo that doesn't recognize edition 2024.
v2 uses the host toolchain, so we install stable Rust first.
2026-03-24 15:18:07 +01:00
Pierre Warnier
8ba8f940fd
prod: GNU compat tests, PAM e2e, setuid, SELinux, audit, packaging
...
Fixes #93 — GNU compatibility test suite (tests/gnu-compat.sh)
Fixes #94 — PAM end-to-end test script (tests/pam-e2e.sh)
Fixes #95 — Setuid permissions in Makefile (chmod 4755)
Fixes #96 — nscd env_clear() on subprocess spawning
Fixes #97 — SELinux file context support (getfattr/chcon/restorecon)
Fixes #98 — Audit logging to syslog/auditd
Fixes #99 — subuid/subgid allocation in useradd
Fixes #100 — Debian packaging (debian/control, debian/rules)
Fixes #101 — Fedora packaging (shadow-rs.spec)
Fixes #103 — Recursive chown on usermod UID change
Fixes #104 — Proper date validation (Feb 31 rejected)
456 tests, zero clippy warnings. Binary: 894KB (release-small).
2026-03-24 15:15:21 +01:00
Pierre Warnier
bcf1eae8a9
Merge pull request #92 from shadow-utils-rs/fix/78-86-88-final
...
fix: binary <1MB, test helpers, completions
2026-03-24 14:55:12 +01:00
Pierre Warnier
748f0ad88d
fix: binary size <1MB, shared test helpers, shell completions
...
Fixes #78 — Binary size: release-small profile achieves 894KB (<1MB).
Default release also shrank from 1.5MB to 1.3MB thanks to
panic=abort + codegen-units=1 from PR #91 .
Fixes #86 — Shared test helper crate at tests/common/mod.rs with
skip_unless_root(), setup_prefix(), setup_full_prefix(), read_file().
Fixes #88 — Shell completion script at util/generate-completions.sh
(placeholder — generates minimal bash/zsh/fish completions).
456 tests, zero clippy warnings.
2026-03-24 14:48:37 +01:00
Pierre Warnier
20afe8c73b
Merge pull request #91 from shadow-utils-rs/fix/79-90-uutils-compliance
...
infra: uutils compliance — edition 2024, unsafe deny, dead_code deny
2026-03-24 14:44:24 +01:00
Pierre Warnier
9e3faa966c
address Copilot review: fix docs, feature-gate crypt, MSRV 1.94, CI msrv job
2026-03-24 14:43:38 +01:00
Pierre Warnier
896a4214b6
infra: uutils compliance — edition 2024, unsafe deny, dead_code deny
...
Fixes #79 — CODE_OF_CONDUCT.md (Contributor Covenant 2.1)
Fixes #80 — locales/en-US.ftl for all 14 tools
Fixes #81 — rust-version = "1.85.0" in workspace
Fixes #82 — edition 2024 (resolver 3, unsafe extern blocks)
Fixes #83 — GitHub Actions CI (fmt, clippy, test, cargo-deny)
Fixes #84 — .clippy.toml with MSRV and quality thresholds
Fixes #85 — deny.toml tightened (multiple-versions=deny)
Fixes #87 — panic=abort, codegen-units=1 in release profile
Fixes #89 — Makefile with install/uninstall/clean targets
Fixes #90 — workspace lints: cargo group, unused_qualifications
Key policy changes enforced by cargo:
- unsafe_code = "deny" workspace-wide. Only pam.rs and crypt.rs
have #[allow(unsafe_code)] (C FFI boundaries).
- dead_code = "deny" workspace-wide. No unused code allowed.
- Edition 2024: set_var/remove_var are unsafe, so sanitize_env
returns a Vec instead of mutating. Signal handler removed
(was unsafe). localtime_r replaced with pure Rust calendar math.
456 tests, zero clippy warnings.
2026-03-24 14:30:22 +01:00
Pierre Warnier
a6e6ef63b2
Merge pull request #77 from shadow-utils-rs/fix/56-67-69-70-remaining
...
docs/fixes: man pages, benchmarks, BSD research, Copilot findings
2026-03-24 13:12:34 +01:00
Pierre Warnier
81d0e1776d
docs/fixes: man pages, benchmarks, BSD research, Copilot findings
...
Fixes #56 — 14 man pages in docs/man/ (markdown format).
Fixes #67 — 8 Copilot findings fixed:
- useradd: proper date validation (Feb 31 rejected)
- userdel/usermod: --root wired to SysRoot
- usermod: --expiredate validates input
- usermod: --login validates name + updates shadow/group
- userdel: -f separated from -r behavior
- useradd: home dir resolved through SysRoot
- skel: preserves directory permissions
Fixes #69 — benchmark script (benches/benchmark.sh)
Fixes #70 — FreeBSD/NetBSD reference (docs/FREEBSD-NETBSD-REFERENCE.md)
456 tests, zero clippy warnings.
2026-03-24 13:05:40 +01:00
Pierre Warnier
cdf13a8ed3
Merge pull request #76 from shadow-utils-rs/fix/75-gshadow-lock
...
security: add gshadow lock in useradd (Codex finding)
2026-03-24 12:38:55 +01:00
Pierre Warnier
688dd7f2fd
security: add gshadow lock in useradd write_new_gshadow
...
Fixes #75 — found by Codex (GPT-5.4) and Copilot.
write_new_gshadow now acquires FileLock on gshadow_path before
atomic_write. Prevents concurrent groupmod/useradd from silently
overwriting each other's gshadow changes.
2026-03-24 12:33:11 +01:00
Pierre Warnier
4c92f922c4
Merge pull request #74 from shadow-utils-rs/fix/73-gemini-round3
...
security: fix 5 Gemini round 3 findings
2026-03-24 12:04:53 +01:00
Pierre Warnier
9242fe4993
security: fix 5 Gemini round 3 findings
...
Fixes #73
Critical: useradd lock-then-read (hold lock across all file ops).
Medium: skel only copies regular files (skip FIFOs/devices).
Medium: lock PID file uses create_new (O_EXCL, no symlink follow).
Medium: usermod validates group names before mutation.
Medium: userdel canonicalizes paths before protected-dir check.
436 tests, zero clippy warnings.
2026-03-24 11:58:48 +01:00
Pierre Warnier
f8fc2118b8
Merge pull request #72 from shadow-utils-rs/fix/71-gemini-phase2-3-findings
...
security: fix 10 Gemini findings, deduplicate hardening
2026-03-24 11:47:34 +01:00
Pierre Warnier
c66e9c9374
security: fix 10 Gemini findings, deduplicate hardening boilerplate
...
Fixes #71
Critical:
- userdel: reads actual home dir from passwd BEFORE deleting entry
- userdel: safe recursive delete (refuses /, mount points, symlinks)
High:
- chage: pure calendar date parsing (no mktime timezone dependency)
- chpasswd: passwords zeroed via zeroize after use
- All 14 tools: hardening functions moved to shadow_core::hardening
module (-506 lines duplicated boilerplate, +69 shared module)
Medium:
- useradd: create_dir instead of check-then-create (TOCTOU fix)
- newgrp: password read from /dev/tty with echo disabled
- usermod: chown home directory when UID changes
Low:
- pwck/grpck: documented that sorting strips comments
- chpasswd: passwords use Zeroizing<String>
436 tests, zero clippy warnings. Net -159 lines.
2026-03-24 11:38:12 +01:00
Pierre Warnier
b4fe23f158
Merge pull request #68 from shadow-utils-rs/feat/phase3-group-management
...
phase3: all 7 remaining tools — shadow-rs complete
2026-03-24 10:55:23 +01:00
Pierre Warnier
8ee65a7552
phase3: implement groupadd, groupdel, groupmod, grpck, chfn, chsh, newgrp
...
All 14 shadow-utils tools are now implemented.
groupadd: create groups with auto GID allocation, system groups, force mode.
groupdel: delete groups, checks for primary group usage.
groupmod: modify GID, rename, password changes.
grpck: verify /etc/group and /etc/gshadow integrity.
chfn: change GECOS sub-fields (name, room, phone).
chsh: change login shell with /etc/shells validation.
newgrp: change effective group with crypt(3) password verification.
449 tests, zero clippy warnings, all 14 tools in multicall binary.
2026-03-24 10:47:07 +01:00
Pierre Warnier
b3a3041726
Merge pull request #66 from shadow-utils-rs/feat/phase2-user-management
...
phase2: useradd, userdel, usermod, chpasswd, chage
2026-03-24 10:29:42 +01:00
Pierre Warnier
ed5bb0b71a
phase2: implement useradd, userdel, usermod, chpasswd, chage
...
Fixes #57 — useradd: create user accounts with all core flags
(-c, -d, -e, -f, -g, -G, -m, -M, -k, -N, -o, -p, -r, -s, -u, -U).
UID/GID allocation, home dir creation, skel copy, shadow entry.
Fixes #62 — userdel: remove user from passwd/shadow/group/gshadow.
Flags: -f, -r, -P. Removes from membership lists.
Fixes #63 — usermod: modify user properties.
Flags: -c, -d, -e, -f, -g, -G, -a, -L, -U, -l, -s, -u, -P.
Lock/unlock via shadow, group membership management.
Fixes #64 — chpasswd: batch password change from stdin.
Reads username:password pairs, updates /etc/shadow.
Supports -e (pre-encrypted), -R (chroot).
Fixes #65 — chage: password aging management.
All flags: -d, -E, -I, -l, -m, -M, -R, -W.
List mode (-l) shows aging info. Matches GNU output format.
364 tests, zero clippy warnings.
2026-03-24 10:19:52 +01:00