Question

After resetting a users password in Active Directory, if the user tries to log in using their old password, the following code validates as True:

Dim up As UserPrincipal = GetAdUser(objContext, arg_strBA, arg_strUsername)

If up IsNot Nothing Then

    Dim valid As Boolean = up.Context.ValidateCredentials(
    up.UserPrincipalName, arg_strPassword, ContextOptions.Negotiate)


    If (valid) Then strReturn = up.SamAccountName

End If

We are resetting the password using the following code:

Dim objUser As New DirectoryEntry(arg_strLDAPPath)

If Not objUser Is Nothing Then
    objUser.AuthenticationType = AuthenticationTypes.Secure


    objUser.Invoke("SetPassword", arg_strNewPW)
    objUser.CommitChanges()
end if

The password reset works fine and the user can log in with their new password, but their old password should not still validate.

When the above ValidateCredentials works for the old password, we are assigning the credentials to a web service call, which then fails with a "401: Unauthorized" error.

Anyone seen anything like this?

Was it helpful?

Solution 2

I fount the answer Here

From the link...

"However, what counts is that ContextOption does not ensure the use of Kerberos only. It turns out that under certain situations (like if you are specifying AD rather than local, and you have a sufficiently up to date server), the code chooses to do Negotiate no matter what. In that sense, specifying Sealing probably means that it will use Kerberos, but not necessarily exclusively. The flag that really matters is burried several layers under that. Under the covers, this method ends up establishing an LdapConnection, setting the network Credentials for the connection, setting that AuthType (the actual flag that matters!), and finally calling the Bind() method. The LdapConnection.Bind() method establishes an authenticated connection to one of the AD servers using the specified credentials. The problem is that when PrincipalContext.ValidateCredentials sets up this call (in your scenario), it always sets the AuthType = Negotiate. In this case, Kerberos does in fact get used, and ends up failing, but the system falls back to NTLM."

OTHER TIPS

This issue is not related to Code but the culprit over hear is the Active directory...

Please refer http://support.microsoft.com/kb/906305 for solution...

This Works - See SOLUTION below - Please let me know if you find this helpful as our shop is divided on whether this is an OK solution.

The following is a Solution to Active Directory Allowing Old Password to work after being changed. I would very much like feedback on the acceptance of this solution as it uses the ChangePassword during the Login Authentication. This is an odd thing to do but it works. Currently our shop is not using this solution so if anyone can tell me if they are using it or not that would be appreciated.

Thank you Ch

Active Directory and Old Passwords returning Valid (15 minutes to +- hour). This occurs when SetPassword or ChangePassword are Invoked.

History:

I find that this is called a “Feature” of AD and is by design built into AD so that when a user changes passwords there is a kind of grace period that allows all resources using those passwords to transfer over to the new one.

One example of AD that supports the concept that AD knows the latest password is that of changing a login password on a PC – in this case the computer will not allow the old password to login. While I do not have the answer to this (other than Microsoft had to get this to work) it is my opinion that this is not as simple as it may appear as the PC is involved and it has passwords on it too.

One example showing how password changes in AD do last for a time period may be:

Using Remote Desktop from a Windows 7 PC to a Windows Server 2008 R2 box. Login from the Windows Security Box then the , click OK box appears, click OK and you are logged in. Now Change your password for the user you used to Remote into the box with (different from your Kirkman user ??), logout and login again with old password (within timeframe 15 minutes to an hour +-). The old password will get you past the Windows Security box and to the OK Box. When you click OK it will then fail. If you start over from Remote Desktop and try a bad password you will be stopped at the Windows Security Box with message “The Logon attempt failed”. After the time limit expires you will not get past the Windows Security box with the old password. (make sure to start from Remote Desktop each time NOT switch users which will act as expected which also shows that the PC in involved somehow). At least it does not the user login – but this does show that (what appears to be AD) at some level allows old passwords to authenticate to some level.

Research: I have found many references to this problem and only one potential solution that to this point I have not been able to determine if we can implement it (this is the reference to calling strictly via Kerberos and not NTLM which is not as simple as it may appear according to the documentation and my research). I have found many links to how to interact with AD in .NET but no actual AD Manual.

SOLUTION SOLUTION SOLUTION - Read this part if you want the SOlution SOLUTION!!! Present: I have found (by accident during testing) that the ChangePassword call to AD will not allow the OldPassword passed to it succeed in changing the password to the new password. It is my opinion that this test that does work is not actually known as I have not found any reference to it being used. I actually have not found any solution to this problem. One morning at 3:00 am I realized that I could exploit this use of ChangePassword to provide a solution to this problem – at least a work-around we can use immediately until we can determine a better approach.

First I check that everything is valid and AD returns that the password is valid. Then a call to ChangePassword (username, oldpassword, newpassword) with the oldpassword and newpassword as password provided by the user (both the same) is done. I know one of two (possibly three but the password policy violation stops it from succeeding) outcomes will happen. Either the OldPassword is good and we fail because the Password Policy is not met (history, new password cannot be one of last N passwords) or we fail because the Old Password is incorrect (both returned as Exception error with text in message). We check for this last condition and if the oldpassword is not valid we do not let the user log in.

Future: Maybe a second set of eyes will help.
I think the solution is in Impersonation or Kerberos. I have not had success in finding out enough on either of these as solutions. It is obvious that AD can differentiate between old passwords because the ChangePassword does it. What we are doing is at the heart of security so not everything is open (like the ability to see password history in AD, I have not found a way to access it).

Did you take the up to 15 minutes of time into account that AD requires to propagate changes like that throughout the network??

Marc

I assume you're ValidateCredentials executes on a client machine. If that is the case, then it has the old (successful) password cached. This is done to enable users to login if the Active Directory is offline or unreachable. Propagating changes takes some time.

If you want to get around this, you should authenticate with the Server serving the Webservice at authentication time instead of the local client machine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top