#![recursion_limit="500"]
extern crate libc;
#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate custom_derive;
#[macro_use]
extern crate enum_derive;
mod errors;
pub use errors::*;
mod nr;
mod base;
mod ambient;
mod bounding;
#[derive(Debug,Clone,Copy)]
pub enum CapSet {
Ambient,
Bounding,
Effective,
Inheritable,
Permitted,
}
custom_derive! {
#[derive(PartialEq,Eq,Hash,Debug,Clone,Copy,
IterVariants(CapsVariants), IterVariantNames(CapsVariantNames))]
#[allow(non_camel_case_types)]
#[repr(u8)]
pub enum Capability {
CAP_CHOWN = nr::CAP_CHOWN,
CAP_DAC_OVERRIDE = nr::CAP_DAC_OVERRIDE,
CAP_DAC_READ_SEARCH = nr::CAP_DAC_READ_SEARCH,
CAP_FOWNER = nr::CAP_FOWNER,
CAP_FSETID = nr::CAP_FSETID,
CAP_KILL = nr::CAP_KILL,
CAP_SETGID = nr::CAP_SETGID,
CAP_SETUID = nr::CAP_SETUID,
CAP_SETPCAP = nr::CAP_SETPCAP,
CAP_LINUX_IMMUTABLE = nr::CAP_LINUX_IMMUTABLE,
CAP_NET_BIND_SERVICE = nr::CAP_NET_BIND_SERVICE,
CAP_NET_BROADCAST = nr::CAP_NET_BROADCAST,
CAP_NET_ADMIN = nr::CAP_NET_ADMIN,
CAP_NET_RAW = nr::CAP_NET_RAW,
CAP_IPC_LOCK = nr::CAP_IPC_LOCK,
CAP_IPC_OWNER = nr::CAP_IPC_OWNER,
CAP_SYS_MODULE = nr::CAP_SYS_MODULE,
CAP_SYS_RAWIO = nr::CAP_SYS_RAWIO,
CAP_SYS_CHROOT = nr::CAP_SYS_CHROOT,
CAP_SYS_PTRACE = nr::CAP_SYS_PTRACE,
CAP_SYS_PACCT = nr::CAP_SYS_PACCT,
CAP_SYS_ADMIN = nr::CAP_SYS_ADMIN,
CAP_SYS_BOOT = nr::CAP_SYS_BOOT,
CAP_SYS_NICE = nr::CAP_SYS_NICE,
CAP_SYS_RESOURCE = nr::CAP_SYS_RESOURCE,
CAP_SYS_TIME = nr::CAP_SYS_TIME,
CAP_SYS_TTY_CONFIG = nr::CAP_SYS_TTY_CONFIG,
CAP_MKNOD = nr::CAP_MKNOD,
CAP_LEASE = nr::CAP_LEASE,
CAP_AUDIT_WRITE = nr::CAP_AUDIT_WRITE,
CAP_AUDIT_CONTROL = nr::CAP_AUDIT_CONTROL,
CAP_SETFCAP = nr::CAP_SETFCAP,
CAP_MAC_OVERRIDE = nr::CAP_MAC_OVERRIDE,
CAP_MAC_ADMIN = nr::CAP_MAC_ADMIN,
CAP_SYSLOG = nr::CAP_SYSLOG,
CAP_WAKE_ALARM = nr::CAP_WAKE_ALARM,
CAP_BLOCK_SUSPEND = nr::CAP_BLOCK_SUSPEND,
CAP_AUDIT_READ = nr::CAP_AUDIT_READ,
}
}
impl Capability {
pub fn bitmask(&self) -> u64 {
1u64 << (*self as u8)
}
pub fn index(&self) -> u8 {
(*self as u8)
}
}
pub type CapsHashSet = std::collections::HashSet<Capability>;
pub fn has_cap(tid: Option<i32>, cset: CapSet, cap: Capability) -> Result<bool> {
let t = tid.unwrap_or(0);
return match cset {
CapSet::Ambient if t == 0 => ambient::has_cap(cap),
CapSet::Bounding if t == 0 => bounding::has_cap(cap),
CapSet::Effective | CapSet::Inheritable | CapSet::Permitted => base::has_cap(t, cset, cap),
_ => bail!("operation not supported"),
};
}
pub fn read(tid: Option<i32>, cset: CapSet) -> Result<CapsHashSet> {
let t = tid.unwrap_or(0);
return match cset {
CapSet::Ambient if t == 0 => ambient::read(),
CapSet::Bounding if t == 0 => bounding::read(),
CapSet::Effective | CapSet::Inheritable | CapSet::Permitted => base::read(t, cset),
_ => bail!("operation not supported"),
};
}
pub fn set(tid: Option<i32>, cset: CapSet, value: CapsHashSet) -> Result<()> {
let t = tid.unwrap_or(0);
return match cset {
CapSet::Ambient if t == 0 => ambient::set(value),
CapSet::Effective | CapSet::Inheritable | CapSet::Permitted => base::set(t, cset, value),
_ => bail!("operation not supported"),
};
}
pub fn clear(tid: Option<i32>, cset: CapSet) -> Result<()> {
let t = tid.unwrap_or(0);
return match cset {
CapSet::Ambient if t == 0 => ambient::clear(),
CapSet::Bounding if t == 0 => bounding::clear(),
CapSet::Effective | CapSet::Permitted | CapSet::Inheritable => base::clear(t, cset),
_ => bail!("operation not supported"),
};
}
pub fn raise(tid: Option<i32>, cset: CapSet, cap: Capability) -> Result<()> {
let t = tid.unwrap_or(0);
return match cset {
CapSet::Ambient if t == 0 => ambient::raise(cap),
CapSet::Effective | CapSet::Permitted | CapSet::Inheritable => base::raise(t, cset, cap),
_ => bail!("operation not supported"),
};
}
pub fn drop(tid: Option<i32>, cset: CapSet, cap: Capability) -> Result<()> {
let t = tid.unwrap_or(0);
return match cset {
CapSet::Ambient if t == 0 => ambient::drop(cap),
CapSet::Bounding if t == 0 => bounding::drop(cap),
CapSet::Effective | CapSet::Permitted | CapSet::Inheritable => base::drop(t, cset, cap),
_ => bail!("operation not supported"),
};
}