mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
[SAMLIB/SAMSRV]
- Implement SamEnumerateGroupsInDomain and SamEnumerateUsersInDomain (ignore UserAccountControl). - Simplify SamrEnumerateAliasesInDomain. svn path=/trunk/; revision=57029
This commit is contained in:
@@ -159,7 +159,7 @@ SamConnect(IN OUT PUNICODE_STRING ServerName,
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamConnect(%p,%p,0x%08x,%p)\n",
|
||||
TRACE("SamConnect(%p %p 0x%08x %p)\n",
|
||||
ServerName, ServerHandle, DesiredAccess, ObjectAttributes);
|
||||
|
||||
RpcTryExcept
|
||||
@@ -188,7 +188,7 @@ SamCreateAliasInDomain(IN SAM_HANDLE DomainHandle,
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamCreateAliasInDomain(%p,%p,0x%08x,%p,%p)\n",
|
||||
TRACE("SamCreateAliasInDomain(%p %p 0x%08x %p %p)\n",
|
||||
DomainHandle, AccountName, DesiredAccess, AliasHandle, RelativeId);
|
||||
|
||||
RpcTryExcept
|
||||
@@ -219,7 +219,7 @@ SamCreateGroupInDomain(IN SAM_HANDLE DomainHandle,
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamCreateGroupInDomain(%p,%p,0x%08x,%p,%p)\n",
|
||||
TRACE("SamCreateGroupInDomain(%p %p 0x%08x %p %p)\n",
|
||||
DomainHandle, AccountName, DesiredAccess, GroupHandle, RelativeId);
|
||||
|
||||
RpcTryExcept
|
||||
@@ -250,7 +250,7 @@ SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamCreateUserInDomain(%p,%p,0x%08x,%p,%p)\n",
|
||||
TRACE("SamCreateUserInDomain(%p %p 0x%08x %p %p)\n",
|
||||
DomainHandle, AccountName, DesiredAccess, UserHandle, RelativeId);
|
||||
|
||||
RpcTryExcept
|
||||
@@ -282,7 +282,7 @@ SamEnumerateAliasesInDomain(IN SAM_HANDLE DomainHandle,
|
||||
PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamEnumerateAliasesInDomain(%p,%p,%p,%lu,%p)\n",
|
||||
TRACE("SamEnumerateAliasesInDomain(%p %p %p %lu %p)\n",
|
||||
DomainHandle, EnumerationContext, Buffer, PreferedMaximumLength,
|
||||
CountReturned);
|
||||
|
||||
@@ -332,7 +332,7 @@ SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle,
|
||||
PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamEnumerateDomainsInSamServer(%p,%p,%p,%lu,%p)\n",
|
||||
TRACE("SamEnumerateDomainsInSamServer(%p %p %p %lu %p)\n",
|
||||
ServerHandle, EnumerationContext, Buffer, PreferedMaximumLength,
|
||||
CountReturned);
|
||||
|
||||
@@ -371,6 +371,101 @@ SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle,
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamEnumerateGroupsInDomain(IN SAM_HANDLE DomainHandle,
|
||||
IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
|
||||
IN PVOID *Buffer,
|
||||
IN ULONG PreferedMaximumLength,
|
||||
OUT PULONG CountReturned)
|
||||
{
|
||||
PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamEnumerateGroupsInDomain(%p %p %p %lu %p)\n",
|
||||
DomainHandle, EnumerationContext, Buffer,
|
||||
PreferedMaximumLength, CountReturned);
|
||||
|
||||
if (EnumerationContext == NULL || Buffer == NULL || CountReturned == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
*Buffer = NULL;
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrEnumerateGroupsInDomain((SAMPR_HANDLE)DomainHandle,
|
||||
EnumerationContext,
|
||||
(PSAMPR_ENUMERATION_BUFFER *)&EnumBuffer,
|
||||
PreferedMaximumLength,
|
||||
CountReturned);
|
||||
if (EnumBuffer != NULL)
|
||||
{
|
||||
if (EnumBuffer->Buffer != NULL)
|
||||
*Buffer = EnumBuffer->Buffer;
|
||||
|
||||
midl_user_free(EnumBuffer);
|
||||
}
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamEnumerateUsersInDomain(IN SAM_HANDLE DomainHandle,
|
||||
IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
|
||||
IN ULONG UserAccountControl,
|
||||
OUT PVOID *Buffer,
|
||||
IN ULONG PreferedMaximumLength,
|
||||
OUT PULONG CountReturned)
|
||||
{
|
||||
PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamEnumerateUsersInDomain(%p %p %lx %p %lu %p)\n",
|
||||
DomainHandle, EnumerationContext, UserAccountControl, Buffer,
|
||||
PreferedMaximumLength, CountReturned);
|
||||
|
||||
if (EnumerationContext == NULL || Buffer == NULL || CountReturned == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
*Buffer = NULL;
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrEnumerateUsersInDomain((SAMPR_HANDLE)DomainHandle,
|
||||
EnumerationContext,
|
||||
UserAccountControl,
|
||||
(PSAMPR_ENUMERATION_BUFFER *)&EnumBuffer,
|
||||
PreferedMaximumLength,
|
||||
CountReturned);
|
||||
if (EnumBuffer != NULL)
|
||||
{
|
||||
if (EnumBuffer->Buffer != NULL)
|
||||
{
|
||||
*Buffer = EnumBuffer->Buffer;
|
||||
}
|
||||
|
||||
midl_user_free(EnumBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamFreeMemory(IN PVOID Buffer)
|
||||
@@ -483,7 +578,7 @@ SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamLookupDomainInSamServer(%p,%p,%p)\n",
|
||||
TRACE("SamLookupDomainInSamServer(%p %p %p)\n",
|
||||
ServerHandle, Name, DomainId);
|
||||
|
||||
RpcTryExcept
|
||||
@@ -553,7 +648,7 @@ SamOpenDomain(IN SAM_HANDLE ServerHandle,
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamOpenDomain(%p,0x%08x,%p,%p)\n",
|
||||
TRACE("SamOpenDomain(%p 0x%08x %p %p)\n",
|
||||
ServerHandle, DesiredAccess, DomainId, DomainHandle);
|
||||
|
||||
RpcTryExcept
|
||||
@@ -582,7 +677,7 @@ SamOpenGroup(IN SAM_HANDLE DomainHandle,
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamOpenGroup(%p,0x%08x,%p,%p)\n",
|
||||
TRACE("SamOpenGroup(%p 0x%08x %p %p)\n",
|
||||
DomainHandle, DesiredAccess, GroupId, GroupHandle);
|
||||
|
||||
RpcTryExcept
|
||||
@@ -611,7 +706,7 @@ SamOpenUser(IN SAM_HANDLE DomainHandle,
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamOpenUser(%p,0x%08x,%lx,%p)\n",
|
||||
TRACE("SamOpenUser(%p 0x%08x %lx %p)\n",
|
||||
DomainHandle, DesiredAccess, UserId, UserHandle);
|
||||
|
||||
RpcTryExcept
|
||||
@@ -770,18 +865,18 @@ NTSTATUS
|
||||
NTAPI
|
||||
SamSetInformationDomain(IN SAM_HANDLE DomainHandle,
|
||||
IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
|
||||
IN PVOID DomainInformation)
|
||||
IN PVOID Buffer)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamSetInformationDomain(%p %lu %p)\n",
|
||||
DomainHandle, DomainInformationClass, DomainInformation);
|
||||
DomainHandle, DomainInformationClass, Buffer);
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrSetInformationDomain((SAMPR_HANDLE)DomainHandle,
|
||||
DomainInformationClass,
|
||||
DomainInformation);
|
||||
Buffer);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
@ stub SamDeleteUser
|
||||
@ stdcall SamEnumerateAliasesInDomain(ptr ptr ptr long ptr)
|
||||
@ stdcall SamEnumerateDomainsInSamServer(ptr ptr ptr long ptr)
|
||||
@ stub SamEnumerateGroupsInDomain
|
||||
@ stub SamEnumerateUsersInDomain
|
||||
@ stdcall SamEnumerateGroupsInDomain(ptr ptr ptr long ptr)
|
||||
@ stdcall SamEnumerateUsersInDomain(ptr ptr long ptr long ptr)
|
||||
@ stdcall SamFreeMemory(ptr)
|
||||
@ stdcall SamGetAliasMembership(ptr long ptr ptr ptr)
|
||||
@ stub SamGetCompatibilityMode
|
||||
|
||||
@@ -1696,8 +1696,197 @@ SamrEnumerateGroupsInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
IN unsigned long PreferedMaximumLength,
|
||||
OUT unsigned long *CountReturned)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
|
||||
PSAM_DB_OBJECT DomainObject;
|
||||
HANDLE GroupsKeyHandle = NULL;
|
||||
HANDLE NamesKeyHandle = NULL;
|
||||
WCHAR GroupName[64];
|
||||
ULONG EnumIndex;
|
||||
ULONG EnumCount = 0;
|
||||
ULONG RequiredLength = 0;
|
||||
ULONG NameLength;
|
||||
ULONG DataLength;
|
||||
ULONG Rid;
|
||||
ULONG i;
|
||||
BOOLEAN MoreEntries = FALSE;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamrEnumerateUsersInDomain(%p %p %p %lu %p)\n",
|
||||
DomainHandle, EnumerationContext, Buffer,
|
||||
PreferedMaximumLength, CountReturned);
|
||||
|
||||
/* Validate the domain handle */
|
||||
Status = SampValidateDbObject(DomainHandle,
|
||||
SamDbDomainObject,
|
||||
DOMAIN_LIST_ACCOUNTS,
|
||||
&DomainObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
Status = SampRegOpenKey(DomainObject->KeyHandle,
|
||||
L"Groups",
|
||||
KEY_READ,
|
||||
&GroupsKeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
Status = SampRegOpenKey(GroupsKeyHandle,
|
||||
L"Names",
|
||||
KEY_READ,
|
||||
&NamesKeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
TRACE("Part 1\n");
|
||||
|
||||
EnumIndex = *EnumerationContext;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
NameLength = 64 * sizeof(WCHAR);
|
||||
Status = SampRegEnumerateValue(NamesKeyHandle,
|
||||
EnumIndex,
|
||||
GroupName,
|
||||
&NameLength,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE("EnumIndex: %lu\n", EnumIndex);
|
||||
TRACE("Group name: %S\n", GroupName);
|
||||
TRACE("Name length: %lu\n", NameLength);
|
||||
|
||||
if ((RequiredLength + NameLength + sizeof(UNICODE_NULL) + sizeof(SAMPR_RID_ENUMERATION)) > PreferedMaximumLength)
|
||||
{
|
||||
MoreEntries = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
RequiredLength += (NameLength + sizeof(UNICODE_NULL) + sizeof(SAMPR_RID_ENUMERATION));
|
||||
EnumCount++;
|
||||
|
||||
EnumIndex++;
|
||||
}
|
||||
|
||||
TRACE("EnumCount: %lu\n", EnumCount);
|
||||
TRACE("RequiredLength: %lu\n", RequiredLength);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
EnumBuffer = midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER));
|
||||
if (EnumBuffer == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
EnumBuffer->EntriesRead = EnumCount;
|
||||
if (EnumCount == 0)
|
||||
goto done;
|
||||
|
||||
EnumBuffer->Buffer = midl_user_allocate(EnumCount * sizeof(SAMPR_RID_ENUMERATION));
|
||||
if (EnumBuffer->Buffer == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
TRACE("Part 2\n");
|
||||
|
||||
EnumIndex = *EnumerationContext;
|
||||
for (i = 0; i < EnumCount; i++, EnumIndex++)
|
||||
{
|
||||
NameLength = 64 * sizeof(WCHAR);
|
||||
DataLength = sizeof(ULONG);
|
||||
Status = SampRegEnumerateValue(NamesKeyHandle,
|
||||
EnumIndex,
|
||||
GroupName,
|
||||
&NameLength,
|
||||
NULL,
|
||||
&Rid,
|
||||
&DataLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE("EnumIndex: %lu\n", EnumIndex);
|
||||
TRACE("Group name: %S\n", GroupName);
|
||||
TRACE("Name length: %lu\n", NameLength);
|
||||
TRACE("RID: %lu\n", Rid);
|
||||
|
||||
EnumBuffer->Buffer[i].RelativeId = Rid;
|
||||
|
||||
EnumBuffer->Buffer[i].Name.Length = (USHORT)NameLength;
|
||||
EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)(DataLength + sizeof(UNICODE_NULL));
|
||||
|
||||
/* FIXME: Disabled because of bugs in widl and rpcrt4 */
|
||||
#if 0
|
||||
EnumBuffer->Buffer[i].Name.Buffer = midl_user_allocate(EnumBuffer->Buffer[i].Name.MaximumLength);
|
||||
if (EnumBuffer->Buffer[i].Name.Buffer == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
memcpy(EnumBuffer->Buffer[i].Name.Buffer,
|
||||
GroupName,
|
||||
EnumBuffer->Buffer[i].Name.Length);
|
||||
#endif
|
||||
}
|
||||
|
||||
done:
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
*EnumerationContext += EnumCount;
|
||||
*Buffer = EnumBuffer;
|
||||
*CountReturned = EnumCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
*EnumerationContext = 0;
|
||||
*Buffer = NULL;
|
||||
*CountReturned = 0;
|
||||
|
||||
if (EnumBuffer != NULL)
|
||||
{
|
||||
if (EnumBuffer->Buffer != NULL)
|
||||
{
|
||||
if (EnumBuffer->EntriesRead != 0)
|
||||
{
|
||||
for (i = 0; i < EnumBuffer->EntriesRead; i++)
|
||||
{
|
||||
if (EnumBuffer->Buffer[i].Name.Buffer != NULL)
|
||||
midl_user_free(EnumBuffer->Buffer[i].Name.Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
midl_user_free(EnumBuffer->Buffer);
|
||||
}
|
||||
|
||||
midl_user_free(EnumBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (NamesKeyHandle != NULL)
|
||||
SampRegCloseKey(NamesKeyHandle);
|
||||
|
||||
if (GroupsKeyHandle != NULL)
|
||||
SampRegCloseKey(GroupsKeyHandle);
|
||||
|
||||
if ((Status == STATUS_SUCCESS) && (MoreEntries == TRUE))
|
||||
Status = STATUS_MORE_ENTRIES;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
@@ -1968,8 +2157,197 @@ SamrEnumerateUsersInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
IN unsigned long PreferedMaximumLength,
|
||||
OUT unsigned long *CountReturned)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
|
||||
PSAM_DB_OBJECT DomainObject;
|
||||
HANDLE UsersKeyHandle = NULL;
|
||||
HANDLE NamesKeyHandle = NULL;
|
||||
WCHAR UserName[64];
|
||||
ULONG EnumIndex;
|
||||
ULONG EnumCount = 0;
|
||||
ULONG RequiredLength = 0;
|
||||
ULONG NameLength;
|
||||
ULONG DataLength;
|
||||
ULONG Rid;
|
||||
ULONG i;
|
||||
BOOLEAN MoreEntries = FALSE;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamrEnumerateUsersInDomain(%p %p %lx %p %lu %p)\n",
|
||||
DomainHandle, EnumerationContext, UserAccountControl, Buffer,
|
||||
PreferedMaximumLength, CountReturned);
|
||||
|
||||
/* Validate the domain handle */
|
||||
Status = SampValidateDbObject(DomainHandle,
|
||||
SamDbDomainObject,
|
||||
DOMAIN_LIST_ACCOUNTS,
|
||||
&DomainObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
Status = SampRegOpenKey(DomainObject->KeyHandle,
|
||||
L"Users",
|
||||
KEY_READ,
|
||||
&UsersKeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
Status = SampRegOpenKey(UsersKeyHandle,
|
||||
L"Names",
|
||||
KEY_READ,
|
||||
&NamesKeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
TRACE("Part 1\n");
|
||||
|
||||
EnumIndex = *EnumerationContext;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
NameLength = 64 * sizeof(WCHAR);
|
||||
Status = SampRegEnumerateValue(NamesKeyHandle,
|
||||
EnumIndex,
|
||||
UserName,
|
||||
&NameLength,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE("EnumIndex: %lu\n", EnumIndex);
|
||||
TRACE("User name: %S\n", UserName);
|
||||
TRACE("Name length: %lu\n", NameLength);
|
||||
|
||||
if ((RequiredLength + NameLength + sizeof(UNICODE_NULL) + sizeof(SAMPR_RID_ENUMERATION)) > PreferedMaximumLength)
|
||||
{
|
||||
MoreEntries = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
RequiredLength += (NameLength + sizeof(UNICODE_NULL) + sizeof(SAMPR_RID_ENUMERATION));
|
||||
EnumCount++;
|
||||
|
||||
EnumIndex++;
|
||||
}
|
||||
|
||||
TRACE("EnumCount: %lu\n", EnumCount);
|
||||
TRACE("RequiredLength: %lu\n", RequiredLength);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
EnumBuffer = midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER));
|
||||
if (EnumBuffer == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
EnumBuffer->EntriesRead = EnumCount;
|
||||
if (EnumCount == 0)
|
||||
goto done;
|
||||
|
||||
EnumBuffer->Buffer = midl_user_allocate(EnumCount * sizeof(SAMPR_RID_ENUMERATION));
|
||||
if (EnumBuffer->Buffer == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
TRACE("Part 2\n");
|
||||
|
||||
EnumIndex = *EnumerationContext;
|
||||
for (i = 0; i < EnumCount; i++, EnumIndex++)
|
||||
{
|
||||
NameLength = 64 * sizeof(WCHAR);
|
||||
DataLength = sizeof(ULONG);
|
||||
Status = SampRegEnumerateValue(NamesKeyHandle,
|
||||
EnumIndex,
|
||||
UserName,
|
||||
&NameLength,
|
||||
NULL,
|
||||
&Rid,
|
||||
&DataLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE("EnumIndex: %lu\n", EnumIndex);
|
||||
TRACE("User name: %S\n", UserName);
|
||||
TRACE("Name length: %lu\n", NameLength);
|
||||
TRACE("RID: %lu\n", Rid);
|
||||
|
||||
EnumBuffer->Buffer[i].RelativeId = Rid;
|
||||
|
||||
EnumBuffer->Buffer[i].Name.Length = (USHORT)NameLength;
|
||||
EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)(DataLength + sizeof(UNICODE_NULL));
|
||||
|
||||
/* FIXME: Disabled because of bugs in widl and rpcrt4 */
|
||||
#if 0
|
||||
EnumBuffer->Buffer[i].Name.Buffer = midl_user_allocate(EnumBuffer->Buffer[i].Name.MaximumLength);
|
||||
if (EnumBuffer->Buffer[i].Name.Buffer == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
memcpy(EnumBuffer->Buffer[i].Name.Buffer,
|
||||
UserName,
|
||||
EnumBuffer->Buffer[i].Name.Length);
|
||||
#endif
|
||||
}
|
||||
|
||||
done:
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
*EnumerationContext += EnumCount;
|
||||
*Buffer = EnumBuffer;
|
||||
*CountReturned = EnumCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
*EnumerationContext = 0;
|
||||
*Buffer = NULL;
|
||||
*CountReturned = 0;
|
||||
|
||||
if (EnumBuffer != NULL)
|
||||
{
|
||||
if (EnumBuffer->Buffer != NULL)
|
||||
{
|
||||
if (EnumBuffer->EntriesRead != 0)
|
||||
{
|
||||
for (i = 0; i < EnumBuffer->EntriesRead; i++)
|
||||
{
|
||||
if (EnumBuffer->Buffer[i].Name.Buffer != NULL)
|
||||
midl_user_free(EnumBuffer->Buffer[i].Name.Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
midl_user_free(EnumBuffer->Buffer);
|
||||
}
|
||||
|
||||
midl_user_free(EnumBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (NamesKeyHandle != NULL)
|
||||
SampRegCloseKey(NamesKeyHandle);
|
||||
|
||||
if (UsersKeyHandle != NULL)
|
||||
SampRegCloseKey(UsersKeyHandle);
|
||||
|
||||
if ((Status == STATUS_SUCCESS) && (MoreEntries == TRUE))
|
||||
Status = STATUS_MORE_ENTRIES;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
@@ -2108,6 +2486,7 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/* Function 15 */
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
@@ -2119,20 +2498,22 @@ SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
{
|
||||
PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
|
||||
PSAM_DB_OBJECT DomainObject;
|
||||
HANDLE AliasesKeyHandle;
|
||||
WCHAR AliasKeyName[64];
|
||||
HANDLE AliasKeyHandle;
|
||||
HANDLE AliasesKeyHandle = NULL;
|
||||
HANDLE NamesKeyHandle = NULL;
|
||||
WCHAR AliasName[64];
|
||||
ULONG EnumIndex;
|
||||
ULONG EnumCount;
|
||||
ULONG RequiredLength;
|
||||
ULONG EnumCount = 0;
|
||||
ULONG RequiredLength = 0;
|
||||
ULONG NameLength;
|
||||
ULONG DataLength;
|
||||
ULONG Rid;
|
||||
ULONG i;
|
||||
BOOLEAN MoreEntries = FALSE;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamrEnumerateAliasesInDomain(%p %p %p %lu %p)\n",
|
||||
DomainHandle, EnumerationContext, Buffer, PreferedMaximumLength,
|
||||
CountReturned);
|
||||
DomainHandle, EnumerationContext, Buffer,
|
||||
PreferedMaximumLength, CountReturned);
|
||||
|
||||
/* Validate the domain handle */
|
||||
Status = SampValidateDbObject(DomainHandle,
|
||||
@@ -2149,18 +2530,27 @@ SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
Status = SampRegOpenKey(AliasesKeyHandle,
|
||||
L"Names",
|
||||
KEY_READ,
|
||||
&NamesKeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
TRACE("Part 1\n");
|
||||
|
||||
EnumIndex = *EnumerationContext;
|
||||
EnumCount = 0;
|
||||
RequiredLength = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
Status = SampRegEnumerateSubKey(AliasesKeyHandle,
|
||||
EnumIndex,
|
||||
64 * sizeof(WCHAR),
|
||||
AliasKeyName);
|
||||
NameLength = 64 * sizeof(WCHAR);
|
||||
Status = SampRegEnumerateValue(NamesKeyHandle,
|
||||
EnumIndex,
|
||||
AliasName,
|
||||
&NameLength,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
@@ -2169,47 +2559,27 @@ SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
}
|
||||
|
||||
TRACE("EnumIndex: %lu\n", EnumIndex);
|
||||
TRACE("Alias key name: %S\n", AliasKeyName);
|
||||
TRACE("Alias name: %S\n", AliasName);
|
||||
TRACE("Name length: %lu\n", NameLength);
|
||||
|
||||
Status = SampRegOpenKey(AliasesKeyHandle,
|
||||
AliasKeyName,
|
||||
KEY_READ,
|
||||
&AliasKeyHandle);
|
||||
TRACE("SampRegOpenKey returned %08lX\n", Status);
|
||||
if (NT_SUCCESS(Status))
|
||||
if ((RequiredLength + NameLength + sizeof(UNICODE_NULL) + sizeof(SAMPR_RID_ENUMERATION)) > PreferedMaximumLength)
|
||||
{
|
||||
DataLength = 0;
|
||||
Status = SampRegQueryValue(AliasKeyHandle,
|
||||
L"Name",
|
||||
NULL,
|
||||
NULL,
|
||||
&DataLength);
|
||||
|
||||
NtClose(AliasKeyHandle);
|
||||
|
||||
TRACE("SampRegQueryValue returned %08lX\n", Status);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
TRACE("Data length: %lu\n", DataLength);
|
||||
|
||||
if ((RequiredLength + DataLength + sizeof(SAMPR_RID_ENUMERATION)) > PreferedMaximumLength)
|
||||
{
|
||||
MoreEntries = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
RequiredLength += (DataLength + sizeof(SAMPR_RID_ENUMERATION));
|
||||
EnumCount++;
|
||||
}
|
||||
MoreEntries = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
RequiredLength += (NameLength + sizeof(UNICODE_NULL) + sizeof(SAMPR_RID_ENUMERATION));
|
||||
EnumCount++;
|
||||
|
||||
EnumIndex++;
|
||||
}
|
||||
|
||||
TRACE("EnumCount: %lu\n", EnumCount);
|
||||
TRACE("RequiredLength: %lu\n", RequiredLength);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
EnumBuffer = midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER));
|
||||
if (EnumBuffer == NULL)
|
||||
{
|
||||
@@ -2233,10 +2603,15 @@ SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
EnumIndex = *EnumerationContext;
|
||||
for (i = 0; i < EnumCount; i++, EnumIndex++)
|
||||
{
|
||||
Status = SampRegEnumerateSubKey(AliasesKeyHandle,
|
||||
EnumIndex,
|
||||
64 * sizeof(WCHAR),
|
||||
AliasKeyName);
|
||||
NameLength = 64 * sizeof(WCHAR);
|
||||
DataLength = sizeof(ULONG);
|
||||
Status = SampRegEnumerateValue(NamesKeyHandle,
|
||||
EnumIndex,
|
||||
AliasName,
|
||||
&NameLength,
|
||||
NULL,
|
||||
&Rid,
|
||||
&DataLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
@@ -2245,53 +2620,28 @@ SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
}
|
||||
|
||||
TRACE("EnumIndex: %lu\n", EnumIndex);
|
||||
TRACE("Alias key name: %S\n", AliasKeyName);
|
||||
TRACE("Alias name: %S\n", AliasName);
|
||||
TRACE("Name length: %lu\n", NameLength);
|
||||
TRACE("RID: %lu\n", Rid);
|
||||
|
||||
Status = SampRegOpenKey(AliasesKeyHandle,
|
||||
AliasKeyName,
|
||||
KEY_READ,
|
||||
&AliasKeyHandle);
|
||||
TRACE("SampRegOpenKey returned %08lX\n", Status);
|
||||
if (NT_SUCCESS(Status))
|
||||
EnumBuffer->Buffer[i].RelativeId = Rid;
|
||||
|
||||
EnumBuffer->Buffer[i].Name.Length = (USHORT)NameLength;
|
||||
EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)(DataLength + sizeof(UNICODE_NULL));
|
||||
|
||||
/* FIXME: Disabled because of bugs in widl and rpcrt4 */
|
||||
#if 0
|
||||
EnumBuffer->Buffer[i].Name.Buffer = midl_user_allocate(EnumBuffer->Buffer[i].Name.MaximumLength);
|
||||
if (EnumBuffer->Buffer[i].Name.Buffer == NULL)
|
||||
{
|
||||
DataLength = 0;
|
||||
Status = SampRegQueryValue(AliasKeyHandle,
|
||||
L"Name",
|
||||
NULL,
|
||||
NULL,
|
||||
&DataLength);
|
||||
TRACE("SampRegQueryValue returned %08lX\n", Status);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
EnumBuffer->Buffer[i].RelativeId = wcstoul(AliasKeyName, NULL, 16);
|
||||
|
||||
EnumBuffer->Buffer[i].Name.Length = (USHORT)DataLength - sizeof(WCHAR);
|
||||
EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)DataLength;
|
||||
EnumBuffer->Buffer[i].Name.Buffer = midl_user_allocate(DataLength);
|
||||
if (EnumBuffer->Buffer[i].Name.Buffer == NULL)
|
||||
{
|
||||
NtClose(AliasKeyHandle);
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
Status = SampRegQueryValue(AliasKeyHandle,
|
||||
L"Name",
|
||||
NULL,
|
||||
EnumBuffer->Buffer[i].Name.Buffer,
|
||||
&DataLength);
|
||||
TRACE("SampRegQueryValue returned %08lX\n", Status);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
TRACE("Alias name: %S\n", EnumBuffer->Buffer[i].Name.Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
NtClose(AliasKeyHandle);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
memcpy(EnumBuffer->Buffer[i].Name.Buffer,
|
||||
AliasName,
|
||||
EnumBuffer->Buffer[i].Name.Length);
|
||||
#endif
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -2301,8 +2651,7 @@ done:
|
||||
*Buffer = EnumBuffer;
|
||||
*CountReturned = EnumCount;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
else
|
||||
{
|
||||
*EnumerationContext = 0;
|
||||
*Buffer = NULL;
|
||||
@@ -2328,7 +2677,11 @@ done:
|
||||
}
|
||||
}
|
||||
|
||||
NtClose(AliasesKeyHandle);
|
||||
if (NamesKeyHandle != NULL)
|
||||
SampRegCloseKey(NamesKeyHandle);
|
||||
|
||||
if (AliasesKeyHandle != NULL)
|
||||
SampRegCloseKey(AliasesKeyHandle);
|
||||
|
||||
if ((Status == STATUS_SUCCESS) && (MoreEntries == TRUE))
|
||||
Status = STATUS_MORE_ENTRIES;
|
||||
@@ -2336,6 +2689,7 @@ done:
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/* Function 16 */
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
||||
@@ -373,6 +373,23 @@ SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle,
|
||||
IN ULONG PreferedMaximumLength,
|
||||
OUT PULONG CountReturned);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamEnumerateGroupsInDomain(IN SAM_HANDLE DomainHandle,
|
||||
IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
|
||||
IN PVOID *Buffer,
|
||||
IN ULONG PreferedMaximumLength,
|
||||
OUT PULONG CountReturned);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamEnumerateUsersInDomain(IN SAM_HANDLE DomainHandle,
|
||||
IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
|
||||
IN ULONG UserAccountControl,
|
||||
OUT PVOID *Buffer,
|
||||
IN ULONG PreferedMaximumLength,
|
||||
OUT PULONG CountReturned);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamFreeMemory(IN PVOID Buffer);
|
||||
|
||||
Reference in New Issue
Block a user