実行権限のみ欠けたディレクトリ(rw-)の挙動

ディレクトリの実行権限は、事実上の「アクセス権限」というのは認識していたが、読み込み、書き込み権限のみで、実行権限がない状態のディレクトリ(rw-)も作ることには作れる。そもそも、wがついててxがついてないディレクトリってどんな動作するんだろと思ったので軽く検証した結果をメモ。


## 先に結論

* ディレクトリの書き込み権限と実行権限はセットになってはじめてファイルの作成がOKな状態にできる。
  * 書き込み権限だけあってもディレクトリ内にファイルの作成はできない。
* ただし書き込み権限がついていると、ディレクトリ自体の更新・アクセス・作成時刻を現在時刻に変更できる[^other]。
  * 誤解しやすい点だが、空の状態のディレクトリの削除、あるいはディレクトリのリネームができるかどうかは、親ディレクトリの権限に依存し、そのディレクトリ自体の権限は関係ない。

[^other]: ほかに書き込み権限のみでできることをご存じの方は教えてくださいｍ


## 検証メモ

### 環境

Dockerコンテナで検証
イメージはubuntu:16.04

### 作業ログ

```bash:Terminal
# rootでまずはuserというユーザのホームディレクトリ以下にhogeというディレクトリを作る。
root$ cd /home/user
root$ chown root:user hoge

# 権限はuserにとってはrw-な状態にする
root$ chmod 766 hoge

root$ ll
total 4.0K
drwxrw-rw- 2 root user 4.0K  4月 26 10:50 hoge

root$ cd hoge

# ファイルもつくる
root$ echo A B C | xargs -n 1 | sed 's/.*/echo & > &/' | sh
root$ ll
-rw-r--r-- 1 root root 2  4月 26 10:52 A
-rw-r--r-- 1 root root 2  4月 26 10:52 B
-rw-r--r-- 1 root root 2  4月 26 10:52 C
```

* ここからuser

```bash:Terminal
# userのホームディレクトリ以下ではあるものの、当然アクセス権はない。
user$ cd /home/user/hoge
bash: cd: /home/user/hoge: Permission denied

# ディレクトリ以下のファイルも開けない
user$ cat hoge/A
cat: hoge/A: Permission denied

# ファイルは作れない。
user$ touch hoge/D
touch: cannot touch 'hoge/D': Permission denied

# リダイレクトもだめ。つまり実行権限がないと書き込みもできない。
user$ echo D > hoge/D
bash: hoge/D: Permission denied

# うるさいが読み込み権限はあるので、ファイル一覧は表示できる。
user$ ls hoge
ls: cannot access 'hoge/B': Permission denied
ls: cannot access 'hoge/C': Permission denied
ls: cannot access 'hoge/A': Permission denied
A  B  C

# ディレクトリの更新日時
user$ ls -l
total 4
drwxrw-rw- 2 root user 4096  4月 26 10:58 hoge

# ディレクトリの作成日時
user$ ls -cl
total 4
drwxrw-rw- 2 root user 4096  4月 26 10:58 hoge

# ディレクトリの参照日時
user$ ls -ul
total 4
drwxrw-rw- 2 root user 4096  4月 26 10:59 hoge

# touch して更新を試みると、それらは更新できる。
user$ touch hoge

user$ ls -l
total 4
drwxrw-rw- 2 root user 4096  4月 26 11:02 hoge

user$ ls -cl
total 4
drwxrw-rw- 2 root user 4096  4月 26 11:02 hoge

user$ ls -ul
total 4
drwxrw-rw- 2 root user 4096  4月 26 11:02 hoge

# しかし--dateオプションは効かない。。
user$ touch --date=1960-01-01 hoge
touch: setting times of 'hoge': Operation not permitted

# -mオプション(更新日時のみ変更)をつけても同じ
user$ touch --date=1960-01-01 -m hoge
touch: setting times of 'hoge': Operation not permitted

# -tオプションもだめ
user$ touch -t "2003010100" hoge
touch: setting times of 'hoge': Operation not permitted

# 中に消せないファイルがあるので、当然ディレクトリは削除できない
user$ rm -rf hoge
rm: cannot remove 'hoge/B': Permission denied
rm: cannot remove 'hoge/C': Permission denied
rm: cannot remove 'hoge/A': Permission denied

# ディレクトリの名前は変更できる
user$ mv hoge hoge1
user$ ls
hoge1

# 権限の変更、所有者の変更は当然無理
user$ chmod +x hoge
chmod: changing permissions of 'hoge1': Operation not permitted

user$ chown user:user hoge
chown: changing ownership of 'hoge': Operation not permitted

# 下記のコマンドをrootで実行してhogeの中身を空にする。
root$ rm hoge/*

# ディレクトリのリネームは可能（親ディレクトリの権限に依存するため当然）
user$ mv hoge hoge1

# ディレクトリが空であれば、rootでなくてもディレクトリを削除できる。これも当然。
user$ rm -rf hoge

```

比較のため、r-xの状態のディレクトリでも同じ実験

```bash:Terminal
# こんどはfugaというr-xなデフォルトの状態のディレクトリを作る。
root$ mkdir /home/user/fuga

root$ cd /home/user

root$ chown root:user fuga

root$ ll
total 8.0K
drwxr-xr-x 2 root root 4.0K  4月 26 11:13 fuga
drwxrw-rw- 2 root user 4.0K  4月 26 11:13 hoge
```

* ここからuser

```bash:Terminal
# touch すらできない
user$ touch fuga
touch: setting times of 'fuga': Permission denied

# 他の検証は同じ
```

### 参考にしたもの

* [ファイルのパーミッション設定、ディレクトリは要注意](http://wordpress.honobono-life.info/lin-base/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E8%A8%AD%E5%AE%9A%E3%80%81%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AF/)

* [Execute vs Read bit. How do directory permissions in Linux work?](https://unix.stackexchange.com/questions/21251/execute-vs-read-bit-how-do-directory-permissions-in-linux-work)