rustdesk/rustdesk · error · io::Error

failed to build portable service listener security attribute

Error message

failed to build portable service listener security attributes from SDDL '{}': {}

What it means

The DACL SDDL string 'D:P(A;;GA;;;SY)(A;;GA;;;<user_sid>)' (protected DACL; GENERIC_ALL for LocalSystem and the current user) is converted into SECURITY_ATTRIBUTES via SecurityAttributes::from_sddl. This error means that conversion failed, and includes both the SDDL and the underlying error.

Source

Thrown at src/ipc/auth.rs:64

    })?;
    debug_assert!(
        user_sid.starts_with("S-1-")
            && user_sid
                .bytes()
                .all(|byte| byte.is_ascii_digit() || byte == b'-'),
        "current_process_user_sid_string returned a non-SDDL SID: {}",
        user_sid
    );
    // SDDL:
    // - `D:P`                => protected DACL (no inherited ACEs)
    // - `(A;;GA;;;SY)`       => allow GENERIC_ALL to LocalSystem
    // - `(A;;GA;;;{user_sid})` => allow GENERIC_ALL to current process user SID
    // References:
    // - Security Descriptor String Format: https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format
    // - ACE strings in SDDL: https://learn.microsoft.com/en-us/windows/win32/secauthz/ace-strings
    let sddl = format!("D:P(A;;GA;;;SY)(A;;GA;;;{user_sid})");
    SecurityAttributes::from_sddl(&sddl).map_err(|err| {
        io::Error::new(
            io::ErrorKind::Other,
            format!(
                "failed to build portable service listener security attributes from SDDL '{}': {}",
                sddl, err
            ),
        )
    })
}

#[cfg(target_os = "macos")]
#[inline]
fn macos_service_ipc_allows_gui_and_service_binaries(
    peer_exe: &Path,
    current_exe: &Path,
    postfix: &str,
) -> bool {
    if postfix != crate::POSTFIX_SERVICE {
        return false;

View on GitHub (pinned to 7aa98d43cf)

Solutions

  1. Copy the SDDL from the message and validate it with PowerShell: New-Object System.Security.AccessControl.RawSecurityDescriptor('<sddl>')
  2. Check the appended inner error for the exact Win32 failure
  3. Verify the account's SID is well-formed: whoami /user
  4. If the SID string is malformed, fix current_process_user_sid_string rather than the SDDL template
Defensive patterns

Strategy: validation

Validate before calling

# Validate the exact SDDL before shipping changes to it (PowerShell)
New-Object System.Security.AccessControl.RawSecurityDescriptor `
  'D:P(A;;GA;;;SY)(A;;GA;;;S-1-5-21-1004336348-1177238915-682003330-512)'

Try / catch

if let Err(e) = SecurityAttributes::from_sddl(&sddl) {
    log::error!("SDDL rejected: '{sddl}': {e}");
    return Err(e); // fail closed — no permissive fallback
}

Prevention

When it happens

Trigger: The SID string embedded in the SDDL is malformed (non-SDDL characters — the debug_assert above checks 'S-1-...' digits/dashes), or ConvertStringSecurityDescriptorToSecurityDescriptor failed from memory/parameter errors.

Common situations: current_process_user_sid_string returning an unexpected format (logon SIDs or placeholder output); downlevel Windows rejecting the SDDL flags; corrupted user account SID.

Related errors


AI-assisted analysis of rustdesk/rustdesk@7aa98d43cf (2026-08-16). Data as JSON: /api/errors/b8d08629c362719a. Report an issue: GitHub.