MySQLにSHOW GRANTS
は、現在のユーザーの権限が表示されます。
ルートとしてログインし、すべてのユーザーの権限を表示する方法はありますか?
MySQLにSHOW GRANTS
は、現在のユーザーの権限が表示されます。
ルートとしてログインし、すべてのユーザーの権限を表示する方法はありますか?
回答:
何も組み込まれていません。ただし、次の2つのオプションがあります。
common_schema
のsql_show_grantsビューを使用します。たとえば、次のクエリを実行できます。
SELECT sql_grants FROM common_schema.sql_show_grants;
または、次のように特定のユーザーを照会できます。
SELECT sql_grants FROM common_schema.sql_show_grants WHERE user='app';
インストールするcommon_schema
には、こちらの手順に従ってください。
免責事項:私はこのツールの著者です。
pt-show-grants
たとえば、Percona Toolkitを使用します。
pt-show-grants --host localhost --user root --ask-pass
どちらの場合でも、GRANT
コマンドまたはREVOKE
(反対の)コマンドを要求できます。
前者の場合、スキーマをインストールする必要があり、後者の場合、PERLスクリプトと依存関係をインストールする必要があります。
information_schema.user_privileges
ますか?
select * from information_schema.user_privileges;
編集:
Shlomi Noachが述べたように:
データベース固有、テーブル固有、列固有、ルーチン固有の特権はリストしません。そのため、mydb。*へのGRANT SELECT ON mydb。*付与は、information_schema.user_privilegesに表示されません。上記のcommon_schemaソリューションは、user_privilegesおよびその他のテーブルのデータを集約して全体像を示します。
information_schema.user_privileges
などのユーザーレベルの権限のみをリストします。またSUPER
、RELOAD
などのオールラウンドDML付与もリストしますSELECT
。データベース固有、テーブル固有、列固有、ルーチン固有の特権はリストしません。そのため、助成金GRANT SELECT ON mydb.* TO myuser@localhost
はに表示されませんinformation_schema.user_privileges
。上記のcommon_schema
ソリューションはuser_privileges
、他のテーブルからのデータを集約して、全体像を示します。
このLinuxシェルフラグメントは、すべてのMySQLユーザーをループし、それぞれに対してSHOW GRANTSを実行します。
mysql --silent --skip-column-names --execute "select concat('\'',User,'\'@\'',Host,'\'') as User from mysql.user" | sort | \
while read u
do echo "-- $u"; mysql --silent --skip-column-names --execute "show grants for $u" | sed 's/$/;/'
done
パスワードなしでMySQLに接続できる場合に最適です。
出力は、MySQLシェルで実行できるようにフォーマットされています。注意:出力には、MySQLルートユーザーのアクセス許可とパスワードも含まれています!MySQLのrootユーザーを変更したくない場合は、これらの行を削除してください。
mysql --defaults-file=/auth/root-mysql.cnf --batch --skip-column-names --execute "SELECT User, Host from mysql.user" | while read user host; do echo "SHOW GRANTS FOR '${user}'@'${host}';"; done | mysql --defaults-file=/auth/root-mysql.cnf --batch | sed 's/^Grants for/-- Grants for/'
Unix bashの1つのライナー(他のユーザーで使用-uroot
する-u$USER_NAME
ために変更)(バックティックのため):
mysql -uroot -p -sNe"`mysql -uroot -p -se"SELECT CONCAT('SHOW GRANTS FOR \'',user,'\'@\'',host,'\';') FROM mysql.user;"`"
または、バックティックなしで、パスワードをインラインで使用します(コマンドの前のスペースは、UbuntuのBash履歴から除外します)。
mysql -uroot -p"$PASSWORD" -sNe"$(mysql -uroot -p"$PASSWORD" -se"SELECT CONCAT('SHOW GRANTS FOR \'',user,'\'@\'',host,'\';') FROM mysql.user;")"
Windowsの場合:
mysql -uroot -p -se"SELECT CONCAT('SHOW GRANTS FOR \'',user,'\'@\'',host,'\';') FROM mysql.user;" > grants.sql
mysql -uroot -p < grants.sql
del grants.sql
次のSELECTステートメントをエラーなしで実行できる場合:
/* User-Specific Grants */ SELECT * FROM mysql.user;
/* Database-Specific Grants */ SELECT * FROM mysql.db;
/* Table-Specific Grants */ SELECT * FROM mysql.tables_priv;
/* Column-Specific Grants */ SELECT * FROM mysql.columns_priv;
その後、.sql構文で記述された次のコード(下記)を自由に使用してください。
このクエリは、既存のすべてのアクセス許可に対してGRANTステートメントを再構築するために設計されました(データベースの移行中に頻繁に維持するため)。ユーザーとパスワードのリンクなど、対処すべき問題がいくつかありますが、パスワードを頻繁に更新するため、このプロジェクトの範囲外でした。
/* Get All Grants/Permissions for MySQL Instance */
/* [Database.Table.Column]-Specific Grants */
SELECT
CONCAT("`",gcl.Db,"`") AS 'Database(s) Affected',
CONCAT("`",gcl.Table_name,"`") AS 'Table(s) Affected',
gcl.User AS 'User-Account(s) Affected',
IF(gcl.Host='%','ALL',gcl.Host) AS 'Remote-IP(s) Affected',
CONCAT("GRANT ",UPPER(gcl.Column_priv)," (",GROUP_CONCAT(gcl.Column_name),") ",
"ON `",gcl.Db,"`.`",gcl.Table_name,"` ",
"TO '",gcl.User,"'@'",gcl.Host,"';") AS 'GRANT Statement (Reconstructed)'
FROM mysql.columns_priv gcl
GROUP BY CONCAT(gcl.Db,gcl.Table_name,gcl.User,gcl.Host)
/* SELECT * FROM mysql.columns_priv */
UNION
/* [Database.Table]-Specific Grants */
SELECT
CONCAT("`",gtb.Db,"`") AS 'Database(s) Affected',
CONCAT("`",gtb.Table_name,"`") AS 'Table(s) Affected',
gtb.User AS 'User-Account(s) Affected',
IF(gtb.Host='%','ALL',gtb.Host) AS 'Remote-IP(s) Affected',
CONCAT(
"GRANT ",UPPER(gtb.Table_priv)," ",
"ON `",gtb.Db,"`.`",gtb.Table_name,"` ",
"TO '",gtb.User,"'@'",gtb.Host,"';"
) AS 'GRANT Statement (Reconstructed)'
FROM mysql.tables_priv gtb
WHERE gtb.Table_priv!=''
/* SELECT * FROM mysql.tables_priv */
UNION
/* Database-Specific Grants */
SELECT
CONCAT("`",gdb.Db,"`") AS 'Database(s) Affected',
"ALL" AS 'Table(s) Affected',
gdb.User AS 'User-Account(s) Affected',
IF(gdb.Host='%','ALL',gdb.Host) AS 'Remote-IP(s) Affected',
CONCAT(
'GRANT ',
CONCAT_WS(',',
IF(gdb.Select_priv='Y','SELECT',NULL),
IF(gdb.Insert_priv='Y','INSERT',NULL),
IF(gdb.Update_priv='Y','UPDATE',NULL),
IF(gdb.Delete_priv='Y','DELETE',NULL),
IF(gdb.Create_priv='Y','CREATE',NULL),
IF(gdb.Drop_priv='Y','DROP',NULL),
IF(gdb.Grant_priv='Y','GRANT',NULL),
IF(gdb.References_priv='Y','REFERENCES',NULL),
IF(gdb.Index_priv='Y','INDEX',NULL),
IF(gdb.Alter_priv='Y','ALTER',NULL),
IF(gdb.Create_tmp_table_priv='Y','CREATE TEMPORARY TABLES',NULL),
IF(gdb.Lock_tables_priv='Y','LOCK TABLES',NULL),
IF(gdb.Create_view_priv='Y','CREATE VIEW',NULL),
IF(gdb.Show_view_priv='Y','SHOW VIEW',NULL),
IF(gdb.Create_routine_priv='Y','CREATE ROUTINE',NULL),
IF(gdb.Alter_routine_priv='Y','ALTER ROUTINE',NULL),
IF(gdb.Execute_priv='Y','EXECUTE',NULL),
IF(gdb.Event_priv='Y','EVENT',NULL),
IF(gdb.Trigger_priv='Y','TRIGGER',NULL)
),
" ON `",gdb.Db,"`.* TO '",gdb.User,"'@'",gdb.Host,"';"
) AS 'GRANT Statement (Reconstructed)'
FROM mysql.db gdb
WHERE gdb.Db != ''
/* SELECT * FROM mysql.db */
UNION
/* User-Specific Grants */
SELECT
"ALL" AS 'Database(s) Affected',
"ALL" AS 'Table(s) Affected',
gus.User AS 'User-Account(s) Affected',
IF(gus.Host='%','ALL',gus.Host) AS 'Remote-IP(s) Affected',
CONCAT(
"GRANT ",
IF((gus.Select_priv='N')&(gus.Insert_priv='N')&(gus.Update_priv='N')&(gus.Delete_priv='N')&(gus.Create_priv='N')&(gus.Drop_priv='N')&(gus.Reload_priv='N')&(gus.Shutdown_priv='N')&(gus.Process_priv='N')&(gus.File_priv='N')&(gus.References_priv='N')&(gus.Index_priv='N')&(gus.Alter_priv='N')&(gus.Show_db_priv='N')&(gus.Super_priv='N')&(gus.Create_tmp_table_priv='N')&(gus.Lock_tables_priv='N')&(gus.Execute_priv='N')&(gus.Repl_slave_priv='N')&(gus.Repl_client_priv='N')&(gus.Create_view_priv='N')&(gus.Show_view_priv='N')&(gus.Create_routine_priv='N')&(gus.Alter_routine_priv='N')&(gus.Create_user_priv='N')&(gus.Event_priv='N')&(gus.Trigger_priv='N')&(gus.Create_tablespace_priv='N')&(gus.Grant_priv='N'),
"USAGE",
IF((gus.Select_priv='Y')&(gus.Insert_priv='Y')&(gus.Update_priv='Y')&(gus.Delete_priv='Y')&(gus.Create_priv='Y')&(gus.Drop_priv='Y')&(gus.Reload_priv='Y')&(gus.Shutdown_priv='Y')&(gus.Process_priv='Y')&(gus.File_priv='Y')&(gus.References_priv='Y')&(gus.Index_priv='Y')&(gus.Alter_priv='Y')&(gus.Show_db_priv='Y')&(gus.Super_priv='Y')&(gus.Create_tmp_table_priv='Y')&(gus.Lock_tables_priv='Y')&(gus.Execute_priv='Y')&(gus.Repl_slave_priv='Y')&(gus.Repl_client_priv='Y')&(gus.Create_view_priv='Y')&(gus.Show_view_priv='Y')&(gus.Create_routine_priv='Y')&(gus.Alter_routine_priv='Y')&(gus.Create_user_priv='Y')&(gus.Event_priv='Y')&(gus.Trigger_priv='Y')&(gus.Create_tablespace_priv='Y')&(gus.Grant_priv='Y'),
"ALL PRIVILEGES",
CONCAT_WS(',',
IF(gus.Select_priv='Y','SELECT',NULL),
IF(gus.Insert_priv='Y','INSERT',NULL),
IF(gus.Update_priv='Y','UPDATE',NULL),
IF(gus.Delete_priv='Y','DELETE',NULL),
IF(gus.Create_priv='Y','CREATE',NULL),
IF(gus.Drop_priv='Y','DROP',NULL),
IF(gus.Reload_priv='Y','RELOAD',NULL),
IF(gus.Shutdown_priv='Y','SHUTDOWN',NULL),
IF(gus.Process_priv='Y','PROCESS',NULL),
IF(gus.File_priv='Y','FILE',NULL),
IF(gus.References_priv='Y','REFERENCES',NULL),
IF(gus.Index_priv='Y','INDEX',NULL),
IF(gus.Alter_priv='Y','ALTER',NULL),
IF(gus.Show_db_priv='Y','SHOW DATABASES',NULL),
IF(gus.Super_priv='Y','SUPER',NULL),
IF(gus.Create_tmp_table_priv='Y','CREATE TEMPORARY TABLES',NULL),
IF(gus.Lock_tables_priv='Y','LOCK TABLES',NULL),
IF(gus.Execute_priv='Y','EXECUTE',NULL),
IF(gus.Repl_slave_priv='Y','REPLICATION SLAVE',NULL),
IF(gus.Repl_client_priv='Y','REPLICATION CLIENT',NULL),
IF(gus.Create_view_priv='Y','CREATE VIEW',NULL),
IF(gus.Show_view_priv='Y','SHOW VIEW',NULL),
IF(gus.Create_routine_priv='Y','CREATE ROUTINE',NULL),
IF(gus.Alter_routine_priv='Y','ALTER ROUTINE',NULL),
IF(gus.Create_user_priv='Y','CREATE USER',NULL),
IF(gus.Event_priv='Y','EVENT',NULL),
IF(gus.Trigger_priv='Y','TRIGGER',NULL),
IF(gus.Create_tablespace_priv='Y','CREATE TABLESPACE',NULL)
)
)
),
" ON *.* TO '",gus.User,"'@'",gus.Host,"' REQUIRE ",
CASE gus.ssl_type
WHEN 'ANY' THEN
"SSL "
WHEN 'X509' THEN
"X509 "
WHEN 'SPECIFIED' THEN
CONCAT_WS("AND ",
IF((LENGTH(gus.ssl_cipher)>0),CONCAT("CIPHER '",CONVERT(gus.ssl_cipher USING utf8),"' "),NULL),
IF((LENGTH(gus.x509_issuer)>0),CONCAT("ISSUER '",CONVERT(gus.ssl_cipher USING utf8),"' "),NULL),
IF((LENGTH(gus.x509_subject)>0),CONCAT("SUBJECT '",CONVERT(gus.ssl_cipher USING utf8),"' "),NULL)
)
ELSE "NONE "
END,
"WITH ",
IF(gus.Grant_priv='Y',"GRANT OPTION ",""),
"MAX_QUERIES_PER_HOUR ",gus.max_questions," ",
"MAX_CONNECTIONS_PER_HOUR ",gus.max_connections," ",
"MAX_UPDATES_PER_HOUR ",gus.max_updates," ",
"MAX_USER_CONNECTIONS ",gus.max_user_connections,
";"
) AS 'GRANT Statement (Reconstructed)'
FROM mysql.user gus
WHERE gus.Password != ''
/* SELECT * FROM mysql.user gus */
/* TODO: */
/* SELECT * FROM mysql.host ghs */
/* SELECT * FROM mysql.procs_priv gpr */
質問や懸念事項に回答/確認してください
これにより、より良いビューが得られます...
mysql> select Host, Db, User, Insert_priv, Update_priv, Delete_priv, Create_tmp_table_priv, Alter_priv from mysql.db limit 1;
+------+------+------+-------------+-------------+-------------+-----------------------+------------+
| Host | Db | User | Insert_priv | Update_priv | Delete_priv | Create_tmp_table_priv | Alter_priv |
+------+------+------+-------------+-------------+-------------+-----------------------+------------+
| % | test | | Y | Y | Y | Y | Y |
+------+------+------+-------------+-------------+-------------+-----------------------+------------+
1 row in set (0.00 sec)
この回答で述べたように、次の一連のコマンドを実行して、すべてのユーザーのデータベース固有、テーブル固有、列固有、およびルーチン固有の特権をリストできます。これは、MySQLコマンドプロンプトではなく、シェルから実行する必要があることに注意してください。
mysql -u root --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql -u root --skip-column-names -A
このアプローチの利点は、追加のソフトウェアをインストールする必要がないことです。
データベースを頻繁に管理している場合は、厳しい権限を保持したいでしょう。ストアドプロシージャを使用して、チェックをすばやく実行できます。この例はmariadbで機能しますが、標準のmysqlバージョンを使用するには調整が必要な場合があります。
Mansur Aliからの回答を使用して、列を少し並べ替え、出力を整理するためにいくつかの順序を追加します。
ルートログインの使用:
USE mysql;
DELIMITER //
CREATE PROCEDURE ShowPrivs(start, end)
BEGIN
SELECT Db, User, Host, Insert_priv, Update_priv, Delete_priv, Create_tmp_table_priv, Alter_priv FROM mysql.db order by Db, Host, User ASC;
END;
//
DELIMITER ;
代わりにmysql.userテーブルをチェックするように手順を変更できます。
ルートログインを使用する使用法:
USE mysql;
CALL ShowPrivs();
Ubuntuでmysqlワークベンチを使用して、この回答の作成手順の一部を実行しました。
余談ですが、ここでは少し話題を外しますが、不明なホストまたはユーザーを表示する手順もあります。不明なホストの例:
USE mysql;
DELIMITER //
CREATE PROCEDURE `ShowUnknownHosts`(IN Hosts_String VARCHAR(200))
BEGIN
SELECT user,host FROM user
WHERE FIND_IN_SET(host, Hosts_String) = 0;
END//
DELIMITER ;
使用上の注意:ホストの文字列をコンマで区切って指定し、 ''の1つのセットのみが使用されるようにします。
CALL ShowUnknownHosts('knownhost1,knownhost2');
プロシージャに別のパラメータを含めることで列変数を作成し、ShowUnknownHosts(user、 'user1、user2');で呼び出すこともできます。例えば。
ERROR 1146 (42S02): Table 'common_schema.sql_show_grants' doesn't exist