Author: ekohl
Date: Sun May 27 05:33:07 2012
New Revision: 56661

URL: http://svn.reactos.org/svn/reactos?rev=56661&view=rev
Log:
[SAMLIB]
- Implement SamCloseHandle, SamConnect and SamOpenDomain.
[SAMSRV]
- Implement SamrCloseHandle, SamrConnect and SamrOpenDomain.
- Start the SAM RPC Server.

Added:
    trunk/reactos/dll/win32/samsrv/database.c   (with props)
Modified:
    trunk/reactos/dll/win32/samlib/samlib.c
    trunk/reactos/dll/win32/samlib/samlib.spec
    trunk/reactos/dll/win32/samsrv/CMakeLists.txt
    trunk/reactos/dll/win32/samsrv/samrpc.c
    trunk/reactos/dll/win32/samsrv/samsrv.c
    trunk/reactos/dll/win32/samsrv/samsrv.h
    trunk/reactos/include/ddk/ntsam.h

Modified: trunk/reactos/dll/win32/samlib/samlib.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.c?rev=56661&r1=56660&r2=56661&view=diff
==============================================================================
--- trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] Sun May 27 05:33:07 
2012
@@ -387,7 +387,21 @@
 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 @@
            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

Modified: trunk/reactos/dll/win32/samlib/samlib.spec
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.spec?rev=56661&r1=56660&r2=56661&view=diff
==============================================================================
--- trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] Sun May 27 05:33:07 
2012
@@ -29,7 +29,7 @@
 @ stub SamLookupIdsInDomain
 @ stub SamLookupNamesInDomain
 @ stub SamOpenAlias
-@ stub SamOpenDomain
+@ stdcall SamOpenDomain(ptr long ptr ptr)
 @ stub SamOpenGroup
 @ stub SamOpenUser
 @ stub SamQueryDisplayInformation

Modified: trunk/reactos/dll/win32/samsrv/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/CMakeLists.txt?rev=56661&r1=56660&r2=56661&view=diff
==============================================================================
--- trunk/reactos/dll/win32/samsrv/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samsrv/CMakeLists.txt [iso-8859-1] Sun May 27 
05:33:07 2012
@@ -8,6 +8,7 @@
 spec2def(samsrv.dll samsrv.spec ADD_IMPORTLIB)
 
 list(APPEND SOURCE
+    database.c
     samrpc.c
     samsrv.c
     setup.c

Added: trunk/reactos/dll/win32/samsrv/database.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/database.c?rev=56661&view=auto
==============================================================================
--- trunk/reactos/dll/win32/samsrv/database.c (added)
+++ trunk/reactos/dll/win32/samsrv/database.c [iso-8859-1] Sun May 27 05:33:07 
2012
@@ -1,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 */
+

Propchange: trunk/reactos/dll/win32/samsrv/database.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: trunk/reactos/dll/win32/samsrv/database.c
------------------------------------------------------------------------------
    svn:keywords = author date id revision

Modified: trunk/reactos/dll/win32/samsrv/samrpc.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samrpc.c?rev=56661&r1=56660&r2=56661&view=diff
==============================================================================
--- trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] Sun May 27 05:33:07 
2012
@@ -13,8 +13,48 @@
 
 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)
 {
@@ -38,8 +78,24 @@
             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 @@
 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 @@
                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 @@
 
 /* Function 12 */
 NTSTATUS
-__stdcall
+NTAPI
 SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
                        IN PRPC_UNICODE_STRING Name,
                        IN ACCESS_MASK DesiredAccess,
@@ -181,7 +312,7 @@
 
 /* Function 13 */
 NTSTATUS
-__stdcall
+NTAPI
 SamrEnumerateUsersInDomain(IN SAMPR_HANDLE DomainHandle,
                            IN OUT unsigned long *EnumerationContext,
                            IN unsigned long UserAccountControl,
@@ -195,7 +326,7 @@
 
 /* Function 14 */
 NTSTATUS
-__stdcall
+NTAPI
 SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle,
                         IN PRPC_UNICODE_STRING AccountName,
                         IN ACCESS_MASK DesiredAccess,
@@ -208,7 +339,7 @@
 
 /* Function 15 */
 NTSTATUS
-__stdcall
+NTAPI
 SamrEnumerateAliasesInDomain(IN SAMPR_HANDLE DomainHandle,
                              IN OUT unsigned long *EnumerationContext,
                              OUT PSAMPR_ENUMERATION_BUFFER *Buffer,
@@ -221,7 +352,7 @@
 
 /* Function 16 */
 NTSTATUS
-__stdcall
+NTAPI
 SamrGetAliasMembership(IN SAMPR_HANDLE DomainHandle,
                        IN PSAMPR_PSID_ARRAY SidArray,
                        OUT PSAMPR_ULONG_ARRAY Membership)
@@ -232,7 +363,7 @@
 
 /* Function 17 */
 NTSTATUS
-__stdcall
+NTAPI
 SamrLookupNamesInDomain(IN SAMPR_HANDLE DomainHandle,
                         IN unsigned long Count,
                         IN RPC_UNICODE_STRING Names[],
@@ -245,7 +376,7 @@
 
 /* Function 18 */
 NTSTATUS
-__stdcall
+NTAPI
 SamrLookupIdsInDomain(IN SAMPR_HANDLE DomainHandle,
                       IN unsigned long Count,
                       IN unsigned long *RelativeIds,
@@ -258,7 +389,7 @@
 
 /* Function 19 */
 NTSTATUS
-__stdcall
+NTAPI
 SamrOpenGroup(IN SAMPR_HANDLE DomainHandle,
               IN ACCESS_MASK DesiredAccess,
               IN unsigned long GroupId,
@@ -270,7 +401,7 @@
 
 /* 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 @@
 
 /* Function 21 */
 NTSTATUS
-__stdcall
+NTAPI
 SamrSetInformationGroup(IN SAMPR_HANDLE GroupHandle,
                         IN GROUP_INFORMATION_CLASS GroupInformationClass,
                         IN PSAMPR_GROUP_INFO_BUFFER Buffer)

Modified: trunk/reactos/dll/win32/samsrv/samsrv.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samsrv.c?rev=56661&r1=56660&r2=56661&view=diff
==============================================================================
--- trunk/reactos/dll/win32/samsrv/samsrv.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samsrv/samsrv.c [iso-8859-1] Sun May 27 05:33:07 
2012
@@ -34,8 +34,19 @@
     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;
 }

Modified: trunk/reactos/dll/win32/samsrv/samsrv.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samsrv.h?rev=56661&r1=56660&r2=56661&view=diff
==============================================================================
--- trunk/reactos/dll/win32/samsrv/samsrv.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samsrv/samsrv.h [iso-8859-1] Sun May 27 05:33:07 
2012
@@ -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);

Modified: trunk/reactos/include/ddk/ntsam.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/ntsam.h?rev=56661&r1=56660&r2=56661&view=diff
==============================================================================
--- trunk/reactos/include/ddk/ntsam.h [iso-8859-1] (original)
+++ trunk/reactos/include/ddk/ntsam.h [iso-8859-1] Sun May 27 05:33:07 2012
@@ -5,6 +5,14 @@
 #ifdef __cplusplus
 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;
 
@@ -21,6 +29,21 @@
 
 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);
 
 


Reply via email to