- 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:
Eric Kohl 2012-05-27 05:33:07 +00:00
parent 8ea9a9d758
commit 203b0d7413
8 changed files with 975 additions and 19 deletions

View file

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

View file

@ -29,7 +29,7 @@
@ stub SamLookupIdsInDomain
@ stub SamLookupNamesInDomain
@ stub SamOpenAlias
@ stub SamOpenDomain
@ stdcall SamOpenDomain(ptr long ptr ptr)
@ stub SamOpenGroup
@ stub SamOpenUser
@ stub SamQueryDisplayInformation

View file

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

View 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 */

View file

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

View file

@ -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;
}

View file

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

View file

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