From: Eric Kohl Date: Mon, 22 Jul 2013 21:27:33 +0000 (+0000) Subject: [SAMSRV] X-Git-Tag: ReactOS-0.3.16~1875 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=c9c250aca3a6e78f082e5e8676bf0530f6fd0f20 [SAMSRV] 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 --- diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index fe7929fc47e..385187c62c7 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -7475,9 +7475,15 @@ SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle, 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; - 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", @@ -7496,6 +7502,14 @@ SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle, 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, @@ -7503,9 +7517,16 @@ SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle, 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 */ @@ -7515,9 +7536,52 @@ SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle, 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)) { + 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 */ @@ -7588,28 +7652,34 @@ SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle, 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); - Status = SampGetObjectAttribute(UserObject, + Status = SampSetObjectAttribute(UserObject, 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; }