mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
[SAMLIB]
- Implement SamCloseHandle, SamConnect and SamOpenDomain. [SAMSRV] - Implement SamrCloseHandle, SamrConnect and SamrOpenDomain. - Start the SAM RPC Server. svn path=/trunk/; revision=56661
This commit is contained in:
parent
8ea9a9d758
commit
203b0d7413
8 changed files with 975 additions and 19 deletions
|
@ -387,7 +387,21 @@ NTSTATUS
|
|||
NTAPI
|
||||
SamCloseHandle(IN SAM_HANDLE SamHandle)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamCloseHandle(%p)\n", SamHandle);
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrCloseHandle((SAMPR_HANDLE *)&SamHandle);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -397,7 +411,52 @@ SamConnect(IN OUT PUNICODE_STRING ServerName,
|
|||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamConnect(%p,%p,0x%08x,%p)\n",
|
||||
ServerName, ServerHandle, DesiredAccess, ObjectAttributes);
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrConnect((PSAMPR_SERVER_NAME)ServerName,
|
||||
(SAMPR_HANDLE *)ServerHandle,
|
||||
DesiredAccess);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamOpenDomain(IN SAM_HANDLE ServerHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN PSID DomainId,
|
||||
OUT PSAM_HANDLE DomainHandle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamOpenDomain(%p,0x%08x,%p,%p)\n",
|
||||
ServerHandle, DesiredAccess, DomainId, DomainHandle);
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrOpenDomain((SAMPR_HANDLE)ServerHandle,
|
||||
DesiredAccess,
|
||||
(PRPC_SID)DomainId,
|
||||
(SAMPR_HANDLE *)DomainHandle);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
@ stub SamLookupIdsInDomain
|
||||
@ stub SamLookupNamesInDomain
|
||||
@ stub SamOpenAlias
|
||||
@ stub SamOpenDomain
|
||||
@ stdcall SamOpenDomain(ptr long ptr ptr)
|
||||
@ stub SamOpenGroup
|
||||
@ stub SamOpenUser
|
||||
@ stub SamQueryDisplayInformation
|
||||
|
|
|
@ -8,6 +8,7 @@ add_rpc_files(server ${REACTOS_SOURCE_DIR}/include/reactos/idl/sam.idl)
|
|||
spec2def(samsrv.dll samsrv.spec ADD_IMPORTLIB)
|
||||
|
||||
list(APPEND SOURCE
|
||||
database.c
|
||||
samrpc.c
|
||||
samsrv.c
|
||||
setup.c
|
||||
|
|
672
reactos/dll/win32/samsrv/database.c
Normal file
672
reactos/dll/win32/samsrv/database.c
Normal file
|
@ -0,0 +1,672 @@
|
|||
/*
|
||||
* PROJECT: Local Security Authority Server DLL
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: dll/win32/samsrv/database.c
|
||||
* PURPOSE: SAM object database
|
||||
* COPYRIGHT: Copyright 2012 Eric Kohl
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include "samsrv.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(samsrv);
|
||||
|
||||
|
||||
/* GLOBALS *****************************************************************/
|
||||
|
||||
static HANDLE SamKeyHandle = NULL;
|
||||
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
static NTSTATUS
|
||||
SampOpenSamKey(VOID)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
L"\\Registry\\Machine\\SAM");
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = RtlpNtOpenKey(&SamKeyHandle,
|
||||
KEY_READ | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
|
||||
&ObjectAttributes,
|
||||
0);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static BOOLEAN
|
||||
LsapIsDatabaseInstalled(VOID)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE KeyHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
L"Policy");
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
SecurityKeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = RtlpNtOpenKey(&KeyHandle,
|
||||
KEY_READ,
|
||||
&ObjectAttributes,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
|
||||
NtClose(KeyHandle);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
LsapCreateDatabaseKeys(VOID)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE PolicyKeyHandle = NULL;
|
||||
HANDLE AccountsKeyHandle = NULL;
|
||||
HANDLE DomainsKeyHandle = NULL;
|
||||
HANDLE SecretsKeyHandle = NULL;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
TRACE("LsapInstallDatabase()\n");
|
||||
|
||||
/* Create the 'Policy' key */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
L"Policy");
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
SecurityKeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtCreateKey(&PolicyKeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("Failed to create the 'Policy' key (Status: 0x%08lx)\n", Status);
|
||||
goto Done;
|
||||
}
|
||||
|
||||
/* Create the 'Accounts' key */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
L"Accounts");
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
PolicyKeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtCreateKey(&AccountsKeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("Failed to create the 'Accounts' key (Status: 0x%08lx)\n", Status);
|
||||
goto Done;
|
||||
}
|
||||
|
||||
/* Create the 'Domains' key */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
L"Domains");
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
PolicyKeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtCreateKey(&DomainsKeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("Failed to create the 'Domains' key (Status: 0x%08lx)\n", Status);
|
||||
goto Done;
|
||||
}
|
||||
|
||||
/* Create the 'Secrets' key */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
L"Secrets");
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
PolicyKeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtCreateKey(&SecretsKeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("Failed to create the 'Secrets' key (Status: 0x%08lx)\n", Status);
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Done:
|
||||
if (SecretsKeyHandle != NULL)
|
||||
NtClose(SecretsKeyHandle);
|
||||
|
||||
if (DomainsKeyHandle != NULL)
|
||||
NtClose(DomainsKeyHandle);
|
||||
|
||||
if (AccountsKeyHandle != NULL)
|
||||
NtClose(AccountsKeyHandle);
|
||||
|
||||
if (PolicyKeyHandle != NULL)
|
||||
NtClose(PolicyKeyHandle);
|
||||
|
||||
TRACE("LsapInstallDatabase() done (Status: 0x%08lx)\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
LsapCreateDatabaseObjects(VOID)
|
||||
{
|
||||
PLSA_DB_OBJECT PolicyObject;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Open the 'Policy' object */
|
||||
Status = LsapOpenDbObject(NULL,
|
||||
L"Policy",
|
||||
LsaDbPolicyObject,
|
||||
0,
|
||||
&PolicyObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
LsapSetObjectAttribute(PolicyObject,
|
||||
L"PolPrDmN",
|
||||
NULL,
|
||||
0);
|
||||
|
||||
LsapSetObjectAttribute(PolicyObject,
|
||||
L"PolPrDmS",
|
||||
NULL,
|
||||
0);
|
||||
|
||||
LsapSetObjectAttribute(PolicyObject,
|
||||
L"PolAcDmN",
|
||||
NULL,
|
||||
0);
|
||||
|
||||
LsapSetObjectAttribute(PolicyObject,
|
||||
L"PolAcDmS",
|
||||
NULL,
|
||||
0);
|
||||
|
||||
/* Close the 'Policy' object */
|
||||
LsapCloseDbObject(PolicyObject);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
LsapUpdateDatabase(VOID)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
NTSTATUS
|
||||
SampInitDatabase(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SampInitDatabase()\n");
|
||||
|
||||
Status = SampOpenSamKey();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("Failed to open the SAM key (Status: 0x%08lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!LsapIsDatabaseInstalled())
|
||||
{
|
||||
Status = LsapCreateDatabaseKeys();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("Failed to create the LSA database keys (Status: 0x%08lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = LsapCreateDatabaseObjects();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("Failed to create the LSA database objects (Status: 0x%08lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = LsapUpdateDatabase();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ERR("Failed to update the LSA database (Status: 0x%08lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TRACE("SampInitDatabase() done\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
SampCreateDbObject(IN PSAM_DB_OBJECT ParentObject,
|
||||
IN LPWSTR ContainerName,
|
||||
IN LPWSTR ObjectName,
|
||||
IN SAM_DB_OBJECT_TYPE ObjectType,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
OUT PSAM_DB_OBJECT *DbObject)
|
||||
{
|
||||
PSAM_DB_OBJECT NewObject;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE ParentKeyHandle;
|
||||
HANDLE ObjectKeyHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (DbObject == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (ParentObject == NULL)
|
||||
ParentKeyHandle = SamKeyHandle;
|
||||
else
|
||||
ParentKeyHandle = ParentObject->KeyHandle;
|
||||
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
ObjectName);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
ParentKeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtCreateKey(&ObjectKeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
NewObject = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
sizeof(SAM_DB_OBJECT));
|
||||
if (NewObject == NULL)
|
||||
{
|
||||
NtClose(ObjectKeyHandle);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
NewObject->Signature = SAMP_DB_SIGNATURE;
|
||||
NewObject->RefCount = 1;
|
||||
NewObject->ObjectType = ObjectType;
|
||||
NewObject->Access = DesiredAccess;
|
||||
NewObject->KeyHandle = ObjectKeyHandle;
|
||||
NewObject->ParentObject = ParentObject;
|
||||
|
||||
if (ParentObject != NULL)
|
||||
ParentObject->RefCount++;
|
||||
|
||||
*DbObject = NewObject;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
SampOpenDbObject(IN PSAM_DB_OBJECT ParentObject,
|
||||
IN LPWSTR ContainerName,
|
||||
IN LPWSTR ObjectName,
|
||||
IN SAM_DB_OBJECT_TYPE ObjectType,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
OUT PSAM_DB_OBJECT *DbObject)
|
||||
{
|
||||
PSAM_DB_OBJECT NewObject;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE ParentKeyHandle;
|
||||
HANDLE ContainerKeyHandle = NULL;
|
||||
HANDLE ObjectKeyHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (DbObject == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (ParentObject == NULL)
|
||||
ParentKeyHandle = SamKeyHandle;
|
||||
else
|
||||
ParentKeyHandle = ParentObject->KeyHandle;
|
||||
|
||||
if (ContainerName != NULL)
|
||||
{
|
||||
/* Open the container key */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
ContainerName);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
ParentKeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenKey(&ContainerKeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Open the object key */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
ObjectName);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
ContainerKeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenKey(&ObjectKeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes);
|
||||
|
||||
NtClose(ContainerKeyHandle);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Open the object key */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
ObjectName);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
ParentKeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenKey(&ObjectKeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
NewObject = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
sizeof(SAM_DB_OBJECT));
|
||||
if (NewObject == NULL)
|
||||
{
|
||||
NtClose(ObjectKeyHandle);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
NewObject->Signature = SAMP_DB_SIGNATURE;
|
||||
NewObject->RefCount = 1;
|
||||
NewObject->ObjectType = ObjectType;
|
||||
NewObject->Access = DesiredAccess;
|
||||
NewObject->KeyHandle = ObjectKeyHandle;
|
||||
NewObject->ParentObject = ParentObject;
|
||||
|
||||
if (ParentObject != NULL)
|
||||
ParentObject->RefCount++;
|
||||
|
||||
*DbObject = NewObject;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
SampValidateDbObject(SAMPR_HANDLE Handle,
|
||||
SAM_DB_OBJECT_TYPE ObjectType,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
PSAM_DB_OBJECT *DbObject)
|
||||
{
|
||||
PSAM_DB_OBJECT LocalObject = (PSAM_DB_OBJECT)Handle;
|
||||
BOOLEAN bValid = FALSE;
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
if (LocalObject->Signature == SAMP_DB_SIGNATURE)
|
||||
{
|
||||
if ((ObjectType == SamDbIgnoreObject) ||
|
||||
(LocalObject->ObjectType == ObjectType))
|
||||
bValid = TRUE;
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
bValid = FALSE;
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
if (bValid == FALSE)
|
||||
return STATUS_INVALID_HANDLE;
|
||||
|
||||
if (DesiredAccess != 0)
|
||||
{
|
||||
/* Check for granted access rights */
|
||||
if ((LocalObject->Access & DesiredAccess) != DesiredAccess)
|
||||
{
|
||||
ERR("SampValidateDbObject access check failed %08lx %08lx\n",
|
||||
LocalObject->Access, DesiredAccess);
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
|
||||
if (DbObject != NULL)
|
||||
*DbObject = LocalObject;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
SampCloseDbObject(PSAM_DB_OBJECT DbObject)
|
||||
{
|
||||
PSAM_DB_OBJECT ParentObject = NULL;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DbObject->RefCount--;
|
||||
|
||||
if (DbObject->RefCount > 0)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
if (DbObject->KeyHandle != NULL)
|
||||
NtClose(DbObject->KeyHandle);
|
||||
|
||||
if (DbObject->ParentObject != NULL)
|
||||
ParentObject = DbObject->ParentObject;
|
||||
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject);
|
||||
|
||||
if (ParentObject != NULL)
|
||||
{
|
||||
ParentObject->RefCount--;
|
||||
|
||||
if (ParentObject->RefCount == 0)
|
||||
Status = SampCloseDbObject(ParentObject);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
NTSTATUS
|
||||
LsapSetObjectAttribute(PLSA_DB_OBJECT DbObject,
|
||||
LPWSTR AttributeName,
|
||||
LPVOID AttributeData,
|
||||
ULONG AttributeSize)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE AttributeKey;
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
AttributeName);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
DbObject->KeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtCreateKey(&AttributeKey,
|
||||
KEY_SET_VALUE,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = RtlpNtSetValueKey(AttributeKey,
|
||||
REG_NONE,
|
||||
AttributeData,
|
||||
AttributeSize);
|
||||
|
||||
NtClose(AttributeKey);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
LsapGetObjectAttribute(PLSA_DB_OBJECT DbObject,
|
||||
LPWSTR AttributeName,
|
||||
LPVOID AttributeData,
|
||||
PULONG AttributeSize)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE AttributeKey;
|
||||
ULONG ValueSize;
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
AttributeName);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
DbObject->KeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenKey(&AttributeKey,
|
||||
KEY_QUERY_VALUE,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
ValueSize = *AttributeSize;
|
||||
Status = RtlpNtQueryValueKey(AttributeKey,
|
||||
NULL,
|
||||
NULL,
|
||||
&ValueSize,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if (AttributeData == NULL || *AttributeSize == 0)
|
||||
{
|
||||
*AttributeSize = ValueSize;
|
||||
Status = STATUS_SUCCESS;
|
||||
goto Done;
|
||||
}
|
||||
else if (*AttributeSize < ValueSize)
|
||||
{
|
||||
*AttributeSize = ValueSize;
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Status = RtlpNtQueryValueKey(AttributeKey,
|
||||
NULL,
|
||||
AttributeData,
|
||||
&ValueSize,
|
||||
0);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
*AttributeSize = ValueSize;
|
||||
}
|
||||
|
||||
Done:
|
||||
NtClose(AttributeKey);
|
||||
|
||||
return Status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
|
@ -13,9 +13,49 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(samsrv);
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
static SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
VOID
|
||||
SampStartRpcServer(VOID)
|
||||
{
|
||||
RPC_STATUS Status;
|
||||
|
||||
TRACE("SampStartRpcServer() called\n");
|
||||
|
||||
Status = RpcServerUseProtseqEpW(L"ncacn_np",
|
||||
10,
|
||||
L"\\pipe\\samr",
|
||||
NULL);
|
||||
if (Status != RPC_S_OK)
|
||||
{
|
||||
WARN("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
|
||||
return;
|
||||
}
|
||||
|
||||
Status = RpcServerRegisterIf(samr_v1_0_s_ifspec,
|
||||
NULL,
|
||||
NULL);
|
||||
if (Status != RPC_S_OK)
|
||||
{
|
||||
WARN("RpcServerRegisterIf() failed (Status %lx)\n", Status);
|
||||
return;
|
||||
}
|
||||
|
||||
Status = RpcServerListen(1, 20, TRUE);
|
||||
if (Status != RPC_S_OK)
|
||||
{
|
||||
WARN("RpcServerListen() failed (Status %lx)\n", Status);
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE("SampStartRpcServer() done\n");
|
||||
}
|
||||
|
||||
|
||||
void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
|
||||
{
|
||||
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
|
||||
|
@ -38,8 +78,24 @@ SamrConnect(IN PSAMPR_SERVER_NAME ServerName,
|
|||
OUT SAMPR_HANDLE *ServerHandle,
|
||||
IN ACCESS_MASK DesiredAccess)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PSAM_DB_OBJECT ServerObject;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamrConnect(%p %p %lx)\n",
|
||||
ServerName, ServerHandle, DesiredAccess);
|
||||
|
||||
Status = SampOpenDbObject(NULL,
|
||||
NULL,
|
||||
L"SAM",
|
||||
SamDbServerObject,
|
||||
DesiredAccess,
|
||||
&ServerObject);
|
||||
if (NT_SUCCESS(Status))
|
||||
*ServerHandle = (SAMPR_HANDLE)ServerObject;
|
||||
|
||||
TRACE("SamrConnect done (Status 0x%08lx)\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Function 1 */
|
||||
|
@ -47,8 +103,24 @@ NTSTATUS
|
|||
NTAPI
|
||||
SamrCloseHandle(IN OUT SAMPR_HANDLE *SamHandle)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PSAM_DB_OBJECT DbObject;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
TRACE("SamrCloseHandle(%p)\n", SamHandle);
|
||||
|
||||
Status = SampValidateDbObject(*SamHandle,
|
||||
SamDbIgnoreObject,
|
||||
0,
|
||||
&DbObject);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
Status = SampCloseDbObject(DbObject);
|
||||
*SamHandle = NULL;
|
||||
}
|
||||
|
||||
TRACE("SamrCloseHandle done (Status 0x%08lx)\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Function 2 */
|
||||
|
@ -114,8 +186,67 @@ SamrOpenDomain(IN SAMPR_HANDLE ServerHandle,
|
|||
IN PRPC_SID DomainId,
|
||||
OUT SAMPR_HANDLE *DomainHandle)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PSAM_DB_OBJECT ServerObject;
|
||||
PSAM_DB_OBJECT DomainObject;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamrOpenDomain(%p %lx %p %p)\n",
|
||||
ServerHandle, DesiredAccess, DomainId, DomainHandle);
|
||||
|
||||
Status = SampValidateDbObject(ServerHandle,
|
||||
SamDbServerObject,
|
||||
SAM_SERVER_LOOKUP_DOMAIN,
|
||||
&ServerObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
/* Validate the Domain SID */
|
||||
if ((DomainId->Revision != SID_REVISION) ||
|
||||
(DomainId->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) ||
|
||||
(memcmp(&DomainId->IdentifierAuthority, &NtSidAuthority, sizeof(SID_IDENTIFIER_AUTHORITY)) != 0))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* Open the domain object */
|
||||
if ((DomainId->SubAuthorityCount == 1) &&
|
||||
(DomainId->SubAuthority[0] == SECURITY_BUILTIN_DOMAIN_RID))
|
||||
{
|
||||
/* Builtin domain object */
|
||||
TRACE("Opening the builtin domain object.\n");
|
||||
|
||||
Status = SampOpenDbObject(ServerObject,
|
||||
L"Domains",
|
||||
L"Builtin",
|
||||
SamDbServerObject,
|
||||
DesiredAccess,
|
||||
&DomainObject);
|
||||
}
|
||||
else if ((DomainId->SubAuthorityCount == 4) &&
|
||||
(DomainId->SubAuthority[0] == SECURITY_NT_NON_UNIQUE))
|
||||
{
|
||||
/* Account domain object */
|
||||
TRACE("Opening the account domain object.\n");
|
||||
|
||||
/* FIXME: Check the account domain sub authorities!!! */
|
||||
|
||||
Status = SampOpenDbObject(ServerObject,
|
||||
L"Domains",
|
||||
L"Account",
|
||||
SamDbServerObject,
|
||||
DesiredAccess,
|
||||
&DomainObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No vaild domain SID */
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
*DomainHandle = (SAMPR_HANDLE)DomainObject;
|
||||
|
||||
TRACE("SamrOpenDomain done (Status 0x%08lx)\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Function 8 */
|
||||
|
@ -168,7 +299,7 @@ SamrEnumerateGroupsInDomain(IN SAMPR_HANDLE DomainHandle,
|
|||
|
||||
/* Function 12 */
|
||||
NTSTATUS
|
||||
__stdcall
|
||||
NTAPI
|
||||
SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
IN PRPC_UNICODE_STRING Name,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
|
@ -181,7 +312,7 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
|
|||
|
||||
/* Function 13 */
|
||||
NTSTATUS
|
||||
__stdcall
|
||||
NTAPI
|
||||
SamrEnumerateUsersInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
IN OUT unsigned long *EnumerationContext,
|
||||
IN unsigned long UserAccountControl,
|
||||
|
@ -195,7 +326,7 @@ SamrEnumerateUsersInDomain(IN SAMPR_HANDLE DomainHandle,
|
|||
|
||||
/* Function 14 */
|
||||
NTSTATUS
|
||||
__stdcall
|
||||
NTAPI
|
||||
SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
IN PRPC_UNICODE_STRING AccountName,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
|
@ -208,7 +339,7 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle,
|
|||
|
||||
/* Function 15 */
|
||||
NTSTATUS
|
||||
__stdcall
|
||||
NTAPI
|
||||
SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
IN OUT unsigned long *EnumerationContext,
|
||||
OUT PSAMPR_ENUMERATION_BUFFER *Buffer,
|
||||
|
@ -221,7 +352,7 @@ SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle,
|
|||
|
||||
/* Function 16 */
|
||||
NTSTATUS
|
||||
__stdcall
|
||||
NTAPI
|
||||
SamrGetAliasMembership(IN SAMPR_HANDLE DomainHandle,
|
||||
IN PSAMPR_PSID_ARRAY SidArray,
|
||||
OUT PSAMPR_ULONG_ARRAY Membership)
|
||||
|
@ -232,7 +363,7 @@ SamrGetAliasMembership(IN SAMPR_HANDLE DomainHandle,
|
|||
|
||||
/* Function 17 */
|
||||
NTSTATUS
|
||||
__stdcall
|
||||
NTAPI
|
||||
SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
IN unsigned long Count,
|
||||
IN RPC_UNICODE_STRING Names[],
|
||||
|
@ -245,7 +376,7 @@ SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle,
|
|||
|
||||
/* Function 18 */
|
||||
NTSTATUS
|
||||
__stdcall
|
||||
NTAPI
|
||||
SamrLookupIdsInDomain(IN SAMPR_HANDLE DomainHandle,
|
||||
IN unsigned long Count,
|
||||
IN unsigned long *RelativeIds,
|
||||
|
@ -258,7 +389,7 @@ SamrLookupIdsInDomain(IN SAMPR_HANDLE DomainHandle,
|
|||
|
||||
/* Function 19 */
|
||||
NTSTATUS
|
||||
__stdcall
|
||||
NTAPI
|
||||
SamrOpenGroup(IN SAMPR_HANDLE DomainHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN unsigned long GroupId,
|
||||
|
@ -270,7 +401,7 @@ SamrOpenGroup(IN SAMPR_HANDLE DomainHandle,
|
|||
|
||||
/* Function 20 */
|
||||
NTSTATUS
|
||||
__stdcall
|
||||
NTAPI
|
||||
SamrQueryInformationGroup(IN SAMPR_HANDLE GroupHandle,
|
||||
IN GROUP_INFORMATION_CLASS GroupInformationClass,
|
||||
OUT PSAMPR_GROUP_INFO_BUFFER *Buffer)
|
||||
|
@ -281,7 +412,7 @@ SamrQueryInformationGroup(IN SAMPR_HANDLE GroupHandle,
|
|||
|
||||
/* Function 21 */
|
||||
NTSTATUS
|
||||
__stdcall
|
||||
NTAPI
|
||||
SamrSetInformationGroup(IN SAMPR_HANDLE GroupHandle,
|
||||
IN GROUP_INFORMATION_CLASS GroupInformationClass,
|
||||
IN PSAMPR_GROUP_INFO_BUFFER Buffer)
|
||||
|
|
|
@ -34,8 +34,19 @@ SamIInitialize(VOID)
|
|||
TRACE("SamIInitialize() called\n");
|
||||
|
||||
if (SampIsSetupRunning())
|
||||
{
|
||||
Status = SampInitializeRegistry();
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Initialize the SAM database */
|
||||
Status = SampInitDatabase();
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
/* Start the RPC server */
|
||||
SampStartRpcServer();
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
#define WIN32_NO_STATUS
|
||||
#include <windows.h>
|
||||
#define NTOS_MODE_USER
|
||||
#include <ndk/cmfuncs.h>
|
||||
#include <ndk/obfuncs.h>
|
||||
#include <ndk/rtlfuncs.h>
|
||||
#include <ndk/umtypes.h>
|
||||
#include <ddk/ntsam.h>
|
||||
|
||||
#include <samsrv/samsrv.h>
|
||||
|
||||
|
@ -18,6 +22,61 @@
|
|||
|
||||
#include <wine/debug.h>
|
||||
|
||||
typedef enum _SAM_DB_OBJECT_TYPE
|
||||
{
|
||||
SamDbIgnoreObject,
|
||||
SamDbContainerObject,
|
||||
SamDbServerObject,
|
||||
SamDbDomainObject,
|
||||
SamDbAliasObject,
|
||||
SamDbGroupObject,
|
||||
SamDbUserObject
|
||||
} SAM_DB_OBJECT_TYPE;
|
||||
|
||||
typedef struct _SAM_DB_OBJECT
|
||||
{
|
||||
ULONG Signature;
|
||||
SAM_DB_OBJECT_TYPE ObjectType;
|
||||
ULONG RefCount;
|
||||
ACCESS_MASK Access;
|
||||
HANDLE KeyHandle;
|
||||
struct _SAM_DB_OBJECT *ParentObject;
|
||||
} SAM_DB_OBJECT, *PSAM_DB_OBJECT;
|
||||
|
||||
#define SAMP_DB_SIGNATURE 0x87654321
|
||||
|
||||
/* database.c */
|
||||
|
||||
NTSTATUS
|
||||
SampInitDatabase(VOID);
|
||||
|
||||
NTSTATUS
|
||||
SampCreateDbObject(IN PSAM_DB_OBJECT ParentObject,
|
||||
IN LPWSTR ContainerName,
|
||||
IN LPWSTR ObjectName,
|
||||
IN SAM_DB_OBJECT_TYPE ObjectType,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
OUT PSAM_DB_OBJECT *DbObject);
|
||||
|
||||
NTSTATUS
|
||||
SampOpenDbObject(IN PSAM_DB_OBJECT ParentObject,
|
||||
IN LPWSTR ContainerName,
|
||||
IN LPWSTR ObjectName,
|
||||
IN SAM_DB_OBJECT_TYPE ObjectType,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
OUT PSAM_DB_OBJECT *DbObject);
|
||||
|
||||
NTSTATUS
|
||||
SampValidateDbObject(SAMPR_HANDLE Handle,
|
||||
SAM_DB_OBJECT_TYPE ObjectType,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
PSAM_DB_OBJECT *DbObject);
|
||||
|
||||
NTSTATUS
|
||||
SampCloseDbObject(PSAM_DB_OBJECT DbObject);
|
||||
|
||||
/* samspc.c */
|
||||
VOID SampStartRpcServer(VOID);
|
||||
|
||||
/* setup.c */
|
||||
BOOL SampIsSetupRunning(VOID);
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SAM_SERVER_CONNECT 1
|
||||
#define SAM_SERVER_SHUTDOWN 2
|
||||
#define SAM_SERVER_INITIALIZE 4
|
||||
#define SAM_SERVER_CREATE_DOMAIN 8
|
||||
#define SAM_SERVER_ENUMERATE_DOMAINS 16
|
||||
#define SAM_SERVER_LOOKUP_DOMAIN 32
|
||||
|
||||
|
||||
typedef PVOID SAM_HANDLE, *PSAM_HANDLE;
|
||||
|
||||
NTSTATUS
|
||||
|
@ -19,6 +27,21 @@ SamConnect(IN OUT PUNICODE_STRING ServerName,
|
|||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
|
||||
IN PUNICODE_STRING AccountName,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
OUT PSAM_HANDLE UserHandle,
|
||||
OUT PULONG RelativeId);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamOpenDomain(IN SAM_HANDLE ServerHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN PSID DomainId,
|
||||
OUT PSAM_HANDLE DomainHandle);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamShutdownSamServer(IN SAM_HANDLE ServerHandle);
|
||||
|
|
Loading…
Reference in a new issue