Skip to content

Commit 8a04391

Browse files
committed
install: add test for install with invalid user or group
1 parent deaaf2a commit 8a04391

1 file changed

Lines changed: 86 additions & 0 deletions

File tree

tests/by-util/test_install.rs

Lines changed: 86 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))]
@@ -2567,3 +2571,85 @@ fn test_install_normal_file_replaces_symlink() {
25672571
// Verify sensitive file was NOT modified
25682572
assert_eq!(at.read("sensitive"), "important data");
25692573
}
2574+
#[test]
2575+
#[cfg(target_os = "linux")]
2576+
fn test_install_set_owner_nonexistent_uid_and_gid() {
2577+
let file = File::open("/etc/login.defs").unwrap();
2578+
let reader = BufReader::new(file);
2579+
let mut uid_min: u32 = 0;
2580+
let mut uid_max: u32 = 0;
2581+
let mut gid_min: u32 = 0;
2582+
let mut gid_max: u32 = 0;
2583+
for line in reader.lines() {
2584+
let line = line.unwrap();
2585+
if line.starts_with("UID_MIN") {
2586+
let tokens: Vec<&str> = line.split_whitespace().collect();
2587+
uid_min = tokens[1].parse().unwrap();
2588+
}
2589+
if line.starts_with("UID_MAX") {
2590+
let tokens: Vec<&str> = line.split_whitespace().collect();
2591+
uid_max = tokens[1].parse().unwrap();
2592+
}
2593+
if line.starts_with("GID_MIN") {
2594+
let tokens: Vec<&str> = line.split_whitespace().collect();
2595+
gid_min = tokens[1].parse().unwrap();
2596+
}
2597+
if line.starts_with("GID_MAX") {
2598+
let tokens: Vec<&str> = line.split_whitespace().collect();
2599+
gid_max = tokens[1].parse().unwrap();
2600+
}
2601+
}
2602+
let file = File::open("/etc/passwd").unwrap();
2603+
let reader = BufReader::new(file);
2604+
2605+
let mut uids: Vec<u32> = vec![];
2606+
let mut gids: Vec<u32> = vec![];
2607+
for line in reader.lines() {
2608+
let line = line.unwrap();
2609+
let tokens: Vec<&str> = line.split(':').collect();
2610+
let uid: u32 = tokens[2].parse().unwrap();
2611+
if (uid_min..=uid_max).contains(&uid) {
2612+
uids.push(uid);
2613+
}
2614+
let gid: u32 = tokens[3].parse().unwrap();
2615+
if (gid_min..=gid_max).contains(&gid) {
2616+
gids.push(gid);
2617+
}
2618+
}
2619+
uids.sort_unstable();
2620+
2621+
let next_uid = if let Some(uid) = uids.last() {
2622+
*uid + 1
2623+
} else {
2624+
uid_min
2625+
};
2626+
2627+
let next_gid = if let Some(gid) = gids.last() {
2628+
*gid + 1
2629+
} else {
2630+
gid_min
2631+
};
2632+
2633+
let ts = TestScenario::new(util_name!());
2634+
let at = &ts.fixtures;
2635+
at.touch("a");
2636+
2637+
if let Ok(result) = run_ucmd_as_root(
2638+
&ts,
2639+
&[
2640+
format!("-o{next_uid}").as_str(),
2641+
format!("-g{next_gid}").as_str(),
2642+
"a",
2643+
"b",
2644+
],
2645+
) {
2646+
result.success();
2647+
assert!(at.file_exists("b"));
2648+
2649+
let metadata = fs::metadata(at.plus("b")).unwrap();
2650+
assert_eq!(metadata.uid(), next_uid);
2651+
assert_eq!(metadata.gid(), next_gid);
2652+
} else {
2653+
println!("Test skipped; requires root user");
2654+
}
2655+
}

0 commit comments

Comments
 (0)