20
Active Directory デデデデ Security Descriptor nTSecurityDescriptor デデデデデデデデデデデデデ デデ デデデ mitchin

Active Directoryデータの Security Descriptor

Embed Size (px)

DESCRIPTION

nTSecurityDescriptor 属性の値を見やすく出力します。 The value of an nTSecurityDescriptor attribute is outputted legible.

Citation preview

Page 1: Active Directoryデータの Security Descriptor

Active Directory データの Security Descriptor

nTSecurityDescriptor 属性の値を見やすく出力する

小山 三智男mitchin

Page 2: Active Directoryデータの Security Descriptor

2

Active Directory データのプロパティ出力

以前、 Active Directory データのプロパティ出力について紹介しました。

初期版http://www.slideshare.net/mitchin227/output-properties

" 大きい整数 " 対応版http://www.slideshare.net/mitchin227/large-integer

これをサンプルアプリに組み込めば出力できるようになります。

サンプルアプリとスライドはこちらhttp://blogs.wankuma.com/mitchin/archive/2013/12/08/328279.aspx

Page 3: Active Directoryデータの Security Descriptor

3

Security Descriptor って?

Security Descriptor とはセキュリティ記述子のことで、ざっくり言えばセキュリティ(アクセス権)設定を記述したものです。ここでは Active Directory オブジェクトに関連付けられたセキュリティ情報を保持するものです。この中に随意アクセス制御リスト( DACL : Discretionary Access Control List )やシステム アクセス制御リスト( SACL : System Access Control List )、所有者、プライマリ グループがあります。DACL はユーザやグループに対して 許可 / 拒否の権限を定義したアクセス規則であるアクセス制御エントリ( ACE : Access Control Entry )の集まりで、単にアクセス制御リスト( ACL )と呼ぶことがあります。SACL は監査規則である ACE の集まりです。

Page 4: Active Directoryデータの Security Descriptor

4

Windows Server 2008 で確認

管理ツール「 Active Directory ユーザとコンピュータ」で、「表示」メニューの「拡張機能」にチェックがついている状態で、ユーザやグループなどのプロパティを表示します。

Page 5: Active Directoryデータの Security Descriptor

5

セキュリティ タブで確認

セキュリティ タブを開きます。

ファイルやフォルダのアクセス権を設定する時もそのプロパティ画面のセキュリティ タブで行いますがこちらも同じです。画面もほぼ同じですね。

Page 6: Active Directoryデータの Security Descriptor

6

属性は nTSecurityDescriptor

属性エディタには表示されません。

Page 7: Active Directoryデータの Security Descriptor

7

nTSecurityDescriptor 属性の値の型は?

nTSecurityDescriptor 属性の値の型は ADSI の IADsSecurityDescriptor です。値をこのインターフェイスにキャストできます。

また、関連するアクセス制御リストのインターフェイスは IADsAccessControlList で、アクセス制御エントリのインターフェイスは IADsAccessControlEntry です。

他にもアクセス制御エントリに関連する次の列挙体があります。•ADS_RIGHTS_ENUM•ADS_ACEFLAG_ENUM•ADS_ACETYPE_ENUM•ADS_FLAGTYPE_ENUM

Page 8: Active Directoryデータの Security Descriptor

8

プログラムから確認するには

DirectoryEntry.Properties プロパティ( PropertyCollection クラス)からプロパティとその値( PropertyValueCollection クラス)を列挙して取得します。nTSecurityDescriptor 属性はオプションのプロパティ出力( OutputOptionalProperties )では取得できないので、通常のプロパティ出力( OutputProperties )の方だけ考慮します。※nTSecurityDescriptor は必須プロパティです。

サンプルコードは次の名前空間をインポートしています。•ActiveDs ( Active DS Type Library の参照設定が必要)•System.IO•System.Security.Principal•System.Text

Page 9: Active Directoryデータの Security Descriptor

9

初期版の出力

COM(ADSI) 未対応のため「 System.__ComObject 」と出力されています。

Page 10: Active Directoryデータの Security Descriptor

10

今回の出力

COM(ADSI) に対応した出力のサンプルです。

Page 11: Active Directoryデータの Security Descriptor

11

出力の書式

今回はセキュリティ記述子の随意アクセス制御リストの各アクセス制御エントリを 番号をつけて見やすい形で出力します。出力する項目は次の 5 つのプロパティです。

•Trustee (ユーザやグループの名前部分のみ)•AccessMask•AceFlags•AceType•Flags

これらの値順に重複は除外して出力します。また、 Trustee 以外は整数型ですが、値は 7 ページに記載した列挙体の値なので、値とそれを表す列挙値の文字列も出力します。※ この文字列の取得はメソッド化します。

Page 12: Active Directoryデータの Security Descriptor

12

通常のプロパティ出力の抜粋( VB )

Public Shared Sub OutputProperties( entry As DirectoryEntry, filePath As String) Dim props = entry.Properties.PropertyNames.Cast( Of String)().OrderBy(Function(s) s).ToList() ' プロパティ名のリスト Using writer As New StreamWriter(filePath, False, Encoding.UTF8) For Each pname In props ' プロパティ数分 Dim val = entry.Properties.Item(pname).Value If TypeOf val Is Byte() Then ' バイト配列の時 ' バイト値を取得して出力 ElseIf TypeOf val Is IADsSecurityDescriptor Then ' セキュリティ記述子の時 --> 次のページに記載 Else ' それ以外の時 ' 各値を取得して出力 End If Next End UsingEnd Sub

Page 13: Active Directoryデータの Security Descriptor

13

IADsSecurityDescriptor の出力( VB )Dim sd = DirectCast(val, IADsSecurityDescriptor)Dim aceGroups = DirectCast(sd.DiscretionaryAcl, IADsAccessControlList).Cast(Of IADsAccessControlEntry)().OrderBy( Function(ace) Path.GetFileName(ace.Trustee)).ThenBy( Function(ace) ace.AccessMask).ThenBy( Function(ace) ace.AceFlags).ThenBy( Function(ace) ace.AceType).ThenBy( Function(ace) ace.Flags).GroupBy( Function(ace) String.Format("{0}|{1}|{2}|{3}|{4}", ace.Trustee, ace.AccessMask, ace.AceFlags, ace.AceType, ace.Flags)).ToList() ' プロパティ値でグループ化した ACE Dim ctr = 0 writer.WriteLine(pname)

Page 14: Active Directoryデータの Security Descriptor

14

IADsSecurityDescriptor の出力( VB )For Each aceGroup In aceGroups 'ACE 数分 Dim ace = aceGroup.First() ctr += 1 writer.WriteLine(" {0:D2}. Trustee : {1}", ctr, Path.GetFileName(ace.Trustee)) writer.WriteLine(" {0:D2}. AccessMask : {1}", ctr, ToEnumValueText(ace.AccessMask, GetType(ADS_RIGHTS_ENUM))) writer.WriteLine(" {0:D2}. AceFlags : {1}", ctr, ToEnumValueText(ace.AceFlags, GetType(ADS_ACEFLAG_ENUM))) writer.WriteLine(" {0:D2}. AceType : {1}", ctr, ToEnumValueText(ace.AceType, GetType(ADS_ACETYPE_ENUM))) writer.WriteLine(" {0:D2}. Flags : {1}", ctr, ToEnumValueText(ace.Flags, GetType(ADS_FLAGTYPE_ENUM)))Next

Page 15: Active Directoryデータの Security Descriptor

15

列挙体のプロパティ値をテキスト化( VB )Private Shared Function ToEnumValueText( value As Integer , enumType As Type) As String If enumType Is GetType(ADS_ACETYPE_ENUM) Then 'AceType の時 Return String.Format("{0}({1})", value, [Enum].ToObject(enumType, value)) End If Dim selector = Function(e As Integer) [Enum].ToObject(enumType, e).ToString() Dim values = [Enum].GetValues(enumType).Cast( Of Integer)().Where(Function(e) (value And e) = e).OrderBy( selector).Select(selector).ToList() ' 設定されている値の列挙体文字列 If values.Count = 0 Then ' 設定されている値がない時 Return value.ToString() End If Return String.Format("{0}({1})", value, String.Join(" | ", values))End Function

Page 16: Active Directoryデータの Security Descriptor

16

通常のプロパティ出力の抜粋( C# )

public static void OutputProperties( DirectoryEntry entry, string filePath) { var props = entry.Properties.PropertyNames. Cast<string>().OrderBy(s => s).ToList(); // プロパティ名のリスト using (var writer = new StreamWriter(filePath, false, Encoding.UTF8)) { foreach (var pname in props) { // プロパティ数分 var val = entry.Properties[pname].Value; if (val is byte[]) { // バイト配列の時 // バイト値を取得して出力 } else if (val is IADsSecurityDescriptor) { // セキュリティ記述子の時 --> 次のページに記載 } else { // それ以外の時 // 各値を取得して出力 } } }}

Page 17: Active Directoryデータの Security Descriptor

17

IADsSecurityDescriptor の出力( C# )var sd = (IADsSecurityDescriptor)val;var aceGroups = ((IADsAccessControlList)sd.DiscretionaryAcl). Cast<IADsAccessControlEntry>().OrderBy( ace => System.IO.Path.GetFileName(ace.Trustee)).ThenBy( ace => ace.AccessMask).ThenBy( ace => ace.AceFlags).ThenBy( ace => ace.AceType).ThenBy( ace => ace.Flags).GroupBy( ace => String.Format("{0}|{1}|{2}|{3}|{4}", ace.Trustee, ace.AccessMask, ace.AceFlags, ace.AceType, ace.Flags)).ToList(); // プロパティ値でグループ化した ACE var ctr = 0; writer.WriteLine(pname);

Page 18: Active Directoryデータの Security Descriptor

18

IADsSecurityDescriptor の出力( C# )foreach (var aceGroup in aceGroups) { //ACE 数分 var ace = aceGroup.First(); ctr++; writer.WriteLine(" {0:D2}. Trustee : {1}", ctr, System.IO.Path.GetFileName(ace.Trustee)); writer.WriteLine(" {0:D2}. AccessMask : {1}", ctr, ToEnumValueText(ace.AccessMask, typeof(ADS_RIGHTS_ENUM))); writer.WriteLine(" {0:D2}. AceFlags : {1}", ctr, ToEnumValueText(ace.AceFlags, typeof(ADS_ACEFLAG_ENUM))); writer.WriteLine(" {0:D2}. AceType : {1}", ctr, ToEnumValueText(ace.AceType, typeof(ADS_ACETYPE_ENUM))); writer.WriteLine(" {0:D2}. Flags : {1}", ctr, ToEnumValueText(ace.Flags, typeof(ADS_FLAGTYPE_ENUM)));}

Page 19: Active Directoryデータの Security Descriptor

19

列挙体のプロパティ値をテキスト化( C# )private static string ToEnumValueText(int value, Type enumType) { if (enumType == typeof(ADS_ACETYPE_ENUM)) { //AceType の時 return String.Format("{0}({1})", value, Enum.ToObject(enumType, value)); }

Func<int, string> selector = e => Enum.ToObject(enumType, e).ToString(); var values = Enum.GetValues(enumType).Cast<int>().Where( e => (value & e) == e).OrderBy(selector).Select(selector).ToList(); // 設定されている値の列挙体文字列

if (values.Count == 0) { // 設定されている値がない時 return value.ToString(); } return String.Format("{0}({1})", value, String.Join(" | ", values));}

Page 20: Active Directoryデータの Security Descriptor

20

詳細や関連情報はブログ等で

Active Directory データのプロパティ出力http://blogs.wankuma.com/mitchin/archive/2013/09/19/328123.aspxhttp://blogs.wankuma.com/mitchin/archive/2013/09/20/328126.aspx

Active Directory データのプロパティ出力の COM 対応版http://blogs.wankuma.com/mitchin/archive/2013/12/04/328271.aspxhttp://blogs.wankuma.com/mitchin/archive/2013/12/05/328273.aspx

わんくま初 LThttp://blogs.wankuma.com/mitchin/archive/2013/12/08/328279.aspx※ スライド、サンプルコード、サンプルアプリのリンクがあります。

COM 対応版の変更点の説明(セキュリティ記述子: SecurityDescriptor )http://blogs.wankuma.com/mitchin/archive/2013/12/09/328281.aspx

COM 対応版の変更点の説明(大きい整数関連)http://blogs.wankuma.com/mitchin/archive/2013/12/06/328275.aspx

COM 対応版の変更点の説明(構造化例外処理を使わないで値がないかを確認)

http://blogs.wankuma.com/mitchin/archive/2013/12/10/328283.aspx