1use super::context::{MlsLevel, MlsRange};
6use super::error::{ParseError, SerializeError, ValidateError};
7use super::parser::PolicyCursor;
8use super::traits::{Parse, PolicyId, Serialize, Validate};
9use super::{NewPolicy, RoleSet, UserId};
10
11use selinux_policy_derive::{HasName, HasPolicyId, Parse, Serialize, Validate};
12
13#[derive(Debug, Clone, PartialEq, Eq, 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 pub fn default_level(&self) -> &MlsLevel {
38 &self.default_level
39 }
40}
41
42#[derive(Parse, Serialize)]
43struct BinaryUserMetadata {
44 key_length: u32,
45 id: u32,
46 bounds: u32,
47}
48
49impl Parse for User {
50 fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
51 let metadata = BinaryUserMetadata::parse(cursor)?;
52 let name = Box::from(cursor.read_bytes(metadata.key_length as usize)?);
53 let roles = RoleSet::parse(cursor)?;
54 let range = MlsRange::parse(cursor)?;
55 let default_level = MlsLevel::parse(cursor)?;
56
57 let bounds = UserId::from_u32(metadata.bounds);
58
59 let id =
60 UserId::from_u32(metadata.id).ok_or(ParseError::InvalidId { value: metadata.id })?;
61
62 Ok(Self { id, name, bounds, roles, range, default_level })
63 }
64}
65
66impl Serialize for User {
67 fn serialize(&self, writer: &mut Vec<u8>) -> Result<(), SerializeError> {
68 let metadata = BinaryUserMetadata {
69 key_length: self.name.len() as u32,
70 id: self.id.as_u32(),
71 bounds: self.bounds.map_or(0, |id| id.as_u32()),
72 };
73 metadata.serialize(writer)?;
74 writer.extend_from_slice(&self.name);
75 self.roles.serialize(writer)?;
76 self.range.serialize(writer)?;
77 self.default_level.serialize(writer)?;
78 Ok(())
79 }
80}
81
82impl Validate for UserId {
83 fn validate(&self, policy: &NewPolicy) -> Result<(), ValidateError> {
84 policy
85 .users()
86 .get_by_id(*self)
87 .map(|_| ())
88 .ok_or_else(|| ValidateError::UnknownId { kind: "user", id: self.as_u32() })
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95 use crate::new_policy::traits::{HasName, HasPolicyId};
96
97 #[test]
98 fn test_user_parse_and_serialize() {
99 let data = [
100 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, ];
123 let mut cursor = PolicyCursor::new(&data);
124 let user = User::parse(&mut cursor).unwrap();
125 assert_eq!(user.id(), UserId::from_u32(1).unwrap());
126 assert_eq!(user.name(), b"test");
127 assert!(user.bounds().is_none());
128 assert!(user.roles().is_empty());
129 assert_eq!(user.mls_range().low().sensitivity().as_u32(), 1);
130 assert_eq!(user.default_level().sensitivity().as_u32(), 1);
131
132 let mut writer = Vec::new();
133 user.serialize(&mut writer).unwrap();
134 assert_eq!(writer, data);
135 }
136}