Objectives:-
- AD account locked out
- AD account password expired
- AD account username/password correct
- AD account disabled
I am using msDS-User-Account-Control-Computed in my DirectorySearcher. This method will return Boolean value true or false.
// This method is Authenticate Active Directory User.
public bool AuthenticateActiveDirectoryUser(string userName, string password)
{
bool isUserAuthenticated = false;
const int UF_DISABLED = 0x0002;
const int UF_LOCKED = 0x0010;
const int UF_EXPIRED = 0x800000;
try
{
DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://myserver.domain.com", userName, password,
AuthenticationTypes.Secure);
DirectorySearcher oSearcher = new DirectorySearcher(directoryEntry, "SAMAccountName=" + userName,
new string[]
{
"userAccountControl",
"msDS-User-Account-Control-Computed"
},
SearchScope.Subtree);
SearchResult result = oSearcher.FindOne();
if (result == null)
{
//"User not identified in AD";
}
else if (Convert.ToBoolean(Convert.ToInt32(result.Properties["userAccountControl"][0]) & UF_DISABLED))
{
//"Account has been disabled. Please contact administrator for more details";
}
else if (result.Properties.Contains("msDS-User-Account-Control-Computed") &&
Convert.ToBoolean(Convert.ToInt32(result.Properties["msDS-User-Account-Control-Computed"][0]) &
UF_LOCKED))
{
//"Account locked-out. Please contact administrator for more details";
}
else if (Convert.ToBoolean(Convert.ToInt32(result.Properties["userAccountControl"][0]) & UF_EXPIRED))
{
//"Password has expired. Please change your password before attempting to login again.";
}
else
{
//Number of days left based on user last changed password.
numberOfDaysLeft = CalculateNumberOfDaysLeftForPasswordExpiry(result, directoryEntry, userName);
isUserAuthenticated = true;
}
return isUserAuthenticated;
}
catch
{
//User validation returned exception. Now check for Password expired or Account locked out.
//Use the admin account (any account has LDAP query rights) to check for the above condition.
DirectoryEntry directoryEntryWithAdmin = new DirectoryEntry("LDAP://myserver.domain.com", Utility.GetAdminUser(), Utility.GetAdminPassword());
DirectorySearcher directorySearch = new DirectorySearcher(directoryEntryWithAdmin, "SAMAccountName=" + userName,
new string[]
{
"userAccountControl",
"msDS-User-Account-Control-Computed"
}
, SearchScope.Subtree);
SearchResult searchResult = directorySearch.FindOne();
if (searchResult == null)
{
//"User not identified in AD";
}
else if (Convert.ToBoolean(Convert.ToInt32(searchResult.Properties["userAccountControl"][0]) & UF_DISABLED))
{
//"Account has been disabled. Please contact administrator for more details";
}
else if (searchResult.Properties.Contains("msDS-User-Account-Control-Computed") &&
Convert.ToBoolean(Convert.ToInt32(searchResult.Properties["msDS-User-Account-Control-Computed"][0]) &
UF_LOCKED))
{
//"Account locked-out. Please contact administrator for more details";
}
else if (Convert.ToBoolean(Convert.ToInt32(searchResult.Properties["msDS-User-Account-Control-Computed"][0]) & UF_EXPIRED))
{
//"Password has expired. Please change your password before attempting to login again.";
}
else
{
//"Username and/or Password incorrect"
}
return false;
}
}
// This Method will return days left for password expiration.
private int? CalculateNumberOfDaysLeftForPasswordExpiry(SearchResult result, DirectoryEntry directoryEntry, string userName)
{
TimeSpan timeSpan;
int? nofDays = null;
if (result != null)
{
DirectorySearcher oSearcher = new DirectorySearcher(directoryEntry);
oSearcher.Filter = "(SAMAccountName=" + userName + ")";
oSearcher.PropertiesToLoad.Add("sn");
oSearcher.PropertiesToLoad.Add("pwdLastSet");
SearchResult searchResult = oSearcher.FindOne();
searchResult.GetDirectoryEntry();
if (searchResult.Properties["pwdLastSet"].Count > 0)
{
Int64 acctPwdChange = 0;
acctPwdChange = (Int64)searchResult.Properties["pwdLastSet"][0];
DateTime dtNow = DateTime.Now;
DateTime dtAcctPwdChange = DateTime.FromFileTime(acctPwdChange).AddDays(passwordExpirationDays);
timeSpan = dtAcctPwdChange - dtNow;
nofDays = timeSpan.Days;
}
}
return nofDays;
}