1
+ use core:: ffi:: c_void;
1
2
use std:: io;
2
3
use std:: os:: windows:: io:: AsRawHandle ;
3
4
use std:: ptr;
4
5
5
6
use windows_sys:: Win32 :: {
6
- Foundation :: ERROR_SUCCESS ,
7
+ Foundation :: { LocalFree , ERROR_SUCCESS } ,
7
8
Security :: {
8
9
Authorization :: { GetSecurityInfo , SE_FILE_OBJECT } ,
9
10
IsWellKnownSid , WinBuiltinAdministratorsSid , WinLocalSystemSid , OWNER_SECURITY_INFORMATION ,
10
- SID ,
11
+ SECURITY_DESCRIPTOR , SID ,
11
12
} ,
12
13
} ;
13
14
14
15
/// Return whether a file handle is owned by either SYSTEM or the built-in administrators account
15
16
pub fn is_admin_owned < T : AsRawHandle > ( handle : T ) -> io:: Result < bool > {
17
+ let mut security_descriptor: * mut SECURITY_DESCRIPTOR = ptr:: null_mut ( ) ;
16
18
let mut owner: * mut SID = ptr:: null_mut ( ) ;
17
19
18
20
// SAFETY: `handle` is a valid handle. We return a pointer to the owner associated with the handle(?)
@@ -21,22 +23,25 @@ pub fn is_admin_owned<T: AsRawHandle>(handle: T) -> io::Result<bool> {
21
23
handle. as_raw_handle ( ) as isize ,
22
24
SE_FILE_OBJECT ,
23
25
OWNER_SECURITY_INFORMATION ,
24
- ( & mut owner) as * mut * mut SID as _ ,
25
- ptr:: null_mut ( ) ,
26
+ ( & mut owner) as * mut * mut SID as * mut * mut c_void ,
26
27
ptr:: null_mut ( ) ,
27
28
ptr:: null_mut ( ) ,
28
29
ptr:: null_mut ( ) ,
30
+ ( & mut security_descriptor) as * mut * mut SECURITY_DESCRIPTOR as * mut * mut c_void ,
29
31
)
30
32
} ;
31
33
32
34
if result != ERROR_SUCCESS {
33
35
return Err ( io:: Error :: from_raw_os_error ( result as i32 ) ) ;
34
36
}
35
37
36
- Ok (
37
- // SAFETY: `owner` is valid, and the well-known type is a valid argument
38
- unsafe { IsWellKnownSid ( owner as _ , WinBuiltinAdministratorsSid ) != 0 } ||
39
- // SAFETY: `owner` is valid, and the well-known type is a valid argument
40
- unsafe { IsWellKnownSid ( owner as _ , WinLocalSystemSid ) != 0 } ,
41
- )
38
+ // SAFETY: `owner` is valid since `security_descriptor` still is, and the well-known type is a valid argument
39
+ let is_system_owned = unsafe { IsWellKnownSid ( owner as _ , WinLocalSystemSid ) != 0 } ;
40
+ // SAFETY: `owner` is valid since `security_descriptor` still is, and the well-known type is a valid argument
41
+ let is_admin_owned = unsafe { IsWellKnownSid ( owner as _ , WinBuiltinAdministratorsSid ) != 0 } ;
42
+
43
+ // SAFETY: Since we no longer need the descriptor (or owner), it may be freed
44
+ unsafe { LocalFree ( security_descriptor. cast ( ) ) } ;
45
+
46
+ Ok ( is_system_owned || is_admin_owned)
42
47
}
0 commit comments