Detect if an Active Directory user account is locked using LDAP in Python

Daniel Reis picture Daniel Reis · Aug 3, 2012 · Viewed 69.6k times · Source

I'm validating user logins using python's ldap module. When the login fails, I get a ldap.INVALID_CREDENTIALS login, but this can be either because of a wrong password or because the account is locked. The account get's locked after the 3rd try.

I would like to detect that the account is locked and report that to the frustrated user, instead of the same "invalid login" message.

Searching for a solution I found:

  • The userAccountControl LOCKED flag is not used by AD;
  • The lockoutTime attribute should be used instead

The LDAP query I should be using to find locked users is:

(&(objectClass=user)(lockoutTime>=1))

Or for a specific user:

(&(objectClass=user)(sAMAccountName=jabberwocky)(lockoutTime>=1))

But this is not working, the query returns no results every time.

Answer

Harvey Kwok picture Harvey Kwok · Aug 7, 2012

A value of zero in lockoutTime means it's not locked out. So, you should try this.

(&(objectClass=user)(!lockoutTime=0)) 

Actually, the above query is still not 100% correct. If you read the fine print from MSDN, Microsoft is suggesting you to add the Lockout-Time attribute to the Lockout-Duration attribute and then compare it with the current time. That's because there is such a thing called lockout duration. Once the lockout duration passes, the user is unlocked automatically. Zero in Lockout-Duration means the account is locked forever until the administrator unlock it.

See this MSDN article

This attribute value is only reset when the account is logged onto successfully. This means that this value may be non zero, yet the account is not locked out. To accurately determine if the account is locked out, you must add the Lockout-Duration to this time and compare the result to the current time, accounting for local time zones and daylight savings time.