Install: implement -Z

Fixes: tests/install/install-Z-selinux
This commit is contained in:
Sylvestre Ledru
2025-10-21 23:27:06 +02:00
parent 0c3eb12ea4
commit 2434c2ae13
7 changed files with 459 additions and 20 deletions
Generated
+1
View File
@@ -3566,6 +3566,7 @@ dependencies = [
"file_diff",
"filetime",
"fluent",
"selinux",
"thiserror 2.0.17",
"uucore",
]
+2 -1
View File
@@ -21,6 +21,7 @@ path = "src/install.rs"
clap = { workspace = true }
filetime = { workspace = true }
file_diff = { workspace = true }
selinux = { workspace = true, optional = true }
thiserror = { workspace = true }
uucore = { workspace = true, default-features = true, features = [
"backup-control",
@@ -34,7 +35,7 @@ uucore = { workspace = true, default-features = true, features = [
fluent = { workspace = true }
[features]
selinux = ["uucore/selinux"]
selinux = ["dep:selinux", "uucore/selinux"]
[[bin]]
name = "install"
+1
View File
@@ -18,6 +18,7 @@ install-help-no-target-directory = treat DEST as a normal file
install-help-verbose = explain what is being done
install-help-preserve-context = preserve security context
install-help-context = set security context of files and directories
install-help-default-context = set SELinux security context of destination file and each created directory to default type
# Error messages
install-error-dir-needs-arg = { $util_name } with -d requires at least one argument.
+1
View File
@@ -18,6 +18,7 @@ install-help-no-target-directory = traiter DEST comme un fichier normal
install-help-verbose = expliquer ce qui est fait
install-help-preserve-context = préserver le contexte de sécurité
install-help-context = définir le contexte de sécurité des fichiers et répertoires
install-help-default-context = définir le contexte de sécurité SELinux du fichier de destination et de chaque répertoire créé au type par défaut
# Messages d'erreur
install-error-dir-needs-arg = { $util_name } avec -d nécessite au moins un argument.
File diff suppressed because it is too large Load Diff
+16 -8
View File
@@ -12,6 +12,8 @@ use crate::translate;
use selinux::SecurityContext;
use thiserror::Error;
use crate::error::UError;
#[derive(Debug, Error)]
pub enum SeLinuxError {
#[error("{}", translate!("selinux-error-not-enabled"))]
@@ -30,15 +32,21 @@ pub enum SeLinuxError {
ContextConversionFailure(String, String),
}
impl UError for SeLinuxError {
fn code(&self) -> i32 {
match self {
Self::SELinuxNotEnabled => 1,
Self::FileOpenFailure(_) => 2,
Self::ContextRetrievalFailure(_) => 3,
Self::ContextSetFailure(_, _) => 4,
Self::ContextConversionFailure(_, _) => 5,
}
}
}
impl From<SeLinuxError> for i32 {
fn from(error: SeLinuxError) -> Self {
match error {
SeLinuxError::SELinuxNotEnabled => 1,
SeLinuxError::FileOpenFailure(_) => 2,
SeLinuxError::ContextRetrievalFailure(_) => 3,
SeLinuxError::ContextSetFailure(_, _) => 4,
SeLinuxError::ContextConversionFailure(_, _) => 5,
}
error.code()
}
}
@@ -50,7 +58,7 @@ pub fn is_selinux_enabled() -> bool {
}
/// Returns a string describing the error and its causes.
fn selinux_error_description(mut error: &dyn Error) -> String {
pub fn selinux_error_description(mut error: &dyn Error) -> String {
let mut description = String::new();
while let Some(source) = error.source() {
let error_text = source.to_string();
+29
View File
@@ -2322,6 +2322,35 @@ fn test_selinux_invalid_args() {
}
}
#[test]
#[cfg(feature = "feat_selinux")]
fn test_selinux_default_context() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
let src = "orig";
at.touch(src);
let dest = "orig.2";
let result = new_ucmd!()
.arg("-Z")
.arg("-v")
.arg(at.plus_as_string(src))
.arg(at.plus_as_string(dest))
.run();
// Skip test if SELinux is not enabled
if result
.stderr_str()
.contains("SELinux is not enabled on this system")
{
println!("Skipping SELinux default context test: SELinux is not enabled");
return;
}
result.success().stdout_contains("orig' -> '");
assert!(at.file_exists(dest));
}
#[test]
#[cfg(not(any(target_os = "openbsd", target_os = "freebsd")))]
fn test_install_compare_with_mode_bits() {