[SAMSRV]
authorEric Kohl <eric.kohl@reactos.org>
Mon, 22 Jul 2013 21:27:33 +0000 (21:27 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 22 Jul 2013 21:27:33 +0000 (21:27 +0000)
SamrChangePasswordUser:
- Check the MinPasswordAge before trying to change the password.
- Set the PasswordLastSet time if the password has been changed successfully.
- Set the BadPasswordCount and LastBadPasswordTime if the caller tried to set a bad password.

svn path=/trunk/; revision=59560

reactos/dll/win32/samsrv/samrpc.c

index fe7929f..385187c 100644 (file)
@@ -7475,9 +7475,15 @@ SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle,
     PENCRYPTED_LM_OWF_PASSWORD NewLmPassword;
     PENCRYPTED_NT_OWF_PASSWORD OldNtPassword;
     PENCRYPTED_NT_OWF_PASSWORD NewNtPassword;
     PENCRYPTED_LM_OWF_PASSWORD NewLmPassword;
     PENCRYPTED_NT_OWF_PASSWORD OldNtPassword;
     PENCRYPTED_NT_OWF_PASSWORD NewNtPassword;
+    BOOLEAN StoredLmPresent = FALSE;
+    BOOLEAN StoredNtPresent = FALSE;
+    BOOLEAN StoredLmEmpty = TRUE;
+    BOOLEAN StoredNtEmpty = TRUE;
     PSAM_DB_OBJECT UserObject;
     ULONG Length;
     PSAM_DB_OBJECT UserObject;
     ULONG Length;
-    SAM_USER_FIXED_DATA FixedUserData;
+    SAM_USER_FIXED_DATA UserFixedData;
+    SAM_DOMAIN_FIXED_DATA DomainFixedData;
+    LARGE_INTEGER SystemTime;
     NTSTATUS Status;
 
     TRACE("(%p %u %p %p %u %p %p %u %p %u %p)\n",
     NTSTATUS Status;
 
     TRACE("(%p %u %p %p %u %p %p %u %p %u %p)\n",
@@ -7496,6 +7502,14 @@ SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle,
         return Status;
     }
 
         return Status;
     }
 
+    /* Get the current time */
+    Status = NtQuerySystemTime(&SystemTime);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("NtQuerySystemTime failed (Status 0x%08lx)\n", Status);
+        return Status;
+    }
+
     /* Retrieve the LM password */
     Length = sizeof(ENCRYPTED_LM_OWF_PASSWORD);
     Status = SampGetObjectAttribute(UserObject,
     /* Retrieve the LM password */
     Length = sizeof(ENCRYPTED_LM_OWF_PASSWORD);
     Status = SampGetObjectAttribute(UserObject,
@@ -7503,9 +7517,16 @@ SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle,
                                     NULL,
                                     &StoredLmPassword,
                                     &Length);
                                     NULL,
                                     &StoredLmPassword,
                                     &Length);
-    if (!NT_SUCCESS(Status))
+    if (NT_SUCCESS(Status))
     {
     {
-
+        if (Length == sizeof(ENCRYPTED_LM_OWF_PASSWORD))
+        {
+            StoredLmPresent = TRUE;
+            if (!RtlEqualMemory(&StoredLmPassword,
+                                &EmptyLmHash,
+                                sizeof(ENCRYPTED_LM_OWF_PASSWORD)))
+                StoredLmEmpty = FALSE;
+        }
     }
 
     /* Retrieve the NT password */
     }
 
     /* Retrieve the NT password */
@@ -7515,9 +7536,52 @@ SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle,
                                     NULL,
                                     &StoredNtPassword,
                                     &Length);
                                     NULL,
                                     &StoredNtPassword,
                                     &Length);
+    if (NT_SUCCESS(Status))
+    {
+        if (Length == sizeof(ENCRYPTED_NT_OWF_PASSWORD))
+        {
+            StoredNtPresent = TRUE;
+            if (!RtlEqualMemory(&StoredNtPassword,
+                                &EmptyNtHash,
+                                sizeof(ENCRYPTED_NT_OWF_PASSWORD)))
+                StoredNtEmpty = FALSE;
+        }
+    }
+
+    /* Retrieve the fixed size user data */
+    Length = sizeof(SAM_USER_FIXED_DATA);
+    Status = SampGetObjectAttribute(UserObject,
+                                    L"F",
+                                    NULL,
+                                    &UserFixedData,
+                                    &Length);
     if (!NT_SUCCESS(Status))
     {
     if (!NT_SUCCESS(Status))
     {
+        TRACE("SampGetObjectAttribute failed to retrieve the fixed user data (Status 0x%08lx)\n", Status);
+        return Status;
+    }
+
+    /* Check if we can change the password at this time */
+    if ((StoredNtEmpty == FALSE) || (StoredNtEmpty == FALSE))
+    {
+        /* Get fixed domain data */
+        Length = sizeof(SAM_DOMAIN_FIXED_DATA);
+        Status = SampGetObjectAttribute(UserObject->ParentObject,
+                                        L"F",
+                                        NULL,
+                                        &DomainFixedData,
+                                        &Length);
+        if (!NT_SUCCESS(Status))
+        {
+            TRACE("SampGetObjectAttribute failed to retrieve the fixed domain data (Status 0x%08lx)\n", Status);
+            return Status;
+        }
 
 
+        if (DomainFixedData.MinPasswordAge.QuadPart > 0)
+        {
+            if (SystemTime.QuadPart < (UserFixedData.PasswordLastSet.QuadPart + DomainFixedData.MinPasswordAge.QuadPart))
+                return STATUS_ACCOUNT_RESTRICTION;
+        }
     }
 
     /* FIXME: Decrypt passwords */
     }
 
     /* FIXME: Decrypt passwords */
@@ -7588,28 +7652,34 @@ SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle,
                                      LmPresent);
         if (NT_SUCCESS(Status))
         {
                                      LmPresent);
         if (NT_SUCCESS(Status))
         {
-            /* Get the fixed size user data */
+            /* Update PasswordLastSet */
+            UserFixedData.PasswordLastSet.QuadPart = SystemTime.QuadPart;
+
+            /* Set the fixed size user data */
             Length = sizeof(SAM_USER_FIXED_DATA);
             Length = sizeof(SAM_USER_FIXED_DATA);
-            Status = SampGetObjectAttribute(UserObject,
+            Status = SampSetObjectAttribute(UserObject,
                                             L"F",
                                             L"F",
-                                            NULL,
-                                            &FixedUserData,
-                                            &Length);
-            if (NT_SUCCESS(Status))
-            {
-                /* Update PasswordLastSet */
-                NtQuerySystemTime(&FixedUserData.PasswordLastSet);
-
-                /* Set the fixed size user data */
-                Status = SampSetObjectAttribute(UserObject,
-                                                L"F",
-                                                REG_BINARY,
-                                                &FixedUserData,
-                                                Length);
-            }
+                                            REG_BINARY,
+                                            &UserFixedData,
+                                            Length);
         }
     }
 
         }
     }
 
+    if (Status == STATUS_WRONG_PASSWORD)
+    {
+        /* Update BadPasswordCount and LastBadPasswordTime */
+        UserFixedData.BadPasswordCount++;
+        UserFixedData.LastBadPasswordTime.QuadPart = SystemTime.QuadPart;
+
+        /* Set the fixed size user data */
+        Length = sizeof(SAM_USER_FIXED_DATA);
+        Status = SampSetObjectAttribute(UserObject,
+                                        L"F",
+                                        REG_BINARY,
+                                        &UserFixedData,
+                                        Length);
+    }
+
     return Status;
 }
 
     return Status;
 }