Reputation: 15847
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
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
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
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