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?…
==============================================================================
--- 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.sp…
==============================================================================
--- 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?…
==============================================================================
--- 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=57…
==============================================================================
--- 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,