Hi,
We currently have a requirement to authenticate ADAM users against an ADAM instance and we have come across an issue when authenticating ADAM user accounts whose password are either [Expired] or have the [Password must be changed on next logon] flag
set. The issue has only manifested itself on Windows Server 2003 environments.
Setup: Windows Server 2003 (Enterprise) with an ADAM instance containing an ADAM user (e.g. user1)
The following is a code snippet which binds to the ADAM instance to validate the user’s credentials:
using (DirectoryEntry en = new DirectoryEntry("LDAP://localhost:389/CN=TestPartition,DC=TestDomain", "user1", "password", AuthenticationTypes.None))
{
en.RefreshCache(); //Attempt to bind
Console.WriteLine("Success");
}
Attempting the above code when User1 has an [Expired] password or has the [Password must be changed on next logon] flag will throw an exception. On Windows Server 2008+, Windows 7, Windows 8 environments, the exception thrown will be aDirectoryServicesCOMException containing an ExtendedErrorMessage property (http://msdn.microsoft.com/en-us/library/system.directoryservices.directoryservicescomexception.extendederrormessage%28v=vs.110%29.aspx). This property can be parsed to determine an error code which explains why the bind failed (http://social.technet.microsoft.com/Forums/windowsserver/en-US/474abb8f-cfc6-4cac-af79-c3e80e80291f/ldap-authentication-error-ldap-error-code-49-80090308-ldaperr-dsid0c090334-comment?forum=winserverDS).If the bind failed with error code 532 (password expired) or 773 (user must reset password) we know that the credentials are correct but the user must change his/her password; in which case we would show the necessary prompts.
However, on a Windows Server 2003 environment the exception thrown in such circumstances will be the genericCOMException (0x8007052E) Logon failure: unknown user name or bad password,which is the same exception thrown when the password is incorrect. The COMException does not contain information on why the bind failed and as a result I am unable to determine whether the credentials are correct or otherwise, for any ADAM user whose password is expired or must be reset. We have tried this on multiple versions of Windows Server 2003 SP2 and all produce the same issue.
In a bit more detail, we are aware that DirectoryEntry.Refresh() uses DirectoryEntry.Bind() which in turn uses the ADsGetLastError() Win32 function to retrieve the error. We can confirm that on a Windows Server 2003 this function returns successfully
(HResult = 0) but with no AD error code (lpError = 0) which is why the DirectoryEntry.Bind() throws a COMException rather than a DirectoryServicesCOMException.
Is there any particular reason why this is happening? Is there any way we can validate an ADAM user’s credentials whose password is expired or must be reset?
Thanks.