18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MySQL権限一覧をきれいに作る方法と、rootユーザー以外で棚卸しする方法

Last updated at Posted at 2016-07-15

information_schemaを利用した権限リスト作成

MySQLで、存在するユーザーと権限の一覧が欲しいとき、
rootユーザーで以下のコマンドを実行すると簡単に確認できます。

シンプルなクエリ

SELECT * FROM information_schema.user_privileges;   -- グローバルレベル権限のリスト
SELECT * FROM information_schema.schema_privileges; -- データベースレベル権限のリスト
SELECT * FROM information_schema.table_privileges;  -- テーブルレベル権限のリスト
SELECT * FROM information_schema.column_privileges; -- カラムレベル権限のリスト

ユーザーごとに権限を並べて表示したいなら、

-- グローバルレベル権限のリスト
SELECT
  grantee user, GROUP_CONCAT(privilege_type ORDER BY privilege_type) privileges
FROM
  information_schema.user_privileges
GROUP BY
  grantee;

-- データベースレベル権限のリスト
SELECT
  grantee user, table_schema db, GROUP_CONCAT(privilege_type ORDER BY privilege_type) privileges
FROM
  information_schema.schema_privileges
GROUP BY
  grantee, table_schema;

-- テーブルレベル権限のリスト
SELECT
  grantee user, table_schema db, table_name tbl, GROUP_CONCAT(privilege_type ORDER BY privilege_type) privileges
FROM
  information_schema.table_privileges
GROUP BY
  grantee, table_schema, table_name;

-- カラムレベル権限のリスト
SELECT
  grantee user, table_schema db, table_name tbl, column_name clmn, GROUP_CONCAT(privilege_type ORDER BY privilege_type) privileges
FROM
  information_schema.column_privileges
GROUP BY
  grantee, table_schema, table_name, column_name;

-- GROUP_CONCAT関数はANSI SQL非標準

一括でリストに出力するなら

(SELECT grantee user, '*'          db, '*'        tbl, '*'         clmn, GROUP_CONCAT(privilege_type ORDER BY privilege_type) privileges FROM information_schema.user_privileges   GROUP BY grantee)
UNION
(SELECT grantee user, table_schema db, '*'        tbl, '*'         clmn, GROUP_CONCAT(privilege_type ORDER BY privilege_type) privileges FROM information_schema.schema_privileges GROUP BY grantee, table_schema)
UNION
(SELECT grantee user, table_schema db, table_name tbl, '*'         clmn, GROUP_CONCAT(privilege_type ORDER BY privilege_type) privileges FROM information_schema.table_privileges  GROUP BY grantee, table_schema, table_name)
UNION
(SELECT grantee user, table_schema db, table_name tbl, column_name clmn, GROUP_CONCAT(privilege_type ORDER BY privilege_type) privileges FROM information_schema.column_privileges GROUP BY grantee, table_schema, table_name, column_name)
ORDER BY user, db, tbl, clmn;

-- 結果例
+----------------+-------+------+------------------+---------------+
| user           | db    | tbl  | clmn             | privileges    |
+----------------+-------+------+------------------+---------------+
| 'testuser'@'%' | *     | *    | *                | FILE,PROCESS  |
| 'testuser'@'%' | mysql | *    | *                | SELECT,INSERT |
| 'testuser'@'%' | mysql | user | *                | DELETE        |
| 'testuser'@'%' | mysql | user | password_expired | UPDATE        |
+----------------+-------+------+------------------+---------------+

percona-tool-kitpt-show-grantsを使っても簡単に権限リストが出力できるようです。

root以外での実行

上記はrootで実行しましたが、内部統制の兼ね合いなどで、
できれば最小権限で動かしたいところです。

mysqlデータベースにデータベースレベルのSELECT権限があれば、
information_schemaのユーザー権限系テーブルで全ユーザーの権限が表示可能です。
上記の権限がないと、表示はSHOW GRANTS相当だけになります。

-- 棚卸し用ユーザー
-- テーブルレベル(mysql.userなど)では効果がなく、データベースレベルが必要
GRANT SELECT ON mysql.* to listmaker; 

ただし、このユーザーはmysql.userテーブルが参照できてしまうので、
全ユーザーのパスワードハッシュが見えてしまいます。
より細かく管理するなら、プログラムで上記のコマンドを実行させるといった方法で、
このユーザー自体の管理にも気をつける必要があります。

その他検討した方法

mysql.userにカラムレベルで権限をつける。

mysql.userにカラム単位で権限をつけていき、
パスワードハッシュは除外することを検討しました。
mysql.user, mysql.db, mysql.tables_priv, mysql.columns_privをSELECTする方法です。
ただ、information_schemaを利用したほうがリスト作成が簡単なのと、
カラム単位での権限制御は避けたかったので除外しました。

information_schemaに対してViewを作成する

Viewはdefinerによって実行権限が決まるので、definerをrootにすれば、
Viewを見るユーザーがroot相当でinformation_schemaを参照できそうだったので試しました。

CREATE SQL SECURITY DEFINER VIEW sampledb.db_privileges AS
  SELECT grantee, table_schema, priviledge_type
  FROM information_schema.schema_privileges; -- Viewを作る

残念ながら、実行ユーザー自身の権限しか閲覧できませんでした。
information_schemaは仮想的なテーブルなので、
実行ユーザーの権限でテーブルの中身があらかじめ動的に作成されるためと思われます。

18
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?