使用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。
任何线索?
先谢谢!
答案 0 :(得分:0)
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
,它只是直接返回错误代码。
修改强>
只是为了澄清参数的用法;如果要查询所需的域缓冲区大小,可以执行以下操作:
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);
在我的例子中,我通过传入一个“足够大”的缓冲区来避免这种情况。