oci_spec/runtime/
capability.rs

1use serde::{
2    de::{Deserializer, Error},
3    Deserialize, Serialize,
4};
5use std::collections::HashSet;
6
7use strum_macros::{Display, EnumString};
8
9/// Capabilities is a unique set of Capability values.
10pub type Capabilities = HashSet<Capability>;
11
12#[derive(Clone, Copy, Debug, EnumString, Eq, Display, Hash, PartialEq, Serialize)]
13/// All available capabilities.
14///
15/// For the purpose of performing permission checks, traditional UNIX
16/// implementations distinguish two categories of processes: privileged
17/// processes (whose effective user ID is 0, referred to as superuser or root),
18/// and unprivileged processes (whose effective UID is nonzero). Privileged
19/// processes bypass all kernel permission checks, while unprivileged processes
20/// are subject to full permission checking based on the process's credentials
21/// (usually: effective UID, effective GID, and supplementary group list).
22///
23/// Starting with kernel 2.2, Linux divides the privileges traditionally
24/// associated with superuser into distinct units, known as capabilities, which
25/// can be independently enabled and disabled. Capabilities are a per-thread attribute.
26#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
27pub enum Capability {
28    #[serde(rename = "CAP_AUDIT_CONTROL")]
29    /// Enable and disable kernel auditing; change auditing filter rules;
30    /// retrieve auditing status and filtering rules.
31    ///
32    /// _since Linux 2.6.11_
33    AuditControl,
34
35    #[serde(rename = "CAP_AUDIT_READ")]
36    /// Allow reading the audit log via multicast netlink socket.
37    ///
38    /// _since Linux 3.16_
39    AuditRead,
40
41    #[serde(rename = "CAP_AUDIT_WRITE")]
42    /// Write records to kernel auditing log.
43    ///
44    /// _since Linux 2.6.11_
45    AuditWrite,
46
47    #[serde(rename = "CAP_BLOCK_SUSPEND")]
48    /// Employ features that can block system suspend
49    /// ([epoll(7)](https://man7.org/linux/man-pages/man7/epoll.7.html)
50    /// **EPOLLWAKEUP**, `/proc/sys/wake_lock`).
51    ///
52    /// _since Linux 3.5_
53    BlockSuspend,
54
55    #[serde(rename = "CAP_BPF")]
56    /// Employ privileged BPF operations; see
57    /// [bpf(2)](https://man7.org/linux/man-pages/man2/bpf.2.html) and
58    /// [bpf-helpers(7)](https://man7.org/linux/man-pages/man7/bpf-helpers.7.html).
59    ///
60    /// This capability was added to separate out BPF functionality from the
61    /// overloaded **CAP_SYS_ADMIN** capability.
62    ///
63    /// _since Linux 5.8_
64    Bpf,
65
66    #[serde(rename = "CAP_CHECKPOINT_RESTORE")]
67    /// - update `/proc/sys/kernel/ns_last_pid` (see
68    ///   [pid_namespaces(7)](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html))
69    /// - employ the set_tid feature of
70    ///   [clone3(2)](https://man7.org/linux/man-pages/man2/clone3.2.html)
71    /// - read the contents of the symbolic links in `/proc/[pid]/map_files` for
72    ///   other processes.
73    ///
74    /// This capability was added to separate out BPF functionality from the
75    /// overloaded **CAP_SYS_ADMIN** capability.
76    ///
77    /// _since Linux 5.9_
78    CheckpointRestore,
79
80    #[serde(rename = "CAP_CHOWN")]
81    /// Make arbitrary changes to file UIDs and GIDs (see
82    /// [chown(2)](https://man7.org/linux/man-pages/man2/chown.2.html)).
83    Chown,
84
85    #[serde(rename = "CAP_DAC_OVERRIDE")]
86    /// Bypass file read, write, and execute permission checks.
87    ///
88    /// (DAC is an abbreviation of "discretionary access control".)
89    DacOverride,
90
91    #[serde(rename = "CAP_DAC_READ_SEARCH")]
92    /// - bypass file read permission checks and directory read and execute
93    ///   permission checks
94    /// - invoke
95    ///   [open_by_handle_at(2)](https://man7.org/linux/man-pages/man2/open_by_handle_at.2.html)
96    /// - use the
97    ///   [linkat(2)](https://man7.org/linux/man-pages/man2/linkat.2.html)
98    ///   **AT_EMPTY_PATH** flag to create a link to a file referred to by a
99    ///   file descriptor.
100    DacReadSearch,
101
102    #[serde(rename = "CAP_FOWNER")]
103    /// - Bypass permission checks on operations that normally require the
104    ///   filesystem UID of the process to match the UID of the file (e.g.,
105    ///   [chmod(2)](https://man7.org/linux/man-pages/man2/chmod.2.html),
106    ///   [utime(2)](https://man7.org/linux/man-pages/man2/utime.2.html)),
107    ///   excluding those operations covered by **CAP_DAC_OVERRIDE** and
108    ///   **CAP_DAC_READ_SEARCH**
109    /// - set inode flags (see
110    ///   [ioctl_iflags(2)](https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html))
111    ///   on arbitrary files
112    /// - set Access Control Lists (ACLs) on arbitrary files
113    /// - ignore directory sticky bit on file deletion
114    /// - modify user extended attributes on sticky directory owned by any user
115    /// - specify **O_NOATIME** for arbitrary files in
116    ///   [open(2)](https://man7.org/linux/man-pages/man2/open.2.html) and
117    ///   [fcntl(2)](https://man7.org/linux/man-pages/man2/fcntl.2.html)
118    ///
119    /// Overrides all restrictions about allowed operations on files, where
120    /// file owner ID must be equal to the user ID, except where CAP_FSETID
121    /// is applicable. It doesn't override MAC and DAC restrictions.
122    Fowner,
123
124    #[serde(rename = "CAP_FSETID")]
125    /// - don't clear set-user-ID and set-group-ID mode bits when a file is
126    ///   modified
127    /// - set the set-group-ID bit for a file whose GID does not match the
128    ///   filesystem or any of the supplementary GIDs of the calling process
129    Fsetid,
130
131    #[serde(rename = "CAP_IPC_LOCK")]
132    /// - lock memory
133    ///   ([mlock(2)](https://man7.org/linux/man-pages/man2/mlock.2.html),
134    ///   [mlockall(2)](https://man7.org/linux/man-pages/man2/mlockall.2.html),
135    ///   [mmap(2)](https://man7.org/linux/man-pages/man2/mmap.2.html),
136    ///   [shmctl(2)](https://man7.org/linux/man-pages/man2/shmctl.2.html))
137    /// - allocate memory using huge pages
138    ///   ([memfd_create(2)](https://man7.org/linux/man-pages/man2/memfd_create.2.html)
139    ///   [mmap(2)](https://man7.org/linux/man-pages/man2/mmap.2.html),
140    ///   [shmctl(2)](https://man7.org/linux/man-pages/man2/shmctl.2.html))
141    IpcLock,
142
143    #[serde(rename = "CAP_IPC_OWNER")]
144    /// Bypass permission checks for operations on System V IPC objects.
145    IpcOwner,
146
147    #[serde(rename = "CAP_KILL")]
148    /// Bypass permission checks for sending signals (see
149    /// [kill(2)](https://man7.org/linux/man-pages/man2/kill.2.html)). This
150    /// includes use of the
151    /// [ioctl(2)](https://man7.org/linux/man-pages/man2/ioctl.2.html)
152    /// **KDSIGACCEPT** operation.
153    Kill,
154
155    #[serde(rename = "CAP_LEASE")]
156    /// Establish leases on arbitrary files (see
157    /// [fcntl(2)](https://man7.org/linux/man-pages/man2/fcntl.2.html)).
158    ///
159    /// _since Linux 2.4_
160    Lease,
161
162    #[serde(rename = "CAP_LINUX_IMMUTABLE")]
163    /// Set the **FS_APPEND_FL** and **FS_IMMUTABLE_FL** inode flags (see
164    /// [ioctl_iflags(2)](https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html)).
165    LinuxImmutable,
166
167    #[serde(rename = "CAP_MAC_ADMIN")]
168    /// Allow MAC configuration or state changes.
169    ///
170    /// Implemented for the Smack Linux Security Module (LSM).
171    ///
172    /// _since Linux 2.6.25_
173    MacAdmin,
174
175    #[serde(rename = "CAP_MAC_OVERRIDE")]
176    /// Override Mandatory Access Control (MAC).
177    ///
178    /// Implemented for the Smack Linux Security Module (LSM).
179    ///
180    /// _since Linux 2.6.25_
181    MacOverride,
182
183    #[serde(rename = "CAP_MKNOD")]
184    /// Create special files using
185    /// [mknod(2)](https://man7.org/linux/man-pages/man2/mknod.2.html).
186    ///
187    /// _since Linux 2.4_
188    Mknod,
189
190    #[serde(rename = "CAP_NET_ADMIN")]
191    /// Perform various network-related operations:
192    /// - interface configuration
193    /// - administration of IP firewall, masquerading, and accounting
194    /// - modify routing tables
195    /// - bind to any address for transparent proxying
196    /// - set type-of-service (TOS)
197    /// - clear driver statistics
198    /// - set promiscuous mode
199    /// - enabling multicasting
200    /// - use
201    ///   [setsockopt(2)](https://man7.org/linux/man-pages/man2/setsockopt.2.html)
202    ///   to set the following socket options: **SO_DEBUG**, **SO_MARK**,
203    ///   **SO_PRIORITY** (for a priority outside the range 0 to 6),
204    ///   **SO_RCVBUFFORCE** and **SO_SNDBUFFORCE**
205    NetAdmin,
206
207    #[serde(rename = "CAP_NET_BIND_SERVICE")]
208    /// Bind a socket to Internet domain privileged ports (port numbers less
209    /// than 1024).
210    NetBindService,
211
212    #[serde(rename = "CAP_NET_BROADCAST")]
213    /// (Unused) Make socket broadcasts, and listen to multicasts.
214    NetBroadcast,
215
216    #[serde(rename = "CAP_NET_RAW")]
217    /// - use RAW and PACKET sockets
218    /// - bind to any address for transparent proxying
219    NetRaw,
220
221    #[serde(rename = "CAP_PERFMON")]
222    /// Employ various performance-monitoring mechanisms, including:
223    /// - call
224    ///   [perf_event_open(2)](https://man7.org/linux/man-pages/man2/perf_event_open.2.html)
225    /// - employ various BPF operations that have performance implications
226    ///
227    /// This capability was added to separate out performance monitoring
228    /// functionality from the overloaded **CAP_SYS_ADMIN** capability. See also
229    /// the kernel source file `Documentation/admin-guide/perf-security.rst`.
230    ///
231    /// _since Linux 5.8_
232    Perfmon,
233
234    #[serde(rename = "CAP_SETGID")]
235    /// - make arbitrary manipulations of process GIDs and supplementary GID list
236    /// - forge GID when passing socket credentials via UNIX domain sockets
237    /// - write a group ID mapping in a user namespace (see
238    ///   [user_namespaces(7)](https://man7.org/linux/man-pages/man7/user_namespaces.7.html))
239    Setgid,
240
241    #[serde(rename = "CAP_SETFCAP")]
242    /// Set arbitrary capabilities on a file.
243    ///
244    /// _since Linux 2.6.24_
245    Setfcap,
246
247    #[serde(rename = "CAP_SETPCAP")]
248    /// If file capabilities are supported (i.e., since LinuxIDMapping 2.6.24):
249    /// add any capability from the calling thread's bounding set to its
250    /// inheritable set; drop capabilities from the bounding set (via
251    /// [prctl(2)](https://man7.org/linux/man-pages/man2/prctl.2.html)
252    /// **PR_CAPBSET_DROP**); make changes to the `securebits` flags.
253    ///
254    /// If file capabilities are not supported (i.e., kernels before Linux
255    /// 2.6.24): grant or remove any capability in the caller's permitted
256    /// capability set to or from any other process. (This property of
257    /// **CAP_SETPCAP** is not available when the kernel is configured to
258    /// support file capabilities, since **CAP_SETPCAP** has entirely different
259    /// semantics for such kernels.)
260    Setpcap,
261
262    #[serde(rename = "CAP_SETUID")]
263    /// - make arbitrary manipulations of process UIDs
264    ///   ([setuid(2)](https://man7.org/linux/man-pages/man2/setuid.2.html),
265    ///   [setreuid(2)](https://man7.org/linux/man-pages/man2/setreuid.2.html),
266    ///   [setresuid(2)](https://man7.org/linux/man-pages/man2/setresuid.2.html),
267    ///   [setfsuid(2)](https://man7.org/linux/man-pages/man2/setfsuid.2.html))
268    /// - forge UID when passing socket credentials via UNIX domain sockets
269    /// - write a user ID mapping in a user namespace (see
270    ///   [user_namespaces(7)](https://man7.org/linux/man-pages/man7/user_namespaces.7.html))
271    Setuid,
272
273    #[serde(rename = "CAP_SYS_ADMIN")]
274    /// - perform a range of system administration operations including:
275    ///   [quotactl(2)](https://man7.org/linux/man-pages/man2/quotactl.2.html),
276    ///   [mount(2)](https://man7.org/linux/man-pages/man2/mount.2.html),
277    ///   [umount(2)](https://man7.org/linux/man-pages/man2/umount.2.html),
278    ///   [pivot_root(2)](https://man7.org/linux/man-pages/man2/pivot_root.2.html),
279    ///   [swapon(2)](https://man7.org/linux/man-pages/man2/swapon.2.html),
280    ///   [swapoff(2)](https://man7.org/linux/man-pages/man2/swapoff.2.html),
281    ///   [sethostname(2)](https://man7.org/linux/man-pages/man2/sethostname.2.html),
282    ///   and [setdomainname(2)](https://man7.org/linux/man-pages/man2/setdomainname.2.html)
283    /// - perform privileged
284    ///   [syslog(2)](https://man7.org/linux/man-pages/man2/syslog.2.html)
285    ///   operations (since Linux 2.6.37, **CAP_SYSLOG** should be used to
286    ///   permit such operations)
287    /// - perform **VM86_REQUEST_IRQ vm86**(2) command
288    /// - access the same checkpoint/restore functionality that is governed by
289    ///   **CAP_CHECKPOINT_RESTORE** (but the latter, weaker capability is
290    ///   preferred for accessing that functionality)
291    /// - perform the same BPF operations as are governed by **CAP_BPF** (but
292    ///   the latter, weaker capability is preferred for accessing that
293    ///   functionality).
294    /// - employ the same performance monitoring mechanisms as are governed by
295    ///   **CAP_PERFMON** (but the latter, weaker capability is preferred for
296    ///   accessing that functionality).
297    /// - perform **IPC_SET** and **IPC_RMID** operations on arbitrary System V
298    ///   IPC objects
299    /// - override **RLIMIT_NPROC** resource limit
300    /// - perform operations on `trusted` and `security` extended attributes
301    ///   (see [xattr(7)](https://man7.org/linux/man-pages/man7/xattr.7.html))
302    /// - use
303    ///   [lookup_dcookie(2)](https://man7.org/linux/man-pages/man2/lookup_dcookie.2.html)
304    /// - use
305    ///   [ioprio_set(2)](https://man7.org/linux/man-pages/man2/ioprio_set.2.html)
306    ///   to assign **IOPRIO_CLASS_RT** and (before Linux 2.6.25)
307    ///   **IOPRIO_CLASS_IDLE** I/O scheduling classes
308    /// - forge PID when passing socket credentials via UNIX domain sockets
309    /// - exceed `/proc/sys/fs/file-max`, the system-wide limit on the number of
310    ///   open files, in system calls that open files (e.g.,
311    ///   [accept(2)](https://man7.org/linux/man-pages/man2/accept.2.html),
312    ///   [execve(2)](https://man7.org/linux/man-pages/man2/execve.2.html),
313    ///   [open(2)](https://man7.org/linux/man-pages/man2/open.2.html),
314    ///   [pipe(2)](https://man7.org/linux/man-pages/man2/pipe.2.html))
315    /// - employ **CLONE_*** flags that create new namespaces with
316    ///   [clone(2)](https://man7.org/linux/man-pages/man2/clone.2.html) and
317    ///   [unshare(2)](https://man7.org/linux/man-pages/man2/unshare.2.html)
318    ///   (but, since Linux 3.8, creating user namespaces does not require any
319    ///   capability)
320    /// - access privileged `perf` event information
321    /// - call [setns(2)](https://man7.org/linux/man-pages/man2/setns.2.html)
322    ///   (requires **CAP_SYS_ADMIN** in the `target` namespace)
323    /// - call
324    ///   [fanotify_init(2)](https://man7.org/linux/man-pages/man2/fanotify_init.2.html)
325    /// - perform privileged **KEYCTL_CHOWN** and **KEYCTL_SETPERM**
326    ///   [keyctl(2)](https://man7.org/linux/man-pages/man2/keyctl.2.html)
327    ///   operations
328    /// - perform
329    ///   [madvise(2)](https://man7.org/linux/man-pages/man2/madvise.2.html)
330    ///   **MADV_HWPOISON** operation
331    /// - employ the **TIOCSTI ioctl**(2) to insert characters into the input
332    ///   queue of a terminal other than the caller's controlling terminal
333    /// - employ the obsolete
334    ///   [nfsservctl(2)](https://man7.org/linux/man-pages/man2/nfsservctl.2.html)
335    ///   system call
336    /// - employ the obsolete
337    ///   [bdflush(2)](https://man7.org/linux/man-pages/man2/bdflush.2.html)
338    ///   system call
339    /// - perform various privileged block-device
340    ///   [ioctl(2)](https://man7.org/linux/man-pages/man2/ioctl.2.html)
341    ///   operations
342    /// - perform various privileged filesystem
343    ///   [ioctl(2)](https://man7.org/linux/man-pages/man2/ioctl.2.html)
344    ///   operations
345    /// - perform privileged
346    ///   [ioctl(2)](https://man7.org/linux/man-pages/man2/ioctl.2.html)
347    ///   operations on the `/dev/random` device (see
348    ///   [random(4)](https://man7.org/linux/man-pages/man4/random.4.html))
349    /// - install a
350    ///   [seccomp(2)](https://man7.org/linux/man-pages/man2/seccomp.2.html)
351    ///   filter without first having to set the `no_new_privs` thread attribute
352    /// - modify allow/deny rules for device control groups
353    /// - employ the
354    ///   [ptrace(2)](https://man7.org/linux/man-pages/man2/ptrace.2.html)
355    ///   **PTRACE_SECCOMP_GET_FILTER** operation to dump tracee's seccomp
356    ///   filters
357    /// - employ the
358    ///   [ptrace(2)](https://man7.org/linux/man-pages/man2/ptrace.2.html)
359    ///   **PTRACE_SETOPTIONS** operation to suspend the tracee's seccomp
360    ///   protections (i.e., the **PTRACE_O_SUSPEND_SECCOMP** flag)
361    /// - perform administrative operations on many device drivers
362    /// - modify autogroup nice values by writing to `/proc/[pid]/autogroup`
363    ///   (see [sched(7)](https://man7.org/linux/man-pages/man7/sched.7.html))
364    SysAdmin,
365
366    #[serde(rename = "CAP_SYS_BOOT")]
367    /// Use [reboot(2)](https://man7.org/linux/man-pages/man2/reboot.2.html) and
368    /// [kexec_load(2)](https://man7.org/linux/man-pages/man2/kexec_load.2.html).
369    SysBoot,
370
371    #[serde(rename = "CAP_SYS_CHROOT")]
372    /// - use [chroot(2)](https://man7.org/linux/man-pages/man2/chroot.2.html)
373    /// - change mount namespaces using
374    ///   [setns(2)](https://man7.org/linux/man-pages/man2/setns.2.html)
375    SysChroot,
376
377    #[serde(rename = "CAP_SYS_MODULE")]
378    /// - load and unload kernel modules (see
379    ///   [init_module(2)](https://man7.org/linux/man-pages/man2/init_module.2.html)
380    ///   and
381    ///   [delete_module(2)](https://man7.org/linux/man-pages/man2/delete_module.2.html))
382    /// - in kernels before 2.6.25: drop capabilities from the system-wide
383    ///   capability bounding set
384    SysModule,
385
386    #[serde(rename = "CAP_SYS_NICE")]
387    /// - lower the process nice value
388    ///   ([nice(2)](https://man7.org/linux/man-pages/man2/nice.2.html),
389    ///   [setpriority(2)](https://man7.org/linux/man-pages/man2/setpriority.2.html))
390    ///   and change the nice value for arbitrary processes
391    /// - set real-time scheduling policies for calling process, and set
392    ///   scheduling policies and priorities for arbitrary processes
393    ///   ([sched_setscheduler(2)](https://man7.org/linux/man-pages/man2/sched_setscheduler.2.html),
394    ///   [sched_setparam(2)](https://man7.org/linux/man-pages/man2/sched_setparam.2.html),
395    ///   [sched_setattr(2)](https://man7.org/linux/man-pages/man2/sched_setattr.2.html))
396    /// - set CPU affinity for arbitrary processes
397    ///   ([sched_setaffinity(2)](https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html))
398    /// - set I/O scheduling class and priority for arbitrary processes
399    ///   ([ioprio_set(2)](https://man7.org/linux/man-pages/man2/ioprio_set.2.html))
400    /// - apply
401    ///   [migrate_pages(2)](https://man7.org/linux/man-pages/man2/migrate_pages.2.html)
402    ///   to arbitrary processes and allow processes to be migrated to arbitrary
403    ///   nodes
404    /// - apply
405    ///   [move_pages(2)](https://man7.org/linux/man-pages/man2/move_pages.2.html)
406    ///   to arbitrary processes
407    /// - use the **MPOL_MF_MOVE_ALL** flag with
408    ///   [mbind(2)](https://man7.org/linux/man-pages/man2/mbind.2.html) and
409    ///   [move_pages(2)](https://man7.org/linux/man-pages/man2/move_pages.2.html)
410    SysNice,
411
412    #[serde(rename = "CAP_SYS_PACCT")]
413    /// Use [acct(2)](https://man7.org/linux/man-pages/man2/acct.2.html).
414    SysPacct,
415
416    #[serde(rename = "CAP_SYS_PTRACE")]
417    /// - trace arbitrary processes using
418    ///   [ptrace(2)](https://man7.org/linux/man-pages/man2/ptrace.2.html)
419    /// - apply
420    ///   [get_robust_list(2)](https://man7.org/linux/man-pages/man2/get_robust_list.2.html)
421    ///   to arbitrary processes
422    /// - transfer data to or from the memory of arbitrary processes using
423    ///   [process_vm_readv(2)](https://man7.org/linux/man-pages/man2/process_vm_readv.2.html)
424    ///   and
425    ///   [process_vm_writev(2)](https://man7.org/linux/man-pages/man2/process_vm_writev.2.html)
426    /// - inspect processes using
427    ///   [kcmp(2)](https://man7.org/linux/man-pages/man2/kcmp.2.html)
428    SysPtrace,
429
430    #[serde(rename = "CAP_SYS_RAWIO")]
431    /// - perform I/O port operations
432    ///   ([iopl(2)](https://man7.org/linux/man-pages/man2/iopl.2.html) and
433    ///   [ioperm(2)](https://man7.org/linux/man-pages/man2/ioperm.2.html));
434    /// - access `/proc/kcore`
435    /// - employ the **FIBMAP ioctl**(2) operation
436    /// - open devices for accessing x86 model-specific registers (MSRs, see
437    ///   [msr(4)](https://man7.org/linux/man-pages/man4/msr.4.html))
438    /// - update `/proc/sys/vm/mmap_min_addr`
439    /// - create memory mappings at addresses below the value specified by
440    ///   `/proc/sys/vm/mmap_min_addr`
441    /// - map files in `/proc/bus/pci`
442    /// - open `/dev/mem` and `/dev/kmem`
443    /// - perform various SCSI device commands
444    /// - perform certain operations on
445    ///   [hpsa(4)](https://man7.org/linux/man-pages/man4/hpsa.4.html) and
446    ///   [cciss(4)](https://man7.org/linux/man-pages/man4/cciss.4.html) devices
447    /// - perform a range of device-specific operations on other devices
448    SysRawio,
449
450    #[serde(rename = "CAP_SYS_RESOURCE")]
451    /// - use reserved space on ext2 filesystems
452    /// - make [ioctl(2)](https://man7.org/linux/man-pages/man2/ioctl.2.html)
453    ///   calls controlling ext3 journaling
454    /// - override disk quota limits
455    /// - increase resource limits (see
456    ///   [setrlimit(2)](https://man7.org/linux/man-pages/man2/setrlimit.2.html))
457    /// - override **RLIMIT_NPROC** resource limit
458    /// - override maximum number of consoles on console allocation
459    /// - override maximum number of keymaps
460    /// - allow more than 64hz interrupts from the real-time clock
461    /// - raise `msg_qbytes` limit for a System V message queue above the limit
462    ///   in `/proc/sys/kernel/msgmnb` (see
463    ///   [msgop(2)](https://man7.org/linux/man-pages/man2/msgop.2.html) and
464    ///   [msgctl(2)](https://man7.org/linux/man-pages/man2/msgctl.2.html))
465    /// - allow the **RLIMIT_NOFILE** resource limit on the number of
466    ///   "in-flight" file descriptors to be bypassed when passing file
467    ///   descriptors to another process via a UNIX domain socket (see
468    ///   [unix(7)](https://man7.org/linux/man-pages/man7/unix.7.html));
469    /// - override the `/proc/sys/fs/pipe-size-max` limit when setting the
470    ///   capacity of a pipe using the **F_SETPIPE_SZ**
471    ///   [fcntl(2)](https://man7.org/linux/man-pages/man2/fcntl.2.html) command
472    /// - use **F_SETPIPE_SZ** to increase the capacity of a pipe above the
473    ///   limit specified by `/proc/sys/fs/pipe-max-size`
474    /// - override `/proc/sys/fs/mqueue/queues_max`,
475    ///   `/proc/sys/fs/mqueue/msg_max` and `/proc/sys/fs/mqueue/msgsize_max`
476    ///   limits when creating POSIX message queues (see
477    ///   [mq_overview(7)](https://man7.org/linux/man-pages/man7/mq_overview.7.html))
478    /// - employ the
479    ///   [prctl(2)](https://man7.org/linux/man-pages/man2/prctl.2.html)
480    ///   **PR_SET_MM** operation
481    /// - set `/proc/[pid]/oom_score_adj` to a value lower than the value last
482    ///   set by a process with **CAP_SYS_RESOURCE**
483    SysResource,
484
485    #[serde(rename = "CAP_SYS_TIME")]
486    /// - set system clock
487    ///   ([settimeofday(2)](https://man7.org/linux/man-pages/man2/settimeofday.2.html),
488    ///   [stime(2)](https://man7.org/linux/man-pages/man2/stime.2.html),
489    ///   [adjtimex(2)](https://man7.org/linux/man-pages/man2/adjtimex.2.html))
490    /// - set real-time (hardware) clock
491    SysTime,
492
493    #[serde(rename = "CAP_SYS_TTY_CONFIG")]
494    /// - use
495    ///   [vhangup(2)](https://man7.org/linux/man-pages/man2/vhangup.2.html)
496    /// - employ various privileged
497    ///   [ioctl(2)](https://man7.org/linux/man-pages/man2/ioctl.2.html)
498    ///   operations on virtual terminals
499    SysTtyConfig,
500
501    #[serde(rename = "CAP_SYSLOG")]
502    /// - perform privileged
503    ///   [syslog(2)](https://man7.org/linux/man-pages/man2/syslog.2.html)
504    ///   operations. See
505    ///   [syslog(2)](https://man7.org/linux/man-pages/man2/syslog.2.html) for
506    ///   information on which operations require privilege.
507    /// - view kernel addresses exposed via `/proc` and other interfaces when
508    ///   `/proc/sys/kernel/kptr_restrict` has the value 1. (See the discussion
509    ///   of the `kptr_restrict` in
510    ///   [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html).)
511    ///
512    /// _since Linux 2.6.37_
513    Syslog,
514
515    #[serde(rename = "CAP_WAKE_ALARM")]
516    /// Trigger something that will wake up the system (set
517    /// **CLOCK_REALTIME_ALARM** and **CLOCK_BOOTTIME_ALARM** timers).
518    /// _since Linux 3.0_
519    WakeAlarm,
520}
521
522impl<'de> Deserialize<'de> for Capability {
523    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
524    where
525        D: Deserializer<'de>,
526    {
527        let input = String::deserialize(deserializer)?;
528        let upper = input.to_uppercase();
529        let stripped = upper.strip_prefix("CAP_").unwrap_or(&upper);
530        match stripped {
531            "AUDIT_CONTROL" => Ok(Self::AuditControl),
532            "AUDIT_READ" => Ok(Self::AuditRead),
533            "AUDIT_WRITE" => Ok(Self::AuditWrite),
534            "BLOCK_SUSPEND" => Ok(Self::BlockSuspend),
535            "BPF" => Ok(Self::Bpf),
536            "CHECKPOINT_RESTORE" => Ok(Self::CheckpointRestore),
537            "CHOWN" => Ok(Self::Chown),
538            "DAC_OVERRIDE" => Ok(Self::DacOverride),
539            "DAC_READ_SEARCH" => Ok(Self::DacReadSearch),
540            "FOWNER" => Ok(Self::Fowner),
541            "FSETID" => Ok(Self::Fsetid),
542            "IPC_LOCK" => Ok(Self::IpcLock),
543            "IPC_OWNER" => Ok(Self::IpcOwner),
544            "KILL" => Ok(Self::Kill),
545            "LEASE" => Ok(Self::Lease),
546            "LINUX_IMMUTABLE" => Ok(Self::LinuxImmutable),
547            "MAC_ADMIN" => Ok(Self::MacAdmin),
548            "MAC_OVERRIDE" => Ok(Self::MacOverride),
549            "MKNOD" => Ok(Self::Mknod),
550            "NET_ADMIN" => Ok(Self::NetAdmin),
551            "NET_BIND_SERVICE" => Ok(Self::NetBindService),
552            "NET_BROADCAST" => Ok(Self::NetBroadcast),
553            "NET_RAW" => Ok(Self::NetRaw),
554            "PERFMON" => Ok(Self::Perfmon),
555            "SETGID" => Ok(Self::Setgid),
556            "SETFCAP" => Ok(Self::Setfcap),
557            "SETPCAP" => Ok(Self::Setpcap),
558            "SETUID" => Ok(Self::Setuid),
559            "SYS_ADMIN" => Ok(Self::SysAdmin),
560            "SYS_BOOT" => Ok(Self::SysBoot),
561            "SYS_CHROOT" => Ok(Self::SysChroot),
562            "SYS_MODULE" => Ok(Self::SysModule),
563            "SYS_NICE" => Ok(Self::SysNice),
564            "SYS_PACCT" => Ok(Self::SysPacct),
565            "SYS_PTRACE" => Ok(Self::SysPtrace),
566            "SYS_RAWIO" => Ok(Self::SysRawio),
567            "SYS_RESOURCE" => Ok(Self::SysResource),
568            "SYS_TIME" => Ok(Self::SysTime),
569            "SYS_TTY_CONFIG" => Ok(Self::SysTtyConfig),
570            "SYSLOG" => Ok(Self::Syslog),
571            "WAKE_ALARM" => Ok(Self::WakeAlarm),
572            other => Err(Error::custom(format!(
573                "no variant for {input} (converted to {other})",
574            ))),
575        }
576    }
577}
578
579#[cfg(test)]
580mod tests {
581    use super::*;
582    use crate::error::Result;
583
584    #[test]
585    fn serialize() {
586        let chown = Capability::Chown;
587        let res = serde_json::to_string(&chown).expect("unable to serialize");
588        assert_eq!("\"CAP_CHOWN\"", res);
589    }
590
591    #[test]
592    fn deserialize() -> Result<()> {
593        for case in &["SYSLOG", "CAP_SYSLOG", "cap_SYSLOG", "sySloG"] {
594            let res: Capability = serde_json::from_str(&format!("\"{case}\""))?;
595            assert_eq!(Capability::Syslog, res);
596        }
597        Ok(())
598    }
599
600    #[test]
601    fn capabilities() -> Result<()> {
602        let res: Capabilities = serde_json::from_str(
603            r#"[
604                "syslog",
605                "SYSLOG",
606                "chown",
607                "cap_chown"
608            ]"#,
609        )?;
610        assert_eq!(res.len(), 2);
611        assert!(res.contains(&Capability::Syslog));
612        assert!(res.contains(&Capability::Chown));
613        Ok(())
614    }
615
616    #[test]
617    fn invalid_string2enum() {
618        let invalid_cap_str = "INVALID_CAP";
619        let unknown_cap = invalid_cap_str.parse::<Capability>();
620        assert!(unknown_cap.is_err());
621    }
622
623    #[test]
624    fn cap_enum_to_string() {
625        let cap = Capability::AuditControl;
626        assert_eq!(cap.to_string(), "AUDIT_CONTROL");
627
628        let cap = Capability::AuditRead;
629        assert_eq!(cap.to_string(), "AUDIT_READ");
630
631        let cap = Capability::SysAdmin;
632        assert_eq!(cap.to_string(), "SYS_ADMIN");
633    }
634
635    #[test]
636    fn cap_string_to_enum() {
637        let cap_str = "AUDIT_CONTROL";
638        let cap_enum: Capability = cap_str.parse().unwrap();
639        assert_eq!(cap_enum, Capability::AuditControl);
640
641        let cap_str = "AUDIT_READ";
642        let cap_enum: Capability = cap_str.parse().unwrap();
643        assert_eq!(cap_enum, Capability::AuditRead);
644
645        let cap_str = "SYS_ADMIN";
646        let cap_enum: Capability = cap_str.parse().unwrap();
647        assert_eq!(cap_enum, Capability::SysAdmin);
648    }
649
650    #[test]
651    fn test_serde_serialization() {
652        let cap = Capability::AuditControl;
653        let serialized = serde_json::to_string(&cap).unwrap();
654        assert_eq!(serialized, "\"CAP_AUDIT_CONTROL\"");
655
656        let cap = Capability::SysAdmin;
657        let serialized = serde_json::to_string(&cap).unwrap();
658        assert_eq!(serialized, "\"CAP_SYS_ADMIN\"");
659    }
660
661    #[test]
662    fn test_serde_deserialization() {
663        let serialized = "\"CAP_AUDIT_CONTROL\"";
664        let cap: Capability = serde_json::from_str(serialized).unwrap();
665        assert_eq!(cap, Capability::AuditControl);
666
667        let serialized = "\"CAP_SYS_ADMIN\"";
668        let cap: Capability = serde_json::from_str(serialized).unwrap();
669        assert_eq!(cap, Capability::SysAdmin);
670    }
671}