From 77f88f2aa61986e71c82ad87d350ee9e96e31a67 Mon Sep 17 00:00:00 2001 From: Esdras Renan Date: Wed, 12 Nov 2025 10:30:09 -0300 Subject: [PATCH] fix: add localservice ACL preflight --- apps/desktop/src-tauri/src/rustdesk.rs | 42 ++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/apps/desktop/src-tauri/src/rustdesk.rs b/apps/desktop/src-tauri/src/rustdesk.rs index d407c46..515600c 100644 --- a/apps/desktop/src-tauri/src/rustdesk.rs +++ b/apps/desktop/src-tauri/src/rustdesk.rs @@ -379,7 +379,7 @@ fn ensure_service_running() -> Result<(), RustdeskError> { match start_sequence() { Ok(_) => Ok(()), - Err(RustdeskError::CommandFailed { command, status: Some(5), .. }) => { + 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 { command: format!("fix_acl ({error})"), @@ -584,8 +584,6 @@ fn replicate_password_artifacts() -> io::Result<()> { } fn run_powershell_elevated(script: &str) -> Result<(), String> { - use std::io::Write; - let temp_dir = env::temp_dir(); let payload = temp_dir.join("raven_payload.ps1"); fs::write(&payload, script).map_err(|error| format!("write payload: {error}"))?; @@ -644,6 +642,44 @@ icacls '{target}' /grant "${{admins}}":(OI)(CI)F "${{localSvc}}":(OI)(CI)F /T /C run_powershell_elevated(&script) } +fn ensure_localservice_writable_preflight() -> Result<(), String> { + let dir = PathBuf::from(LOCAL_SERVICE_CONFIG); + if can_write_dir(&dir) { + return Ok(()); + } + 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."); + Ok(()) + } else { + Err("continua sem permissão para LocalService (após preflight)".into()) + } +} + +fn can_write_dir(dir: &Path) -> bool { + if fs::create_dir_all(dir).is_err() { + return false; + } + let probe = dir.join(".raven_acl_probe"); + match OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(&probe) + { + Ok(mut file) => { + if file.write_all(b"ok").is_err() { + let _ = fs::remove_file(&probe); + return false; + } + let _ = fs::remove_file(&probe); + true + } + Err(_) => false, + } +} + fn write_remote_id_value(path: &Path, id: &str) -> io::Result<()> { if let Some(parent) = path.parent() { fs::create_dir_all(parent)?;