Banshee
Banshee

Reputation: 15847

How to know if DirectoryEntry is a user or a group?

Hi,

I have the following code to create a tree from the current AD :

public static ActiveDirectory GetActiveDirectoryTree(string pathToAD = "")
{
    DirectoryEntry objADAM = default(DirectoryEntry);
    // Binding object. 
    DirectoryEntry objGroupEntry = default(DirectoryEntry);
    // Group Results. 
    DirectorySearcher objSearchADAM = default(DirectorySearcher);
    // Search object. 
    SearchResultCollection objSearchResults = default(SearchResultCollection);
    // Binding path. 
    ActiveDirectory result = new ActiveDirectory();
    ActiveDirectoryItem treeNode;

    // Get the AD LDS object. 
    try
    {
        if (pathToAD.Length > 0)
            objADAM = new DirectoryEntry();
        else
            objADAM = new DirectoryEntry(pathToAD);
        objADAM.RefreshCache();
    }
    catch (Exception e)
    {
        throw e;
    }

    // Get search object, specify filter and scope, 
    // perform search. 
    try
    {
        objSearchADAM = new DirectorySearcher(objADAM);
        objSearchADAM.Filter = "(&(objectClass=group))";
        objSearchADAM.SearchScope = SearchScope.Subtree;
        objSearchResults = objSearchADAM.FindAll();
    }
    catch (Exception e)
    {
        throw e;
    }

    // Enumerate groups 
    try
    {
        if (objSearchResults.Count != 0)
        {
            //SearchResult objResult = default(SearchResult);
            foreach (SearchResult objResult in objSearchResults)
            {
                objGroupEntry = objResult.GetDirectoryEntry();
                result.ActiveDirectoryTree.Add(new ActiveDirectoryItem() { Id = objGroupEntry.Guid, ParentId = objGroupEntry.Parent.Guid, AccountName = objGroupEntry.Name, Type = ActiveDirectoryType.Group, PickableNode = false });

                foreach (object child in objGroupEntry.Properties["member"])
                {
                    treeNode = new ActiveDirectoryItem();
                    var path = "LDAP://" + child.ToString().Replace("/", "\\/");
                    using (var memberEntry = new DirectoryEntry(path))
                    {
                        if (memberEntry.Properties.Contains("sAMAccountName") && memberEntry.Properties.Contains("objectSid"))
                        {
                            treeNode.Id = Guid.NewGuid();
                            treeNode.ParentId = objGroupEntry.Guid;
                            treeNode.AccountName = memberEntry.Properties["sAMAccountName"][0].ToString();
                            treeNode.Type = ActiveDirectoryType.User;
                            treeNode.PickableNode = true;
                            treeNode.FullName = memberEntry.Properties["Name"][0].ToString();

                            byte[] sidBytes = (byte[])memberEntry.Properties["objectSid"][0];
                            treeNode.ObjectSid = new System.Security.Principal.SecurityIdentifier(sidBytes, 0).ToString();

                            result.ActiveDirectoryTree.Add(treeNode);
                        }
                    }
                }
            }
        }
        else
        {
            throw new Exception("No groups found");
        }
    }
    catch (Exception e)
    {
        throw new Exception(e.Message);
    }

    return result;
} 

The problem is that using (var memberEntry = new DirectoryEntry(path)) returns DomainUsers as a user to this tree and Im not sure if this is correct?

Say that I store the sidId for the DomainUsers node and then sends it to the following method :

public static Boolean GetActiveDirectoryName(string sidId,out string samAccountName,out string fullName)
        {
            samAccountName = string.Empty;
            fullName = string.Empty;


            if (sidId != null && sidId.Length > 0)
            {
                var ctx = new System.DirectoryServices.AccountManagement.PrincipalContext(ContextType.Domain, null);
                using (var up = UserPrincipal.FindByIdentity(ctx, IdentityType.Sid, sidId))
                {
                    samAccountName = up.SamAccountName;
                    fullName = up.Name;

                    return true;
                }
            }
            return false;
        }

The up will be set to null? If I choose another user in the AD then it workes just fine. I suspect that the DomainUsers is a group, but how do I check for this on then DirectoryEntry?

BestRegards

Upvotes: 7

Views: 8414

Answers (2)

Just Shadow
Just Shadow

Reputation: 11921

Warning:
The accepted answer is dangerous to use since the DirectoryEntry.SchemaEntry.Name might be anything. (See here for more details).

So, the easiest way would be to check the objectClass instead, like this:

// For group check
bool isGroup = entry.Properties["objectClass"]?.Contains("group") == true;
// For user check
bool isUser = entry.Properties["objectClass"]?.Contains("user") == true;

P.S. For those who are wondering why I've used == true, see here

Upvotes: 3

Maverik
Maverik

Reputation: 5681

Off the top of my head: Have you considered checking Schema properties of the returned result? I'm thinking you could easily figure a group by using DirectoryEntry.SchemaEntry.Name. It should return group if your schema entry is a group.

Reference: MSDN: DirectoryEntry.SchemaEntry


Just out of curiosity and a bit off topic in your code above:

 if (pathToAD.Length > 0)
      objADAM = new DirectoryEntry();
 else
      objADAM = new DirectoryEntry(pathToAD);
 objADAM.RefreshCache();

wouldn't you want to use pathToAD IF the Length>0?

Upvotes: 6

Related Questions