]> git.proxmox.com Git - proxmox-backup.git/blob - pbs-api-types/src/acl.rs
move acl to pbs_config workspaces, pbs_api_types cleanups
[proxmox-backup.git] / pbs-api-types / src / acl.rs
1 use std::str::FromStr;
2
3 use serde::{Deserialize, Serialize};
4 use serde::de::{value, IntoDeserializer};
5
6 use proxmox::api::api;
7 use proxmox::api::schema::{
8 ApiStringFormat, BooleanSchema, EnumEntry, Schema, StringSchema,
9 };
10 use proxmox::{constnamedbitmap, const_regex};
11
12 const_regex! {
13 pub ACL_PATH_REGEX = concat!(r"^(?:/|", r"(?:/", PROXMOX_SAFE_ID_REGEX_STR!(), ")+", r")$");
14 }
15
16 // define Privilege bitfield
17
18 constnamedbitmap! {
19 /// Contains a list of privilege name to privilege value mappings.
20 ///
21 /// The names are used when displaying/persisting privileges anywhere, the values are used to
22 /// allow easy matching of privileges as bitflags.
23 PRIVILEGES: u64 => {
24 /// Sys.Audit allows knowing about the system and its status
25 PRIV_SYS_AUDIT("Sys.Audit");
26 /// Sys.Modify allows modifying system-level configuration
27 PRIV_SYS_MODIFY("Sys.Modify");
28 /// Sys.Modify allows to poweroff/reboot/.. the system
29 PRIV_SYS_POWER_MANAGEMENT("Sys.PowerManagement");
30
31 /// Datastore.Audit allows knowing about a datastore,
32 /// including reading the configuration entry and listing its contents
33 PRIV_DATASTORE_AUDIT("Datastore.Audit");
34 /// Datastore.Allocate allows creating or deleting datastores
35 PRIV_DATASTORE_ALLOCATE("Datastore.Allocate");
36 /// Datastore.Modify allows modifying a datastore and its contents
37 PRIV_DATASTORE_MODIFY("Datastore.Modify");
38 /// Datastore.Read allows reading arbitrary backup contents
39 PRIV_DATASTORE_READ("Datastore.Read");
40 /// Allows verifying a datastore
41 PRIV_DATASTORE_VERIFY("Datastore.Verify");
42
43 /// Datastore.Backup allows Datastore.Read|Verify and creating new snapshots,
44 /// but also requires backup ownership
45 PRIV_DATASTORE_BACKUP("Datastore.Backup");
46 /// Datastore.Prune allows deleting snapshots,
47 /// but also requires backup ownership
48 PRIV_DATASTORE_PRUNE("Datastore.Prune");
49
50 /// Permissions.Modify allows modifying ACLs
51 PRIV_PERMISSIONS_MODIFY("Permissions.Modify");
52
53 /// Remote.Audit allows reading remote.cfg and sync.cfg entries
54 PRIV_REMOTE_AUDIT("Remote.Audit");
55 /// Remote.Modify allows modifying remote.cfg
56 PRIV_REMOTE_MODIFY("Remote.Modify");
57 /// Remote.Read allows reading data from a configured `Remote`
58 PRIV_REMOTE_READ("Remote.Read");
59
60 /// Sys.Console allows access to the system's console
61 PRIV_SYS_CONSOLE("Sys.Console");
62
63 /// Tape.Audit allows reading tape backup configuration and status
64 PRIV_TAPE_AUDIT("Tape.Audit");
65 /// Tape.Modify allows modifying tape backup configuration
66 PRIV_TAPE_MODIFY("Tape.Modify");
67 /// Tape.Write allows writing tape media
68 PRIV_TAPE_WRITE("Tape.Write");
69 /// Tape.Read allows reading tape backup configuration and media contents
70 PRIV_TAPE_READ("Tape.Read");
71
72 /// Realm.Allocate allows viewing, creating, modifying and deleting realms
73 PRIV_REALM_ALLOCATE("Realm.Allocate");
74 }
75 }
76
77 /// Admin always has all privileges. It can do everything except a few actions
78 /// which are limited to the 'root@pam` superuser
79 pub const ROLE_ADMIN: u64 = std::u64::MAX;
80
81 /// NoAccess can be used to remove privileges from specific (sub-)paths
82 pub const ROLE_NO_ACCESS: u64 = 0;
83
84 #[rustfmt::skip]
85 #[allow(clippy::identity_op)]
86 /// Audit can view configuration and status information, but not modify it.
87 pub const ROLE_AUDIT: u64 = 0
88 | PRIV_SYS_AUDIT
89 | PRIV_DATASTORE_AUDIT;
90
91 #[rustfmt::skip]
92 #[allow(clippy::identity_op)]
93 /// Datastore.Admin can do anything on the datastore.
94 pub const ROLE_DATASTORE_ADMIN: u64 = 0
95 | PRIV_DATASTORE_AUDIT
96 | PRIV_DATASTORE_MODIFY
97 | PRIV_DATASTORE_READ
98 | PRIV_DATASTORE_VERIFY
99 | PRIV_DATASTORE_BACKUP
100 | PRIV_DATASTORE_PRUNE;
101
102 #[rustfmt::skip]
103 #[allow(clippy::identity_op)]
104 /// Datastore.Reader can read/verify datastore content and do restore
105 pub const ROLE_DATASTORE_READER: u64 = 0
106 | PRIV_DATASTORE_AUDIT
107 | PRIV_DATASTORE_VERIFY
108 | PRIV_DATASTORE_READ;
109
110 #[rustfmt::skip]
111 #[allow(clippy::identity_op)]
112 /// Datastore.Backup can do backup and restore, but no prune.
113 pub const ROLE_DATASTORE_BACKUP: u64 = 0
114 | PRIV_DATASTORE_BACKUP;
115
116 #[rustfmt::skip]
117 #[allow(clippy::identity_op)]
118 /// Datastore.PowerUser can do backup, restore, and prune.
119 pub const ROLE_DATASTORE_POWERUSER: u64 = 0
120 | PRIV_DATASTORE_PRUNE
121 | PRIV_DATASTORE_BACKUP;
122
123 #[rustfmt::skip]
124 #[allow(clippy::identity_op)]
125 /// Datastore.Audit can audit the datastore.
126 pub const ROLE_DATASTORE_AUDIT: u64 = 0
127 | PRIV_DATASTORE_AUDIT;
128
129 #[rustfmt::skip]
130 #[allow(clippy::identity_op)]
131 /// Remote.Audit can audit the remote
132 pub const ROLE_REMOTE_AUDIT: u64 = 0
133 | PRIV_REMOTE_AUDIT;
134
135 #[rustfmt::skip]
136 #[allow(clippy::identity_op)]
137 /// Remote.Admin can do anything on the remote.
138 pub const ROLE_REMOTE_ADMIN: u64 = 0
139 | PRIV_REMOTE_AUDIT
140 | PRIV_REMOTE_MODIFY
141 | PRIV_REMOTE_READ;
142
143 #[rustfmt::skip]
144 #[allow(clippy::identity_op)]
145 /// Remote.SyncOperator can do read and prune on the remote.
146 pub const ROLE_REMOTE_SYNC_OPERATOR: u64 = 0
147 | PRIV_REMOTE_AUDIT
148 | PRIV_REMOTE_READ;
149
150 #[rustfmt::skip]
151 #[allow(clippy::identity_op)]
152 /// Tape.Audit can audit the tape backup configuration and media content
153 pub const ROLE_TAPE_AUDIT: u64 = 0
154 | PRIV_TAPE_AUDIT;
155
156 #[rustfmt::skip]
157 #[allow(clippy::identity_op)]
158 /// Tape.Admin can do anything on the tape backup
159 pub const ROLE_TAPE_ADMIN: u64 = 0
160 | PRIV_TAPE_AUDIT
161 | PRIV_TAPE_MODIFY
162 | PRIV_TAPE_READ
163 | PRIV_TAPE_WRITE;
164
165 #[rustfmt::skip]
166 #[allow(clippy::identity_op)]
167 /// Tape.Operator can do tape backup and restore (but no configuration changes)
168 pub const ROLE_TAPE_OPERATOR: u64 = 0
169 | PRIV_TAPE_AUDIT
170 | PRIV_TAPE_READ
171 | PRIV_TAPE_WRITE;
172
173 #[rustfmt::skip]
174 #[allow(clippy::identity_op)]
175 /// Tape.Reader can do read and inspect tape content
176 pub const ROLE_TAPE_READER: u64 = 0
177 | PRIV_TAPE_AUDIT
178 | PRIV_TAPE_READ;
179
180 /// NoAccess can be used to remove privileges from specific (sub-)paths
181 pub const ROLE_NAME_NO_ACCESS: &str = "NoAccess";
182
183 #[api(
184 type_text: "<role>",
185 )]
186 #[repr(u64)]
187 #[derive(Serialize, Deserialize)]
188 /// Enum representing roles via their [PRIVILEGES] combination.
189 ///
190 /// Since privileges are implemented as bitflags, each unique combination of privileges maps to a
191 /// single, unique `u64` value that is used in this enum definition.
192 pub enum Role {
193 /// Administrator
194 Admin = ROLE_ADMIN,
195 /// Auditor
196 Audit = ROLE_AUDIT,
197 /// Disable Access
198 NoAccess = ROLE_NO_ACCESS,
199 /// Datastore Administrator
200 DatastoreAdmin = ROLE_DATASTORE_ADMIN,
201 /// Datastore Reader (inspect datastore content and do restores)
202 DatastoreReader = ROLE_DATASTORE_READER,
203 /// Datastore Backup (backup and restore owned backups)
204 DatastoreBackup = ROLE_DATASTORE_BACKUP,
205 /// Datastore PowerUser (backup, restore and prune owned backup)
206 DatastorePowerUser = ROLE_DATASTORE_POWERUSER,
207 /// Datastore Auditor
208 DatastoreAudit = ROLE_DATASTORE_AUDIT,
209 /// Remote Auditor
210 RemoteAudit = ROLE_REMOTE_AUDIT,
211 /// Remote Administrator
212 RemoteAdmin = ROLE_REMOTE_ADMIN,
213 /// Syncronisation Opertator
214 RemoteSyncOperator = ROLE_REMOTE_SYNC_OPERATOR,
215 /// Tape Auditor
216 TapeAudit = ROLE_TAPE_AUDIT,
217 /// Tape Administrator
218 TapeAdmin = ROLE_TAPE_ADMIN,
219 /// Tape Operator
220 TapeOperator = ROLE_TAPE_OPERATOR,
221 /// Tape Reader
222 TapeReader = ROLE_TAPE_READER,
223 }
224
225
226 impl FromStr for Role {
227 type Err = value::Error;
228
229 fn from_str(s: &str) -> Result<Self, Self::Err> {
230 Self::deserialize(s.into_deserializer())
231 }
232 }
233
234 pub const ACL_PATH_FORMAT: ApiStringFormat =
235 ApiStringFormat::Pattern(&ACL_PATH_REGEX);
236
237 pub const ACL_PATH_SCHEMA: Schema = StringSchema::new(
238 "Access control path.")
239 .format(&ACL_PATH_FORMAT)
240 .min_length(1)
241 .max_length(128)
242 .schema();
243
244 pub const ACL_PROPAGATE_SCHEMA: Schema = BooleanSchema::new(
245 "Allow to propagate (inherit) permissions.")
246 .default(true)
247 .schema();
248
249 pub const ACL_UGID_TYPE_SCHEMA: Schema = StringSchema::new(
250 "Type of 'ugid' property.")
251 .format(&ApiStringFormat::Enum(&[
252 EnumEntry::new("user", "User"),
253 EnumEntry::new("group", "Group")]))
254 .schema();
255
256 #[api(
257 properties: {
258 propagate: {
259 schema: ACL_PROPAGATE_SCHEMA,
260 },
261 path: {
262 schema: ACL_PATH_SCHEMA,
263 },
264 ugid_type: {
265 schema: ACL_UGID_TYPE_SCHEMA,
266 },
267 ugid: {
268 type: String,
269 description: "User or Group ID.",
270 },
271 roleid: {
272 type: Role,
273 }
274 }
275 )]
276 #[derive(Serialize, Deserialize)]
277 /// ACL list entry.
278 pub struct AclListItem {
279 pub path: String,
280 pub ugid: String,
281 pub ugid_type: String,
282 pub propagate: bool,
283 pub roleid: String,
284 }