Validating AD credentials when the user’s password “must be changed at next logon” using C#

We have several AD controllers in our setup. On controllers running Windows Server 2008 R2, this is not an issue. But if your code is hitting AD controllers running Windows server 2003, the PrincipalContext.ValidateCredentials method will always return false on users that have the “user must change password at next logon” checkbox checked; even if the username and password combination is valid.

The code below is a workaround for the Windows 2003 servers. It pretty much unchecks the checkbox, then validates the credentials, and then re-checks the checkbox.

var adContext = new PrincipalContext(ContextType.Domain, adLocation, adContainer, adAdminUsername, adAdminPassword);

var initialValidation = adContext.ValidateCredentials(username, password);
Console.WriteLine("Initial validation returned: " + initialValidation);

if (!initialValidation)
{
    // maybe validation failed because "user must change password at next logon".
    // let's see if that is the case.

    var user = UserPrincipal.FindByIdentity(adContext, username);
    if (user.LastPasswordSet == null)
    {
        // the user must change his password at next logon. So this might be
        // why validation returned false

        // uncheck the "change password" checkbox and attempt validation again

        var deUser = user.GetUnderlyingObject() as DirectoryEntry;
        var property = deUser.Properties["pwdLastSet"];
        property.Value = -1;
        deUser.CommitChanges();

        // property was unset, retry validation
        adContext.ValidateCredentials(username, password);
        Console.WriteLine("Secondary validation returned: " + adContext.ValidateCredentials(username, password));

        // re check the checkbox
        property.Value = 0;
        deUser.CommitChanges();
  }
}
Advertisements