id: add conditional compilation for selinux

This commit is contained in:
Jan Scheer 2021-07-12 17:33:24 +02:00
parent 92bc647ac3
commit 7abc6a665e
No known key found for this signature in database
GPG key ID: C62AD4C29E2B9828
6 changed files with 50 additions and 20 deletions

View file

@ -13,8 +13,8 @@ env:
PROJECT_NAME: coreutils
PROJECT_DESC: "Core universal (cross-platform) utilities"
PROJECT_AUTH: "uutils"
RUST_MIN_SRV: "1.51.0" ## v1.51.0
RUST_COV_SRV: "1.51.0" ## supported rust version for code coverage; (date required/used by 'coverage') ## !maint: refactor when code coverage support is included in the stable channel
RUST_MIN_SRV: "1.51.0" ## MSRV v1.51.0
RUST_COV_SRV: "2020-07-01" ## (~v1.47.0) supported rust version for code coverage; (date required/used by 'coverage') ## !maint: refactor when code coverage support is included in the stable channel
on: [push, pull_request]
@ -249,6 +249,8 @@ jobs:
# { os, target, cargo-options, features, use-cross, toolchain }
- { os: ubuntu-latest , target: arm-unknown-linux-gnueabihf , features: feat_os_unix_gnueabihf , use-cross: use-cross }
- { os: ubuntu-latest , target: aarch64-unknown-linux-gnu , features: feat_os_unix_gnueabihf , use-cross: use-cross }
- { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross }
# - { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , features: feat_selinux , use-cross: use-cross }
# - { os: ubuntu-18.04 , target: i586-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross } ## note: older windows platform; not required, dev-FYI only
# - { os: ubuntu-18.04 , target: i586-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross } ## note: older windows platform; not required, dev-FYI only
- { os: ubuntu-18.04 , target: i686-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross }
@ -272,7 +274,9 @@ jobs:
esac
case '${{ matrix.job.os }}' in
macos-latest) brew install coreutils ;; # needed for testing
ubuntu-latest) sudo apt-get -y update ; sudo apt-get -y install libselinux1 libselinux1-dev ;; # TODO: probably redundant here
esac
case '${{ matrix.job.features }}' in
feat_selinux) sudo apt-get -y update ; sudo apt-get -y install libselinux1-dev ;; # TODO: is here the right place for this?
esac
- name: Initialize workflow variables
id: vars

View file

@ -146,6 +146,7 @@ feat_os_unix_musl = [
feat_require_crate_cpp = [
"stdbuf",
]
feat_selinux = ["id/selinux", "selinux"]
# "feat_require_unix" == set of utilities requiring support which is only available on unix platforms (as of 2020-04-23)
feat_require_unix = [
"chgrp",
@ -229,6 +230,7 @@ clap = { version = "2.33", features = ["wrap_help"] }
lazy_static = { version="1.3" }
textwrap = { version="=0.11.0", features=["term_size"] } # !maint: [2020-05-10; rivy] unstable crate using undocumented features; pinned currently, will review
uucore = { version=">=0.0.9", package="uucore", path="src/uucore" }
selinux = { version="0.1.1", optional = true }
# * uutils
uu_test = { optional=true, version="0.0.7", package="uu_test", path="src/uu/test" }
#
@ -353,7 +355,6 @@ unindent = "0.1"
uucore = { version=">=0.0.9", package="uucore", path="src/uucore", features=["entries", "process"] }
walkdir = "2.2"
atty = "0.2"
selinux = "0.1.1"
[target.'cfg(unix)'.dev-dependencies]
rlimit = "0.4.0"

View file

@ -28,8 +28,8 @@ pub fn main() {
if val == "1" && key.starts_with(env_feature_prefix) {
let krate = key[env_feature_prefix.len()..].to_lowercase();
match krate.as_ref() {
"default" | "macos" | "unix" | "windows" => continue, // common/standard feature names
"nightly" | "test_unimplemented" => continue, // crate-local custom features
"default" | "macos" | "unix" | "windows" | "selinux" => continue, // common/standard feature names
"nightly" | "test_unimplemented" => continue, // crate-local custom features
"test" => continue, // over-ridden with 'uu_test' to avoid collision with rust core crate 'test'
s if s.starts_with(feature_prefix) => continue, // crate feature sets
_ => {} // util feature name

View file

@ -18,8 +18,11 @@ path = "src/id.rs"
clap = { version = "2.33", features = ["wrap_help"] }
uucore = { version=">=0.0.9", package="uucore", path="../../uucore", features=["entries", "process"] }
uucore_procs = { version=">=0.0.6", package="uucore_procs", path="../../uucore_procs" }
selinux = "0.1.1"
selinux = { version="0.1.1", optional = true }
[[bin]]
name = "id"
path = "src/main.rs"
[features]
feat_selinux = ["selinux"]

View file

@ -35,8 +35,8 @@
extern crate uucore;
use clap::{crate_version, App, Arg};
#[cfg(target_os = "linux")]
use selinux::{self, KernelSupport, SecurityContext};
#[cfg(all(target_os = "linux", feature = "selinux"))]
use selinux;
use std::ffi::CStr;
use uucore::entries::{self, Group, Locate, Passwd};
pub use uucore::libc;
@ -52,6 +52,11 @@ macro_rules! cstr2cow {
static ABOUT: &str = "Print user and group information for each specified USER,
or (when USER omitted) for the current user.";
#[cfg(not(feature = "selinux"))]
static CONTEXT_HELP_TEXT: &str = "print only the security context of the process (not enabled)";
#[cfg(feature = "selinux")]
static CONTEXT_HELP_TEXT: &str = "print only the security context of the process";
mod options {
pub const OPT_AUDIT: &str = "audit"; // GNU's id does not have this
pub const OPT_CONTEXT: &str = "context";
@ -138,10 +143,16 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
zflag: matches.is_present(options::OPT_ZERO),
cflag: matches.is_present(options::OPT_CONTEXT),
#[cfg(not(target_os = "linux"))]
selinux_supported: false,
#[cfg(target_os = "linux")]
selinux_supported: selinux::kernel_support() != KernelSupport::Unsupported,
selinux_supported: {
#[cfg(feature = "selinux")]
{
selinux::kernel_support() != selinux::KernelSupport::Unsupported
}
#[cfg(not(feature = "selinux"))]
{
false
}
},
user_specified: !users.is_empty(),
ids: None,
};
@ -181,8 +192,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
if state.cflag {
if state.selinux_supported {
// print SElinux context and exit
#[cfg(target_os = "linux")]
if let Ok(context) = SecurityContext::current(false) {
#[cfg(all(target_os = "linux", feature = "selinux"))]
if let Ok(context) = selinux::SecurityContext::current(false) {
let bytes = context.as_bytes();
print!("{}{}", String::from_utf8_lossy(bytes), line_ending);
} else {
@ -412,7 +423,7 @@ pub fn uu_app() -> App<'static, 'static> {
.short("Z")
.long(options::OPT_CONTEXT)
.conflicts_with_all(&[options::OPT_GROUP, options::OPT_EFFECTIVE_USER])
.help("print only the security context of the process"),
.help(CONTEXT_HELP_TEXT),
)
.arg(
Arg::with_name(options::ARG_USERS)
@ -555,13 +566,13 @@ fn id_print(state: &State, groups: Vec<u32>) {
.join(",")
);
#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", feature = "selinux"))]
if state.selinux_supported
&& !state.user_specified
&& std::env::var_os("POSIXLY_CORRECT").is_none()
{
// print SElinux context (does not depend on "-Z")
if let Ok(context) = SecurityContext::current(false) {
if let Ok(context) = selinux::SecurityContext::current(false) {
let bytes = context.as_bytes();
print!(" context={}", String::from_utf8_lossy(bytes));
}

View file

@ -17,6 +17,17 @@ fn test_id_no_specified_user() {
let exp_result = unwrap_or_return!(expected_result(&ts, &[]));
let mut _exp_stdout = exp_result.stdout_str().to_string();
#[cfg(not(feature = "feat_selinux"))]
{
// NOTE: strip 'context' part from exp_stdout if selinux not enabled:
// example:
// uid=1001(runner) gid=121(docker) groups=121(docker),4(adm),101(systemd-journal) \
// context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
if let Some(context_offset) = exp_result.stdout_str().find(" context=") {
_exp_stdout.replace_range(context_offset.._exp_stdout.len() - 1, "");
}
}
result
.stdout_is(_exp_stdout)
.stderr_is(exp_result.stderr_str())
@ -354,7 +365,7 @@ fn test_id_zero() {
}
#[test]
#[cfg(target_os = "linux")]
#[cfg(feature = "feat_selinux")]
fn test_id_context() {
use selinux::{self, KernelSupport};
if selinux::kernel_support() == KernelSupport::Unsupported {
@ -423,7 +434,7 @@ fn test_id_no_specified_user_posixly() {
let result = ts.ucmd().env("POSIXLY_CORRECT", "1").succeeds();
assert!(!result.stdout_str().contains("context="));
#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", feature = "feat_selinux"))]
{
use selinux::{self, KernelSupport};
if selinux::kernel_support() == KernelSupport::Unsupported {