Author: ekohl
Date: Sun Jun  3 20:54:06 2012
New Revision: 56690

URL: http://svn.reactos.org/svn/reactos?rev=56690&view=rev
Log:
[SAMLIB]: Implement SamAddMemberToAlias, SamCreateAliasInDomain, 
SamEnumerateDomainsInSamServer, SamOpenAlias, SamQueryInformationDomain and 
SamQueryInformationUser.
[SAMSRV]: Implement SamrEnumerateDomainsInSamServer (buggy, probably a bug in 
WIDL), SamrQueryInformationDomain.DomainNameInformation, 
SamrCreateAliasInDomain, SamrOpenAlias and SamrAddMemberToAlias.
[SAMSRV]: Add more registry helper routines.
[SAMSRV]: Create builtin aliases upon setup.

Modified:
    trunk/reactos/dll/win32/samlib/samlib.c
    trunk/reactos/dll/win32/samlib/samlib.spec
    trunk/reactos/dll/win32/samsrv/registry.c
    trunk/reactos/dll/win32/samsrv/samrpc.c
    trunk/reactos/dll/win32/samsrv/samsrv.h
    trunk/reactos/dll/win32/samsrv/setup.c
    trunk/reactos/include/ddk/ntsam.h
    trunk/reactos/include/reactos/idl/sam.idl

Modified: trunk/reactos/dll/win32/samlib/samlib.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.c?rev=56690&r1=56689&r2=56690&view=diff
==============================================================================
--- trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samlib/samlib.c [iso-8859-1] Sun Jun  3 20:54:06 
2012
@@ -105,6 +105,31 @@
 
 NTSTATUS
 NTAPI
+SamAddMemberToAlias(IN SAM_HANDLE AliasHandle,
+                    IN PSID MemberId)
+{
+    NTSTATUS Status;
+
+    TRACE("SamAddMemberToAlias(%p %p)\n",
+          AliasHandle, MemberId);
+
+    RpcTryExcept
+    {
+        Status = SamrAddMemberToAlias((SAMPR_HANDLE)AliasHandle,
+                                      (PRPC_SID)MemberId);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+NTSTATUS
+NTAPI
 SamCloseHandle(IN SAM_HANDLE SamHandle)
 {
     NTSTATUS Status;
@@ -142,6 +167,37 @@
         Status = SamrConnect((PSAMPR_SERVER_NAME)ServerName,
                              (SAMPR_HANDLE *)ServerHandle,
                              DesiredAccess);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamCreateAliasInDomain(IN SAM_HANDLE DomainHandle,
+                       IN PUNICODE_STRING AccountName,
+                       IN ACCESS_MASK DesiredAccess,
+                       OUT PSAM_HANDLE AliasHandle,
+                       OUT PULONG RelativeId)
+{
+    NTSTATUS Status;
+
+    TRACE("SamCreateAliasInDomain(%p,%p,0x%08x,%p,%p)\n",
+          DomainHandle, AccountName, DesiredAccess, AliasHandle, RelativeId);
+
+    RpcTryExcept
+    {
+        Status = SamrCreateAliasInDomain((SAMPR_HANDLE)DomainHandle,
+                                         (PRPC_UNICODE_STRING)AccountName,
+                                         DesiredAccess,
+                                         (SAMPR_HANDLE *)AliasHandle,
+                                         RelativeId);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -186,9 +242,59 @@
 
 NTSTATUS
 NTAPI
+SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle,
+                               IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
+                               OUT PVOID *Buffer,
+                               IN ULONG PreferedMaximumLength,
+                               OUT PULONG CountReturned)
+{
+    PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
+    NTSTATUS Status;
+
+    TRACE("SamEnumerateDomainsInSamServer(%p,%p,%p,%lu,%p)\n",
+          ServerHandle, EnumerationContext, Buffer, PreferedMaximumLength,
+          CountReturned);
+
+    if ((EnumerationContext == NULL) ||
+        (Buffer == NULL) ||
+        (CountReturned == NULL))
+        return STATUS_INVALID_PARAMETER;
+
+    *Buffer = NULL;
+
+    RpcTryExcept
+    {
+        Status = SamrEnumerateDomainsInSamServer((SAMPR_HANDLE)ServerHandle,
+                                                 EnumerationContext,
+                                                 (PSAMPR_ENUMERATION_BUFFER 
*)&EnumBuffer,
+                                                 PreferedMaximumLength,
+                                                 CountReturned);
+
+        if (EnumBuffer != NULL)
+        {
+            if (EnumBuffer->Buffer != NULL)
+            {
+                *Buffer = EnumBuffer->Buffer;
+            }
+
+            midl_user_free(EnumBuffer);
+        }
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+NTSTATUS
+NTAPI
 SamFreeMemory(IN PVOID Buffer)
 {
-    if (Buffer!= NULL)
+    if (Buffer != NULL)
         midl_user_free(Buffer);
 
     return STATUS_SUCCESS;
@@ -211,6 +317,35 @@
         Status = SamrLookupDomainInSamServer((SAMPR_HANDLE)ServerHandle,
                                              (PRPC_UNICODE_STRING)Name,
                                              (PRPC_SID *)DomainId);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+NTSTATUS
+NTAPI
+SamOpenAlias(IN SAM_HANDLE DomainHandle,
+             IN ACCESS_MASK DesiredAccess,
+             IN ULONG AliasId,
+             OUT PSAM_HANDLE AliasHandle)
+{
+    NTSTATUS Status;
+
+    TRACE("SamOpenAlias(%p 0x%08x %lx %p)\n",
+          DomainHandle, DesiredAccess, AliasId, AliasHandle);
+
+    RpcTryExcept
+    {
+        Status = SamrOpenAlias((SAMPR_HANDLE)DomainHandle,
+                               DesiredAccess,
+                               AliasId,
+                               (SAMPR_HANDLE *)AliasHandle);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -282,12 +417,55 @@
 
 NTSTATUS
 NTAPI
+SamQueryInformationDomain(IN SAM_HANDLE DomainHandle,
+                          IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
+                          OUT PVOID *Buffer)
+{
+    NTSTATUS Status;
+
+    TRACE("SamQueryInformationDomain(%p %lu %p)\n",
+          DomainHandle, DomainInformationClass, Buffer);
+
+    RpcTryExcept
+    {
+        Status = SamrQueryInformationDomain((SAMPR_HANDLE)DomainHandle,
+                                            DomainInformationClass,
+                                            (PSAMPR_DOMAIN_INFO_BUFFER 
*)Buffer);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+NTSTATUS
+NTAPI
 SamQueryInformationUser(IN SAM_HANDLE UserHandle,
                         IN USER_INFORMATION_CLASS UserInformationClass,
                         OUT PVOID *Buffer)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status;
+
+    TRACE("SamQueryInformationUser(%p %lu %p)\n",
+          UserHandle, UserInformationClass, Buffer);
+
+    RpcTryExcept
+    {
+        Status = SamrQueryInformationUser((SAMPR_HANDLE)UserHandle,
+                                          UserInformationClass,
+                                          (PSAMPR_USER_INFO_BUFFER *)Buffer);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
 
@@ -349,6 +527,7 @@
 NTAPI
 SamShutdownSamServer(IN SAM_HANDLE ServerHandle)
 {
+    UNIMPLEMENTED;
     return STATUS_NOT_IMPLEMENTED;
 }
 

Modified: trunk/reactos/dll/win32/samlib/samlib.spec
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samlib/samlib.spec?rev=56690&r1=56689&r2=56690&view=diff
==============================================================================
--- trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samlib/samlib.spec [iso-8859-1] Sun Jun  3 20:54:06 
2012
@@ -1,4 +1,4 @@
-@ stub SamAddMemberToAlias
+@ stdcall SamAddMemberToAlias(ptr ptr)
 @ stub SamAddMemberToGroup
 @ stub SamAddMultipleMembersToAlias
 @ stub SamChangePasswordUser2
@@ -7,7 +7,7 @@
 @ stdcall SamCloseHandle(ptr)
 @ stdcall SamConnect(ptr ptr long ptr)
 @ stub SamConnectWithCreds
-@ stub SamCreateAliasInDomain
+@ stdcall SamCreateAliasInDomain(ptr ptr long ptr ptr)
 @ stub SamCreateGroupInDomain
 @ stub SamCreateUser2InDomain
 @ stdcall SamCreateUserInDomain(ptr ptr long ptr ptr)
@@ -15,7 +15,7 @@
 @ stub SamDeleteGroup
 @ stub SamDeleteUser
 @ stub SamEnumerateAliasesInDomain
-@ stub SamEnumerateDomainsInSamServer
+@ stdcall SamEnumerateDomainsInSamServer(ptr ptr ptr long ptr)
 @ stub SamEnumerateGroupsInDomain
 @ stub SamEnumerateUsersInDomain
 @ stdcall SamFreeMemory(ptr)
@@ -28,13 +28,13 @@
 @ stdcall SamLookupDomainInSamServer(ptr ptr ptr)
 @ stub SamLookupIdsInDomain
 @ stub SamLookupNamesInDomain
-@ stub SamOpenAlias
+@ stdcall SamOpenAlias(ptr long long ptr)
 @ stdcall SamOpenDomain(ptr long ptr ptr)
 @ stub SamOpenGroup
 @ stdcall SamOpenUser(ptr long long ptr)
 @ stub SamQueryDisplayInformation
 @ stub SamQueryInformationAlias
-@ stub SamQueryInformationDomain
+@ stdcall SamQueryInformationDomain(ptr long ptr)
 @ stub SamQueryInformationGroup
 @ stdcall SamQueryInformationUser(ptr long ptr)
 @ stub SamQuerySecurityObject

Modified: trunk/reactos/dll/win32/samsrv/registry.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/registry.c?rev=56690&r1=56689&r2=56690&view=diff
==============================================================================
--- trunk/reactos/dll/win32/samsrv/registry.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samsrv/registry.c [iso-8859-1] Sun Jun  3 20:54:06 
2012
@@ -16,7 +16,42 @@
 /* FUNCTIONS ***************************************************************/
 
 NTSTATUS
-NTAPI
+SampRegCloseKey(IN HANDLE KeyHandle)
+{
+    return NtClose(KeyHandle);
+}
+
+
+NTSTATUS
+SampRegCreateKey(IN HANDLE ParentKeyHandle,
+                 IN LPCWSTR KeyName,
+                 IN ACCESS_MASK DesiredAccess,
+                 OUT HANDLE KeyHandle)
+{
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING Name;
+    ULONG Disposition;
+
+    RtlInitUnicodeString(&Name, KeyName);
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &Name,
+                               OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+                               ParentKeyHandle,
+                               NULL);
+
+    /* Create the key */
+    return ZwCreateKey(KeyHandle,
+                       DesiredAccess,
+                       &ObjectAttributes,
+                       0,
+                       NULL,
+                       0,
+                       &Disposition);
+}
+
+
+NTSTATUS
 SampRegEnumerateSubKey(IN HANDLE KeyHandle,
                        IN ULONG Index,
                        IN ULONG Length,
@@ -74,7 +109,6 @@
 
 
 NTSTATUS
-NTAPI
 SampRegOpenKey(IN HANDLE ParentKeyHandle,
                IN LPCWSTR KeyName,
                IN ACCESS_MASK DesiredAccess,
@@ -171,5 +205,8 @@
     /* Free the memory and return status */
     RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
 
+    if ((Data == NULL) && (Status == STATUS_BUFFER_OVERFLOW))
+        Status = STATUS_SUCCESS;
+
     return Status;
 }

Modified: trunk/reactos/dll/win32/samsrv/samrpc.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samrpc.c?rev=56690&r1=56689&r2=56690&view=diff
==============================================================================
--- trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] Sun Jun  3 20:54:06 
2012
@@ -269,11 +269,201 @@
 SamrEnumerateDomainsInSamServer(IN SAMPR_HANDLE ServerHandle,
                                 IN OUT unsigned long *EnumerationContext,
                                 OUT PSAMPR_ENUMERATION_BUFFER *Buffer,
-                                IN unsigned long PreferedMaximumLength,
-                                OUT unsigned long *CountReturned)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+                                IN ULONG PreferedMaximumLength,
+                                OUT PULONG CountReturned)
+{
+    PSAM_DB_OBJECT ServerObject;
+    WCHAR DomainKeyName[64];
+    HANDLE DomainsKeyHandle;
+    HANDLE DomainKeyHandle;
+    ULONG EnumIndex;
+    ULONG EnumCount;
+    ULONG RequiredLength;
+    ULONG DataLength;
+    ULONG i;
+    PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
+    NTSTATUS Status;
+
+    TRACE("SamrEnumerateDomainsInSamServer(%p %p %p %lu %p)\n",
+          ServerHandle, EnumerationContext, Buffer, PreferedMaximumLength,
+          CountReturned);
+
+    /* Validate the server handle */
+    Status = SampValidateDbObject(ServerHandle,
+                                  SamDbServerObject,
+                                  SAM_SERVER_ENUMERATE_DOMAINS,
+                                  &ServerObject);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    Status = SampRegOpenKey(ServerObject->KeyHandle,
+                            L"Domains",
+                            KEY_READ,
+                            &DomainsKeyHandle);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    EnumIndex = *EnumerationContext;
+    EnumCount = 0;
+    RequiredLength = 0;
+
+    while (TRUE)
+    {
+        Status = SampRegEnumerateSubKey(DomainsKeyHandle,
+                                        EnumIndex,
+                                        64 * sizeof(WCHAR),
+                                        DomainKeyName);
+        if (!NT_SUCCESS(Status))
+            break;
+
+        TRACE("EnumIndex: %lu\n", EnumIndex);
+        TRACE("Domain key name: %S\n", DomainKeyName);
+
+        Status = SampRegOpenKey(DomainsKeyHandle,
+                                DomainKeyName,
+                                KEY_READ,
+                                &DomainKeyHandle);
+        TRACE("SampRegOpenKey returned %08lX\n", Status);
+        if (NT_SUCCESS(Status))
+        {
+            DataLength = 0;
+            Status = SampRegQueryValue(DomainKeyHandle,
+                                       L"Name",
+                                       NULL,
+                                       NULL,
+                                       &DataLength);
+            TRACE("SampRegQueryValue returned %08lX\n", Status);
+            if (NT_SUCCESS(Status))
+            {
+                TRACE("Data length: %lu\n", DataLength);
+
+                if ((RequiredLength + DataLength + sizeof(UNICODE_STRING)) > 
PreferedMaximumLength)
+                    break;
+
+                RequiredLength += (DataLength + sizeof(UNICODE_STRING));
+                EnumCount++;
+            }
+
+            NtClose(DomainKeyHandle);
+        }
+
+        EnumIndex++;
+    }
+
+    TRACE("EnumCount: %lu\n", EnumCount);
+    TRACE("RequiredLength: %lu\n", RequiredLength);
+
+    EnumBuffer = midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER));
+    if (EnumBuffer == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    EnumBuffer->EntriesRead = EnumCount;
+    EnumBuffer->Buffer = midl_user_allocate(EnumCount * 
sizeof(SAMPR_RID_ENUMERATION));
+    if (EnumBuffer->Buffer == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    EnumIndex = *EnumerationContext;
+    for (i = 0; i < EnumCount; i++, EnumIndex++)
+    {
+        Status = SampRegEnumerateSubKey(DomainsKeyHandle,
+                                        EnumIndex,
+                                        64 * sizeof(WCHAR),
+                                        DomainKeyName);
+        if (!NT_SUCCESS(Status))
+            break;
+
+        TRACE("EnumIndex: %lu\n", EnumIndex);
+        TRACE("Domain key name: %S\n", DomainKeyName);
+
+        Status = SampRegOpenKey(DomainsKeyHandle,
+                                DomainKeyName,
+                                KEY_READ,
+                                &DomainKeyHandle);
+        TRACE("SampRegOpenKey returned %08lX\n", Status);
+        if (NT_SUCCESS(Status))
+        {
+            DataLength = 0;
+            Status = SampRegQueryValue(DomainKeyHandle,
+                                       L"Name",
+                                       NULL,
+                                       NULL,
+                                       &DataLength);
+            TRACE("SampRegQueryValue returned %08lX\n", Status);
+            if (NT_SUCCESS(Status))
+            {
+                EnumBuffer->Buffer[i].RelativeId = 0;
+                EnumBuffer->Buffer[i].Name.Length = (USHORT)DataLength - 
sizeof(WCHAR);
+                EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)DataLength;
+                EnumBuffer->Buffer[i].Name.Buffer = 
midl_user_allocate(DataLength);
+                if (EnumBuffer->Buffer[i].Name.Buffer == NULL)
+                {
+                    NtClose(DomainKeyHandle);
+                    Status = STATUS_INSUFFICIENT_RESOURCES;
+                    goto done;
+                }
+
+                Status = SampRegQueryValue(DomainKeyHandle,
+                                           L"Name",
+                                           NULL,
+                                           EnumBuffer->Buffer[i].Name.Buffer,
+                                           &DataLength);
+                TRACE("SampRegQueryValue returned %08lX\n", Status);
+                if (NT_SUCCESS(Status))
+                {
+                    TRACE("Domain name: %S\n", 
EnumBuffer->Buffer[i].Name.Buffer);
+                }
+            }
+
+            NtClose(DomainKeyHandle);
+
+            if (!NT_SUCCESS(Status))
+                goto done;
+        }
+    }
+
+    if (NT_SUCCESS(Status))
+    {
+        *EnumerationContext += EnumCount;
+        *Buffer = EnumBuffer;
+        *CountReturned = EnumCount;
+    }
+
+done:
+    if (!NT_SUCCESS(Status))
+    {
+        *EnumerationContext = 0;
+        *Buffer = NULL;
+        *CountReturned = 0;
+
+        if (EnumBuffer != NULL)
+        {
+            if (EnumBuffer->Buffer != NULL)
+            {
+                if (EnumBuffer->EntriesRead != 0)
+                {
+                    for (i = 0; i < EnumBuffer->EntriesRead; i++)
+                    {
+                        if (EnumBuffer->Buffer[i].Name.Buffer != NULL)
+                            midl_user_free(EnumBuffer->Buffer[i].Name.Buffer);
+                    }
+                }
+
+                midl_user_free(EnumBuffer->Buffer);
+            }
+
+            midl_user_free(EnumBuffer);
+        }
+    }
+
+    NtClose(DomainsKeyHandle);
+
+    return Status;
 }
 
 /* Function 7 */
@@ -348,6 +538,64 @@
     return Status;
 }
 
+
+static NTSTATUS
+SampQueryDomainName(PSAM_DB_OBJECT DomainObject,
+                    PSAMPR_DOMAIN_INFO_BUFFER *Buffer)
+{
+    PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer = NULL;
+    ULONG Length = 0;
+    NTSTATUS Status;
+
+    *Buffer = NULL;
+
+    InfoBuffer = midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER));
+    if (InfoBuffer == NULL)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    Status = SampGetObjectAttribute(DomainObject,
+                                    L"Name",
+                                    NULL,
+                                    NULL,
+                                    &Length);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    InfoBuffer->Name.DomainName.Length = Length - sizeof(WCHAR);
+    InfoBuffer->Name.DomainName.MaximumLength = Length;
+    InfoBuffer->Name.DomainName.Buffer = midl_user_allocate(Length);
+    if (InfoBuffer->Name.DomainName.Buffer == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    Status = SampGetObjectAttribute(DomainObject,
+                                    L"Name",
+                                    NULL,
+                                    (PVOID)InfoBuffer->Name.DomainName.Buffer,
+                                    &Length);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    *Buffer = InfoBuffer;
+
+done:
+    if (!NT_SUCCESS(Status))
+    {
+        if (InfoBuffer != NULL)
+        {
+            if (InfoBuffer->Name.DomainName.Buffer != NULL)
+                midl_user_free(InfoBuffer->Name.DomainName.Buffer);
+
+            midl_user_free(InfoBuffer);
+        }
+    }
+
+    return Status;
+}
+
+
 /* Function 8 */
 NTSTATUS
 NTAPI
@@ -355,8 +603,32 @@
                            IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
                            OUT PSAMPR_DOMAIN_INFO_BUFFER *Buffer)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PSAM_DB_OBJECT DomainObject;
+    NTSTATUS Status;
+
+    TRACE("SamrQueryInformationDomain(%p %lu %p)\n",
+          DomainHandle, DomainInformationClass, Buffer);
+
+    /* Validate the server handle */
+    Status = SampValidateDbObject(DomainHandle,
+                                  SamDbDomainObject,
+                                  DOMAIN_READ_OTHER_PARAMETERS,
+                                  &DomainObject);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    switch (DomainInformationClass)
+    {
+        case DomainNameInformation:
+            Status = SampQueryDomainName(DomainObject,
+                                         Buffer);
+            break;
+
+        default:
+            Status = STATUS_NOT_IMPLEMENTED;
+    }
+
+    return Status;
 }
 
 static NTSTATUS
@@ -399,7 +671,7 @@
     {
         case DomainNameInformation:
             Status = SampSetDomainName(DomainObject,
-                                       
(PSAMPR_DOMAIN_NAME_INFORMATION)DomainInformation);
+                                       &DomainInformation->Name);
             break;
 
         default:
@@ -579,8 +851,116 @@
                         OUT SAMPR_HANDLE *AliasHandle,
                         OUT unsigned long *RelativeId)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PSAM_DB_OBJECT DomainObject;
+    PSAM_DB_OBJECT AliasObject;
+    ULONG ulSize;
+    ULONG ulRid;
+    WCHAR szRid[9];
+    BOOL bAliasExists = FALSE;
+    NTSTATUS Status;
+
+    TRACE("SamrCreateAliasInDomain(%p %p %lx %p %p)\n",
+          DomainHandle, AccountName, DesiredAccess, AliasHandle, RelativeId);
+
+    /* Validate the domain handle */
+    Status = SampValidateDbObject(DomainHandle,
+                                  SamDbDomainObject,
+                                  DOMAIN_CREATE_ALIAS,
+                                  &DomainObject);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
+    /* Get the NextRID attribute */
+    ulSize = sizeof(ULONG);
+    Status = SampGetObjectAttribute(DomainObject,
+                                    L"NextRID",
+                                    NULL,
+                                    (LPVOID)&ulRid,
+                                    &ulSize);
+    if (!NT_SUCCESS(Status))
+        ulRid = DOMAIN_USER_RID_MAX + 1;
+
+    TRACE("RID: %lx\n", ulRid);
+
+    /* Convert the RID into a string (hex) */
+    swprintf(szRid, L"%08lX", ulRid);
+
+    /* Check whether the user name is already in use */
+    Status = SampCheckDbObjectNameAlias(DomainObject,
+                                        L"Aliases",
+                                        AccountName->Buffer,
+                                        &bAliasExists);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
+    if (bAliasExists)
+    {
+        TRACE("The alias account %S already exists!\n", AccountName->Buffer);
+        return STATUS_ALIAS_EXISTS;
+    }
+
+    /* Create the user object */
+    Status = SampCreateDbObject(DomainObject,
+                                L"Aliases",
+                                szRid,
+                                SamDbAliasObject,
+                                DesiredAccess,
+                                &AliasObject);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
+    /* Add the name alias for the user object */
+    Status = SampSetDbObjectNameAlias(DomainObject,
+                                      L"Aliases",
+                                      AccountName->Buffer,
+                                      ulRid);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
+    /* Set the name attribute */
+    Status = SampSetObjectAttribute(AliasObject,
+                                    L"Name",
+                                    REG_SZ,
+                                    (LPVOID)AccountName->Buffer,
+                                    AccountName->MaximumLength);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
+    /* FIXME: Set default alias attributes */
+
+    if (NT_SUCCESS(Status))
+    {
+        *AliasHandle = (SAMPR_HANDLE)AliasObject;
+        *RelativeId = ulRid;
+    }
+
+    /* Increment the NextRID attribute */
+    ulRid++;
+    ulSize = sizeof(ULONG);
+    SampSetObjectAttribute(DomainObject,
+                           L"NextRID",
+                           REG_DWORD,
+                           (LPVOID)&ulRid,
+                           ulSize);
+
+    TRACE("returns with status 0x%08lx\n", Status);
+
+    return Status;
 }
 
 /* Function 15 */
@@ -723,11 +1103,47 @@
 NTAPI
 SamrOpenAlias(IN SAMPR_HANDLE DomainHandle,
               IN ACCESS_MASK DesiredAccess,
-              IN unsigned long AliasId,
+              IN ULONG AliasId,
               OUT SAMPR_HANDLE *AliasHandle)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PSAM_DB_OBJECT DomainObject;
+    PSAM_DB_OBJECT AliasObject;
+    WCHAR szRid[9];
+    NTSTATUS Status;
+
+    TRACE("SamrOpenAlias(%p %lx %lx %p)\n",
+          DomainHandle, DesiredAccess, AliasId, AliasHandle);
+
+    /* Validate the domain handle */
+    Status = SampValidateDbObject(DomainHandle,
+                                  SamDbDomainObject,
+                                  DOMAIN_LOOKUP,
+                                  &DomainObject);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
+    /* Convert the RID into a string (hex) */
+    swprintf(szRid, L"%08lX", AliasId);
+
+    /* Create the alias object */
+    Status = SampOpenDbObject(DomainObject,
+                              L"Aliases",
+                              szRid,
+                              SamDbAliasObject,
+                              DesiredAccess,
+                              &AliasObject);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
+    *AliasHandle = (SAMPR_HANDLE)AliasObject;
+
+    return STATUS_SUCCESS;
 }
 
 /* Function 28 */
@@ -767,8 +1183,52 @@
 SamrAddMemberToAlias(IN SAMPR_HANDLE AliasHandle,
                      IN PRPC_SID MemberId)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PSAM_DB_OBJECT AliasObject;
+    LPWSTR MemberIdString = NULL;
+    HANDLE MembersKeyHandle = NULL;
+    NTSTATUS Status;
+
+    TRACE("SamrAddMemberToAlias(%p %p)\n",
+          AliasHandle, MemberId);
+
+    /* Validate the domain handle */
+    Status = SampValidateDbObject(AliasHandle,
+                                  SamDbAliasObject,
+                                  ALIAS_ADD_MEMBER,
+                                  &AliasObject);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
+    ConvertSidToStringSidW(MemberId, &MemberIdString);
+    TRACE("Member SID: %S\n", MemberIdString);
+
+    Status = SampRegCreateKey(AliasObject->KeyHandle,
+                              L"Members",
+                              KEY_WRITE,
+                              &MembersKeyHandle);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("SampRegCreateKey failed with status 0x%08lx\n", Status);
+        goto done;
+    }
+
+    Status = SampRegSetValue(MembersKeyHandle,
+                             MemberIdString,
+                             REG_BINARY,
+                             NULL,
+                             0);
+
+done:
+    if (MembersKeyHandle != NULL)
+        SampRegCloseKey(MembersKeyHandle);
+
+    if (MemberIdString != NULL)
+        LocalFree(MemberIdString);
+
+    return Status;
 }
 
 /* Function 32 */

Modified: trunk/reactos/dll/win32/samsrv/samsrv.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samsrv.h?rev=56690&r1=56689&r2=56690&view=diff
==============================================================================
--- trunk/reactos/dll/win32/samsrv/samsrv.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samsrv/samsrv.h [iso-8859-1] Sun Jun  3 20:54:06 
2012
@@ -17,6 +17,7 @@
 #include <ndk/umtypes.h>
 #include <ddk/ntsam.h>
 #include <ntsecapi.h>
+#include <sddl.h>
 
 #include <samsrv/samsrv.h>
 
@@ -105,14 +106,21 @@
 
 /* registry.h */
 NTSTATUS
-NTAPI
+SampRegCloseKey(IN HANDLE KeyHandle);
+
+NTSTATUS
+SampRegCreateKey(IN HANDLE ParentKeyHandle,
+                 IN LPCWSTR KeyName,
+                 IN ACCESS_MASK DesiredAccess,
+                 OUT HANDLE KeyHandle);
+
+NTSTATUS
 SampRegEnumerateSubKey(IN HANDLE KeyHandle,
                        IN ULONG Index,
                        IN ULONG Length,
                        OUT LPWSTR Buffer);
 
 NTSTATUS
-NTAPI
 SampRegOpenKey(IN HANDLE ParentKeyHandle,
                IN LPCWSTR KeyName,
                IN ACCESS_MASK DesiredAccess,

Modified: trunk/reactos/dll/win32/samsrv/setup.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/setup.c?rev=56690&r1=56689&r2=56690&view=diff
==============================================================================
--- trunk/reactos/dll/win32/samsrv/setup.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/samsrv/setup.c [iso-8859-1] Sun Jun  3 20:54:06 2012
@@ -59,35 +59,87 @@
 
 
 static BOOL
+SampCreateAliasAccount(HKEY hDomainKey,
+                       LPCWSTR lpAccountName,
+                       ULONG ulRelativeId)
+{
+    DWORD dwDisposition;
+    WCHAR szAccountKeyName[32];
+    HKEY hAccountKey = NULL;
+    HKEY hNamesKey = NULL;
+
+    swprintf(szAccountKeyName, L"Aliases\\%08lX", ulRelativeId);
+
+    if (!RegCreateKeyExW(hDomainKey,
+                         szAccountKeyName,
+                         0,
+                         NULL,
+                         REG_OPTION_NON_VOLATILE,
+                         KEY_ALL_ACCESS,
+                         NULL,
+                         &hAccountKey,
+                         &dwDisposition))
+    {
+        RegSetValueEx(hAccountKey,
+                      L"Name",
+                      0,
+                      REG_SZ,
+                      (LPVOID)lpAccountName,
+                      (wcslen(lpAccountName) + 1) * sizeof(WCHAR));
+
+        RegCloseKey(hAccountKey);
+    }
+
+    if (!RegOpenKeyExW(hDomainKey,
+                       L"Aliases\\Names",
+                       0,
+                       KEY_ALL_ACCESS,
+                       &hNamesKey))
+    {
+        RegSetValueEx(hNamesKey,
+                      lpAccountName,
+                      0,
+                      REG_DWORD,
+                      (LPVOID)&ulRelativeId,
+                      sizeof(ULONG));
+
+        RegCloseKey(hNamesKey);
+    }
+
+    return TRUE;
+}
+
+
+static BOOL
 SampCreateUserAccount(HKEY hDomainKey,
                       LPCWSTR lpAccountName,
                       ULONG ulRelativeId)
 {
     DWORD dwDisposition;
-    WCHAR szUserKeyName[32];
-    HKEY hUserKey = NULL;
+    WCHAR szAccountKeyName[32];
+    HKEY hAccountKey = NULL;
     HKEY hNamesKey = NULL;
 
-    swprintf(szUserKeyName, L"Users\\%08lX", ulRelativeId);
+    swprintf(szAccountKeyName, L"Users\\%08lX", ulRelativeId);
 
     if (!RegCreateKeyExW(hDomainKey,
-                         szUserKeyName,
+                         szAccountKeyName,
                          0,
                          NULL,
                          REG_OPTION_NON_VOLATILE,
                          KEY_ALL_ACCESS,
                          NULL,
-                         &hUserKey,
+                         &hAccountKey,
                          &dwDisposition))
     {
-        RegSetValueEx(hUserKey,
+        RegSetValueEx(hAccountKey,
                       L"Name",
                       0,
                       REG_SZ,
                       (LPVOID)lpAccountName,
                       (wcslen(lpAccountName) + 1) * sizeof(WCHAR));
 
-        RegCloseKey(hUserKey);
+        RegCloseKey(hAccountKey);
     }
 
     if (!RegOpenKeyExW(hDomainKey,
@@ -119,7 +171,7 @@
 {
     DWORD dwDisposition;
     HKEY hDomainKey = NULL;
-    HKEY hAliasKey = NULL;
+    HKEY hAliasesKey = NULL;
     HKEY hGroupsKey = NULL;
     HKEY hUsersKey = NULL;
     HKEY hNamesKey = NULL;
@@ -157,16 +209,16 @@
 
     /* Create the Alias container */
     if (!RegCreateKeyExW(hDomainKey,
-                         L"Alias",
+                         L"Aliases",
                          0,
                          NULL,
                          REG_OPTION_NON_VOLATILE,
                          KEY_ALL_ACCESS,
                          NULL,
-                         &hAliasKey,
+                         &hAliasesKey,
                          &dwDisposition))
     {
-        if (!RegCreateKeyExW(hAliasKey,
+        if (!RegCreateKeyExW(hAliasesKey,
                              L"Names",
                              0,
                              NULL,
@@ -177,7 +229,7 @@
                              &dwDisposition))
             RegCloseKey(hNamesKey);
 
-        RegCloseKey(hAliasKey);
+        RegCloseKey(hAliasesKey);
     }
 
     /* Create the Groups container */
@@ -344,6 +396,21 @@
                          pBuiltinSid,
                          &hDomainKey))
     {
+        SampCreateAliasAccount(hDomainKey,
+                               L"Administrators",
+                               DOMAIN_ALIAS_RID_ADMINS);
+
+        SampCreateAliasAccount(hDomainKey,
+                               L"Users",
+                               DOMAIN_ALIAS_RID_USERS);
+
+        SampCreateAliasAccount(hDomainKey,
+                               L"Guests",
+                               DOMAIN_ALIAS_RID_GUESTS);
+
+        SampCreateAliasAccount(hDomainKey,
+                               L"Power Users",
+                               DOMAIN_ALIAS_RID_POWER_USERS);
 
         RegCloseKey(hDomainKey);
     }

Modified: trunk/reactos/include/ddk/ntsam.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/ntsam.h?rev=56690&r1=56689&r2=56690&view=diff
==============================================================================
--- trunk/reactos/include/ddk/ntsam.h [iso-8859-1] (original)
+++ trunk/reactos/include/ddk/ntsam.h [iso-8859-1] Sun Jun  3 20:54:06 2012
@@ -5,6 +5,12 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+
+#define ALIAS_ADD_MEMBER 1
+#define ALIAS_REMOVE_MEMBER 2
+#define ALIAS_LIST_MEMBERS 4
+#define ALIAS_READ_INFORMATION 8
+#define ALIAS_WRITE_ACCOUNT 16
 
 #define DOMAIN_READ_PASSWORD_PARAMETERS 1
 #define DOMAIN_WRITE_PASSWORD_PARAMS 2
@@ -38,6 +44,19 @@
 #define USER_WRITE_GROUP_INFORMATION 1024
 
 typedef PVOID SAM_HANDLE, *PSAM_HANDLE;
+typedef ULONG SAM_ENUMERATE_HANDLE, *PSAM_ENUMERATE_HANDLE;
+
+typedef struct _SAM_RID_ENUMERATION
+{
+    ULONG RelativeId;
+    UNICODE_STRING Name;
+} SAM_RID_ENUMERATION, *PSAM_RID_ENUMERATION;
+
+typedef struct _SAM_SID_ENUMERATION
+{
+    PSID Sid;
+    UNICODE_STRING Name;
+} SAM_SID_ENUMERATION, *PSAM_SID_ENUMERATION;
 
 typedef enum _DOMAIN_INFORMATION_CLASS
 {
@@ -103,6 +122,11 @@
 
 NTSTATUS
 NTAPI
+SamAddMemberToAlias(IN SAM_HANDLE AliasHandle,
+                    IN PSID MemberId);
+
+NTSTATUS
+NTAPI
 SamCloseHandle(IN SAM_HANDLE SamHandle);
 
 NTSTATUS
@@ -111,6 +135,14 @@
            OUT PSAM_HANDLE ServerHandle,
            IN ACCESS_MASK DesiredAccess,
            IN POBJECT_ATTRIBUTES ObjectAttributes);
+
+NTSTATUS
+NTAPI
+SamCreateAliasInDomain(IN SAM_HANDLE DomainHandle,
+                       IN PUNICODE_STRING AccountName,
+                       IN ACCESS_MASK DesiredAccess,
+                       OUT PSAM_HANDLE AliasHandle,
+                       OUT PULONG RelativeId);
 
 NTSTATUS
 NTAPI
@@ -122,6 +154,14 @@
 
 NTSTATUS
 NTAPI
+SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle,
+                               IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
+                               OUT PVOID *Buffer,
+                               IN ULONG PreferedMaximumLength,
+                               OUT PULONG CountReturned);
+
+NTSTATUS
+NTAPI
 SamFreeMemory(IN PVOID Buffer);
 
 NTSTATUS
@@ -129,6 +169,13 @@
 SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
                            IN PUNICODE_STRING Name,
                            OUT PSID *DomainId);
+
+NTSTATUS
+NTAPI
+SamOpenAlias(IN SAM_HANDLE DomainHandle,
+             IN ACCESS_MASK DesiredAccess,
+             IN ULONG AliasId,
+             OUT PSAM_HANDLE AliasHandle);
 
 NTSTATUS
 NTAPI
@@ -146,6 +193,12 @@
 
 NTSTATUS
 NTAPI
+SamQueryInformationDomain(IN SAM_HANDLE DomainHandle,
+                          IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
+                          OUT PVOID *Buffer);
+
+NTSTATUS
+NTAPI
 SamQueryInformationUser(IN SAM_HANDLE UserHandle,
                         IN USER_INFORMATION_CLASS UserInformationClass,
                         OUT PVOID *Buffer);

Modified: trunk/reactos/include/reactos/idl/sam.idl
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/idl/sam.idl?rev=56690&r1=56689&r2=56690&view=diff
==============================================================================
--- trunk/reactos/include/reactos/idl/sam.idl [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/idl/sam.idl [iso-8859-1] Sun Jun  3 20:54:06 
2012
@@ -1036,7 +1036,7 @@
     SamrOpenAlias(
         [in] SAMPR_HANDLE DomainHandle,
         [in] ACCESS_MASK DesiredAccess,
-        [in] unsigned long AliasId,
+        [in] ULONG AliasId,
         [out] SAMPR_HANDLE *AliasHandle);
 
     /* Function 28 */
@@ -1088,7 +1088,7 @@
     SamrOpenUser(
         [in] SAMPR_HANDLE DomainHandle,
         [in] ACCESS_MASK DesiredAccess,
-        [in] unsigned long UserId,
+        [in] ULONG UserId,
         [out] SAMPR_HANDLE *UserHandle);
 
     /* Function 35 */


Reply via email to