1use std::fmt::Write;
2
3use crate::prelude::{ForensicError, ForensicResult};
4
5pub const LOCAL_SYSTEM_SID_STR: &str = "S-1-5-18";
6pub const LOCAL_SYSTEM_SID_BIN: [u8; 12] = [
7 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x12, 0x00, 0x00, 0x00,
8];
9pub const BUILTIN_ADMINS_SID_STR: &str = "S-1-5-32-544";
10pub const BUILTIN_ADMINS_SID_BIN: [u8; 16] = [
11 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00,
12];
13pub const BUILTIN_USERS_SID_STR: &str = "S-1-5-32-545";
14pub const BUILTIN_USERS_SID_BIN: [u8; 16] = [
15 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x21, 0x02, 0x00, 0x00,
16];
17pub const BUILTIN_GUESTS_SID_STR: &str = "S-1-5-32-546";
18pub const BUILTIN_GUESTS_SID_BIN: [u8; 16] = [
19 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x22, 0x02, 0x00, 0x00,
20];
21
22pub fn to_string_sid(sid: &[u8]) -> ForensicResult<String> {
32 if sid.len() < 8 {
33 return Err(ForensicError::bad_format_str(
34 "SID must have at least 8 bytes",
35 ));
36 }
37
38 let mut id = String::with_capacity(32);
39
40 let subauthority_count = sid[1];
41 let mut identifier_authority =
42 (u16::from_be_bytes(sid[2..4].try_into().unwrap_or_default()) as u64) << 32;
43 identifier_authority |= u32::from_be_bytes(sid[4..8].try_into().unwrap_or_default()) as u64;
44 let _ = write!(&mut id, "S-{}-{}", sid[0], identifier_authority);
45 let mut start = 8;
46
47 for _ in 0..subauthority_count {
48 if start + 4 > sid.len() {
49 break;
50 }
51 let authority = &sid[start..start + 4];
52 let tmp = u32::from_le_bytes(authority.try_into().unwrap_or_default());
53 let _ = write!(&mut id, "-{}", tmp);
54 start += 4;
55 }
56
57 Ok(id)
58}
59
60#[test]
61fn should_generate_valid_sids() {
62 assert_eq!(
64 "S-1-5-21-2127521184-1604012920-1887927527-72713",
65 to_string_sid(&[
66 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x00, 0xA0, 0x65,
67 0xCF, 0x7E, 0x78, 0x4B, 0x9B, 0x5F, 0xE7, 0x7C, 0x87, 0x70, 0x09, 0x1C, 0x01, 0x00
68 ])
69 .unwrap()
70 );
71 assert_eq!(
72 BUILTIN_ADMINS_SID_STR,
73 to_string_sid(&BUILTIN_ADMINS_SID_BIN).unwrap()
74 );
75 assert_eq!(
76 BUILTIN_USERS_SID_STR,
77 to_string_sid(&BUILTIN_USERS_SID_BIN).unwrap()
78 );
79 assert_eq!(
80 BUILTIN_GUESTS_SID_STR,
81 to_string_sid(&BUILTIN_GUESTS_SID_BIN).unwrap()
82 );
83 assert_eq!(
84 LOCAL_SYSTEM_SID_STR,
85 to_string_sid(&LOCAL_SYSTEM_SID_BIN).unwrap()
86 );
87 assert_eq!(
88 "S-1-5-21-1366093794-4292800403-1155380978-513",
89 to_string_sid(&[
90 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x00, 0xe2, 0xef,
91 0x6c, 0x51, 0x93, 0xef, 0xde, 0xff, 0xf2, 0xb6, 0xdd, 0x44, 0x01, 0x02, 0x00, 0x00
92 ])
93 .unwrap()
94 );
95}