CreateWellKnownSid 说 WinAccountAdministratorSid 的参数不正确,但适用于 WinBuiltAdministratorsSid

标签 c windows winapi

我正在尝试使用 CreateWellKnownSid 获取内置管理员帐户的众所周知的 SID,以便我可以在其他功能中使用它,但我得到的是参数不正确使用 WinAccountAdministratorSid 作为第一个参数时的错误消息;但是,如果我使用 WinBuiltinAdministratorsSidWinBuiltinUsersSid 它会起作用。不知道发生了什么。

代码:

#include <Windows.h>
#include <wchar.h>
#include <LM.h>
#include <locale.h>

#pragma comment(lib, "Netapi32.lib")

#define MAX_NAME 256

VOID ShowError(DWORD errorCode)
{
    //FormatMessageW
    DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS;
    LPWSTR errorMessage;
    DWORD size = 0;

    if (!FormatMessageW(flags, NULL, errorCode, 0, (LPWSTR)&errorMessage, size, NULL))
    {
        fwprintf(stderr, L"Could not get the format message, error code: %u\n", GetLastError());
        exit(1);
    }

    wprintf(L"\n%s", errorMessage);

    LocalFree(errorMessage);
}

int wmain(int argc, WCHAR **argv)
{
    _wsetlocale(LC_ALL, L"English");

    //LocalAlloc
    UINT memFlags = LMEM_FIXED; //Allocates fixed memory
    DWORD numOfBytes = SECURITY_MAX_SID_SIZE;
    PSID builtInAdminSid;

    /*Allocating memory to hold the SID for the
    built-in administrator user*/
    if (!(builtInAdminSid = LocalAlloc(memFlags, numOfBytes)))
    {
        ShowError(GetLastError());
        return 1;
    }

    //CreateWellKnownSid
    WELL_KNOWN_SID_TYPE accountAdminSid = WinAccountAdministratorSid;
    PSID domainSid = NULL;

    /*We will ask Windows for the well known Admin SID.
    If this function fails, we cannot continue*/
    if (!CreateWellKnownSid(accountAdminSid, NULL,
                            builtInAdminSid, &numOfBytes))
    {
        ShowError(GetLastError());
        LocalFree(builtInAdminSid); //Do not forget to free memory!
        return 1;

    }


    return 0;
}

我做错了什么吗?

编辑:

似乎我必须指定 DomainSid 参数,但如何为本地计算机检索它?

最佳答案

有时 CreateWellKnownSid 需要 DomainSid 参数,原因很简单 - 它将 DomainSid 与众所周知的 rid 连接起来(向 sid 添加一个 SubAuthority) .

要获取DomainSid,我们可以使用LsaQueryInformationPolicy with PolicyAccountDomainInformation - 检索系统帐户域的名称和 SID。 - 此 api 调用返回 POLICY_ACCOUNT_DOMAIN_INFO DomainSid

存在的结构
#include <Ntsecapi.h>

ULONG CreateSid()
{
    LSA_HANDLE PolicyHandle;

    static LSA_OBJECT_ATTRIBUTES oa = { sizeof(oa) };

    NTSTATUS status = LsaOpenPolicy(0, &oa, POLICY_VIEW_LOCAL_INFORMATION, &PolicyHandle);

    if (0 <= status)
    {
        PPOLICY_ACCOUNT_DOMAIN_INFO ppadi;

        if (0 <= (status = LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (void**)&ppadi)))
        {
            PSID sid = alloca(MAX_SID_SIZE);

            ULONG cbSid = MAX_SID_SIZE;

            if (!CreateWellKnownSid(::WinAccountAdministratorSid, ppadi->DomainSid, sid, &cbSid))
            {
                status = GetLastError();
            }

            LsaFreeMemory(ppadi);
        }

        LsaClose(PolicyHandle);
    }

    return status;
}

关于CreateWellKnownSid 说 WinAccountAdministratorSid 的参数不正确,但适用于 WinBuiltAdministratorsSid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48285213/

相关文章:

Windows 上的 C 模块需要 Linux 系统包含

c++ - 确保内存映射页在内存中

c - 处理来自多个 fread 调用的错误的更简洁的方法

c - 自制fstat获取文件大小,总是返回0长度

windows - cpan 与 -MCPAN - Perl

windows - git (ssh_exchange_identification) 连接由对等方重置(windows、gitlab)

c - 读取 MIDI 文件 (C) : 0x00 appearing after the end of a var-length value

c - Linux线程优先级

c++ - 无法弄清楚如何在 Win32 对话框中托管 Web 浏览器(例如 IWebBrowser2)。 ATL 还行,没有 MFC

c++ - 帮助使用 WinAPI 包装器