2016年9月13日火曜日

MySQL 8.0.0で追加されたROLEの仕組み

正直なんの情報もなくてすごく困ったんだけど、何故か自分のブログ記事に助けられた。

日々の覚書: MariaDB 10.0.5で実装されたROLEを試す


ほぼこの時と同じ。MariaDB 10.0の時はロールを割り当てるユーザーが存在しなくても割り当てられたけど、MySQL 8.0は先にCREATE USERしておかないと割り当てられなかったことくらい。

mysql80> CREATE ROLE sys_select;
Query OK, 0 rows affected (0.00 sec)

mysql80> GRANT SELECT ON mysql.* TO sys_select;
Query OK, 0 rows affected (0.00 sec)

mysql80> SELECT * FROM mysql.user WHERE user = 'sys_select'\G
*************************** 1. row ***************************
                  Host: %
                  User: sys_select
           Select_priv: N
           Insert_priv: N
           Update_priv: N
           Delete_priv: N
           Create_priv: N
             Drop_priv: N
           Reload_priv: N
         Shutdown_priv: N
          Process_priv: N
             File_priv: N
            Grant_priv: N
       References_priv: N
            Index_priv: N
            Alter_priv: N
          Show_db_priv: N
            Super_priv: N
 Create_tmp_table_priv: N
      Lock_tables_priv: N
          Execute_priv: N
       Repl_slave_priv: N
      Repl_client_priv: N
      Create_view_priv: N
        Show_view_priv: N
   Create_routine_priv: N
    Alter_routine_priv: N
      Create_user_priv: N
            Event_priv: N
          Trigger_priv: N
Create_tablespace_priv: N
              ssl_type:
            ssl_cipher:
           x509_issuer:
          x509_subject:
         max_questions: 0
           max_updates: 0
       max_connections: 0
  max_user_connections: 0
                plugin: mysql_native_password
 authentication_string:
      password_expired: Y
 password_last_changed: 2016-09-05 11:55:04
     password_lifetime: NULL
        account_locked: Y
      Create_role_priv: N
        Drop_role_priv: N
1 row in set (0.00 sec)

MariaDB 10.0では is_role なるカラムでロールかどうかを識別していたけど、MySQL 8.0にはそれっぽいカラムはなさげ。account_lockedで代用している気配。


mysql80> GRANT sys_select TO yoku0825;
Query OK, 0 rows affected (0.00 sec)

mysql80> SELECT * FROM default_roles;
Empty set (0.00 sec)

mysql80> SELECT * FROM role_edges;
+-----------+------------+---------+----------+-------------------+
| FROM_HOST | FROM_USER  | TO_HOST | TO_USER  | WITH_ADMIN_OPTION |
+-----------+------------+---------+----------+-------------------+
| %         | sys_select | %       | yoku0825 | N                 |
+-----------+------------+---------+----------+-------------------+
1 row in set (0.00 sec)

ロールのマッピングはmysql.role_edgesテーブルに記録される。


$ mysql80 -uyoku0825

mysql80> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| yoku0825@%     |
+----------------+
1 row in set (0.00 sec)

mysql80> SELECT current_role();
+----------------+
| current_role() |
+----------------+
| NONE           |
+----------------+
1 row in set (0.00 sec)

mysql80> SHOW GRANTS;
+------------------------------------------+
| Grants for yoku0825@%                    |
+------------------------------------------+
| GRANT USAGE ON *.* TO `yoku0825`@`%`     |
| GRANT `sys_select`@`%` TO `yoku0825`@`%` |
+------------------------------------------+
2 rows in set (0.00 sec)

mysql80> SELECT user, host FROM mysql.user;
ERROR 1142 (42000): SELECT command denied to user 'yoku0825'@'localhost' for table 'user'

mysql80> SET ROLE sys_select;
Query OK, 0 rows affected (0.00 sec)

mysql80> SELECT current_role();
+------------------+
| current_role()   |
+------------------+
| `sys_select`@`%` |
+------------------+
1 row in set (0.00 sec)

mysql80> SELECT user, host FROM mysql.user;
+------------+-----------+
| user       | host      |
+------------+-----------+
| sys_select | %         |
| yoku0825   | %         |
| mysql.sys  | localhost |
| root       | localhost |
+------------+-----------+
4 rows in set (0.00 sec)

まるっきり MariaDBのとき と同じで助かるというか捗るというか。

MariaDBは10.1からとされていた(10.1使ってないから本当にされたのか知らない。。)デフォルトロールも実装されている。
勘に任せてALTER USERしてみた。


mysql80> ALTER USER yoku0825 DEFAULT ROLE sys_select;
Query OK, 0 rows affected (0.01 sec)

mysql80> SELECT * FROM default_roles;
+------+----------+-------------------+-------------------+
| HOST | USER     | DEFAULT_ROLE_HOST | DEFAULT_ROLE_USER |
+------+----------+-------------------+-------------------+
| %    | yoku0825 | %                 | sys_select        |
+------+----------+-------------------+-------------------+
1 row in set (0.00 sec)

$ mysql80 -uyoku0825
mysql80> SELECT current_role();
+------------------+
| current_role()   |
+------------------+
| `sys_select`@`%` |
+------------------+
1 row in set (0.00 sec)

なるほど大正解。しかしこれ、ユーザーアカウントとROLEを区別してないってことは、もしかして逆もできるのかしら。


mysql80> GRANT yoku0825 TO sys_select;
Query OK, 0 rows affected (0.01 sec)

mysql80> SELECT * FROM role_edges;
+-----------+------------+---------+------------+-------------------+
| FROM_HOST | FROM_USER  | TO_HOST | TO_USER    | WITH_ADMIN_OPTION |
+-----------+------------+---------+------------+-------------------+
| %         | sys_select | %       | yoku0825   | N                 |
| %         | yoku0825   | %       | sys_select | N                 |
+-----------+------------+---------+------------+-------------------+
2 rows in set (0.00 sec)

( д ) ゚ ゚ やっぱりできた
アカウント同士でも試してみたけど


mysql80> GRANT root@localhost TO yoku0825;
Query OK, 0 rows affected (0.00 sec)

$ mysql80 -uyoku0825
mysql80> SET ROLE root@localhost;
Query OK, 0 rows affected (0.00 sec)

mysql80> SET GLOBAL innodb_buffer_pool_dump_now= 1;
Query OK, 0 rows affected (0.00 sec)

おおおおおお…ユーザーとロールは区別した方がいいと思うんだけど、設定次第でこうも出来ると…。
ロール機能自体はウェルカムですねべんり。

0 件のコメント :

コメントを投稿