Reputation: 867
I had a problem with LookupAccountName
, wrote a question and figured it out I had to use LookupAccountName
twice to work. Now I am trying to use NetLocalGroupAddMembers
with the SID that I got from LookupAccountName
, it returns success, but the newly created users won't be added to Users group.
I am getting the Users group from the CreateWellKnownSid
, translating it to string using LookupAccountSid
and sending the account SID to NetLocalGroupAddMembers
by translating the first argument (the new account name) to SID with LookupAccountName.
EDIT:
This is a testable set of code:
#include <Windows.h>
#include <tchar.h>
#include <wchar.h>
#include <LM.h>
#include <sddl.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\n", errorMessage);
LocalFree(errorMessage);
}
int wmain(int argc, WCHAR **argv)
{
//NetUserAdd function
NET_API_STATUS addUser;
DWORD infoLevel = 1; //USER_INFO_1
USER_INFO_1 userData;
DWORD paramError = 0;
//LocalAlloc
UINT memAttributes = LMEM_FIXED;
DWORD sidSize = SECURITY_MAX_SID_SIZE;
//CreateWellKnownSid
WELL_KNOWN_SID_TYPE sidType = WinBuiltinUsersSid;
PSID groupSID;
//LookupAccountSid
WCHAR name[MAX_NAME];
DWORD nameSize = MAX_NAME;
WCHAR domainName[MAX_NAME];
DWORD domainNameSize = MAX_NAME;
SID_NAME_USE accountType;
//LookupAccountName
LPCWSTR machine = NULL;
BYTE accountSIDBuf[SECURITY_MAX_SID_SIZE];
PSID accountSID = (PSID)accountSIDBuf;
DWORD cbSid = 0;
SID_NAME_USE typeOfAccount;
/*WCHAR refDomain[MAX_NAME];*/
DWORD cchRefDomain = 0;
//NetLocalGroupAddMembers
NET_API_STATUS localGroupAdd;
DWORD levelOfData = 0; //LOCALGROUP_MEMBERS_INFO_0
LOCALGROUP_MEMBERS_INFO_0 localMembers;
DWORD totalEntries = 0;
if (argc != 2)
{
fwprintf(stderr, L"\nUsage: %s [UserName]\n", *argv);
return 1;
}
//Set up USER_INFO_1 structure
userData.usri1_name = argv[1];
userData.usri1_password = NULL;
userData.usri1_priv = USER_PRIV_USER;
userData.usri1_home_dir = NULL;
userData.usri1_comment = NULL;
userData.usri1_flags = UF_SCRIPT;
userData.usri1_script_path = NULL;
addUser = NetUserAdd(NULL, infoLevel, (LPBYTE)&userData, ¶mError);
if (addUser != NERR_Success)
{
fwprintf(stderr, L"\nA system error has ocurred: %d\n", addUser);
return 1;
}
else
{
//Let's allocate memory for the SID
if (!(groupSID = LocalAlloc(memAttributes, sidSize))) //if fails
{
ShowError(GetLastError());
exit(1);
}
//Let's create a SID for Users group
if (!CreateWellKnownSid(sidType, NULL, groupSID, &sidSize))
{
ShowError(GetLastError());
exit(1);
}
else
{
if (!LookupAccountSidW(NULL, groupSID, name, &nameSize,
domainName, &domainNameSize, &accountType))
{
ShowError(GetLastError());
return 1;
}
if (!LookupAccountNameW(NULL, argv[1], NULL, &cbSid, NULL, &cchRefDomain, &typeOfAccount))
{
ShowError(GetLastError());
/*exit(1);*/
}
PSID theSID;
LPWSTR refDomainName = (LPWSTR)malloc(cchRefDomain * sizeof(WCHAR));
if (!(theSID = LocalAlloc(memAttributes, cbSid)))
{
ShowError(GetLastError());
exit(1);
}
if (refDomainName == NULL)
{
fwprintf(stderr, L"Error allocating memory for RefDomainName \n");
exit(1);
}
//Here we go again!
if (!LookupAccountNameW(NULL, argv[1], theSID, &cbSid,
refDomainName, &cchRefDomain, &typeOfAccount))
{
ShowError(GetLastError());
exit(1);
}
//Here I should be able to use NetLocalGroupAddMembers
//to add the user passed as argument to the Users group.
localMembers.lgrmi0_sid = theSID;
localGroupAdd = NetLocalGroupAddMembers(NULL, name, levelOfData, (LPBYTE)&localMembers, totalEntries);
if (localGroupAdd != NERR_Success)
{
ShowError(localGroupAdd);
return 1;
}
else
{
ShowError(localGroupAdd);
}
LocalFree(theSID);
free(refDomainName);
}
LocalFree(groupSID);
}
return 0;
}
This is the result I got, as expected:
The data area passed to a system call is too small.
The operation completed successfully.
But when I query the newly created user with Net User, It says:
Local Group Memberships
Global Group Membership *None
It should say Users in the Local Group Membership.
Any help?
Thanks!
Upvotes: 1
Views: 266
Reputation: 16781
You are calling NetLocalGroupAddMembers
with totalentries
=0, but you should call it with 1.
Side notes:
Is there any good reason to put all variables at the top and not declare them where you need them? Locality might have helped you find the error.
usri1_password
is not documented to be allowed to be NULL
.
Are you sure you want to pass NULL
everywhere as machine/system name. Sometimes this is something different than ".", see for example LookupAccountSidW
.
Upvotes: 2