Author: ekohl Date: Sat Aug 11 19:41:17 2012 New Revision: 57057
URL: http://svn.reactos.org/svn/reactos?rev=57057&view=rev Log: [SAMLIB/SAMSRV] - Implement SamLookupIdsInDomain and SamrLookupIdsInDomain.
Modified: trunk/reactos/dll/win32/samlib/samlib.c trunk/reactos/dll/win32/samlib/samlib.spec trunk/reactos/dll/win32/samsrv/samrpc.c trunk/reactos/include/ddk/ntsam.h
Modified: trunk/reactos/dll/win32/samlib/samlib.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.c?r... ============================================================================== --- trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] Sat Aug 11 19:41:17 2012 @@ -648,6 +648,116 @@
NTSTATUS NTAPI +SamLookupIdsInDomain(IN SAM_HANDLE DomainHandle, + IN ULONG Count, + IN PULONG RelativeIds, + OUT PUNICODE_STRING *Names, + OUT PSID_NAME_USE *Use) +{ + SAMPR_RETURNED_USTRING_ARRAY NamesBuffer = {0, NULL}; + SAMPR_ULONG_ARRAY UseBuffer = {0, NULL}; + ULONG i; + NTSTATUS Status; + + TRACE("SamLookupIdsInDomain(%p %lu %p %p %p)\n", + DomainHandle, Count, RelativeIds, Names, Use); + + *Names = NULL; + *Use = NULL; + + RpcTryExcept + { + Status = SamrLookupIdsInDomain((SAMPR_HANDLE)DomainHandle, + Count, + RelativeIds, + &NamesBuffer, + &UseBuffer); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + if (NT_SUCCESS(Status)) + { + *Names = midl_user_allocate(Count * sizeof(RPC_UNICODE_STRING)); + if (*Names == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + for (i = 0; i < Count; i++) + { + (*Names)[i].Buffer = midl_user_allocate(NamesBuffer.Element[i].MaximumLength); + if ((*Names)[i].Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + } + + *Use = midl_user_allocate(Count * sizeof(SID_NAME_USE)); + if (*Use == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + for (i = 0; i < Count; i++) + { + (*Names)[i].Length = NamesBuffer.Element[i].Length; + (*Names)[i].MaximumLength = NamesBuffer.Element[i].MaximumLength; + + RtlCopyMemory((*Names)[i].Buffer, + NamesBuffer.Element[i].Buffer, + NamesBuffer.Element[i].Length); + } + + RtlCopyMemory(*Use, + UseBuffer.Element, + Count * sizeof(SID_NAME_USE)); + } + +done: + if (!NT_SUCCESS(Status)) + { + if (*Names != NULL) + { + for (i = 0; i < Count; i++) + { + if ((*Names)[i].Buffer != NULL) + midl_user_free((*Names)[i].Buffer); + } + + midl_user_free(*Names); + } + + if (*Use != NULL) + midl_user_free(*Use); + } + + if (NamesBuffer.Element != NULL) + { + for (i = 0; i < NamesBuffer.Count; i++) + { + if (NamesBuffer.Element[i].Buffer != NULL) + midl_user_free(NamesBuffer.Element[i].Buffer); + } + + midl_user_free(NamesBuffer.Element); + } + + if (UseBuffer.Element != NULL) + midl_user_free(UseBuffer.Element); + + return 0; +} + + +NTSTATUS +NTAPI SamLookupNamesInDomain(IN SAM_HANDLE DomainHandle, IN ULONG Count, IN PUNICODE_STRING Names, @@ -664,9 +774,6 @@ *RelativeIds = NULL; *Use = NULL;
- RidBuffer.Element = NULL; - UseBuffer.Element = NULL; - RpcTryExcept { Status = SamrLookupNamesInDomain((SAMPR_HANDLE)DomainHandle,
Modified: trunk/reactos/dll/win32/samlib/samlib.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.spe... ============================================================================== --- trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] Sat Aug 11 19:41:17 2012 @@ -26,7 +26,7 @@ @ stdcall SamGetMembersInAlias(ptr ptr ptr) @ stub SamGetMembersInGroup @ stdcall SamLookupDomainInSamServer(ptr ptr ptr) -@ stub SamLookupIdsInDomain +@ stdcall SamLookupIdsInDomain(ptr long ptr ptr ptr) @ stdcall SamLookupNamesInDomain(ptr long ptr ptr ptr) @ stdcall SamOpenAlias(ptr long long ptr) @ stdcall SamOpenDomain(ptr long ptr ptr)
Modified: trunk/reactos/dll/win32/samsrv/samrpc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samrpc.c?r... ============================================================================== --- trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] Sat Aug 11 19:41:17 2012 @@ -2925,6 +2925,9 @@ SampRegCloseKey(AccountsKeyHandle); }
+ if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) + break; + /* Return alias account */ if (NT_SUCCESS(Status) && RelativeId != 0) { @@ -2961,6 +2964,9 @@ SampRegCloseKey(AccountsKeyHandle); }
+ if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) + break; + /* Return group account */ if (NT_SUCCESS(Status) && RelativeId != 0) { @@ -2997,6 +3003,9 @@ SampRegCloseKey(AccountsKeyHandle); }
+ if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) + break; + /* Return user account */ if (NT_SUCCESS(Status) && RelativeId != 0) { @@ -3050,13 +3059,276 @@ NTSTATUS NTAPI SamrLookupIdsInDomain(IN SAMPR_HANDLE DomainHandle, - IN unsigned long Count, - IN unsigned long *RelativeIds, + IN ULONG Count, + IN ULONG *RelativeIds, OUT PSAMPR_RETURNED_USTRING_ARRAY Names, OUT PSAMPR_ULONG_ARRAY Use) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAM_DB_OBJECT DomainObject; + WCHAR RidString[9]; + HANDLE AccountsKeyHandle; + HANDLE AccountKeyHandle; + ULONG MappedCount = 0; + ULONG DataLength; + ULONG i; + NTSTATUS Status; + + TRACE("SamrLookupIdsInDomain(%p %lu %p %p %p)\n", + DomainHandle, Count, RelativeIds, Names, Use); + + /* Validate the domain handle */ + Status = SampValidateDbObject(DomainHandle, + SamDbDomainObject, + DOMAIN_LOOKUP, + &DomainObject); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + + Names->Count = 0; + Use->Count = 0; + + if (Count == 0) + return STATUS_SUCCESS; + + /* Allocate the names array */ + Names->Element = midl_user_allocate(Count * sizeof(ULONG)); + if (Names->Element == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + /* Allocate the use array */ + Use->Element = midl_user_allocate(Count * sizeof(ULONG)); + if (Use->Element == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Names->Count = Count; + Use->Count = Count; + + for (i = 0; i < Count; i++) + { + TRACE("RID: %lu\n", RelativeIds[i]); + + swprintf(RidString, L"%08lx", RelativeIds[i]); + + /* Lookup aliases */ + Status = SampRegOpenKey(DomainObject->KeyHandle, + L"Aliases", + KEY_READ, + &AccountsKeyHandle); + if (NT_SUCCESS(Status)) + { + Status = SampRegOpenKey(AccountsKeyHandle, + RidString, + KEY_READ, + &AccountKeyHandle); + if (NT_SUCCESS(Status)) + { + DataLength = 0; + Status = SampRegQueryValue(AccountKeyHandle, + L"Name", + NULL, + NULL, + &DataLength); + if (NT_SUCCESS(Status)) + { + Names->Element[i].Buffer = midl_user_allocate(DataLength); + if (Names->Element[i].Buffer == NULL) + Status = STATUS_INSUFFICIENT_RESOURCES; + + if (NT_SUCCESS(Status)) + { + Names->Element[i].MaximumLength = DataLength; + Names->Element[i].Length = DataLength - sizeof(WCHAR); + + Status = SampRegQueryValue(AccountKeyHandle, + L"Name", + NULL, + Names->Element[i].Buffer, + &DataLength); + } + } + + SampRegCloseKey(AccountKeyHandle); + } + + SampRegCloseKey(AccountsKeyHandle); + } + + if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) + break; + + /* Return alias account */ + if (NT_SUCCESS(Status) && Names->Element[i].Buffer != NULL) + { + TRACE("Name: %S\n", Names->Element[i].Buffer); + Use->Element[i] = SidTypeAlias; + MappedCount++; + continue; + } + + /* Lookup groups */ + Status = SampRegOpenKey(DomainObject->KeyHandle, + L"Groups", + KEY_READ, + &AccountsKeyHandle); + if (NT_SUCCESS(Status)) + { + Status = SampRegOpenKey(AccountsKeyHandle, + RidString, + KEY_READ, + &AccountKeyHandle); + if (NT_SUCCESS(Status)) + { + DataLength = 0; + Status = SampRegQueryValue(AccountKeyHandle, + L"Name", + NULL, + NULL, + &DataLength); + if (NT_SUCCESS(Status)) + { + Names->Element[i].Buffer = midl_user_allocate(DataLength); + if (Names->Element[i].Buffer == NULL) + Status = STATUS_INSUFFICIENT_RESOURCES; + + if (NT_SUCCESS(Status)) + { + Names->Element[i].MaximumLength = DataLength; + Names->Element[i].Length = DataLength - sizeof(WCHAR); + + Status = SampRegQueryValue(AccountKeyHandle, + L"Name", + NULL, + Names->Element[i].Buffer, + &DataLength); + } + } + + SampRegCloseKey(AccountKeyHandle); + } + + SampRegCloseKey(AccountsKeyHandle); + } + + if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) + break; + + /* Return group account */ + if (NT_SUCCESS(Status) && Names->Element[i].Buffer != NULL) + { + TRACE("Name: %S\n", Names->Element[i].Buffer); + Use->Element[i] = SidTypeGroup; + MappedCount++; + continue; + } + + /* Lookup users */ + Status = SampRegOpenKey(DomainObject->KeyHandle, + L"Users", + KEY_READ, + &AccountsKeyHandle); + if (NT_SUCCESS(Status)) + { + Status = SampRegOpenKey(AccountsKeyHandle, + RidString, + KEY_READ, + &AccountKeyHandle); + if (NT_SUCCESS(Status)) + { + DataLength = 0; + Status = SampRegQueryValue(AccountKeyHandle, + L"Name", + NULL, + NULL, + &DataLength); + if (NT_SUCCESS(Status)) + { + TRACE("DataLength: %lu\n", DataLength); + + Names->Element[i].Buffer = midl_user_allocate(DataLength); + if (Names->Element[i].Buffer == NULL) + Status = STATUS_INSUFFICIENT_RESOURCES; + + if (NT_SUCCESS(Status)) + { + Names->Element[i].MaximumLength = DataLength; + Names->Element[i].Length = DataLength - sizeof(WCHAR); + + Status = SampRegQueryValue(AccountKeyHandle, + L"Name", + NULL, + Names->Element[i].Buffer, + &DataLength); + } + } + + SampRegCloseKey(AccountKeyHandle); + } + + SampRegCloseKey(AccountsKeyHandle); + } + + if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) + break; + + /* Return user account */ + if (NT_SUCCESS(Status) && Names->Element[i].Buffer != NULL) + { + TRACE("Name: %S\n", Names->Element[i].Buffer); + Use->Element[i] = SidTypeUser; + MappedCount++; + continue; + } + + /* Return unknown account */ + Use->Element[i] = SidTypeUnknown; + } + +done: + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + Status = STATUS_SUCCESS; + + if (NT_SUCCESS(Status)) + { + if (MappedCount == 0) + Status = STATUS_NONE_MAPPED; + else if (MappedCount < Count) + Status = STATUS_SOME_NOT_MAPPED; + } + else + { + if (Names->Element != NULL) + { + for (i = 0; i < Count; i++) + { + if (Names->Element[i].Buffer != NULL) + midl_user_free(Names->Element[i].Buffer); + } + + midl_user_free(Names->Element); + Names->Element = NULL; + } + + Names->Count = 0; + + if (Use->Element != NULL) + { + midl_user_free(Use->Element); + Use->Element = NULL; + } + + Use->Count = 0; + } + + return Status; }
Modified: trunk/reactos/include/ddk/ntsam.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/ntsam.h?rev=570... ============================================================================== --- trunk/reactos/include/ddk/ntsam.h [iso-8859-1] (original) +++ trunk/reactos/include/ddk/ntsam.h [iso-8859-1] Sat Aug 11 19:41:17 2012 @@ -426,6 +426,14 @@
NTSTATUS NTAPI +SamLookupIdsInDomain(IN SAM_HANDLE DomainHandle, + IN ULONG Count, + IN PULONG RelativeIds, + OUT PUNICODE_STRING *Names, + OUT PSID_NAME_USE *Use); + +NTSTATUS +NTAPI SamLookupNamesInDomain(IN SAM_HANDLE DomainHandle, IN ULONG Count, IN PUNICODE_STRING Names,