mirror of
https://github.com/uutils/coreutils
synced 2024-12-12 22:32:53 +00:00
chcon: allow repeated flags and arguments
This commit is contained in:
parent
dbfd4d80ee
commit
8be5f7a89d
2 changed files with 119 additions and 1 deletions
|
@ -154,6 +154,7 @@ pub fn uu_app() -> Command {
|
|||
.override_usage(format_usage(USAGE))
|
||||
.infer_long_args(true)
|
||||
.disable_help_flag(true)
|
||||
.args_override_self(true)
|
||||
.arg(
|
||||
Arg::new(options::HELP)
|
||||
.long(options::HELP)
|
||||
|
@ -180,7 +181,7 @@ pub fn uu_app() -> Command {
|
|||
.arg(
|
||||
Arg::new(options::preserve_root::PRESERVE_ROOT)
|
||||
.long(options::preserve_root::PRESERVE_ROOT)
|
||||
.conflicts_with(options::preserve_root::NO_PRESERVE_ROOT)
|
||||
.overrides_with(options::preserve_root::NO_PRESERVE_ROOT)
|
||||
.help("Fail to operate recursively on '/'.")
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
|
|
|
@ -374,6 +374,30 @@ fn user_change() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn user_change_repeated() {
|
||||
let (dir, mut cmd) = at_and_ucmd!();
|
||||
|
||||
dir.touch("a.tmp");
|
||||
let a_context = get_file_context(dir.plus("a.tmp")).unwrap();
|
||||
let new_a_context = if let Some(a_context) = a_context {
|
||||
let mut components: Vec<_> = a_context.split(':').collect();
|
||||
components[0] = "guest_u";
|
||||
components.join(":")
|
||||
} else {
|
||||
set_file_context(dir.plus("a.tmp"), "unconfined_u:object_r:user_tmp_t:s0").unwrap();
|
||||
String::from("guest_u:object_r:user_tmp_t:s0")
|
||||
};
|
||||
|
||||
cmd.args(&["--verbose", "--user=wrong", "--user=guest_u"])
|
||||
.arg(dir.plus("a.tmp"))
|
||||
.succeeds();
|
||||
assert_eq!(
|
||||
get_file_context(dir.plus("a.tmp")).unwrap(),
|
||||
Some(new_a_context)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn role_change() {
|
||||
let (dir, mut cmd) = at_and_ucmd!();
|
||||
|
@ -471,6 +495,99 @@ fn valid_reference() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_reference_repeat_flags() {
|
||||
let (dir, mut cmd) = at_and_ucmd!();
|
||||
|
||||
dir.touch("a.tmp");
|
||||
let new_a_context = "guest_u:object_r:etc_t:s0:c42";
|
||||
set_file_context(dir.plus("a.tmp"), new_a_context).unwrap();
|
||||
|
||||
dir.touch("b.tmp");
|
||||
let b_context = get_file_context(dir.plus("b.tmp")).unwrap();
|
||||
assert_ne!(b_context.as_deref(), Some(new_a_context));
|
||||
|
||||
cmd.arg("--verbose")
|
||||
.arg("-vvRRHHLLPP") // spell-checker:disable-line
|
||||
.arg("--no-preserve-root")
|
||||
.arg("--no-preserve-root")
|
||||
.arg("--preserve-root")
|
||||
.arg("--preserve-root")
|
||||
.arg("--dereference")
|
||||
.arg("--dereference")
|
||||
.arg("--no-dereference")
|
||||
.arg("--no-dereference")
|
||||
.arg(format!("--reference={}", dir.plus_as_string("a.tmp")))
|
||||
.arg(dir.plus("b.tmp"))
|
||||
.succeeds();
|
||||
assert_eq!(
|
||||
get_file_context(dir.plus("b.tmp")).unwrap().as_deref(),
|
||||
Some(new_a_context)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_reference_repeated_reference() {
|
||||
let (dir, mut cmd) = at_and_ucmd!();
|
||||
|
||||
dir.touch("a.tmp");
|
||||
let new_a_context = "guest_u:object_r:etc_t:s0:c42";
|
||||
set_file_context(dir.plus("a.tmp"), new_a_context).unwrap();
|
||||
|
||||
dir.touch("wrong.tmp");
|
||||
let new_wrong_context = "guest_u:object_r:etc_t:s42:c0";
|
||||
set_file_context(dir.plus("wrong.tmp"), new_wrong_context).unwrap();
|
||||
|
||||
dir.touch("b.tmp");
|
||||
let b_context = get_file_context(dir.plus("b.tmp")).unwrap();
|
||||
assert_ne!(b_context.as_deref(), Some(new_a_context));
|
||||
|
||||
cmd.arg("--verbose")
|
||||
.arg(format!("--reference={}", dir.plus_as_string("wrong.tmp")))
|
||||
.arg(format!("--reference={}", dir.plus_as_string("a.tmp")))
|
||||
.arg(dir.plus("b.tmp"))
|
||||
.succeeds();
|
||||
assert_eq!(
|
||||
get_file_context(dir.plus("b.tmp")).unwrap().as_deref(),
|
||||
Some(new_a_context)
|
||||
);
|
||||
assert_eq!(
|
||||
get_file_context(dir.plus("wrong.tmp")).unwrap().as_deref(),
|
||||
Some(new_wrong_context)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_reference_multi() {
|
||||
let (dir, mut cmd) = at_and_ucmd!();
|
||||
|
||||
dir.touch("a.tmp");
|
||||
let new_a_context = "guest_u:object_r:etc_t:s0:c42";
|
||||
set_file_context(dir.plus("a.tmp"), new_a_context).unwrap();
|
||||
|
||||
dir.touch("b1.tmp");
|
||||
let b1_context = get_file_context(dir.plus("b1.tmp")).unwrap();
|
||||
assert_ne!(b1_context.as_deref(), Some(new_a_context));
|
||||
|
||||
dir.touch("b2.tmp");
|
||||
let b2_context = get_file_context(dir.plus("b2.tmp")).unwrap();
|
||||
assert_ne!(b2_context.as_deref(), Some(new_a_context));
|
||||
|
||||
cmd.arg("--verbose")
|
||||
.arg(format!("--reference={}", dir.plus_as_string("a.tmp")))
|
||||
.arg(dir.plus("b1.tmp"))
|
||||
.arg(dir.plus("b2.tmp"))
|
||||
.succeeds();
|
||||
assert_eq!(
|
||||
get_file_context(dir.plus("b1.tmp")).unwrap().as_deref(),
|
||||
Some(new_a_context)
|
||||
);
|
||||
assert_eq!(
|
||||
get_file_context(dir.plus("b2.tmp")).unwrap().as_deref(),
|
||||
Some(new_a_context)
|
||||
);
|
||||
}
|
||||
|
||||
fn get_file_context(path: impl AsRef<Path>) -> Result<Option<String>, selinux::errors::Error> {
|
||||
let path = path.as_ref();
|
||||
match selinux::SecurityContext::of_path(path, false, false) {
|
||||
|
|
Loading…
Reference in a new issue