🗿

[C#] ファイルに、フルアクセス権限を付与する

2021/11/06に公開

もくじ
https://qiita.com/tera1707/items/4fda73d86eded283ec4f

やりたいこと

WindowsPCに作った管理者ユーザー、管理者でないユーザーのすべてからアクセスできるファイルを作りたい。

やり方

FileSecurityクラス、FileSystemAccessRuleクラスを使う。

  • File.GetAccessControl()でファイル名を指定してFileSecurityを取得
  • 指定したいアクセス権限(AccessRights)を指定してFileSystemAccessRuleクラス作成
  • FileSecurityのAddAccessRule()に、作成したFileSystemAccessRuleを渡す
  • そのFileSecurityをFile.SetAccessControl()に渡す

これで、指定のファイルにほしいアクセス権限をセットできる。
コードとしては下記になる。
(肝はAddFileSecurity()メソッド。)

using System;
using System.IO;
using System.Security.AccessControl;
using System.Windows;

namespace FileAccessRightsTest
{
    class Program
    {
        static string TargetStringFilePath = @"C:\ProgramData\MyDebug\TargetString.txt";

        static void Main(string[] args)
        {
            WriteStringToFile(TargetStringFilePath, "AAAAAAA......");
        }

        /// <summary>
        /// アクセス権限セットのありなしを選ばせた後、
        /// 指定のファイルを作成し(開き)、
        /// 全ユーザーにフルアクセス権限を許可する。
        /// ファイルを開けなかったら開けないときの例外のMessageをMessageBoxで表示する
        /// </summary>
        public static void WriteStringToFile(string path, string data)
        {
            Console.WriteLine("0:アクセス権限セットなし  1:セットあり");
            var acSet = Console.ReadLine();

            try
            {
                var dir = Path.GetDirectoryName(path);
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }

                using (var fs = new FileStream(path, FileMode.Create))
                using (var sw = new StreamWriter(fs))
                {
                    sw.Write(data);
                    MessageBox.Show("ファイル作成完了");
                }

                if (acSet != "0")
                {
                    AddFileSecurity(path, @"BUILTIN\Users", FileSystemRights.FullControl, AccessControlType.Allow);
                    MessageBox.Show("セキュリティセット完了");
                }
                else
                {
                    MessageBox.Show("セキュリティセットなし");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        // https://docs.microsoft.com/ja-jp/dotnet/api/system.security.accesscontrol.filesecurity?view=windowsdesktop-5.0
	// のサンプルそのまま。
        public static void AddFileSecurity(string fileName, string account, FileSystemRights rights, AccessControlType controlType)
        {
            // Get a FileSecurity object that represents the
            // current security settings.
            FileSecurity fSecurity = File.GetAccessControl(fileName);

            // Add the FileSystemAccessRule to the security settings.
            fSecurity.AddAccessRule(new FileSystemAccessRule(account, rights, controlType));

            // Set the new access settings.
            File.SetAccessControl(fileName, fSecurity);
        }
    }
}

メモ

サンプルコードでは、@"C:\ProgramData\MyDebug\TargetString.txt"にファイルを作っている。

上記コードを使ってフルアクセスを付与するやり方、具体的には

  • 管理者ユーザーAでログイン
  • 上記コードでTargetString.txtを作成、"BUILTIN\Users"にフルアクセス権限を付与
  • 管理者でないユーザーBでログイン
  • 上記コードでTargetString.txtに書き込み

という手順を踏むと、ユーザーBでもファイルに書き込みができる。


そうではなく、フルアクセス権限を付与しない場合、例えば、

  • 管理者ユーザーAでログイン
  • 上記コードでTargetString.txtを作成、"BUILTIN\Users"に権限を付与はしない
  • 管理者でないユーザーBでログイン
  • 上記コードでTargetString.txtに書き込み

→ ユーザーBでファイル書き込み失敗し、catchに流れて「アクセス拒否されました」とMsgBox表示

となる。

今後のToDo

とりあえず権限付与してやればアクセスができることは分かったが、

MS公式にあるような「DACL」「SACL」、よくわかってない。
勉強必要...

参考

FileSecurityクラスの公式説明
https://docs.microsoft.com/ja-jp/dotnet/api/system.security.accesscontrol.filesecurity?view=windowsdesktop-5.0

@"BUILTIN\Users"で、全ユーザーにアクセス許可できるとある
https://stackoverflow.com/questions/8944765/c-sharp-set-directory-permissions-for-all-users-in-windows-7

WellKnownSidType.BuiltinUsersSidでも全ユーザー指定できる?(試してない)
https://stackoverflow.com/questions/9108399/how-to-grant-full-permission-to-a-file-created-by-my-application-for-all-users?answertab=active#tab-top

ファイルの読み書き
https://qiita.com/tera1707/items/65025aca202ef0535fa5

Discussion