Windows(共有)フォルダの移動を禁止する

Windows では、親フォルダのアクセス許可 (permission) が「読み取り専用」であっても、その子フォルダを移動できてしまう。

ノートPCでタッチパッドの感度が高いと、ポインタを移動しているつもりが、一瞬ボタンを押したことになってしまう。エクスプローラでついフォルダを(意図せず)ドラッグしてしまい、行方不明にしてしまう。

アスセス許可の設定で, この挙動を防ぐ方法について。

以下の例では、親フォルダ p とその子フォルダ c1, c2 を用意する。c1, c2 を移動できないようにする。

ファイル属性

NTFS には, ファイルの属性に readonly がある. FILE_ATTRIBUTE_READONLY値 (0x1). しかし、これをディレクトリに適用しても、エクスプローラは無視する。

エクスプローラではこの属性をフォルダに付けることはできず、attribコマンドで付けたとしても、何の問題もなく、削除できてしまう。

Windows 上でのアクセス許可設定

Windows (というか NTFS) にはアクセス権の継承があるので、設定の順番に注意。

アクセス権の継承は、親フォルダで設定されたアクセス権をそのまま子オブジェクトに伝播させる仕組み。子オブジェクト独自の設定がなくても、アクセス許可できる。逆に、単純に継承を切ると、子オブジェクトに誰もアクセスできなくなってしまう。

親フォルダのpermission

親フォルダ p のプロパティ。"セキュリティ"タブ, 右下の[詳細設定] (Advanced...) ボタンをクリック。

"pのセキュリティの詳細設定" ダイアログボックスが開く。

1. まず初めに、この親フォルダ (p) のさらに親からの継承を外してやる。でないと設定を変更できない。

[継承の無効化]ボタンをクリック。「継承のブロック」ポップアップが表示される。

「→継承されたアクセス許可をこのオブジェクトの明示的なアクセス許可に変換します。」をクリック。これで、"継承元"列が「なし」に変わる。

ここで一度、[適用]ボタンをクリックして、反映させる。「アクセス許可エントリ」ペインの下にあるボタンの[表示]が[編集]に変わって、変更が可能になる。

2. 次いで, ユーザを選択して、[編集]ボタンをクリック。

適用先: は,「このフォルダー、サブフォルダーおよびファイル」のまま。"このフォルダーのみ" にしてしまうと、子フォルダのアクセス権が削除されて (正しくは継承が切れて), アクセス自体ができなくなってしまう。

右上の"高度なアクセス許可を表示する"をクリック。"サブフォルダーとファイルの削除"のチェックを外す。これがキモ。

Windows は、ファイル属性 (attribute) とアクセスコントロールリスト (ACL) が独立していて、ここではACLの一つ FILE_DELETE_CHILD値 (0x40) を変更してやる. .NET だと DeleteSubdirectoriesAndFiles という名前.

[OK]ボタンを繰り返し、更新する。

残念でした。これだけではダメです。Windows のアクセス許可は, "いずれか" が許可であれば操作可能という挙動なので、子フォルダの設定も変えてやらないといけません。

子フォルダのpermission

今度はそれぞれの子フォルダのプロパティから、同様に、アクセス許可を変更する。

まず、[継承の無効化]ボタンで、親フォルダpからの継承を切る。

ユーザを選択して、[編集]ボタンをクリック。

"サブフォルダーとファイルの削除"のチェックが外れている (親の設定が引き継がれているため) が、これはチェックを入れて戻してやる。逆に、"削除"のチェックを外す。

[OK]ボタンを押して更新する。あとはすべてのフォルダで繰り返す。

以上の設定で、フォルダc1を移動しようとすると、次のダイアログボックスが出て、弾かれる。

フォルダc1内のファイルは、"削除"アクセス権が(継承してくるため)外れているが、実害はない。

子フォルダc1のアクセス権を設定しただけでは、依然としてフォルダ移動できてしまう。必ずp, c1両方の設定変更が必要。

上述のとおり、どちらかが許可なら許可になる。でもその挙動って、許可し過ぎになりやすく、危うい。

Sambaサーバで設定

Windows 上での設定は、フォルダが増えると地味に大変。Sambaなら、UNIX側から一撃で設定できる。

Windows側から、p, c1, c2 を作る。

Samba は多様な設定方法がありますが、POSIX ACL マップ (vfs objects = acl_xattr になっていない) の場合は, Windows 側で行った「高度なアクセス許可」はすべて無視されます。

Windows ACL を利用する設定の場合は、上述の方法が使えます。

いずれの場合でも, UNIX側のシェルで, フォルダ p に対して, chmod -w p するだけでよい。これで、この例の c1, c2 とも移動, 削除できなくなる。