mirror of
https://github.com/reactos/reactos.git
synced 2024-12-30 19:14:31 +00:00
[NETAPI32]
Fix NetLocalGroupGetMembers and implement level 1. The netapi32:access winetest does not crash any more and group members appear in the user manager control panel. svn path=/trunk/; revision=59186
This commit is contained in:
parent
6922a068e7
commit
a37d2347c3
1 changed files with 133 additions and 72 deletions
|
@ -50,10 +50,13 @@ typedef struct _MEMBER_ENUM_CONTEXT
|
|||
SAM_HANDLE ServerHandle;
|
||||
SAM_HANDLE DomainHandle;
|
||||
SAM_HANDLE AliasHandle;
|
||||
LSA_HANDLE LsaHandle;
|
||||
|
||||
PSID *Sids;
|
||||
ULONG Count;
|
||||
ULONG Index;
|
||||
PLSA_REFERENCED_DOMAIN_LIST Domains;
|
||||
PLSA_TRANSLATED_NAME Names;
|
||||
|
||||
} MEMBER_ENUM_CONTEXT, *PMEMBER_ENUM_CONTEXT;
|
||||
|
||||
|
||||
|
@ -160,66 +163,6 @@ FreeAliasInfo(PALIAS_GENERAL_INFORMATION AliasInfo)
|
|||
}
|
||||
|
||||
|
||||
static
|
||||
NET_API_STATUS
|
||||
BuildAliasMemberBuffer(PSID MemberSid,
|
||||
DWORD level,
|
||||
LPVOID *Buffer)
|
||||
{
|
||||
LPVOID LocalBuffer = NULL;
|
||||
PLOCALGROUP_MEMBERS_INFO_0 MembersInfo0;
|
||||
PVOID Ptr;
|
||||
ULONG Size = 0;
|
||||
NET_API_STATUS ApiStatus = NERR_Success;
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
Size = sizeof(LOCALGROUP_MEMBERS_INFO_0) +
|
||||
RtlLengthSid(MemberSid);
|
||||
break;
|
||||
|
||||
default:
|
||||
ApiStatus = ERROR_INVALID_LEVEL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
ApiStatus = NetApiBufferAllocate(Size, &LocalBuffer);
|
||||
if (ApiStatus != NERR_Success)
|
||||
goto done;
|
||||
|
||||
ZeroMemory(LocalBuffer, Size);
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
MembersInfo0 = (PLOCALGROUP_MEMBERS_INFO_0)LocalBuffer;
|
||||
|
||||
Ptr = (PVOID)MembersInfo0++;
|
||||
MembersInfo0->lgrmi0_sid = (PSID)Ptr;
|
||||
|
||||
memcpy(MembersInfo0->lgrmi0_sid,
|
||||
MemberSid,
|
||||
RtlLengthSid(MemberSid));
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
if (ApiStatus == NERR_Success)
|
||||
{
|
||||
*Buffer = LocalBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LocalBuffer != NULL)
|
||||
NetApiBufferFree(LocalBuffer);
|
||||
}
|
||||
|
||||
return ApiStatus;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NET_API_STATUS
|
||||
OpenAliasByName(SAM_HANDLE DomainHandle,
|
||||
|
@ -996,14 +939,21 @@ NetLocalGroupGetMembers(
|
|||
LPDWORD totalentries,
|
||||
PDWORD_PTR resumehandle)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING ServerName;
|
||||
UNICODE_STRING AliasName;
|
||||
PMEMBER_ENUM_CONTEXT EnumContext = NULL;
|
||||
LPVOID Buffer = NULL;
|
||||
PLOCALGROUP_MEMBERS_INFO_0 MembersInfo0;
|
||||
PLOCALGROUP_MEMBERS_INFO_1 MembersInfo1;
|
||||
LPWSTR Ptr;
|
||||
ULONG Size = 0;
|
||||
ULONG SidLength;
|
||||
ULONG i;
|
||||
NET_API_STATUS ApiStatus = NERR_Success;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
TRACE("(%s %s %d %p %d, %p %p %p) stub!\n", debugstr_w(servername),
|
||||
TRACE("(%s %s %d %p %d, %p %p %p)\n", debugstr_w(servername),
|
||||
debugstr_w(localgroupname), level, bufptr, prefmaxlen, entriesread,
|
||||
totalentries, resumehandle);
|
||||
|
||||
|
@ -1109,30 +1059,135 @@ NetLocalGroupGetMembers(
|
|||
ApiStatus = NERR_Success;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
if (level != 0)
|
||||
{
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
Status = LsaOpenPolicy((servername != NULL) ? &ServerName : NULL,
|
||||
(PLSA_OBJECT_ATTRIBUTES)&ObjectAttributes,
|
||||
POLICY_EXECUTE,
|
||||
&EnumContext->LsaHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
Status = LsaLookupSids(EnumContext->LsaHandle,
|
||||
EnumContext->Count,
|
||||
EnumContext->Sids,
|
||||
&EnumContext->Domains,
|
||||
&EnumContext->Names);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Build the member information buffer */
|
||||
ApiStatus = BuildAliasMemberBuffer(EnumContext->Sids[EnumContext->Index],
|
||||
level,
|
||||
&Buffer);
|
||||
/* Calculate the required buffer size */
|
||||
for (i = 0; i < EnumContext->Count; i++)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
Size = sizeof(LOCALGROUP_MEMBERS_INFO_0) +
|
||||
RtlLengthSid(EnumContext->Sids[i]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
Size = sizeof(LOCALGROUP_MEMBERS_INFO_1) +
|
||||
RtlLengthSid(EnumContext->Sids[i]) +
|
||||
EnumContext->Names[i].Name.Length + sizeof(WCHAR);
|
||||
break;
|
||||
|
||||
default:
|
||||
ApiStatus = ERROR_INVALID_LEVEL;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the member buffer */
|
||||
ApiStatus = NetApiBufferAllocate(Size, &Buffer);
|
||||
if (ApiStatus != NERR_Success)
|
||||
goto done;
|
||||
|
||||
EnumContext->Index++;
|
||||
(*entriesread)++;
|
||||
ZeroMemory(Buffer, Size);
|
||||
|
||||
/* Fill the member buffer */
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
MembersInfo0 = (PLOCALGROUP_MEMBERS_INFO_0)Buffer;
|
||||
Ptr = (PVOID)((ULONG_PTR)Buffer + sizeof(LOCALGROUP_MEMBERS_INFO_0) * EnumContext->Count);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
MembersInfo1 = (PLOCALGROUP_MEMBERS_INFO_1)Buffer;
|
||||
Ptr = (PVOID)((ULONG_PTR)Buffer + sizeof(LOCALGROUP_MEMBERS_INFO_1) * EnumContext->Count);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < EnumContext->Count; i++)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
MembersInfo0->lgrmi0_sid = (PSID)Ptr;
|
||||
|
||||
SidLength = RtlLengthSid(EnumContext->Sids[i]);
|
||||
memcpy(MembersInfo0->lgrmi0_sid,
|
||||
EnumContext->Sids[i],
|
||||
SidLength);
|
||||
Ptr = (PVOID)((ULONG_PTR)Ptr + SidLength);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
MembersInfo1->lgrmi1_sid = (PSID)Ptr;
|
||||
|
||||
SidLength = RtlLengthSid(EnumContext->Sids[i]);
|
||||
memcpy(MembersInfo1->lgrmi1_sid,
|
||||
EnumContext->Sids[i],
|
||||
SidLength);
|
||||
|
||||
Ptr = (PVOID)((ULONG_PTR)Ptr + SidLength);
|
||||
|
||||
MembersInfo1->lgrmi1_sidusage = EnumContext->Names[i].Use;
|
||||
|
||||
TRACE("Name: %S\n", EnumContext->Names[i].Name.Buffer);
|
||||
|
||||
MembersInfo1->lgrmi1_name = (LPWSTR)Ptr;
|
||||
|
||||
memcpy(MembersInfo1->lgrmi1_name,
|
||||
EnumContext->Names[i].Name.Buffer,
|
||||
EnumContext->Names[i].Name.Length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*entriesread = EnumContext->Count;
|
||||
|
||||
*bufptr = (LPBYTE)Buffer;
|
||||
|
||||
done:
|
||||
if (ApiStatus == NERR_Success && EnumContext->Index < EnumContext->Count)
|
||||
ApiStatus = ERROR_MORE_DATA;
|
||||
|
||||
if (EnumContext != NULL)
|
||||
*totalentries = EnumContext->Count - EnumContext->Index;
|
||||
*totalentries = EnumContext->Count;
|
||||
|
||||
if (resumehandle == NULL || ApiStatus != ERROR_MORE_DATA)
|
||||
{
|
||||
/* Release the enumeration context */
|
||||
if (EnumContext != NULL)
|
||||
{
|
||||
if (EnumContext->LsaHandle != NULL)
|
||||
LsaClose(EnumContext->LsaHandle);
|
||||
|
||||
if (EnumContext->AliasHandle != NULL)
|
||||
SamCloseHandle(EnumContext->AliasHandle);
|
||||
|
||||
|
@ -1145,6 +1200,12 @@ done:
|
|||
if (EnumContext->Sids != NULL)
|
||||
SamFreeMemory(EnumContext->Sids);
|
||||
|
||||
if (EnumContext->Domains != NULL)
|
||||
LsaFreeMemory(EnumContext->Domains);
|
||||
|
||||
if (EnumContext->Names != NULL)
|
||||
LsaFreeMemory(EnumContext->Names);
|
||||
|
||||
NetApiBufferFree(EnumContext);
|
||||
EnumContext = NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue