とりとめも

藻類が学んだり感じたりしたことを未来の自分のために書き留めるところ

WindowsサーバーのデータをrobocopyでACLごとコピーしたら共有フォルダへのアクセスが不可になった話

はじめに

随分お久しぶりなブログとなってしまいました。
半年ぶり……?

この間なにをしていたかと言えば、色々していたんですが、それは置いといて。
ブログのリハビリをしなければということで、今回はWindowsサーバーのデータ移行時に遭遇した問題について書きます。

半年前に書いてたRubyとかCentOSとかとは随分色合いが違いますが、そっち方面についてもまた書いていきたいです。がんばる。

問題の経緯

  • Windowsサーバー(主にファイルサーバーとして利用)のデータ移行をした
    • OSは2003 → 2012
    • robocopy /MIRでACLごとコピーした
    • クライアントPCはWindows 7で変わらず
  • 移行後、一般ユーザーでは特定の共有フォルダにネットワーク経由でアクセスできなくなった
    • アクセス権エラーが出る

結論と解決方法

該当のフォルダは「削除拒否」が付与されていたのですが、大昔にその設定が行われた際のicaclsコマンドが誤っていたのでした。

アクセス不可  icacls フォルダ名 /deny ユーザー名:D
 アクセス可  icacls フォルダ名 /deny ユーザー名:(DE)

詳細は後述。

解決方法

GUIから

このコマンドが原因だと知る前に、GUIから削除拒否権限を再設定したのですが、それで問題は解消できました。

コマンドで

後述のリンク先にもありますが、コマンドで再設定する場合は以下のようになります。

icacls フォルダ名 /remove:d ユーザー名
icacls フォルダ名 /deny ユーザー名:(DE)

以上の通り、適当に再設定してあげればよいので解決は簡単そうです。

結局これなに?

2003の頃は問題なかったわけで、この事象なんなの?というのを以下に整理します。
有名なお話のようですし、下記リンクの内容がほぼすべてなのですが。

https://support.microsoft.com/ja-jp/help/2784859

要するに、icacls /denyする際、「D」を指定してしまうと、余計な拒否設定(Synchronize)まで付与されてしまうとのことです。
そしてそれはSMB2以降を使用したアクセスでのみ機能するため、Windows Server2003時代は表に出ていなかったようです。

なので、icaclsで削除拒否を付与する際はDではなく(DE)にしましょう、というのが結論ですね。私が自分で削除拒否を設定するときも(DE)にしていたはずです。
でも、Dも(DE)もプロパティ等を一見する限りは同じ設定のように思えるため、OSが変わった途端に事象が発生すると、これが原因と気付くのは少し難しい気がします。
(とりあえずGUIから手動で再設定してしまえば解決はしますが)

以下は、具体的に何がどうなっていたのかメモです。蛇足です。

問題のフォルダ体系とACL

簡略化して書くと、以下の2フォルダが同じ階層に存在しました。
アクセス権限はすべてドメイングループで制御しており、一般ユーザー(Users)と管理者(Admins)しか存在しない、程度に思ってください。

  • ~\hoge\OKフォルダ
    • Users「変更可」「削除拒否(このフォルダのみ)」
    • GUIから設定した(あとで判明)
    • 移行後もアクセスできた
  • ~\hoge\NGフォルダ
    • Users「変更可」「削除拒否(このフォルダのみ)」
    • icaclsコマンドで設定した(あとで判明)
    • 移行後アクセスできなかった
      ※Adminsは全フォルダにフルコントロール

OKフォルダとNGフォルダのアクセス可否が問題の焦点ですが、上記の通り、ACLは同じに設定されているように見えました。
もう少し詳しく見てみます。

icaclsで見てみる

icaclsコマンドで見てみれば、たしかに同じ値が表示されました。以下のような感じです。

~hoge>icacls *
NG Users:(DENY)(D)
   Administrators:(OI)(CI)(F)
   Users:(OI)(CI)(M)

OK Users:(DENY)(D)
   Administrators:(OI)(CI)(F)
   Users:(OI)(CI)(M)

Get-Aclで見てみる

でもpowershellのGet-Aclコマンドレットで見てみると様相が変わりました。
各フォルダの「Deny」権限のみを抽出すると、以下のようになります。

PS ~\hoge> (Get-Acl OK).Access | Where-Object {$_.AccessControlType -eq
 "Deny"}

FileSystemRights  : Delete
AccessControlType : Deny
IdentityReference : Users
IsInherited       : False
InheritanceFlags  : None
PropagationFlags  : None

PS ~\hoge> (Get-Acl NG).Access | Where-Object {$_.AccessControlType -eq
 "Deny"}

FileSystemRights  : Delete, Synchronize
AccessControlType : Deny
IdentityReference : Users
IsInherited       : False
InheritanceFlags  : None
PropagationFlags  : None

……Synchronizeって何?
これが今回の問題の元凶のようです。先の権限設定コマンドでいえば以下のような感じ。

アクセス不可  icacls フォルダ名 /deny ユーザー名:D
        →Synchronizeの拒否も付く。
 アクセス可  icacls フォルダ名 /deny ユーザー名:(DE)
        →純粋にDeleteの拒否だけが付く。
                GUIから設定した場合もこちらのパターン。

このSynchronizeですが、恥ずかしながらこれまで全然知りませんでした。
以下ではSynchronizeについてわかったことをまとめます。
……結局、全然わからなかったのですが。

Synchronizeについて

パッとわかる情報は見つけられませんでした。
https://msdn.microsoft.com/en-us/library/aa364399(VS.85).aspx
恐らくこのあたりが核心に近い気がするのですが、私の貧弱な知識では理解できませんでした……。

なにやら待機関数なるものがオブジェクト(フォルダ/ファイル)の状態を取得する際に関係してくるらしかったり、Windows APIをあれこれする際に重要そうだったり、そんな雰囲気を感じています。

こんぽんてきな知識の不足を感じる。
でもあまり悲しんでも仕方ありません。可能な範囲で(今の自分に必要なレベルで)理解することにします。

要するに?

前述の通り概念的にはさっぱり分かりませんでした。
私のレベルで実際使用するうえで重要となるのは、結局は以下の点だと思います。


(こちらの記事から引用)

"同期 (SYNCHRONIZE)" の権限が拒否された場合には、以下手順でファイルやフォルダーにアクセス出来なくなります。

・ コンピューターにログオンした状態で、フォルダーやファイルにアクセスする。
・ SMB2 を利用したネットワーク経由でフォルダーやファイルにアクセスする。

特にネットワーク経由のアクセスの際には、アクセス元・先の両方がSMB2に対応している必要があるため、ファイルサーバーが2003だった場合には発生しなかったということですね。

おわりに

robocopyACLごとデータをコピーした際に遭遇した問題についてまとめました。
厳密にはrobocopyに限った話ではなく、icaclでアクセス権を操作する際に発生する問題のようでした。

長々書きましたが、分かったことはそう多くはありませんでした。
実用面では、icaclsでの削除拒否付与時は以下のコマンドを使いましょうというのが要点です。

icacls フォルダ名 /deny ユーザー名:(DE)

理論面(?)ではSynchronizeなる概念が関わっているようですが、よく理解できませんでした。
理解するための前提知識が2層3層に渡っているっぽくて、どう調べればよいのかもわからない有様です。

今の私が必要とする領域の知識ではなさそうですが、でもこういうことを知らずにあれこれ触り続けるのもなんだかなーという思いもあります。恥ずかしいというか、情けないというか。

ひとまず自分に必要な事柄から身につけるのが優先事項なんですけどね。
でもいつかちゃんと勉強して理解したいなー。