1use crate::errors::CapsError;
4use crate::nr;
5use crate::runtime;
6use crate::{Capability, CapsHashSet};
7use std::io::Error;
8
9pub fn clear() -> Result<(), CapsError> {
10 let ret = unsafe { libc::prctl(nr::PR_CAP_AMBIENT, nr::PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) };
11 match ret {
12 0 => Ok(()),
13 _ => Err(format!(
14 "PR_CAP_AMBIENT_CLEAR_ALL failure: {}",
15 Error::last_os_error()
16 )
17 .into()),
18 }
19}
20
21pub fn drop(cap: Capability) -> Result<(), CapsError> {
22 let ret = unsafe {
23 libc::prctl(
24 nr::PR_CAP_AMBIENT,
25 nr::PR_CAP_AMBIENT_LOWER,
26 libc::c_uint::from(cap.index()),
27 0,
28 0,
29 )
30 };
31 match ret {
32 0 => Ok(()),
33 _ => Err(format!("PR_CAP_AMBIENT_LOWER failure: {}", Error::last_os_error()).into()),
34 }
35}
36
37pub fn has_cap(cap: Capability) -> Result<bool, CapsError> {
38 let ret = unsafe {
39 libc::prctl(
40 nr::PR_CAP_AMBIENT,
41 nr::PR_CAP_AMBIENT_IS_SET,
42 libc::c_uint::from(cap.index()),
43 0,
44 0,
45 )
46 };
47 match ret {
48 0 => Ok(false),
49 1 => Ok(true),
50 _ => Err(format!("PR_CAP_AMBIENT_IS_SET failure: {}", Error::last_os_error()).into()),
51 }
52}
53
54pub fn raise(cap: Capability) -> Result<(), CapsError> {
55 let ret = unsafe {
56 libc::prctl(
57 nr::PR_CAP_AMBIENT,
58 nr::PR_CAP_AMBIENT_RAISE,
59 libc::c_uint::from(cap.index()),
60 0,
61 0,
62 )
63 };
64 match ret {
65 0 => Ok(()),
66 _ => Err(format!("PR_CAP_AMBIENT_RAISE failure: {}", Error::last_os_error()).into()),
67 }
68}
69
70pub fn read() -> Result<CapsHashSet, CapsError> {
71 let mut res = super::CapsHashSet::new();
72 for c in runtime::thread_all_supported() {
73 if has_cap(c)? {
74 res.insert(c);
75 }
76 }
77 Ok(res)
78}
79
80pub fn set(value: &super::CapsHashSet) -> Result<(), CapsError> {
81 for c in runtime::thread_all_supported() {
82 if value.contains(&c) {
83 raise(c)?;
84 } else {
85 drop(c)?;
86 };
87 }
88 Ok(())
89}