[SAMSRV]
authorEric Kohl <eric.kohl@reactos.org>
Sun, 22 Jul 2012 15:12:00 +0000 (15:12 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 22 Jul 2012 15:12:00 +0000 (15:12 +0000)
- Ensure that account names are not in use when a new alias, group or user is created. Return a proper status code if the account name is alread in use.
- Initialize logon/password  related data for new user account objects.
- Add missing prototypes and user account control bits to ntsam.h

svn path=/trunk/; revision=56936

reactos/dll/win32/samsrv/database.c
reactos/dll/win32/samsrv/samrpc.c
reactos/dll/win32/samsrv/samsrv.h
reactos/include/ddk/ntsam.h
reactos/include/reactos/idl/sam.idl

index 421ef74..199b549 100644 (file)
@@ -484,10 +484,10 @@ SampCloseDbObject(PSAM_DB_OBJECT DbObject)
 
 
 NTSTATUS
-SampSetDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject,
-                         IN LPCWSTR lpContainerName,
-                         IN LPCWSTR lpAliasName,
-                         IN ULONG ulAliasValue)
+SampSetAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
+                           IN LPCWSTR lpContainerName,
+                           IN LPCWSTR lpAccountName,
+                           IN ULONG ulRelativeId)
 {
     OBJECT_ATTRIBUTES ObjectAttributes;
     UNICODE_STRING KeyName;
@@ -496,6 +496,8 @@ SampSetDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject,
     HANDLE NamesKeyHandle = NULL;
     NTSTATUS Status;
 
+    TRACE("SampSetAccountNameInDomain()\n");
+
     /* Open the container key */
     RtlInitUnicodeString(&KeyName, lpContainerName);
 
@@ -527,13 +529,13 @@ SampSetDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject,
         goto done;
 
     /* Set the alias value */
-    RtlInitUnicodeString(&ValueName, lpAliasName);
+    RtlInitUnicodeString(&ValueName, lpAccountName);
 
     Status = NtSetValueKey(NamesKeyHandle,
                            &ValueName,
                            0,
                            REG_DWORD,
-                           (LPVOID)&ulAliasValue,
+                           (LPVOID)&ulRelativeId,
                            sizeof(ULONG));
 
 done:
@@ -547,87 +549,6 @@ done:
 }
 
 
-NTSTATUS
-SampCheckDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject,
-                           IN LPCWSTR lpContainerName,
-                           IN LPCWSTR lpAliasName,
-                           OUT PBOOL bAliasExists)
-{
-    PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    UNICODE_STRING KeyName;
-    UNICODE_STRING ValueName;
-    HANDLE ContainerKeyHandle = NULL;
-    HANDLE NamesKeyHandle = NULL;
-    ULONG BufferLength = sizeof(ULONG);
-    NTSTATUS Status;
-
-    /* Open the container key */
-    RtlInitUnicodeString(&KeyName, lpContainerName);
-
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &KeyName,
-                               OBJ_CASE_INSENSITIVE,
-                               DomainObject->KeyHandle,
-                               NULL);
-
-    Status = NtOpenKey(&ContainerKeyHandle,
-                       KEY_ALL_ACCESS,
-                       &ObjectAttributes);
-    if (!NT_SUCCESS(Status))
-        return Status;
-
-    /* Open the 'Names' key */
-    RtlInitUnicodeString(&KeyName, L"Names");
-
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &KeyName,
-                               OBJ_CASE_INSENSITIVE,
-                               ContainerKeyHandle,
-                               NULL);
-
-    Status = NtOpenKey(&NamesKeyHandle,
-                       KEY_ALL_ACCESS,
-                       &ObjectAttributes);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    /* Get the alias value */
-    RtlInitUnicodeString(&ValueName, lpAliasName);
-
-    BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
-
-    /* Allocate memory for the value */
-    ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
-    if (ValueInfo == NULL)
-        return STATUS_NO_MEMORY;
-
-    /* Query the value */
-    Status = ZwQueryValueKey(NamesKeyHandle,
-                             &ValueName,
-                             KeyValuePartialInformation,
-                             ValueInfo,
-                             BufferLength,
-                             &BufferLength);
-
-    *bAliasExists = (Status != STATUS_OBJECT_NAME_NOT_FOUND);
-
-    Status = STATUS_SUCCESS;
-
-    /* Free the memory and return status */
-    RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
-
-done:
-    if (NamesKeyHandle)
-        NtClose(NamesKeyHandle);
-
-    if (ContainerKeyHandle)
-        NtClose(ContainerKeyHandle);
-
-    return Status;
-}
-
-
 NTSTATUS
 SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
                              IN LPWSTR lpAccountName)
@@ -636,7 +557,7 @@ SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
     HANDLE NamesKey;
     NTSTATUS Status;
 
-    TRACE("SampCheckNameInDomain()\n");
+    TRACE("SampCheckAccountNameInDomain()\n");
 
     Status = SampRegOpenKey(DomainObject->KeyHandle,
                             L"Aliases",
@@ -656,11 +577,12 @@ SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
                                        NULL,
                                        NULL);
             if (Status == STATUS_SUCCESS)
+            {
+                SampRegCloseKey(NamesKey);
                 Status = STATUS_ALIAS_EXISTS;
+            }
             else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
                 Status = STATUS_SUCCESS;
-
-            SampRegCloseKey(NamesKey);
         }
 
         SampRegCloseKey(AccountKey);
@@ -690,11 +612,12 @@ SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
                                        NULL,
                                        NULL);
             if (Status == STATUS_SUCCESS)
+            {
+                SampRegCloseKey(NamesKey);
                 Status = STATUS_ALIAS_EXISTS;
+            }
             else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
                 Status = STATUS_SUCCESS;
-
-            SampRegCloseKey(NamesKey);
         }
 
         SampRegCloseKey(AccountKey);
@@ -724,11 +647,12 @@ SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
                                        NULL,
                                        NULL);
             if (Status == STATUS_SUCCESS)
+            {
+                SampRegCloseKey(NamesKey);
                 Status = STATUS_ALIAS_EXISTS;
+            }
             else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
                 Status = STATUS_SUCCESS;
-
-            SampRegCloseKey(NamesKey);
         }
 
         SampRegCloseKey(AccountKey);
index 4fb41b2..35ebbba 100644 (file)
@@ -1622,11 +1622,11 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle,
         return Status;
     }
 
-    /* Add the name alias for the user object */
-    Status = SampSetDbObjectNameAlias(DomainObject,
-                                      L"Groups",
-                                      Name->Buffer,
-                                      ulRid);
+    /* Add the account name of the user object */
+    Status = SampSetAccountNameInDomain(DomainObject,
+                                        L"Groups",
+                                        Name->Buffer,
+                                        ulRid);
     if (!NT_SUCCESS(Status))
     {
         TRACE("failed with status 0x%08lx\n", Status);
@@ -1723,6 +1723,13 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
     TRACE("SamrCreateUserInDomain(%p %p %lx %p %p)\n",
           DomainHandle, Name, DesiredAccess, UserHandle, RelativeId);
 
+    if (Name == NULL ||
+        Name->Length == 0 ||
+        Name->Buffer == NULL ||
+        UserHandle == NULL ||
+        RelativeId == NULL)
+        return STATUS_INVALID_PARAMETER;
+
     /* Validate the domain handle */
     Status = SampValidateDbObject(DomainHandle,
                                   SamDbDomainObject,
@@ -1791,11 +1798,11 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
         return Status;
     }
 
-    /* Add the name alias for the user object */
-    Status = SampSetDbObjectNameAlias(DomainObject,
-                                      L"Users",
-                                      Name->Buffer,
-                                      ulRid);
+    /* Add the account name for the user object */
+    Status = SampSetAccountNameInDomain(DomainObject,
+                                        L"Users",
+                                        Name->Buffer,
+                                        ulRid);
     if (!NT_SUCCESS(Status))
     {
         TRACE("failed with status 0x%08lx\n", Status);
@@ -1805,12 +1812,17 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
     /* Initialize fixed user data */
     memset(&FixedUserData, 0, sizeof(SAM_USER_FIXED_DATA));
     FixedUserData.Version = 1;
-
+    FixedUserData.LastLogon.QuadPart = 0;
+    FixedUserData.LastLogoff.QuadPart = 0;
+    FixedUserData.PasswordLastSet.QuadPart = 0;
+    FixedUserData.AccountExpires.LowPart = MAXULONG;
+    FixedUserData.AccountExpires.HighPart = MAXLONG;
+    FixedUserData.LastBadPasswordTime.QuadPart = 0;
     FixedUserData.UserId = ulRid;
     FixedUserData.PrimaryGroupId = DOMAIN_GROUP_RID_USERS;
-//    FixedUserData.UserAccountControl = USER_ACCOUNT_DISABLED |
-//                                       USER_PASSWORD_NOT_REQUIRED ||
-//                                       USER_NORMAL_ACCOUNT;
+    FixedUserData.UserAccountControl = USER_ACCOUNT_DISABLED |
+                                       USER_PASSWORD_NOT_REQUIRED |
+                                       USER_NORMAL_ACCOUNT;
 
     /* Set fixed user data attribute */
     Status = SampSetObjectAttribute(UserObject,
@@ -2050,11 +2062,11 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle,
         return Status;
     }
 
-    /* Add the name alias for the user object */
-    Status = SampSetDbObjectNameAlias(DomainObject,
-                                      L"Aliases",
-                                      AccountName->Buffer,
-                                      ulRid);
+    /* Add the account name for the alias object */
+    Status = SampSetAccountNameInDomain(DomainObject,
+                                        L"Aliases",
+                                        AccountName->Buffer,
+                                        ulRid);
     if (!NT_SUCCESS(Status))
     {
         TRACE("failed with status 0x%08lx\n", Status);
index ce441ea..c7e54ad 100644 (file)
@@ -139,20 +139,14 @@ NTSTATUS
 SampCloseDbObject(PSAM_DB_OBJECT DbObject);
 
 NTSTATUS
-SampSetDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject,
-                         IN LPCWSTR lpContainerName,
-                         IN LPCWSTR lpAliasName,
-                         IN DWORD dwAliasValue);
+SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
+                             IN LPWSTR lpAccountName);
 
 NTSTATUS
-SampCheckDbObjectNameAlias(IN PSAM_DB_OBJECT DomainObject,
+SampSetAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
                            IN LPCWSTR lpContainerName,
-                           IN LPCWSTR lpAliasName,
-                           OUT PBOOL bAliasExists);
-
-NTSTATUS
-SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
-                             IN LPWSTR lpAccountName);
+                           IN LPCWSTR lpAccountName,
+                           IN ULONG ulRelativeId);
 
 NTSTATUS
 SampSetObjectAttribute(PSAM_DB_OBJECT DbObject,
index 1e13410..3ff860e 100644 (file)
@@ -163,6 +163,31 @@ extern "C" {
                                         USER_READ_GROUP_INFORMATION |\
                                         USER_WRITE_GROUP_INFORMATION)
 
+/* User account control bits */
+#define USER_ACCOUNT_DISABLED                       0x00000001
+#define USER_HOME_DIRECTORY_REQUIRED                0x00000002
+#define USER_PASSWORD_NOT_REQUIRED                  0x00000004
+#define USER_TEMP_DUPLICATE_ACCOUNT                 0x00000008
+#define USER_NORMAL_ACCOUNT                         0x00000010
+#define USER_MNS_LOGON_ACCOUNT                      0x00000020
+#define USER_INTERDOMAIN_TRUST_ACCOUNT              0x00000040
+#define USER_WORKSTATION_TRUST_ACCOUNT              0x00000080
+#define USER_SERVER_TRUST_ACCOUNT                   0x00000100
+#define USER_DONT_EXPIRE_PASSWORD                   0x00000200
+#define USER_ACCOUNT_AUTO_LOCKED                    0x00000400
+#define USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED        0x00000800
+#define USER_SMARTCARD_REQUIRED                     0x00001000
+#define USER_TRUSTED_FOR_DELEGATION                 0x00002000
+#define USER_NOT_DELEGATED                          0x00004000
+#define USER_USE_DES_KEY_ONLY                       0x00008000
+#define USER_DONT_REQUIRE_PREAUTH                   0x00010000
+#define USER_PASSWORD_EXPIRED                       0x00020000
+#define USER_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x00040000
+#define USER_NO_AUTH_DATA_REQUIRED                  0x00080000
+#define USER_PARTIAL_SECRETS_ACCOUNT                0x00100000
+#define USER_USE_AES_KEYS                           0x00200000
+
+
 typedef PVOID SAM_HANDLE, *PSAM_HANDLE;
 typedef ULONG SAM_ENUMERATE_HANDLE, *PSAM_ENUMERATE_HANDLE;
 
@@ -291,6 +316,12 @@ NTAPI
 SamAddMemberToAlias(IN SAM_HANDLE AliasHandle,
                     IN PSID MemberId);
 
+NTSTATUS
+NTAPI
+SamAddMemberToGroup(IN SAM_HANDLE GroupHandle,
+                    IN ULONG MemberId,
+                    IN ULONG Attributes);
+
 NTSTATUS
 NTAPI
 SamCloseHandle(IN SAM_HANDLE SamHandle);
@@ -414,6 +445,12 @@ SamQueryInformationDomain(IN SAM_HANDLE DomainHandle,
                           IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
                           OUT PVOID *Buffer);
 
+NTSTATUS
+NTAPI
+SamQueryInformationGroup(IN SAM_HANDLE GroupHandle,
+                         IN GROUP_INFORMATION_CLASS GroupInformationClass,
+                         OUT PVOID *Buffer);
+
 NTSTATUS
 NTAPI
 SamQueryInformationUser(IN SAM_HANDLE UserHandle,
@@ -435,7 +472,13 @@ NTSTATUS
 NTAPI
 SamSetInformationDomain(IN SAM_HANDLE DomainHandle,
                         IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
-                        IN PVOID DomainInformation);
+                        IN PVOID Buffer);
+
+NTSTATUS
+NTAPI
+SamSetInformationGroup(IN SAM_HANDLE GroupHandle,
+                       IN GROUP_INFORMATION_CLASS GroupInformationClass,
+                       IN PVOID Buffer);
 
 NTSTATUS
 NTAPI
@@ -447,7 +490,6 @@ NTSTATUS
 NTAPI
 SamShutdownSamServer(IN SAM_HANDLE ServerHandle);
 
-
 #ifdef __cplusplus
 }
 #endif
index 90d5406..3ff5467 100644 (file)
@@ -628,9 +628,9 @@ typedef struct _SAMPR_USER_INTERNAL1_INFORMATION
 {
     ENCRYPTED_NT_OWF_PASSWORD EncryptedNtOwfPassword;
     ENCRYPTED_LM_OWF_PASSWORD EncryptedLmOwfPassword;
-    unsigned char NtPasswordPresent;
-    unsigned char LmPasswordPresent;
-    unsigned char PasswordExpired;
+    BOOLEAN NtPasswordPresent;
+    BOOLEAN LmPasswordPresent;
+    BOOLEAN PasswordExpired;
 } SAMPR_USER_INTERNAL1_INFORMATION, *PSAMPR_USER_INTERNAL1_INFORMATION;
 
 typedef struct _SAMPR_USER_INTERNAL4_INFORMATION
@@ -648,13 +648,13 @@ typedef struct _SAMPR_USER_INTERNAL4_INFORMATION_NEW
 typedef struct _SAMPR_USER_INTERNAL5_INFORMATION
 {
     SAMPR_ENCRYPTED_USER_PASSWORD UserPassword;
-    unsigned char PasswordExpired;
+    BOOLEAN PasswordExpired;
 } SAMPR_USER_INTERNAL5_INFORMATION, *PSAMPR_USER_INTERNAL5_INFORMATION;
 
 typedef struct _SAMPR_USER_INTERNAL5_INFORMATION_NEW
 {
     SAMPR_ENCRYPTED_USER_PASSWORD_NEW UserPassword;
-    unsigned char PasswordExpired;
+    BOOLEAN PasswordExpired;
 } SAMPR_USER_INTERNAL5_INFORMATION_NEW, *PSAMPR_USER_INTERNAL5_INFORMATION_NEW;
 
 cpp_quote("#ifndef _NTSAM_")