Skip to content

Commit d1808f0

Browse files
committed
Add SMACK support to id, mkdir, mkfifo, mknod utilities
1 parent b3d05b6 commit d1808f0

File tree

14 files changed

+154
-34
lines changed

14 files changed

+154
-34
lines changed

Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,13 @@ feat_selinux = [
6868
# "feat_smack" == enable support for SMACK Security Context (by using `--features feat_smack`)
6969
# NOTE:
7070
# * Running a uutils compiled with `feat_smack` requires a SMACK enabled Kernel at run time.
71-
feat_smack = ["ls/smack"]
71+
feat_smack = [
72+
"id/smack",
73+
"ls/smack",
74+
"mkdir/smack",
75+
"mkfifo/smack",
76+
"mknod/smack",
77+
]
7278
##
7379
## feature sets
7480
## (common/core and Tier1) feature sets

src/uu/id/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ path = "src/main.rs"
2929

3030
[features]
3131
feat_selinux = ["selinux"]
32+
smack = ["uucore/smack"]

src/uu/id/src/id.rs

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ macro_rules! cstr2cow {
6262
}
6363

6464
fn get_context_help_text() -> String {
65-
#[cfg(not(feature = "selinux"))]
65+
#[cfg(not(any(feature = "selinux", feature = "smack")))]
6666
return translate!("id-context-help-disabled");
67-
#[cfg(feature = "selinux")]
67+
#[cfg(any(feature = "selinux", feature = "smack"))]
6868
return translate!("id-context-help-enabled");
6969
}
7070

@@ -98,7 +98,10 @@ struct State {
9898
rflag: bool, // --real
9999
zflag: bool, // --zero
100100
cflag: bool, // --context
101+
#[cfg(feature = "selinux")]
101102
selinux_supported: bool,
103+
#[cfg(feature = "smack")]
104+
smack_supported: bool,
102105
ids: Option<Ids>,
103106
// The behavior for calling GNU's `id` and calling GNU's `id $USER` is similar but different.
104107
// * The SELinux context is only displayed without a specified user.
@@ -136,16 +139,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
136139
zflag: matches.get_flag(options::OPT_ZERO),
137140
cflag: matches.get_flag(options::OPT_CONTEXT),
138141

139-
selinux_supported: {
140-
#[cfg(feature = "selinux")]
141-
{
142-
uucore::selinux::is_selinux_enabled()
143-
}
144-
#[cfg(not(feature = "selinux"))]
145-
{
146-
false
147-
}
148-
},
142+
#[cfg(feature = "selinux")]
143+
selinux_supported: uucore::selinux::is_selinux_enabled(),
144+
#[cfg(feature = "smack")]
145+
smack_supported: uucore::smack::is_smack_enabled(),
149146
user_specified: !users.is_empty(),
150147
ids: None,
151148
};
@@ -179,26 +176,43 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
179176
let line_ending = LineEnding::from_zero_flag(state.zflag);
180177

181178
if state.cflag {
182-
return if state.selinux_supported {
183-
// print SElinux context and exit
184-
#[cfg(all(any(target_os = "linux", target_os = "android"), feature = "selinux"))]
179+
// SELinux context
180+
#[cfg(feature = "selinux")]
181+
if state.selinux_supported {
185182
if let Ok(context) = selinux::SecurityContext::current(false) {
186183
let bytes = context.as_bytes();
187184
print!("{}{line_ending}", String::from_utf8_lossy(bytes));
185+
return Ok(());
188186
} else {
189-
// print error because `cflag` was explicitly requested
190187
return Err(USimpleError::new(
191188
1,
192189
translate!("id-error-cannot-get-context"),
193190
));
194191
}
195-
Ok(())
196-
} else {
197-
Err(USimpleError::new(
198-
1,
199-
translate!("id-error-context-selinux-only"),
200-
))
201-
};
192+
}
193+
194+
// SMACK label
195+
#[cfg(feature = "smack")]
196+
if state.smack_supported {
197+
match uucore::smack::get_smack_label_for_self() {
198+
Ok(label) => {
199+
print!("{label}{line_ending}");
200+
return Ok(());
201+
}
202+
Err(_) => {
203+
return Err(USimpleError::new(
204+
1,
205+
translate!("id-error-cannot-get-context"),
206+
));
207+
}
208+
}
209+
}
210+
211+
// Neither SELinux nor SMACK supported
212+
return Err(USimpleError::new(
213+
1,
214+
translate!("id-error-context-selinux-only"),
215+
));
202216
}
203217

204218
for i in 0..=users.len() {
@@ -666,7 +680,7 @@ fn id_print(state: &State, groups: &[u32]) {
666680
.join(",")
667681
);
668682

669-
#[cfg(all(any(target_os = "linux", target_os = "android"), feature = "selinux"))]
683+
#[cfg(feature = "selinux")]
670684
if state.selinux_supported
671685
&& !state.user_specified
672686
&& std::env::var_os("POSIXLY_CORRECT").is_none()
@@ -677,6 +691,17 @@ fn id_print(state: &State, groups: &[u32]) {
677691
print!(" context={}", String::from_utf8_lossy(bytes));
678692
}
679693
}
694+
695+
#[cfg(feature = "smack")]
696+
if state.smack_supported
697+
&& !state.user_specified
698+
&& std::env::var_os("POSIXLY_CORRECT").is_none()
699+
{
700+
// print SMACK label (does not depend on "-Z")
701+
if let Ok(label) = uucore::smack::get_smack_label_for_self() {
702+
print!(" context={label}");
703+
}
704+
}
680705
}
681706

682707
#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "openbsd")))]

src/uu/mkdir/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ fluent = { workspace = true }
2424

2525
[features]
2626
selinux = ["uucore/selinux"]
27+
smack = ["uucore/smack"]
2728

2829
[[bin]]
2930
name = "mkdir"

src/uu/mkdir/locales/en-US.ftl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ mkdir-error-empty-directory-name = cannot create directory '': No such file or d
1414
mkdir-error-file-exists = { $path }: File exists
1515
mkdir-error-failed-to-create-tree = failed to create whole tree
1616
mkdir-error-cannot-set-permissions = cannot set permissions { $path }
17+
mkdir-error-smack-context = failed to set default file creation context to '{ $context }':
1718
1819
# Verbose output
1920
mkdir-verbose-created-directory = { $util_name }: created directory { $path }

src/uu/mkdir/src/mkdir.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,19 @@ fn create_single_dir(path: &Path, is_parent: bool, config: &Config) -> UResult<(
300300
}
301301
}
302302

303+
// Apply SMACK context if requested
304+
#[cfg(feature = "smack")]
305+
if config.set_selinux_context && uucore::smack::is_smack_enabled() {
306+
if let Some(ctx) = config.context {
307+
if let Err(_e) = uucore::smack::set_smack_label_for_path(path, ctx) {
308+
let _ = std::fs::remove_dir(path);
309+
return Err(USimpleError::new(
310+
1,
311+
translate!("mkdir-error-smack-context", "context" => ctx.clone()),
312+
));
313+
}
314+
}
315+
}
303316
Ok(())
304317
}
305318

src/uu/mkfifo/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ fluent = { workspace = true }
2525

2626
[features]
2727
selinux = ["uucore/selinux"]
28+
smack = ["uucore/smack"]
2829

2930
[[bin]]
3031
name = "mkfifo"

src/uu/mkfifo/locales/en-US.ftl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ mkfifo-error-invalid-mode = invalid mode: { $error }
1111
mkfifo-error-missing-operand = missing operand
1212
mkfifo-error-cannot-create-fifo = cannot create fifo { $path }: File exists
1313
mkfifo-error-cannot-set-permissions = cannot set permissions on { $path }: { $error }
14+
mkfifo-error-smack-context = failed to set default file creation context to '{ $context }':

src/uu/mkfifo/src/mkfifo.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,26 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
7575
}
7676
}
7777
}
78+
79+
// Apply SMACK context if requested
80+
#[cfg(feature = "smack")]
81+
{
82+
let set_smack_context = matches.get_flag(options::SELINUX);
83+
let context = matches.get_one::<String>(options::CONTEXT);
84+
85+
if (set_smack_context || context.is_some()) && uucore::smack::is_smack_enabled() {
86+
if let Some(ctx) = context {
87+
use std::path::Path;
88+
if let Err(_e) = uucore::smack::set_smack_label_for_path(Path::new(&f), ctx) {
89+
let _ = fs::remove_file(&f);
90+
return Err(USimpleError::new(
91+
1,
92+
translate!("mkfifo-error-smack-context", "context" => ctx.clone()),
93+
));
94+
}
95+
}
96+
}
97+
}
7898
}
7999

80100
Ok(())

src/uu/mknod/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ fluent = { workspace = true }
2626

2727
[features]
2828
selinux = ["uucore/selinux"]
29+
smack = ["uucore/smack"]
2930

3031
[[bin]]
3132
name = "mknod"

0 commit comments

Comments
 (0)