2017-02-24 3 views
1

3つの異なるmySQLサーバー(5.0.51a-24 + lenny5-log、5.5.54- 0 + deb7u2と5.6.35)に数百のデータベースと何百人ものユーザーがいる。MySQL:既存のデータベースにアクセスできないすべてのユーザーを一覧表示する方法

私は、サーバー上の既存のデータベースにアクセスできないユーザーの一覧を返すクエリを探しています。

mysql.userを見ると、サーバー上のすべてのユーザーを見ることができます。ここまでは順調ですね。さて、mysql.dbを見ると、データベースとの関係を見ることができます。だから私は結果を得ることは、のような単純なものができることを考え出し:データベースが削除された関係が更新されないただしので、

SELECT * 
    FROM mysql.`user` tblusers 
WHERE NOT EXISTS (SELECT * 
        FROM mysql.`db` tbldbrelation 
        WHERE tblusers.User = tbldbrelation.User) 

、(私の知る限り)、一人でこれら二つの事を見て、私はシステム、サービス、rootユーザーなどしか手に入れません。私は別のアプローチが必要です。明らかに、show databases;は現在サーバー上のすべてのデータベースを返します。しかし、どのようにこれを考慮に入れることができますか?そうすれば、既存の特定のデータベースにアクセスできないユーザーのリストが表示されます。

+0

インストール済みの完全なMySQLサーバのバージョン –

+0

'5.0.51a-24 + lenny5-log'、 、' 5.5.54-0 + deb7u2'、 '5.6.35'の3つの異なるサーバにそれぞれ提供してください – TomRA

答えて

1

Percona Toolkit's pt-show-grantsを使用して、すべてのユーザーとその特権をダンプします。次に、USAGE以外の特権を持たないユーザーを探します。

たとえば、ローカルMySQLインスタンスにdummyという名前のダミーユーザーを作成しましたが、ユーザーに任意のデータベースに対する権限を付与しませんでした。

PT-ショー助成金の出力:

$ pt-show-grants h=127.0.0.1 
-- Grants dumped by pt-show-grants 
-- Dumped from server 127.0.0.1 via TCP/IP, MySQL 8.0.0-dmr at 2017-02-25 18:35:54 
-- Grants for 'dummy'@'127.0.0.1' 
GRANT USAGE ON *.* TO `dummy`@`127.0.0.1`; 
-- Grants for 'mysql.sys'@'localhost' 
GRANT SELECT ON `sys`.`sys_config` TO `mysql.sys`@`localhost`; 
GRANT TRIGGER ON `sys`.* TO `mysql.sys`@`localhost`; 
GRANT USAGE ON *.* TO `mysql.sys`@`localhost`; 
-- Grants for 'root'@'localhost' 
GRANT ALL PRIVILEGES ON *.* TO `root`@`localhost` WITH GRANT OPTION; 
GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION; 

mysql.sysユーザーとrootユーザーは、MySQL 8.0に標準装備されています。上の行は、ダミーにはUSAGE特権があるが、それ以外は何も表示されないことを示しています。

1

あなたの質問は答えが難しいものでしたが、最終的にどのような種類の特権も割り当てられていないユーザーアカウントを表示するための「単純な」クエリが得られました。今、私たちのDB :)

をきれいにするために、クエリを理解するために、それが一定のレベルに

まずレベルを分割しましょう、列レベルのアクセス権を持っていないすべてのユーザーを一覧表示します。

第2レベルでは、テーブルレベルの権限を持たないユーザーと、列レベルのアクセス権を持たないユーザーのみを一覧表示します。

SELECT B.User FROM mysql.user B LEFT JOIN mysql.tables_priv ON (mysql.tables_priv.User = B.User) WHERE 
mysql.tables_priv.Db IS NULL AND (Table_priv=0 OR Table_priv IS NULL) AND (Column_priv=0 OR Column_priv IS NULL) 
AND B.User IN (
    SELECT C.User FROM mysql.user C LEFT JOIN mysql.columns_priv ON (mysql.columns_priv.User = C.User) WHERE 
    (Column_priv=0 OR Column_priv IS NULL) AND mysql.columns_priv.Db IS NULL) 

第三レベル、リストのデータベースレベルの権限を持たないユーザー、およびリストだけ前の2つのクエリのアクセスを持っていない人。

SELECT A.User FROM mysql.user A LEFT JOIN mysql.db ON (mysql.db.User = A.User) WHERE 
mysql.db.Db IS NULL 
AND A.User IN (
    SELECT B.User FROM mysql.user B LEFT JOIN mysql.tables_priv ON (mysql.tables_priv.User = B.User) WHERE 
    mysql.tables_priv.Db IS NULL AND (Table_priv=0 OR Table_priv IS NULL) AND (Column_priv=0 OR Column_priv IS NULL) 
    AND B.User IN (
     SELECT C.User FROM mysql.user C LEFT JOIN mysql.columns_priv ON (mysql.columns_priv.User = C.User) WHERE 
     (Column_priv=0 OR Column_priv IS NULL) AND mysql.columns_priv.Db IS NULL) 
) 

第3レベルでは、データベースレベルでアクセスできるユーザーを確認し、テーブル/列レベルのアクセス権を持たないユーザーのみを一覧表示します。

最後に、

SELECT mysql.user.Host, mysql.user.User 
FROM mysql.user WHERE mysql.user.User IN (
    SELECT A.User FROM mysql.user A LEFT JOIN mysql.db ON (mysql.db.User = A.User) WHERE 
    mysql.db.Db IS NULL 
    AND A.User IN (
     SELECT B.User FROM mysql.user B LEFT JOIN mysql.tables_priv ON (mysql.tables_priv.User = B.User) WHERE 
     mysql.tables_priv.Db IS NULL AND (Table_priv=0 OR Table_priv IS NULL) AND (Column_priv=0 OR Column_priv IS NULL) 
     AND B.User IN (
      SELECT C.User FROM mysql.user C LEFT JOIN mysql.columns_priv ON (mysql.columns_priv.User = C.User) WHERE 
      (Column_priv=0 OR Column_priv IS NULL) AND mysql.columns_priv.Db IS NULL) 
     ) 
) AND CONCAT(Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Reload_priv,Shutdown_priv,Process_priv,File_priv,Grant_priv,References_priv,Index_priv,Alter_priv,Show_db_priv,Super_priv,Create_tmp_table_priv,Lock_tables_priv,Execute_priv,Repl_slave_priv,Repl_client_priv,Create_view_priv,Show_view_priv,Create_routine_priv,Alter_routine_priv,Create_user_priv,Event_priv,Trigger_priv,Create_tablespace_priv) NOT LIKE '%Y%' 

グローバルアクセス権が割り当てられておらず、他のサブクエリの基準に一致するもののみをリストします。

EDIT

"プリティ・ストレート":このクエリでのみ5.5バージョンでテストされたよう、フィードバックをお願いします。

+0

すばらしい詳細な提案をありがとう。 3台のサーバーのうち2台の新しいサーバー(5.5と5.6)で正常に動作しました。しかし、古いサーバー(5.0を実行中)は、「不明な列」エラーを返しました。このバージョンのMySQLでは、 'Event_priv'、' Trigger_priv'、 'Create_tablespace_priv'が' mysql.user'に存在しないからです。 CONTAT()の3つの列を省略すると、クエリが20分以上実行されただけです。その後、クライアント(SQLYog)はサーバーへの接続を失っただけです。私はその事実をさらに調査しなかった - 理由は主に私の次のポイント(別のコメント) – TomRA

+0

クエリは、データベースに関係のない、つまり権限がないユーザーを返します。そして、これはうまく動作します。たとえば、ユーザーを作成して、それにどのデータベースにもアクセスを許可しない場合です。それから、私は結果に現れます。しかし、別のシナリオを試してみましょう。これは私が扱っているものです... このユーザーの新しいユーザーとデータベースを作成し、そのユーザーにアクセスを許可します。データベースを削除します(ユーザーから離れる)。次に、_existing_データベースにアクセスできないが、mysql.dbにまだ現れているユーザがいます。そのようなユーザーは返されません、私たちは正方形に戻っておきます:(アイデア? – TomRA

関連する問題