{"record":{"id":"ef520e4e02579105","repo":"rustdesk/rustdesk","slug":"failed-to-resolve-current-process-sid","errorCode":null,"errorMessage":"failed to resolve current process SID: {}","messagePattern":"failed to resolve current process SID: (.+?)","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"src/ipc/auth.rs","lineNumber":42,"sourceCode":"use std::{\n    fs,\n    path::{Path, PathBuf},\n    sync::{Mutex, OnceLock},\n};\n#[cfg(windows)]\nuse windows::Win32::{Foundation::HANDLE, System::Pipes::GetNamedPipeClientProcessId};\n\n#[cfg(windows)]\n#[inline]\npub(crate) fn should_allow_everyone_create_on_windows(postfix: &str) -> bool {\n    postfix.is_empty() || hbb_common::config::is_service_ipc_postfix(postfix)\n}\n\n#[cfg(windows)]\n#[inline]\npub(crate) fn portable_service_listener_security_attributes() -> io::Result<SecurityAttributes> {\n    let user_sid = crate::platform::windows::current_process_user_sid_string().map_err(|err| {\n        io::Error::new(\n            io::ErrorKind::Other,\n            format!(\"failed to resolve current process SID: {}\", err),\n        )\n    })?;\n    debug_assert!(\n        user_sid.starts_with(\"S-1-\")\n            && user_sid\n                .bytes()\n                .all(|byte| byte.is_ascii_digit() || byte == b'-'),\n        \"current_process_user_sid_string returned a non-SDDL SID: {}\",\n        user_sid\n    );\n    // SDDL:\n    // - `D:P`                => protected DACL (no inherited ACEs)\n    // - `(A;;GA;;;SY)`       => allow GENERIC_ALL to LocalSystem\n    // - `(A;;GA;;;{user_sid})` => allow GENERIC_ALL to current process user SID\n    // References:\n    // - Security Descriptor String Format: https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/rustdesk/rustdesk/blob/7aa98d43cf1962a7a29ec16ffef42974377ef11e/src/ipc/auth.rs#L24-L60","documentation":"On Windows, the portable-service IPC listener builds a restrictive DACL, and first resolves the current process user's SID via current_process_user_sid_string() (token → TokenUser → SID → SDDL string). This error wraps a failure anywhere in that chain, before any SDDL is constructed.","triggerScenarios":"OpenProcessToken or GetTokenInformation failing: process token inaccessible, an impersonation/restricted token without normal user groups, or the SID-to-string conversion failing.","commonSituations":"Running under unusual token contexts (job objects, sandboxed restricted tokens, some service hosts); privileges stripped from the process; security software interfering with token queries.","solutions":["Read the appended inner error ('err') to see which step failed","Run the process with a normal interactive-user or LocalSystem token","Avoid launching the binary from restricted/sandboxed parents","If it persists, capture a token dump with whoami /all in the same context to verify the token exposes a user SID"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Smoke-test SID resolution before building the listener\nlet sid = rustdesk::platform::windows::current_process_user_sid_string()\n    .map_err(|e| log::error!(\"SID lookup failed: {e}\"))?;\nassert!(sid.starts_with(\"S-1-\"));","typeGuard":null,"tryCatchPattern":"match portable_service_listener_security_attributes() {\n    Err(e) if e.to_string().contains(\"SID\") => {\n        // run in normal user context and retry; do not silently fall back to a NULL DACL\n        return Err(e);\n    }\n    r => r,\n}","preventionTips":["Do not launch RustDesk from restricted/sandboxed token contexts","Never fall back to a permissive security descriptor when SID resolution fails — fail closed","Test IPC listener startup as both normal user and service account in CI"],"tags":["windows","security","ipc","named-pipe"],"backgroundTag":null,"analyzedSha":"7aa98d43cf1962a7a29ec16ffef42974377ef11e","analyzedAt":"2026-08-16T06:17:34.842Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}