From 251ea7ec52db7a3b63578d64c1c77a17a27544da Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 2 Aug 2012 20:09:24 +0000 Subject: [PATCH] [SAMLIB/SAMSRV] - Implement SamEnumerateGroupsInDomain and SamEnumerateUsersInDomain (ignore UserAccountControl). - Simplify SamrEnumerateAliasesInDomain. svn path=/trunk/; revision=57029 --- reactos/dll/win32/samlib/samlib.c | 121 +++++- reactos/dll/win32/samlib/samlib.spec | 4 +- reactos/dll/win32/samsrv/samrpc.c | 552 ++++++++++++++++++++++----- reactos/include/ddk/ntsam.h | 17 + 4 files changed, 580 insertions(+), 114 deletions(-) diff --git a/reactos/dll/win32/samlib/samlib.c b/reactos/dll/win32/samlib/samlib.c index f33c9151d1e..dea21b53237 100644 --- a/reactos/dll/win32/samlib/samlib.c +++ b/reactos/dll/win32/samlib/samlib.c @@ -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) { diff --git a/reactos/dll/win32/samlib/samlib.spec b/reactos/dll/win32/samlib/samlib.spec index b5b111d0524..37ee98484a9 100644 --- a/reactos/dll/win32/samlib/samlib.spec +++ b/reactos/dll/win32/samlib/samlib.spec @@ -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 diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index 35ebbbae2d0..4a3c30222ae 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -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 diff --git a/reactos/include/ddk/ntsam.h b/reactos/include/ddk/ntsam.h index 3ff860e9be0..e992b02e27e 100644 --- a/reactos/include/ddk/ntsam.h +++ b/reactos/include/ddk/ntsam.h @@ -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);