|
5 | 5 |
|
6 | 6 | // spell-checker:ignore (ToDO) coreutil |
7 | 7 |
|
| 8 | +use std::fs::read; |
| 9 | +use std::io::Write; |
| 10 | +use tempfile::NamedTempFile; |
| 11 | +use tempfile::TempPath; |
| 12 | +use uucore::process::{getgid, getuid}; |
8 | 13 | use uutests::new_ucmd; |
9 | 14 | use uutests::unwrap_or_return; |
10 | | -use uutests::util::{TestScenario, check_coreutil_version, expected_result, is_ci, whoami}; |
| 15 | +use uutests::util::{ |
| 16 | + TestScenario, check_coreutil_version, expected_result, get_tests_binary, is_ci, |
| 17 | + run_ucmd_as_root, whoami, |
| 18 | +}; |
11 | 19 | use uutests::util_name; |
12 | 20 |
|
13 | 21 | const VERSION_MIN_MULTIPLE_USERS: &str = "8.31"; // this feature was introduced in GNU's coreutils 8.31 |
@@ -470,3 +478,43 @@ fn test_id_pretty_print_password_record() { |
470 | 478 | .fails() |
471 | 479 | .stderr_contains("the argument '-p' cannot be used with '-P'"); |
472 | 480 | } |
| 481 | + |
| 482 | +#[test] |
| 483 | +fn test_id_pretty_print_suid_binary() { |
| 484 | + if let Some(suid_coreutils_path) = create_root_owned_suid_coreutils_binary() { |
| 485 | + let result = TestScenario::new(util_name!()) |
| 486 | + .cmd(suid_coreutils_path.to_str().unwrap()) |
| 487 | + .args(&[util_name!(), "-p"]) |
| 488 | + .succeeds(); |
| 489 | + |
| 490 | + // The `euid` line should be present only if the real UID does not belong to `root` |
| 491 | + if getuid() == 0 { |
| 492 | + result.stdout_does_not_contain("euid\t"); |
| 493 | + } else { |
| 494 | + result.stdout_contains_line("euid\troot"); |
| 495 | + } |
| 496 | + |
| 497 | + // The `rgid` line should be present only if the real GID does not belong to `root` |
| 498 | + if getgid() == 0 { |
| 499 | + result.stdout_does_not_contain("rgid\t"); |
| 500 | + } else { |
| 501 | + result.stdout_contains("rgid\t"); |
| 502 | + } |
| 503 | + } else { |
| 504 | + print!("Test skipped; requires root user"); |
| 505 | + } |
| 506 | +} |
| 507 | + |
| 508 | +/// Create SUID temp file owned by `root:root` with the contents of the `coreutils` binary |
| 509 | +fn create_root_owned_suid_coreutils_binary() -> Option<TempPath> { |
| 510 | + let mut temp_file = NamedTempFile::new().unwrap(); |
| 511 | + let coreutils_binary = read(get_tests_binary()).unwrap(); |
| 512 | + temp_file.write_all(&coreutils_binary).unwrap(); |
| 513 | + let temp_path = temp_file.into_temp_path(); |
| 514 | + let temp_path_str = temp_path.to_str().unwrap(); |
| 515 | + |
| 516 | + run_ucmd_as_root(&TestScenario::new("chown"), &["root:root", temp_path_str]).ok()?; |
| 517 | + run_ucmd_as_root(&TestScenario::new("chmod"), &["+xs", temp_path_str]).ok()?; |
| 518 | + |
| 519 | + Some(temp_path) |
| 520 | +} |
0 commit comments