ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう)

プログラムからディレクトリのアクセス権を追加した場合、「特殊なアクセス許可」になってしまい意図したアクセス権が設定できない現象について紹介します。

現象の確認

コード例

次のコードを準備します。
.NET の場合
private void button5_Click(object sender, EventArgs e)
{
  Directory.CreateDirectory(@"c:\\develop\dev");
  string filePath = @"c:\\develop\dev";

  FileSystemAccessRule rule = new FileSystemAccessRule(
    new NTAccount("everyone"),
    FileSystemRights.FullControl,
    AccessControlType.Allow);

  DirectoryInfo di = new DirectoryInfo(filePath);
  DirectorySecurity security = FileSystemAclExtensions.GetAccessControl(di);
  security.SetAccessRule(rule);
  FileSystemAclExtensions.SetAccessControl(di, security);
}
.NET Framework の場合
private void button6_Click(object sender, EventArgs e)
{
  Directory.CreateDirectory(@"c:\\develop\dev");
  string filePath = @"c:\\develop\dev";

  FileSystemAccessRule rule = new FileSystemAccessRule(
    new NTAccount("everyone"),
    FileSystemRights.FullControl,
    AccessControlType.Allow);

  DirectorySecurity security = Directory.GetAccessControl(filePath);
  security.SetAccessRule(rule);
  Directory.SetAccessControl(filePath, security);
}
上記のコードを実行すると、c:\develop フォルダに devフォルダを作成し、"everyone"のフルコントロール権を割り当てます。
しかし、実行後フォルダのプロパティのセキュリティタブを見ると、アクセス権に"everyone"のユーザーは追加されているものの、 フルコントロールのアクセス権にチェックが入っていません。
アクセス許可の欄を見ると[特殊なアクセス許可]に[許可]のチェックが入っているのみです。
ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう):画像1 ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう):画像2

アクセス権の設定内容を詳しく確認します。 フォルダのプロパティの[セキュリティタブ]の[詳細設定]ボタンを押し、セキュリティの詳細設定ダイアログを開き、[アクセス許可の変更]ボタンを押します。セキュリティの詳細設定ダイアログが開きますので、"everyone"を選択し、[編集]ボタンを押します。
ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう):画像3

下図のアクセス許可エントリダイアログが開きます。設定内容を確認すると、[適用先]の項目が[このフォルダのみ]になっています。
ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう):画像4

適用先のドロップダウンリストボックスをクリックし、リストの[このフォルダ、サブフォルダおよびファイル]をクリックして選択します。 設定後、[OK]ボタンを押しダイアログを閉じます。
ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう):画像5
ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう):画像6

フォルダのプロパティダイアログを開き、[セキュリティ]タブのアクセス権を確認すると、[フルコントロール]にチェックがついていることが確認できます。
ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう):画像7
ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう):画像8

対処法

アクセス権の追加時に、適用先を[このフォルダ、サブフォルダおよびファイル]にするには、以下のコードを記述します。

コード

下記のコードを実行すると、"everyone"にフルコントロールのアクセス権をつけられます。
FileSystemAccessRuleクラスのコンストラクタの第3引数に InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit を与え、第4引数に PropagationFlags.None を与えます。
.NET 5以降
private void button4_Click(object sender, EventArgs e)
{
  Directory.CreateDirectory(@"c:\\develop\dev");
  string filePath = @"c:\\develop\dev";

  FileSystemAccessRule rule = new FileSystemAccessRule(
    new NTAccount("everyone"),   //ユーザー
    FileSystemRights.FullControl, //変更権限
    InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit,
    PropagationFlags.None,
    AccessControlType.Allow);//アクセス許可

  DirectoryInfo di = new DirectoryInfo(filePath);
  DirectorySecurity security = FileSystemAclExtensions.GetAccessControl(di);
  security.SetAccessRule(rule);
  FileSystemAclExtensions.SetAccessControl(di, security);
}
.NET Framework
private void button3_Click(object sender, EventArgs e)
{
  Directory.CreateDirectory(@"c:\\develop\dev");
  string filePath = @"c:\\develop\dev";

  FileSystemAccessRule rule = new FileSystemAccessRule(
    new NTAccount("everyone"),   
    FileSystemRights.FullControl, 
    InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit,
    PropagationFlags.None,
    AccessControlType.Allow);
      
  DirectorySecurity security = Directory.GetAccessControl(filePath);
  security.SetAccessRule(rule);
  Directory.SetAccessControl(filePath, security); 
}

InheritanceFlagsの違いによるアクセス権の違い

FileSystemAccessRuleのコンストラクタの引数のInheritanceFlagsを変えてどのようにアクセス権が変わるか見てみます。

InheritanceFlags.ContainerInheritの場合

private void button3_Click(object sender, EventArgs e)
{
  Directory.CreateDirectory(@"c:\\develop\dev");
  string filePath = @"c:\\develop\dev";

  FileSystemAccessRule rule = new FileSystemAccessRule(
    new NTAccount("everyone"),   
    FileSystemRights.FullControl, 
    InheritanceFlags.ContainerInherit,
    PropagationFlags.None,
    AccessControlType.Allow);
      
  DirectorySecurity security = Directory.GetAccessControl(filePath);
  security.SetAccessRule(rule);
  Directory.SetAccessControl(filePath, security); 
}
InheritanceFlags.ContainerInheritを指定した場合は適用先が[このフォルダーとサブフォルダー]になります。
ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう):画像9

InheritanceFlags.Noneの場合

private void button3_Click(object sender, EventArgs e)
{
  Directory.CreateDirectory(@"c:\\develop\dev");
  string filePath = @"c:\\develop\dev";

  FileSystemAccessRule rule = new FileSystemAccessRule(
    new NTAccount("everyone"),   
    FileSystemRights.FullControl, 
    InheritanceFlags.None,
    PropagationFlags.None,
    AccessControlType.Allow);
      
  DirectorySecurity security = Directory.GetAccessControl(filePath);
  security.SetAccessRule(rule);
  Directory.SetAccessControl(filePath, security); 
}
InheritanceFlags.Noneを指定した場合は適用先が[このフォルダーのみ]になります。
ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう):画像10

InheritanceFlags.ObjectInheritの場合

private void button3_Click(object sender, EventArgs e)
{
  Directory.CreateDirectory(@"c:\\develop\dev");
  string filePath = @"c:\\develop\dev";

  FileSystemAccessRule rule = new FileSystemAccessRule(
    new NTAccount("everyone"),   
    FileSystemRights.FullControl, 
    InheritanceFlags.ObjectInherit,
    PropagationFlags.None,
    AccessControlType.Allow);
      
  DirectorySecurity security = Directory.GetAccessControl(filePath);
  security.SetAccessRule(rule);
  Directory.SetAccessControl(filePath, security); 
}
InheritanceFlags.ObjectInheritを指定した場合は適用先が[このフォルダーとファイル]になります。
ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう):画像11

InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInheritの場合

private void button3_Click(object sender, EventArgs e)
{
  Directory.CreateDirectory(@"c:\\develop\dev");
  string filePath = @"c:\\develop\dev";

  FileSystemAccessRule rule = new FileSystemAccessRule(
    new NTAccount("everyone"),
    FileSystemRights.FullControl,
    InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit,
    PropagationFlags.None,
    AccessControlType.Allow);

  DirectorySecurity security = Directory.GetAccessControl(filePath);
  security.SetAccessRule(rule);
  Directory.SetAccessControl(filePath, security);
}
InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit を指定した場合は適用先が[このフォルダー、サブフォルダーおよびファイル]になります。
ディレクトリへのアクセス権が意図したとおりにならない (「特殊なアクセス許可」になってしまう):画像12
AuthorPortraitAlt
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
作成日: 2010-11-22
改訂日: 2022-11-03
Copyright © 1995–2025 iPentec all rights reserverd.