Commit Graph

12 Commits

Author SHA1 Message Date
Pierre Warnier d89b4aaa64 Makefile: drop PROFILE var, fix stale comments
Address Copilot review round 2:

- Remove PROFILE variable and hardcode --release / target/release/.
  Cargo maps "dev" profile to target/debug/ (not target/dev/), so
  PROFILE=dev would silently break install. Nobody installs debug
  builds of setuid-root tools.

- Fix stale comments in Makefile and README that referenced the old
  "chmod on symlink follows through" approach. The current code uses
  install -Dm4755 directly.
2026-04-16 10:43:14 +02:00
Pierre Warnier 698eaf7cf3 make install: default to standalone per-tool binaries (#138)
Switch the default install to build and install 14 standalone per-tool
binaries with a least-privilege setuid layout matching GNU shadow-utils.
Only passwd/chfn/chsh/newgrp are setuid-root; the other 10 tools are 0755.

The previous multicall install is preserved as `make install-multicall`
for container/embedded use cases where the ~14x disk savings matter and
the enlarged setuid attack surface is acceptable.

The old layout chmod'd symlinks pointing to the multicall binary, which
(because chmod follows symlinks) marked the underlying ELF setuid-root.
That meant all 14 tools ran with euid=0 when invoked via symlink. Each
tool's internal getuid() check was defense-in-depth, not OS-level least
privilege. The standalone layout gives the latter.

Raised by @oech3 in uutils/coreutils#11828.
2026-04-15 14:19:21 +02:00
Pierre Warnier 347349721a README: credit Claude Code as main writer, add links for all AI tools 2026-04-03 16:19:35 +02:00
Pierre Warnier 4259dc7cd0 docs: fix stale claims, add missing -p flag to usermod man page
- README: fix passwd flag count (17→16), add Landlock mention, add
  Hardened goal, update usermod description with -p, fix past tense
- CONTRIBUTING: fix unsafe description to match actual workspace policy
- CHANGELOG: add [Unreleased] section for post-v0.1.0 changes
- OPENBSD-REFERENCE: move all implemented items to correct section
- SECURITY-HARDENING: mark all 21 items as implemented
- man/usermod: add -p/--password flag documentation
2026-04-03 15:16:41 +02:00
Pierre Warnier 95d2b2478a docs: add CI/MSRV badges, fix stale reference
- Add CI and MSRV badges to README
- Remove "(when created)" from CODE_OF_CONDUCT.md reference in CONTRIBUTING.md
2026-04-03 14:45:17 +02: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 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
Pierre Warnier 07d328ec87 pwck: address Copilot review — sort fix, -r flag, permissions check 2026-03-24 09:58:50 +01:00
Pierre Warnier be3d6a6c4e docs: add credits for OpenBSD, sudo-rs, uucore, Copilot, Gemini 2026-03-23 16:18:10 +01:00
Pierre Warnier 3ed6188aea tests: add proptest, edge cases, fuzz targets, integration tests, docs
Fixes #11 — tests/by-util/test_passwd.rs: 15 integration tests
  following uutils convention (status format, exit codes, lock/unlock
  cycle, aging, lifecycle, quiet mode, error cases).

Fixes #12 — fuzz targets for all parsers:
  fuzz_passwd_parse, fuzz_shadow_parse, fuzz_login_defs_parse,
  fuzz_validate_username. All must not panic on any input.

Fixes #15 — proptest round-trip tests for PasswdEntry, ShadowEntry:
  generate random valid entries, serialize, parse back, compare.

Fixes #16 — parser edge case tests:
  wrong field counts, empty files, roundtrip via file I/O, negative
  values, boundary values, unicode rejection, null bytes, mixed
  whitespace, duplicate keys, key-only lines.

Also: CONTRIBUTING.md, SECURITY.md created. README.md and CLAUDE.md
updated to reflect uucore integration and current project state.

142 tests passing on Debian/Alpine/Fedora, zero clippy warnings.
2026-03-23 14:11:19 +01:00
Pierre Warnier 202acc16c9 README: rewrite following uutils format, add local Docker git hooks
README.md: project overview with CVE motivation, goals, tool status
table, Docker build/test/lint instructions, architecture diagram,
test matrix, contributing guidelines with GPL clean-room warning.

hooks/: local CI via Docker (no GitHub Actions, no cloud):
- pre-commit: cargo fmt + clippy on Debian (~5s)
- pre-push: fmt + clippy + tests on Debian/Alpine/Fedora (~30s)
- install.sh: symlinks hooks into .git/hooks/
2026-03-23 13:13:36 +01:00
Pierre Warnier eabec36e06 Initial commit 2026-03-23 10:56:43 +01:00