copy local machine from remote machine shared folders can'work
Bug Description
We have a RustDesk Server Pro 1.4.6 running in docker. Our problem: I connect to a machine (win10-11) that has multiple shares, I can copy/move files from my own machine to these shared folders without any problems. However, if I want to copy anything from these shares to my own machine, it doesn't work, the download doesn't even start. However, it doesn't work in the file transfer window either. However, if I copy from the C: drive of the remote machine to my own machine, it works fine.
I read the forums and found the same problem, but I couldn't find a solution.
We reviewed the rustdeskserver settings, firewall rules, ports, and we also reviewed the installer generated with the server. We didn't find any problems anywhere.
I would like to ask for your help in solving this problem.
How to Reproduce
TI tested it in several ways. I checked the settings. I suspected the ports at first. But I found everything fine.
Expected Behavior
It would be nice if it worked to copy from shared folders to your own computer via the file transfer window. Maybe drag&drop could work, like in teamviewer.
Operating system(s) on local (controlling) side and remote (controlled) side
windows10-11 <----> windows10-11
RustDesk Version(s) on local (controlling) side and remote (controlled) side
RustDesk Server Pro 1.4.6
Screenshots
Additional Context
No response
https://github.com/rustdesk/rustdesk/discussions/1948
Copilot mentioned this.
While the cm process runs as the logged-in user, some file operations may
execute in worker threads that don't properly inherit the user security context.
The impersonation ensures all file operations run with the active user's
credentials, giving access to network shares and mapped drives.
But why writing is ok, reading needs impersonation? It seems not make sense.
diff --git a/src/platform/windows.rs b/src/platform/windows.rs
index b5663c26c..116a692e5 100644
--- a/src/platform/windows.rs
+++ b/src/platform/windows.rs
@@ -3658,6 +3658,70 @@ pub(super) fn get_pids_with_first_arg_by_wmic<S1: AsRef<str>, S2: AsRef<str>>(
.unwrap_or_default()
}
+/// RAII guard that impersonates the active console user and reverts on drop.
+/// This allows the service (running as SYSTEM) to access user-specific resources
+/// like network-mapped drives and network shares.
+pub struct ImpersonateUser {
+ impersonated: bool,
+}
+
+impl ImpersonateUser {
+ pub fn new() -> Self {
+ let impersonated = unsafe { impersonate_active_user() };
+ if !impersonated {
+ log::warn!("Failed to impersonate active user, file operations may fail for network shares");
+ }
+ Self { impersonated }
+ }
+}
+
+impl Drop for ImpersonateUser {
+ fn drop(&mut self) {
+ if self.impersonated {
+ unsafe {
+ use winapi::um::securitybaseapi::RevertToSelf;
+ RevertToSelf();
+ }
+ }
+ }
+}
+
+#[link(name = "secur32")]
+extern "system" {
+ fn ImpersonateLoggedOnUser(hToken: HANDLE) -> BOOL;
+}
+
+unsafe fn impersonate_active_user() -> bool {
+ use winapi::um::winbase::WTSGetActiveConsoleSessionId;
+
+ let session_id = WTSGetActiveConsoleSessionId();
+ if session_id == 0xFFFFFFFF {
+ log::debug!("No active console session");
+ return false;
+ }
+
+ let mut token: HANDLE = std::ptr::null_mut();
+ let mut token_pid: DWORD = 0;
+
+ // Get user token for the active session
+ if GetSessionUserTokenWin(&mut token, session_id, TRUE, &mut token_pid) == FALSE {
+ log::error!("Failed to get user token for session {}: {}", session_id, io::Error::last_os_error());
+ return false;
+ }
+
+ // Impersonate the user
+ let result = ImpersonateLoggedOnUser(token);
+ CloseHandle(token);
+
+ if result == FALSE {
+ log::error!("ImpersonateLoggedOnUser failed: {}", io::Error::last_os_error());
+ return false;
+ }
+
+ log::debug!("Successfully impersonated user from session {}", session_id);
+ true
+}
+
#[cfg(test)]
mod tests {
use super::*;
spawn_blocking(move || {
// Impersonate the active user to access network shares and mapped drives
let _guard = crate::platform::windows::ImpersonateUser::new();
fs::read_dir(&path, include_hidden)
})
@biroszabolcs @DonnEdwards
Hello, I can successfully read and write to the shared folder during file transfers. The only problem is that the network drive cannot be detected. I'm not sure if my test scenario matches what you did. Please let me know if there are any differences.
Both versions are 1.4.4, so the number probably doesn't matter.
https://github.com/user-attachments/assets/c2219725-77b6-43ab-9b09-773e43deb37d
We accidentally find some clue about this. Will let you test and verify.