[SAMLIB/SAMSRV]

- Implement SamLookupIdsInDomain and SamrLookupIdsInDomain.

svn path=/trunk/; revision=57057
This commit is contained in:
Eric Kohl 2012-08-11 19:41:17 +00:00
parent 67f22b7b53
commit 0015122a38
4 changed files with 395 additions and 8 deletions

View file

@ -646,6 +646,116 @@ SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
}
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,
@ -664,9 +774,6 @@ SamLookupNamesInDomain(IN SAM_HANDLE DomainHandle,
*RelativeIds = NULL;
*Use = NULL;
RidBuffer.Element = NULL;
UseBuffer.Element = NULL;
RpcTryExcept
{
Status = SamrLookupNamesInDomain((SAMPR_HANDLE)DomainHandle,

View file

@ -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)

View file

@ -2925,6 +2925,9 @@ SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle,
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 @@ SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle,
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 @@ SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle,
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 @@ done:
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;
}

View file

@ -424,6 +424,14 @@ SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
IN PUNICODE_STRING Name,
OUT PSID *DomainId);
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,