Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions src/uu/useradd/src/useradd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1062,14 +1062,16 @@ pub fn uu_app() -> Command {
.short('e')
.long("expiredate")
.value_name("EXPIRE_DATE")
.help("Account expiration date (YYYY-MM-DD)"),
.help("Account expiration date (YYYY-MM-DD)")
.allow_hyphen_values(true),
)
.arg(
Arg::new(options::INACTIVE)
.short('f')
.long("inactive")
.value_name("INACTIVE")
.help("Days the password may stay expired before the account is disabled"),
.help("Days the password may stay expired before the account is disabled")
.allow_hyphen_values(true),
)
.arg(
Arg::new(options::GID)
Expand Down Expand Up @@ -2376,6 +2378,22 @@ mod tests {
assert_eq!(uid, 9100);
}

#[test]
fn test_negative_one_inactive_and_expiredate() {
let m = uu_app()
.try_get_matches_from(["useradd", "-f", "-1", "-e", "-1", "testuser"])
.expect("should parse -f -1 -e -1");
assert_eq!(
m.get_one::<String>(options::INACTIVE).map(String::as_str),
Some("-1")
);
assert_eq!(
m.get_one::<String>(options::EXPIRE_DATE)
.map(String::as_str),
Some("-1")
);
}

#[test]
fn test_determine_uid_honors_sys_uid_range_for_system() {
let entries: Vec<PasswdEntry> = vec![];
Expand Down
18 changes: 16 additions & 2 deletions src/uu/usermod/src/usermod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,15 +584,17 @@ pub fn uu_app() -> Command {
.short('e')
.long("expiredate")
.value_name("EXPIRE_DATE")
.help("Set the account expiration date"),
.help("Set the account expiration date")
.allow_hyphen_values(true),
)
.arg(
Arg::new(options::INACTIVE)
.short('f')
.long("inactive")
.value_name("INACTIVE")
.value_parser(clap::value_parser!(i64))
.help("Days the password may stay expired before disabling the account"),
.help("Days the password may stay expired before disabling the account")
.allow_hyphen_values(true),
)
.arg(
Arg::new(options::GID)
Expand Down Expand Up @@ -737,6 +739,18 @@ mod tests {
);
}

#[test]
fn test_negative_one_inactive_and_expiredate() {

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.

could you please also add a test in tests/by-util/test_usermod.rs checking that -e -1 / -f -1 blank the shadow fields? thanks

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added test_negative_one_blanks_inactive_and_expiredate in 9de8fb5: it starts from a shadow line with inactive 30 and expire 19782, runs usermod -e -1 -f -1, and checks both fields come out empty. It fails on main.

let m = uu_app()
.try_get_matches_from(["usermod", "-f", "-1", "-e", "-1", "u"])
.expect("should parse -f -1 -e -1");
assert_eq!(m.get_one::<i64>(options::INACTIVE).copied(), Some(-1));
assert_eq!(
m.get_one::<String>(options::EXPIREDATE).map(String::as_str),
Some("-1")
);
}

#[test]
fn test_append_groups() {
let m = uu_app()
Expand Down
21 changes: 21 additions & 0 deletions tests/by-util/test_usermod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,27 @@ fn test_expiredate_accepts_iso_date() {
);
}

#[test]
fn test_negative_one_blanks_inactive_and_expiredate() {
if crate::common::skip_unless_root() {
return;
}

let dir = setup_prefix(
"alice:x:1000:1000:Alice:/home/alice:/bin/bash\n",
"alice:$6$h:19500:0:99999:7:30:19782:\n",
"alice:x:1000:\n",
);

let code = run_with_prefix(&dir, &["-e", "-1", "-f", "-1", "alice"]);
assert_eq!(code, 0, "-1 must be accepted for -e and -f");
assert_eq!(
read_shadow(&dir),
"alice:$6$h:19500:0:99999:7:::\n",
"-1 must blank the inactive and expire fields"
);
}

#[test]
fn test_bad_expiredate_changes_nothing() {
if crate::common::skip_unless_root() {
Expand Down
Loading