GA

2026/04/30

MySQL 5.7とそれ以前のpartial_revokesもどき

TL;DR

  • さっさとMySQL 8.0とそれ以降にアップグレードして partial_revokes を使う
  • 過去にはこんなテクニックがあったんだよという記憶だけ

日々の覚書: GRANTでデータベース名にワイルドカードを指定することとpartial revokesと でもちょっと書いていた、「GRANTでデータベース名にワイルドカード」を一捻りしたバージョン。

「一般ユーザーに(データベース名は動的に変わる、などの理由で)任意のスキーマに対するCREATE, DROPその他の権限を割り当てたいけど mysqlperformance_schemasys だけはダメ、グローバルGRANTはやりたくない」という、まさに partial_revokes が欲しい状況を5.7で何とかしたい。

mysql (とその他システム) スキーマには明示的な *_priv = 'N' を割り当てて、それ以外の % にはスキーマレベルでのALLをGRANTする。

mysql57 8> SELECT @@version;
+------------+
| @@version  |
+------------+
| 5.7.44-log |
+------------+
1 row in set (0.00 sec)

mysql57 8> CREATE USER yoku0825;
Query OK, 0 rows affected (0.00 sec)

mysql57 8> GRANT ALL ON `%`.* TO yoku0825 WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)

mysql57 8> INSERT INTO mysql.db (host, db, user) VALUES ('%', 'mysql', 'yoku0825'), ('%', 'sys', 'yoku0825'), ('%', 'performance_schema', 'yoku0825');   -- *_privカラムのデフォルトは 'N'
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql57 8> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

「明示的な *_priv = 'N' の割り当て」はGRANTステートメントではできない ( GRANT USAGE ON mysql.* TO yoku0825 とかやっても mysql.db に全部 ‘N’ の行ができたりはしない)っぽいので、INSERTステートメントとFLUSH PRIVILEGESで表現する。

と、

mysql57 9> SHOW GRANTS;  -- 自分がmysqlスキーマとかに権限がないことが見えないのが嫌だといえば嫌だが (partial_revokesは見える)
+-------------------------------------------------------------------+
| Grants for yoku0825@%                                             |
+-------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'yoku0825'@'%'                              |
| GRANT ALL PRIVILEGES ON `%`.* TO 'yoku0825'@'%' WITH GRANT OPTION |
+-------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql57 9> SELECT COUNT(*) FROM mysql.user;
ERROR 1142 (42000): SELECT command denied to user 'yoku0825'@'localhost' for table 'user'

mysql57 9> SHOW TABLES FROM sys;
ERROR 1044 (42000): Access denied for user 'yoku0825'@'%' to database 'sys'

mysql57 9> CREATE DATABASE yoku0825;
Query OK, 1 row affected (0.00 sec)

mysql57 9> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| d1                 |
| world              |
| yoku0825           |
+--------------------+
4 rows in set (0.00 sec)

だいたいやりたいことができそう。
partial_revokesを有効にするとスキーマ名ワイルドカードが効かなくなるからできなくなるけど、そもそもつなぎのためのテクニックだろうからそれはそれで(アップグレードする時に忘れずに処置すれば)大丈夫なはず。

0 件のコメント :

コメントを投稿