PrincipalSearcher.FindAll returns different results when using a custom UserPrincipal

3.8k views Asked by At

Given the code below

using (var context = new PrincipalContext(ContextType.Domain, SOME_DOMAIN))
using (UserPrincipal userPrincipal =  new UserPrincipal(context) { Enabled = true })
using (PrincipalSearchResult<Principal> results = new PrincipalSearcher(userPrincipal).FindAll())
{
    Console.WriteLine(results.Count());
}

using (var context = new PrincipalContext(ContextType.Domain, SOME_DOMAIN))
using (CustomUserPrinciple userPrincipal =  new CustomUserPrinciple(context) { Enabled = true })
using (PrincipalSearchResult<Principal> results = new PrincipalSearcher(userPrincipal).FindAll())
{
    Console.WriteLine(results.Count());
}

[DirectoryObjectClass("user")]
[DirectoryRdnPrefix("CN")]
public class CustomUserPrinciple : UserPrincipal
{
    public CustomUserPrinciple(PrincipalContext context)
        : base(context)
    {
    }
}

I expected the counts to be the same however it looks like the search using the custom principal doesn't return just users like the first search. The results include other active directory object types like computers.

Is this by design and if so, is there a way I can restrict the custom principal search to return just users ?

1

There are 1 answers

2
JPBlanc On BEST ANSWER

The results include other active directory object types like computers, just because if you look your objects with a tool like ADSIEDIT.MSC (W2K3 support tools) you'll see that the objectClass of a computer is also user. This is explained by the fact that in the Active-Directory's schema the computer class is the child of th user class. It exists an attribute objectCategory that allow to make the difference.

You can change your class this way :

[DirectoryObjectClass("user")]
[DirectoryRdnPrefix("CN")]
public class CustomUserPrinciple : UserPrincipal
{
    public CustomUserPrinciple(PrincipalContext context)
        : base(context)
    {
    }

    [DirectoryProperty("objectCategory")]
    public string objectCategory
    {
      get
      {
        object[] result = this.ExtensionGet("objectCategory");
        if (result != null)
        {
          return (string)result[0];
        }
        else
        {
          return string.Empty;
        }
      }
      set { this.ExtensionSet("objectCategory", value); }
    }
}

And manage you query like this :

using (UserPrincipal userPrincipal =  new UserPrincipal(context) { objectCategory="Person",Enabled = true })
using (PrincipalSearchResult<Principal> results = new PrincipalSearcher(userPrincipal).FindAll())
{
    Console.WriteLine(results.Count());
}