views:

6637

answers:

3

I need to find a way to check if an Active Directory UserAccount has his account locked or not.

I've tried userAccountControl property in a Windows 2000 AD but that property does not change a byte when I force an account to get locked (by trying to log on to a workstation providing the wrong password for that specific user) And I can tell by using ADExplorer.exe utility made by semi-god -> Mr. Russinovich

I've seen that in the 3.5 Framework they use the method .InvokeGet("userLockedOut"); but I'm trying to do this in a Enterprise Application that was written in .Net Framework 1.1 and there's no chance of using newer ones (just if you thought of suggesting so).

+1  A: 

Here is a link with all the info on Active Directory stuff...

http://www.codeproject.com/KB/system/everythingInAD.aspx

J.13.L
Thanks for your reply.... this article found at codeproject which every other post in the Net refers to is not for .Net Framework 1.1 is for 2.0 and above...http://www.codeproject.com/KB/system/everythingInAD.aspx#45
monoco
A: 

Found this, it is a little more than I have done in the past (can't find exact snippets) though the key is doing a directory search and limiting based on the lockouttime for your user(s) that are returned. Additionally for a particular user, you can limit your search further using additional properties. The codeproject link above has that particular logic (for search limiting) I believe.

class Lockout : IDisposable
{
  DirectoryContext context;
  DirectoryEntry root;
  DomainPolicy policy;

  public Lockout(string domainName)
  {
    this.context = new DirectoryContext(
      DirectoryContextType.Domain,
      domainName
      );

    //get our current domain policy
    Domain domain = Domain.GetDomain(this.context);

    this.root = domain.GetDirectoryEntry();
    this.policy = new DomainPolicy(this.root);      
  }

  public void FindLockedAccounts()
  {
    //default for when accounts stay locked indefinitely
    string qry = "(lockoutTime>=1)";

    TimeSpan duration = this.policy.LockoutDuration;

    if (duration != TimeSpan.MaxValue)
    {
      DateTime lockoutThreshold =
        DateTime.Now.Subtract(duration);

      qry = String.Format(
        "(lockoutTime>={0})",
        lockoutThreshold.ToFileTime()
        );
    }

    DirectorySearcher ds = new DirectorySearcher(
      this.root,
      qry
      );

    using (SearchResultCollection src = ds.FindAll())
    {
      foreach (SearchResult sr in src)
      {
        long ticks =
          (long)sr.Properties["lockoutTime"][0];

        Console.WriteLine(
          "{0} locked out at {1}",
          sr.Properties["name"][0],
          DateTime.FromFileTime(ticks)
          );
      }
    }
  }

  public void Dispose()
  {
    if (this.root != null)
    {
      this.root.Dispose();
    }
  }
}

Code was pulled from this post: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/5e0fadc2-f27b-48f6-a6ac-644e12256c67/

Joshua
Thank you Joshua, but unfortunately your solution which I had already seen surfing the web implements classes that are from .Net 2.0 and abovesuch as: HostSecurityManager.DomainPolicy PropertyNote: This property is new in the .NET Framework version 2.0.
monoco
Ahh, sorry, didn't see the 1.1 in my excitement to answer the question.
Joshua
A: 

After seeing the .NET 1.1, check this thread out: http://forums.asp.net/t/434077.aspx, using the lockouttime in the filter should still do the trick.

Specifically in the thread (after the larger code post which provides alot of the syntax):

(&(objectClass=user)(objectCategory=person)(lockoutTime>=1));

One other thing, it turns out that if you are using .NET v.1.1, then S.DS converts the Integer8 to the long integer correctly for you (does not work with 1.0) - which means you can do away with reflection code (in the post):

//use the filter from above

SearchResultCollection src = ds.FindAll();  

foreach(SearchResult sr in src)

{

     DateTime lockoutTime = DateTime.FromFileTime((long)sr.Properties["lockoutTime][0]);

     Response.Output.Write("Locked Out on: {0}", lockoutTime.ToString());

}
Joshua