mirror of
https://github.com/reactos/reactos.git
synced 2025-08-07 01:52:57 +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 ServerHandle;
|
||||||
SAM_HANDLE DomainHandle;
|
SAM_HANDLE DomainHandle;
|
||||||
SAM_HANDLE AliasHandle;
|
SAM_HANDLE AliasHandle;
|
||||||
|
LSA_HANDLE LsaHandle;
|
||||||
|
|
||||||
PSID *Sids;
|
PSID *Sids;
|
||||||
ULONG Count;
|
ULONG Count;
|
||||||
ULONG Index;
|
PLSA_REFERENCED_DOMAIN_LIST Domains;
|
||||||
|
PLSA_TRANSLATED_NAME Names;
|
||||||
|
|
||||||
} MEMBER_ENUM_CONTEXT, *PMEMBER_ENUM_CONTEXT;
|
} 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
|
static
|
||||||
NET_API_STATUS
|
NET_API_STATUS
|
||||||
OpenAliasByName(SAM_HANDLE DomainHandle,
|
OpenAliasByName(SAM_HANDLE DomainHandle,
|
||||||
|
@ -996,14 +939,21 @@ NetLocalGroupGetMembers(
|
||||||
LPDWORD totalentries,
|
LPDWORD totalentries,
|
||||||
PDWORD_PTR resumehandle)
|
PDWORD_PTR resumehandle)
|
||||||
{
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
UNICODE_STRING ServerName;
|
UNICODE_STRING ServerName;
|
||||||
UNICODE_STRING AliasName;
|
UNICODE_STRING AliasName;
|
||||||
PMEMBER_ENUM_CONTEXT EnumContext = NULL;
|
PMEMBER_ENUM_CONTEXT EnumContext = NULL;
|
||||||
LPVOID Buffer = 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;
|
NET_API_STATUS ApiStatus = NERR_Success;
|
||||||
NTSTATUS Status = STATUS_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,
|
debugstr_w(localgroupname), level, bufptr, prefmaxlen, entriesread,
|
||||||
totalentries, resumehandle);
|
totalentries, resumehandle);
|
||||||
|
|
||||||
|
@ -1109,30 +1059,135 @@ NetLocalGroupGetMembers(
|
||||||
ApiStatus = NERR_Success;
|
ApiStatus = NERR_Success;
|
||||||
goto done;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build the member information buffer */
|
Status = LsaLookupSids(EnumContext->LsaHandle,
|
||||||
ApiStatus = BuildAliasMemberBuffer(EnumContext->Sids[EnumContext->Index],
|
EnumContext->Count,
|
||||||
level,
|
EnumContext->Sids,
|
||||||
&Buffer);
|
&EnumContext->Domains,
|
||||||
|
&EnumContext->Names);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ApiStatus = NetpNtStatusToApiStatus(Status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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)
|
if (ApiStatus != NERR_Success)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
EnumContext->Index++;
|
ZeroMemory(Buffer, Size);
|
||||||
(*entriesread)++;
|
|
||||||
|
/* 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:
|
done:
|
||||||
if (ApiStatus == NERR_Success && EnumContext->Index < EnumContext->Count)
|
|
||||||
ApiStatus = ERROR_MORE_DATA;
|
|
||||||
|
|
||||||
if (EnumContext != NULL)
|
if (EnumContext != NULL)
|
||||||
*totalentries = EnumContext->Count - EnumContext->Index;
|
*totalentries = EnumContext->Count;
|
||||||
|
|
||||||
if (resumehandle == NULL || ApiStatus != ERROR_MORE_DATA)
|
if (resumehandle == NULL || ApiStatus != ERROR_MORE_DATA)
|
||||||
{
|
{
|
||||||
/* Release the enumeration context */
|
/* Release the enumeration context */
|
||||||
if (EnumContext != NULL)
|
if (EnumContext != NULL)
|
||||||
{
|
{
|
||||||
|
if (EnumContext->LsaHandle != NULL)
|
||||||
|
LsaClose(EnumContext->LsaHandle);
|
||||||
|
|
||||||
if (EnumContext->AliasHandle != NULL)
|
if (EnumContext->AliasHandle != NULL)
|
||||||
SamCloseHandle(EnumContext->AliasHandle);
|
SamCloseHandle(EnumContext->AliasHandle);
|
||||||
|
|
||||||
|
@ -1145,6 +1200,12 @@ done:
|
||||||
if (EnumContext->Sids != NULL)
|
if (EnumContext->Sids != NULL)
|
||||||
SamFreeMemory(EnumContext->Sids);
|
SamFreeMemory(EnumContext->Sids);
|
||||||
|
|
||||||
|
if (EnumContext->Domains != NULL)
|
||||||
|
LsaFreeMemory(EnumContext->Domains);
|
||||||
|
|
||||||
|
if (EnumContext->Names != NULL)
|
||||||
|
LsaFreeMemory(EnumContext->Names);
|
||||||
|
|
||||||
NetApiBufferFree(EnumContext);
|
NetApiBufferFree(EnumContext);
|
||||||
EnumContext = NULL;
|
EnumContext = NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue