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

时间:2019-02-26 22:09:56

标签: c++ windows winapi sid

我正在尝试将SID转换为字符串,然后使用ConvertSidToStringSidConvertStringSidToSid重新转换,但是转换失败,错误代码为1337。

我创建的测试SID无法进行往返-导致ConvertStringSidToSid失败,代码为1337(ERROR_INVALID_SID)。看起来Windows似乎使用十六进制(而不是十进制)在字符串表示形式和ConvertStringSidToSid扼流圈中使用太多字节来表示标识符授权。上面链接的ConvertStringSidToSid文档说:“您可以使用此函数来检索ConvertSidToStringSid函数转换为字符串格式的SID”,这表明应该支持我尝试做的事情。是否有更好的方法将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

2 个答案:

答案 0 :(得分:3)

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

  

nSubAuthorityCount

     

指定要放置在SID中的子机构的数量。此参数还标识有多少子权限参数具有有意义的值。此参数的值必须介于1到8之间。

  

S-R-I-S

     

在此符号中,文字字符“ S”将数字序列标识为SID, R 是修订级别, I 是标识符授权值,和 S …是一个或多个子权限值。

即使0返回了AllocateAndInitializeSid,也可能是疏忽,但传递TRUE是错误的。

ConvertSidToStringSidW似乎也没有检查该要求,这就是转换成功的原因。 ConvertStringSidToSidW之所以失败,是因为它期望使用以下格式的字符串: S- R - I - S

答案 1 :(得分:1)

您错过了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;
}