私が理解している限り、それを行う1つの方法は次のとおりです。
- RootDSE から、構成 NamingContext を探します。
crossRef
構成 NamingContextで、属性が存在するクラスのオブジェクトを探しますnETBIOSName
。
dnsRoot
これらのエントリから、および属性を使用して記述しているアルゴリズムを使用しnCName
ます。フォレスト DNS が機能していると、 のドメイン コントローラに参加できますdnsRoot
。nCName
ルートから検索できます。
これは、エンタープライズ管理者グループのメンバーとして慎重に行ってください。
コードの例を次に示します。
/* Retreiving RootDSE
*/
string ldapBase = "LDAP://WM2008R2ENT:389/";
string sFromWhere = ldapBase + "rootDSE";
DirectoryEntry root = new DirectoryEntry(sFromWhere, "dom\\jpb", "PWD");
string configurationNamingContext = root.Properties["configurationNamingContext"][0].ToString();
/* Retreiving the root of all the domains
*/
sFromWhere = ldapBase + configurationNamingContext;
DirectoryEntry deBase = new DirectoryEntry(sFromWhere, "dom\\jpb", "PWD");
DirectorySearcher dsLookForDomain = new DirectorySearcher(deBase);
dsLookForDomain.Filter = "(&(objectClass=crossRef)(nETBIOSName=*))";
dsLookForDomain.SearchScope = SearchScope.Subtree;
dsLookForDomain.PropertiesToLoad.Add("nCName");
dsLookForDomain.PropertiesToLoad.Add("dnsRoot");
SearchResultCollection srcDomains = dsLookForDomain.FindAll();
foreach (SearchResult aSRDomain in srcDomains)
{
/* For each root look for the groups containing my user
*/
string nCName = aSRDomain.Properties["nCName"][0].ToString();
string dnsRoot = aSRDomain.Properties["dnsRoot"][0].ToString();
/* To find all the groups that "user1" is a member of :
* Set the base to the groups container DN; for example root DN (dc=dom,dc=fr)
* Set the scope to subtree
* Use the following filter :
* (member:1.2.840.113556.1.4.1941:=cn=user1,cn=users,DC=x)
*/
/* Connection to Active Directory
*/
sFromWhere = "LDAP://" + dnsRoot + "/" + nCName;
deBase = new DirectoryEntry(sFromWhere, "dom\\jpb", "PWD");
DirectorySearcher dsLookFor = new DirectorySearcher(deBase);
// you cancomplete the filter here (&(member:1.2.840.113556.1.4.1941:=CN=user1 Users,OU=MonOu,DC=dom,DC=fr)(cn=*2)
dsLookFor.Filter = "(member:1.2.840.113556.1.4.1941:=CN=user1 Users,OU=MonOu,DC=dom,DC=fr)";
dsLookFor.SearchScope = SearchScope.Subtree;
dsLookFor.PropertiesToLoad.Add("cn");
SearchResultCollection srcGroups = dsLookFor.FindAll();
foreach (SearchResult srcGroup in srcGroups)
{
Console.WriteLine("{0}", srcGroup.Path);
}
}
これは単なる概念実証であり、以下を完了する必要があります。
using(){}
DirectoryEntry オブジェクトを破棄するためのフォームの使用
例外管理
編集済み (2011-10-18 13:25)
問題を解決する方法についてのコメントは、System.DirectoryServices.AccountManagement Namespaceで指定されたメソッドにあります。これは一種の再帰的ソリューションです。今回は、group2 (第 3 ドメイン) に属する group1 (別のドメイン) に属するユーザーでテストしたところ、動作するようです。
/* Retreiving a principal context
*/
Console.WriteLine("Retreiving a principal context");
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, "WM2008R2ENT:389", "dc=dom,dc=fr", "jpb", "PWD");
/* Look for all the groups a user belongs to
*/
UserPrincipal aUser = UserPrincipal.FindByIdentity(domainContext, "user1");
PrincipalSearchResult<Principal> a = aUser.GetAuthorizationGroups();
foreach (GroupPrincipal gTmp in a)
{
Console.WriteLine(gTmp.Name);
}