Skip to content

Commit 48f76cc

Browse files
committed
see if this makes a difference on windows (#386)
1 parent d6c6ec6 commit 48f76cc

File tree

2 files changed

+28
-19
lines changed

2 files changed

+28
-19
lines changed

git-sec/src/lib.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ pub mod identity {
5252
use std::borrow::Cow;
5353
use std::path::Path;
5454

55-
fn err(msg: &str) -> std::io::Error {
56-
std::io::Error::new(std::io::ErrorKind::Other, msg)
55+
fn err(msg: impl Into<String>) -> std::io::Error {
56+
std::io::Error::new(std::io::ErrorKind::Other, msg.into())
5757
}
5858

5959
pub fn is_path_owned_by_current_user(path: Cow<'_, Path>) -> std::io::Result<bool> {
@@ -75,14 +75,15 @@ pub mod identity {
7575
.map_err(|_| err("Failed to open process token"))?;
7676

7777
let mut len = 0_u32;
78-
if Security::GetTokenInformation(&handle, Security::TokenUser, std::ptr::null_mut(), 0, &mut len)
78+
if !Security::GetTokenInformation(handle, Security::TokenUser, std::ptr::null_mut(), 0, &mut len)
7979
.as_bool()
8080
{
81-
let mut token_user = Security::TOKEN_USER::default();
81+
let mut info_buf = Vec::<u8>::new();
82+
info_buf.reserve_exact(len as usize);
8283
if Security::GetTokenInformation(
83-
&handle,
84+
handle,
8485
Security::TokenUser,
85-
&mut token_user as *mut _ as *mut std::ffi::c_void,
86+
info_buf.as_mut_ptr() as *mut std::ffi::c_void,
8687
len,
8788
&mut len,
8889
)
@@ -91,16 +92,13 @@ pub mod identity {
9192
// NOTE: we avoid to copy the sid or cache it in any way for now, even though it should be possible
9293
// with a custom allocation/vec/box and it's just very raw. Can the `windows` crate do better?
9394
// When/If yes, then let's improve this.
94-
if Security::IsValidSid(token_user.User.Sid).as_bool() {
95-
use std::os::windows::ffi::OsStrExt;
96-
let mut wide_path: Vec<_> = path.as_ref().as_os_str().encode_wide().collect();
97-
// err = GetNamedSecurityInfoW(wpath, SE_FILE_OBJECT,
98-
// OWNER_SECURITY_INFORMATION |
99-
// DACL_SECURITY_INFORMATION,
100-
// &sid, NULL, NULL, NULL, &descriptor);
95+
// It should however be possible to create strings from SIDs, check this once more.
96+
let info: *const Security::TOKEN_USER = std::mem::transmute(info_buf.as_ptr());
97+
if Security::IsValidSid((*info).User.Sid).as_bool() {
98+
let wide_path = to_wide_path(&path);
10199
let mut path_sid = PSID::default();
102100
let res = Security::Authorization::GetNamedSecurityInfoW(
103-
windows::core::PCWSTR(wide_path.as_mut_ptr()),
101+
windows::core::PCWSTR(wide_path.as_ptr()),
104102
SE_FILE_OBJECT,
105103
Security::OWNER_SECURITY_INFORMATION | Security::DACL_SECURITY_INFORMATION,
106104
&mut path_sid,
@@ -111,18 +109,19 @@ pub mod identity {
111109
);
112110

113111
if res == ERROR_SUCCESS.0 && Security::IsValidSid(path_sid).as_bool() {
114-
is_owned = Security::EqualSid(path_sid, token_user.User.Sid).as_bool();
112+
is_owned = Security::EqualSid(path_sid, (*info).User.Sid).as_bool();
113+
dbg!(is_owned, path.as_ref());
115114
} else {
116-
err_msg = "couldn't get owner for path or it wasn't valid".into();
115+
err_msg = format!("couldn't get owner for path or it wasn't valid: {}", res).into();
117116
}
118117
} else {
119-
err_msg = "owner id of current process wasn't set or valid".into();
118+
err_msg = String::from("owner id of current process wasn't set or valid").into();
120119
}
121120
} else {
122-
err_msg = "Could not get information about the token user".into();
121+
err_msg = String::from("Could not get information about the token user").into();
123122
}
124123
} else {
125-
err_msg = "Could not get token information for length of token user".into();
124+
err_msg = String::from("Could not get token information for length of token user").into();
126125
}
127126
CloseHandle(handle);
128127
if !descriptor.is_invalid() {
@@ -131,5 +130,12 @@ pub mod identity {
131130
}
132131
err_msg.map(|msg| Err(err(msg))).unwrap_or(Ok(is_owned))
133132
}
133+
134+
fn to_wide_path(path: &Path) -> Vec<u16> {
135+
use std::os::windows::ffi::OsStrExt;
136+
let mut wide_path: Vec<_> = path.as_os_str().encode_wide().collect();
137+
wide_path.push(0);
138+
wide_path
139+
}
134140
}
135141
}

git-sec/tests/identity/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ mod uid {
22
#[test]
33
fn from_path() -> crate::Result {
44
let dir = tempfile::tempdir()?;
5+
let file = dir.path().join("file");
6+
std::fs::write(&file, &[])?;
7+
assert!(git_sec::identity::is_path_owned_by_current_user(file.into())?);
58
assert!(git_sec::identity::is_path_owned_by_current_user(dir.path().into())?);
69
Ok(())
710
}

0 commit comments

Comments
 (0)