Windows-rs: How to build a PSID to call CreateWellKnownSid

Created on 20 Jun 2021  路  6Comments  路  Source: microsoft/windows-rs

Hi!

I am trying to port a project of mine from winapi to windows-rs and could not find example code or documentation to call CreateWellKnownSid correctly.

Here is what I tried:

fn main() {

    const SECURITY_MAX_SID_SIZE : isize = 68isize;
    const WinBuiltinAdministratorsSid : WELL_KNOWN_SID_TYPE = WELL_KNOWN_SID_TYPE(26i32);

    unsafe {
        let mut admin_sid = PSID(SECURITY_MAX_SID_SIZE);
        let mut sid_size = (std::mem::size_of::<u8>() as u32 * SECURITY_MAX_SID_SIZE as u32);
        let domain_sid = PSID::NULL;

        if CreateWellKnownSid(WinBuiltinAdministratorsSid, domain_sid, admin_sid, &mut sid_size) == BOOL(0) {
            println!("CreateWellKnownSid failed {:?}", GetLastError());
        }
        else {
            println!("CreateWellKnownSid succeeded");
        }
    }
}

As is, this code just does an access violation because my "admin_sid" parameter is all but correctly initialised.
It seems the issue is with this third argument (that should be 'out' but is only PSID in metadata).

Complete repro:
create_well_known_sid.zip

Thank you for bringing "officially" the breadth of Windows APIs to Rust!

question

All 6 comments

The pSid parameter has the [Out] attribute in the metadata referenced by version 0.11.0 of this crate:

psid

Are you using an older version of the windows crate?

Nope, I tested with 0.11.0 (latest).
I surely miss something to allocate this parameter properly pior to calling this API.

The trick is that CreateWellKnownSid doesn't allocate the SID - it expects the caller to provide a buffer and it will dutifully fill in that buffer. Here's an example:

use bindings::{Windows::Win32::Foundation::*, Windows::Win32::Security::*};

fn main() -> windows::Result<()> {
    unsafe {
        let buffer: [u8; 32] = [0; 32];
        let mut buffer_len = buffer.len() as u32;
        let sid = PSID(buffer.as_ptr() as _);

        CreateWellKnownSid(
            WinBuiltinAdministratorsSid,
            PSID::NULL,
            sid,
            &mut buffer_len,
        )
        .ok()?;

        assert_eq!(GetLengthSid(sid), buffer_len);
        println!("length: {}", buffer_len);
        println!("{:?}", buffer);

        Ok(())
    }
}

Also, you may be interested in the windows-permissions crate, which abstracts away Sid handling behind a safe API. Though it uses winapi and not windows-rs for its bindings.

Somebody should port it. 馃槈

Verified solved with your great help!
Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ZCWorks picture ZCWorks  路  3Comments

DJankauskas picture DJankauskas  路  3Comments

kennykerr picture kennykerr  路  5Comments

ctaggart picture ctaggart  路  4Comments

AyashiNoCeres picture AyashiNoCeres  路  4Comments