use crate::common::util::*; use rust_users::*; #[test] fn test_invalid_option() { new_ucmd!().arg("-w").arg("/").fails(); } static DIR: &'static str = "/tmp"; #[test] fn test_invalid_group() { new_ucmd!() .arg("__nosuchgroup__") .arg("/") .fails() .stderr_is("chgrp: invalid group: __nosuchgroup__"); } #[test] fn test_1() { if get_effective_gid() != 0 { new_ucmd!() .arg("bin") .arg(DIR) .fails() .stderr_is("chgrp: changing group of '/tmp': Operation not permitted (os error 1)"); } } #[test] fn test_fail_silently() { if get_effective_gid() != 0 { for opt in &["-f", "--silent", "--quiet"] { new_ucmd!() .arg(opt) .arg("bin") .arg(DIR) .run() .fails_silently(); } } } #[test] fn test_preserve_root() { // It's weird that on OS X, `realpath /etc/..` returns '/private' for d in &[ "/", "/////tmp///../../../../", "../../../../../../../../../../../../../../", "./../../../../../../../../../../../../../../", ] { new_ucmd!() .arg("--preserve-root") .arg("-R") .arg("bin").arg(d) .fails() .stderr_is("chgrp: it is dangerous to operate recursively on '/'\nchgrp: use --no-preserve-root to override this failsafe"); } } #[test] fn test_preserve_root_symlink() { let file = "test_chgrp_symlink2root"; for d in &[ "/", "////tmp//../../../../", "..//../../..//../..//../../../../../../../../", ".//../../../../../../..//../../../../../../../", ] { let (at, mut ucmd) = at_and_ucmd!(); at.symlink_file(d, file); ucmd.arg("--preserve-root") .arg("-HR") .arg("bin").arg(file) .fails() .stderr_is("chgrp: it is dangerous to operate recursively on '/'\nchgrp: use --no-preserve-root to override this failsafe"); } let (at, mut ucmd) = at_and_ucmd!(); at.symlink_file("///usr", file); ucmd.arg("--preserve-root") .arg("-HR") .arg("bin").arg(format!(".//{}/..//..//../../", file)) .fails() .stderr_is("chgrp: it is dangerous to operate recursively on '/'\nchgrp: use --no-preserve-root to override this failsafe"); let (at, mut ucmd) = at_and_ucmd!(); at.symlink_file("/", "/tmp/__root__"); ucmd.arg("--preserve-root") .arg("-R") .arg("bin").arg("/tmp/__root__/.") .fails() .stderr_is("chgrp: it is dangerous to operate recursively on '/'\nchgrp: use --no-preserve-root to override this failsafe"); use std::fs; fs::remove_file("/tmp/__root__").unwrap(); } #[test] #[cfg(target_os = "linux")] fn test_reference() { // skip for root or MS-WSL // * MS-WSL is bugged (as of 2019-12-25), allowing non-root accounts su-level privileges for `chgrp` // * for MS-WSL, succeeds and stdout == 'group of /etc retained as root' if !(get_effective_gid() == 0 || is_wsl()) { new_ucmd!() .arg("-v") .arg("--reference=/etc/passwd") .arg("/etc") .fails() .stderr_is("chgrp: changing group of '/etc': Operation not permitted (os error 1)\nfailed to change group of '/etc' from root to root"); } } #[test] #[cfg(target_vendor = "apple")] fn test_reference() { new_ucmd!() .arg("-v") .arg("--reference=/etc/passwd") .arg("/etc") .succeeds(); } #[test] #[cfg(target_os = "linux")] fn test_big_p() { if get_effective_gid() != 0 { new_ucmd!() .arg("-RP") .arg("bin") .arg("/proc/self/cwd") .fails() .stderr_is( "chgrp: changing group of '/proc/self/cwd': Operation not permitted (os error 1)\n", ); } } #[test] #[cfg(target_os = "linux")] fn test_big_h() { if get_effective_gid() != 0 { assert!( new_ucmd!() .arg("-RH") .arg("bin") .arg("/proc/self/fd") .fails() .stderr .lines() .fold(0, |acc, _| acc + 1) > 1 ); } }