ドメインユーザを表す DomainUser クラスのデータバインド用のメソッドから呼び出してる DirectoryAccess クラスのメソッドのC#のコードです。
※引数チェックは省略します。
//指定した名前と種類の Directory オブジェクトを検索します。
public static DirectoryObject FindDirectoryObject(string name, CategoryType objectCategory)
{
using (var root = GetRootEntry()) //ルートのDirectoryEntryを取得 参考:ユーザやグループの検索
{
if (CanConnectDomain) //ドメインに接続できる時
{
string filter;
switch (objectCategory)
{
case CategoryType.User:
filter = String.Format("(&(objectCategory={0})(sAMAccountName={1}))", objectCategory, name);
break;
case CategoryType.PrintQueue:
filter = String.Format("(&(objectCategory={0})(printerName={1}))", objectCategory, name);
break;
default:
filter = String.Format("(&(objectCategory={0})(name={1}))", objectCategory, name);
break;
}
using (var searcher = new DirectorySearcher(root, filter))
{
var result = searcher.FindOne();
return (result == null) ? null : CreateInstance(result.GetDirectoryEntry());
}
}
else //ドメインに接続できない時 <-- こっちはローカル
{
return CreateInstance(root.Children.Find(name, objectCategory.ToString()));
}
}
}
//ユーザの所属するグループを取得します。
public static ReadOnlyCollection<string> GetBelongGroups(IUser user)
{
var groups = new List<string>();
foreach (IADs group in user.Native.Groups()) //所属するグループ数分(プライマリ グループ以外)
{
groups.Add(group.Get("cn").ToString()); //C# だと IADs.Get メソッドの戻り値の型が object じゃなく dynamic になる
}
if (user is DomainUser) //ドメインユーザの時
{
var primaryGroupId = ((DomainUser)user).PrimaryGroupId;
groups.Add(GroupTokens[primaryGroupId]);
//GroupTokens プロパティ:IDictionary は下のLoadGroupTokens メソッド内で要素がセットされます。
}
groups.Sort();
return groups.AsReadOnly();
}
//ユーザを取得します。
public static IList GetUsers() where T : DirectoryObject, IUser
{
var users = new List();
using (var root = GetRootEntry()) //ルートのDirectoryEntryを取得
{
if (CanConnectDomain) //ドメインに接続できる時
{
var filter = String.Format("(objectCategory={0})", CategoryType.User);
using (var searcher = new DirectorySearcher(root, filter))
{
using (var results = searcher.FindAll())
{
foreach (SearchResult res in results)
{
users.Add((T)CreateInstance(res.GetDirectoryEntry()));
}
}
if (GroupTokens.Count == 0) //ドメイングループのPrimaryGroupTokenと名前の組のリストがない時
{
LoadGroupTokens(searcher); //ドメイングループのPrimaryGroupTokenと名前の組のリストをロード
}
}
}
else //ドメインに接続できない時 <-- こっちはローカル
{
root.Children.SchemaFilter.Add(CategoryType.User.ToString());
foreach (DirectoryEntry entry in root.Children)
{
users.Add((T)CreateInstance(entry));
}
}
}
return users;
}
//DirectoryObject のインスタンスを作成します。
private static DirectoryObject CreateInstance(DirectoryEntry entry)
{
CategoryType category;
if (Enum.TryParse<CategoryType>(entry.SchemaClassName, true, out category) == false)
{
throw new ArgumentException("entry の種類が CategoryType に該当しません。", "entry");
}
switch (category)
{
case CategoryType.User:
if (CanConnectDomain) //ドメインに接続できる時
{
return new DomainUser(entry);
}
else //ドメインに接続できない時
{
return new LocalUser(entry);
}
default:
throw new NotImplementedException();
}
}
//ドメイングループの PrimaryGroupToken と名前の組のリストをロードします。
private static void LoadGroupTokens(DirectorySearcher searcher)
{
searcher.Filter = String.Format("(objectCategory={0})", CategoryType.Group);
using (var results = searcher.FindAll())
{
foreach (SearchResult res in results)
{
var entry = res.GetDirectoryEntry();
entry.Invoke("GetInfoEx", new object[] { "primaryGroupToken" }, 0);
var token = Convert.ToInt32(entry.Properties["primaryGroupToken"].Value);
GroupTokens.Add(token, entry.Properties["cn"].Value.ToString());
}
}
}
所属するグループの取得については「ユーザの所属するグループの取得」を参照してください。
インスタンスの作成で、ドメインに接続できない時(対象がローカルの時)は LocalUser を作成してますが、このクラスについては次回書きます。