Active Directoryデータの Security Descriptor
nTSecurityDescriptor 属性の値を見やすく出力する

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

初期版
http://www.slideshare.net/mitchin227/output-p...
Security Descriptor って?
Security Descriptor とはセキュリティ記述子のことで、ざっく
り言えばセキュリティ(アクセス権)設定を記述したものです。
ここでは Active Directory オブジェクト...
Windows Server 2008 で確認
管理ツール「Active Directory ユーザとコンピュータ」で、
「表示」メニューの「拡張機能」にチェックがついている状態で、
ユーザやグループなどのプロパティを表示します。

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

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

6
nTSecurityDescriptor 属性の値の型は?
nTSecurityDescriptor 属性の値の型は ADSI の
IADsSecurityDescriptor です。
値をこのインターフェイスにキャストできます。
また、関連す...
プログラムから確認するには
DirectoryEntry.Properties プロパティ(PropertyCollection
クラス)からプロパティとその値(PropertyValueCollection ク
ラス)を列挙して取得します。
...
初期版の出力
COM(ADSI) 未対応のため「System.__ComObject」と出力されてい
ます。

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

10
出力の書式
今回はセキュリティ記述子の随意アクセス制御リストの各アクセ
ス制御エントリを 番号をつけて見やすい形で出力します。
出力する項目は次の 5 つのプロパティです。
• Trustee(ユーザやグループの名前部分のみ)
• Access...
通常のプロパティ出力の抜粋(VB)
Public Shared Sub OutputProperties(
entry As DirectoryEntry, filePath As String)
Dim props = entry.Prope...
IADsSecurityDescriptor の出力(VB)
Dim sd = DirectCast(val, IADsSecurityDescriptor)
Dim aceGroups = DirectCast(sd.Discretionar...
IADsSecurityDescriptor の出力(VB)
For Each aceGroup In aceGroups 'ACE数分
Dim ace = aceGroup.First()
ctr += 1
writer.WriteLine(...
列挙体のプロパティ値をテキスト化(VB)
Private Shared Function ToEnumValueText(
value As Integer , enumType As Type) As String
If enumType I...
通常のプロパティ出力の抜粋(C#)
public static void OutputProperties(
DirectoryEntry entry, string filePath) {
var props = entry.Properti...
IADsSecurityDescriptor の出力(C#)
var sd = (IADsSecurityDescriptor)val;
var aceGroups = ((IADsAccessControlList)sd.Discretion...
IADsSecurityDescriptor の出力(C#)
foreach (var aceGroup in aceGroups) { //ACE数分
var ace = aceGroup.First();
ctr++;
writer.Wri...
列挙体のプロパティ値をテキスト化(C#)
private static string ToEnumValueText(int value, Type enumType) {
if (enumType == typeof(ADS_ACETYPE_...
詳細や関連情報はブログ等で
Active Directoryデータのプロパティ出力
http://blogs.wankuma.com/mitchin/archive/2013/09/19/328123.aspx
http://blogs.wan...
Upcoming SlideShare
Loading in …5
×

Active Directoryデータの Security Descriptor

599 views

Published on

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

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
599
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
2
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Active Directoryデータの Security Descriptor

  1. 1. Active Directoryデータの Security Descriptor nTSecurityDescriptor 属性の値を見やすく出力する 小山 三智男 mitchin
  2. 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 2
  3. 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 の集まりです。 3
  4. 4. Windows Server 2008 で確認 管理ツール「Active Directory ユーザとコンピュータ」で、 「表示」メニューの「拡張機能」にチェックがついている状態で、 ユーザやグループなどのプロパティを表示します。 4
  5. 5. セキュリティ タブで確認 セキュリティ タブを開き ます。 ファイルやフォルダのア クセス権を設定する時も そのプロパティ画面のセ キュリティ タブで行いま すがこちらも同じです。 画面もほぼ同じですね。 5
  6. 6. 属性は nTSecurityDescriptor 属性エディタには表示されません。 6
  7. 7. nTSecurityDescriptor 属性の値の型は? nTSecurityDescriptor 属性の値の型は ADSI の IADsSecurityDescriptor です。 値をこのインターフェイスにキャストできます。 また、関連するアクセス制御リストのインターフェイスは IADsAccessControlList で、アクセス制御エントリのインター フェイスは IADsAccessControlEntry です。 他にもアクセス制御エントリに関連する次の列挙体があります。 • ADS_RIGHTS_ENUM • ADS_ACEFLAG_ENUM • ADS_ACETYPE_ENUM • ADS_FLAGTYPE_ENUM 7
  8. 8. プログラムから確認するには DirectoryEntry.Properties プロパティ(PropertyCollection クラス)からプロパティとその値(PropertyValueCollection ク ラス)を列挙して取得します。 nTSecurityDescriptor 属性はオプションのプロパティ出力 (OutputOptionalProperties)では取得できないので、通常のプ ロパティ出力(OutputProperties)の方だけ考慮します。 ※nTSecurityDescriptor は必須プロパティです。 サンプルコードは次の名前空間をインポートしています。 • ActiveDs(Active DS Type Library の参照設定が必要) • System.IO • System.Security.Principal • System.Text 8
  9. 9. 初期版の出力 COM(ADSI) 未対応のため「System.__ComObject」と出力されてい ます。 9
  10. 10. 今回の出力 COM(ADSI) に対応した出力のサンプルです。 10
  11. 11. 出力の書式 今回はセキュリティ記述子の随意アクセス制御リストの各アクセ ス制御エントリを 番号をつけて見やすい形で出力します。 出力する項目は次の 5 つのプロパティです。 • Trustee(ユーザやグループの名前部分のみ) • AccessMask • AceFlags • AceType • Flags これらの値順に重複は除外して出力します。 また、Trustee 以外は整数型ですが、値は7ページに記載した列 挙体の値なので、値とそれを表す列挙値の文字列も出力します。 ※この文字列の取得はメソッド化します。 11
  12. 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 Using End Sub 12
  13. 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) 13
  14. 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 14
  15. 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 15
  16. 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 { //それ以外の時 //各値を取得して出力 } } } } 16
  17. 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); 17
  18. 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))); } 18
  19. 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)); } 19
  20. 20. 詳細や関連情報はブログ等で Active Directoryデータのプロパティ出力 http://blogs.wankuma.com/mitchin/archive/2013/09/19/328123.aspx http://blogs.wankuma.com/mitchin/archive/2013/09/20/328126.aspx Active Directoryデータのプロパティ出力のCOM対応版 http://blogs.wankuma.com/mitchin/archive/2013/12/04/328271.aspx http://blogs.wankuma.com/mitchin/archive/2013/12/05/328273.aspx わんくま初LT http://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 20

×