ホームC#でファイルアクセス権限の付与 > ファイルのアクセス権を列挙する
ファイルのアクセス権を列挙する
前置きが長かったが、ようやくプログラムに入る。
今回使用する名前空間は以下の通りである。
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
ファイルのアクセス権を列挙するには、GetAccessRulesメソッドを使う。FreeCell.exeのアクセス権を列挙するサンプルを以下に示す。
string filePath = @"C:\Program Files\Microsoft Games\FreeCell\FreeCell.exe";

//見出し
string ace = "AccessControlType"
   + "\tAccountName"
   + "\tFileSystemRights"
   + "\tIsInherited";
System.Diagnostics.Debug.WriteLine(ace);

//アクセス権の列挙
FileSecurity security = File.GetAccessControl(filePath);
foreach (FileSystemAccessRule rule in
   security.GetAccessRules(true, true, typeof(NTAccount)))
{
   ace = rule.AccessControlType
       + "\t" + (rule.IdentityReference as NTAccount).Value
       + "\t" + rule.FileSystemRights.ToString()
       + "\t" + rule.IsInherited.ToString();
   System.Diagnostics.Debug.WriteLine(ace);
}
FileSecurityクラスはファイルのセキュリティを司るクラスである。FileクラスのGetAccessControlメソッドで取得する。
FileSystemAccessRuleはアクセス権の情報を持つクラスである。FileSecurityクラスのGetAccessRulesメソッドでFileSystemAccessRuleクラスのコレクションを取得することができるので、ここではforeachで一つずつ取り出して解析している。
FileSystemAccessRuleクラスのAccessControlTypeプロパティは、権限が許可か拒否かを取得する。普通に使っていれば拒否権限が設定されていることはまずないだろう。
IdentityReferenceプロパティは誰(SID)に対するアクセス権が設定されているかを取得する。NTAccountクラスにキャストしてValueプロパティを取得することにより、見慣れたユーザー名が取得できる。同一ユーザーに対する権限が複数回現れることがあるから注意が必要である。
FileSystemRightsプロパティは設定されている権限を取得する。複数の権限が設定されていれば複数の権限が取得できる。
IsInheritedプロパティは、アクセス権限が継承されたものであるかどうか取得する。
プログラムのテスト
プログラムを実行した結果は以下の通りである。
AccessControlType    AccountName    FileSystemRights    IsInherited
Allow    NT AUTHORITY\SYSTEM    FullControl    False
Allow    BUILTIN\Administrators    FullControl    False
Allow    BUILTIN\Users    ReadAndExecute, Synchronize    False
Allow    NT SERVICE\TrustedInstaller    FullControl    True
Allow    BUILTIN\Administrators    ReadAndExecute, Synchronize    True
Allow    NT AUTHORITY\SYSTEM    ReadAndExecute, Synchronize    True
Allow    BUILTIN\Users    ReadAndExecute, Synchronize    True
ここでBUILTIN\Administratorsに関する権限が2回現れているが、これは一方が継承した権限、もう一方が明示的な権限である。最終的な権限は2つの権限の積み上げになり、ここではフルコントロールになる。

なおこの結果はセキュリティの詳細設定画面で表示される内容と同じものになるはずである。(ファイルの右クリックから[プロパティ]→[セキュリティ]タブ選択→[詳細設定]ボタン押下で表示)

フォルダーのアクセス権を列挙する
フォルダーのアクセス権を列挙するには、やはりGetAccessRulesメソッドを使う。wwwroot(IISの仮想ディレクトリのルート)のアクセス権を列挙するサンプルを以下に示す。
string folderPath = @"C:\inetpub\wwwroot";

//見出し
System.Diagnostics.Debug.WriteLine(
   "AreAccessRulesCanonical\tAreAccessRulesProtected");
//ディレクトリのセキュリティオブジェクト取得
DirectorySecurity security = Directory.GetAccessControl(folderPath);
//アクセス許可の並び順、継承からの保護
System.Diagnostics.Debug.WriteLine(security.AreAccessRulesCanonical
   + "\t" + security.AreAccessRulesProtected);

//見出し
string ace = "AccessControlType"
   + "\tAccountName"
   + "\tFileSystemRights"
   + "\tIsInherited"
   + "\tInheritanceFlags"
   + "\tPropagationFlags";
System.Diagnostics.Debug.WriteLine(ace);

//アクセス権の列挙
foreach (FileSystemAccessRule rule in
   security.GetAccessRules(true, true, typeof(NTAccount)))
{
   ace = rule.AccessControlType
       + "\t" + (rule.IdentityReference as NTAccount).Value
       + "\t" + rule.FileSystemRights.ToString()
       + "\t" + rule.IsInherited.ToString()
       + "\t" + rule.InheritanceFlags.ToString()
       + "\t" + rule.PropagationFlags.ToString();
   System.Diagnostics.Debug.WriteLine(ace);
}
DirectorySecurityクラスはフォルダーのセキュリティを司るクラスである。DirectoryクラスのGetAccessControlメソッドで取得する。
DirectorySecurityクラスのAreAccessRulesCanonicalプロパティは、設定されているアクセス権限が標準の並び順になっているかを返す。(拒否権限が許可権限の前に設定されている、など) この順番が不正だと、正しくアクセス権限が評価されないことがあるから注意が必要である。
AreAccessRulesProtectedプロパティはアクセス権限を親から継承する設定になっているかを返す。権限が親から継承される場合falseを返す。
FileSystemAccessRuleクラスのInheritanceFlagsプロパティは、アクセス権限を継承する先の種類(ファイル、フォルダー)を取得する。
PropagationFlagsプロパティは、アクセス権限を適用する範囲を取得する。

InheritanceFlagsとPropagationFlagsの詳細は、アクセス権限の継承を参照のこと。
プログラムのテスト
プログラムを実行した結果は以下の通りである。
AreAccessRulesCanonical AreAccessRulesProtected
True False
AccessControlType AccountName FileSystemRights IsInherited InheritanceFlags PropagationFlags
Allow BUILTIN\IIS_IUSRS ReadAndExecute, Synchronize False None None
Allow BUILTIN\IIS_IUSRS -1610612736 False ContainerInherit, ObjectInherit InheritOnly
Allow NT SERVICE\TrustedInstaller FullControl True None None
Allow NT SERVICE\TrustedInstaller 268435456 True ContainerInherit, ObjectInherit InheritOnly
Allow NT AUTHORITY\SYSTEM FullControl True None None
Allow NT AUTHORITY\SYSTEM 268435456 True ContainerInherit, ObjectInherit InheritOnly
Allow BUILTIN\Administrators FullControl True None None
Allow BUILTIN\Administrators 268435456 True ContainerInherit, ObjectInherit InheritOnly
Allow BUILTIN\Users ReadAndExecute, Synchronize True None None
Allow BUILTIN\Users -1610612736 True ContainerInherit, ObjectInherit InheritOnly
Allow CREATOR OWNER 268435456 True ContainerInherit, ObjectInherit InheritOnly
1ユーザーにつき2行ずつ権限が出力されている点を除けば、セキュリティの詳細設定画面と同一の結果になっていることが確認できる。これはWindows7 x64版で実行した結果だが、どうもアクセス許可と、InheritanceFlags/PropagationFlagsフラグ群が別の行になって出力されているようである。原因は不明。

既知の問題
アクセス権を列挙するためには、実行ユーザーに、そのファイルまたはフォルダーの「アクセス許可の読み取り」権限がないといけない。

既定の組み合わせでは、以下のいずれかがあればよい。
  • フルコントロール
  • 変更
  • 読み取りと実行
  • 読み取り
権限が不足する場合、GetAccessControlメソッド実行時に例外UnauthorizedAccessException(呼び出し元に、必要なアクセス許可がありません。)が発生する。
次のステップ
ユーザーにアクセス権を追加する
Copyright (c) 2010 BOSS. All rights reserved.