Skip to content

Commit e7b56c7

Browse files
committed
install: add test for install with invalid user or group
1 parent 6b8eb1f commit e7b56c7

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

tests/by-util/test_install.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
use filetime::FileTime;
99
use std::fs;
1010
#[cfg(target_os = "linux")]
11+
use std::fs::File;
12+
#[cfg(target_os = "linux")]
13+
use std::io::{BufRead, BufReader};
14+
#[cfg(target_os = "linux")]
1115
use std::os::unix::ffi::OsStringExt;
1216
use std::os::unix::fs::{MetadataExt, PermissionsExt};
1317
#[cfg(not(windows))]
@@ -2489,3 +2493,86 @@ fn test_install_non_utf8_paths() {
24892493

24902494
ucmd.arg("-D").arg(source_file).arg(&target_path).succeeds();
24912495
}
2496+
2497+
#[test]
2498+
#[cfg(target_os = "linux")]
2499+
fn test_install_set_owner_nonexistent_uid_and_gid() {
2500+
let file = File::open("/etc/login.defs").unwrap();
2501+
let reader = BufReader::new(file);
2502+
let mut uid_min: u32 = 0;
2503+
let mut uid_max: u32 = 0;
2504+
let mut gid_min: u32 = 0;
2505+
let mut gid_max: u32 = 0;
2506+
for line in reader.lines() {
2507+
let line = line.unwrap();
2508+
if line.starts_with("UID_MIN") {
2509+
let tokens: Vec<&str> = line.split_whitespace().collect();
2510+
uid_min = tokens[1].parse().unwrap();
2511+
}
2512+
if line.starts_with("UID_MAX") {
2513+
let tokens: Vec<&str> = line.split_whitespace().collect();
2514+
uid_max = tokens[1].parse().unwrap();
2515+
}
2516+
if line.starts_with("GID_MIN") {
2517+
let tokens: Vec<&str> = line.split_whitespace().collect();
2518+
gid_min = tokens[1].parse().unwrap();
2519+
}
2520+
if line.starts_with("GID_MAX") {
2521+
let tokens: Vec<&str> = line.split_whitespace().collect();
2522+
gid_max = tokens[1].parse().unwrap();
2523+
}
2524+
}
2525+
let file = File::open("/etc/passwd").unwrap();
2526+
let reader = BufReader::new(file);
2527+
2528+
let mut uids: Vec<u32> = vec![];
2529+
let mut gids: Vec<u32> = vec![];
2530+
for line in reader.lines() {
2531+
let line = line.unwrap();
2532+
let tokens: Vec<&str> = line.split(':').collect();
2533+
let uid: u32 = tokens[2].parse().unwrap();
2534+
if (uid_min..=uid_max).contains(&uid) {
2535+
uids.push(uid);
2536+
}
2537+
let gid: u32 = tokens[3].parse().unwrap();
2538+
if (gid_min..=gid_max).contains(&gid) {
2539+
gids.push(gid);
2540+
}
2541+
}
2542+
uids.sort_unstable();
2543+
2544+
let next_uid = if let Some(uid) = uids.last() {
2545+
*uid + 1
2546+
} else {
2547+
uid_min
2548+
};
2549+
2550+
let next_gid = if let Some(gid) = gids.last() {
2551+
*gid + 1
2552+
} else {
2553+
gid_min
2554+
};
2555+
2556+
let ts = TestScenario::new(util_name!());
2557+
let at = &ts.fixtures;
2558+
at.touch("a");
2559+
2560+
if let Ok(result) = run_ucmd_as_root(
2561+
&ts,
2562+
&[
2563+
format!("-o{next_uid}").as_str(),
2564+
format!("-g{next_gid}").as_str(),
2565+
"a",
2566+
"b",
2567+
],
2568+
) {
2569+
result.success();
2570+
assert!(at.file_exists("b"));
2571+
2572+
let metadata = fs::metadata(at.plus("b")).unwrap();
2573+
assert_eq!(metadata.uid(), next_uid);
2574+
assert_eq!(metadata.gid(), next_gid);
2575+
} else {
2576+
println!("Test skipped; requires root user");
2577+
}
2578+
}

0 commit comments

Comments
 (0)