devices/virtio/fs/
caps.rs1use std::ffi::c_void;
6use std::io;
7use std::os::raw::c_int;
8
9#[allow(non_camel_case_types)]
10type cap_t = *mut c_void;
11
12#[allow(non_camel_case_types)]
13pub type cap_value_t = u32;
14
15#[allow(non_camel_case_types)]
16type cap_flag_t = u32;
17
18#[allow(non_camel_case_types)]
19type cap_flag_value_t = i32;
20
21#[link(name = "cap")]
22extern "C" {
23 fn cap_free(ptr: *mut c_void) -> c_int;
24
25 fn cap_set_flag(
26 c: cap_t,
27 f: cap_flag_t,
28 ncap: c_int,
29 caps: *const cap_value_t,
30 val: cap_flag_value_t,
31 ) -> c_int;
32
33 fn cap_get_proc() -> cap_t;
34 fn cap_set_proc(cap: cap_t) -> c_int;
35}
36
37#[repr(u32)]
38pub enum Capability {
39 Chown = 0,
40 DacOverride = 1,
41 DacReadSearch = 2,
42 Fowner = 3,
43 Fsetid = 4,
44 Kill = 5,
45 Setgid = 6,
46 Setuid = 7,
47 Setpcap = 8,
48 LinuxImmutable = 9,
49 NetBindService = 10,
50 NetBroadcast = 11,
51 NetAdmin = 12,
52 NetRaw = 13,
53 IpcLock = 14,
54 IpcOwner = 15,
55 SysModule = 16,
56 SysRawio = 17,
57 SysChroot = 18,
58 SysPtrace = 19,
59 SysPacct = 20,
60 SysAdmin = 21,
61 SysBoot = 22,
62 SysNice = 23,
63 SysResource = 24,
64 SysTime = 25,
65 SysTtyConfig = 26,
66 Mknod = 27,
67 Lease = 28,
68 AuditWrite = 29,
69 AuditControl = 30,
70 Setfcap = 31,
71 MacOverride = 32,
72 MacAdmin = 33,
73 Syslog = 34,
74 WakeAlarm = 35,
75 BlockSuspend = 36,
76 AuditRead = 37,
77 Last,
78}
79
80impl From<Capability> for cap_value_t {
81 fn from(c: Capability) -> cap_value_t {
82 c as cap_value_t
83 }
84}
85
86#[repr(u32)]
87pub enum Set {
88 Effective = 0,
89 Permitted = 1,
90 Inheritable = 2,
91}
92
93impl From<Set> for cap_flag_t {
94 fn from(s: Set) -> cap_flag_t {
95 s as cap_flag_t
96 }
97}
98
99#[repr(i32)]
100pub enum Value {
101 Clear = 0,
102 Set = 1,
103}
104
105impl From<Value> for cap_flag_value_t {
106 fn from(v: Value) -> cap_flag_value_t {
107 v as cap_flag_value_t
108 }
109}
110
111pub struct Caps(cap_t);
112
113impl Caps {
114 pub fn for_current_thread() -> io::Result<Caps> {
116 let caps = unsafe { cap_get_proc() };
119 if caps.is_null() {
120 Err(io::Error::last_os_error())
121 } else {
122 Ok(Caps(caps))
123 }
124 }
125
126 pub fn update(&mut self, caps: &[Capability], set: Set, value: Value) -> io::Result<()> {
128 let ret = unsafe {
132 cap_set_flag(
133 self.0,
134 set.into(),
135 caps.len() as c_int,
136 caps.as_ptr() as *const cap_value_t,
138 value.into(),
139 )
140 };
141
142 if ret == 0 {
143 Ok(())
144 } else {
145 Err(io::Error::last_os_error())
146 }
147 }
148
149 pub fn apply(&self) -> io::Result<()> {
151 if unsafe { cap_set_proc(self.0) } == 0 {
153 Ok(())
154 } else {
155 Err(io::Error::last_os_error())
156 }
157 }
158}
159
160impl Drop for Caps {
161 fn drop(&mut self) {
162 unsafe {
164 cap_free(self.0);
165 }
166 }
167}