From fbaeef858966f30dfa64960daa27977a20f23b4f Mon Sep 17 00:00:00 2001 From: Alexey Chernyshov Date: Thu, 30 Jul 2020 19:22:19 +0300 Subject: [PATCH] Do not check readonly on network locations (#1506) Do not try to analyze if the current process can write network location on Windows. There's no way on Windows to tell if we can write a network location because it's not being controlled by the OS itself. Thus now the lock symbol is never shown on network locations. This PR introduces a new unsafe call. --- src/modules/directory.rs | 2 +- src/modules/utils/directory_win.rs | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/modules/directory.rs b/src/modules/directory.rs index a2c397f1d..51297bd4b 100644 --- a/src/modules/directory.rs +++ b/src/modules/directory.rs @@ -107,7 +107,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { .map(|variable| match variable { "path" => Some(Ok(&final_dir_string)), "read_only" => { - if is_readonly_dir(current_dir.to_str()?) { + if is_readonly_dir(context.current_dir.to_str()?) { Some(Ok(&lock_symbol)) } else { None diff --git a/src/modules/utils/directory_win.rs b/src/modules/utils/directory_win.rs index 6574be555..decf1eb97 100644 --- a/src/modules/utils/directory_win.rs +++ b/src/modules/utils/directory_win.rs @@ -10,21 +10,31 @@ use winapi::um::handleapi; use winapi::um::processthreadsapi; use winapi::um::securitybaseapi; use winapi::um::winnt::{ - SecurityImpersonation, DACL_SECURITY_INFORMATION, FILE_ALL_ACCESS, FILE_GENERIC_EXECUTE, - FILE_GENERIC_READ, FILE_GENERIC_WRITE, GENERIC_MAPPING, GROUP_SECURITY_INFORMATION, HANDLE, - OWNER_SECURITY_INFORMATION, PRIVILEGE_SET, PSECURITY_DESCRIPTOR, STANDARD_RIGHTS_READ, - TOKEN_DUPLICATE, TOKEN_IMPERSONATE, TOKEN_QUERY, + SecurityImpersonation, BOOLEAN, DACL_SECURITY_INFORMATION, FILE_ALL_ACCESS, + FILE_GENERIC_EXECUTE, FILE_GENERIC_READ, FILE_GENERIC_WRITE, GENERIC_MAPPING, + GROUP_SECURITY_INFORMATION, HANDLE, LPCWSTR, OWNER_SECURITY_INFORMATION, PRIVILEGE_SET, + PSECURITY_DESCRIPTOR, STANDARD_RIGHTS_READ, TOKEN_DUPLICATE, TOKEN_IMPERSONATE, TOKEN_QUERY, }; /// Checks if the current user has write access right to the `folder_path` /// /// First, the function extracts DACL from the given directory and then calls `AccessCheck` against /// the current process access token and directory's security descriptor. +/// Does not work for network drives and always returns true pub fn is_write_allowed(folder_path: &str) -> std::result::Result { let folder_name: Vec = OsStr::new(folder_path) .encode_wide() .chain(iter::once(0)) .collect(); + + if is_network_path(&folder_name) { + log::info!( + "Directory '{:?}' is a network drive, unable to check write permissions. See #1506 for details", + folder_path + ); + return Ok(true); + } + let mut length: DWORD = 0; let rc = unsafe { @@ -115,3 +125,12 @@ pub fn is_write_allowed(folder_path: &str) -> std::result::Result BOOLEAN; +} + +fn is_network_path(folder_path: &Vec) -> bool { + return unsafe { PathIsNetworkPathW(folder_path.as_ptr()) } == 1; +}