Reputation: 1005
I have application which allows users to change their passwords. Those users are stored in Active Directory. On password change I need to apply password policies. Complexity policies are easy. But what if password has to differ to last 20 passwords for this user? Is anyhow possible to use AD user's password history for this?
I know AD stores list of last about 20 passwords' hashes for each user. Afaik it is not possible to retrieve that list. But is anyhow possible to ask AD if password is contained by that list? Or is possible to ask AD, if password is valid new password for particular user according to policies defined by AD configuration?
Upvotes: 1
Views: 1872
Reputation: 41008
No, AD doesn't give away that information. The only way to check if a password is good is to try to change it.
But note that there's a difference between "changing" the password, and "setting" the password.
Setting a password (or "resetting") is what is usually done by an administrator and the password history policies don't apply (you can actually set a password to the same thing it already is):
user.Invoke("SetPassword", newpassword);
Changing a password is what the end user does, and password history restrictions apply. In this case, the old password must be provided:
user.Invoke("ChangePassword", new object[] { oldpassword, newpassword });
If that fails, then you know there's a problem. It will tell you if the old password is wrong, or it'll tell you that the new password is bad. But it gives you the same error if either the new password is the same as an old one or it failed the complexity requirements - it won't tell you which one.
In both cases, user
is a DirectoryEntry
object.
If you want to get fancy, you could figure out how to read the complexity requirements from AD and determine if the given password matches. If it does match, but the password is still rejected, then you can safely assume the password history is the issue.
If you are not using Fine-Grained Password Policies (only on 2008+), then there is only one policy for the whole domain, which can be read from the attributes at the root of the domain:
var domain = new DirectoryEntry("LDAP://domain.com");
Then read these attributes:
Upvotes: 1