[NETAPI32]

NetLocalGroupEnum: Make sure that built-in aliases are retrieved once and only one alias is enumerated upon each consecutive call. Retrieve name and comment for each alias.

svn path=/trunk/; revision=57684
This commit is contained in:
Eric Kohl 2012-11-07 18:51:38 +00:00
parent e2dd0a34a1
commit 20ec872b2f

View file

@ -49,8 +49,10 @@ typedef struct _ENUM_CONTEXT
SAM_HANDLE AccountDomainHandle; SAM_HANDLE AccountDomainHandle;
SAM_ENUMERATE_HANDLE EnumerationContext; SAM_ENUMERATE_HANDLE EnumerationContext;
PSAM_RID_ENUMERATION EnumBuffer; PSAM_RID_ENUMERATION Buffer;
ULONG EnumReturned; ULONG Returned;
ULONG Index;
BOOLEAN BuiltinDone;
} ENUM_CONTEXT, *PENUM_CONTEXT; } ENUM_CONTEXT, *PENUM_CONTEXT;
@ -241,9 +243,12 @@ NET_API_STATUS WINAPI NetLocalGroupEnum(
LPDWORD totalentries, LPDWORD totalentries,
PDWORD_PTR resumehandle) PDWORD_PTR resumehandle)
{ {
PSAM_RID_ENUMERATION CurrentAlias;
PENUM_CONTEXT EnumContext = NULL; PENUM_CONTEXT EnumContext = NULL;
PSID DomainSid = NULL; PSID DomainSid = NULL;
ULONG i; ULONG i;
SAM_HANDLE AliasHandle = NULL;
PALIAS_GENERAL_INFORMATION AliasInfo = NULL;
NET_API_STATUS ApiStatus = NERR_Success; NET_API_STATUS ApiStatus = NERR_Success;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
@ -267,8 +272,10 @@ NET_API_STATUS WINAPI NetLocalGroupEnum(
goto done; goto done;
EnumContext->EnumerationContext = 0; EnumContext->EnumerationContext = 0;
EnumContext->EnumBuffer = NULL; EnumContext->Buffer = NULL;
EnumContext->EnumReturned = 0; EnumContext->Returned = 0;
EnumContext->Index = 0;
EnumContext->BuiltinDone = FALSE;
Status = SamConnect(NULL, Status = SamConnect(NULL,
&EnumContext->ServerHandle, &EnumContext->ServerHandle,
@ -290,7 +297,7 @@ NET_API_STATUS WINAPI NetLocalGroupEnum(
} }
Status = SamOpenDomain(EnumContext->ServerHandle, Status = SamOpenDomain(EnumContext->ServerHandle,
DOMAIN_LIST_ACCOUNTS, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
DomainSid, DomainSid,
&EnumContext->AccountDomainHandle); &EnumContext->AccountDomainHandle);
@ -312,7 +319,7 @@ NET_API_STATUS WINAPI NetLocalGroupEnum(
} }
Status = SamOpenDomain(EnumContext->ServerHandle, Status = SamOpenDomain(EnumContext->ServerHandle,
DOMAIN_LIST_ACCOUNTS, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
DomainSid, DomainSid,
&EnumContext->BuiltinDomainHandle); &EnumContext->BuiltinDomainHandle);
@ -326,40 +333,96 @@ NET_API_STATUS WINAPI NetLocalGroupEnum(
} }
} }
while (TRUE) while (TRUE)
{ {
Status = SamEnumerateAliasesInDomain(EnumContext->BuiltinDomainHandle,
&EnumContext->EnumerationContext,
(PVOID *)&EnumContext->EnumBuffer,
prefmaxlen,
&EnumContext->EnumReturned);
TRACE("SamEnumerateAliasesInDomain returned (Status %08lx)\n", Status); if (EnumContext->Index >= EnumContext->Returned)
{
if (EnumContext->BuiltinDone == TRUE)
{
ApiStatus = NERR_Success;
goto done;
}
TRACE("Calling SamEnumerateAliasesInDomain\n");
Status = SamEnumerateAliasesInDomain(EnumContext->BuiltinDomainHandle,
&EnumContext->EnumerationContext,
(PVOID *)&EnumContext->Buffer,
prefmaxlen,
&EnumContext->Returned);
TRACE("SamEnumerateAliasesInDomain returned (Status %08lx)\n", Status);
if (!NT_SUCCESS(Status))
{
ERR("SamEnumerateAliasesInDomain failed (Status %08lx)\n", Status);
ApiStatus = NetpNtStatusToApiStatus(Status);
goto done;
}
if (Status == STATUS_MORE_ENTRIES)
{
ApiStatus = NERR_BufTooSmall;
goto done;
}
else
{
EnumContext->BuiltinDone = TRUE;
}
}
TRACE("EnumContext: %lu\n", EnumContext);
TRACE("EnumContext->Returned: %lu\n", EnumContext->Returned);
TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
/* Get a pointer to the current alias */
CurrentAlias = &EnumContext->Buffer[EnumContext->Index];
TRACE("RID: %lu\n", CurrentAlias->RelativeId);
Status = SamOpenAlias(EnumContext->BuiltinDomainHandle,
ALIAS_READ_INFORMATION,
CurrentAlias->RelativeId,
&AliasHandle);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ERR("SamEnumerateAliasesInDomain failed (Status %08lx)\n", Status); ERR("SamOpenAlias failed (Status %08lx)\n", Status);
ApiStatus = NetpNtStatusToApiStatus(Status); ApiStatus = NetpNtStatusToApiStatus(Status);
goto done; goto done;
} }
TRACE("EnumContext: %lu\n", EnumContext); Status = SamQueryInformationAlias(AliasHandle,
TRACE("EnumReturned: %lu\n", EnumContext->EnumReturned); AliasGeneralInformation,
TRACE("EnumBuffer: %p\n", EnumContext->EnumBuffer); (PVOID *)&AliasInfo);
if (!NT_SUCCESS(Status))
for (i = 0; i < EnumContext->EnumReturned; i++)
{ {
TRACE("RID: %lu\n", EnumContext->EnumBuffer[i].RelativeId); ERR("SamQueryInformationAlias failed (Status %08lx)\n", Status);
TRACE("Name: %p\n", EnumContext->EnumBuffer[i].Name.Buffer); ApiStatus = NetpNtStatusToApiStatus(Status);
TRACE("Name: %S\n", EnumContext->EnumBuffer[i].Name.Buffer); goto done;
if (EnumContext->EnumBuffer[i].Name.Buffer != NULL)
{
TRACE("Name: %hx\n", EnumContext->EnumBuffer[i].Name.Buffer[0]);
}
} }
if (Status != STATUS_MORE_ENTRIES) SamCloseHandle(AliasHandle);
break; AliasHandle = NULL;
TRACE("Name: %S\n", AliasInfo->Name.Buffer);
TRACE("Comment: %S\n", AliasInfo->AdminComment.Buffer);
if (AliasInfo != NULL)
{
if (AliasInfo->Name.Buffer != NULL)
SamFreeMemory(AliasInfo->Name.Buffer);
if (AliasInfo->AdminComment.Buffer != NULL)
SamFreeMemory(AliasInfo->AdminComment.Buffer);
SamFreeMemory(AliasInfo);
AliasInfo = NULL;
}
EnumContext->Index++;
} }
@ -377,14 +440,14 @@ done:
if (EnumContext->ServerHandle != NULL) if (EnumContext->ServerHandle != NULL)
SamCloseHandle(EnumContext->ServerHandle); SamCloseHandle(EnumContext->ServerHandle);
if (EnumContext->EnumBuffer != NULL) if (EnumContext->Buffer != NULL)
{ {
for (i = 0; i < EnumContext->EnumReturned; i++) for (i = 0; i < EnumContext->Returned; i++)
{ {
SamFreeMemory(EnumContext->EnumBuffer[i].Name.Buffer); SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
} }
SamFreeMemory(EnumContext->EnumBuffer); SamFreeMemory(EnumContext->Buffer);
} }
NetApiBufferFree(EnumContext); NetApiBufferFree(EnumContext);
@ -392,6 +455,19 @@ done:
} }
} }
if (AliasHandle != NULL)
SamCloseHandle(AliasHandle);
if (AliasInfo != NULL)
{
if (AliasInfo->Name.Buffer != NULL)
SamFreeMemory(AliasInfo->Name.Buffer);
if (AliasInfo->AdminComment.Buffer != NULL)
SamFreeMemory(AliasInfo->AdminComment.Buffer);
SamFreeMemory(AliasInfo);
}
if (resumehandle != NULL) if (resumehandle != NULL)
*resumehandle = (DWORD_PTR)EnumContext; *resumehandle = (DWORD_PTR)EnumContext;