The native System.DirectoryService can’t recursively retrieve groups, so I created this enchanced one.
public class ActiveDirectoryService
{
private readonly string _gusetUserid;
private readonly string _guestPasswd;
private readonly DirectoryEntry _ldapEntry;
public enum FilterType
{
CN, // subGroup
SAMAccountName // user
}
public ActiveDirectoryService(string host, string baseDN, string guestUserId, string guestPasswd)
{
_gusetUserid = guestUserId;
_guestPasswd = guestPasswd;
_ldapEntry = new DirectoryEntry("LDAP://" + host + "/" + baseDN, _gusetUserid, _guestPasswd);
}
public IEnumerable<string> GetADUserGroups(string username)
{
return GetADUserGroups(username, true);
}
public IEnumerable<string> GetADUserGroups(string username, bool recursive)
{
return GetParentGroups(username, new List<string>(), FilterType.SAMAccountName, recursive);
}
private IList<string> GetParentGroups(string childName,
IList<string> originalGroups,
FilterType filterType,
bool recursive)
{
var search = new DirectorySearcher(_ldapEntry)
{
Filter = string.Format("({0}={1})", filterType, childName)
};
search.PropertiesToLoad.Add("memberOf");
SearchResult result = search.FindOne();
if (result != null)
{
int propertyCount = result.Properties["memberOf"].Count;
string dn;
for (int i = 0; i < propertyCount; i++)
{
dn = result.Properties["memberOf"][i].ToString();
int equalsIndex = dn.IndexOf("=", 1);
int commaIndex = dn.IndexOf(",", 1);
if (equalsIndex != -1)
{
string groupName = dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1);
if (!originalGroups.Contains(groupName))
{
originalGroups.Add(groupName);
if (recursive) originalGroups = GetParentGroups(groupName, originalGroups, FilterType.CN, true);
}
}
}
}
return originalGroups;
}
}
namespace ActiveDirectoryServiceSpecs
{
[TestFixture]
public class ActiveDirectoryServiceSpecs
{
const string LDAP_HOST = "Dcxx";
const string LDAP_BASE_DN = "DC=xxxx,DC=xxx,DC=xx";
const string LDAP_GUEST_USERID = "guest";
const string LDAP_GUEST_PASSWD = "hello";
private ActiveDirectoryService _SUT;
[SetUp]
public void Setup()
{
_SUT = new ActiveDirectoryService(LDAP_HOST, LDAP_BASE_DN, LDAP_GUEST_USERID, LDAP_GUEST_PASSWD);
}
[Test]
public void should_get_immediate_user_ad_groups()
{
IEnumerable<string> adUserGroups = _SUT.GetADUserGroups("fmao", false);
Assert.That(adUserGroups.Count() > 0);
Assert.IsFalse(adUserGroups.Contains("Information Systems"));
foreach (var s in adUserGroups)
{
Console.WriteLine(s);
}
}
[Test]
public void should_get_recursive_user_ad_groups()
{
IEnumerable<string> adUserGroups = _SUT.GetADUserGroups("fmao", true);
Assert.That(adUserGroups.Count() > 20);
Assert.That(adUserGroups.Contains("Information Systems"));
foreach (var s in adUserGroups)
{
Console.WriteLine(s);
}
}
}
}