管理者タブの「管理者がメンバシップ一覧を変更できる」とオブジェクトタブの「誤って削除されないようにオブジェクトを保護する」のチェックボックスのON/OFFの取得については、対応する属性もプロパティもないのでプログラムから取得(導出)します。
先に Development グループの出力サンプル。
AccessControlType、ActiveDirectoryRights、IdentityReference、ObjectFlags、ObjectType の 5つのプロパティを出力しました。
赤枠がチェックを入れた場合に増えたものです。
左:チェックなし、中:管理者がメンバシップ一覧を変更できる、右:誤って削除されないようにオブジェクトを保護する
※どれもクリックすると新しいウィンドウで拡大図が表示されます。
この増えた項目の有無でチェックのON/OFFを判別します。
2つのチェックボックスの項目は DirectoryEntry.ObjectSecurity プロパティ(エントリのセキュリティ記述子:ActiveDirectorySecurity クラス)に対象のアクセス規則があるかどうかで判断します。
「管理者がメンバシップ一覧を変更できる」チェックボックスについては、管理者が指定されていなければ(「managedBy」属性がなければ)チェックはOFFです。
アクセス規則は DirectoryEntry.ObjectSecurity.GetAccessRules メソッドで取得します。戻り値は AuthorizationRuleCollection クラス(System.Security.AccessControl 名前空間)のインスタンスになります。
各要素は AuthorizationRule 抽象基本クラスになるので、継承クラスである ActiveDirectoryAccessRule クラスのインスタンスのみ処理します。
コードはこんな感じ。(System.Security.AccessControl と System.Security.Principal 名前空間をインポート、引数の null チェックは省略)
VB
Public Shared Function CanChangeMembershipList(entry As DirectoryEntry) As Boolean
Dim admin = entry.Properties.Item("managedBy").Value
If admin Is Nothing Then '管理者が指定されていない時
Return False
End If
Dim filter = String.Format("(distinguishedName={0})", admin) '管理者の SID が欲しいので管理者を検索する
Dim binaryForm As Byte()
Dim adminSid As SecurityIdentifier
Using root As New DirectoryEntry(LdapRootPath) 'ユーザやグループの検索を参照
Using searcher As New DirectorySearcher(root, filter)
Dim result = searcher.FindOne()
binaryForm = DirectCast(result.GetDirectoryEntry().Properties.Item("objectSid").Value, Byte())
adminSid = New SecurityIdentifier(binaryForm, 0)
End Using
End Using
binaryForm = DirectCast(entry.Properties.Item("objectSid").Value, Byte())
Dim entrySid = New SecurityIdentifier(binaryForm, 0)
Dim rules = entry.ObjectSecurity.GetAccessRules(True, False, entrySid.GetType())
Dim rule = rules.OfType(Of ActiveDirectoryAccessRule)().FirstOrDefault(
Function(ar) (ar.ActiveDirectoryRights = ActiveDirectoryRights.WriteProperty) AndAlso ar.IdentityReference.Equals(adminSid))
Return rule IsNot Nothing
End Function
Public Shared Function IsObjectProtected(entry As DirectoryEntry) As Boolean
Dim binaryForm = DirectCast(entry.Properties.Item("objectSid").Value, Byte())
Dim entrySid = New SecurityIdentifier(binaryForm, 0)
Dim rules = entry.ObjectSecurity.GetAccessRules(True, False, entrySid.GetType())
Dim rule = rules.OfType(Of ActiveDirectoryAccessRule)().FirstOrDefault(
Function(ar) (ar.AccessControlType = AccessControlType.Deny) AndAlso
(ar.ActiveDirectoryRights = (ActiveDirectoryRights.DeleteTree Or ActiveDirectoryRights.Delete)))
Return rule IsNot Nothing
End Function
C#
public static bool CanChangeMembershipList(DirectoryEntry entry)
{
var admin = entry.Properties["managedBy"].Value;
if (admin == null) //管理者が指定されていない時
{
return false;
}
var filter = String.Format("(distinguishedName={0})", admin); //管理者の SID が欲しいので管理者を検索する
byte[] binaryForm;
SecurityIdentifier adminSid;
using (var root = new DirectoryEntry(LdapRootPath)) //ユーザやグループの検索を参照
{
using (var searcher = new DirectorySearcher(root, filter))
{
var result = searcher.FindOne();
binaryForm = (byte[])result.GetDirectoryEntry().Properties["objectSid"].Value;
adminSid = new SecurityIdentifier(binaryForm, 0);
}
}
binaryForm = (byte[])entry.Properties["objectSid"].Value;
var entrySid = new SecurityIdentifier(binaryForm, 0);
var rules = entry.ObjectSecurity.GetAccessRules(true, false, entrySid.GetType());
var rule = rules.OfType<ActiveDirectoryAccessRule>().FirstOrDefault(
ar => (ar.ActiveDirectoryRights == ActiveDirectoryRights.WriteProperty) && ar.IdentityReference.Equals(adminSid));
return rule != null;
}
public static bool IsObjectProtected(DirectoryEntry entry)
{
var binaryForm = (byte[])entry.Properties["objectSid"].Value;
var entrySid = new SecurityIdentifier(binaryForm, 0);
var rules = entry.ObjectSecurity.GetAccessRules(true, false, entrySid.GetType());
var rule = rules.OfType<ActiveDirectoryAccessRule>().FirstOrDefault(
ar => (ar.AccessControlType == AccessControlType.Deny) &&
(ar.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)));
return rule != null;
}
出力結果の増えた項目を基に、「管理者がメンバシップ一覧を変更できる」チェックボックスの方は ActiveDirectoryRights プロパティが WriteProperty で IdentityReference プロパティが管理者の SID であるアクセス規則があるかどうか、「誤って削除されないようにオブジェクトを保護する」チェックボックスの方は AccessControlType プロパティが Deny で ActiveDirectoryRights プロパティが DeleteTree と Delete であるアクセス規則があるかどうかで判別してます。