iceoryx2_bb_posix/
permission.rs

1// Copyright (c) 2023 Contributors to the Eclipse Foundation
2//
3// See the NOTICE file(s) distributed with this work for additional
4// information regarding copyright ownership.
5//
6// This program and the accompanying materials are made available under the
7// terms of the Apache Software License 2.0 which is available at
8// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
9// which is available at https://opensource.org/licenses/MIT.
10//
11// SPDX-License-Identifier: Apache-2.0 OR MIT
12
13//! Defines the [`Permission`] of a file or directory in a POSIX system.
14//! Can be used in
15//! combination with [`crate::file_descriptor::FileDescriptorManagement`] to set the
16//! credentials of [`crate::file::File`], [`crate::shared_memory::SharedMemory`] and others.
17
18use bitflags::bitflags;
19use iceoryx2_pal_posix::*;
20use std::fmt::Display;
21
22type ModeType = posix::mode_t;
23
24/// Defines the permission of a file or directory in a POSIX system.
25#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
26pub struct Permission(ModeType);
27
28bitflags! {
29    impl Permission: ModeType {
30        const OWNER_READ = 0o0400;
31        const OWNER_WRITE = 0o0200;
32        const OWNER_EXEC = 0o0100;
33        const OWNER_ALL = 0o0700;
34
35        const GROUP_READ = 0o0040;
36        const GROUP_WRITE = 0o0020;
37        const GROUP_EXEC = 0o0010;
38        const GROUP_ALL = 0o0070;
39
40        const OTHERS_READ = 0o0004;
41        const OTHERS_WRITE = 0o0002;
42        const OTHERS_EXEC = 0o0001;
43        const OTHERS_ALL = 0o0007;
44
45        const ALL = 0o0777;
46
47        const SET_UID = 0o4000;
48        const SET_GID= 0o2000;
49        const STICKY_BIT = 0o1000;
50
51        const MASK = 0o7777;
52        const UNKNOWN = 0xFFFF;
53        const _ = !0;
54    }
55}
56
57impl Permission {
58    pub fn none() -> Self {
59        Self(0)
60    }
61}
62
63/// Trait which allows other types like integers to be converted into [`Permission`].
64pub trait PermissionExt {
65    /// converts value into [`Permission`]
66    fn as_permission(&self) -> Permission;
67}
68
69impl PermissionExt for posix::mode_t {
70    fn as_permission(&self) -> Permission {
71        let mut p = Permission::none();
72
73        let owner = self & posix::S_IRWXU;
74        if owner & posix::S_IRUSR != 0 {
75            p |= Permission::OWNER_READ;
76        }
77        if owner & posix::S_IWUSR != 0 {
78            p |= Permission::OWNER_WRITE;
79        }
80        if owner & posix::S_IXUSR != 0 {
81            p |= Permission::OWNER_EXEC;
82        }
83
84        let group = self & posix::S_IRWXG;
85        if group & posix::S_IRGRP != 0 {
86            p |= Permission::GROUP_READ;
87        }
88        if group & posix::S_IWGRP != 0 {
89            p |= Permission::GROUP_WRITE;
90        }
91        if group & posix::S_IXGRP != 0 {
92            p |= Permission::GROUP_EXEC;
93        }
94
95        let others = self & posix::S_IRWXO;
96        if others & posix::S_IROTH != 0 {
97            p |= Permission::OTHERS_READ;
98        }
99        if others & posix::S_IWOTH != 0 {
100            p |= Permission::OTHERS_WRITE;
101        }
102        if others & posix::S_IXOTH != 0 {
103            p |= Permission::OTHERS_EXEC;
104        }
105
106        if self & posix::S_ISUID != 0 {
107            p |= Permission::SET_UID;
108        }
109        if self & posix::S_ISGID != 0 {
110            p |= Permission::SET_GID;
111        }
112
113        if self & posix::S_ISVTX != 0 {
114            p |= Permission::STICKY_BIT;
115        }
116
117        p
118    }
119}
120
121impl Permission {
122    /// Returns true when self contains the permissions of the rhs, otherwise false.
123    pub fn has(&self, rhs: Permission) -> bool {
124        (self.0 & rhs.0) != 0
125    }
126
127    /// Converts the permissions into the C type mode_t
128    pub fn as_mode(&self) -> posix::mode_t {
129        self.0
130    }
131}
132
133impl Display for Permission {
134    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135        let mut owner = "---".to_string();
136        if self.has(Permission::OWNER_READ) {
137            owner.replace_range(0..1, "r");
138        }
139        if self.has(Permission::OWNER_WRITE) {
140            owner.replace_range(1..2, "w");
141        }
142        if self.has(Permission::OWNER_EXEC) {
143            owner.replace_range(2..3, "x");
144        }
145
146        let mut group = "---".to_string();
147        if self.has(Permission::GROUP_READ) {
148            group.replace_range(0..1, "r");
149        }
150        if self.has(Permission::GROUP_WRITE) {
151            group.replace_range(1..2, "w");
152        }
153        if self.has(Permission::GROUP_EXEC) {
154            group.replace_range(2..3, "x");
155        }
156
157        let mut others = "---".to_string();
158        if self.has(Permission::OTHERS_READ) {
159            others.replace_range(0..1, "r")
160        }
161        if self.has(Permission::OTHERS_WRITE) {
162            others.replace_range(1..2, "w")
163        }
164        if self.has(Permission::OTHERS_EXEC) {
165            others.replace_range(2..3, "x")
166        }
167
168        let mut bits = String::new();
169        if self.has(Permission::STICKY_BIT) {
170            bits += "StickyBit, ";
171        }
172        if self.has(Permission::SET_UID) {
173            bits += "SetUid, ";
174        }
175        if self.has(Permission::SET_GID) {
176            bits += "SetGid, ";
177        }
178
179        if bits.is_empty() {
180            bits += "-";
181        } else {
182            bits.truncate(bits.len() - 2);
183        }
184
185        write!(
186            f,
187            "Permission {{ Owner: {}, Group: {}, Others: {}, Bits: {} }}",
188            owner, group, others, bits
189        )
190    }
191}