diff --git a/src/uu/useradd/src/useradd.rs b/src/uu/useradd/src/useradd.rs index af76918..5432915 100644 --- a/src/uu/useradd/src/useradd.rs +++ b/src/uu/useradd/src/useradd.rs @@ -511,7 +511,9 @@ fn parse_options(matches: &clap::ArgMatches) -> Result Command { .short('U') .long("user-group") .action(ArgAction::SetTrue) + .conflicts_with(options::GID) .help("Also create a matching user-private group (default)"), ) .arg( @@ -1403,6 +1406,15 @@ mod tests { assert!(result.is_err()); } + #[test] + fn test_clap_user_group_conflicts_with_gid() { + let result = uu_app().try_get_matches_from(["useradd", "-U", "-g", "100", "user"]); + assert_eq!( + result.unwrap_err().kind(), + clap::error::ErrorKind::ArgumentConflict + ); + } + #[test] fn test_clap_non_unique_requires_uid() { let result = uu_app().try_get_matches_from(["useradd", "-o", "user"]); diff --git a/tests/by-util/test_useradd.rs b/tests/by-util/test_useradd.rs index 2888165..ad7f896 100644 --- a/tests/by-util/test_useradd.rs +++ b/tests/by-util/test_useradd.rs @@ -510,6 +510,28 @@ fn test_create_user_with_key_long_option() { ); } +#[test] +fn test_user_group_flag_wins_over_usergroups_enab_no() { + if crate::common::skip_unless_root() { + return; + } + + let dir = setup_root_dir(); + let defs = dir.path().join("etc/login.defs"); + let content = std::fs::read_to_string(&defs).expect("read login.defs"); + std::fs::write( + &defs, + content.replace("USERGROUPS_ENAB yes", "USERGROUPS_ENAB no"), + ) + .expect("write login.defs"); + + // USERGROUPS_ENAB only sets the default; -U asks for the group explicitly + assert_eq!(run_with_root(&dir, &["-U", "ugu"]), 0); + let group = read_group(&dir); + assert!(group.contains("ugu:x:1000:"), "got: {group}"); + assert!(read_passwd(&dir).contains("ugu:x:1000:1000:")); +} + #[test] fn test_create_system_user_with_key_sys_uid_range() { if crate::common::skip_unless_root() {