1use bitflags::bitflags;
2use core::mem::MaybeUninit;
3
4use crate::pid::Pid;
5use crate::{backend, io};
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub struct CapabilitySets {
10 pub effective: CapabilitySet,
12 pub permitted: CapabilitySet,
14 pub inheritable: CapabilitySet,
16}
17
18#[deprecated(since = "1.1.0", note = "Renamed to CapabilitySet")]
20pub type CapabilityFlags = CapabilitySet;
21
22bitflags! {
23 #[repr(transparent)]
25 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
26 pub struct CapabilitySet: u64 {
27 const CHOWN = 1 << linux_raw_sys::general::CAP_CHOWN;
29 const DAC_OVERRIDE = 1 << linux_raw_sys::general::CAP_DAC_OVERRIDE;
31 const DAC_READ_SEARCH = 1 << linux_raw_sys::general::CAP_DAC_READ_SEARCH;
33 const FOWNER = 1 << linux_raw_sys::general::CAP_FOWNER;
35 const FSETID = 1 << linux_raw_sys::general::CAP_FSETID;
37 const KILL = 1 << linux_raw_sys::general::CAP_KILL;
39 const SETGID = 1 << linux_raw_sys::general::CAP_SETGID;
41 const SETUID = 1 << linux_raw_sys::general::CAP_SETUID;
43 const SETPCAP = 1 << linux_raw_sys::general::CAP_SETPCAP;
45 const LINUX_IMMUTABLE = 1 << linux_raw_sys::general::CAP_LINUX_IMMUTABLE;
47 const NET_BIND_SERVICE = 1 << linux_raw_sys::general::CAP_NET_BIND_SERVICE;
49 const NET_BROADCAST = 1 << linux_raw_sys::general::CAP_NET_BROADCAST;
51 const NET_ADMIN = 1 << linux_raw_sys::general::CAP_NET_ADMIN;
53 const NET_RAW = 1 << linux_raw_sys::general::CAP_NET_RAW;
55 const IPC_LOCK = 1 << linux_raw_sys::general::CAP_IPC_LOCK;
57 const IPC_OWNER = 1 << linux_raw_sys::general::CAP_IPC_OWNER;
59 const SYS_MODULE = 1 << linux_raw_sys::general::CAP_SYS_MODULE;
61 const SYS_RAWIO = 1 << linux_raw_sys::general::CAP_SYS_RAWIO;
63 const SYS_CHROOT = 1 << linux_raw_sys::general::CAP_SYS_CHROOT;
65 const SYS_PTRACE = 1 << linux_raw_sys::general::CAP_SYS_PTRACE;
67 const SYS_PACCT = 1 << linux_raw_sys::general::CAP_SYS_PACCT;
69 const SYS_ADMIN = 1 << linux_raw_sys::general::CAP_SYS_ADMIN;
71 const SYS_BOOT = 1 << linux_raw_sys::general::CAP_SYS_BOOT;
73 const SYS_NICE = 1 << linux_raw_sys::general::CAP_SYS_NICE;
75 const SYS_RESOURCE = 1 << linux_raw_sys::general::CAP_SYS_RESOURCE;
77 const SYS_TIME = 1 << linux_raw_sys::general::CAP_SYS_TIME;
79 const SYS_TTY_CONFIG = 1 << linux_raw_sys::general::CAP_SYS_TTY_CONFIG;
81 const MKNOD = 1 << linux_raw_sys::general::CAP_MKNOD;
83 const LEASE = 1 << linux_raw_sys::general::CAP_LEASE;
85 const AUDIT_WRITE = 1 << linux_raw_sys::general::CAP_AUDIT_WRITE;
87 const AUDIT_CONTROL = 1 << linux_raw_sys::general::CAP_AUDIT_CONTROL;
89 const SETFCAP = 1 << linux_raw_sys::general::CAP_SETFCAP;
91 const MAC_OVERRIDE = 1 << linux_raw_sys::general::CAP_MAC_OVERRIDE;
93 const MAC_ADMIN = 1 << linux_raw_sys::general::CAP_MAC_ADMIN;
95 const SYSLOG = 1 << linux_raw_sys::general::CAP_SYSLOG;
97 const WAKE_ALARM = 1 << linux_raw_sys::general::CAP_WAKE_ALARM;
99 const BLOCK_SUSPEND = 1 << linux_raw_sys::general::CAP_BLOCK_SUSPEND;
101 const AUDIT_READ = 1 << linux_raw_sys::general::CAP_AUDIT_READ;
103 const PERFMON = 1 << linux_raw_sys::general::CAP_PERFMON;
105 const BPF = 1 << linux_raw_sys::general::CAP_BPF;
107 const CHECKPOINT_RESTORE = 1 << linux_raw_sys::general::CAP_CHECKPOINT_RESTORE;
109
110 const _ = !0;
112 }
113}
114
115#[inline]
122#[doc(alias = "capget")]
123pub fn capabilities(pid: Option<Pid>) -> io::Result<CapabilitySets> {
124 capget(pid)
125}
126
127#[inline]
135#[doc(alias = "capset")]
136pub fn set_capabilities(pid: Option<Pid>, sets: CapabilitySets) -> io::Result<()> {
137 capset(pid, sets)
138}
139
140#[inline]
141#[allow(unsafe_code)]
142fn capget(pid: Option<Pid>) -> io::Result<CapabilitySets> {
143 let mut data = [MaybeUninit::<linux_raw_sys::general::__user_cap_data_struct>::uninit(); 2];
144
145 let data = {
146 let mut header = linux_raw_sys::general::__user_cap_header_struct {
147 version: linux_raw_sys::general::_LINUX_CAPABILITY_VERSION_3,
148 pid: Pid::as_raw(pid) as backend::c::c_int,
149 };
150
151 backend::thread::syscalls::capget(&mut header, &mut data)?;
152 unsafe { (data[0].assume_init(), data[1].assume_init()) }
155 };
156
157 let effective = u64::from(data.0.effective) | (u64::from(data.1.effective) << u32::BITS);
158 let permitted = u64::from(data.0.permitted) | (u64::from(data.1.permitted) << u32::BITS);
159 let inheritable = u64::from(data.0.inheritable) | (u64::from(data.1.inheritable) << u32::BITS);
160
161 Ok(CapabilitySets {
163 effective: CapabilitySet::from_bits_retain(effective),
164 permitted: CapabilitySet::from_bits_retain(permitted),
165 inheritable: CapabilitySet::from_bits_retain(inheritable),
166 })
167}
168
169#[inline]
170fn capset(pid: Option<Pid>, sets: CapabilitySets) -> io::Result<()> {
171 let mut header = linux_raw_sys::general::__user_cap_header_struct {
172 version: linux_raw_sys::general::_LINUX_CAPABILITY_VERSION_3,
173 pid: Pid::as_raw(pid) as backend::c::c_int,
174 };
175 let data = [
176 linux_raw_sys::general::__user_cap_data_struct {
177 effective: sets.effective.bits() as u32,
178 permitted: sets.permitted.bits() as u32,
179 inheritable: sets.inheritable.bits() as u32,
180 },
181 linux_raw_sys::general::__user_cap_data_struct {
182 effective: (sets.effective.bits() >> u32::BITS) as u32,
183 permitted: (sets.permitted.bits() >> u32::BITS) as u32,
184 inheritable: (sets.inheritable.bits() >> u32::BITS) as u32,
185 },
186 ];
187
188 backend::thread::syscalls::capset(&mut header, &data)
189}