Currently I authenticate users against some AD using the following code:
DirectoryEntry entry = new DirectoryEntry(_path, username, pwd);
try
{
// Bind
The "password expires" check is relatively easy - at least on Windows (not sure how other systems handle this): when the Int64 value of "pwdLastSet" is 0, then the user will have to change his (or her) password at next logon. The easiest way to check this is include this property in your DirectorySearcher:
DirectorySearcher search = new DirectorySearcher(entry)
{ Filter = "(sAMAccountName=" + username + ")" };
search.PropertiesToLoad.Add("cn");
search.PropertiesToLoad.Add("pwdLastSet");
SearchResult result = search.FindOne();
if (result == null)
{
return false;
}
Int64 pwdLastSetValue = (Int64)result.Properties["pwdLastSet"][0];
As for the "account is locked out" check - this seems easy at first, but isn't.... The "UF_Lockout" flag on "userAccountControl" doesn't do its job reliably.
Beginning with Windows 2003 AD, there's a new computed attribute which you can check for: msDS-User-Account-Control-Computed.
Given a DirectoryEntry user, you can do:
string attribName = "msDS-User-Account-Control-Computed";
user.RefreshCache(new string[] { attribName });
const int UF_LOCKOUT = 0x0010;
int userFlags = (int)user.Properties[attribName].Value;
if(userFlags & UF_LOCKOUT == UF_LOCKOUT)
{
// if this is the case, the account is locked out
}
If you can use .NET 3.5, things have gotten a lot easier - check out the MSDN article on how to deal with users and groups in .NET 3.5 using the System.DirectoryServices.AccountManagement namespace. E.g. you now do have a property IsAccountLockedOut on the UserPrincipal class which reliably tells you whether or not an account is locked out.
Hope this helps!
Marc