reactos/dll/win32/samsrv/alias.c

372 lines
10 KiB
C

/*
* PROJECT: Local Security Authority Server DLL
* LICENSE: GPL - See COPYING in the top level directory
* FILE: dll/win32/samsrv/alias.c
* PURPOSE: Alias specific helper functions
* COPYRIGHT: Copyright 2013 Eric Kohl
*/
#include "samsrv.h"
/* FUNCTIONS ***************************************************************/
NTSTATUS
SampOpenAliasObject(IN PSAM_DB_OBJECT DomainObject,
IN ULONG AliasId,
IN ACCESS_MASK DesiredAccess,
OUT PSAM_DB_OBJECT *AliasObject)
{
WCHAR szRid[9];
TRACE("(%p %lu %lx %p)\n",
DomainObject, AliasId, DesiredAccess, AliasObject);
/* Convert the RID into a string (hex) */
swprintf(szRid, L"%08lX", AliasId);
/* Create the user object */
return SampOpenDbObject(DomainObject,
L"Aliases",
szRid,
AliasId,
SamDbAliasObject,
DesiredAccess,
AliasObject);
}
NTSTATUS
SampAddMemberToAlias(IN PSAM_DB_OBJECT AliasObject,
IN PRPC_SID MemberId)
{
LPWSTR MemberIdString = NULL;
HANDLE MembersKeyHandle = NULL;
HANDLE MemberKeyHandle = NULL;
ULONG MemberIdLength;
NTSTATUS Status;
TRACE("(%p %p)\n",
AliasObject, MemberId);
ConvertSidToStringSidW(MemberId, &MemberIdString);
TRACE("Member SID: %S\n", MemberIdString);
MemberIdLength = RtlLengthSid(MemberId);
Status = SampRegCreateKey(AliasObject->KeyHandle,
L"Members",
KEY_WRITE,
&MembersKeyHandle);
if (!NT_SUCCESS(Status))
{
TRACE("SampRegCreateKey failed with status 0x%08lx\n", Status);
goto done;
}
Status = SampRegSetValue(MembersKeyHandle,
MemberIdString,
REG_BINARY,
MemberId,
MemberIdLength);
if (!NT_SUCCESS(Status))
{
TRACE("SampRegSetValue failed with status 0x%08lx\n", Status);
goto done;
}
Status = SampRegCreateKey(AliasObject->MembersKeyHandle,
MemberIdString,
KEY_WRITE,
&MemberKeyHandle);
if (!NT_SUCCESS(Status))
{
TRACE("SampRegCreateKey failed with status 0x%08lx\n", Status);
goto done;
}
Status = SampRegSetValue(MemberKeyHandle,
AliasObject->Name,
REG_BINARY,
MemberId,
MemberIdLength);
if (!NT_SUCCESS(Status))
{
TRACE("SampRegSetValue failed with status 0x%08lx\n", Status);
goto done;
}
done:
SampRegCloseKey(&MemberKeyHandle);
SampRegCloseKey(&MembersKeyHandle);
if (MemberIdString != NULL)
LocalFree(MemberIdString);
return Status;
}
NTSTATUS
NTAPI
SampRemoveMemberFromAlias(IN PSAM_DB_OBJECT AliasObject,
IN PRPC_SID MemberId)
{
LPWSTR MemberIdString = NULL;
HANDLE MembersKeyHandle = NULL;
HANDLE MemberKeyHandle = NULL;
ULONG ulValueCount;
NTSTATUS Status;
TRACE("(%p %p)\n",
AliasObject, MemberId);
ConvertSidToStringSidW(MemberId, &MemberIdString);
TRACE("Member SID: %S\n", MemberIdString);
Status = SampRegOpenKey(AliasObject->MembersKeyHandle,
MemberIdString,
KEY_WRITE | KEY_QUERY_VALUE,
&MemberKeyHandle);
if (!NT_SUCCESS(Status))
{
TRACE("SampRegOpenKey failed with status 0x%08lx\n", Status);
goto done;
}
Status = SampRegDeleteValue(MemberKeyHandle,
AliasObject->Name);
if (!NT_SUCCESS(Status))
{
TRACE("SampRegDeleteValue failed with status 0x%08lx\n", Status);
goto done;
}
Status = SampRegQueryKeyInfo(MemberKeyHandle,
NULL,
&ulValueCount);
if (!NT_SUCCESS(Status))
{
TRACE("SampRegQueryKeyInfo failed with status 0x%08lx\n", Status);
goto done;
}
if (ulValueCount == 0)
{
SampRegCloseKey(&MemberKeyHandle);
Status = SampRegDeleteKey(AliasObject->MembersKeyHandle,
MemberIdString);
if (!NT_SUCCESS(Status))
{
TRACE("SampRegDeleteKey failed with status 0x%08lx\n", Status);
goto done;
}
}
Status = SampRegOpenKey(AliasObject->KeyHandle,
L"Members",
KEY_WRITE | KEY_QUERY_VALUE,
&MembersKeyHandle);
if (!NT_SUCCESS(Status))
{
TRACE("SampRegOpenKey failed with status 0x%08lx\n", Status);
goto done;
}
Status = SampRegDeleteValue(MembersKeyHandle,
MemberIdString);
if (!NT_SUCCESS(Status))
{
TRACE("SampRegDeleteValue failed with status 0x%08lx\n", Status);
goto done;
}
Status = SampRegQueryKeyInfo(MembersKeyHandle,
NULL,
&ulValueCount);
if (!NT_SUCCESS(Status))
{
TRACE("SampRegQueryKeyInfo failed with status 0x%08lx\n", Status);
goto done;
}
if (ulValueCount == 0)
{
SampRegCloseKey(&MembersKeyHandle);
Status = SampRegDeleteKey(AliasObject->KeyHandle,
L"Members");
if (!NT_SUCCESS(Status))
{
TRACE("SampRegDeleteKey failed with status 0x%08lx\n", Status);
goto done;
}
}
done:
SampRegCloseKey(&MemberKeyHandle);
SampRegCloseKey(&MembersKeyHandle);
if (MemberIdString != NULL)
LocalFree(MemberIdString);
return Status;
}
NTSTATUS
SampGetMembersInAlias(IN PSAM_DB_OBJECT AliasObject,
OUT PULONG MemberCount,
OUT PSAMPR_SID_INFORMATION *MemberArray)
{
HANDLE MembersKeyHandle = NULL;
PSAMPR_SID_INFORMATION Members = NULL;
ULONG Count = 0;
ULONG DataLength;
ULONG Index;
NTSTATUS Status;
/* Open the members key of the alias object */
Status = SampRegOpenKey(AliasObject->KeyHandle,
L"Members",
KEY_READ,
&MembersKeyHandle);
if (!NT_SUCCESS(Status))
{
ERR("SampRegOpenKey failed with status 0x%08lx\n", Status);
goto done;
}
/* Get the number of members */
Status = SampRegQueryKeyInfo(MembersKeyHandle,
NULL,
&Count);
if (!NT_SUCCESS(Status))
{
ERR("SampRegQueryKeyInfo failed with status 0x%08lx\n", Status);
goto done;
}
/* Allocate the member array */
Members = midl_user_allocate(Count * sizeof(SAMPR_SID_INFORMATION));
if (Members == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
/* Enumerate the members */
Index = 0;
while (TRUE)
{
/* Get the size of the next SID */
DataLength = 0;
Status = SampRegEnumerateValue(MembersKeyHandle,
Index,
NULL,
NULL,
NULL,
NULL,
&DataLength);
if (!NT_SUCCESS(Status))
{
if (Status == STATUS_NO_MORE_ENTRIES)
Status = STATUS_SUCCESS;
break;
}
/* Allocate a buffer for the SID */
Members[Index].SidPointer = midl_user_allocate(DataLength);
if (Members[Index].SidPointer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
/* Read the SID into the buffer */
Status = SampRegEnumerateValue(MembersKeyHandle,
Index,
NULL,
NULL,
NULL,
(PVOID)Members[Index].SidPointer,
&DataLength);
if (!NT_SUCCESS(Status))
{
goto done;
}
Index++;
}
if (NT_SUCCESS(Status))
{
*MemberCount = Count;
*MemberArray = Members;
}
done:
return Status;
}
NTSTATUS
SampRemoveAllMembersFromAlias(IN PSAM_DB_OBJECT AliasObject)
{
HANDLE MembersKeyHandle = NULL;
PSAMPR_SID_INFORMATION MemberArray = NULL;
ULONG MemberCount = 0;
ULONG Index;
NTSTATUS Status;
TRACE("(%p)\n", AliasObject);
/* Open the members key of the alias object */
Status = SampRegOpenKey(AliasObject->KeyHandle,
L"Members",
KEY_READ,
&MembersKeyHandle);
if (!NT_SUCCESS(Status))
{
ERR("SampRegOpenKey failed (Status 0x%08lx)\n", Status);
goto done;
}
/* Get a list of all members of the alias */
Status = SampGetMembersInAlias(AliasObject,
&MemberCount,
&MemberArray);
if (!NT_SUCCESS(Status))
{
ERR("SampGetMembersInAlias failed (Status 0x%08lx)\n", Status);
goto done;
}
/* Remove all members from the alias */
for (Index = 0; Index < MemberCount; Index++)
{
Status = SampRemoveMemberFromAlias(AliasObject,
MemberArray[Index].SidPointer);
if (!NT_SUCCESS(Status))
goto done;
}
done:
if (MemberArray != NULL)
{
for (Index = 0; Index < MemberCount; Index++)
{
if (MemberArray[Index].SidPointer != NULL)
midl_user_free(MemberArray[Index].SidPointer);
}
midl_user_free(MemberArray);
}
SampRegCloseKey(&MembersKeyHandle);
return Status;
}
/* EOF */