mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 20:17:45 +00:00
Merge pull request #2438 from jhscheer/id_selinux_context
id: add support for showing SELinux context (--context/-Z)
This commit is contained in:
commit
b877486265
8 changed files with 425 additions and 34 deletions
4
.github/workflows/CICD.yml
vendored
4
.github/workflows/CICD.yml
vendored
|
@ -13,7 +13,7 @@ env:
|
|||
PROJECT_NAME: coreutils
|
||||
PROJECT_DESC: "Core universal (cross-platform) utilities"
|
||||
PROJECT_AUTH: "uutils"
|
||||
RUST_MIN_SRV: "1.43.1" ## v1.43.0
|
||||
RUST_MIN_SRV: "1.47.0" ## MSRV v1.47.0
|
||||
RUST_COV_SRV: "2021-05-06" ## (~v1.52.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 }
|
||||
|
|
198
Cargo.lock
generated
198
Cargo.lock
generated
|
@ -73,6 +73,29 @@ dependencies = [
|
|||
"compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.59.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453c49e5950bb0eb63bb3df640e31618846c89d5b7faa54040d76e98e0134375"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"clap",
|
||||
"env_logger 0.8.4",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"peeking_take_while",
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.2"
|
||||
|
@ -94,6 +117,18 @@ version = "1.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "0.19.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"tap",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blake2b_simd"
|
||||
version = "0.5.11"
|
||||
|
@ -144,6 +179,15 @@ version = "1.0.68"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db507a7679252d2276ed0dd8113c6875ec56d3089f9225b2b42c30cc1f8e5c89"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
|
@ -169,6 +213,17 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c"
|
||||
dependencies = [
|
||||
"glob 0.3.0",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
|
@ -232,6 +287,7 @@ dependencies = [
|
|||
"rand 0.7.3",
|
||||
"regex",
|
||||
"rlimit",
|
||||
"selinux",
|
||||
"sha1",
|
||||
"tempfile",
|
||||
"textwrap",
|
||||
|
@ -582,6 +638,19 @@ dependencies = [
|
|||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
|
@ -624,6 +693,12 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.8.4"
|
||||
|
@ -731,6 +806,12 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "if_rust_version"
|
||||
version = "1.0.0"
|
||||
|
@ -786,12 +867,28 @@ version = "1.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "locale"
|
||||
version = "0.2.2"
|
||||
|
@ -923,6 +1020,18 @@ version = "0.1.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "6.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"funty",
|
||||
"memchr 2.4.0",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.6"
|
||||
|
@ -1088,6 +1197,12 @@ dependencies = [
|
|||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.19"
|
||||
|
@ -1179,7 +1294,7 @@ version = "0.9.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"env_logger 0.7.1",
|
||||
"log",
|
||||
"rand 0.7.3",
|
||||
"rand_core 0.5.1",
|
||||
|
@ -1200,6 +1315,12 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "radium"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.5.6"
|
||||
|
@ -1368,6 +1489,12 @@ dependencies = [
|
|||
"redox_syscall 0.2.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reference-counted-singleton"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e03aec30be874d0786379a6ee483c653c58dd6863ad4ed873e697ed968f9358"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
|
@ -1422,6 +1549,12 @@ version = "0.13.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
|
@ -1437,6 +1570,32 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "selinux"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd525eeb189eb26c8471463186bba87644e3d8a9c7ae392adaf9ec45ede574bc"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"reference-counted-singleton",
|
||||
"selinux-sys",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "selinux-sys"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d842d177120716580c4c6cb56dfe3c5f3a3e3dcec635091f1b2034b6c0be4c6"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"cc",
|
||||
"dunce",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.6.0"
|
||||
|
@ -1468,6 +1627,12 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.9"
|
||||
|
@ -1565,6 +1730,12 @@ dependencies = [
|
|||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.2.0"
|
||||
|
@ -1598,6 +1769,15 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termion"
|
||||
version = "1.5.6"
|
||||
|
@ -2075,6 +2255,7 @@ name = "uu_id"
|
|||
version = "0.0.7"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"selinux",
|
||||
"uucore",
|
||||
"uucore_procs",
|
||||
]
|
||||
|
@ -2837,6 +3018,15 @@ version = "0.10.2+wasi-snapshot-preview1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "3.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wild"
|
||||
version = "2.0.4"
|
||||
|
@ -2889,6 +3079,12 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "0.2.2"
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# coreutils (uutils)
|
||||
# * see the repository LICENSE, README, and CONTRIBUTING files for more information
|
||||
|
||||
# spell-checker:ignore (libs) libselinux
|
||||
|
||||
[package]
|
||||
name = "coreutils"
|
||||
version = "0.0.7"
|
||||
|
@ -138,6 +140,11 @@ feat_os_unix_musl = [
|
|||
#
|
||||
"feat_require_unix",
|
||||
]
|
||||
# "feat_selinux" == set of utilities providing support for SELinux Security Context if enabled with `--features feat_selinux`.
|
||||
# NOTE:
|
||||
# The selinux(-sys) crate requires `libselinux` headers and shared library to be accessible in the C toolchain at compile time.
|
||||
# Running a uutils compiled with `feat_selinux` requires an SELinux enabled Kernel at run time.
|
||||
feat_selinux = ["id/selinux", "selinux"]
|
||||
## feature sets with requirements (restricting cross-platform availability)
|
||||
#
|
||||
# ** NOTE: these `feat_require_...` sets should be minimized as much as possible to encourage cross-platform availability of utilities
|
||||
|
@ -229,6 +236,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.3", optional = true }
|
||||
# * uutils
|
||||
uu_test = { optional=true, version="0.0.7", package="uu_test", path="src/uu/test" }
|
||||
#
|
||||
|
|
4
build.rs
4
build.rs
|
@ -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
|
||||
|
|
|
@ -1 +1 @@
|
|||
msrv = "1.43.1"
|
||||
msrv = "1.47.0"
|
||||
|
|
|
@ -18,7 +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 = { version="0.1.3", optional = true }
|
||||
|
||||
[[bin]]
|
||||
name = "id"
|
||||
path = "src/main.rs"
|
||||
|
||||
[features]
|
||||
feat_selinux = ["selinux"]
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
//
|
||||
|
||||
// spell-checker:ignore (ToDO) asid auditid auditinfo auid cstr egid emod euid getaudit getlogin gflag nflag pline rflag termid uflag gsflag zflag cflag
|
||||
|
||||
// README:
|
||||
// This was originally based on BSD's `id`
|
||||
// (noticeable in functionality, usage text, options text, etc.)
|
||||
// and synced with:
|
||||
|
@ -25,8 +28,10 @@
|
|||
//
|
||||
// * Help text based on BSD's `id` manpage and GNU's `id` manpage.
|
||||
//
|
||||
|
||||
// spell-checker:ignore (ToDO) asid auditid auditinfo auid cstr egid emod euid getaudit getlogin gflag nflag pline rflag termid uflag gsflag zflag
|
||||
// * This passes GNU's coreutils Test suite (8.32) for "tests/id/context.sh" if compiled with
|
||||
// `--features feat_selinux`. It should also pass "tests/id/no-context.sh", but that depends on
|
||||
// `uu_ls -Z` being implemented and therefore fails at the moment
|
||||
//
|
||||
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(dead_code)]
|
||||
|
@ -35,6 +40,8 @@
|
|||
extern crate uucore;
|
||||
|
||||
use clap::{crate_version, App, Arg};
|
||||
#[cfg(all(target_os = "linux", feature = "selinux"))]
|
||||
use selinux;
|
||||
use std::ffi::CStr;
|
||||
use uucore::entries::{self, Group, Locate, Passwd};
|
||||
pub use uucore::libc;
|
||||
|
@ -50,6 +57,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";
|
||||
|
@ -93,6 +105,8 @@ struct State {
|
|||
gsflag: bool, // --groups
|
||||
rflag: bool, // --real
|
||||
zflag: bool, // --zero
|
||||
cflag: bool, // --context
|
||||
selinux_supported: bool,
|
||||
ids: Option<Ids>,
|
||||
// The behavior for calling GNU's `id` and calling GNU's `id $USER` is similar but different.
|
||||
// * The SELinux context is only displayed without a specified user.
|
||||
|
@ -109,6 +123,7 @@ struct State {
|
|||
// 1000 10 968 975
|
||||
// +++ exited with 0 +++
|
||||
user_specified: bool,
|
||||
exit_code: i32,
|
||||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
|
@ -132,8 +147,21 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
gsflag: matches.is_present(options::OPT_GROUPS),
|
||||
rflag: matches.is_present(options::OPT_REAL_ID),
|
||||
zflag: matches.is_present(options::OPT_ZERO),
|
||||
cflag: matches.is_present(options::OPT_CONTEXT),
|
||||
|
||||
selinux_supported: {
|
||||
#[cfg(feature = "selinux")]
|
||||
{
|
||||
selinux::kernel_support() != selinux::KernelSupport::Unsupported
|
||||
}
|
||||
#[cfg(not(feature = "selinux"))]
|
||||
{
|
||||
false
|
||||
}
|
||||
},
|
||||
user_specified: !users.is_empty(),
|
||||
ids: None,
|
||||
exit_code: 0,
|
||||
};
|
||||
|
||||
let default_format = {
|
||||
|
@ -141,13 +169,16 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
!(state.uflag || state.gflag || state.gsflag)
|
||||
};
|
||||
|
||||
if (state.nflag || state.rflag) && default_format {
|
||||
if (state.nflag || state.rflag) && default_format && !state.cflag {
|
||||
crash!(1, "cannot print only names or real IDs in default format");
|
||||
}
|
||||
if (state.zflag) && default_format {
|
||||
if state.zflag && default_format && !state.cflag {
|
||||
// NOTE: GNU test suite "id/zero.sh" needs this stderr output:
|
||||
crash!(1, "option --zero not permitted in default format");
|
||||
}
|
||||
if state.user_specified && state.cflag {
|
||||
crash!(1, "cannot print security context when user specified");
|
||||
}
|
||||
|
||||
let delimiter = {
|
||||
if state.zflag {
|
||||
|
@ -163,7 +194,23 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
'\n'
|
||||
}
|
||||
};
|
||||
let mut exit_code = 0;
|
||||
|
||||
if state.cflag {
|
||||
if state.selinux_supported {
|
||||
// print SElinux context and exit
|
||||
#[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 {
|
||||
// print error because `cflag` was explicitly requested
|
||||
crash!(1, "can't get process context");
|
||||
}
|
||||
return state.exit_code;
|
||||
} else {
|
||||
crash!(1, "--context (-Z) works only on an SELinux-enabled kernel");
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0..=users.len() {
|
||||
let possible_pw = if !state.user_specified {
|
||||
|
@ -173,7 +220,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
Ok(p) => Some(p),
|
||||
Err(_) => {
|
||||
show_error!("'{}': no such user", users[i]);
|
||||
exit_code = 1;
|
||||
state.exit_code = 1;
|
||||
if i + 1 >= users.len() {
|
||||
break;
|
||||
} else {
|
||||
|
@ -187,17 +234,17 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
if matches.is_present(options::OPT_PASSWORD) {
|
||||
// BSD's `id` ignores all but the first specified user
|
||||
pline(possible_pw.map(|v| v.uid()));
|
||||
return exit_code;
|
||||
return state.exit_code;
|
||||
};
|
||||
if matches.is_present(options::OPT_HUMAN_READABLE) {
|
||||
// BSD's `id` ignores all but the first specified user
|
||||
pretty(possible_pw);
|
||||
return exit_code;
|
||||
return state.exit_code;
|
||||
}
|
||||
if matches.is_present(options::OPT_AUDIT) {
|
||||
// BSD's `id` ignores specified users
|
||||
auditid();
|
||||
return exit_code;
|
||||
return state.exit_code;
|
||||
}
|
||||
|
||||
let (uid, gid) = possible_pw.map(|p| (p.uid(), p.gid())).unwrap_or((
|
||||
|
@ -217,7 +264,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
if state.nflag {
|
||||
entries::gid2grp(gid).unwrap_or_else(|_| {
|
||||
show_error!("cannot find name for group ID {}", gid);
|
||||
exit_code = 1;
|
||||
state.exit_code = 1;
|
||||
gid.to_string()
|
||||
})
|
||||
} else {
|
||||
|
@ -232,7 +279,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
if state.nflag {
|
||||
entries::uid2usr(uid).unwrap_or_else(|_| {
|
||||
show_error!("cannot find name for user ID {}", uid);
|
||||
exit_code = 1;
|
||||
state.exit_code = 1;
|
||||
uid.to_string()
|
||||
})
|
||||
} else {
|
||||
|
@ -257,7 +304,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
if state.nflag {
|
||||
entries::gid2grp(id).unwrap_or_else(|_| {
|
||||
show_error!("cannot find name for group ID {}", id);
|
||||
exit_code = 1;
|
||||
state.exit_code = 1;
|
||||
id.to_string()
|
||||
})
|
||||
} else {
|
||||
|
@ -276,7 +323,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
|
||||
if default_format {
|
||||
id_print(&state, groups);
|
||||
id_print(&mut state, groups);
|
||||
}
|
||||
print!("{}", line_ending);
|
||||
|
||||
|
@ -285,7 +332,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
exit_code
|
||||
state.exit_code
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
|
@ -319,6 +366,7 @@ pub fn uu_app() -> App<'static, 'static> {
|
|||
Arg::with_name(options::OPT_GROUP)
|
||||
.short("g")
|
||||
.long(options::OPT_GROUP)
|
||||
.conflicts_with(options::OPT_EFFECTIVE_USER)
|
||||
.help("Display only the effective group ID as a number"),
|
||||
)
|
||||
.arg(
|
||||
|
@ -328,6 +376,7 @@ pub fn uu_app() -> App<'static, 'static> {
|
|||
.conflicts_with_all(&[
|
||||
options::OPT_GROUP,
|
||||
options::OPT_EFFECTIVE_USER,
|
||||
options::OPT_CONTEXT,
|
||||
options::OPT_HUMAN_READABLE,
|
||||
options::OPT_PASSWORD,
|
||||
options::OPT_AUDIT,
|
||||
|
@ -379,7 +428,8 @@ pub fn uu_app() -> App<'static, 'static> {
|
|||
Arg::with_name(options::OPT_CONTEXT)
|
||||
.short("Z")
|
||||
.long(options::OPT_CONTEXT)
|
||||
.help("NotImplemented: print only the security context of the process"),
|
||||
.conflicts_with_all(&[options::OPT_GROUP, options::OPT_EFFECTIVE_USER])
|
||||
.help(CONTEXT_HELP_TEXT),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ARG_USERS)
|
||||
|
@ -499,34 +549,80 @@ fn auditid() {
|
|||
println!("asid={}", auditinfo.ai_asid);
|
||||
}
|
||||
|
||||
fn id_print(state: &State, groups: Vec<u32>) {
|
||||
fn id_print(state: &mut State, groups: Vec<u32>) {
|
||||
let uid = state.ids.as_ref().unwrap().uid;
|
||||
let gid = state.ids.as_ref().unwrap().gid;
|
||||
let euid = state.ids.as_ref().unwrap().euid;
|
||||
let egid = state.ids.as_ref().unwrap().egid;
|
||||
|
||||
print!("uid={}({})", uid, entries::uid2usr(uid).unwrap());
|
||||
print!(" gid={}({})", gid, entries::gid2grp(gid).unwrap());
|
||||
print!(
|
||||
"uid={}({})",
|
||||
uid,
|
||||
entries::uid2usr(uid).unwrap_or_else(|_| {
|
||||
show_error!("cannot find name for user ID {}", uid);
|
||||
state.exit_code = 1;
|
||||
uid.to_string()
|
||||
})
|
||||
);
|
||||
print!(
|
||||
" gid={}({})",
|
||||
gid,
|
||||
entries::gid2grp(gid).unwrap_or_else(|_| {
|
||||
show_error!("cannot find name for group ID {}", gid);
|
||||
state.exit_code = 1;
|
||||
gid.to_string()
|
||||
})
|
||||
);
|
||||
if !state.user_specified && (euid != uid) {
|
||||
print!(" euid={}({})", euid, entries::uid2usr(euid).unwrap());
|
||||
print!(
|
||||
" euid={}({})",
|
||||
euid,
|
||||
entries::uid2usr(euid).unwrap_or_else(|_| {
|
||||
show_error!("cannot find name for user ID {}", euid);
|
||||
state.exit_code = 1;
|
||||
euid.to_string()
|
||||
})
|
||||
);
|
||||
}
|
||||
if !state.user_specified && (egid != gid) {
|
||||
print!(" egid={}({})", euid, entries::gid2grp(egid).unwrap());
|
||||
print!(
|
||||
" egid={}({})",
|
||||
euid,
|
||||
entries::gid2grp(egid).unwrap_or_else(|_| {
|
||||
show_error!("cannot find name for group ID {}", egid);
|
||||
state.exit_code = 1;
|
||||
egid.to_string()
|
||||
})
|
||||
);
|
||||
}
|
||||
print!(
|
||||
" groups={}",
|
||||
groups
|
||||
.iter()
|
||||
.map(|&gr| format!("{}({})", gr, entries::gid2grp(gr).unwrap()))
|
||||
.map(|&gr| format!(
|
||||
"{}({})",
|
||||
gr,
|
||||
entries::gid2grp(gr).unwrap_or_else(|_| {
|
||||
show_error!("cannot find name for group ID {}", gr);
|
||||
state.exit_code = 1;
|
||||
gr.to_string()
|
||||
})
|
||||
))
|
||||
.collect::<Vec<_>>()
|
||||
.join(",")
|
||||
);
|
||||
|
||||
// NOTE: (SELinux NotImplemented) placeholder:
|
||||
// if !state.user_specified {
|
||||
// // print SElinux context (does not depend on "-Z")
|
||||
// print!(" context={}", get_selinux_contexts().join(":"));
|
||||
// }
|
||||
#[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) = selinux::SecurityContext::current(false) {
|
||||
let bytes = context.as_bytes();
|
||||
print!(" context={}", String::from_utf8_lossy(bytes));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
|
|
|
@ -17,9 +17,9 @@ 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(target_os = "linux")]
|
||||
#[cfg(not(feature = "feat_selinux"))]
|
||||
{
|
||||
// NOTE: (SELinux NotImplemented) strip 'context' part from exp_stdout:
|
||||
// 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
|
||||
|
@ -363,3 +363,88 @@ fn test_id_zero() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
fn test_id_context() {
|
||||
use selinux::{self, KernelSupport};
|
||||
if selinux::kernel_support() == KernelSupport::Unsupported {
|
||||
println!("test skipped: Kernel has no support for SElinux context",);
|
||||
return;
|
||||
}
|
||||
let ts = TestScenario::new(util_name!());
|
||||
for c_flag in &["-Z", "--context"] {
|
||||
ts.ucmd()
|
||||
.args(&[c_flag])
|
||||
.succeeds()
|
||||
.stdout_only(unwrap_or_return!(expected_result(&ts, &[c_flag])).stdout_str());
|
||||
for &z_flag in &["-z", "--zero"] {
|
||||
let args = [c_flag, z_flag];
|
||||
ts.ucmd()
|
||||
.args(&args)
|
||||
.succeeds()
|
||||
.stdout_only(unwrap_or_return!(expected_result(&ts, &args)).stdout_str());
|
||||
for &opt1 in &["--name", "--real"] {
|
||||
// id: cannot print only names or real IDs in default format
|
||||
let args = [opt1, c_flag];
|
||||
ts.ucmd()
|
||||
.args(&args)
|
||||
.succeeds()
|
||||
.stdout_only(unwrap_or_return!(expected_result(&ts, &args)).stdout_str());
|
||||
let args = [opt1, c_flag, z_flag];
|
||||
ts.ucmd()
|
||||
.args(&args)
|
||||
.succeeds()
|
||||
.stdout_only(unwrap_or_return!(expected_result(&ts, &args)).stdout_str());
|
||||
for &opt2 in &["--user", "--group", "--groups"] {
|
||||
// u/g/G n/r z Z
|
||||
// for now, we print clap's standard response for "conflicts_with" instead of:
|
||||
// id: cannot print "only" of more than one choice
|
||||
let args = [opt2, c_flag, opt1];
|
||||
let _result = ts.ucmd().args(&args).fails();
|
||||
// let exp_result = unwrap_or_return!(expected_result(&args));
|
||||
// result
|
||||
// .stdout_is(exp_result.stdout_str())
|
||||
// .stderr_is(exp_result.stderr_str())
|
||||
// .code_is(exp_result.code());
|
||||
}
|
||||
}
|
||||
for &opt2 in &["--user", "--group", "--groups"] {
|
||||
// u/g/G z Z
|
||||
// for now, we print clap's standard response for "conflicts_with" instead of:
|
||||
// id: cannot print "only" of more than one choice
|
||||
let args = [opt2, c_flag];
|
||||
let _result = ts.ucmd().args(&args).fails();
|
||||
// let exp_result = unwrap_or_return!(expected_result(&args));
|
||||
// result
|
||||
// .stdout_is(exp_result.stdout_str())
|
||||
// .stderr_is(exp_result.stderr_str())
|
||||
// .code_is(exp_result.code());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_id_no_specified_user_posixly() {
|
||||
// gnu/tests/id/no-context.sh
|
||||
|
||||
let ts = TestScenario::new(util_name!());
|
||||
let result = ts.ucmd().env("POSIXLY_CORRECT", "1").run();
|
||||
assert!(!result.stdout_str().contains("context="));
|
||||
if !is_ci() {
|
||||
result.success();
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "linux", feature = "feat_selinux"))]
|
||||
{
|
||||
use selinux::{self, KernelSupport};
|
||||
if selinux::kernel_support() == KernelSupport::Unsupported {
|
||||
println!("test skipped: Kernel has no support for SElinux context",);
|
||||
} else {
|
||||
let result = ts.ucmd().succeeds();
|
||||
assert!(result.stdout_str().contains("context="));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue