Windows Serverを用いてファイル共有を行うとき、第一階層のフォルダやファイルはユーザーにいじってほしくないときの設定
やりたいこと
タイトル通り。
共有フォルダ内の第一階層は、部門ごと・用途別など固定にしておき、Administratorsのみ編集可能とする
第二階層以下はユーザーに自由に触ってもらってよいものとする
D:
└─share ← 共有フォルダルート
├─総務部 ← 第一階層(触ってほしくない)
│ └─サブフォルダ ←第二階層以降(自由に触ってもらっていい)
├─経理部
│ └─サブフォルダ
└─営業部
└─サブフォルダ
UNCパスは \\svfile.nwtraders.msft\share\
であるものとする
期待する動作
ユーザーは…
- ルートフォルダにおいて、ファイルやサブフォルダの作成を行うことができない
- ルートフォルダのサブフォルダ(例では「総務部」など)の移動、削除、名前の変更を行うことができない
- ルートフォルダのサブフォルダ内は自由に操作できる
Administratorsユーザーは…
- フルコントロールを与えられている
環境
- Windows Server 2008 R2 Standard
- ドメインに参加している
とりあえず実現できた設定
ルートフォルダ
ドメインユーザーを追加し、「フォルダーの内容の一覧表示」のみ「許可」とし、他は「未定義」とした。
サブフォルダ(第一階層)
ドメインユーザーを指定し、セキュリティの詳細設定で
- フォルダーのスキャン/ファイルの実行
- フォルダーの一覧/データの読み取り
- 属性の読み取り
- 特殊属性の読み取り
- ファイルの作成/書き込み
- フォルダーの作成/データの追加
- 属性の書き込み
- 特殊属性の書き込み
- サブフォルダーとファイルの削除
- アクセス許可の読み取り」
の権限を与えた。
(「属性」「特殊属性」は必要か分からないがとりあえず付けた)
なお、上記のかなり多い項目は、icacls
のアクセス許可マスクに直すと(RX,W,DC)
というシンプルなものになる。
これ実務だとサブフォルダが大量にあって手動で設定超めんどくせーってところまで来た
バッチファイルで何とかできないか試行中だが変数展開してくれない!なぜ!
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
REM ルートフォルダの指定。最後に必ず「\」をつける
SET ROOT_DIR=D:\share\
SET USER=NWTRADERS\user
REM ルートフォルダの権限設定
REM CI=コンテナー継承、RX=読み取りと実行のアクセス権
icacls %ROOT_DIR% /grant %USER%:(CI)(RX) /Q
REM サブディレクトリの権限設定
FOR /D %%s IN (%ROOT_DIR%*) DO (
SET SUBDIR=%%s
REM ECHO !SUBDIR!\
REM OI=オブジェクト継承、CI=コンテナー継承、F=フルコントロール
icacls !SUBDIR!\ /grant %USER%:(OI)(CI)(F) /Q
)
ENDLOCAL
PAUSE
REM ECHO !SUBDIR!\
のREMを外すとサブディレクトリのフルパスが表示される。
直後のicacls
コマンドで (CI)(F) の使い方が誤っています。
とメッセージが出て止まってしまう。
動き的に!SUBDIR!
が展開されていないことが原因だと思われるが、なぜ…
バッチファイル化でうまく動かない件の解決方法
可読性は落ちるかもしれないが、サブルーチン化することで動作させることに成功した。
@ECHO OFF
REM ルートフォルダの指定。最後に必ず「\」をつける
SET ROOT_DIR=D:\share\
SET SID="NWTRADERS\User"
REM ルートフォルダの権限設定
CALL :icacls_grant_root %ROOT_DIR%
REM サブディレクトリの権限設定
FOR /D %%s IN (%ROOT_DIR%*) DO CALL :icacls_grant_subdir %%s
PAUSE
EXIT 0
REM ルートフォルダの権限設定: CI=コンテナー継承、RX=読み取りと実行のアクセス権
:icacls_grant_root
SET DIR=%1
icacls %DIR% /grant %SID%:(CI)(RX)
EXIT /B 0
REM サブディレクトリの権限設定: OI=オブジェクト継承、CI=コンテナー継承、RX=読み取りと実行のアクセス権、W=書き込み専用アクセス権、DC=子の削除
:icacls_grant_subdir
SET DIR=%1
icacls %DIR% /grant %SID%:(OI)(CI)(RX,W,DC)
EXIT /B 0
:icacls_revoke
SET DIR=%1
icacls %DIR% /remove %SID% /Q
EXIT /B 0
動かなかった原因として、icacls
に渡す権限指定の中でカンマ区切りのものがあるが、引数の区切り文字だと認識してしまい中途半端な状態でコマンドに渡ってしまっていた。
ダブルクォートで囲えば回避できるはずだが、なぜかできなかったため、権限指定をサブルーチン内で決め打ちすることとした。
覚書
icacls コマンドラインツール
コマンドラインからファイルやフォルダのアクセス許可リストの読み取り、書き込みが可能。
cacls
の代替。
詳しくはicacls /?
を参照のこと
継承について
アットマークアイティの記事が詳しい。
オブジェクト継承(OI)
「このフォルダーとファイルのみに適用」
ファイルに継承される。
コンテナー継承
「このフォルダーとサブフォルダーに適用」
フォルダーに継承される