2013-01-12 16:22:46 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: Local Security Authority Server DLL
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
|
|
* FILE: dll/win32/samsrv/domain.c
|
|
|
|
* PURPOSE: Domain specific helper functions
|
|
|
|
* COPYRIGHT: Copyright 2013 Eric Kohl
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "samsrv.h"
|
|
|
|
|
|
|
|
/* FUNCTIONS ***************************************************************/
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
SampSetAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
|
|
|
|
IN LPCWSTR lpContainerName,
|
|
|
|
IN LPCWSTR lpAccountName,
|
|
|
|
IN ULONG ulRelativeId)
|
|
|
|
{
|
|
|
|
HANDLE ContainerKeyHandle = NULL;
|
|
|
|
HANDLE NamesKeyHandle = NULL;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
TRACE("SampSetAccountNameInDomain()\n");
|
|
|
|
|
|
|
|
/* Open the container key */
|
2013-09-01 15:46:00 +00:00
|
|
|
Status = SampRegOpenKey(DomainObject->KeyHandle,
|
|
|
|
lpContainerName,
|
|
|
|
KEY_ALL_ACCESS,
|
|
|
|
&ContainerKeyHandle);
|
2013-01-12 16:22:46 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
|
|
|
|
|
|
|
/* Open the 'Names' key */
|
2013-09-01 15:46:00 +00:00
|
|
|
Status = SampRegOpenKey(ContainerKeyHandle,
|
|
|
|
L"Names",
|
|
|
|
KEY_ALL_ACCESS,
|
|
|
|
&NamesKeyHandle);
|
2013-01-12 16:22:46 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Set the alias value */
|
2013-09-01 15:46:00 +00:00
|
|
|
Status = SampRegSetValue(NamesKeyHandle,
|
|
|
|
lpAccountName,
|
|
|
|
REG_DWORD,
|
|
|
|
(LPVOID)&ulRelativeId,
|
|
|
|
sizeof(ULONG));
|
2013-01-12 16:22:46 +00:00
|
|
|
|
|
|
|
done:
|
2013-09-01 15:46:00 +00:00
|
|
|
SampRegCloseKey(&NamesKeyHandle);
|
|
|
|
SampRegCloseKey(&ContainerKeyHandle);
|
2013-01-12 16:22:46 +00:00
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
SampRemoveAccountNameFromDomain(IN PSAM_DB_OBJECT DomainObject,
|
|
|
|
IN LPCWSTR lpContainerName,
|
|
|
|
IN LPCWSTR lpAccountName)
|
|
|
|
{
|
|
|
|
HANDLE ContainerKeyHandle = NULL;
|
|
|
|
HANDLE NamesKeyHandle = NULL;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
TRACE("(%S %S)\n", lpContainerName, lpAccountName);
|
|
|
|
|
|
|
|
/* Open the container key */
|
2013-09-01 15:46:00 +00:00
|
|
|
Status = SampRegOpenKey(DomainObject->KeyHandle,
|
|
|
|
lpContainerName,
|
|
|
|
KEY_ALL_ACCESS,
|
|
|
|
&ContainerKeyHandle);
|
2013-01-12 16:22:46 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
|
|
|
|
|
|
|
/* Open the 'Names' key */
|
2013-09-01 15:46:00 +00:00
|
|
|
Status = SampRegOpenKey(ContainerKeyHandle,
|
|
|
|
L"Names",
|
|
|
|
KEY_SET_VALUE,
|
|
|
|
&NamesKeyHandle);
|
2013-01-12 16:22:46 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Delete the account name value */
|
|
|
|
Status = SampRegDeleteValue(NamesKeyHandle,
|
|
|
|
lpAccountName);
|
|
|
|
|
|
|
|
done:
|
2013-09-01 15:46:00 +00:00
|
|
|
SampRegCloseKey(&NamesKeyHandle);
|
|
|
|
SampRegCloseKey(&ContainerKeyHandle);
|
2013-01-12 16:22:46 +00:00
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
|
|
|
|
IN LPCWSTR lpAccountName)
|
|
|
|
{
|
2013-09-01 15:46:00 +00:00
|
|
|
HANDLE AccountKey = NULL;
|
|
|
|
HANDLE NamesKey = NULL;
|
2013-01-12 16:22:46 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
TRACE("SampCheckAccountNameInDomain()\n");
|
|
|
|
|
|
|
|
Status = SampRegOpenKey(DomainObject->KeyHandle,
|
|
|
|
L"Aliases",
|
|
|
|
KEY_READ,
|
|
|
|
&AccountKey);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = SampRegOpenKey(AccountKey,
|
|
|
|
L"Names",
|
|
|
|
KEY_READ,
|
|
|
|
&NamesKey);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = SampRegQueryValue(NamesKey,
|
|
|
|
lpAccountName,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
if (Status == STATUS_SUCCESS)
|
|
|
|
{
|
2013-09-01 15:46:00 +00:00
|
|
|
SampRegCloseKey(&NamesKey);
|
2013-01-12 16:22:46 +00:00
|
|
|
Status = STATUS_ALIAS_EXISTS;
|
|
|
|
}
|
|
|
|
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-09-01 15:46:00 +00:00
|
|
|
SampRegCloseKey(&AccountKey);
|
2013-01-12 16:22:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
TRACE("Checking for alias account failed (Status 0x%08lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = SampRegOpenKey(DomainObject->KeyHandle,
|
|
|
|
L"Groups",
|
|
|
|
KEY_READ,
|
|
|
|
&AccountKey);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = SampRegOpenKey(AccountKey,
|
|
|
|
L"Names",
|
|
|
|
KEY_READ,
|
|
|
|
&NamesKey);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = SampRegQueryValue(NamesKey,
|
|
|
|
lpAccountName,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
if (Status == STATUS_SUCCESS)
|
|
|
|
{
|
2013-09-01 15:46:00 +00:00
|
|
|
SampRegCloseKey(&NamesKey);
|
2013-01-12 16:22:46 +00:00
|
|
|
Status = STATUS_ALIAS_EXISTS;
|
|
|
|
}
|
|
|
|
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-09-01 15:46:00 +00:00
|
|
|
SampRegCloseKey(&AccountKey);
|
2013-01-12 16:22:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
TRACE("Checking for group account failed (Status 0x%08lx)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = SampRegOpenKey(DomainObject->KeyHandle,
|
|
|
|
L"Users",
|
|
|
|
KEY_READ,
|
|
|
|
&AccountKey);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = SampRegOpenKey(AccountKey,
|
|
|
|
L"Names",
|
|
|
|
KEY_READ,
|
|
|
|
&NamesKey);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = SampRegQueryValue(NamesKey,
|
|
|
|
lpAccountName,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
if (Status == STATUS_SUCCESS)
|
|
|
|
{
|
2013-09-01 15:46:00 +00:00
|
|
|
SampRegCloseKey(&NamesKey);
|
2013-01-12 16:22:46 +00:00
|
|
|
Status = STATUS_ALIAS_EXISTS;
|
|
|
|
}
|
|
|
|
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-09-01 15:46:00 +00:00
|
|
|
SampRegCloseKey(&AccountKey);
|
2013-01-12 16:22:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
TRACE("Checking for user account failed (Status 0x%08lx)\n", Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2013-05-22 13:56:49 +00:00
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
SampRemoveMemberFromAllAliases(IN PSAM_DB_OBJECT DomainObject,
|
|
|
|
IN PRPC_SID MemberSid)
|
|
|
|
{
|
|
|
|
WCHAR AliasKeyName[64];
|
|
|
|
LPWSTR MemberSidString = NULL;
|
2013-09-01 15:46:00 +00:00
|
|
|
HANDLE AliasesKey = NULL;
|
|
|
|
HANDLE MembersKey = NULL;
|
|
|
|
HANDLE AliasKey = NULL;
|
2013-05-22 13:56:49 +00:00
|
|
|
ULONG Index;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
TRACE("(%p %p)\n", DomainObject, MemberSid);
|
|
|
|
|
|
|
|
ConvertSidToStringSidW(MemberSid, &MemberSidString);
|
|
|
|
TRACE("Member SID: %S\n", MemberSidString);
|
|
|
|
|
|
|
|
Status = SampRegOpenKey(DomainObject->KeyHandle,
|
|
|
|
L"Aliases",
|
|
|
|
KEY_READ,
|
|
|
|
&AliasesKey);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Index = 0;
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
Status = SampRegEnumerateSubKey(AliasesKey,
|
|
|
|
Index,
|
|
|
|
64,
|
|
|
|
AliasKeyName);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (Status == STATUS_NO_MORE_ENTRIES)
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
TRACE("Alias key name: %S\n", AliasKeyName);
|
|
|
|
|
|
|
|
Status = SampRegOpenKey(AliasesKey,
|
|
|
|
AliasKeyName,
|
|
|
|
KEY_READ,
|
|
|
|
&AliasKey);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = SampRegOpenKey(AliasKey,
|
|
|
|
L"Members",
|
|
|
|
KEY_WRITE,
|
|
|
|
&MembersKey);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = SampRegDeleteValue(AliasKey,
|
|
|
|
MemberSidString);
|
|
|
|
|
2013-09-01 15:46:00 +00:00
|
|
|
SampRegCloseKey(&MembersKey);
|
2013-05-22 13:56:49 +00:00
|
|
|
}
|
|
|
|
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
2013-09-01 15:46:00 +00:00
|
|
|
SampRegCloseKey(&AliasKey);
|
2013-05-22 13:56:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = SampRegOpenKey(AliasesKey,
|
|
|
|
L"Members",
|
|
|
|
KEY_WRITE,
|
|
|
|
&MembersKey);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = SampRegDeleteKey(MembersKey,
|
|
|
|
MemberSidString);
|
|
|
|
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
2013-09-01 15:46:00 +00:00
|
|
|
SampRegCloseKey(&MembersKey);
|
2013-05-22 13:56:49 +00:00
|
|
|
}
|
|
|
|
|
2013-09-01 15:46:00 +00:00
|
|
|
SampRegCloseKey(&AliasesKey);
|
2013-05-22 13:56:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (MemberSidString != NULL)
|
|
|
|
LocalFree(MemberSidString);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2013-10-26 09:09:31 +00:00
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
SampCreateAccountSid(IN PSAM_DB_OBJECT DomainObject,
|
|
|
|
IN ULONG ulRelativeId,
|
|
|
|
IN OUT PSID *AccountSid)
|
|
|
|
{
|
|
|
|
PSID DomainSid = NULL;
|
|
|
|
ULONG Length = 0;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = SampGetObjectAttribute(DomainObject,
|
|
|
|
L"SID",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&Length);
|
|
|
|
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
|
|
|
|
{
|
|
|
|
TRACE("Status 0x%08lx\n", Status);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
TRACE("Length: %lu\n", Length);
|
|
|
|
|
|
|
|
DomainSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
|
|
|
|
if (DomainSid == NULL)
|
|
|
|
{
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = SampGetObjectAttribute(DomainObject,
|
|
|
|
L"SID",
|
|
|
|
NULL,
|
|
|
|
DomainSid,
|
|
|
|
&Length);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
TRACE("Status 0x%08lx\n", Status);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
*AccountSid = AppendRidToSid(DomainSid,
|
|
|
|
ulRelativeId);
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (DomainSid != NULL)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2013-01-12 16:22:46 +00:00
|
|
|
/* EOF */
|