From a535a6625b6a07ee7f3d03b380b4c229f6d196bb Mon Sep 17 00:00:00 2001 From: Esdras Renan Date: Wed, 12 Nov 2025 11:43:07 -0300 Subject: [PATCH] feat: support LocalSystem RustDesk profile auto-fix --- apps/desktop/src-tauri/src/rustdesk.rs | 75 +++++++++++++++++++------- 1 file changed, 56 insertions(+), 19 deletions(-) diff --git a/apps/desktop/src-tauri/src/rustdesk.rs b/apps/desktop/src-tauri/src/rustdesk.rs index bffa15b..ef288ee 100644 --- a/apps/desktop/src-tauri/src/rustdesk.rs +++ b/apps/desktop/src-tauri/src/rustdesk.rs @@ -26,6 +26,7 @@ const DEFAULT_PASSWORD: &str = "FMQ9MA>e73r.FI> = Lazy::new(|| Mutex::new(())); @@ -64,9 +65,9 @@ pub fn ensure_rustdesk( let _guard = PROVISION_MUTEX.lock(); log_event("Iniciando preparo do RustDesk"); - if let Err(error) = ensure_localservice_writable_preflight() { + if let Err(error) = ensure_service_profiles_writable_preflight() { log_event(&format!( - "Aviso: não foi possível preparar ACL do LocalService ({error}). Continuando mesmo assim; o serviço pode não aplicar a senha." + "Aviso: não foi possível preparar ACL dos perfis do serviço ({error}). Continuando mesmo assim; o serviço pode não aplicar a senha." )); } @@ -381,8 +382,8 @@ fn ensure_service_running() -> Result<(), RustdeskError> { match start_sequence() { Ok(_) => Ok(()), Err(RustdeskError::CommandFailed { command: _, status: Some(5), .. }) => { - log_event("SC retornou acesso negado; tentando ajustar ACL do LocalService..."); - fix_localservice_acl().map_err(|error| RustdeskError::CommandFailed { + log_event("SC retornou acesso negado; tentando ajustar ACL dos perfis do serviço..."); + ensure_service_profiles_writable_preflight().map_err(|error| RustdeskError::CommandFailed { command: format!("fix_acl ({error})"), status: Some(5), })?; @@ -476,13 +477,22 @@ fn ensure_remote_id_files(id: &str) { fn remote_id_directories() -> Vec { let mut dirs = Vec::new(); dirs.push(program_data_config_dir()); - dirs.push(PathBuf::from(LOCAL_SERVICE_CONFIG)); + for profile in service_profile_dirs() { + dirs.push(profile); + } if let Some(appdir) = user_appdata_config_dir() { dirs.push(appdir); } dirs } +fn service_profile_dirs() -> Vec { + vec![ + PathBuf::from(LOCAL_SERVICE_CONFIG), + PathBuf::from(LOCAL_SYSTEM_CONFIG), + ] +} + fn ensure_password_files(secret: &str) -> Result<(), String> { let mut errors = Vec::new(); @@ -630,9 +640,10 @@ exit $process.ExitCode Err(format!("elevated ps exit {:?}", status.code())) } -fn fix_localservice_acl() -> Result<(), String> { - let target = r"C:\\Windows\\ServiceProfiles\\LocalService\\AppData\\Roaming\\RustDesk\\config"; +fn fix_profile_acl(target: &Path) -> Result<(), String> { + let target_str = target.display().to_string().replace('\', "\\"); let transcript = env::temp_dir().join("raven_acl_ps.log"); + let log_str = transcript.display().to_string().replace('\', "\\"); let script = format!( r#" $ErrorActionPreference='Stop' @@ -656,32 +667,58 @@ try {{ try {{ Stop-Transcript | Out-Null }} catch {{ }} }} "#, - target = target, - log = transcript.display() + target = target_str, + log = log_str ); let result = run_powershell_elevated(&script); if result.is_err() { if let Ok(content) = fs::read_to_string(&transcript) { - log_event(&format!("ACL transcript:\n{content}")); + log_event(&format!( + "ACL transcript para {}:\n{}", + target.display(), content + )); } } let _ = fs::remove_file(&transcript); result } -fn ensure_localservice_writable_preflight() -> Result<(), String> { - let dir = PathBuf::from(LOCAL_SERVICE_CONFIG); - if can_write_dir(&dir) { - return Ok(()); +fn ensure_service_profiles_writable_preflight() -> Result<(), String> { + let mut success = false; + let mut last_error: Option = None; + + for dir in service_profile_dirs() { + if can_write_dir(&dir) { + success = true; + continue; + } + log_event(&format!( + "Tentando corrigir ACL via UAC (preflight) em {}...", + dir.display() + )); + if let Err(error) = fix_profile_acl(&dir) { + last_error = Some(error); + continue; + } + if can_write_dir(&dir) { + log_event(&format!( + "ACL ajustada com sucesso em {}", + dir.display() + )); + success = true; + } else { + last_error = Some(format!( + "continua sem permissão para {} mesmo após preflight", + dir.display() + )); + } } - log_event("Tentando corrigir ACL do perfil LocalService via UAC (preflight)..."); - fix_localservice_acl()?; - if can_write_dir(&dir) { - log_event("ACL do LocalService ajustada com sucesso."); + + if success { Ok(()) } else { - Err("continua sem permissão para LocalService (após preflight)".into()) + Err(last_error.unwrap_or_else(|| "nenhum perfil de serviço acessível".into())) } }