[SAMLIB]
authorEric Kohl <eric.kohl@reactos.org>
Thu, 31 May 2012 11:07:51 +0000 (11:07 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Thu, 31 May 2012 11:07:51 +0000 (11:07 +0000)
- Implement SamOpenUser and SamSetInformationUser.
- Add SamQueryInformationUser stub.

[SAMSRV]
- Implement SamrOpenUser.
- Add a hack to SamrSetInformationUser that enables us to store a users password (as plain-text) in the registry.
- SamrCreateUserInDomain: Fix the creation of user account key names and start counting user RIDs at 1000.
- Clean-up the SAM registry setup code.
- Assingn SIDs to the BUILTIN and Account domains.
- Create the Administrator and Guest accounts in the SAM setup.

svn path=/trunk/; revision=56679

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

index 0f4146b..3dc6370 100644 (file)
@@ -404,6 +404,7 @@ SamCloseHandle(IN SAM_HANDLE SamHandle)
     return Status;
 }
 
+
 NTSTATUS
 NTAPI
 SamConnect(IN OUT PUNICODE_STRING ServerName,
@@ -431,6 +432,7 @@ SamConnect(IN OUT PUNICODE_STRING ServerName,
     return Status;
 }
 
+
 NTSTATUS
 NTAPI
 SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
@@ -461,6 +463,7 @@ SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
     return Status;
 }
 
+
 NTSTATUS
 NTAPI
 SamOpenDomain(IN SAM_HANDLE ServerHandle,
@@ -489,6 +492,74 @@ SamOpenDomain(IN SAM_HANDLE ServerHandle,
     return Status;
 }
 
+
+NTSTATUS
+NTAPI
+SamOpenUser(IN SAM_HANDLE DomainHandle,
+            IN ACCESS_MASK DesiredAccess,
+            IN ULONG UserId,
+            OUT PSAM_HANDLE UserHandle)
+{
+    NTSTATUS Status;
+
+    TRACE("SamOpenUser(%p,0x%08x,%lx,%p)\n",
+          DomainHandle, DesiredAccess, UserId, UserHandle);
+
+    RpcTryExcept
+    {
+        Status = SamrOpenUser((SAMPR_HANDLE)DomainHandle,
+                              DesiredAccess,
+                              UserId,
+                              (SAMPR_HANDLE *)UserHandle);
+    }
+    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
+NTAPI
+SamSetInformationUser(IN SAM_HANDLE UserHandle,
+                      IN USER_INFORMATION_CLASS UserInformationClass,
+                      IN PVOID Buffer)
+{
+    NTSTATUS Status;
+
+    TRACE("SamSetInformationUser(%p %lu %p)\n",
+          UserHandle, UserInformationClass, Buffer);
+
+    RpcTryExcept
+    {
+        Status = SamrSetInformationUser((SAMPR_HANDLE)UserHandle,
+                                        UserInformationClass,
+                                        Buffer);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
 NTSTATUS
 NTAPI
 SamShutdownSamServer(IN SAM_HANDLE ServerHandle)
index 25cb6e2..b2a5307 100644 (file)
 @ stub SamOpenAlias
 @ stdcall SamOpenDomain(ptr long ptr ptr)
 @ stub SamOpenGroup
-@ stub SamOpenUser
+@ stdcall SamOpenUser(ptr long long ptr)
 @ stub SamQueryDisplayInformation
 @ stub SamQueryInformationAlias
 @ stub SamQueryInformationDomain
 @ stub SamQueryInformationGroup
-@ stub SamQueryInformationUser
+@ stdcall SamQueryInformationUser(ptr long ptr)
 @ stub SamQuerySecurityObject
 @ stub SamRemoveMemberFromAlias
 @ stub SamRemoveMemberFromForeignDomain
@@ -46,7 +46,7 @@
 @ stub SamSetInformationAlias
 @ stub SamSetInformationDomain
 @ stub SamSetInformationGroup
-@ stub SamSetInformationUser
+@ stdcall SamSetInformationUser(ptr long ptr)
 @ stub SamSetMemberAttributesOfGroup
 @ stub SamSetSecurityObject
 @ stdcall SamShutdownSamServer(ptr)
index 8e19334..dd4b6de 100644 (file)
@@ -337,12 +337,12 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
                                     (LPVOID)&ulRid,
                                     &ulSize);
     if (!NT_SUCCESS(Status))
-        ulRid = DOMAIN_USER_RID_MAX;
+        ulRid = DOMAIN_USER_RID_MAX + 1;
 
     TRACE("RID: %lx\n", ulRid);
 
     /* Convert the RID into a string (hex) */
-    _ultow(ulRid, szRid, 16);
+    swprintf(szRid, L"%08lX", ulRid);
 
     /* Check whether the user name is already in use */
     Status = SampCheckDbObjectNameAlias(DomainObject,
@@ -385,9 +385,9 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
         return Status;
     }
 
-    /* Set the account name attribute */
+    /* Set the name attribute */
     Status = SampSetObjectAttribute(UserObject,
-                                    L"AccountName",
+                                    L"Name",
                                     REG_SZ,
                                     (LPVOID)Name->Buffer,
                                     Name->MaximumLength);
@@ -658,12 +658,48 @@ SamrGetMembersInAlias(IN SAMPR_HANDLE AliasHandle,
 NTSTATUS
 NTAPI
 SamrOpenUser(IN SAMPR_HANDLE DomainHandle,
-             IN unsigned long DesiredAccess,
+             IN ACCESS_MASK DesiredAccess,
              IN unsigned long UserId,
              OUT SAMPR_HANDLE *UserHandle)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PSAM_DB_OBJECT DomainObject;
+    PSAM_DB_OBJECT UserObject;
+    WCHAR szRid[9];
+    NTSTATUS Status;
+
+    TRACE("SamrOpenUser(%p %lx %lx %p)\n",
+          DomainHandle, DesiredAccess, UserId, UserHandle);
+
+    /* 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", UserId);
+
+    /* Create the user object */
+    Status = SampOpenDbObject(DomainObject,
+                              L"Users",
+                              szRid,
+                              SamDbUserObject,
+                              DesiredAccess,
+                              &UserObject);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
+    *UserHandle = (SAMPR_HANDLE)UserObject;
+
+    return STATUS_SUCCESS;
 }
 
 /* Function 35 */
@@ -686,6 +722,27 @@ SamrQueryInformationUser(IN SAMPR_HANDLE UserHandle,
     return STATUS_NOT_IMPLEMENTED;
 }
 
+
+static
+NTSTATUS
+SampSetPasswordInformation(PSAM_DB_OBJECT UserObject,
+                           PSAMPR_USER_SET_PASSWORD_INFORMATION PasswordInfo)
+{
+    NTSTATUS Status;
+
+    TRACE("Password: %S\n", PasswordInfo->Password.Buffer);
+    TRACE("PasswordExpired: %d\n", PasswordInfo->PasswordExpired);
+
+    Status = SampSetObjectAttribute(UserObject,
+                                    L"Password",
+                                    REG_SZ,
+                                    PasswordInfo->Password.Buffer,
+                                    PasswordInfo->Password.MaximumLength);
+
+    return Status;
+}
+
+
 /* Function 37 */
 NTSTATUS
 NTAPI
@@ -693,8 +750,36 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle,
                        IN USER_INFORMATION_CLASS UserInformationClass,
                        IN PSAMPR_USER_INFO_BUFFER Buffer)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PSAM_DB_OBJECT UserObject;
+    NTSTATUS Status;
+
+    TRACE("SamrSetInformationUser(%p %lu %p)\n",
+          UserHandle, UserInformationClass, Buffer);
+
+    /* Validate the domain handle */
+    Status = SampValidateDbObject(UserHandle,
+                                  SamDbUserObject,
+                                  USER_FORCE_PASSWORD_CHANGE,
+                                  &UserObject);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("failed with status 0x%08lx\n", Status);
+        return Status;
+    }
+
+    switch (UserInformationClass)
+    {
+        case UserSetPasswordInformation:
+            Status = SampSetPasswordInformation(UserObject,
+                                                (PSAMPR_USER_SET_PASSWORD_INFORMATION)Buffer);
+            break;
+
+        default:
+            Status = STATUS_INVALID_INFO_CLASS;
+            break;
+    }
+
+    return Status;
 }
 
 /* Function 38 */
@@ -848,7 +933,7 @@ NTAPI
 SamrCreateUser2InDomain(IN SAMPR_HANDLE DomainHandle,
                         IN PRPC_UNICODE_STRING Name,
                         IN unsigned long AccountType,
-                        IN unsigned long DesiredAccess,
+                        IN ACCESS_MASK DesiredAccess,
                         OUT SAMPR_HANDLE *UserHandle,
                         OUT unsigned long *GrantedAccess,
                         OUT unsigned long *RelativeId)
index af33771..9c4037f 100644 (file)
@@ -7,7 +7,7 @@
  * PROGRAMMERS:     Eric Kohl
  */
 
-#include <stdlib.h>
+#include <stdio.h>
 #define WIN32_NO_STATUS
 #include <windows.h>
 #define NTOS_MODE_USER
@@ -16,6 +16,7 @@
 #include <ndk/rtlfuncs.h>
 #include <ndk/umtypes.h>
 #include <ddk/ntsam.h>
+#include <ntsecapi.h>
 
 #include <samsrv/samsrv.h>
 
index 9450160..cc62d15 100644 (file)
@@ -13,6 +13,9 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(samsrv);
 
+/* GLOBALS *****************************************************************/
+
+SID_IDENTIFIER_AUTHORITY SecurityNtAuthority = {SECURITY_NT_AUTHORITY};
 
 /* FUNCTIONS ***************************************************************/
 
@@ -56,326 +59,309 @@ SampIsSetupRunning(VOID)
 
 
 static BOOL
-CreateNamesKey(HKEY hParentKey)
+SampCreateUserAccount(HKEY hDomainKey,
+                      LPCWSTR lpAccountName,
+                      ULONG ulRelativeId)
 {
     DWORD dwDisposition;
-    HKEY hNamesKey;
-
-    if (RegCreateKeyExW(hParentKey,
-                        L"Names",
-                        0,
-                        NULL,
-                        REG_OPTION_NON_VOLATILE,
-                        KEY_ALL_ACCESS,
-                        NULL,
-                        &hNamesKey,
-                        &dwDisposition))
-        return FALSE;
-
-    RegCloseKey(hNamesKey);
-    return TRUE;
-}
+    WCHAR szUserKeyName[32];
+    HKEY hUserKey = NULL;
+    HKEY hNamesKey = NULL;
+
+    swprintf(szUserKeyName, L"Users\\%08lX", ulRelativeId);
+
+    if (!RegCreateKeyExW(hDomainKey,
+                         szUserKeyName,
+                         0,
+                         NULL,
+                         REG_OPTION_NON_VOLATILE,
+                         KEY_ALL_ACCESS,
+                         NULL,
+                         &hUserKey,
+                         &dwDisposition))
+    {
+        RegSetValueEx(hUserKey,
+                      L"Name",
+                      0,
+                      REG_SZ,
+                      (LPVOID)lpAccountName,
+                      (wcslen(lpAccountName) + 1) * sizeof(WCHAR));
+
+        RegCloseKey(hUserKey);
+    }
 
+    if (!RegOpenKeyExW(hDomainKey,
+                       L"Users\\Names",
+                       0,
+                       KEY_ALL_ACCESS,
+                       &hNamesKey))
+    {
+        RegSetValueEx(hNamesKey,
+                      lpAccountName,
+                      0,
+                      REG_DWORD,
+                      (LPVOID)&ulRelativeId,
+                      sizeof(ULONG));
+
+        RegCloseKey(hNamesKey);
+    }
 
-static BOOL
-CreateBuiltinAliases(HKEY hAliasesKey)
-{
     return TRUE;
 }
 
 
 static BOOL
-CreateBuiltinGroups(HKEY hGroupsKey)
-{
-    return TRUE;
-}
-
-
-static BOOL
-CreateBuiltinUsers(HKEY hUsersKey)
-{
-    return TRUE;
-}
-
-
-BOOL
-SampInitializeSAM(VOID)
+SampCreateDomain(IN HKEY hDomainsKey,
+                 IN LPCWSTR lpDomainName,
+                 IN PSID lpDomainSid,
+                 OUT PHKEY lpDomainKey)
 {
     DWORD dwDisposition;
-    HKEY hSamKey = NULL;
-    HKEY hDomainsKey = NULL;
-    HKEY hAccountKey = NULL;
-    HKEY hBuiltinKey = NULL;
-    HKEY hAliasesKey = NULL;
+    HKEY hDomainKey = NULL;
+    HKEY hAliasKey = NULL;
     HKEY hGroupsKey = NULL;
     HKEY hUsersKey = NULL;
-    BOOL bResult = TRUE;
+    HKEY hNamesKey = NULL;
 
-    TRACE("SampInitializeSAM() called\n");
+    if (lpDomainKey != NULL)
+        *lpDomainKey = NULL;
 
-    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
-                        L"SAM\\SAM",
+    if (RegCreateKeyExW(hDomainsKey,
+                        lpDomainName,
                         0,
                         NULL,
                         REG_OPTION_NON_VOLATILE,
                         KEY_ALL_ACCESS,
                         NULL,
-                        &hSamKey,
+                        &hDomainKey,
                         &dwDisposition))
-    {
-        ERR("Failed to create 'Sam' key! (Error %lu)\n", GetLastError());
         return FALSE;
-    }
 
-    if (RegCreateKeyExW(hSamKey,
-                        L"Domains",
-                        0,
-                        NULL,
-                        REG_OPTION_NON_VOLATILE,
-                        KEY_ALL_ACCESS,
-                        NULL,
-                        &hDomainsKey,
-                        &dwDisposition))
+    if (lpDomainSid != NULL)
     {
-        ERR("Failed to create 'Domains' key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
+        RegSetValueEx(hDomainKey,
+                      L"SID",
+                      0,
+                      REG_BINARY,
+                      (LPVOID)lpDomainSid,
+                      RtlLengthSid(lpDomainSid));
     }
 
-    RegCloseKey(hSamKey);
-    hSamKey = NULL;
-
-    /* Create the 'Domains\\Account' key */
-    if (RegCreateKeyExW(hDomainsKey,
-                        L"Account",
-                        0,
-                        NULL,
-                        REG_OPTION_NON_VOLATILE,
-                        KEY_ALL_ACCESS,
-                        NULL,
-                        &hAccountKey,
-                        &dwDisposition))
+    /* Create the Alias container */
+    if (!RegCreateKeyExW(hDomainKey,
+                         L"Alias",
+                         0,
+                         NULL,
+                         REG_OPTION_NON_VOLATILE,
+                         KEY_ALL_ACCESS,
+                         NULL,
+                         &hAliasKey,
+                         &dwDisposition))
     {
-        ERR("Failed to create 'Domains\\Account' key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
+        if (!RegCreateKeyExW(hAliasKey,
+                             L"Names",
+                             0,
+                             NULL,
+                             REG_OPTION_NON_VOLATILE,
+                             KEY_ALL_ACCESS,
+                             NULL,
+                             &hNamesKey,
+                             &dwDisposition))
+            RegCloseKey(hNamesKey);
+
+        RegCloseKey(hAliasKey);
     }
 
-
-    /* Create the 'Account\Aliases' key */
-    if (RegCreateKeyExW(hAccountKey,
-                        L"Aliases",
-                        0,
-                        NULL,
-                        REG_OPTION_NON_VOLATILE,
-                        KEY_ALL_ACCESS,
-                        NULL,
-                        &hAliasesKey,
-                        &dwDisposition))
+    /* Create the Groups container */
+    if (!RegCreateKeyExW(hDomainKey,
+                         L"Groups",
+                         0,
+                         NULL,
+                         REG_OPTION_NON_VOLATILE,
+                         KEY_ALL_ACCESS,
+                         NULL,
+                         &hGroupsKey,
+                         &dwDisposition))
     {
-        ERR("Failed to create 'Account\\Aliases' key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
-    }
+        if (!RegCreateKeyExW(hGroupsKey,
+                             L"Names",
+                             0,
+                             NULL,
+                             REG_OPTION_NON_VOLATILE,
+                             KEY_ALL_ACCESS,
+                             NULL,
+                             &hNamesKey,
+                             &dwDisposition))
+            RegCloseKey(hNamesKey);
 
-    if (!CreateNamesKey(hAliasesKey))
-    {
-        ERR("Failed to create 'Account\\Aliases\\Names' key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
+        RegCloseKey(hGroupsKey);
     }
 
-    RegCloseKey(hAliasesKey);
-    hAliasesKey = NULL;
 
-    /* Create the 'Account\Groups' key */
-    if (RegCreateKeyExW(hAccountKey,
-                        L"Groups",
-                        0,
-                        NULL,
-                        REG_OPTION_NON_VOLATILE,
-                        KEY_ALL_ACCESS,
-                        NULL,
-                        &hGroupsKey,
-                        &dwDisposition))
+    /* Create the Users container */
+    if (!RegCreateKeyExW(hDomainKey,
+                         L"Users",
+                         0,
+                         NULL,
+                         REG_OPTION_NON_VOLATILE,
+                         KEY_ALL_ACCESS,
+                         NULL,
+                         &hUsersKey,
+                         &dwDisposition))
     {
-        ERR("Failed to create 'Account\\Groups' key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
-    }
+        if (!RegCreateKeyExW(hUsersKey,
+                             L"Names",
+                             0,
+                             NULL,
+                             REG_OPTION_NON_VOLATILE,
+                             KEY_ALL_ACCESS,
+                             NULL,
+                             &hNamesKey,
+                             &dwDisposition))
+            RegCloseKey(hNamesKey);
 
-    if (!CreateNamesKey(hGroupsKey))
-    {
-        ERR("Failed to create 'Account\\Groups\\Names' key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
+        RegCloseKey(hUsersKey);
     }
 
-    RegCloseKey(hGroupsKey);
-    hGroupsKey = NULL;
+    if (lpDomainKey != NULL)
+        *lpDomainKey = hDomainKey;
 
+    return TRUE;
+}
 
-    /* Create the 'Account\Users' key */
-    if (RegCreateKeyExW(hAccountKey,
-                        L"Users",
-                        0,
-                        NULL,
-                        REG_OPTION_NON_VOLATILE,
-                        KEY_ALL_ACCESS,
-                        NULL,
-                        &hUsersKey,
-                        &dwDisposition))
-    {
-        ERR("Failed to create 'Account\\Users' key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
-    }
 
-    if (!CreateNamesKey(hUsersKey))
+NTSTATUS
+SampGetAccountDomainInfo(PPOLICY_ACCOUNT_DOMAIN_INFO *AccountDomainInfo)
+{
+    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
+    LSA_HANDLE PolicyHandle;
+    NTSTATUS Status;
+
+    TRACE("SampGetAccountDomainInfo\n");
+
+    memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
+    ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
+
+    Status = LsaOpenPolicy(NULL,
+                           &ObjectAttributes,
+                           POLICY_TRUST_ADMIN,
+                           &PolicyHandle);
+    if (Status != STATUS_SUCCESS)
     {
-        ERR("Failed to create 'Account\\Aliases\\Users' key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
+        ERR("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
+        return Status;
     }
 
-    RegCloseKey(hUsersKey);
-    hUsersKey = NULL;
+    Status = LsaQueryInformationPolicy(PolicyHandle,
+                                       PolicyAccountDomainInformation,
+                                       (PVOID *)AccountDomainInfo);
 
-    RegCloseKey(hAccountKey);
-    hAccountKey = NULL;
+    LsaClose(PolicyHandle);
 
-    /* Create the 'Domains\\Builtin' */
-    if (RegCreateKeyExW(hDomainsKey,
-                        L"Builtin",
+    return Status;
+}
+
+
+BOOL
+SampInitializeSAM(VOID)
+{
+    PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL;
+    DWORD dwDisposition;
+    HKEY hSamKey = NULL;
+    HKEY hDomainsKey = NULL;
+    HKEY hDomainKey = NULL;
+    PSID pBuiltinSid = NULL;
+    BOOL bResult = TRUE;
+    NTSTATUS Status;
+
+    TRACE("SampInitializeSAM() called\n");
+
+    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
+                        L"SAM\\SAM",
                         0,
                         NULL,
                         REG_OPTION_NON_VOLATILE,
                         KEY_ALL_ACCESS,
                         NULL,
-                        &hBuiltinKey,
+                        &hSamKey,
                         &dwDisposition))
     {
-        ERR("Failed to create Builtin key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
+        ERR("Failed to create 'Sam' key! (Error %lu)\n", GetLastError());
+        return FALSE;
     }
 
-
-    /* Create the 'Builtin\Aliases' key */
-    if (RegCreateKeyExW(hBuiltinKey,
-                        L"Aliases",
+    if (RegCreateKeyExW(hSamKey,
+                        L"Domains",
                         0,
                         NULL,
                         REG_OPTION_NON_VOLATILE,
                         KEY_ALL_ACCESS,
                         NULL,
-                        &hAliasesKey,
+                        &hDomainsKey,
                         &dwDisposition))
     {
-        ERR("Failed to create 'Builtin\\Aliases' key! (Error %lu)\n", GetLastError());
+        ERR("Failed to create 'Domains' key! (Error %lu)\n", GetLastError());
         bResult = FALSE;
         goto done;
     }
 
-    if (!CreateNamesKey(hAliasesKey))
-    {
-        ERR("Failed to create 'Builtin\\Aliases\\Names' key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
-    }
+    RegCloseKey(hSamKey);
+    hSamKey = NULL;
 
-    /* Create builtin aliases */
-    if (!CreateBuiltinAliases(hAliasesKey))
+    /* Create and initialize the Builtin Domain SID */
+    pBuiltinSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, RtlLengthRequiredSid(1));
+    if (pBuiltinSid == NULL)
     {
-        ERR("Failed to create builtin aliases!\n");
+        ERR("Failed to alloacte the Builtin Domain SID\n");
         bResult = FALSE;
         goto done;
     }
 
-    RegCloseKey(hAliasesKey);
-    hAliasesKey = NULL;
+    RtlInitializeSid(pBuiltinSid, &SecurityNtAuthority, 1);
+    *(RtlSubAuthoritySid(pBuiltinSid, 0)) = SECURITY_BUILTIN_DOMAIN_RID;
 
-    /* Create the 'Builtin\Groups' key */
-    if (RegCreateKeyExW(hBuiltinKey,
-                        L"Groups",
-                        0,
-                        NULL,
-                        REG_OPTION_NON_VOLATILE,
-                        KEY_ALL_ACCESS,
-                        NULL,
-                        &hGroupsKey,
-                        &dwDisposition))
+    /* Get account domain information */
+    Status = SampGetAccountDomainInfo(&AccountDomainInfo);
+    if (!NT_SUCCESS(Status))
     {
-        ERR("Failed to create 'Builtin\\Groups' key! (Error %lu)\n", GetLastError());
+        ERR("SampGetAccountDomainInfo failed (Status %08lx)\n", Status);
         bResult = FALSE;
         goto done;
     }
 
-    if (!CreateNamesKey(hGroupsKey))
+    /* Create the Builtin domain */
+    if (SampCreateDomain(hDomainsKey,
+                         L"Builtin",
+                         pBuiltinSid,
+                         &hDomainKey))
     {
-        ERR("Failed to create 'Builtin\\Groups\\Names' key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
-    }
 
-    /* Create builtin groups */
-    if (!CreateBuiltinGroups(hGroupsKey))
-    {
-        ERR("Failed to create builtin groups!\n");
-        bResult = FALSE;
-        goto done;
+        RegCloseKey(hDomainKey);
     }
 
-    RegCloseKey(hGroupsKey);
-    hGroupsKey = NULL;
-
-
-    /* Create the 'Builtin\Users' key */
-    if (RegCreateKeyExW(hBuiltinKey,
-                        L"Users",
-                        0,
-                        NULL,
-                        REG_OPTION_NON_VOLATILE,
-                        KEY_ALL_ACCESS,
-                        NULL,
-                        &hUsersKey,
-                        &dwDisposition))
+    /* Create the Account domain */
+    if (SampCreateDomain(hDomainsKey,
+                         L"Account",
+                         AccountDomainInfo->DomainSid, //NULL,
+                         &hDomainKey))
     {
-        ERR("Failed to create 'Builtin\\Users' key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
-    }
+        SampCreateUserAccount(hDomainKey,
+                              L"Administrator",
+                              DOMAIN_USER_RID_ADMIN);
 
-    if (!CreateNamesKey(hUsersKey))
-    {
-        ERR("Failed to create 'Builtin\\Users\\Names' key! (Error %lu)\n", GetLastError());
-        bResult = FALSE;
-        goto done;
-    }
+        SampCreateUserAccount(hDomainKey,
+                              L"Guest",
+                              DOMAIN_USER_RID_GUEST);
 
-    /* Create builtin users */
-    if (!CreateBuiltinUsers(hUsersKey))
-    {
-        ERR("Failed to create builtin users!\n");
-        bResult = FALSE;
-        goto done;
+        RegCloseKey(hDomainKey);
     }
 
 done:
-    if (hAliasesKey)
-        RegCloseKey(hAliasesKey);
-
-    if (hGroupsKey)
-        RegCloseKey(hGroupsKey);
-
-    if (hUsersKey)
-        RegCloseKey(hUsersKey);
-
-    if (hAccountKey)
-        RegCloseKey(hAccountKey);
+    if (AccountDomainInfo)
+        LsaFreeMemory(AccountDomainInfo);
 
-    if (hBuiltinKey)
-        RegCloseKey(hBuiltinKey);
+    if (pBuiltinSid)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, pBuiltinSid);
 
     if (hDomainsKey)
         RegCloseKey(hDomainsKey);
index fec2f53..b1e7dc4 100644 (file)
@@ -25,9 +25,60 @@ extern "C" {
 #define SAM_SERVER_ENUMERATE_DOMAINS 16
 #define SAM_SERVER_LOOKUP_DOMAIN 32
 
+#define USER_READ_GENERAL 1
+#define USER_READ_PREFERENCES 2
+#define USER_WRITE_PREFERENCES 4
+#define USER_READ_LOGON 8
+#define USER_READ_ACCOUNT 16
+#define USER_WRITE_ACCOUNT 32
+#define USER_CHANGE_PASSWORD 64
+#define USER_FORCE_PASSWORD_CHANGE 128
+#define USER_LIST_GROUPS 256
+#define USER_READ_GROUP_INFORMATION 512
+#define USER_WRITE_GROUP_INFORMATION 1024
 
 typedef PVOID SAM_HANDLE, *PSAM_HANDLE;
 
+typedef enum _USER_INFORMATION_CLASS
+{
+    UserGeneralInformation = 1,
+    UserPreferencesInformation,
+    UserLogonInformation,
+    UserLogonHoursInformation,
+    UserAccountInformation,
+    UserNameInformation,
+    UserAccountNameInformation,
+    UserFullNameInformation,
+    UserPrimaryGroupInformation,
+    UserHomeInformation,
+    UserScriptInformation,
+    UserProfileInformation,
+    UserAdminCommentInformation,
+    UserWorkStationsInformation,
+    UserSetPasswordInformation,
+    UserControlInformation,
+    UserExpiresInformation,
+    UserInternal1Information,
+    UserInternal2Information,
+    UserParametersInformation,
+    UserAllInformation,
+    UserInternal3Information,
+    UserInternal4Information,
+    UserInternal5Information,
+    UserInternal4InformationNew,
+    UserInternal5InformationNew,
+    UserInternal6Information,
+    UserExtendedInformation,
+    UserLogonUIInformation,
+} USER_INFORMATION_CLASS, *PUSER_INFORMATION_CLASS;
+
+typedef struct _USER_SET_PASSWORD_INFORMATION
+{
+    UNICODE_STRING Password;
+    BOOLEAN PasswordExpired;
+} USER_SET_PASSWORD_INFORMATION, *PUSER_SET_PASSWORD_INFORMATION;
+
+
 NTSTATUS
 NTAPI
 SamCloseHandle(IN SAM_HANDLE SamHandle);
@@ -54,6 +105,25 @@ SamOpenDomain(IN SAM_HANDLE ServerHandle,
               IN PSID DomainId,
               OUT PSAM_HANDLE DomainHandle);
 
+NTSTATUS
+NTAPI
+SamOpenUser(IN SAM_HANDLE DomainHandle,
+            IN ACCESS_MASK DesiredAccess,
+            IN ULONG UserId,
+            OUT PSAM_HANDLE UserHandle);
+
+NTSTATUS
+NTAPI
+SamQueryInformationUser(IN SAM_HANDLE UserHandle,
+                        IN USER_INFORMATION_CLASS UserInformationClass,
+                        OUT PVOID *Buffer);
+
+NTSTATUS
+NTAPI
+SamSetInformationUser(IN SAM_HANDLE UserHandle,
+                      IN USER_INFORMATION_CLASS UserInformationClass,
+                      IN PVOID Buffer);
+
 NTSTATUS
 NTAPI
 SamShutdownSamServer(IN SAM_HANDLE ServerHandle);
index 141629a..cff1024 100644 (file)
@@ -152,6 +152,7 @@ typedef enum _DOMAIN_SERVER_ROLE
     DomainServerRolePrimary = 3
 } DOMAIN_SERVER_ROLE, *PDOMAIN_SERVER_ROLE;
 
+cpp_quote("#ifndef _NTSECAPI_H")
 typedef struct _DOMAIN_PASSWORD_INFORMATION
 {
     unsigned short MinPasswordLength;
@@ -160,6 +161,7 @@ typedef struct _DOMAIN_PASSWORD_INFORMATION
     OLD_LARGE_INTEGER MaxPasswordAge;
     OLD_LARGE_INTEGER MinPasswordAge;
 } DOMAIN_PASSWORD_INFORMATION, *PDOMAIN_PASSWORD_INFORMATION;
+cpp_quote("#endif")
 
 typedef struct _DOMAIN_LOGOFF_INFORMATION
 {
@@ -600,6 +602,13 @@ typedef struct _SAMPR_USER_WORKSTATIONS_INFORMATION
     RPC_UNICODE_STRING WorkStations;
 } SAMPR_USER_WORKSTATIONS_INFORMATION, *PSAMPR_USER_WORKSTATIONS_INFORMATION;
 
+typedef struct _SAMPR_USER_SET_PASSWORD_INFORMATION
+{
+//    SAMPR_ENCRYPTED_USER_PASSWORD Password;
+    RPC_UNICODE_STRING Password;
+    BOOLEAN PasswordExpired;
+} SAMPR_USER_SET_PASSWORD_INFORMATION, *PSAMPR_USER_SET_PASSWORD_INFORMATION;
+
 typedef struct _SAMPR_USER_LOGON_HOURS_INFORMATION
 {
     SAMPR_LOGON_HOURS LogonHours;
@@ -638,6 +647,7 @@ typedef struct _SAMPR_USER_INTERNAL5_INFORMATION_NEW
     unsigned char PasswordExpired;
 } SAMPR_USER_INTERNAL5_INFORMATION_NEW, *PSAMPR_USER_INTERNAL5_INFORMATION_NEW;
 
+cpp_quote("#ifndef _NTSAM_")
 typedef enum _USER_INFORMATION_CLASS
 {
     UserGeneralInformation = 1,
@@ -654,16 +664,23 @@ typedef enum _USER_INFORMATION_CLASS
     UserProfileInformation = 12,
     UserAdminCommentInformation = 13,
     UserWorkStationsInformation = 14,
+    UserSetPasswordInformation = 15, /* This is missing from the SAM RPC documentation */
     UserControlInformation = 16,
     UserExpiresInformation = 17,
     UserInternal1Information = 18,
+    UserInternal2Information = 19,   /* This is missing from the SAM RPC documentation */
     UserParametersInformation = 20,
     UserAllInformation = 21,
+    UserInternal3Information = 22,   /* This is missing from the SAM RPC documentation */
     UserInternal4Information = 23,
     UserInternal5Information = 24,
     UserInternal4InformationNew = 25,
     UserInternal5InformationNew = 26,
+    UserInternal6Information,        /* This is missing from the SAM RPC documentation */
+    UserExtendedInformation,         /* This is missing from the SAM RPC documentation */
+    UserLogonUIInformation,          /* This is missing from the SAM RPC documentation */
 } USER_INFORMATION_CLASS, *PUSER_INFORMATION_CLASS;
+cpp_quote("#endif")
 
 typedef [switch_type(USER_INFORMATION_CLASS)] union _SAMPR_USER_INFO_BUFFER
 {
@@ -681,6 +698,7 @@ typedef [switch_type(USER_INFORMATION_CLASS)] union _SAMPR_USER_INFO_BUFFER
     [case(UserProfileInformation)] SAMPR_USER_PROFILE_INFORMATION Profile;
     [case(UserAdminCommentInformation)] SAMPR_USER_ADMIN_COMMENT_INFORMATION AdminComment;
     [case(UserWorkStationsInformation)] SAMPR_USER_WORKSTATIONS_INFORMATION WorkStations;
+    [case(UserSetPasswordInformation)] SAMPR_USER_SET_PASSWORD_INFORMATION SetPassword;
     [case(UserControlInformation)] USER_CONTROL_INFORMATION Control;
     [case(UserExpiresInformation)] USER_EXPIRES_INFORMATION Expires;
     [case(UserInternal1Information)] SAMPR_USER_INTERNAL1_INFORMATION Internal1;
@@ -1015,7 +1033,7 @@ interface samr
     __stdcall
     SamrOpenAlias(
         [in] SAMPR_HANDLE DomainHandle,
-        [in] unsigned long DesiredAccess,
+        [in] ACCESS_MASK DesiredAccess,
         [in] unsigned long AliasId,
         [out] SAMPR_HANDLE *AliasHandle);
 
@@ -1067,7 +1085,7 @@ interface samr
     __stdcall
     SamrOpenUser(
         [in] SAMPR_HANDLE DomainHandle,
-        [in] unsigned long DesiredAccess,
+        [in] ACCESS_MASK DesiredAccess,
         [in] unsigned long UserId,
         [out] SAMPR_HANDLE *UserHandle);
 
@@ -1209,7 +1227,7 @@ interface samr
         [in] SAMPR_HANDLE DomainHandle,
         [in] PRPC_UNICODE_STRING Name,
         [in] unsigned long AccountType,
-        [in] unsigned long DesiredAccess,
+        [in] ACCESS_MASK DesiredAccess,
         [out] SAMPR_HANDLE *UserHandle,
         [out] unsigned long *GrantedAccess,
         [out] unsigned long *RelativeId);