Author: ekohl Date: Mon Jul 22 21:27:33 2013 New Revision: 59560
URL: http://svn.reactos.org/svn/reactos?rev=59560&view=rev Log: [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.
Modified: trunk/reactos/dll/win32/samsrv/samrpc.c
Modified: trunk/reactos/dll/win32/samsrv/samrpc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samrpc.c?r... ============================================================================== --- trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] Mon Jul 22 21:27:33 2013 @@ -7475,9 +7475,15 @@ 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", @@ -7493,6 +7499,14 @@ if (!NT_SUCCESS(Status)) { TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status); + return Status; + } + + /* Get the current time */ + Status = NtQuerySystemTime(&SystemTime); + if (!NT_SUCCESS(Status)) + { + TRACE("NtQuerySystemTime failed (Status 0x%08lx)\n", Status); return Status; }
@@ -7503,9 +7517,16 @@ 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 @@ NULL, &StoredNtPassword, &Length); - if (!NT_SUCCESS(Status)) - { - + 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,26 +7652,32 @@ 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;