diff options
| author | David Lönnhager <david.l@mullvad.net> | 2025-03-19 18:52:46 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2025-03-24 16:43:29 +0100 |
| commit | 85a07b3c58a246497f738bcbf15d2ff5b7d1b577 (patch) | |
| tree | fce8b0e47df3b4c166a246656153b6c1c020909e | |
| parent | bdaefa370f9a0464753690655b017a868872b69b (diff) | |
| download | mullvadvpn-85a07b3c58a246497f738bcbf15d2ff5b7d1b577.tar.xz mullvadvpn-85a07b3c58a246497f738bcbf15d2ff5b7d1b577.zip | |
Add function for checking if file is owned by admin or system account
| -rw-r--r-- | talpid-windows/Cargo.toml | 1 | ||||
| -rw-r--r-- | talpid-windows/src/fs.rs | 47 | ||||
| -rw-r--r-- | talpid-windows/src/lib.rs | 3 |
3 files changed, 51 insertions, 0 deletions
diff --git a/talpid-windows/Cargo.toml b/talpid-windows/Cargo.toml index 0b9e1d2672..594e17f9ef 100644 --- a/talpid-windows/Cargo.toml +++ b/talpid-windows/Cargo.toml @@ -23,6 +23,7 @@ features = [ "Win32_Foundation", "Win32_Globalization", "Win32_Security", + "Win32_Security_Authorization", "Win32_System_Diagnostics_ToolHelp", "Win32_System_IO", "Win32_Networking_WinSock", diff --git a/talpid-windows/src/fs.rs b/talpid-windows/src/fs.rs new file mode 100644 index 0000000000..eb78efa963 --- /dev/null +++ b/talpid-windows/src/fs.rs @@ -0,0 +1,47 @@ +use core::ffi::c_void; +use std::io; +use std::os::windows::io::AsRawHandle; +use std::ptr; + +use windows_sys::Win32::{ + Foundation::{LocalFree, ERROR_SUCCESS}, + Security::{ + Authorization::{GetSecurityInfo, SE_FILE_OBJECT}, + IsWellKnownSid, WinBuiltinAdministratorsSid, WinLocalSystemSid, OWNER_SECURITY_INFORMATION, + SECURITY_DESCRIPTOR, SID, + }, +}; + +/// Return whether a file handle is owned by either SYSTEM or the built-in administrators account +pub fn is_admin_owned<T: AsRawHandle>(handle: T) -> io::Result<bool> { + let mut security_descriptor: *mut SECURITY_DESCRIPTOR = ptr::null_mut(); + let mut owner: *mut SID = ptr::null_mut(); + + // SAFETY: `handle` is a valid handle + let result = unsafe { + GetSecurityInfo( + handle.as_raw_handle() as isize, + SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION, + (&mut owner) as *mut *mut SID as *mut *mut c_void, + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + (&mut security_descriptor) as *mut *mut SECURITY_DESCRIPTOR as *mut *mut c_void, + ) + }; + + if result != ERROR_SUCCESS { + return Err(io::Error::from_raw_os_error(result as i32)); + } + + // SAFETY: `owner` is valid since `security_descriptor` still is, and the well-known type is a valid argument + let is_system_owned = unsafe { IsWellKnownSid(owner as _, WinLocalSystemSid) != 0 }; + // SAFETY: `owner` is valid since `security_descriptor` still is, and the well-known type is a valid argument + let is_admin_owned = unsafe { IsWellKnownSid(owner as _, WinBuiltinAdministratorsSid) != 0 }; + + // SAFETY: Since we no longer need the descriptor (or owner), it may be freed + unsafe { LocalFree(security_descriptor.cast()) }; + + Ok(is_system_owned || is_admin_owned) +} diff --git a/talpid-windows/src/lib.rs b/talpid-windows/src/lib.rs index 53fa172ee0..92db769623 100644 --- a/talpid-windows/src/lib.rs +++ b/talpid-windows/src/lib.rs @@ -3,6 +3,9 @@ #![deny(missing_docs)] #![cfg(windows)] +/// File system +pub mod fs; + /// I/O pub mod io; |
