xref: /DragonOS/kernel/src/process/cred.rs (revision c635d8a9cfe25bc11779f323ef0c7d7a0f597d4a)
1 use core::sync::atomic::AtomicUsize;
2 
3 use alloc::vec::Vec;
4 
5 const GLOBAL_ROOT_UID: Kuid = Kuid(0);
6 const GLOBAL_ROOT_GID: Kgid = Kgid(0);
7 pub static INIT_CRED: Cred = Cred::init();
8 
9 int_like!(Kuid, AtomicKuid, usize, AtomicUsize);
10 int_like!(Kgid, AtomicKgid, usize, AtomicUsize);
11 
12 bitflags! {
13     pub struct CAPFlags:u64{
14         const CAP_EMPTY_SET = 0;
15         const CAP_FULL_SET = (1 << 41) - 1;
16     }
17 }
18 
19 pub enum CredFsCmp {
20     Equal,
21     Less,
22     Greater,
23 }
24 
25 /// 凭证集
26 #[derive(Debug, Clone, PartialEq, Eq)]
27 pub struct Cred {
28     /// 进程实际uid
29     pub uid: Kuid,
30     /// 进程实际gid
31     pub gid: Kgid,
32     /// 进程保存的uid
33     pub suid: Kuid,
34     /// 进程保存的gid
35     pub sgid: Kgid,
36     /// 进程有效的uid
37     pub euid: Kuid,
38     /// 进程有效的gid
39     pub egid: Kgid,
40     /// UID for VFS ops
41     pub fsuid: Kuid,
42     /// GID for VFS ops
43     pub fsgid: Kgid,
44     /// 子进程可以继承的权限
45     pub cap_inheritable: CAPFlags,
46     /// 当前进程被赋予的权限
47     pub cap_permitted: CAPFlags,
48     /// 当前进程实际使用的权限
49     pub cap_effective: CAPFlags,
50     /// capability bounding set
51     pub cap_bset: CAPFlags,
52     /// Ambient capability set
53     pub cap_ambient: CAPFlags,
54     /// supplementary groups for euid/fsgid
55     pub group_info: Option<GroupInfo>,
56 }
57 
58 impl Cred {
59     pub const fn init() -> Self {
60         Self {
61             uid: GLOBAL_ROOT_UID,
62             gid: GLOBAL_ROOT_GID,
63             suid: GLOBAL_ROOT_UID,
64             sgid: GLOBAL_ROOT_GID,
65             euid: GLOBAL_ROOT_UID,
66             egid: GLOBAL_ROOT_GID,
67             fsuid: GLOBAL_ROOT_UID,
68             fsgid: GLOBAL_ROOT_GID,
69             cap_inheritable: CAPFlags::CAP_EMPTY_SET,
70             cap_permitted: CAPFlags::CAP_FULL_SET,
71             cap_effective: CAPFlags::CAP_FULL_SET,
72             cap_bset: CAPFlags::CAP_FULL_SET,
73             cap_ambient: CAPFlags::CAP_FULL_SET,
74             group_info: None,
75         }
76     }
77 
78     #[allow(dead_code)]
79     /// Compare two credentials with respect to filesystem access.
80     pub fn fscmp(&self, other: Cred) -> CredFsCmp {
81         if *self == other {
82             return CredFsCmp::Equal;
83         }
84 
85         if self.fsuid < other.fsuid {
86             return CredFsCmp::Less;
87         }
88         if self.fsuid > other.fsuid {
89             return CredFsCmp::Greater;
90         }
91 
92         if self.fsgid < other.fsgid {
93             return CredFsCmp::Less;
94         }
95         if self.fsgid > other.fsgid {
96             return CredFsCmp::Greater;
97         }
98 
99         if self.group_info == other.group_info {
100             return CredFsCmp::Equal;
101         }
102 
103         if let (Some(ga), Some(gb)) = (&self.group_info, &other.group_info) {
104             let ga_count = ga.gids.len();
105             let gb_count = gb.gids.len();
106 
107             if ga_count < gb_count {
108                 return CredFsCmp::Less;
109             }
110             if ga_count > gb_count {
111                 return CredFsCmp::Greater;
112             }
113 
114             for i in 0..ga_count {
115                 if ga.gids[i] < gb.gids[i] {
116                     return CredFsCmp::Less;
117                 }
118                 if ga.gids[i] > gb.gids[i] {
119                     return CredFsCmp::Greater;
120                 }
121             }
122         } else {
123             if self.group_info.is_none() {
124                 return CredFsCmp::Less;
125             }
126             if other.group_info.is_none() {
127                 return CredFsCmp::Greater;
128             }
129         }
130 
131         return CredFsCmp::Equal;
132     }
133 
134     pub fn setuid(&mut self, uid: usize) {
135         self.uid.0 = uid;
136     }
137 
138     pub fn seteuid(&mut self, euid: usize) {
139         self.euid.0 = euid;
140     }
141 
142     pub fn setsuid(&mut self, suid: usize) {
143         self.suid.0 = suid;
144     }
145 
146     pub fn setfsuid(&mut self, fsuid: usize) {
147         self.fsuid.0 = fsuid;
148     }
149 
150     pub fn setgid(&mut self, gid: usize) {
151         self.gid.0 = gid;
152     }
153 
154     pub fn setegid(&mut self, egid: usize) {
155         self.egid.0 = egid;
156     }
157 
158     pub fn setsgid(&mut self, sgid: usize) {
159         self.sgid.0 = sgid;
160     }
161 
162     pub fn setfsgid(&mut self, fsgid: usize) {
163         self.fsgid.0 = fsgid;
164     }
165 }
166 
167 #[derive(Debug, Clone, PartialEq, Eq)]
168 pub struct GroupInfo {
169     pub gids: Vec<Kgid>,
170 }
171