capng
A safe, idiomatic Rust wrapper around libcap-ng for managing Linux POSIX capabilities.
Repository Health
Technical Analysis
capng is a lightweight Rust binding for libcap-ng, the Linux library for managing POSIX capabilities — the fine-grained privilege system that lets processes hold specific superuser powers (like binding to low ports or changing file ownership) without running as full root. It wraps libcap-ng’s C API in safe, typed Rust functions, replacing raw integer flags and unchecked return codes with bitflags-based types (Type, Set, Flags) and a dedicated Result-based error enum.
The crate links against the system libcap-ng library at build time and exposes functions to clear, fill, and apply capability sets, drop privileges after changing UID/GID, query which capabilities a process currently holds, and convert between capability names and their numeric IDs — everything needed to write privilege-dropping daemons and sandboxed system tools in Rust.
What You Get
- Safe Rust bindings for the full libcap-ng capability API (clear, fill, apply, lock, update).
- Typed bitflags enums (Type, Set, Flags) instead of raw C integer constants.
- A dedicated Error enum with descriptive messages for every libcap-ng failure mode.
- Helpers to save and restore capability state, and to convert between capability names and IDs.
Common Use Cases
- Dropping root privileges to a minimal capability set after a daemon binds a privileged port.
- Building sandboxed system utilities (container runtimes, VMMs) that need fine-grained privilege control.
- Auditing or printing a process’s current effective/permitted/bounding capabilities for diagnostics.
Under The Hood
Architecture capng consists of a single crate (src/lib.rs, src/bindings.rs) that separates unsafe FFI declarations from a safe public API. bindings.rs declares the extern “C” signatures for libcap-ng’s C functions (capng_clear, capng_update, capng_apply, capng_save_state, etc.) linked via #[link(name = “cap-ng”)]. lib.rs wraps every unsafe call in a safe function that checks return codes and converts negative or non-zero results into a typed Error enum, so callers never touch raw C ints or pointers directly; the one exception, CapngState, wraps an opaque *mut c_void from capng_save_state/capng_restore_state and is manually marked Send.
Tech Stack The crate targets Rust 2018 edition with only two dependencies — bitflags 1.0 for the Type/Set/Flags enums and libc 0.2.69 for freeing C-allocated buffers returned by capng_print_caps_*. There’s no bindgen step; bindings.rs is hand-written and committed. build.rs performs the system linking: it reads the LIBCAPNG_LIB_PATH env var to add a native search path and LIBCAPNG_LINK_TYPE (dylib or static, default dylib) to choose the link mode against the system’s libcap-ng shared library.
Code Quality Test coverage lives directly in lib.rs under #[cfg(test)] — four tests exercise clear/fill, printing, and single and batch capability updates using named capabilities like CHOWN, FOWNER, and KILL. Error handling is consistent throughout: every fallible libcap-ng call is checked against its C-defined failure sentinel and mapped to a specific Error variant with a human-readable Display message, rather than panicking or returning bare booleans. Naming mirrors the underlying libcap-ng C API closely (capng_update -> update, capng_have_capabilities -> have_capabilities), which keeps the wrapper predictable at the cost of some non-idiomatic Rust naming like ALL_CAPS enum variants (Action::DROP, Print::STDOUT).
API Design The public API is small and single-purpose: fewer than 20 functions covering the entire libcap-ng surface, each accepting bitflags types instead of raw integers and returning Result<T, Error> or Option instead of sentinel values. Getting started requires no builder pattern or configuration struct — call clear(Set::BOTH), update(…), and apply(Set::BOTH) directly. The tradeoff is minimal documentation: there are no doc comments on public functions and no usage examples beyond the test module, so using it correctly requires prior familiarity with libcap-ng’s own C API and the Linux capabilities model.