使用 LookupAccountName 时访问冲突写入位置 0x00000000

2024-04-05

创建用户帐户后NetUserAdd,我发现我需要使用NetLocalGroupAddMembers将用户添加到 Users 组,所以我调用CreateWellKnownSid获取用户的 SID,LookupAccountSid 从该 SID 获取字符串名称并将其传递给NetLocalGroupAddMembers.

我还需要指定用户名,但是需要的功能域名\名称格式为level 3 (LOCALGROUP_MEMBERS_INFO_3),但我没有。我决定打电话LookupAccountName获取用户名SID并将其传递给level 0 (LOCALGROUP_MEMBERS_INFO_0).

我就是这样做的:

//LocalAlloc
    UINT memAttributes = LMEM_FIXED;
    SIZE_T sidSize = SECURITY_MAX_SID_SIZE;

//LookupAccountName
    PSID accountSID;
    SID_NAME_USE typeOfAccount;

//NetLocalGroupAddMembers
    NET_API_STATUS localGroupAdd;
    DWORD levelOfData = 0;  //LOCALGROUP_MEMBERS_INFO_0
    LOCALGROUP_MEMBERS_INFO_0 localMembers;
    DWORD totalEntries = 0;



//Allocate memory for LookupAccountName
        if (!(accountSID = LocalAlloc(memAttributes, sidSize)))
        {
            wprintf(L"\nMemory allocation for account SID failed: \n");
            ShowError(GetLastError());
            exit(1);

        }


if (!LookupAccountNameW(NULL, argv[1], accountSID,
                                    (LPDWORD)&sidSize, NULL, 0, &typeOfAccount))
            {
                fwprintf(stderr, L"Error getting SID from name: \n");
                ShowError(GetLastError());
                return 1;

            }

//Here I should be able to use NetLocalGroupAddMembers
            //to add the user passed as argument to the Users group. 
            localMembers.lgrmi0_sid = accountSID;

            localGroupAdd = NetLocalGroupAddMembers(NULL, name, levelOfData, (LPBYTE)&localMembers, totalEntries);

            if (localGroupAdd != NERR_Success)
            {
                fwprintf(stderr, L"Error adding member to the local group: \n");
                ShowError(GetLastError());
                return 1;
            }
            else
            {
                wprintf(L"\nUser %s has been successfully added.\n", argv[1]);

            }

这是我收到的错误:

UserCreator.exe 中的 0x743F059A (sechost.dll) 处抛出异常: 0xC0000005:访问冲突写入位置 0x00000000。

有什么线索吗?


ReferencedDomainName 参数实际上不是可选的。

LPCTSTR machine = NULL, username = /*TEXT("Anders")*/ argv[1];
TCHAR domain[MAX_PATH];
BYTE accountSIDbuf[SECURITY_MAX_SID_SIZE];
PSID accountSID = (PSID) accountSIDbuf;
DWORD cbSid = SECURITY_MAX_SID_SIZE, cchRD = MAX_PATH;
SID_NAME_USE snu;

if (!LookupAccountName(machine, username, accountSID, &cbSid, domain, &cchRD, &snu))
{
    printf("Error %u\n", GetLastError());
    return ;
}

LPTSTR sidstr;
if (!ConvertSidToStringSid(accountSID, &sidstr)) { return ; }
_tprintf(_T("SID of %s\\%s is %s\n"), domain, username, sidstr);
LocalFree(sidstr);

您的代码的另一个问题是ShowError(GetLastError());你不能使用GetLastError()调用其他函数后。重写为

DWORD error = GetLastError();
fwprintf(stderr, L"Error getting SID from name: \n");
ShowError(error);

但在这种情况下,即使这样也是错误的,因为NetLocalGroupAddMembers不打电话SetLastError,它只是直接返回错误代码。

Edit:

只是为了阐明参数用法;如果你想查询域缓冲区所需的大小,你可以这样做:

DWORD cchRD = 0;
LookupAccountName(..., NULL, &cchRD, &snu); // The function is still going to report failure
LPTSTR domain = malloc(cchRD * sizeof(*domain));
LookupAccountName(..., domain, &cchRD, &snu);

在我的示例中,我通过传入“足够大”的缓冲区来避免这种情况。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 LookupAccountName 时访问冲突写入位置 0x00000000 的相关文章

随机推荐