fix: improve RustDesk ACL automation

This commit is contained in:
Esdras Renan 2025-11-12 11:25:24 -03:00
parent 5105d2cfed
commit 2339d5010f

View file

@ -266,6 +266,7 @@ fn write_config_files() -> Result<PathBuf, RustdeskError> {
)); ));
let service_profile = PathBuf::from(LOCAL_SERVICE_CONFIG).join("RustDesk2.toml"); let service_profile = PathBuf::from(LOCAL_SERVICE_CONFIG).join("RustDesk2.toml");
let _ = ensure_localservice_writable_preflight();
if let Err(error) = write_file(&service_profile, &config_contents) { if let Err(error) = write_file(&service_profile, &config_contents) {
log_event(&format!( log_event(&format!(
"Falha ao gravar config no perfil do serviço: {error}" "Falha ao gravar config no perfil do serviço: {error}"
@ -534,22 +535,18 @@ fn propagate_password_profile() -> io::Result<bool> {
"Copiando {} para ProgramData/LocalService", "Copiando {} para ProgramData/LocalService",
src_path.display() src_path.display()
)); ));
let contents = fs::read(&src_path)?;
let mut propagated = false;
for dest_root in [program_data_config_dir(), PathBuf::from(LOCAL_SERVICE_CONFIG)] { for dest_root in [program_data_config_dir(), PathBuf::from(LOCAL_SERVICE_CONFIG)] {
let target_path = dest_root.join("RustDesk.toml"); let target_path = dest_root.join("RustDesk.toml");
if let Some(parent) = target_path.parent() { copy_overwrite(&src_path, &target_path)?;
fs::create_dir_all(parent)?;
}
if target_path.is_dir() {
fs::remove_dir_all(&target_path)?;
}
fs::write(&target_path, &contents)?;
log_event(&format!( log_event(&format!(
"RustDesk.toml propagado para {}", "RustDesk.toml propagado para {}",
target_path.display() target_path.display()
)); ));
propagated = true;
} }
Ok(true) Ok(propagated)
} }
fn replicate_password_artifacts() -> io::Result<()> { fn replicate_password_artifacts() -> io::Result<()> {
@ -575,10 +572,7 @@ fn replicate_password_artifacts() -> io::Result<()> {
} }
let target_path = dest.join(name); let target_path = dest.join(name);
if target_path.is_dir() { copy_overwrite(&source_path, &target_path)?;
fs::remove_dir_all(&target_path)?;
}
fs::copy(&source_path, &target_path)?;
log_event(&format!( log_event(&format!(
"Artefato de senha {name} replicado para {}", "Artefato de senha {name} replicado para {}",
target_path.display() target_path.display()
@ -638,22 +632,42 @@ exit $process.ExitCode
fn fix_localservice_acl() -> Result<(), String> { fn fix_localservice_acl() -> Result<(), String> {
let target = r"C:\\Windows\\ServiceProfiles\\LocalService\\AppData\\Roaming\\RustDesk\\config"; let target = r"C:\\Windows\\ServiceProfiles\\LocalService\\AppData\\Roaming\\RustDesk\\config";
let transcript = env::temp_dir().join("raven_acl_ps.log");
let script = format!( let script = format!(
r#" r#"
$ErrorActionPreference = 'Stop' $ErrorActionPreference='Stop'
if (-not (Test-Path '{target}')) {{ New-Item -ItemType Directory -Force -Path '{target}' | Out-Null }} Start-Transcript -Path '{log}' -Force
$admins = (New-Object Security.Principal.SecurityIdentifier('S-1-5-32-544')).Translate([Security.Principal.NTAccount]).Value try {{
$localSvc = (New-Object Security.Principal.SecurityIdentifier('S-1-5-19')).Translate([Security.Principal.NTAccount]).Value if (-not (Test-Path '{target}')) {{ New-Item -ItemType Directory -Force -Path '{target}' | Out-Null }}
takeown /F '{target}' /R /D Y | Out-Null
if ($LASTEXITCODE -ne 0) {{ $take = $LASTEXITCODE }} else {{ $take = 0 }} & takeown /F '{target}' /R /D Y
icacls '{target}' /grant "${{admins}}":(OI)(CI)F "${{localSvc}}":(OI)(CI)F /T /C | Out-Null $takeCode = $LASTEXITCODE
$ica = $LASTEXITCODE
if (($take -eq 0) -and ($ica -in 0,1)) {{ exit 0 }} & icacls '{target}' /grant '*S-1-5-32-544:(OI)(CI)F' '*S-1-5-19:(OI)(CI)F' /T /C /Q
if ($ica -ne 0) {{ exit $ica }} $icaCode = $LASTEXITCODE
exit $take
"# if (($takeCode -eq 0) -and ($icaCode -in 0,1)) {{ exit 0 }}
if ($icaCode -ne 0) {{ exit $icaCode }}
exit $takeCode
}} catch {{
Write-Host ("exception: " + ($_.Exception.Message))
exit 1
}} finally {{
try {{ Stop-Transcript | Out-Null }} catch {{ }}
}}
"#,
target = target,
log = transcript.display()
); );
run_powershell_elevated(&script)
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}"));
}
}
let _ = fs::remove_file(&transcript);
result
} }
fn ensure_localservice_writable_preflight() -> Result<(), String> { fn ensure_localservice_writable_preflight() -> Result<(), String> {
@ -821,6 +835,19 @@ fn hidden_command(program: impl AsRef<OsStr>) -> Command {
cmd cmd
} }
fn copy_overwrite(src: &Path, dst: &Path) -> io::Result<()> {
if let Some(parent) = dst.parent() {
fs::create_dir_all(parent)?;
}
if dst.is_dir() {
fs::remove_dir_all(dst)?;
} else if dst.exists() {
fs::remove_file(dst)?;
}
fs::copy(src, dst)?;
Ok(())
}
fn log_event(message: impl AsRef<str>) { fn log_event(message: impl AsRef<str>) {
if let Some(dir) = logs_directory() { if let Some(dir) = logs_directory() {
if let Err(error) = append_log(dir, message.as_ref()) { if let Err(error) = append_log(dir, message.as_ref()) {