How to check a valid Active Directory password using .NET or LDAP

The main question

Is there a way to check the Active Directory password if it has expired using .NET or some other LDAP query? To be clear, I'm not talking about checking if a password has expired, I'm talking about checking if an expired password is correct.

I found this answer which explains how this can be done using the Win32 API LogonUser () function . I asked a separate question about issues with PowerShell . Here I am asking if this can be done in any way other than Win32 API, preferably .NET.

Further discussion of the topic

The PrincipalContext.ValidateCredentials method and the DirectoryEntry constructor return the same login error message if the password is incorrect, expired, or needs to be changed at the next login. There is no way to distinguish between a wrong password and a correct but expired password.

Active Directory doesn't reveal password hashes, and AFAIK can't get around this (which is probably a good thing ...), so try making a hash script and comparing it to the directory is dead end.

The best solution I could come up with using .NET (or anything other than the Win32 API for that matter) is this awkward solution:

  • Check if the password has expired (by checking if the difference between the pwdLastSet date and the current date is greater than the maximum password age).
  • If it has expired, check if it is locked. If so, open it.
  • Read the badPwdCount attribute .
  • Attempting to authenticate by any means increases badPwdCount if it fails ( ValidateCredentials , DirectoryEntry , runas command, many other ways). Make sure the login failed.
  • Read badPwdCount again . If it has increased, the entered password is incorrect. If it hasn't increased, the password is incorrect.

(Stage 2 is required because failed authentication attempts do not increase badPwdCount if the account is locked out.)

However, I see a few drawbacks to this plan:

  • It can give false results if an attempt to authenticate from a different source occurs between the before and after badLogonCount , or if badLogonCount is reset by an administrator or has expired.
  • The script must ensure that the same domain controller is used throughout to avoid false results due to convergence delays.
  • In some cases, the script has to make changes (unlock the account), otherwise it won't work. Ideally, a validation operation should not change any aspect of the data it is looking at.

While these problems are rare and I can think of how to mitigate them, these methods are quite messy and not 100% reliable, and overall, they are far from ideal.

Is there any direct way to check this with .NET or any kind of LDAP query - some authentication tools that lead to errors that differentiate between invalid credentials and valid credentials for an expired password like LogonUser () , or whatever another creative way of differentiating that defies pitfalls like the idea outlined above?

Similar questions, but no answers

This topic has been raised several times before, but there are no answers to this specific question.

Both answers to this question are designed to validate credentials when the "User must change password at next logon" checkbox is selected. At a cursory glance, the second answer seems to be about the case where the password has expired because one of the branches of code throws a "1907 Password Expired" exception, but if you read the code carefully, you will see that this error message is misleading; it only appears if the "User must change password at next logon" checkbox is selected and the credentials are correct.

Both of these are answered by the answer links suggesting the use of LogonUser () .

[Note. I added tags c#

and vb.net

, because although the question is not language specific, I believe these are the tags that are most likely to draw it to the attention of people knowledgeable about the subject; other tags appear to have very low visibility on their own, with only 7 views in the first 5 hours.]

+3


source to share





All Articles