![]() |
![]() |
ディレクトリの x ビットの意味は分かりにくい。ここではその意味を探求する。
MacOSX (FreeBSD) での実験
-bash$ cd /tmp -bash$ mkdir T -bash$ ls -ld T drwxr-xr-x 2 arisawa wheel 68 23 Apr 10:31 T -bash$ touch T/a -bash$ chmod 666 T -bash$ ls -l T ls: a: Permission denied -bash$ cd T -bash: cd: T: Permission denied -bash$ touch T/a touch: T/a: Permission denied -bash$ rm T/a rm: T/a: Permission denied -bash$ >T/a -bash: T/a: Permission denied -bash$ cat T/a cat: T/a: Permission denied -bash$
つまり x ビットを外すことによってディレクトリは完全に鍵をかけられたことになる。
rw ビットはその場合には役割を失っている。
Plan 9 についてはどうか? マニュアルにはディレクトリの x ビットの意味は "search" であると説明されている*。しかしこの説明は良く分からない。
* "search" の言い回しは Unix 時代からのものらしい。以下は FreeBSD のマニュアルからの引用である。
The perm symbols represent the portions of the mode bits as follows:
....
x The execute/search bits.
ちょっと実験をしてみよう。
term% mkdir T term% touch T/a term% chmod 666 T term% cd T term% ls -l --rw-rw-r-- M 8 arisawa arisawa 0 Apr 23 10:39 a term% cat a cat: can't open a: 'a' permission denied term% touch a touch: a: cannot create: file already exists term% rm a rm: a: 'a' permission denied term% >a a: rc: can't open: file already exists term% cp a b cp: can't stat a: 'a' permission denied term% touch b term%
Plan 9 では x ビットを外してもディレクトリの中に入って行ける。そしてディレクトリの rw ビットの意味は保たれているようだ。この実験を見る限り x ビットを外す事によって、ディレクトリの中のファイルに対する全てのオペレーションが禁止されているように見える。
以下はディレクトリTを新たに作成し
cd T
ls
touch a
cat a
touch -c a
rm a
の操作をこの順に行った時の、いろいろな rwx ビットの組み合わせに対する実験である。
| mod | cd T | ls | touch a | cat a | touch -c a | rm a |
|---|---|---|---|---|---|---|
| --- | OK | denied | denied |   |   |   |
| --x | OK | denied | denied |   |   |   |
| -w- | OK | denied | OK | denied | denied | denied |
| -wx | OK | denied | OK | OK | OK | OK |
| r-- | OK | OK | denied |   |   |   |
| r-x | OK | OK | denied |   |   |   |
| rw- | OK | OK | OK | denied | denied | denied |
| rwx | OK | OK | OK | OK | OK | OK |
ディレクトリのモード属性に関わらずディレクトリの中へは常に入って行ける。
"ls" はディレクトリの r ビットによって成否が決まる。
"touch a" は a を生成する。これはディレクトリの x ビットによって成否が決まる。
"touch -c a" と "rm a" は a が存在している場合にのみ意味を持つ。従って "touch a" が拒否された場合にはやっても意味が無いので表では空白になっている。
なお "touch -c a" は a の変更時刻を現在にするだけでシステムコールとしては wstat を使っている。
書き込みオープンについても実験した方が良いのだが、結果は予想通りであろう。
仮に学生から宿題のファイルをどこかのディレクトリに受け取りたいとせよ。筆者もこのニーズは強い。この場合には次の要請に応える必要がある。
Plan 9 ではレポートの受け取り用に rw- のディレクトリを作成すれば良い事がわかる。
ディレクトリの x ビットの下での w ビットは Unix でも Plan 9 でもディレクトリの一覧の変更を許す意味である。即ちファイルの生成と削除が許される。ファイルの w ビットの意味はファイルの内容の変更を許す事であってファイル foo に対して
chmod 664 foo
としたところで foo が他人による削除から保護される事を意味しない。これは我々の日常的な感覚に反する事であり、そのために間違いを犯す原因になる。
Plan 9 では /tmp の実体は $home/tmp なので問題は起きにくいが、Unix の場合には/tmp は共同利用のディレクトリであり /tmp の許可ビットは rwxrwdrwx となっていた。その場合には /tmp に書いたファイルは誰かに消される危険性を持っている。
最近の Unix では /tmp は rwxrwxrwt になっているようだ。この場合には他人による削除から保護される。ディレクトリ T に t ビットを立てるには
chmod +t T
を実行すればよい。
Plan 9 には他人からの削除を保護する意味での t ビットは存在しない。Plan 9 でも共同利用のディレクトリを持ちたい場合にはどのようにすればよいだろうか?
T を rwxrwdrwx のディレクトリとせよ。
mkdir T/arisawa
chmod 770 T/arisawa
touch T/arisawa/foo
とすれば foo は他のユーザから保護されている。他のユーザは
rm T/arisawa/foo
を実行しても T/arisawa のディレクトリの許可ビットのために拒否される。
rm -rf T/arisawa
が存在する。他方、直接 T/arisawa を消そうとしてもディレクトリが空ではないと言って断られる。
この例では chmod 770 として他のユーザを強く排除したが、0 ではなく、もっと緩いビットを立てることもできる。
ここで述べた考え方は /cron/*/cron に適用されている。
Plan 9 では /mail/tmp が smtpd の作業場所として位置づけられている。smtpd は none の権限でメールの処理をしている。そのために潜在的な問題を抱えている。ちゃんとしたことをやりたいのであれば smtpd は他のユーザ、例えば upas としてサービスを行う必要があろう。