rootからGRANT ALL したユーザーが、他ユーザーに対して、GRANT ALLできない

## これは何

SQLの権限周りでハマった際に助けてもらったメモです。
MySQL5.6のお話です。

rootからGRANT ALL したユーザーが、他ユーザーに対して、GRANT ALLできませんでした。
rootからWITH GRANT OPTIONを付与したユーザーは、他ユーザーに対してGRANT ALLできることがわかりました。

## 被権限付与ユーザーが、別ユーザーに権限を付与できない

あるDBユーザーに全てのDB・テーブルに対して、権限を与えようと、以下のコマンドを打ちました。

```
mysql> GRANT ALL ON *.* TO DBユーザー名;
```

しかし失敗します。

下記参考から考えると、WITH GRANT OPTIONが抜けていたせいかと思います。
grant allでは権限付与関連の権限は付与されないのかもしれません。

## コマンドで考えてみる

```sql
【rootユーザー】 
【GRANT ALL ON *.* TO】の場合

mysql> CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
mysql> GRANT ALL ON *.* TO 'newuser'@'localhost';
mysql> FLUSH PRIVILEGES;
mysql> show grants for 'newuser'@'localhost';
+-------------------------------------------------------------------------------------------------------------------------+
| Grants for newuser@localhost                                                                                            |
+-------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'newuser'@'localhost' IDENTIFIED BY PASSWORD '***' |
+-------------------------------------------------------------------------------------------------------------------------+
```

```sql
【rootユーザー】 
【GRANT ALL ON *.* TO】と　【WITH GRANT OPTION】の場合

mysql> CREATE USER 'newuser2'@'localhost' IDENTIFIED BY 'password';
mysql> GRANT ALL ON *.* TO 'newuser2'@'localhost' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
mysql> show grants for 'newuser2'@'localhost';
+--------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for newuser2@localhost                                                                                                              |
+--------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'newuser2'@'localhost' IDENTIFIED BY PASSWORD '***' WITH GRANT OPTION |
+--------------------------------------------------------------------------------------------------------------------------------------------+
```

```sql
【rootユーザー】 
【権限付与用のユーザー作成】

mysql> CREATE USER 'newuser3'@'localhost' IDENTIFIED BY 'password';
```

```sql
【newuserユーザー】 
【newuser3に権限付与する】

mysql> GRANT ALL ON *.* TO 'newuser3'@'localhost';
ERROR 1045 (28000): Access denied for user 'newuser'@'localhost' (using password: YES)
```

```sql
【newuser2ユーザー】 
【newuser3に権限付与する】

mysql> GRANT ALL ON *.* TO 'newuser3'@'localhost';
Query OK, 0 rows affected (0.01 sec)
```

このように、rootからWITH GRANT OPTIONを付与したユーザーは、他ユーザーに対してGRANT ALL ONできることがわかりました。

## WITH GRANT OPTIONについて

```
【引用】
WITH 句は、次のいくつかの目的に使用されます。

ユーザーがほかのユーザーに権限を付与できるようにするため

ユーザーに対するリソース制限を指定するため

ユーザーがサーバーへのセキュア接続を使用する必要があるかどうか、およびその方法を指定するため

WITH GRANT OPTION 句は、ユーザーが、そのユーザーの持つ指定された権限レベルにある任意の権限を
ほかのユーザーに与えることができるようにします。
異なる権限を持つ 2 人のユーザーが権限を組み合わせることができる可能性があるため、
GRANT OPTION 権限を与える相手には十分に注意してください。

自分が保持していない権限を別のユーザーに付与することはできません。
GRANT OPTION 権限を使用して割り当てることができるのは、自分が保持している権限だけです。

あるユーザーに特定の権限レベルにある GRANT OPTION 権限を付与すると、
そのユーザーがそのレベルに保持している (または、将来与えられる可能性のある) すべての権限も、
そのユーザーからほかのユーザーに付与される場合があることに注意してください。

あるユーザーに、データベースに対する INSERT 権限を付与するとします。
次に、そのデータベースに対する SELECT 権限を付与し、WITH GRANT OPTION を指定した場合、
そのユーザーはほかのユーザーに SELECT 権限だけでなく、INSERT 権限も与えることができます。
そのあと、そのユーザーにデータベースに対する UPDATE 権限を付与すると、そのユーザーは INSERT、SELECT、および UPDATE を付与できます。
```

## 総括

ここまで書いてきてなんですが、改めて文章化すると、そりゃそうか…と思いました。
コマンドの意味をしっかり理解して打っていれば、分かることですね…
自分はここまで書いてやっと、なるほど〜と思いました。（）

## 参考

```
https://dev.mysql.com/doc/refman/5.6/ja/grant.html
https://qiita.com/PallCreaker/items/0b02c5f42be5d1a14adb
```