Open5

Windows Serverを用いてファイル共有を行うとき、第一階層のフォルダやファイルはユーザーにいじってほしくないときの設定

Kumasun MorinoKumasun Morino

やりたいこと

タイトル通り。
共有フォルダ内の第一階層は、部門ごと・用途別など固定にしておき、Administratorsのみ編集可能とする
第二階層以下はユーザーに自由に触ってもらってよいものとする

フォルダ構造(例)
D:
└─share   ← 共有フォルダルート
   ├─総務部  ← 第一階層(触ってほしくない)
   │   └─サブフォルダ ←第二階層以降(自由に触ってもらっていい)
   ├─経理部
   │   └─サブフォルダ
   └─営業部
         └─サブフォルダ

UNCパスは \\svfile.nwtraders.msft\share\ であるものとする

期待する動作

ユーザーは…

  • ルートフォルダにおいて、ファイルやサブフォルダの作成を行うことができない
  • ルートフォルダのサブフォルダ(例では「総務部」など)の移動、削除、名前の変更を行うことができない
  • ルートフォルダのサブフォルダ内は自由に操作できる

Administratorsユーザーは…

  • フルコントロールを与えられている

環境

  • Windows Server 2008 R2 Standard
  • ドメインに参加している
Kumasun MorinoKumasun Morino

とりあえず実現できた設定

ルートフォルダ

ルートフォルダのアクセス許可エントリ

ドメインユーザーを追加し、「フォルダーの内容の一覧表示」のみ「許可」とし、他は「未定義」とした。

サブフォルダ(第一階層)

サブフォルダ(第一階層)のアクセス許可エントリ

ドメインユーザーを指定し、セキュリティの詳細設定で

  • フォルダーのスキャン/ファイルの実行
  • フォルダーの一覧/データの読み取り
  • 属性の読み取り
  • 特殊属性の読み取り
  • ファイルの作成/書き込み
  • フォルダーの作成/データの追加
  • 属性の書き込み
  • 特殊属性の書き込み
  • サブフォルダーとファイルの削除
  • アクセス許可の読み取り」
    の権限を与えた。
    (「属性」「特殊属性」は必要か分からないがとりあえず付けた)

なお、上記のかなり多い項目は、icaclsのアクセス許可マスクに直すと(RX,W,DC)というシンプルなものになる。

Kumasun MorinoKumasun Morino

これ実務だとサブフォルダが大量にあって手動で設定超めんどくせーってところまで来た
バッチファイルで何とかできないか試行中だが変数展開してくれない!なぜ!

@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!が展開されていないことが原因だと思われるが、なぜ…

Kumasun MorinoKumasun Morino

バッチファイル化でうまく動かない件の解決方法

可読性は落ちるかもしれないが、サブルーチン化することで動作させることに成功した。

@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に渡す権限指定の中でカンマ区切りのものがあるが、引数の区切り文字だと認識してしまい中途半端な状態でコマンドに渡ってしまっていた。
ダブルクォートで囲えば回避できるはずだが、なぜかできなかったため、権限指定をサブルーチン内で決め打ちすることとした。

Kumasun MorinoKumasun Morino

覚書

icacls コマンドラインツール

コマンドラインからファイルやフォルダのアクセス許可リストの読み取り、書き込みが可能。
caclsの代替。

詳しくはicacls /?を参照のこと

継承について

アットマークアイティの記事が詳しい。

オブジェクト継承(OI)

「このフォルダーとファイルのみに適用」
ファイルに継承される。

コンテナー継承

「このフォルダーとサブフォルダーに適用」
フォルダーに継承される