top
Loading...
5.7.6.訪問控制,階段2:請求核實
5.7.6. 訪問控制, 階段2:請求核實

一旦你建立了連接,服務器進入訪問控制的階段2。對在此連接上進來的每個請求,服務器檢查你想執行什么操作,然后檢查是否有足夠的權限來執行它。這正是在授權表中的權限列發揮作用的地方。這些權限可以來自userdbhosttables_privcolumns_priv表。(你會發現參考5.7.2節,“權限系統工作原理”很有幫助,它列出了每個 授權表中呈現的列。)

user表在全局基礎上授予賦予你的權限,該權限不管當前的數據庫是什么均適用。例如,如果user表授予你DELETE權限, 你可以刪除在服務器主機上從任何數據庫刪除行!換句話說,user表權限是超級用戶權限。只把user表的權限授予超級用戶如服務器或數據庫主管是明智的。對其他用戶,你應該把在user表中的權限設成'N'并且僅在特定數據庫的基礎上授權。你可以為特定的數據庫、表或列授權。

dbhost表授予數據庫特定的權限。在這些表中的范圍列的值可以采用以下方式:

  • 通配符字符%_可用于兩個表的HostDb列。它們與用LIKE操作符執行的模式匹配操作具有相同的含義。如果授權時你想使用某個字符,必須使用反斜現引用。例如,要想在數據庫名中包括下劃線(_),在GRANT語句中用\_來指定
  • db表的'%'Host值意味著“任何主機”,在db表中空Host值意味著“對進一步的信息咨詢host表”(本節后面將描述的一個過程)。
  • host表的'%'或空Host值意味著“任何主機”。
  • 在兩個表中的'%'或空Db值意味著“任何數據庫”。
  • 在兩個表中的空User值匹配匿名用戶。

dbhost表在服務器啟動時被讀取并排序(同時它讀user)db表在HostDbUser范圍列上排序,并且host表在HostDb范圍列上排序。對于user表,首先根據最具體的值最后根據最不具體的值排序,并且當服務器尋找匹配條目時,它使用它找到的第一匹配。

tables_privcolumns_priv表授予表和列特定的權限。這些表的范圍列的值可以如下被指定:

  • 通配符%_可用在使用在兩個表的Host列。
  • 在兩個表中的'%'或空Host意味著“任何主機”。
  • 在兩個表中的DbTable_nameColumn_name列不能包含通配符或空。

tables_privcolumns_priv表根據HostDbUser列被排序。這類似于db表的排序,因為只有Host列可以包含通配符,排序更簡單。

請求證實進程在下面描述。(如果你熟悉訪問檢查的源碼,你會注意到這里的描述與在代碼使用的算法略有不同。描述等價于代碼實際做的東西;不同處只是使解釋更簡單。)

對需要管理權限的請求(SHUTDOWNRELOAD等等),服務器僅檢查user表條目,因為那是唯一指定管理權限的表。如果行許可請求的操作,訪問被授權,否則拒絕。例如,如果你想要執行mysqladmin shutdown,但是由于user表行沒有為你授予HUTDOWN權限,甚至不用檢查dbhost表就拒絕你的訪問。(因為它們不包含hutdown_priv行列,沒有這樣做的必要。)

對數據庫有關的請求(INSERTUPDATE等等),服務器首先通過查找user表行來檢查用戶的全局(超級用戶)權限。如果行允許請求的操作,訪問被授權。如果在user表中全局權限不夠,服務器通過檢查dbhost表確定特定的用戶數據庫權限:

  1. 服務器在db表的HostDbUser列上查找匹配。HostUser對應連接用戶的主機名和MySQL用戶名。Db列對應用戶想要訪問的數據庫。如果沒有HostUser的行,訪問被拒絕。
  2. 如果db表中有匹配的行而且它的Host列不是空的,該行定義用戶的數據庫特定的權限。
  3. 如果匹配的db表的行的Host列是空的,它表示host表列舉被允許訪問數據庫的主機。在這種情況下,在host表中作進一步查找以發現HostDb列上的匹配。如果沒有host表行匹配,訪問被拒絕。如果有匹配,用戶數據庫特定的權限以在dbhost表的行的權限,即在兩個行都是'Y'的權限的交集(而不是并集!)計算。(這樣你可以授予在db表行中的一般權限,然后用host表行按主機主機為基礎有選擇地限制它們。)

在確定了由dbhost表行授予的數據庫特定的權限后,服務器把他們加到由user表授予的全局權限中。如果結果允許請求的操作,訪問被授權。否則,服務器檢查在tables_privcolumns_priv表中的用戶的表和列權限并把它們加到用戶權限中。基于此結果允許或拒絕訪問。

用布爾術語表示,前面關于用戶權限如何計算的描述可以這樣總結:

global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges

它可能不明顯,為什么呢,如果全局user行的權限最初發現對請求的操作不夠,服務器以后把這些權限加到數據庫、表并列的特定權限。原因是請求可能要求超過一種類型的權限。例如,如果你執行INSERT INTO ... SELECT語句,你就需要INSERTSELECT權限。你的權限必須是user表行授予一個權限而db表行授予另一個權限。在這種情況下,你有必要的權限執行請求,但是服務器不能自己把兩個表區別開來;兩個行授予的權限必須組合起來。

host表不受GRANTREVOKE語句的影響,因此在大多數MySQL安裝中沒有使用。如果你直接修改它,你可以用于某種專門目的,例如用來維護安全服務器列表。例如,在TcXhost表包含在本地網絡上所有的機器的表。這些表被授予所有的權限。

你也可以使用host表指定安全的主機。假定你有一臺機器public.your.domain,它位于你認為不安全的公共區域,你可以用下列的host表條目允許除了那臺機器外的網絡上所有主機的訪問:

+--------------------+----+-
| Host               | Db | ...
+--------------------+----+-
| public.your.domain | %  | ... (all privileges set to 'N')
| %.your.domain      | %  | ... (all privileges set to 'Y')
+--------------------+----+-

當然,一定要測試授權表中的行(例如,使用SHOW GRANTSmysqlaccess),確保你的訪問權限實際按你期望的方式被設置。

作者:mysql.com
來源:http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html
北斗有巢氏 有巢氏北斗