MySQL安全性系統是靈活的。它允許以許多不同的方法設置用戶訪問權限。通常,可通過GRANT 和REVOKE 語句來進行,這些語句對控制客戶機訪問的授權表進行修改。但是,您擁有的可能是不支持這些語句的舊版本MySQL(這些語句在MySQL3.22.11以前的版本
中沒有使用),或者可能發覺用戶的權限好像不是按希望地在工作。對於這樣的情況,了解MySQL授權表的結構以及服務器怎樣使用它們來決定訪問許可權是有幫助的。您了解到這樣一個程度,就可以通過直接修改授權表來增加、刪除或修改用戶的權限,還可以在檢查表時
診斷權限的問題。
筆者假定您已經閱讀了第11章的“用戶賬號管理”一節,並理解GRANT 和R E V O K E語句是怎樣工作的。GRANT 和REVOKE 提供了建立MySQL賬號和相關權限的便利方法,但是,它們只是一個前端。所有真正的操作都發生在MySQL授權表中。
MySQL授權表的結構和內容
在網絡上連接到服務器的客戶機對MySQL數據庫的訪問是由授權表內容控制的。這些表定位在mysql數據庫中,並在首次安裝MySQL的過程中進行初始化(如附錄A 所描述的)。表12-1和表12-2 示出列五個授權表,它們是user、db、host、tables_priv 和c o l um n s _ priv。
授權表的內容按下列各項使用:
user user 表列出可連接到服務器和口令的用戶,並指定用戶擁有哪些全局(超級用戶)權限(如果有的話)。任何在user 表項中所允許的權限都是全局權限,並適用於所有的數據庫。例如,如果在這裡允許DELETE 權限,則在該項中列出的用戶可從任何表中刪除記錄。因此,在進行這項操作之前千萬要小心,通常,最好在user 表項中關閉所有的權限,而使用其他的、有更多限制的表來指定權限。對超級用戶(如r o o t)則是一個例外,但一般很少有。
db db 表列出數據庫以及哪些用戶擁有訪問這些數據庫的權限。這裡指定的權限適用於數據庫中所有的表。
host host 表與db表結合使用,在更細的級別上控制對特定主機的數據庫訪問權限。該表不受GRANT 和REVOKE 語句的影響,因此您會發現根本不會去使用它。
tables_priv tables_priv 表指定表級的權限。在這裡所指定的權限適用於表中所有的列。
columns_priv columns_priv 表指定列級的權限。在這裡所指定的權限適用於表中特定的列。
在12 . 2 . 4節“不用GRANT 建立用戶”中,我們將討論GRANT 語句怎樣修改這些表以及怎樣通過直接修改授權表來達到相同的結果。
tables_priv 和columns_priv 表是在MySQL3.22.11中引入的(與GRANT 語句同時)。如果您擁有MySQL的舊版本,則mysql數據庫只有user、db 和host 表。如果已經從舊版本升級到3 . 2 2 . 11以上的版本,但仍沒有tables_priv 和columns_priv 表的話,可運行mysql_fix_privileges_table 腳本創建它們。
沒有rows_priv 表,因為MySQL不提供記錄級的權限。例如,不能使用戶只局限於某些列中包含某個值的表中的那些行。如果需要這個能力,必須編寫應用程序。如果要想執行咨詢記錄級鎖定(advisory record-level locking),可用附錄C 中介紹的GET_LOCK() 函數進行。
授權表中包含兩種類型的列:作用域列( scope column)和權限列( privilege column),前者決定一個項何時可用,後者決定一個項可授予哪些權限(有些授權表中包含其他各式各樣的列,但在這裡與我們無關)。
1. 授權表的作用域列
授權表作用域列指定表項何時使用。每個授權表項中都包含User 和Host 列,以指明該項在特定的用戶從特定的主機上連接時應用( host 表是一個例外,它被用於一種特定的、我們還未接觸過的方法中)。其他表中包含附加的作用域列。例如, db 表中包含一個Db 列以指明該項適用於哪個數據庫。同樣, tables_priv 和columns_priv 表中包含使該作用域對數據庫中特定表或表中的列縮小的作用域字段。
2. 授權表權限列
授權表中還包含權限列。這些列指明了哪些權限被在作用域列中指定的用戶所擁有。MySQL支持的權限顯示在以下列表中。該列表使用用於GRANT 語句的權限名。對於大部分來說,在user、db 和host 表中權限列的名字與在第11章利用GRANT 語句連接中所討論的