1use selinux_policy_derive::{HasName, HasPolicyId, Parse, Serialize, Validate};
6
7use super::context::{MlsLevel, MlsRange};
8use super::error::{ParseError, SerializeError, ValidateError};
9use super::parser::{PolicyCursor, PolicyWriter};
10use super::traits::{Parse, PolicyId, Serialize, Validate};
11use super::{NewPolicy, RoleSet, UserId};
12
13#[derive(Debug, Validate, HasName, HasPolicyId)]
15pub struct User {
16 id: UserId,
17 name: Box<[u8]>,
18 bounds: Option<UserId>,
19 roles: RoleSet,
20 range: MlsRange,
21 default_level: MlsLevel,
22}
23
24impl User {
25 pub fn bounds(&self) -> Option<UserId> {
26 self.bounds
27 }
28
29 pub fn roles(&self) -> &RoleSet {
30 &self.roles
31 }
32
33 pub fn mls_range(&self) -> &MlsRange {
34 &self.range
35 }
36
37 #[cfg(test)]
38 pub fn default_level(&self) -> &MlsLevel {
39 &self.default_level
40 }
41}
42
43#[derive(Parse, Serialize)]
44struct BinaryUserMetadata {
45 key_length: u32,
46 id: UserId,
47 bounds: Option<UserId>,
48}
49
50impl Parse for User {
51 fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
52 let metadata = BinaryUserMetadata::parse(cursor)?;
53 let name = Box::from(cursor.read_bytes(metadata.key_length as usize)?);
54 let roles = RoleSet::parse(cursor)?;
55 let range = MlsRange::parse(cursor)?;
56 let default_level = MlsLevel::parse(cursor)?;
57
58 Ok(Self { id: metadata.id, name, bounds: metadata.bounds, roles, range, default_level })
59 }
60}
61
62impl Serialize for User {
63 fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
64 let metadata = BinaryUserMetadata {
65 key_length: self.name.len() as u32,
66 id: self.id,
67 bounds: self.bounds,
68 };
69 metadata.serialize(writer)?;
70 writer.write_bytes(&self.name);
71 self.roles.serialize(writer)?;
72 self.range.serialize(writer)?;
73 self.default_level.serialize(writer)?;
74 Ok(())
75 }
76}
77
78impl Validate for UserId {
79 fn validate(&self, policy: &NewPolicy) -> Result<(), ValidateError> {
80 policy
81 .users()
82 .get_by_id(*self)
83 .map(|_| ())
84 .ok_or_else(|| ValidateError::UnknownId { kind: "user", id: self.as_u32() })
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 use crate::new_policy::metadata::PolicyVersion;
92 use crate::new_policy::traits::{HasName, HasPolicyId};
93
94 #[test]
95 fn test_user_parse_and_serialize() {
96 let data = [
97 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, b't', b'e', b's', b't', 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ];
120 let mut cursor = PolicyCursor::new(&data);
121 let user = User::parse(&mut cursor).unwrap();
122 assert_eq!(user.id(), UserId::from_u32(1).unwrap());
123 assert_eq!(user.name(), b"test");
124 assert!(user.bounds().is_none());
125 assert!(user.roles().is_empty());
126 assert_eq!(user.mls_range().low().sensitivity().as_u32(), 1);
127 assert_eq!(user.default_level().sensitivity().as_u32(), 1);
128
129 let mut writer = Vec::new();
130 let mut policy_writer = PolicyWriter::new(PolicyVersion::V33, &mut writer);
131 user.serialize(&mut policy_writer).unwrap();
132 assert_eq!(writer, data);
133 }
134}