Skip to content

useradd: implemented useradd -K/--key KEY=VALUE (override /etc/login.defs defaults) - #211

Merged
pierre-warnier merged 2 commits into
uutils:mainfrom
jlesage:implement-useradd-k-param
Sep 3, 2026
Merged

useradd: implemented useradd -K/--key KEY=VALUE (override /etc/login.defs defaults)#211
pierre-warnier merged 2 commits into
uutils:mainfrom
jlesage:implement-useradd-k-param

Conversation

@jlesage

@jlesage jlesage commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

This implements the useradd -K/--key KEY=VALUE (override /etc/login.defs defaults).

@pierre-warnier pierre-warnier left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this @jlesage, and sorry for the slow first response — the maintainers were away over August.

This is a well-put-together contribution: the LoginDefs::set/apply_overrides API is a clean place for the logic, overrides are applied before the defaults are read (so CREATE_HOME/SKEL behave correctly), and you covered it at three levels — unit tests on the parser, allocation tests for UID/GID/SYS ranges, and root-only integration tests. I ran the suite as root in the Debian container: 23/23 test_useradd tests pass, and fmt + clippy -D warnings + the full workspace suite are green.

One thing to fix before merge, then I'm happy to land it:

useradd -D ignores -K

cmd_defaults() is the third LoginDefs::load site and it doesn't get the overrides, so -K is silently dropped in -D mode. Verified on your branch:

$ useradd -D -K HOME=/OVERRIDDEN -K SHELL=/bin/zsh
GROUP=100
HOME=/home        # expected /OVERRIDDEN
INACTIVE=-1
EXPIRE=
SHELL=            # expected /bin/zsh

parse_options and do_useradd both apply them correctly — it's just this one path. Something like:

fn cmd_defaults(matches: &clap::ArgMatches) -> UResult<()> {
    let root = SysRoot::default();
    let mut defs = LoginDefs::load(&root.login_defs_path())
        .map_err(|e| UseraddError::CannotUpdatePasswd(format!("{e}")))?;
    apply_login_defs_overrides(&mut defs, &parse_login_defs_overrides(matches)?);

(the _matches parameter is already there, just unused). A small -D -K assertion in the integration tests would lock it in.

Non-blocking, for me to follow up

groupadd already has its own -K handling in allocate_gid, which hand-patches only GID_MIN/GID_MAX/SYS_GID_* and silently ignores unparseable values and every other key. Your LoginDefs::apply_overrides is strictly better — I'll open a separate PR migrating groupadd onto it after this lands, so the two tools behave the same. Nothing for you to do here.

cmd_defaults loaded login.defs but dropped -K/--key, so
`useradd -D -K HOME=...` printed the file values. Apply
overrides before printing, and honor --root so -R -D
uses the chroot login.defs.
@jlesage

jlesage commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

@pierre-warnier thank you for the review. I pushed the requested fix. Thank you!

@pierre-warnier pierre-warnier left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified and merging — thanks @jlesage.

The -D path now honours the overrides:

$ useradd -D
HOME=/home
$ useradd -D -K HOME=/OVERRIDDEN -K SHELL=/bin/zsh
HOME=/OVERRIDDEN
SHELL=/bin/zsh

You also went past what I asked for, and both additions are good ones:

  • cmd_defaults was hardcoding SysRoot::default(), so useradd -D -R /some/root silently read the host's login.defs. That was a separate bug and you fixed it.
  • Splitting out write_defaults(matches, out) makes the report testable — it previously wrote straight to stdout with no seam.

Full gate green on Debian: fmt, clippy -D warnings, cargo test --workspace, and 25/25 test_useradd integration tests as root.

Sorry again for the four-week wait on the first review. Follow-up on my side: groupadd has its own hand-rolled -K handling that only understands the GID-range keys and swallows parse errors; I'll migrate it onto your LoginDefs::apply_overrides so both tools behave identically (#223).

@pierre-warnier
pierre-warnier merged commit 3c5acdc into uutils:main Sep 3, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants