/* * Active Directory has a global catalog (GC), which contains a partial replica of all objects * in the directory. It also contains partial replicas of the schema and configuration containers. * One or more domain controllers in a domain can hold a copy of the global catalog. * * The global catalog holds a replica of every object in Active Directory, but with only a small * number of their attributes. The attributes in the global catalog are those most frequently used * in search operations, such as a user's first and last names, login names, and so on. The global * catalog attributes also include those required to locate a full replica of the object. The * global catalog allows users to quickly find objects of interest without knowing what domain * holds them and without requiring a contiguous extended namespace in the enterprise; that is, * you can search the entire forest. * * The following sample code demonstrates a way to check if a caller is in a perticular security * group. It searches the global catalog to obtain the group's SID(Security Id), and then call * CheckTokenMembership to find out if the caller is in that group. It is very useful when a service * process need to check a caller's membership for authentication or authorization. * * In real applications, you may need to cache the SIDs of the groups for better performance since * searching the global catalog is fast, but not that fast. * * * -- DavidM, Dalun Software, Nov.28, 2004 All rights reserved. * * * * */
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.DirectoryServices;
using System.Security.Principal;
using System.Runtime.InteropServices;
namespace IsInGroup
{
///
/// Summary description for Class1.
///
class Class1
{
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
static extern int CheckTokenMembership(int TokenHandle, byte[] PSID, out bool IsMember);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
static extern bool IsValidSid(byte[] PSID);
public static string GetCallerName()
{
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
return principal.Identity.Name.Split('\\')[1];
}
///
/// The main entry point for the application.
///
static void Main(string[] args)
{
string groupName = "administrators";
//get current caller's information
string user = GetCallerName();
//search global catalog and get SID of the group
Byte[] sid = null;
DirectoryEntry entry = new DirectoryEntry("GC:");
IEnumerator ie = entry.Children.GetEnumerator();
ie.MoveNext();
DirectorySearcher ds = new DirectorySearcher((DirectoryEntry)ie.Current);
string sam = "(sAMAccountName=" + groupName + ")";
ds.Filter = "(&(|" + sam + ")(objectClass=group))";
using (SearchResultCollection resColl = ds.FindAll())
{
if (resColl.Count > 0)
{
ResultPropertyCollection resultPropColl = resColl[0].Properties;
string name = (string)resultPropColl["name"][0];
string adsPath = (string)resultPropColl["adspath"][0];
sid = (byte[])resultPropColl["objectsid"][0];
if (sid == null || !IsValidSid(sid))
{
System.Console.WriteLine("Invalid SID for the group.");
return;
}
else
{
System.Console.WriteLine("Group found: " + name);
System.Console.WriteLine("Group ADS path: " + adsPath);
}
}
else
{
System.Console.WriteLine("Required info was not found in the Global Catalog.");
return;
}
}
bool bIsMember = false;
if (CheckTokenMembership(0, sid, out bIsMember) == 0)
{
System.Console.WriteLine("Failed to call CheckTokenMembership.");
}
else
{
System.Console.WriteLine(user + (bIsMember ? " is a member of " : " isn't a member of ") + groupName);
}
}
}
}
THIS POST IS PROVIDED "AS-IS" WITH NO WARRANTIES AND CONFERS NO RIGHTS. Build time: Sun 03/30/2008 . ©2007 Dalun Software. All rights reserved. Back to Article List