为什么 ConvertStringSidToSid 无法转换字符串 SID?

Why does ConvertStringSidToSid fail to convert a string SID?

我正在尝试使用 ConvertSidToStringSid and ConvertStringSidToSid 将 SID 转换为字符串并再次转换回来,但是转换失败,错误代码为 1337。

我创建的测试 SID 无法进行往返——它导致 ConvertStringSidToSid 失败,代码为 1337 (ERROR_INVALID_SID)。看起来 Windows 在字符串表示中使用十六进制而不是十进制表示具有太多字节的标识符权限,并且 ConvertStringSidToSid 阻塞。上面链接的 ConvertStringSidToSid 文档说 "You can use this function to retrieve a SID that the ConvertSidToStringSid function converted to string format," 这表明应该支持我正在尝试做的事情。是否有更好的方法将 SID 来回转换为字符串表示形式?

这是一个演示问题的最小示例:

#include "pch.h"
#include <iostream>
#include <windows.h>
#include <sddl.h>

int main()
{
    SID_IDENTIFIER_AUTHORITY sid_id_auth = { 1,2,3,4,5,6 };
    PSID sid;
    PSID new_sid;
    LPWSTR string_sid;

    // Create a new SID with the given ID authority and no sub-authorities
    if (!AllocateAndInitializeSid(&sid_id_auth, 0, 0, 0, 0, 0, 0, 0, 0, 0, &sid)) {
        std::cout << "Failed to allocate SID: error code " << GetLastError() << std::endl;
        return 1;
    }

    // Stringify and print
    if (!ConvertSidToStringSidW(sid, &string_sid)) {
        std::cout << "Failed to convert to string: error code " << GetLastError() << std::endl;
        FreeSid(sid);
        return 2;
    }
    std::wcout << string_sid << std::endl;

    // Destringify and print
    if (ConvertStringSidToSidW(string_sid, &new_sid)) {
        std::cout << "Success" << std::endl;
    }
    else {
        std::cout << "Failed: error code " << GetLastError() << std::endl;
    }

    // Clean up
    LocalFree(string_sid);
    LocalFree(new_sid);
    FreeSid(sid);
}

在我的机器上(Windows 10.0.16299,Visual Studio 15.9.7),打印:

S-1-0x10203040506
Failed: error code 1337

您将 nSubAuthorityCount 的无效值传递给 AllocateAndInitializeSid
文档指出:

nSubAuthorityCount

Specifies the number of subauthorities to place in the SID. This parameter also identifies how many of the subauthority parameters have meaningful values. This parameter must contain a value from 1 to 8.

S-R-I-S

In this notation, the literal character "S" identifies the series of digits as a SID, R is the revision level, I is the identifier-authority value, and S… is one or more subauthority values.

因此传递 0 是错误的,即使 AllocateAndInitializeSid returns TRUE 这可能是一个疏忽。

ConvertSidToStringSidW 似乎也没有检查该要求,这就是转换成功的原因。
ConvertStringSidToSidW 失败,因为它需要格式为 S-R-I- 的字符串S.

您错过了 SID components 中的标识符权限值:S-1-0x10203040506。所以你得到 ERROR_INVALID_SID (1337).

添加标识符权限值后,这里我使用SECURITY_NT_AUTHORITY(与Windows well-known SIDs一起使用):5,如下所示。错误解决了。

if (ConvertStringSidToSidW(L"S-1-5-0x10203040506", &new_sid)) {
    std::cout << "Success" << std::endl;
}
else {
    std::cout << "Failed: error code " << GetLastError() << std::endl;
}