Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SIDs and Access Masks

Security Identifiers (SIDs)

A SID uniquely identifies a security principal — a user, group, computer, or service. It consists of a revision (always 1), a 6-byte identifier authority, and up to 15 sub-authority values.

#![allow(unused)]
fn main() {
use win_sd::Sid;

// Parse from standard string format
let sid: Sid = "S-1-5-32-544".parse().unwrap();
assert_eq!(sid, Sid::administrators());
assert_eq!(sid.to_string(), "S-1-5-32-544");

// Well-known SID constructors
let _ = Sid::everyone();           // S-1-1-0
let _ = Sid::local_system();       // S-1-5-18
let _ = Sid::authenticated_users();// S-1-5-11
let _ = Sid::anonymous();          // S-1-5-7
let _ = Sid::creator_owner();      // S-1-3-0

// Domain SIDs
let domain = Sid::from_authority(5, vec![21, 100, 200, 300]);
let alice = Sid::from_authority(5, vec![21, 100, 200, 300, 1001]);
assert_eq!(alice.rid(), Some(1001));
assert_eq!(alice.domain(), domain);
}

SIDs implement Hash, Eq, Ord, and optional Serialize/Deserialize, making them suitable as HashMap keys.

ACCESS_MASK

The AccessMask is a 32-bit bitmask encoding the permissions requested or granted. Bits are divided into regions:

BitsCategoryExamples
0–15Object-specificFILE_READ_DATA, FILE_WRITE_DATA, KEY_QUERY_VALUE
16–20Standard rightsDELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER, SYNCHRONIZE
24–25SpecialACCESS_SYSTEM_SECURITY, MAXIMUM_ALLOWED
28–31GenericGENERIC_READ, GENERIC_WRITE, GENERIC_EXECUTE, GENERIC_ALL
#![allow(unused)]
fn main() {
use win_sd::AccessMask;
use acls_rs::algebra::JoinSemilattice;

// Named constants
let read = AccessMask::FILE_GENERIC_READ;
let write = AccessMask::FILE_GENERIC_WRITE;

// Lattice algebra: join (OR) is the least upper bound
let combined = read.join(write);
assert!(combined.contains(read));
assert!(combined.contains(write));

// Subset partial order
assert!(read < AccessMask::FILE_ALL_ACCESS);

// Bitwise operators
let rw = AccessMask::FILE_READ_DATA | AccessMask::FILE_WRITE_DATA;
assert_eq!(rw & AccessMask::FILE_READ_DATA, AccessMask::FILE_READ_DATA);
}

File-specific composites

ConstantBits
FILE_GENERIC_READFILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES | READ_CONTROL | SYNCHRONIZE
FILE_GENERIC_WRITEFILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES | READ_CONTROL | SYNCHRONIZE
FILE_GENERIC_EXECUTEFILE_EXECUTE | FILE_READ_ATTRIBUTES | READ_CONTROL | SYNCHRONIZE
FILE_ALL_ACCESSAll standard + file-specific rights (0x001F01FF)

Registry key rights

The crate also defines registry key constants (KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_READ, KEY_WRITE, KEY_ALL_ACCESS) and Active Directory rights (ADS_RIGHT_DS_READ_PROP, ADS_RIGHT_DS_WRITE_PROP, etc.) for use with Object ACEs.

Generic rights mapping

Generic rights (bits 28–31) are abstract — they must be mapped to object-specific bits before use in access checks. GenericMapping provides this:

#![allow(unused)]
fn main() {
use win_sd::{AccessMask, GenericMapping};

let mapping = GenericMapping::file();
let expanded = mapping.map_mask(AccessMask::GENERIC_READ);
assert_eq!(expanded, AccessMask::FILE_GENERIC_READ);
}

Pre-defined mappings: file(), directory(), registry_key().