2017-02-24 42 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

它在3臺不同的服務器上分別運行'5.0.51a-24 + lenny5-log', '5.5.54-0 + deb7u2'和'5.6.35' – 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用戶和根用戶都是標準的上的MySQL 8.0。上面的代碼顯示dummy具有USAGE特權,但沒有別的。

1

你的問題是一個挑戰,但最終,即使我們有一個「簡單」的查詢來顯示哪些用戶帳戶沒有任何類型的特權分配(是的,沒有特權),並使用它清潔我們的DB :)

我們理解查詢,讓它分裂到一定程度

第一級,列出沒有列級訪問的每個用戶。

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 

第二級,列出沒有表級別權限的用戶,以及僅列出沒有列級別權限的用戶。

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) 

第三級,列出沒有數據庫級別權限的用戶,並列出只有那些沒有訪問前兩個查詢的用戶。

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) 
) 

第三級,檢查任何人誰在數據庫級別訪問,並列出誰沒有表/列級別訪問。

最後。

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%' 

僅列出那些沒有分配全局訪問權限並匹配其他子查詢條件的人員。

「漂亮直」

編輯:請給予反饋意見,因爲這是查詢只有5.5版本的測試。

+0

非常感謝您提供優秀而詳細的建議。它在三臺服務器中的兩臺新服務器上運行良好(5.5和5.6)。舊的服務器(運行5.0)卻返回了「未知列」 - 錯誤。原因是這個版本的MySQL中的'mysql.user'中不存在'Event_priv','Trigger_priv'和'Create_tablespace_priv'。而在CONTAT()中忽略這3列,只會導致查詢運行20分鐘以上。之後我的客戶端(SQLYog)失去了與服務器的連接。我沒有進一步調查此事 - 主要原因是我的下一個要點(單獨評論) – TomRA

+0

查詢返回與任何數據庫無關的用戶,即無特權。如果我說,創建一個用戶並且不授予它對任何數據庫的訪問權,這工作正常。然後我出現在結果中。但是,讓我們嘗試另一種場景,這就是我正在處理的... 爲此用戶創建一個新用戶和一個新數據庫以訪問 - 並授予他所說的訪問權限。刪除數據庫(離開用戶)。然後你有一個用戶不能訪問任何_existing_數據庫,但仍然出現在'mysql.db'中。因此,用戶將不會被退回,離開我們回到廣場1 :(想法? – TomRA

相關問題