xref: /aosp_15_r20/external/crosvm/win_util/src/security_attributes.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker use std::alloc::alloc_zeroed;
6*bb4ee6a4SAndroid Build Coastguard Worker use std::alloc::dealloc;
7*bb4ee6a4SAndroid Build Coastguard Worker use std::alloc::handle_alloc_error;
8*bb4ee6a4SAndroid Build Coastguard Worker use std::alloc::Layout;
9*bb4ee6a4SAndroid Build Coastguard Worker use std::convert::TryFrom;
10*bb4ee6a4SAndroid Build Coastguard Worker use std::convert::TryInto;
11*bb4ee6a4SAndroid Build Coastguard Worker use std::io;
12*bb4ee6a4SAndroid Build Coastguard Worker use std::mem::size_of;
13*bb4ee6a4SAndroid Build Coastguard Worker use std::os::windows::io::RawHandle;
14*bb4ee6a4SAndroid Build Coastguard Worker use std::ptr;
15*bb4ee6a4SAndroid Build Coastguard Worker 
16*bb4ee6a4SAndroid Build Coastguard Worker use once_cell::sync::OnceCell;
17*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::FALSE;
18*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::HLOCAL;
19*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::LPDWORD;
20*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::LPVOID;
21*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::TRUE;
22*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::winerror::ERROR_INSUFFICIENT_BUFFER;
23*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::winerror::ERROR_SUCCESS;
24*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::EXPLICIT_ACCESS_A;
25*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::NO_INHERITANCE;
26*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::NO_MULTIPLE_TRUSTEE;
27*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::PEXPLICIT_ACCESSA;
28*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::SET_ACCESS;
29*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::TRUSTEE_A;
30*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::TRUSTEE_IS_SID;
31*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::TRUSTEE_IS_USER;
32*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::aclapi::SetEntriesInAclA;
33*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::handleapi::CloseHandle;
34*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::minwinbase::SECURITY_ATTRIBUTES;
35*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::processthreadsapi::GetCurrentProcess;
36*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::processthreadsapi::OpenProcessToken;
37*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::processthreadsapi::OpenThreadToken;
38*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::securitybaseapi::GetTokenInformation;
39*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::securitybaseapi::InitializeSecurityDescriptor;
40*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::securitybaseapi::MakeSelfRelativeSD;
41*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::securitybaseapi::SetSecurityDescriptorDacl;
42*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winbase::LocalFree;
43*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TokenIntegrityLevel;
44*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TokenStatistics;
45*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TokenUser;
46*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::ACL;
47*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::GENERIC_ALL;
48*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::PACL;
49*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::PSECURITY_DESCRIPTOR;
50*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::SECURITY_DESCRIPTOR;
51*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::SECURITY_DESCRIPTOR_REVISION;
52*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TOKEN_ALL_ACCESS;
53*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TOKEN_INFORMATION_CLASS;
54*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TOKEN_MANDATORY_LABEL;
55*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TOKEN_STATISTICS;
56*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TOKEN_USER;
57*bb4ee6a4SAndroid Build Coastguard Worker 
58*bb4ee6a4SAndroid Build Coastguard Worker /// Struct for wrapping `SECURITY_ATTRIBUTES` and `SECURITY_DESCRIPTOR`.
59*bb4ee6a4SAndroid Build Coastguard Worker pub struct SecurityAttributes<T: SecurityDescriptor> {
60*bb4ee6a4SAndroid Build Coastguard Worker     // The security descriptor shouldn't move, as it will be referenced by the
61*bb4ee6a4SAndroid Build Coastguard Worker     // security attributes. We already limit what can be done with the security
62*bb4ee6a4SAndroid Build Coastguard Worker     // attributes by only providing a reference to it, but we also want to
63*bb4ee6a4SAndroid Build Coastguard Worker     // ensure the security descriptor pointer remains valid even if this struct
64*bb4ee6a4SAndroid Build Coastguard Worker     // moves around.
65*bb4ee6a4SAndroid Build Coastguard Worker     _security_descriptor: T,
66*bb4ee6a4SAndroid Build Coastguard Worker     security_attributes: SECURITY_ATTRIBUTES,
67*bb4ee6a4SAndroid Build Coastguard Worker }
68*bb4ee6a4SAndroid Build Coastguard Worker 
69*bb4ee6a4SAndroid Build Coastguard Worker impl<T: SecurityDescriptor> SecurityAttributes<T> {
70*bb4ee6a4SAndroid Build Coastguard Worker     /// Create a new `SecurityAttributes` struct with the provided `security_descriptor`.
new_with_security_descriptor(security_descriptor: T, inherit: bool) -> Self71*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new_with_security_descriptor(security_descriptor: T, inherit: bool) -> Self {
72*bb4ee6a4SAndroid Build Coastguard Worker         let sd = security_descriptor.security_descriptor();
73*bb4ee6a4SAndroid Build Coastguard Worker         let security_attributes = SECURITY_ATTRIBUTES {
74*bb4ee6a4SAndroid Build Coastguard Worker             nLength: size_of::<SECURITY_ATTRIBUTES>() as u32,
75*bb4ee6a4SAndroid Build Coastguard Worker             lpSecurityDescriptor: sd as PSECURITY_DESCRIPTOR,
76*bb4ee6a4SAndroid Build Coastguard Worker             bInheritHandle: if inherit { TRUE } else { FALSE },
77*bb4ee6a4SAndroid Build Coastguard Worker         };
78*bb4ee6a4SAndroid Build Coastguard Worker         SecurityAttributes {
79*bb4ee6a4SAndroid Build Coastguard Worker             _security_descriptor: security_descriptor,
80*bb4ee6a4SAndroid Build Coastguard Worker             security_attributes,
81*bb4ee6a4SAndroid Build Coastguard Worker         }
82*bb4ee6a4SAndroid Build Coastguard Worker     }
83*bb4ee6a4SAndroid Build Coastguard Worker }
84*bb4ee6a4SAndroid Build Coastguard Worker 
85*bb4ee6a4SAndroid Build Coastguard Worker impl SecurityAttributes<SelfRelativeSecurityDescriptor> {
86*bb4ee6a4SAndroid Build Coastguard Worker     /// Create a new `SecurityAttributes` struct. This struct will have a
87*bb4ee6a4SAndroid Build Coastguard Worker     /// `SECURITY_DESCRIPTOR` that allows full access (`GENERIC_ALL`) to only
88*bb4ee6a4SAndroid Build Coastguard Worker     /// the current user.
new(inherit: bool) -> io::Result<Self>89*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new(inherit: bool) -> io::Result<Self> {
90*bb4ee6a4SAndroid Build Coastguard Worker         Ok(Self::new_with_security_descriptor(
91*bb4ee6a4SAndroid Build Coastguard Worker             SelfRelativeSecurityDescriptor::new()?,
92*bb4ee6a4SAndroid Build Coastguard Worker             inherit,
93*bb4ee6a4SAndroid Build Coastguard Worker         ))
94*bb4ee6a4SAndroid Build Coastguard Worker     }
95*bb4ee6a4SAndroid Build Coastguard Worker }
96*bb4ee6a4SAndroid Build Coastguard Worker 
97*bb4ee6a4SAndroid Build Coastguard Worker impl<T: SecurityDescriptor> AsRef<SECURITY_ATTRIBUTES> for SecurityAttributes<T> {
as_ref(&self) -> &SECURITY_ATTRIBUTES98*bb4ee6a4SAndroid Build Coastguard Worker     fn as_ref(&self) -> &SECURITY_ATTRIBUTES {
99*bb4ee6a4SAndroid Build Coastguard Worker         &self.security_attributes
100*bb4ee6a4SAndroid Build Coastguard Worker     }
101*bb4ee6a4SAndroid Build Coastguard Worker }
102*bb4ee6a4SAndroid Build Coastguard Worker 
103*bb4ee6a4SAndroid Build Coastguard Worker impl<T: SecurityDescriptor> AsMut<SECURITY_ATTRIBUTES> for SecurityAttributes<T> {
as_mut(&mut self) -> &mut SECURITY_ATTRIBUTES104*bb4ee6a4SAndroid Build Coastguard Worker     fn as_mut(&mut self) -> &mut SECURITY_ATTRIBUTES {
105*bb4ee6a4SAndroid Build Coastguard Worker         &mut self.security_attributes
106*bb4ee6a4SAndroid Build Coastguard Worker     }
107*bb4ee6a4SAndroid Build Coastguard Worker }
108*bb4ee6a4SAndroid Build Coastguard Worker 
109*bb4ee6a4SAndroid Build Coastguard Worker pub trait TokenClass {
class() -> TOKEN_INFORMATION_CLASS110*bb4ee6a4SAndroid Build Coastguard Worker     fn class() -> TOKEN_INFORMATION_CLASS;
111*bb4ee6a4SAndroid Build Coastguard Worker }
112*bb4ee6a4SAndroid Build Coastguard Worker 
113*bb4ee6a4SAndroid Build Coastguard Worker impl TokenClass for TOKEN_MANDATORY_LABEL {
class() -> TOKEN_INFORMATION_CLASS114*bb4ee6a4SAndroid Build Coastguard Worker     fn class() -> TOKEN_INFORMATION_CLASS {
115*bb4ee6a4SAndroid Build Coastguard Worker         TokenIntegrityLevel
116*bb4ee6a4SAndroid Build Coastguard Worker     }
117*bb4ee6a4SAndroid Build Coastguard Worker }
118*bb4ee6a4SAndroid Build Coastguard Worker 
119*bb4ee6a4SAndroid Build Coastguard Worker impl TokenClass for TOKEN_STATISTICS {
class() -> TOKEN_INFORMATION_CLASS120*bb4ee6a4SAndroid Build Coastguard Worker     fn class() -> TOKEN_INFORMATION_CLASS {
121*bb4ee6a4SAndroid Build Coastguard Worker         TokenStatistics
122*bb4ee6a4SAndroid Build Coastguard Worker     }
123*bb4ee6a4SAndroid Build Coastguard Worker }
124*bb4ee6a4SAndroid Build Coastguard Worker 
125*bb4ee6a4SAndroid Build Coastguard Worker impl TokenClass for TOKEN_USER {
class() -> TOKEN_INFORMATION_CLASS126*bb4ee6a4SAndroid Build Coastguard Worker     fn class() -> TOKEN_INFORMATION_CLASS {
127*bb4ee6a4SAndroid Build Coastguard Worker         TokenUser
128*bb4ee6a4SAndroid Build Coastguard Worker     }
129*bb4ee6a4SAndroid Build Coastguard Worker }
130*bb4ee6a4SAndroid Build Coastguard Worker 
131*bb4ee6a4SAndroid Build Coastguard Worker pub struct TokenInformation<T> {
132*bb4ee6a4SAndroid Build Coastguard Worker     token_info: *mut T,
133*bb4ee6a4SAndroid Build Coastguard Worker     layout: Layout,
134*bb4ee6a4SAndroid Build Coastguard Worker }
135*bb4ee6a4SAndroid Build Coastguard Worker 
136*bb4ee6a4SAndroid Build Coastguard Worker impl<T: TokenClass> TokenInformation<T> {
new(mut token: Token) -> io::Result<Self>137*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new(mut token: Token) -> io::Result<Self> {
138*bb4ee6a4SAndroid Build Coastguard Worker         let token_handle = token.get();
139*bb4ee6a4SAndroid Build Coastguard Worker         // Retrieve the size of the struct.
140*bb4ee6a4SAndroid Build Coastguard Worker         let mut size: u32 = 0;
141*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: size is valid, and TokenInformation is optional and allowed to be null.
142*bb4ee6a4SAndroid Build Coastguard Worker         if unsafe {
143*bb4ee6a4SAndroid Build Coastguard Worker             // The idiomatic usage of GetTokenInformation() requires two calls
144*bb4ee6a4SAndroid Build Coastguard Worker             // to the function: the first to get the length of the data that the
145*bb4ee6a4SAndroid Build Coastguard Worker             // function would return, and the second to fetch the data.
146*bb4ee6a4SAndroid Build Coastguard Worker             GetTokenInformation(
147*bb4ee6a4SAndroid Build Coastguard Worker                 /* TokenHandle= */ token_handle,
148*bb4ee6a4SAndroid Build Coastguard Worker                 /* TokenInformationClass= */ T::class(),
149*bb4ee6a4SAndroid Build Coastguard Worker                 /* TokenInformation= */ ptr::null_mut(),
150*bb4ee6a4SAndroid Build Coastguard Worker                 /* TokenInformationLength= */ 0,
151*bb4ee6a4SAndroid Build Coastguard Worker                 /* ReturnLength= */ &mut size,
152*bb4ee6a4SAndroid Build Coastguard Worker             ) == 0
153*bb4ee6a4SAndroid Build Coastguard Worker         } {
154*bb4ee6a4SAndroid Build Coastguard Worker             const INSUFFICIENT_BUFFER: i32 = ERROR_INSUFFICIENT_BUFFER as i32;
155*bb4ee6a4SAndroid Build Coastguard Worker             match io::Error::last_os_error().raw_os_error() {
156*bb4ee6a4SAndroid Build Coastguard Worker                 Some(INSUFFICIENT_BUFFER) => {
157*bb4ee6a4SAndroid Build Coastguard Worker                     // Despite returning failure, the function will fill in the
158*bb4ee6a4SAndroid Build Coastguard Worker                     // expected buffer length into the ReturnLength parameter.
159*bb4ee6a4SAndroid Build Coastguard Worker                     // It may fail in other ways (e.g. if an invalid TokenHandle
160*bb4ee6a4SAndroid Build Coastguard Worker                     // is provided), so we check that we receive the expected
161*bb4ee6a4SAndroid Build Coastguard Worker                     // error code before assuming that we received a valid
162*bb4ee6a4SAndroid Build Coastguard Worker                     // ReturnLength. In this case, we can ignore the error.
163*bb4ee6a4SAndroid Build Coastguard Worker                 }
164*bb4ee6a4SAndroid Build Coastguard Worker                 _ => return Err(io::Error::last_os_error()),
165*bb4ee6a4SAndroid Build Coastguard Worker             };
166*bb4ee6a4SAndroid Build Coastguard Worker         }
167*bb4ee6a4SAndroid Build Coastguard Worker 
168*bb4ee6a4SAndroid Build Coastguard Worker         // size must be > 0. 0-sized layouts break alloc()'s assumptions.
169*bb4ee6a4SAndroid Build Coastguard Worker         assert!(size > 0, "Unable to get size of token information");
170*bb4ee6a4SAndroid Build Coastguard Worker 
171*bb4ee6a4SAndroid Build Coastguard Worker         // Since we don't statically know the full size of the struct, we
172*bb4ee6a4SAndroid Build Coastguard Worker         // allocate memory for it based on the previous call, aligned to pointer
173*bb4ee6a4SAndroid Build Coastguard Worker         // size.
174*bb4ee6a4SAndroid Build Coastguard Worker         let layout = Layout::from_size_align(size as usize, size_of::<LPVOID>())
175*bb4ee6a4SAndroid Build Coastguard Worker             .expect("Failed to create layout");
176*bb4ee6a4SAndroid Build Coastguard Worker         assert!(layout.size() > 0, "Failed to create valid layout");
177*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: We assert that layout's size is non-zero.
178*bb4ee6a4SAndroid Build Coastguard Worker         let token_info = unsafe { alloc_zeroed(layout) } as *mut T;
179*bb4ee6a4SAndroid Build Coastguard Worker         if token_info.is_null() {
180*bb4ee6a4SAndroid Build Coastguard Worker             handle_alloc_error(layout);
181*bb4ee6a4SAndroid Build Coastguard Worker         }
182*bb4ee6a4SAndroid Build Coastguard Worker 
183*bb4ee6a4SAndroid Build Coastguard Worker         let token_info = TokenInformation::<T> { token_info, layout };
184*bb4ee6a4SAndroid Build Coastguard Worker 
185*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: token_user and size are valid.
186*bb4ee6a4SAndroid Build Coastguard Worker         if unsafe {
187*bb4ee6a4SAndroid Build Coastguard Worker             GetTokenInformation(
188*bb4ee6a4SAndroid Build Coastguard Worker                 /* TokenHandle= */ token_handle,
189*bb4ee6a4SAndroid Build Coastguard Worker                 /* TokenInformationClass= */ T::class(),
190*bb4ee6a4SAndroid Build Coastguard Worker                 /* TokenInformation= */ token_info.token_info as LPVOID,
191*bb4ee6a4SAndroid Build Coastguard Worker                 /* TokenInformationLength= */ size,
192*bb4ee6a4SAndroid Build Coastguard Worker                 /* ReturnLength= */ &mut size,
193*bb4ee6a4SAndroid Build Coastguard Worker             ) == 0
194*bb4ee6a4SAndroid Build Coastguard Worker         } {
195*bb4ee6a4SAndroid Build Coastguard Worker             return Err(io::Error::last_os_error());
196*bb4ee6a4SAndroid Build Coastguard Worker         }
197*bb4ee6a4SAndroid Build Coastguard Worker 
198*bb4ee6a4SAndroid Build Coastguard Worker         Ok(token_info)
199*bb4ee6a4SAndroid Build Coastguard Worker     }
200*bb4ee6a4SAndroid Build Coastguard Worker }
201*bb4ee6a4SAndroid Build Coastguard Worker 
202*bb4ee6a4SAndroid Build Coastguard Worker impl<T> AsRef<T> for TokenInformation<T> {
as_ref(&self) -> &T203*bb4ee6a4SAndroid Build Coastguard Worker     fn as_ref(&self) -> &T {
204*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: The underlying pointer is guaranteed to be properly aligned, dereferenceable, and
205*bb4ee6a4SAndroid Build Coastguard Worker         // point to a valid T. The underlying value will not be modified through the pointer and can
206*bb4ee6a4SAndroid Build Coastguard Worker         // only be accessed through these returned references.
207*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { &*self.token_info }
208*bb4ee6a4SAndroid Build Coastguard Worker     }
209*bb4ee6a4SAndroid Build Coastguard Worker }
210*bb4ee6a4SAndroid Build Coastguard Worker 
211*bb4ee6a4SAndroid Build Coastguard Worker impl<T> AsMut<T> for TokenInformation<T> {
as_mut(&mut self) -> &mut T212*bb4ee6a4SAndroid Build Coastguard Worker     fn as_mut(&mut self) -> &mut T {
213*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: The underlying pointer is guaranteed to be properly aligned, dereferenceable, and
214*bb4ee6a4SAndroid Build Coastguard Worker         // point to a valid T. The underlying value will not be modified through the pointer and can
215*bb4ee6a4SAndroid Build Coastguard Worker         // only be accessed through these returned references.
216*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { &mut *self.token_info }
217*bb4ee6a4SAndroid Build Coastguard Worker     }
218*bb4ee6a4SAndroid Build Coastguard Worker }
219*bb4ee6a4SAndroid Build Coastguard Worker 
220*bb4ee6a4SAndroid Build Coastguard Worker impl<T> Drop for TokenInformation<T> {
drop(&mut self)221*bb4ee6a4SAndroid Build Coastguard Worker     fn drop(&mut self) {
222*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: We ensure the pointer is valid in the constructor, and we are using the same
223*bb4ee6a4SAndroid Build Coastguard Worker         // layout struct as during the allocation.
224*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { dealloc(self.token_info as *mut u8, self.layout) }
225*bb4ee6a4SAndroid Build Coastguard Worker     }
226*bb4ee6a4SAndroid Build Coastguard Worker }
227*bb4ee6a4SAndroid Build Coastguard Worker 
228*bb4ee6a4SAndroid Build Coastguard Worker pub struct Token {
229*bb4ee6a4SAndroid Build Coastguard Worker     token: RawHandle,
230*bb4ee6a4SAndroid Build Coastguard Worker }
231*bb4ee6a4SAndroid Build Coastguard Worker 
232*bb4ee6a4SAndroid Build Coastguard Worker impl Token {
233*bb4ee6a4SAndroid Build Coastguard Worker     /// Open the current process's token.
new_for_process() -> io::Result<Self>234*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new_for_process() -> io::Result<Self> {
235*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: GetCurrentProcess is an alias for -1.
236*bb4ee6a4SAndroid Build Coastguard Worker         Self::from_process(unsafe { GetCurrentProcess() })
237*bb4ee6a4SAndroid Build Coastguard Worker     }
238*bb4ee6a4SAndroid Build Coastguard Worker 
239*bb4ee6a4SAndroid Build Coastguard Worker     /// Open the token of a process.
from_process(proc_handle: RawHandle) -> io::Result<Self>240*bb4ee6a4SAndroid Build Coastguard Worker     pub fn from_process(proc_handle: RawHandle) -> io::Result<Self> {
241*bb4ee6a4SAndroid Build Coastguard Worker         let mut token: RawHandle = ptr::null_mut();
242*bb4ee6a4SAndroid Build Coastguard Worker 
243*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: Token is valid.
244*bb4ee6a4SAndroid Build Coastguard Worker         if unsafe {
245*bb4ee6a4SAndroid Build Coastguard Worker             OpenProcessToken(
246*bb4ee6a4SAndroid Build Coastguard Worker                 /* ProcessHandle= */ proc_handle,
247*bb4ee6a4SAndroid Build Coastguard Worker                 /* DesiredAccess= */ TOKEN_ALL_ACCESS,
248*bb4ee6a4SAndroid Build Coastguard Worker                 /* TokenHandle= */ &mut token,
249*bb4ee6a4SAndroid Build Coastguard Worker             ) == 0
250*bb4ee6a4SAndroid Build Coastguard Worker         } {
251*bb4ee6a4SAndroid Build Coastguard Worker             return Err(io::Error::last_os_error());
252*bb4ee6a4SAndroid Build Coastguard Worker         }
253*bb4ee6a4SAndroid Build Coastguard Worker         Ok(Token { token })
254*bb4ee6a4SAndroid Build Coastguard Worker     }
255*bb4ee6a4SAndroid Build Coastguard Worker 
256*bb4ee6a4SAndroid Build Coastguard Worker     /// Open the token of a thread.
from_thread(thread_handle: RawHandle) -> io::Result<Self>257*bb4ee6a4SAndroid Build Coastguard Worker     pub fn from_thread(thread_handle: RawHandle) -> io::Result<Self> {
258*bb4ee6a4SAndroid Build Coastguard Worker         let mut token: RawHandle = ptr::null_mut();
259*bb4ee6a4SAndroid Build Coastguard Worker 
260*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: Token is valid. We use OpenAsSelf to ensure the token access is measured
261*bb4ee6a4SAndroid Build Coastguard Worker         // using the caller's non-impersonated identity.
262*bb4ee6a4SAndroid Build Coastguard Worker         if unsafe {
263*bb4ee6a4SAndroid Build Coastguard Worker             OpenThreadToken(
264*bb4ee6a4SAndroid Build Coastguard Worker                 thread_handle,
265*bb4ee6a4SAndroid Build Coastguard Worker                 TOKEN_ALL_ACCESS,
266*bb4ee6a4SAndroid Build Coastguard Worker                 /* OpenAsSelf= */ TRUE,
267*bb4ee6a4SAndroid Build Coastguard Worker                 &mut token,
268*bb4ee6a4SAndroid Build Coastguard Worker             ) == 0
269*bb4ee6a4SAndroid Build Coastguard Worker         } {
270*bb4ee6a4SAndroid Build Coastguard Worker             return Err(io::Error::last_os_error());
271*bb4ee6a4SAndroid Build Coastguard Worker         }
272*bb4ee6a4SAndroid Build Coastguard Worker         Ok(Token { token })
273*bb4ee6a4SAndroid Build Coastguard Worker     }
274*bb4ee6a4SAndroid Build Coastguard Worker 
get(&mut self) -> RawHandle275*bb4ee6a4SAndroid Build Coastguard Worker     fn get(&mut self) -> RawHandle {
276*bb4ee6a4SAndroid Build Coastguard Worker         self.token
277*bb4ee6a4SAndroid Build Coastguard Worker     }
278*bb4ee6a4SAndroid Build Coastguard Worker }
279*bb4ee6a4SAndroid Build Coastguard Worker 
280*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for Token {
drop(&mut self)281*bb4ee6a4SAndroid Build Coastguard Worker     fn drop(&mut self) {
282*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: Token is valid, but the call should be safe regardless.
283*bb4ee6a4SAndroid Build Coastguard Worker         unsafe {
284*bb4ee6a4SAndroid Build Coastguard Worker             CloseHandle(self.token);
285*bb4ee6a4SAndroid Build Coastguard Worker         }
286*bb4ee6a4SAndroid Build Coastguard Worker     }
287*bb4ee6a4SAndroid Build Coastguard Worker }
288*bb4ee6a4SAndroid Build Coastguard Worker 
289*bb4ee6a4SAndroid Build Coastguard Worker pub trait SecurityDescriptor {
security_descriptor(&self) -> *const SECURITY_DESCRIPTOR290*bb4ee6a4SAndroid Build Coastguard Worker     fn security_descriptor(&self) -> *const SECURITY_DESCRIPTOR;
291*bb4ee6a4SAndroid Build Coastguard Worker }
292*bb4ee6a4SAndroid Build Coastguard Worker 
293*bb4ee6a4SAndroid Build Coastguard Worker pub struct AbsoluteSecurityDescriptor {
294*bb4ee6a4SAndroid Build Coastguard Worker     descriptor: SECURITY_DESCRIPTOR,
295*bb4ee6a4SAndroid Build Coastguard Worker     acl: *mut ACL,
296*bb4ee6a4SAndroid Build Coastguard Worker }
297*bb4ee6a4SAndroid Build Coastguard Worker 
298*bb4ee6a4SAndroid Build Coastguard Worker impl AbsoluteSecurityDescriptor {
299*bb4ee6a4SAndroid Build Coastguard Worker     /// Creates a `SECURITY_DESCRIPTOR` struct which gives full access rights
300*bb4ee6a4SAndroid Build Coastguard Worker     /// (`GENERIC_ALL`) to only the current user.
new() -> io::Result<AbsoluteSecurityDescriptor>301*bb4ee6a4SAndroid Build Coastguard Worker     fn new() -> io::Result<AbsoluteSecurityDescriptor> {
302*bb4ee6a4SAndroid Build Coastguard Worker         let token = Token::new_for_process()?;
303*bb4ee6a4SAndroid Build Coastguard Worker         let token_user = TokenInformation::<TOKEN_USER>::new(token)?;
304*bb4ee6a4SAndroid Build Coastguard Worker         let sid = token_user.as_ref().User.Sid;
305*bb4ee6a4SAndroid Build Coastguard Worker 
306*bb4ee6a4SAndroid Build Coastguard Worker         let mut ea = EXPLICIT_ACCESS_A {
307*bb4ee6a4SAndroid Build Coastguard Worker             grfAccessPermissions: GENERIC_ALL,
308*bb4ee6a4SAndroid Build Coastguard Worker             grfAccessMode: SET_ACCESS,
309*bb4ee6a4SAndroid Build Coastguard Worker             grfInheritance: NO_INHERITANCE,
310*bb4ee6a4SAndroid Build Coastguard Worker             Trustee: TRUSTEE_A {
311*bb4ee6a4SAndroid Build Coastguard Worker                 TrusteeForm: TRUSTEE_IS_SID,
312*bb4ee6a4SAndroid Build Coastguard Worker                 TrusteeType: TRUSTEE_IS_USER,
313*bb4ee6a4SAndroid Build Coastguard Worker                 ptstrName: sid as *mut i8,
314*bb4ee6a4SAndroid Build Coastguard Worker                 pMultipleTrustee: ptr::null_mut(),
315*bb4ee6a4SAndroid Build Coastguard Worker                 MultipleTrusteeOperation: NO_MULTIPLE_TRUSTEE,
316*bb4ee6a4SAndroid Build Coastguard Worker             },
317*bb4ee6a4SAndroid Build Coastguard Worker         };
318*bb4ee6a4SAndroid Build Coastguard Worker 
319*bb4ee6a4SAndroid Build Coastguard Worker         let mut security_descriptor: std::mem::MaybeUninit<AbsoluteSecurityDescriptor> =
320*bb4ee6a4SAndroid Build Coastguard Worker             std::mem::MaybeUninit::uninit();
321*bb4ee6a4SAndroid Build Coastguard Worker 
322*bb4ee6a4SAndroid Build Coastguard Worker         let ptr = security_descriptor.as_mut_ptr();
323*bb4ee6a4SAndroid Build Coastguard Worker 
324*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: security_descriptor is valid but uninitialized, and
325*bb4ee6a4SAndroid Build Coastguard Worker         // InitializeSecurityDescriptor will initialize it.
326*bb4ee6a4SAndroid Build Coastguard Worker         if unsafe {
327*bb4ee6a4SAndroid Build Coastguard Worker             InitializeSecurityDescriptor(
328*bb4ee6a4SAndroid Build Coastguard Worker                 /* pSecurityDescriptor= */
329*bb4ee6a4SAndroid Build Coastguard Worker                 ptr::addr_of_mut!((*ptr).descriptor) as PSECURITY_DESCRIPTOR,
330*bb4ee6a4SAndroid Build Coastguard Worker                 /* dwRevision= */ SECURITY_DESCRIPTOR_REVISION,
331*bb4ee6a4SAndroid Build Coastguard Worker             ) == 0
332*bb4ee6a4SAndroid Build Coastguard Worker         } {
333*bb4ee6a4SAndroid Build Coastguard Worker             return Err(io::Error::last_os_error());
334*bb4ee6a4SAndroid Build Coastguard Worker         }
335*bb4ee6a4SAndroid Build Coastguard Worker 
336*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: ea and acl are valid and OldAcl is allowed to be null.
337*bb4ee6a4SAndroid Build Coastguard Worker         if unsafe {
338*bb4ee6a4SAndroid Build Coastguard Worker             SetEntriesInAclA(
339*bb4ee6a4SAndroid Build Coastguard Worker                 /* cCountOfExplicitEntries= */ 1,
340*bb4ee6a4SAndroid Build Coastguard Worker                 /* pListOfExplicitEntries= */ &mut ea as PEXPLICIT_ACCESSA,
341*bb4ee6a4SAndroid Build Coastguard Worker                 /* OldAcl= */ ptr::null_mut(),
342*bb4ee6a4SAndroid Build Coastguard Worker                 /* NewAcl= */
343*bb4ee6a4SAndroid Build Coastguard Worker                 ptr::addr_of_mut!((*ptr).acl) as *mut PACL,
344*bb4ee6a4SAndroid Build Coastguard Worker             )
345*bb4ee6a4SAndroid Build Coastguard Worker         } != ERROR_SUCCESS
346*bb4ee6a4SAndroid Build Coastguard Worker         {
347*bb4ee6a4SAndroid Build Coastguard Worker             return Err(io::Error::last_os_error());
348*bb4ee6a4SAndroid Build Coastguard Worker         }
349*bb4ee6a4SAndroid Build Coastguard Worker 
350*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: security_descriptor is valid and initialized after
351*bb4ee6a4SAndroid Build Coastguard Worker         // InitializeSecurityDescriptor() and SetEntriesInAclA().
352*bb4ee6a4SAndroid Build Coastguard Worker         let mut security_descriptor = unsafe { security_descriptor.assume_init() };
353*bb4ee6a4SAndroid Build Coastguard Worker         let sd = &mut security_descriptor.descriptor as *mut SECURITY_DESCRIPTOR;
354*bb4ee6a4SAndroid Build Coastguard Worker 
355*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: The descriptor is valid, and acl is valid after SetEntriesInAclA()
356*bb4ee6a4SAndroid Build Coastguard Worker         if unsafe {
357*bb4ee6a4SAndroid Build Coastguard Worker             SetSecurityDescriptorDacl(
358*bb4ee6a4SAndroid Build Coastguard Worker                 /* pSecurityDescriptor= */ sd as PSECURITY_DESCRIPTOR,
359*bb4ee6a4SAndroid Build Coastguard Worker                 /* bDaclPresent= */ TRUE,
360*bb4ee6a4SAndroid Build Coastguard Worker                 /* pDacl= */ security_descriptor.acl,
361*bb4ee6a4SAndroid Build Coastguard Worker                 /* bDaclDefaulted= */ FALSE,
362*bb4ee6a4SAndroid Build Coastguard Worker             ) == 0
363*bb4ee6a4SAndroid Build Coastguard Worker         } {
364*bb4ee6a4SAndroid Build Coastguard Worker             return Err(io::Error::last_os_error());
365*bb4ee6a4SAndroid Build Coastguard Worker         }
366*bb4ee6a4SAndroid Build Coastguard Worker 
367*bb4ee6a4SAndroid Build Coastguard Worker         Ok(security_descriptor)
368*bb4ee6a4SAndroid Build Coastguard Worker     }
369*bb4ee6a4SAndroid Build Coastguard Worker }
370*bb4ee6a4SAndroid Build Coastguard Worker 
371*bb4ee6a4SAndroid Build Coastguard Worker impl SecurityDescriptor for AbsoluteSecurityDescriptor {
security_descriptor(&self) -> *const SECURITY_DESCRIPTOR372*bb4ee6a4SAndroid Build Coastguard Worker     fn security_descriptor(&self) -> *const SECURITY_DESCRIPTOR {
373*bb4ee6a4SAndroid Build Coastguard Worker         &self.descriptor as *const SECURITY_DESCRIPTOR
374*bb4ee6a4SAndroid Build Coastguard Worker     }
375*bb4ee6a4SAndroid Build Coastguard Worker }
376*bb4ee6a4SAndroid Build Coastguard Worker 
377*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for AbsoluteSecurityDescriptor {
drop(&mut self)378*bb4ee6a4SAndroid Build Coastguard Worker     fn drop(&mut self) {
379*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: We guarantee that on creation acl is initialized to a pointer that can be freed.
380*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { LocalFree(self.acl as HLOCAL) };
381*bb4ee6a4SAndroid Build Coastguard Worker     }
382*bb4ee6a4SAndroid Build Coastguard Worker }
383*bb4ee6a4SAndroid Build Coastguard Worker 
384*bb4ee6a4SAndroid Build Coastguard Worker pub struct SelfRelativeSecurityDescriptor {
385*bb4ee6a4SAndroid Build Coastguard Worker     descriptor: *mut SECURITY_DESCRIPTOR,
386*bb4ee6a4SAndroid Build Coastguard Worker     layout: Layout,
387*bb4ee6a4SAndroid Build Coastguard Worker }
388*bb4ee6a4SAndroid Build Coastguard Worker 
389*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for SelfRelativeSecurityDescriptor {
drop(&mut self)390*bb4ee6a4SAndroid Build Coastguard Worker     fn drop(&mut self) {
391*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: We own self.descriptor and guarantee it is a valid pointer.
392*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { dealloc(self.descriptor as *mut u8, self.layout) }
393*bb4ee6a4SAndroid Build Coastguard Worker     }
394*bb4ee6a4SAndroid Build Coastguard Worker }
395*bb4ee6a4SAndroid Build Coastguard Worker 
396*bb4ee6a4SAndroid Build Coastguard Worker impl Clone for SelfRelativeSecurityDescriptor {
clone(&self) -> Self397*bb4ee6a4SAndroid Build Coastguard Worker     fn clone(&self) -> Self {
398*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: We know that the layout's size is non-zero.
399*bb4ee6a4SAndroid Build Coastguard Worker         let descriptor = unsafe { alloc_zeroed(self.layout) } as *mut SECURITY_DESCRIPTOR;
400*bb4ee6a4SAndroid Build Coastguard Worker         if descriptor.is_null() {
401*bb4ee6a4SAndroid Build Coastguard Worker             handle_alloc_error(self.layout);
402*bb4ee6a4SAndroid Build Coastguard Worker         }
403*bb4ee6a4SAndroid Build Coastguard Worker         let sd = SelfRelativeSecurityDescriptor {
404*bb4ee6a4SAndroid Build Coastguard Worker             descriptor,
405*bb4ee6a4SAndroid Build Coastguard Worker             layout: self.layout,
406*bb4ee6a4SAndroid Build Coastguard Worker         };
407*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
408*bb4ee6a4SAndroid Build Coastguard Worker         //  * `src` is at least `count` bytes, as it was allocated using the above layout.
409*bb4ee6a4SAndroid Build Coastguard Worker         //  * `dst` is at least `count` bytes, as we just allocated it using the above layout.
410*bb4ee6a4SAndroid Build Coastguard Worker         //  * `src` and `dst` are aligned according to the layout, and we are copying byte-wise.
411*bb4ee6a4SAndroid Build Coastguard Worker         //  * `src` and `dst` do not overlap, as we just allocated new memory for `dst`.
412*bb4ee6a4SAndroid Build Coastguard Worker         unsafe {
413*bb4ee6a4SAndroid Build Coastguard Worker             std::ptr::copy_nonoverlapping::<u8>(
414*bb4ee6a4SAndroid Build Coastguard Worker                 /* src= */ self.descriptor as *const u8,
415*bb4ee6a4SAndroid Build Coastguard Worker                 /* dst= */ sd.descriptor as *mut u8,
416*bb4ee6a4SAndroid Build Coastguard Worker                 /* count= */ self.layout.size(),
417*bb4ee6a4SAndroid Build Coastguard Worker             )
418*bb4ee6a4SAndroid Build Coastguard Worker         };
419*bb4ee6a4SAndroid Build Coastguard Worker         sd
420*bb4ee6a4SAndroid Build Coastguard Worker     }
421*bb4ee6a4SAndroid Build Coastguard Worker }
422*bb4ee6a4SAndroid Build Coastguard Worker 
423*bb4ee6a4SAndroid Build Coastguard Worker impl TryFrom<AbsoluteSecurityDescriptor> for SelfRelativeSecurityDescriptor {
424*bb4ee6a4SAndroid Build Coastguard Worker     type Error = io::Error;
425*bb4ee6a4SAndroid Build Coastguard Worker 
try_from(sd: AbsoluteSecurityDescriptor) -> io::Result<Self>426*bb4ee6a4SAndroid Build Coastguard Worker     fn try_from(sd: AbsoluteSecurityDescriptor) -> io::Result<Self> {
427*bb4ee6a4SAndroid Build Coastguard Worker         let mut size: u32 = 0;
428*bb4ee6a4SAndroid Build Coastguard Worker         let descriptor = &sd.descriptor as *const SECURITY_DESCRIPTOR;
429*bb4ee6a4SAndroid Build Coastguard Worker 
430*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: Descriptor and size are valid, and pSelfRelativeSD is optional and allowed to be
431*bb4ee6a4SAndroid Build Coastguard Worker         // null.
432*bb4ee6a4SAndroid Build Coastguard Worker         if unsafe {
433*bb4ee6a4SAndroid Build Coastguard Worker             MakeSelfRelativeSD(
434*bb4ee6a4SAndroid Build Coastguard Worker                 /* pAbsoluteSD= */ descriptor as PSECURITY_DESCRIPTOR,
435*bb4ee6a4SAndroid Build Coastguard Worker                 /* pSelfRelativeSD= */ ptr::null_mut(),
436*bb4ee6a4SAndroid Build Coastguard Worker                 /* lpdwBufferLength= */ &mut size as LPDWORD,
437*bb4ee6a4SAndroid Build Coastguard Worker             )
438*bb4ee6a4SAndroid Build Coastguard Worker         } == 0
439*bb4ee6a4SAndroid Build Coastguard Worker         {
440*bb4ee6a4SAndroid Build Coastguard Worker             const INSUFFICIENT_BUFFER: i32 = ERROR_INSUFFICIENT_BUFFER as i32;
441*bb4ee6a4SAndroid Build Coastguard Worker             match io::Error::last_os_error().raw_os_error() {
442*bb4ee6a4SAndroid Build Coastguard Worker                 Some(INSUFFICIENT_BUFFER) => {
443*bb4ee6a4SAndroid Build Coastguard Worker                     // Despite returning failure, the function will fill in the
444*bb4ee6a4SAndroid Build Coastguard Worker                     // expected buffer length into the lpdwBufferLength parameter.
445*bb4ee6a4SAndroid Build Coastguard Worker                     // It may fail in other ways (e.g. if an invalid pAbsoluteSD
446*bb4ee6a4SAndroid Build Coastguard Worker                     // is provided), so we check that we receive the expected
447*bb4ee6a4SAndroid Build Coastguard Worker                     // error code before assuming that we received a valid
448*bb4ee6a4SAndroid Build Coastguard Worker                     // lpdwBufferLength. In this case, we can ignore the error.
449*bb4ee6a4SAndroid Build Coastguard Worker                 }
450*bb4ee6a4SAndroid Build Coastguard Worker                 _ => return Err(io::Error::last_os_error()),
451*bb4ee6a4SAndroid Build Coastguard Worker             }
452*bb4ee6a4SAndroid Build Coastguard Worker         }
453*bb4ee6a4SAndroid Build Coastguard Worker         // size must be > 0. 0-sized layouts break alloc()'s assumptions.
454*bb4ee6a4SAndroid Build Coastguard Worker         assert!(size > 0, "Unable to get size of self-relative SD");
455*bb4ee6a4SAndroid Build Coastguard Worker 
456*bb4ee6a4SAndroid Build Coastguard Worker         // Since we don't statically know the full size of the struct, we
457*bb4ee6a4SAndroid Build Coastguard Worker         // allocate memory for it based on the previous call, aligned to pointer
458*bb4ee6a4SAndroid Build Coastguard Worker         // size.
459*bb4ee6a4SAndroid Build Coastguard Worker         let layout = Layout::from_size_align(size as usize, size_of::<LPVOID>())
460*bb4ee6a4SAndroid Build Coastguard Worker             .expect("Failed to create layout");
461*bb4ee6a4SAndroid Build Coastguard Worker         assert!(layout.size() > 0, "Failed to create valid layout");
462*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: We assert that layout's size is non-zero.
463*bb4ee6a4SAndroid Build Coastguard Worker         let self_relative_sd = unsafe { alloc_zeroed(layout) } as *mut SECURITY_DESCRIPTOR;
464*bb4ee6a4SAndroid Build Coastguard Worker         if self_relative_sd.is_null() {
465*bb4ee6a4SAndroid Build Coastguard Worker             handle_alloc_error(layout);
466*bb4ee6a4SAndroid Build Coastguard Worker         }
467*bb4ee6a4SAndroid Build Coastguard Worker 
468*bb4ee6a4SAndroid Build Coastguard Worker         let self_relative_sd = SelfRelativeSecurityDescriptor {
469*bb4ee6a4SAndroid Build Coastguard Worker             descriptor: self_relative_sd,
470*bb4ee6a4SAndroid Build Coastguard Worker             layout,
471*bb4ee6a4SAndroid Build Coastguard Worker         };
472*bb4ee6a4SAndroid Build Coastguard Worker 
473*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: Descriptor is valid, the newly allocated self_relative_sd descriptor is valid,
474*bb4ee6a4SAndroid Build Coastguard Worker         // and size is valid.
475*bb4ee6a4SAndroid Build Coastguard Worker         if unsafe {
476*bb4ee6a4SAndroid Build Coastguard Worker             MakeSelfRelativeSD(
477*bb4ee6a4SAndroid Build Coastguard Worker                 /* pAbsoluteSD= */ descriptor as PSECURITY_DESCRIPTOR,
478*bb4ee6a4SAndroid Build Coastguard Worker                 /* pSelfRelativeSD= */ self_relative_sd.descriptor as PSECURITY_DESCRIPTOR,
479*bb4ee6a4SAndroid Build Coastguard Worker                 /* lpdwBufferLength= */ &mut size as LPDWORD,
480*bb4ee6a4SAndroid Build Coastguard Worker             )
481*bb4ee6a4SAndroid Build Coastguard Worker         } == 0
482*bb4ee6a4SAndroid Build Coastguard Worker         {
483*bb4ee6a4SAndroid Build Coastguard Worker             return Err(io::Error::last_os_error());
484*bb4ee6a4SAndroid Build Coastguard Worker         }
485*bb4ee6a4SAndroid Build Coastguard Worker 
486*bb4ee6a4SAndroid Build Coastguard Worker         Ok(self_relative_sd)
487*bb4ee6a4SAndroid Build Coastguard Worker     }
488*bb4ee6a4SAndroid Build Coastguard Worker }
489*bb4ee6a4SAndroid Build Coastguard Worker 
490*bb4ee6a4SAndroid Build Coastguard Worker impl SelfRelativeSecurityDescriptor {
491*bb4ee6a4SAndroid Build Coastguard Worker     /// Creates a `SECURITY_DESCRIPTOR` struct which gives full access rights
492*bb4ee6a4SAndroid Build Coastguard Worker     /// (`GENERIC_ALL`) to only the current user.
new() -> io::Result<Self>493*bb4ee6a4SAndroid Build Coastguard Worker     fn new() -> io::Result<Self> {
494*bb4ee6a4SAndroid Build Coastguard Worker         AbsoluteSecurityDescriptor::new()?.try_into()
495*bb4ee6a4SAndroid Build Coastguard Worker     }
496*bb4ee6a4SAndroid Build Coastguard Worker 
497*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets a copy of a singleton `SelfRelativeSecurityDescriptor`.
get_singleton() -> SelfRelativeSecurityDescriptor498*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_singleton() -> SelfRelativeSecurityDescriptor {
499*bb4ee6a4SAndroid Build Coastguard Worker         static DEFAULT_SECURITY_DESCRIPTOR: OnceCell<SelfRelativeSecurityDescriptor> =
500*bb4ee6a4SAndroid Build Coastguard Worker             OnceCell::new();
501*bb4ee6a4SAndroid Build Coastguard Worker         DEFAULT_SECURITY_DESCRIPTOR
502*bb4ee6a4SAndroid Build Coastguard Worker             .get_or_init(|| {
503*bb4ee6a4SAndroid Build Coastguard Worker                 SelfRelativeSecurityDescriptor::new().expect("Failed to create security descriptor")
504*bb4ee6a4SAndroid Build Coastguard Worker             })
505*bb4ee6a4SAndroid Build Coastguard Worker             .clone()
506*bb4ee6a4SAndroid Build Coastguard Worker     }
507*bb4ee6a4SAndroid Build Coastguard Worker }
508*bb4ee6a4SAndroid Build Coastguard Worker 
509*bb4ee6a4SAndroid Build Coastguard Worker impl SecurityDescriptor for SelfRelativeSecurityDescriptor {
security_descriptor(&self) -> *const SECURITY_DESCRIPTOR510*bb4ee6a4SAndroid Build Coastguard Worker     fn security_descriptor(&self) -> *const SECURITY_DESCRIPTOR {
511*bb4ee6a4SAndroid Build Coastguard Worker         self.descriptor
512*bb4ee6a4SAndroid Build Coastguard Worker     }
513*bb4ee6a4SAndroid Build Coastguard Worker }
514*bb4ee6a4SAndroid Build Coastguard Worker 
515*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: The descriptor and ACLs are treated as immutable by consuming functions and can be safely
516*bb4ee6a4SAndroid Build Coastguard Worker // shared between threads.
517*bb4ee6a4SAndroid Build Coastguard Worker unsafe impl Send for SelfRelativeSecurityDescriptor {}
518*bb4ee6a4SAndroid Build Coastguard Worker 
519*bb4ee6a4SAndroid Build Coastguard Worker //SAFETY: The descriptor and ACLs are treated as immutable by consuming functions.
520*bb4ee6a4SAndroid Build Coastguard Worker unsafe impl Sync for SelfRelativeSecurityDescriptor {}
521