Windowsでファイルが削除できない場合、他のプロセスが使っているか、セキュリティで拒否されているかだが後者の場合のことを調べると結構大変なことがわかる。
Windows 2000以降からセキュリティ機能が強化され、ファイルやプロセスやスレッドなどのカーネルオブジェクトはセキュリティディスクリプタ(SD)をもつ。SDにはACL(Access Control List)が定義される。ACLはACE(Access Control Entry)のリストでACEはSIDとパーミッションをもつ。SIDはユーザやグループの識別子で、表現方法も一様ではない。コードで使う場合は、SID構造体は定義されておらずvoid*で扱う、文字列で扱う表示法は2つあるようで1つは「S-1-」で始まる文字列、もう一つはSDDLで定義される文字列。Sで始まる文字列はレジストリなどに記述されたりしているのでこれを調べる。これはディレクトリ構造あるいは電話番号のように理解することができると思う。
最初のS-1-は今のところたぶん固定でその次の数字がidentifier-authorityになりその次がRID(relative identifier)になる。
定義済みのSIDがいくつかある。
Universal well-known SID | String value | Identifies |
---|---|---|
Null SID | S-1-0-0 | A group with no members. This is often used when a SID value is not known. |
World | S-1-1-0 | A group that includes all users. |
Local | S-1-2-0 | Users who log on to terminals locally (physically) connected to the system. |
Creator Owner ID | S-1-3-0 | A security identifier to be replaced by the security identifier of the user who created a new object. This SID is used in inheritable ACEs. |
Creator Group ID | S-1-3-1 | A security identifier to be replaced by the primary-group SID of the user who created a new object. Use this SID in inheritable ACEs. |
これをみるとSIDはLinuxのユーザ、グループよりも広い概念で、ある動作をしている人や、ある概念なども記述しているものであるようだ。
まとめると
S-1-[authority]-[RID]-
になる。authorityはコードではXX_AUTHORITYで#defineされており、RIDはXX_RIDで#defineされる。
authorityが
0 = SECURITY_NULL_SID_AUTHORITY
1 = SECURITY_WORLD_SID_AUTHORITY、すべての人、WindowsだとEveryoneが相当する。
2 = SECURITY_LOCAL_SID_AUTHORITY、ローカルで使ってる人
3 = SECURITY_CREATOR_SID_AUTHORITY、作った人
5 = SECURITY_NT_AUTHORITY、NTはWindows NTのことか?Windowsのユーザなどはこれが使われる。
RIDはautorityに依存する。
S-1-2-0はautorityが2、RIDが0で、ローカルの人を表すと思われる。
S-1-2-1はautorityが2、RIDが1で、ローカルでログオンしてる人を表すと思われる。
S-1-5-で始まるものはWindowsが管理しているものでいろいろあるが一般ユーザはS-1-5-21-で始まるようだ。
レジストリエディタでHKEY_USERS配下を見るといくつかのSIDがマウントされており自分と一致するのはHKEY_CURRENT_USERにマウントされている。
セキュリティオブジェクトにアクセスする方はtokenを使って行う。このtokenと対象オブジェクトのACEが次々比較されアクセスできるかが決まる。ACLが存在しない場合2つの意味があってACLそのものがない場合と、ACEが0個の場合がある、前者の場合はアクセスは許可され、後者の場合は拒否される、よってACEには基本的に許可を記述し、許可の中で例外的なものを拒否記述する。ACEは上から順に評価され、おそらくSID一致のエントリーが見つかったら更なる処理はしないので拒否は上に書かないとならない。ACLが存在しないとはFATのようなもののことを言っていてNTFSではそういうことはないのだと思う。
SIDの比較はtokenが持っているログインユーザのSIDや属しているグループSIDで行う。上記の話は読み書きでのことだがファイルを作成する場合はtokenが持っているデフォルトのSDが使われる。
長いのでまた今度書こう。最初に書いたファイルを削除したい場合はcygwinをインストールして
$ rm -rfv /cygdrive/C/Dirなどとやるのが早い。