posix_acl/
entry.rs

1use crate::util::{check_pointer, check_return, AutoPtr};
2use crate::Qualifier::{Group, GroupObj, Mask, Other, Undefined, User, UserObj};
3use acl_sys::{
4    acl_entry_t, acl_get_permset, acl_get_qualifier, acl_get_tag_type, acl_permset_t, ACL_GROUP,
5    ACL_GROUP_OBJ, ACL_MASK, ACL_OTHER, ACL_UNDEFINED_TAG, ACL_USER, ACL_USER_OBJ,
6};
7use std::ptr::null_mut;
8
9/// The subject of a permission grant.
10#[derive(Copy, Clone, Debug, PartialEq, Eq)]
11pub enum Qualifier {
12    /// Unrecognized/corrupt entries
13    Undefined,
14    /// Permissions for owner of the file
15    UserObj,
16    /// Permissions for owning group of the file
17    GroupObj,
18    /// Permissions for everyone else not covered by the ACL
19    Other,
20    /// Permissions for user with UID `u32` value
21    User(u32),
22    /// Permissions for group with GID `u32` value
23    Group(u32),
24    /// Auto-generated entry
25    Mask,
26}
27
28impl Qualifier {
29    pub(crate) fn tag_type(self) -> i32 {
30        match self {
31            Undefined => ACL_UNDEFINED_TAG,
32            UserObj => ACL_USER_OBJ,
33            GroupObj => ACL_GROUP_OBJ,
34            User(_) => ACL_USER,
35            Group(_) => ACL_GROUP,
36            Mask => ACL_MASK,
37            Other => ACL_OTHER,
38        }
39    }
40    pub(crate) fn uid(self) -> Option<u32> {
41        match self {
42            User(uid) | Group(uid) => Some(uid),
43            _ => None,
44        }
45    }
46    /// Convert C type `acl_entry_t` to Rust Qualifier
47    pub(crate) fn from_entry(entry: acl_entry_t) -> Qualifier {
48        let tag_type = 0;
49        let ret = unsafe { acl_get_tag_type(entry, &tag_type) };
50        check_return(ret, "acl_get_tag_type");
51        match tag_type {
52            ACL_UNDEFINED_TAG => Undefined,
53            ACL_USER_OBJ => UserObj,
54            ACL_GROUP_OBJ => GroupObj,
55            ACL_USER => User(Qualifier::get_entry_uid(entry)),
56            ACL_GROUP => Group(Qualifier::get_entry_uid(entry)),
57            ACL_MASK => Mask,
58            ACL_OTHER => Other,
59            _ => {
60                panic!("Unexpected tag type {}", tag_type);
61            }
62        }
63    }
64    /// Helper function for `from_entry()`
65    fn get_entry_uid(entry: acl_entry_t) -> u32 {
66        unsafe {
67            let uid = AutoPtr(acl_get_qualifier(entry).cast::<u32>());
68            check_pointer(uid.0, "acl_get_qualifier");
69            *uid.0
70        }
71    }
72}
73
74/// Returned from [`PosixACL::entries()`](crate::PosixACL::entries).
75#[derive(Copy, Clone, Debug, PartialEq, Eq)]
76#[allow(clippy::upper_case_acronyms)]
77#[allow(clippy::module_name_repetitions)]
78pub struct ACLEntry {
79    pub qual: Qualifier,
80    pub perm: u32,
81}
82
83impl ACLEntry {
84    /// Convert C type `acl_entry_t` to Rust `ACLEntry`
85    pub(crate) fn from_entry(entry: acl_entry_t) -> ACLEntry {
86        let perm;
87        let mut permset: acl_permset_t = null_mut();
88        unsafe {
89            let ret = acl_get_permset(entry, &mut permset);
90            check_return(ret, "acl_get_permset");
91            perm = *(permset as *const u32);
92        }
93        ACLEntry {
94            qual: Qualifier::from_entry(entry),
95            perm,
96        }
97    }
98}