Re: Get list of the Groups a User belongs to
- From: "Willy Denoyette [MVP]" <willy.denoyette@xxxxxxxxxx>
- Date: Sat, 9 Dec 2006 17:58:45 +0100
"Mark Rae" <mark@xxxxxxxxxxxxxxxxx> wrote in message news:OHJnUd5GHHA.1276@xxxxxxxxxxxxxxxxxxxxxxx
"Dave Sexton" <dave@jwa[remove.this]online.com> wrote in message news:uTLecD5GHHA.420@xxxxxxxxxxxxxxxxxxxxxxx
You'll have to use P/Invoke for this, of course :)
System.DirectoryServices will do all of this, and much more, for you without recourse to p/invoke...
using System;
using System.Collections.Generic;
using System.DirectoryServices;
public static List<string> GetGroupsForUser(string pstrUser)
{
/// <summary>
/// Gets the groups a user is a member of
/// </summary>
/// <param name="pstrGroup">ActiveDirectory group to evaluate</param>
/// <returns>List<string> of groups for pstrUser</returns>
DirectorySearcher objDS = null;
SearchResult objSR = null;
DirectoryEntry objUser = null;
List<string> lstGroups = new List<string>();
try
{
objDS = new DirectorySearcher("objectCategory=User");
objDS.Filter = "(SAMAccountName=" + pstrUser + ")";
objSR = objDS.FindOne();
objUser = new DirectoryEntry(objSR.Path);
PropertyCollection colProperties = objUser.Properties;
PropertyValueCollection colPropertyValues = colProperties["memberOf"];
foreach (string strGroup in colPropertyValues)
{
lstGroups.Add(GetSAMAccountName(strGroup).ToLower());
}
return lstGroups;
}
catch (Exception)
{
throw;
}
finally
{
if (objUser != null)
{
objUser.Close();
objUser.Dispose();
objUser = null;
}
if (objSR != null)
{
objSR = null;
}
if (objDS != null)
{
objDS.Dispose();
objDS = null;
}
}
}
public static string GetSAMAccountName(string pstrPath)
{
/// <summary>
/// Gets a SAM Account Name from a given LDAP path
/// </summary>
/// <param name="pstrPath">LDAP path to bind to</param>
DirectoryEntry objADEntry = null;
try
{
objADEntry = new DirectoryEntry("LDAP://" + pstrPath);
return objADEntry.Properties["SAMAccountName"].Value.ToString();
}
catch (System.Runtime.InteropServices.COMException)
{
return String.Empty;
}
catch (System.NullReferenceException)
{
return String.Empty;
}
catch (Exception)
{
throw;
}
finally
{
if (objADEntry != null)
{
objADEntry.Close();
objADEntry.Dispose();
objADEntry = null;
}
}
}
Just a few remarks:
You may simplify your code and make it easier to read and maintain by applying the *using* idiom, this way, you get rid of the Dispose, Close and completely redundant "obj = null" calls.
Your code will only work when the caller is running in his domain account, when this is not the case, you need to bind explicitly against the Domain or the DC, and preferably using FastBind for performance reasons. You may also bind to the GC (the Global Catalog) using GC://... in order to speed-up the queries.
Another point to consider is that the binding user must have "query" privileges to all of the objects you query, normally all domain member do have this privilege, but highly secured AD's may restrict access to some objects to special accounts only. So it's possible that a user can bind to his user object, but not to (some) of the related objects.
You should also try to reuse the already established DirectoryEntry object for further operations against the AD, the way you do forces adsi to rebind and this can be a costly operation especially on slow connections and uses a lot more resources at the LDAP server.
The following code snip shows how to take advantage of a single bind by using the GetDirectorEntry() for each successive object retrieval.
public static List<string> GetGroupsForUser(string userAccount)
{
string rootPath = "LDAP://{0}/DC=xxx,DC=yyy,DC=zzz";
string accountDomain = "domain"; // domain name or dc name or empty when binding to logon domain
string userAccount = userAccount
rootPath = String.Format(
rootPath
, accountDomain);
string authUser = "xxx\yyyyy"; // account used to bind, here hardcoded, not production safe!
string authPassword = "PASSWORD"; // his password, here hardcoded, not production safe!
List<string> lstGroups = new List<string>();
using (DirectoryEntry root = new DirectoryEntry(rootPath, authUser, authPassword, AuthenticationTypes.FastBind))
{
using (DirectorySearcher ds = new DirectorySearcher(root))
{
SearchResult sr = null;
ds.Filter = "(SAMAccountName=" + userAccount + ")";
sr = ds.FindOne();
using (DirectoryEntry user = sr.GetDirectoryEntry())
{
PropertyCollection pcoll = user.Properties;
PropertyValueCollection memberOf = pcoll["memberOf"];
foreach (string cnGroup in memberOf)
{
ds.Filter = cnGroup.Substring(0, cnGroup.IndexOf(','));
sr = ds.FindOne();
using (DirectoryEntry group = sr.GetDirectoryEntry())
{
lstGroups.Add(group.Properties["SAMAccountName"].Value.ToString());
}
}
}
}
}
return lstGroups;
}
....
Willy.
.
- Follow-Ups:
- Re: Get list of the Groups a User belongs to
- From: Mark Rae
- Re: Get list of the Groups a User belongs to
- References:
- Get list of the Groups a User belongs to
- From: Jeff Williams
- Re: Get list of the Groups a User belongs to
- From: Dave Sexton
- Re: Get list of the Groups a User belongs to
- From: Mark Rae
- Get list of the Groups a User belongs to
- Prev by Date: Design issues
- Next by Date: Re: Design issues
- Previous by thread: Re: Get list of the Groups a User belongs to
- Next by thread: Re: Get list of the Groups a User belongs to
- Index(es):
Relevant Pages
|