国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

MySQL中文參考手冊7(MySQL 存取權(quán)限系統(tǒng)) grant 設(shè)置密碼 password

2024-07-24 12:54:46
字體:
供稿:網(wǎng)友

mysql中文參考手冊7(mysql 存取權(quán)限系統(tǒng))
轉(zhuǎn)載 譯者:晏子

〖返回〗〖轉(zhuǎn)發(fā)〗


譯者:晏子 ([email protected])主頁:http://linuxdb.yeah.net
6 mysql 存取權(quán)限系統(tǒng)
mysql有一個(gè)先進(jìn)但非標(biāo)準(zhǔn)的安全/權(quán)限系統(tǒng)。本節(jié)描述它的工作原理。 

6.1 權(quán)限系統(tǒng)做什么
mysql權(quán)限系統(tǒng)的主要功能是證實(shí)連接到一臺給定主機(jī)的一個(gè)用戶,并且賦予該用戶在一個(gè)數(shù)據(jù)庫上select、 insert、update和delete的權(quán)限。 

附加的功能包括有一個(gè)匿名的用戶和對于mysql特定的功能例如load data infile進(jìn)行授權(quán)及管理操作的能力。 

6.2 mysql 用戶名和口令
由mysql使用用戶名和口令的方法與unix或windows使用的方式有很多不同之處: 

mysql使用于認(rèn)證目的的用戶名,與unix用戶名(登錄名字)或windows用戶名無關(guān)。缺省地,大多數(shù)mysql客戶嘗試使用當(dāng)前unix用戶名作為mysql用戶名登錄,但是這僅僅為了方便。客戶程序允許用-u或--user選項(xiàng)指定一個(gè)不同的名字,這意味著無論如何你不能使得一個(gè)數(shù)據(jù)庫更安全,除非所有的mysql用戶名都有口令。任何人可以試圖用任何名字連接服務(wù)器,而且如果他們指定了沒有口令的任何名字,他們將成功。 
mysql用戶名最長可以是16各字符;典型地,unix用戶名限制為8個(gè)字符。 
mysql口令與unix口令沒關(guān)系。在你使用登錄到一臺unix機(jī)器口令和你使用在那臺機(jī)器上存取一個(gè)數(shù)據(jù)庫的口令之間沒有必要有關(guān)聯(lián)。 
mysql加密口令使用了一個(gè)unix登錄期間所用的不同算法,見7.4.12 雜項(xiàng)函數(shù)一節(jié)中描述password()和encrypt()函數(shù)部分。 

6.3 與mysql服務(wù)器連接
當(dāng)你想要存取一個(gè)mysql服務(wù)器時(shí),mysql客戶程序一般要求你指定連接參數(shù):你想要聯(lián)接的主機(jī)、你的用戶名和你的口令。例如,mysql客戶可以象這樣啟動(可選的參數(shù)被包括在“[”和“]”之間): 

shell> mysql [-h host_name][-u user_name][-pyour_pass ]
-h, -u和-p選項(xiàng)的另一種形式是--host=host_name、--user=user_name和--password=your_pass。注意在-p或--password=與跟隨它后面的口令之間沒有空格。 

注意:在命令行上指定一個(gè)口令是不安全的!隨后在你系統(tǒng)上的任何用戶可以通過打類似這樣的命令發(fā)現(xiàn)你的口令:ps auxww。見4.15.4 選項(xiàng)文件。 

對于命令行沒有的聯(lián)接參數(shù),mysql使用缺省值: 

缺省主機(jī)名是localhost。 
缺省用戶名是你的unix登錄名。 
如果沒有-p,則沒有提供口令。 

這樣, 對一個(gè)unix用戶joe,下列命令是等價(jià)的: 

shell>mysql -h localhost -u joe 
shell>mysql -h localhost 
shell>mysql -u joe 
shell>mysql

其它mysql客戶程序有同樣表現(xiàn)。 

在unix系統(tǒng)上,當(dāng)你進(jìn)行一個(gè)連接時(shí),你可以指定要使用的不同的缺省值,這樣你不必每次在你調(diào)用一個(gè)客戶程序是在命令行上輸入他們。這可以有很多方法做到: 

你能在你的主目錄下“.my.cnf”的配置文件的[client]小節(jié)里指定連接參數(shù)。文件的相關(guān)小節(jié)看上去可能像這樣: 
[client] 
host=host_name 
user=user_name 
password=your_pass

見4.15.4 選項(xiàng)文件。

你可以用環(huán)境變量指定連接參數(shù)。主機(jī)可用mysql_host指定,mysql用戶名字可用user指定(僅對 windows),口令可用mysql_pwd指定(但是這不安全,見下一節(jié)) 。 
如果連接參數(shù)以多種方法被指定,在命令行上被指定的值優(yōu)先于在配置文件和環(huán)境變量中指定的值,而在配置文件指定的值優(yōu)先于在環(huán)境變量指定的值。 

6.4 使你的口令安全
以一種暴露的可被其他用戶發(fā)現(xiàn)的方式指定你的口令是不妥當(dāng)?shù)摹.?dāng)你運(yùn)行客戶程序時(shí),你可以使用下列方法指定你的口令,還有每個(gè)方法的風(fēng)險(xiǎn)評估: 

使用一個(gè)在命令行上-pyour_pass或--password=your_pass的選項(xiàng)。這很方便但是不安全,因?yàn)槟愕目诹顚ο到y(tǒng)狀態(tài)程序(例如ps)變得可見,它可以被其他的用戶調(diào)用來顯示命令行。(一般mysql客戶在他們的初始化順序期間用零覆蓋命令行參數(shù),但是仍然有一個(gè)短暫間隔時(shí)間內(nèi)參數(shù)值可見的。) 
使用一個(gè)-p或--password選項(xiàng)(沒有指定your_pass值)。在這種情況下,客戶程序請求來自終端的口令: 
shell>mysql - u  user_name - p
enter password: ********

客戶回應(yīng)“*”字符到作為輸入你的口令的終端使得旁觀者不能看見它。因?yàn)樗鼘ζ渌脩舨豢梢姡c在命令行上指定它相比,這樣進(jìn)入你的口令更安全。然而,這個(gè)輸入一個(gè)口令的方法僅僅為你交互式運(yùn)行程序是合適的。如果你想要從非交互式運(yùn)行的一個(gè)腳本調(diào)用一個(gè)客戶,就沒有從終端輸入入口令的機(jī)會。 


在一個(gè)配置文件中存儲你的口令。例如,你可你的主目錄的“.my.cnf”文件中的[client]節(jié)列出你的口令: 
[client]
password=your_pass

如果你在“.my.cnf”里面存儲口令,文件應(yīng)該不是組或世界可讀或可寫的。保證文件的存取模式是400或600。見4.15.4 選項(xiàng)文件。 



你可在mysql_pwd環(huán)境變量中存儲口令,但是這個(gè)方法必須想到是極不安全的且應(yīng)該不使用。ps的某些版本包括顯示運(yùn)行進(jìn)程的環(huán)境的選項(xiàng);如果你設(shè)定mysql_pwd,你的口令將對所有人是顯而易見的,甚至在沒有這樣一個(gè)版本的ps系統(tǒng)上,假設(shè)沒有其他方法觀察到進(jìn)程環(huán)境是不明智的。 
總之,最安全的方法是讓客戶程序提示口令或在一個(gè)適當(dāng)保護(hù)的“.my.cnf”文件中指定口令。 

6.5   mysql提供的權(quán)限
權(quán)限信息用user、db、host、tables_priv和columns_priv表被存儲在mysql數(shù)據(jù)庫中(即在名為mysql的數(shù)據(jù)庫中)。在mysql啟動時(shí)和在6.9 權(quán)限修改何時(shí)生效所說的情況時(shí),服務(wù)器讀入這些數(shù)據(jù)庫表內(nèi)容。 

本手冊所用的涉及由mysql提供的權(quán)限名稱顯示在下表,還有在授權(quán)表中每個(gè)權(quán)限的表列名稱和每個(gè)權(quán)限有關(guān)的上下文: 

權(quán)限           列               上下文  
select      select_priv           表 
insert      insert_priv           表 
update      update_priv           表 
delete      delete_priv           表 
index       index_priv            表 
alter       alter_priv            表 
create      create_priv         數(shù)據(jù)庫、表或索引 
drop        drop_priv           數(shù)據(jù)庫或表 
grant       grant_priv          數(shù)據(jù)庫或表 
references  references_priv     數(shù)據(jù)庫或表 
reload      reload_priv         服務(wù)器管理 
shutdown    shutdown_priv       服務(wù)器管理 
process     process_priv        服務(wù)器管理 
file        file_priv           在服務(wù)器上的文件存取 

select、insert、update和delete權(quán)限允許你在一個(gè)數(shù)據(jù)庫現(xiàn)有的表上實(shí)施操作。 

select語句只有在他們真正從一個(gè)表中檢索行是才需要select權(quán)限,你可以執(zhí)行某個(gè)select語句,甚至沒有任何到服務(wù)器上的數(shù)據(jù)庫里的存取任何東西的許可。例如,你可使用mysql客戶作為一個(gè)簡單的計(jì)算器: 

mysql> select 1+1;
mysql> select pi()*2;

index權(quán)限允許你創(chuàng)建或拋棄(刪除)索引。 

alter權(quán)限允許你使用alter table。 

create和drop權(quán)限允許你創(chuàng)建新的數(shù)據(jù)庫和表,或拋棄(刪除)現(xiàn)存的數(shù)據(jù)庫和表。 

注意:如果你將mysql數(shù)據(jù)庫的drop權(quán)限授予一個(gè)用戶,該用戶能拋棄存儲了mysql存取權(quán)限的數(shù)據(jù)庫! 

grant權(quán)限允許你把你自己擁有的那些權(quán)限授給其他的用戶。 

file權(quán)限給予你用load data infile和select ... into outfile語句讀和寫服務(wù)器上的文件,任何被授予這個(gè)權(quán)限的用戶都能讀或?qū)憁ysql服務(wù)器能讀或?qū)懙娜魏挝募?nbsp;

其余的權(quán)限用于管理性操作,它使用mysqladmin程序?qū)嵤O卤盹@示mysqladmin支配每個(gè)管理性權(quán)限允許你執(zhí)行的命令: 

優(yōu)惠         權(quán)限擁有者允許執(zhí)行的命令  
reload       reload, refresh, flush-privileges, flush-hosts, flush-logs, flush-tables  
shutdown     shutdown  
precess      processlist, kill  

reload命令告訴服務(wù)器再讀入授權(quán)表,refresh命令清洗所有表并打開和關(guān)閉記錄文件,flush-privileges是reload的一個(gè)同義詞,其它flush-*命令執(zhí)行類似refresh的功能,但是范圍更有限,并且在某些情況下可能更好用。例如,如果你只是想清洗記錄文件,flush-logs比refresh是更好的選擇。 

shutdown命令關(guān)掉服務(wù)器。 

processlist命令顯示在服務(wù)器內(nèi)執(zhí)行的線程的信息。kill命令殺死服務(wù)器線程。你總是能顯示或殺死你自己的線程,但是你需要process權(quán)限來顯示或殺死其他用戶啟動的線程。 

總的說來,只授予權(quán)限給需要他們的那些用戶是一個(gè)好主意,但是你應(yīng)該在授予某個(gè)權(quán)限時(shí)試驗(yàn)特定的警告: 

grant權(quán)限允許用戶放棄他們的權(quán)限給其他用戶。2個(gè)有不同的權(quán)限并有g(shù)rant權(quán)限的用戶可以合并權(quán)限。 
alter權(quán)限可以用于通過重新命名表來推翻權(quán)限系統(tǒng)。 
file權(quán)限可以被濫用在服務(wù)器上讀取任何世界可讀(world-readable,即任何人可讀)的文件到一張數(shù)據(jù)庫表,然后其內(nèi)容能用select被存取。 
shutdown權(quán)限通過終止服務(wù)器可以被濫用完全拒絕為其他用戶服務(wù), 。 
precess權(quán)限能被用來察看當(dāng)前執(zhí)行的查詢的普通文本,包括設(shè)定或改變口令查詢。 
在mysql數(shù)據(jù)庫上的權(quán)限能被用來改變口令和其他存取權(quán)限信息。(口令被加密存儲,所以一個(gè)惡意的用戶不能簡單地讀取他們。然而,有足夠的權(quán)限,同一個(gè)用戶能用不同的一個(gè)代替一個(gè)口令。) 
有一些事情你不能用mysql權(quán)限系統(tǒng)做到: 

你不能明顯地指定一個(gè)給定用戶應(yīng)該被拒絕存取。即,你不能明顯地匹配一個(gè)用戶并且然后拒絕連接。 
你不能指定一個(gè)用戶有權(quán)創(chuàng)建立或拋棄一個(gè)數(shù)據(jù)庫中的表,也不能創(chuàng)建或拋棄數(shù)據(jù)庫本身。 

6.6 權(quán)限系統(tǒng)工作原理
mysql權(quán)限系統(tǒng)保證所有的用戶可以嚴(yán)格地做他們假定被允許做的事情。當(dāng)你連接一個(gè)mysql服務(wù)器時(shí), 你的身份由你從那連接的主機(jī)和你指定的用戶名來決定,系統(tǒng)根據(jù)你的身份和你想做什么來授予權(quán)限。 

mysql在認(rèn)定身份中考慮你的主機(jī)名和用戶名字,是因?yàn)橛泻苄〉脑蚣俣ㄒ粋€(gè)給定的用戶在因特網(wǎng)上屬于同一個(gè)人。例如,用戶從whitehouse.gov連接的bill不必和從mosoft.com連接bill是同一個(gè)人。 mysql通過允許你區(qū)分在不同的主機(jī)上碰巧有同樣名字用戶來處理它:你可以對從whitehouse.gov連接授與bill一個(gè)權(quán)限集,而為從microsoft.com的連接授予一個(gè)不同的權(quán)限集。 

mysql存取控制包含2個(gè)階段: 

階段1:服務(wù)器檢查你是否允許連接。 
階段2:假定你能連接,服務(wù)器檢查你發(fā)出的每個(gè)請求。看你是否有足夠的權(quán)限實(shí)施它。例如,如果你從數(shù)據(jù)庫中一個(gè)表精選(select)行或從數(shù)據(jù)庫拋棄一個(gè)表,服務(wù)器確定你對表有select權(quán)限或?qū)?shù)據(jù)庫有drop權(quán)限。 

服務(wù)器在存取控制的兩個(gè)階段使用在mysql的數(shù)據(jù)庫中的user、db和host表,在這些授權(quán)表中字段如下: 

表名稱                  user                db                  host  
范圍字段                host                host                host  
                        user                db                  db  
                        password            user   
權(quán)限字段                select_priv         select_priv         select_priv  
                        insert_priv         insert_priv         insert_priv  
                        update_priv         update_priv         update_priv  
                        delete_priv         delete_priv         delete_priv  
                        index_priv          index_priv          index_priv  
                        alter_priv          alter_priv          alter_priv  
                        create_priv         create_priv         create_priv  
                        drop_priv           drop_priv           drop_priv  
                        grant_priv          grant_priv          grant_priv  
                        reload_priv    
                        shutdown_priv    
                        process_priv    
                        file_priv    

對存取控制的第二階段(請求證實(shí)),如果請求涉及表,服務(wù)器可以另外參考tables_priv和columns_priv表。這些表的字段如下: 

表名稱                     tables_priv                columns_priv  
范圍字段                     host                       host  
                                 db                         db  
                                 user                       user  
                               table_name                 table_name  
                               column_name  
權(quán)限字段                   table_priv                 column_priv  
                               column_priv   
其他字段                   timestamp                  timestamp  
                               grantor   

每個(gè)授權(quán)表包含范圍字段和權(quán)限字段。 

范圍字段決定表中每個(gè)條目的范圍,即,條目適用的上下文。例如, 一個(gè)user表?xiàng)l目的host和user值為'thomas.loc.gov'和'bob'將被用于證實(shí)來自主機(jī)thomas.loc.gov的bob對服務(wù)器的連接。同樣,一個(gè)db表?xiàng)l目的host、user和db字段的值是'thomas.loc.gov'、'bob'和'reports'將用在bob從主機(jī)聯(lián)接thomas.loc.gov存取reports數(shù)據(jù)庫的時(shí)候。 tables_priv和columns_priv表包含范圍字段,指出每個(gè)條目適用的表或表/列的組合。 

對于檢查存取的用途,比較host值是忽略大小寫的。user、password、db和table_name值是區(qū)分大小寫的。column_name值在mysql3.22.12或以后版本是忽略大小寫的。 

權(quán)限字段指出由一個(gè)表?xiàng)l目授予的權(quán)限,即,可實(shí)施什么操作。服務(wù)器組合各種的授權(quán)表的信息形成一個(gè)用戶權(quán)限的完整描述。為此使用的規(guī)則在6.8 存取控制, 階段2:請求證實(shí)描述。

范圍字段是字符串,如下所述;每個(gè)字段的缺省值是空字符串: 

字段名      類型  
host       char(60)  
user       char(16)  
password   char(16)  
db         char(64)  (tables_priv和columns_priv表為char(60)) 

在user、db和host表中,所有權(quán)限字段被聲明為enum('n','y')--每一個(gè)都可有值'n'或'y',并且缺省值是'n'. 

在tables_priv和columns_priv表中,權(quán)限字段被聲明為set字段: 

表名         字段名        可能的集合成員  
tables_priv  table_priv   'select', 'insert', 'update', 'delete', 'create', 'drop', 'grant', 'references', 'index', 'alter'  
tables_priv  column_priv  'select', 'insert', 'update', 'references'  
columns_priv column_priv  'select', 'insert', 'update', 'references'  

簡單地說,服務(wù)器使用這樣的授權(quán)表: 

user表范圍字段決定是否允許或拒絕到來的連接。對于允許的連接,權(quán)限字段指出用戶的全局(超級用戶)權(quán)限。 
db和host表一起使用: 

         db表范圍字段決定用戶能從哪個(gè)主機(jī)存取哪個(gè)數(shù)據(jù)庫。權(quán)限字段決定允許哪個(gè)操作。 
         
         當(dāng)你想要一個(gè)給定的db條目應(yīng)用于若干主機(jī)時(shí),host表作為db表的擴(kuò)展被使用。例如,如果你想要一個(gè)用戶能在你的網(wǎng)絡(luò)從若干主機(jī)使用一個(gè)數(shù)據(jù)庫,在用戶的db表的host條目設(shè)為空值,然后將那些主機(jī)的每一個(gè)移入host表。這個(gè)機(jī)制詳細(xì)描述在6.8 存取控制, 階段2:請求證實(shí)。 

tables_priv和columns_priv表類似于db表,但是更精致:他們在表和列級應(yīng)用而非在數(shù)據(jù)庫級。 
注意管理權(quán)限(reload, shutdown, 等等)僅在user表中被指定。這是因?yàn)楣芾硇圆僮魇欠?wù)器本身的操作并且不是特定數(shù)據(jù)庫,因此沒有理由在其他授權(quán)表中列出這樣的權(quán)限。事實(shí)上,只需要請教user表來決定你是否執(zhí)行一個(gè)管理操作。 

file權(quán)限也僅在user表中指定。它不是管理性權(quán)限,但你讀或謝在服務(wù)器主機(jī)上的文件的的能力獨(dú)立于你正在存取的數(shù)據(jù)庫。 

當(dāng)mysqld服務(wù)器啟動時(shí),讀取一次授權(quán)表內(nèi)容。對授權(quán)表的更改生效在6.9 權(quán)限更改何時(shí)生效描述。 

當(dāng)你修改授權(quán)表的內(nèi)容時(shí),確保你按你想要的方式更改權(quán)限設(shè)置是一個(gè)好主意。為幫助診斷問題,見6.13 “存取拒絕引起”錯誤的原因。對于安全問題上的忠告,見6.14 怎么對使mysql安全對抗解密高手。 

一個(gè)有用的診斷工具是mysqlaccess腳本,由carlier yves 提供給mysql分發(fā)。使用--help選項(xiàng)調(diào)用mysqlaccess查明它怎樣工作。注意:mysqlaccess僅用user、db和host表僅檢查存取。它不檢查表或列級權(quán)限。 

6.7 存取控制, 階段1:連接證實(shí)
當(dāng)你試圖聯(lián)接一個(gè)mysql服務(wù)器時(shí),服務(wù)器基于你的身份和你是否能通過供應(yīng)正確的口令驗(yàn)證身份來接受或拒絕連接。如果不是,服務(wù)器完全具結(jié)你的存取,否則,服務(wù)器接受連接,然后進(jìn)入階段2并且等待請求。 

你的身份基于2個(gè)信息: 

你從那個(gè)主機(jī)連接 
你的mysql用戶名 

身份檢查使用3個(gè)user表(host, user和password)范圍字段執(zhí)行。服務(wù)器只有在一個(gè)user表?xiàng)l目匹配你的主機(jī)名和用戶名并且你提供了正確的口令時(shí)才接受連接。 

在user表范圍字段可以如下被指定: 

一個(gè)host值可以是主機(jī)名或一個(gè)ip數(shù)字,或'localhost'指出本地主機(jī)。 
你可以在host字段里使用通配符字符“%”和“_”。 
一個(gè)host值'%'匹配任何主機(jī)名,一個(gè)空白host值等價(jià)于'%'。注意這些值匹配能創(chuàng)建一個(gè)連接到你的服務(wù)器的任何主機(jī)! 
通配符字符在user字段中不允許,但是你能指定空白的值,它匹配任何名字。如果user表匹配到來的連接的條目有一個(gè)空白的用戶名,用戶被認(rèn)為是匿名用戶(沒有名字的用戶),而非客戶實(shí)際指定的名字。這意味著一個(gè)空白的用戶名被用于在連接期間的進(jìn)一步的存取檢查(即,在階段2期間)。 
password字段可以是空白的。這不意味著匹配任何口令,它意味著用戶必須不指定一個(gè)口令進(jìn)行連接。 
非空白password值代表加密的口令。 mysql不以任何人可以看的純文本格式存儲口令,相反,正在試圖聯(lián)接的一個(gè)用戶提供的口令被加密(使用password()函數(shù)),并且與存儲了user表中的已經(jīng)加密的版本比較。如果他們匹配,口令是正確的。 

下面的例子顯示出各種user表中host和user條目的值的組合如何應(yīng)用于到來的連接: 

host 值               user 值      被條目匹配的連接  
'thomas.loc.gov'      'fred'       fred, 從thomas.loc.gov 連接 
'thomas.loc.gov'      ''           任何用戶, 從thomas.loc.gov連接  
'%'                   'fred'       fred, 從任何主機(jī)連接 
'%'                   ''           任何用戶, 從任何主機(jī)連接 
'%.loc.gov'           'fred'       fred, 從在loc.gov域的任何主機(jī)連接 
'x.y.%'               'fred'       fred, 從x.y.net、x.y.com,x.y.edu等聯(lián)接。(這或許無用) 
'144.155.166.177'     'fred'       fred, 從有144.155.166.177 ip 地址的主機(jī)連接 
'144.155.166.%'       'fred'       fred, 從144.155.166 c類子網(wǎng)的任何主機(jī)連接 

既然你能在host字段使用ip通配符值(例如,'144.155.166.%'匹配在一個(gè)子網(wǎng)上的每臺主機(jī)),有可能某人可能企圖探究這種能力,通過命名一臺主機(jī)為144.155.166.somewhere.com。為了阻止這樣的企圖,mysql不允許匹配以數(shù)字和一個(gè)點(diǎn)起始的主機(jī)名,這樣,如果你用一個(gè)命名為類似1.2.foo.com的主機(jī),它的名字決不會匹配授權(quán)表中host列。只有一個(gè)ip數(shù)字能匹配ip通配符值。 

一個(gè)到來的連接可以被在user表中的超過一個(gè)條目匹配。例如,一個(gè)由fred從thomas.loc.gov的連接匹配多個(gè)條目如上所述。如果超過一個(gè)匹配,服務(wù)器怎么選擇使用哪個(gè)條目呢?服務(wù)器在啟動時(shí)讀入user表后通過排序來解決這個(gè)問題,然后當(dāng)一個(gè)用戶試圖連接時(shí),以排序的順序?yàn)g覽條目,第一個(gè)匹配的條目被使用。 

user表排序工作如下,假定user表看起來像這樣: 

+-----------+----------+-
| host      | user     | ...
+-----------+----------+-
| %         | root     | ...
| %         | jeffrey  | ...
| localhost | root     | ...
| localhost |          | ...
+-----------+----------+-

當(dāng)服務(wù)器在表中讀取時(shí),它以最特定的host值為先的次序排列('%'在host列里意味著“任何主機(jī)”并且是最不特定的)。有相同host值的條目以最特定的user值為先的次序排列(一個(gè)空白u(yù)ser值意味著“任何用戶”并且是最不特定的)。最終排序的user表看起來像這樣: 

+-----------+----------+-
| host      | user     | ...
+-----------+----------+-
| localhost | root     | ...
| localhost |          | ...
| %         | jeffrey  | ...
| %         | root     | ...
+-----------+----------+-

當(dāng)一個(gè)連接被嘗試時(shí),服務(wù)器瀏覽排序的條目并使用找到的第一個(gè)匹配。對于由jeffrey從localhost的一個(gè)連接,在host列的'localhost'條目首先匹配。那些有空白用戶名的條目匹配連接的主機(jī)名和用戶名。('%'/'jeffrey'條目也將匹配,但是它不是在表中的第一匹配。)

這是另外一個(gè)例子。假定user表看起來像這樣: 

+----------------+----------+-
| host           | user     | ...
+----------------+----------+-
| %              | jeffrey  | ...
| thomas.loc.gov |          | ...
+----------------+----------+-

排序后的表看起來像這樣: 

+----------------+----------+-
| host           | user     | ...
+----------------+----------+-
| thomas.loc.gov |          | ...
| %              | jeffrey  | ...
+----------------+----------+-

一個(gè)由jeffrey從thomas.loc.gov的連接被第一個(gè)條目匹配,而一個(gè)由jeffrey從whitehouse.gov的連接被第二個(gè)匹配。 

普遍的誤解是認(rèn)為,對一個(gè)給定的用戶名,當(dāng)服務(wù)器試圖對連接尋找匹配時(shí),明確命名那個(gè)用戶的所有條目將首先被使用。這明顯不是事實(shí)。先前的例子說明了這點(diǎn),在那里一個(gè)由jeffrey從thomas.loc.gov的連接沒被包含'jeffrey'作為user字段值的條目匹配,但是由沒有用戶名的題目匹配! 

如果你有服務(wù)器連接的問題,打印出user表并且手工排序它看看第一個(gè)匹配在哪兒進(jìn)行。 

6.8 存取控制,階段2:請求證實(shí)
一旦你建立了一個(gè)連接,服務(wù)器進(jìn)入階段2。對在此連接上進(jìn)來的每個(gè)請求,服務(wù)器檢查你是否有足夠的權(quán)限來執(zhí)行它,它基于你希望執(zhí)行的操作類型。這正是在授權(quán)表中的權(quán)限字段發(fā)揮作用的地方。這些權(quán)限可以來子user、db、host、tables_priv或columns_priv表的任何一個(gè)。授權(quán)表用grant和revoke命令操作。見7.26 grant和revoke 句法。(你可以發(fā)覺參考6.6 權(quán)限系統(tǒng)怎樣工作很有幫助,它列出了在每個(gè)權(quán)限表中呈現(xiàn)的字段。)

user表在一個(gè)全局基礎(chǔ)上授予賦予你的權(quán)限,該權(quán)限不管當(dāng)前的數(shù)據(jù)庫是什么均適用。例如,如果user表授予你delete權(quán)限, 你可以刪除在服務(wù)器主機(jī)上從任何數(shù)據(jù)庫刪除行!換句話說,user表權(quán)限是超級用戶權(quán)限。只把user表的權(quán)限授予超級用戶如服務(wù)器或數(shù)據(jù)庫主管是明智的。對其他用戶,你應(yīng)該把在user表中的權(quán)限設(shè)成'n'并且僅在一個(gè)特定數(shù)據(jù)庫的基礎(chǔ)上授權(quán), 使用db和host表。 

db和host表授予數(shù)據(jù)庫特定的權(quán)限。在范圍字段的值可以如下被指定: 

通配符字符“%”和“_”可被用于兩個(gè)表的host和db字段。 
在db表的'%'host值意味著“任何主機(jī)”,在db表中一個(gè)空白host值意味著“對進(jìn)一步的信息咨詢host表”。 
在host表的一個(gè)'%'或空白host值意味著“任何主機(jī)”。 
在兩個(gè)表中的一個(gè)'%'或空白db值意味著“任何數(shù)據(jù)庫”。 
在兩個(gè)表中的一個(gè)空白u(yù)ser值匹配匿名用戶。 

db和host表在服務(wù)器啟動時(shí)被讀取和排序(同時(shí)它讀user表)。db表在host、db和user范圍字段上排序,并且host表在host和db范圍字段上排序。對于user表,排序首先放置最特定的值然后最后最不特定的值,并且當(dāng)服務(wù)器尋找匹配入條目時(shí),它使用它找到的第一個(gè)匹配。 

tables_priv和columns_priv表授予表和列特定的權(quán)限。在范圍字段的值可以如下被指定: 

通配符“%”和“_”可用在使用在兩個(gè)表的host字段。 
在兩個(gè)表中的一個(gè)'%'或空白host意味著“任何主機(jī)”。 
在兩個(gè)表中的db、table_name和column_name字段不能包含通配符或空白。 

tables_priv和columns_priv表在host、db和user字段上被排序。這類似于db表的排序,盡管因?yàn)橹挥衕ost字段可以包含通配符,但排序更簡單。 

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

對管理請求(shutdown、reload等等),服務(wù)器僅檢查user表?xiàng)l目,因?yàn)槟鞘俏ㄒ恢付ü芾頇?quán)限的表。如果條目許可請求的操作,存取被授權(quán)了,否則拒絕。例如,如果你想要執(zhí)行mysqladmin shutdown,但是你的user表?xiàng)l目沒有為你授予shutdown權(quán)限,存取甚至不用檢查db或host表就被拒絕。(因?yàn)樗麄儾话瑂hutdown_priv行列,沒有這樣做的必要。)

對數(shù)據(jù)庫有關(guān)的請求(insert、update等等),服務(wù)器首先通過查找user表?xiàng)l目來檢查用戶的全局(超級用戶)權(quán)限。如果條目允許請求的操作,存取被授權(quán)。如果在user表中全局權(quán)限不夠,服務(wù)器通過檢查db和host表確定特定的用戶數(shù)據(jù)庫權(quán)限: 

服務(wù)器在db表的host、db和user字段上查找一個(gè)匹配。 host和user對應(yīng)連接用戶的主機(jī)名和mysql用戶名。db字段對應(yīng)用戶想要存取的數(shù)據(jù)庫。如果沒有host和user的條目,存取被拒絕。 
如果db表中的條目有一個(gè)匹配而且它的host字段不是空白的,該條目定義用戶的數(shù)據(jù)庫特定的權(quán)限。 
如果匹配的db表的條目的host字段是空白的,它表示host表列舉主機(jī)應(yīng)該被允許存取數(shù)據(jù)庫的主機(jī)。在這種情況下,在host表中作進(jìn)一步查找以發(fā)現(xiàn)host和db字段上的匹配。如果沒有host表?xiàng)l目匹配,存取被拒絕。如果有匹配,用戶數(shù)據(jù)庫特定的權(quán)限以在db和host表的條目的權(quán)限,即在兩個(gè)條目都是'y'的權(quán)限的交集(而不是并集!)計(jì)算。(這樣你可以授予在db表?xiàng)l目中的一般權(quán)限,然后用host表?xiàng)l目按一個(gè)主機(jī)一個(gè)主機(jī)為基礎(chǔ)地有選擇地限制它們。) 

在確定了由db和host表?xiàng)l目授予的數(shù)據(jù)庫特定的權(quán)限后,服務(wù)器把他們加到由user表授予的全局權(quán)限中。如果結(jié)果允許請求的操作,存取被授權(quán)。否則,服務(wù)器檢查在tables_priv和columns_priv表中的用戶的表和列權(quán)限并把它們加到用戶權(quán)限中。基于此結(jié)果允許或拒絕存取。 

用布爾術(shù)語表示,前面關(guān)于一個(gè)用戶權(quán)限如何計(jì)算的描述可以這樣總結(jié): 

global privileges
or (database privileges and host privileges)
or table privileges
or column privileges

它可能不明顯,為什么呢,如果全局user條目的權(quán)限最初發(fā)現(xiàn)對請求的操作不夠,服務(wù)器以后把這些權(quán)限加到數(shù)據(jù)庫、表和列的特定權(quán)限。原因是一個(gè)請求可能要求超過一種類型的權(quán)限。例如,如果你執(zhí)行一個(gè)insert ... select語句,你就都要insert和select權(quán)限。你的權(quán)限必須如此以便user表?xiàng)l目授予一個(gè)權(quán)限而db表?xiàng)l目授予另一個(gè)。在這種情況下,你有必要的權(quán)限執(zhí)行請求,但是服務(wù)器不能自己把兩個(gè)表區(qū)別開來;兩個(gè)條目授予的權(quán)限必須組合起來。 

host表能被用來維護(hù)一個(gè)“安全”服務(wù)器列表。在tcx,host表包含一個(gè)在本地的網(wǎng)絡(luò)上所有的機(jī)器的表,這些被授予所有的權(quán)限。 

你也可以使用host表指定不安全的主機(jī)。假定你有一臺機(jī)器public.your.domain,它位于你不認(rèn)為是安全的一個(gè)公共區(qū)域,你可以用下列的host表?xiàng)l目子允許除了那臺機(jī)器外的網(wǎng)絡(luò)上所有主機(jī)的存取: 

+--------------------+----+-
| host               | db | ...
+--------------------+----+-
| public.your.domain | %  | ... (所有權(quán)限設(shè)為 'n')
| %.your.domain      | %  | ... (所有權(quán)限設(shè)為 'y')
+--------------------+----+-

當(dāng)然,你應(yīng)該總是測試你在授權(quán)表中的條目(例如,使用mysqlaccess)讓你確保你的存取權(quán)限實(shí)際上以你認(rèn)為的方式被設(shè)置。 

6.9 權(quán)限更改何時(shí)生效
當(dāng)mysqld啟動時(shí),所有的授權(quán)表內(nèi)容被讀進(jìn)存儲器并且從那點(diǎn)生效。 

用grant、revoke或set password對授權(quán)表施行的修改會立即被服務(wù)器注意到。 

如果你手工地修改授權(quán)表(使用insert、update等等),你應(yīng)該執(zhí)行一個(gè)flush privileges語句或運(yùn)行mysqladmin flush-privileges告訴服務(wù)器再裝載授權(quán)表,否則你的改變將不生效,除非你重啟服務(wù)器。 

當(dāng)服務(wù)器注意到授權(quán)表被改變了時(shí),現(xiàn)存的客戶連接有如下影響: 

表和列權(quán)限在客戶的下一次請求時(shí)生效。 
數(shù)據(jù)庫權(quán)限改變在下一個(gè)use db_name命令生效。 
全局權(quán)限的改變和口令改變在下一次客戶連接時(shí)生效。 


6.10 建立初始的mysql權(quán)限
在安裝mysql后,你通過運(yùn)行scripts/mysql_install_db安裝初始的存取權(quán)限。見4.7.1 快速安裝概述。 scripts/mysql_install_db腳本啟動mysqld服務(wù)器,然后初始化授權(quán)表,包含下列權(quán)限集合: 

mysql root用戶作為可做任何事情的一個(gè)超級用戶被創(chuàng)造。連接必須由本地主機(jī)發(fā)出。注意:出世的root口令是空的,因此任何人能以root而沒有一個(gè)口令進(jìn)行連接并且被授予所有權(quán)限。 
一個(gè)匿名用戶被創(chuàng)造,他可對有一個(gè)'test'或以'test_'開始的名字的數(shù)據(jù)庫做任何時(shí)期事情,連接必須由本地主機(jī)發(fā)出。這意味著任何本地用戶能連接并且視為匿名用戶。 
其他權(quán)限被拒絕。例如,一般用戶不能使用mysqladmin shutdown或mysqladmin processlist。 
注意:對win32的初始權(quán)限是不同的。見4.12.4 在win32上運(yùn)行mysql。 

既然你的安裝初始時(shí)廣開大門,你首先應(yīng)該做的事情之一是為mysql root用戶指定一個(gè)口令。你可以做如下(注意,你使用password()函數(shù)指定口令): 

shell> mysql -u root mysql
mysql> update user set password=password('new_password')
           where user='root';
mysql> flush privileges;

在mysql 3.22和以上版本中,你可以使用set password語句: 

shell> mysql -u root mysql
mysql> set password for root=password('new_password');

設(shè)置口令的另一種方法是使用mysqladmin命令: 

shell> mysqladmin -u root password new_password 

注意:如果你使用第一種方法在user表里直接更新口令,你必須告訴服務(wù)器再次讀入授權(quán)表(用flush privileges),因?yàn)榉駝t改變將不被注意到。 

一旦root口令被設(shè)置,此后當(dāng)你作為root與服務(wù)器連接時(shí),你必須供應(yīng)那個(gè)口令。 

你可能希望讓root口令為空白以便當(dāng)你施行附加的安裝時(shí),你不需要指定它或測試,但是保證在任何真實(shí)的生產(chǎn)工作中使用你的安裝之前,設(shè)置它。 

看看scripts/mysql_install_db腳本,看它如何安裝缺省的權(quán)限。你可用它作為一個(gè)研究如何增加其他用戶的基礎(chǔ)。 

如果你想要初始的權(quán)限不同于上面描述的那些,在你運(yùn)行mysql_install_db之前,你可以修改它。 

為了完全重建權(quán)限表,刪除在包含mysql數(shù)據(jù)庫的目錄下所有“*.frm”,“*.myi”和“*.myd”文件。(這是在數(shù)據(jù)庫目錄下面命名為“mysql”的目錄,當(dāng)你運(yùn)行mysqld --help時(shí),它被列出。)然后運(yùn)行mysql_install_db腳本,可能在首先編輯它擁有你想要的權(quán)限之后。 

注意:對于比mysql 3.22.10舊的版本,你不應(yīng)該刪除“*.frm”文件。如果你偶然做了,你應(yīng)該在運(yùn)行mysql_install_db之前你的mysql分發(fā)中拷回它們。 

6.11 向mysql增加新用戶權(quán)限
你可以有2個(gè)不同的方法增加用戶:通過使用grant語句或通過直接操作mysql授權(quán)表。比較好的方法是使用grant語句,因?yàn)樗麄兪歉喢鞑⑶液孟皴e誤少些。 

下面的例子顯示出如何使用mysql客戶安裝新用戶。這些例子假定權(quán)限根據(jù)以前的章節(jié)描述的缺省被安裝。這意味著為了改變,你必須在mysqld正在運(yùn)行同一臺機(jī)器上,你必須作為mysql root用戶連接,并且root用戶必須對mysql數(shù)據(jù)庫有insert權(quán)限和reload管理權(quán)限。另外,如果你改變了root用戶口令,你必須如下的mysql命令指定它。 

你可以通過發(fā)出grant語句增加新用戶: 

shell> mysql --user=root mysql
mysql> grant all privileges on *.* to [email protected]
           identified by 'something' with grant option;
mysql> grant all privileges on *.* to [email protected]"%"
           identified by 'something' with grant option;
mysql> grant reload,process on *.* to [email protected];
mysql> grant usage on *.* to [email protected];

這些grant語句安裝3個(gè)新用戶: 

monty 
可以從任何地方連接服務(wù)器的一個(gè)完全的超級用戶,但是必須使用一個(gè)口令('something'做這個(gè)。注意,我們必須對[email protected]和[email protected]"%"發(fā)出grant語句。如果我們增加localhost條目,對localhost的匿名用戶條目在我們從本地主機(jī)連接接時(shí)由mysql_install_db創(chuàng)建的條目將優(yōu)先考慮,因?yàn)樗懈囟ǖ膆ost字段值,所以以user表排列順序看更早到來。 
admin 
可以從localhost沒有一個(gè)口令進(jìn)行連接并且被授予reload和process管理權(quán)限的用戶。這允許用戶執(zhí)行mysqladmin reload、mysqladmin refresh和mysqladmin flush-*命令,還有mysqladmin processlist。沒有授予數(shù)據(jù)庫有關(guān)的權(quán)限。他們能在以后通過發(fā)出另一個(gè)grant語句授權(quán)。 
dummy 
可以不用一個(gè)口令連接的一個(gè)用戶,但是只能從本地主機(jī)。全局權(quán)限被設(shè)置為'n'--usage權(quán)限類型允許你無需權(quán)限就可設(shè)置一個(gè)用戶。它假定你將在以后授予數(shù)據(jù)庫相關(guān)的權(quán)限。 
你也可以直接通過發(fā)出insert語句增加同樣的用戶存取信息,然后告訴服務(wù)器再次裝入授權(quán)表: 

shell> mysql --user=root mysql
mysql> insert into user values('localhost','monty',password('something'),
                'y','y','y','y','y','y','y','y','y','y','y','y','y','y')
mysql> insert into user values('%','monty',password('something'),
                'y','y','y','y','y','y','y','y','y','y','y','y','y','y')
mysql> insert into user set host='localhost',user='admin',
                 reload_priv='y', process_priv='y';
mysql> insert into user (host,user,password)
                        values('localhost','dummy','');
mysql> flush privileges;

取決于你的mysql版本,對上述,你可能必須使用一個(gè)不同數(shù)目'y'值(在3.22.11以前的版本有更少的權(quán)限列)。對admin用戶,只用在3.22.11開始的版本具有的更加可讀的insert擴(kuò)充的語法。 

注意,為了設(shè)置一個(gè)超級用戶,你只需創(chuàng)造一個(gè)user表?xiàng)l目,其權(quán)限字段設(shè)為'y'。不需要db或host表的條目。 

在user表中的權(quán)限列不是由最后一個(gè)insert語句明確設(shè)置的(對dummy用戶),因此那些列被賦予缺省值'n'。這是grant usage做的同樣的事情。 

下列例子增加一個(gè)用戶custom,他能從主機(jī)localhost、server.domain和whitehouse.gov連接。他只想要從localhost存取bankaccount數(shù)據(jù)庫,從whitehouse.gov存取expenses數(shù)據(jù)庫和從所有3臺主機(jī)存取customer數(shù)據(jù)庫。他想要從所有3臺主機(jī)上使用口令stupid。 

為了使用grant語句設(shè)置個(gè)用戶的權(quán)限,運(yùn)行這些命令: 

shell> mysql --user=root mysql
mysql> grant select,insert,update,delete,create,drop
           on bankaccount.*
           to [email protected]
           identified by 'stupid';
mysql> grant select,insert,update,delete,create,drop
           on expenses.*
           to [email protected]
           identified by 'stupid';
mysql> grant select,insert,update,delete,create,drop
           on customer.*
           to [email protected]'%'
           identified by 'stupid';

通過直接修改授權(quán)表設(shè)置用戶權(quán)限,運(yùn)行這些命令(注意,在結(jié)束時(shí)flush privileges): 

shell> mysql --user=root mysql
mysql> insert into user (host,user,password)
       values('localhost','custom',password('stupid'));
mysql> insert into user (host,user,password)
       values('server.domain','custom',password('stupid'));
mysql> insert into user (host,user,password)
       values('whitehouse.gov','custom',password('stupid'));
mysql> insert into db
       (host,db,user,select_priv,insert_priv,update_priv,delete_priv,
        create_priv,drop_priv)
       values
       ('localhost','bankaccount','custom','y','y','y','y','y','y');
mysql> insert into db
       (host,db,user,select_priv,insert_priv,update_priv,delete_priv,
        create_priv,drop_priv)
       values
       ('whitehouse.gov','expenses','custom','y','y','y','y','y','y');
mysql> insert into db
       (host,db,user,select_priv,insert_priv,update_priv,delete_priv,
        create_priv,drop_priv)
       values('%','customer','custom','y','y','y','y','y','y');
mysql> flush privileges;

頭3個(gè)insert語句增加user表?xiàng)l目,允許用戶custom用給定口令從不同的主機(jī)進(jìn)行連接,但是沒有授予任何許可(所有權(quán)限被設(shè)置為缺省值'n')。后3個(gè)insert語句增加db表?xiàng)l目,授予custom以bankaccount、expenses和customer數(shù)據(jù)庫權(quán)限,但是只能在從正確的主機(jī)存取時(shí)。通常,在授權(quán)表直接被修改時(shí),服務(wù)器必須被告知再次裝入他們(用flush privileges)以便使權(quán)限修改生效。

如果你想要給特定的用戶從一個(gè)給定的域上的任何機(jī)器上存取權(quán)限,你可以發(fā)出一個(gè)如下的grant語句: 

mysql> grant ...
           on *.*
           to [email protected]"%.mydomainname.com"
           identified by 'mypassword';

為了通過直接修改授權(quán)表做同樣的事情,這樣做: 

mysql> insert into user values ('%.mydomainname.com', 'myusername',
           password('mypassword'),...);
mysql> flush privileges;

你也可以使用xmysqladmin、mysql_webadmin甚至xmysql在授權(quán)表中插入、改變和更新值。你可以在mysql的contrib目錄找到這些實(shí)用程序。 

6.12 怎樣設(shè)置口令
在前面小節(jié)的例子里說明了一個(gè)重要的原則:當(dāng)你使用insert或update語句存儲一個(gè)非空的口令時(shí),你必須使用password()函數(shù)加密它。這是因?yàn)樵趗ser表中以加密形式存儲口令,而不是作為純文本。如果你忘記這個(gè)事實(shí),你可能像這樣試圖設(shè)置口令: 

shell> mysql -u root mysql 
mysql> insert into user (host,user,password) values('%','jeffrey','biscuit'); 
mysql> flush privileges

結(jié)果是純文本值'biscuit'作為口令被存儲在user表中。在用戶jeffrey試圖用這個(gè)口令連接服務(wù)器時(shí),mysql客戶用password()加密它并且將結(jié)果送給服務(wù)器,服務(wù)器比較在user表中的值(它是純文本值'biscuit')和加密的口令(而不是 'biscuit'),比較失敗并且服務(wù)器拒絕連接: 

shell> mysql -u jeffrey -pbiscuit test
access denied

因?yàn)楫?dāng)他們被插入user表時(shí),口令必須被加密,相反,insert語句應(yīng)該象這樣被指定: 

mysql> insert into user (host,user,password)
       values('%','jeffrey',password('biscuit'));

當(dāng)你使用set password語句時(shí),你也必須使用password()函數(shù): 

mysql> set password for [email protected]"%" = password('biscuit'); 

如果你使用grant ... identified by語句或mysqladmin password命令設(shè)置口令,password()函數(shù)是不必要的。他們都考慮到為你加密口令,多以你可像這樣指定一個(gè)口令'biscuit': 

mysql> grant usage on *.* to [email protected]"%" identified by 'biscuit';



shell> mysqladmin -u jeffrey password biscuit 

注意: password()不是以在unix口令加密的同樣方法施行口令加密。你不應(yīng)該假定如果你的unix口令和你的mysql口令是一樣的,password()將導(dǎo)致與在unix口令文件被存儲的同樣的加密值。見6.2 mysql 用戶名和口令。 

6.13 access denied錯誤的原因

當(dāng)你試著聯(lián)接mysql服務(wù)器時(shí),如果你碰到access denied錯誤,顯示在下面的表指出一些你能用來更正這個(gè)問題的動作: 

你是在安裝mysql以后運(yùn)行mysql_install_db的腳本,來設(shè)置初始授權(quán)表內(nèi)容嗎?如果不是,這樣做。見6.10 設(shè)置初始mysql權(quán)限。通過執(zhí)行這個(gè)命令測試初始權(quán)限: 
shell> mysql -u root test 

服務(wù)器應(yīng)該讓你無誤地連接。你也應(yīng)該保證你在mysql數(shù)據(jù)庫目錄有一個(gè)文件“user.myd”。通常,它是“path/var/mysql/user.myd”,在此path是mysql安裝根目錄的路徑。 

在一個(gè)新的安裝以后,你應(yīng)該連接服務(wù)器并且設(shè)置你的用戶及其存取許可: 
shell> mysql -u root mysql 

服務(wù)器應(yīng)該讓你連接,因?yàn)閙ysql root用戶初始時(shí)沒有口令。既然那也是一個(gè)安全風(fēng)險(xiǎn),當(dāng)你正在設(shè)置其他mysql用戶時(shí),設(shè)定root口令是一件重要的事請。如果你作為root嘗試連接并且得到這個(gè)錯誤: 

access denied for user: '@unknown' to database mysql 

這意味著,你沒有一個(gè)條目在user表中的一個(gè)user列值為'root'并且mysqld不能為你的客庫解析主機(jī)名。在這種情況下,你必須用--skip-grant-tables選項(xiàng)重啟服務(wù)器并且編輯你的“/etc/hosts”或“windowshosts”文件為你的主機(jī)增加一個(gè)條目。 

如果你從一個(gè)3.22.11以前的版本更新一個(gè)現(xiàn)存的mysql安裝到3.22.11版或以后版本,你運(yùn)行了mysql_fix_privilege_tables腳本嗎?如果沒有,運(yùn)行它。在grant語句變得能工作時(shí),授權(quán)表的結(jié)構(gòu)用mysql 3.22.11修改 。 
如果你直接對授權(quán)表做修改(使用insert或update語句)并且你的改變似乎被忽略,記住,你必須發(fā)出一個(gè)flush privileges語句或執(zhí)行一個(gè)mysqladmin flush-privileges命令導(dǎo)致服務(wù)器再次讀入表,否則你的改變要道下一次服務(wù)器被重啟時(shí)再生效。記住在你設(shè)定root口令以后,你將不需要指定它,直到在你清洗(flush)權(quán)限以后,因?yàn)榉?wù)器仍然不會知道你改變了口令! 
如果你的權(quán)限似乎在一個(gè)會話(session)當(dāng)中改變了,可能是一個(gè)超級用戶改變了他們。再次裝入授權(quán)表作用于新客戶連接,但是它也影響現(xiàn)存的連接,如6.9 權(quán)限改變何時(shí)生效小節(jié)所述。 
為了測試,用--skip-grant-tables選項(xiàng)啟動mysqld守護(hù)進(jìn)程,然后你可以改變mysql授權(quán)表并且使用mysqlaccess腳本檢查你的修改是否有如期的效果。當(dāng)你對你的改變滿意時(shí),執(zhí)行mysqladmin flush-privileges告訴mysqld服務(wù)器開始使用新的權(quán)限表。注意:再次裝入授權(quán)表覆蓋了--skip-grant-tables選項(xiàng)。這允許你告訴服務(wù)器開始使用授權(quán)表,而不用停掉并重啟它。 
如果你有一個(gè)perl、python或odbc程序的存取問題,試著用mysql -u user_name db_name或mysql -u user_name -pyour_pass db_name與服務(wù)器連接。如果你能用mysql客戶連接,這是你程序的一個(gè)問題而不是存取權(quán)限的問題。(注意在-p和口令之間沒有空格;你也能使用--password=your_pass句法指定口令。) 
如果你不能讓口令工作,記得如果你用insert, update或set password語句設(shè)置口令,你必須使用password()函數(shù)。如果你用grant ... indentified by語句或mysqladmin password命令指定口令,password()函數(shù)是不需要的。見6.12 怎樣設(shè)置口令。 
localhost是你本地主機(jī)名的一個(gè)同義詞,并且也是如果你不明確地指定主機(jī)而客戶嘗試連接的缺省主機(jī)。然而,如果你正在運(yùn)行于一個(gè)使用mit-pthreads的系統(tǒng)上,連接localhost是不行的(localhost連接使用unix套接字進(jìn)行,它沒被 mit-pthreads支持),為了在這樣的系統(tǒng)上避免這個(gè)問題,你應(yīng)該使用--host選項(xiàng)明確地命名服務(wù)器主機(jī),這將做一個(gè) tcp/ip連接到mysqld服務(wù)器。在這種情況下,你必須有在服務(wù)器主機(jī)上的user表中條目的你真實(shí)的主機(jī)名。(即使你在服務(wù)器同一臺的主機(jī)上運(yùn)行一個(gè)客戶程序,這也是真的。) 
當(dāng)嘗試用mysql -u user_name db_name與數(shù)據(jù)庫連接時(shí),如果你得到一個(gè)access denied錯誤,你可能有與user桌有關(guān)的問題,通過執(zhí)行mysql -u root mysql并且發(fā)出下面的sql語句檢查: 
mysql> select * from user; 

結(jié)果應(yīng)該包含一個(gè)有host和user列的條目匹配你的計(jì)算機(jī)主機(jī)名和你的mysql用戶名。 

access denied錯誤消息將告訴你,你正在用哪個(gè)用戶嘗試登錄,你正在試圖用連接哪個(gè)主機(jī),并且你是否正在使用一個(gè)口令。通常,你應(yīng)該在user表中有一個(gè)條目,正確地匹配在錯誤消息給出的主機(jī)名和用戶名。 
如果當(dāng)你試著從一個(gè)不是mysql服務(wù)器正在運(yùn)行的主機(jī)上連接時(shí),你得到下列錯誤,那么在user表中沒有匹配那臺主機(jī)行: 
host ... is not allowed to connect to this mysql server 

你可以通過使用mysql命令行工具(在服務(wù)器主機(jī)上!)修正它,把你正在試圖連接的用戶/主機(jī)名組合新加一行到user表中。如果你不在運(yùn)行mysql 3.22并且你不知道你正在從它連接的機(jī)器的ip數(shù)字或主機(jī)名,你應(yīng)該把一個(gè)'%'條目作為host列值放在user表中并且在服務(wù)器機(jī)器上使用--log選項(xiàng)重啟mysqld。在試圖從客戶機(jī)器連接以后,在mysql記錄文件中的信息將顯示你如何真正進(jìn)行連接。(然后用在記錄文件上面顯示出的實(shí)際的主機(jī)名代替user表中的'%'條目。否則,你將有一個(gè)不安全的系統(tǒng)。)

如果mysql -u root test工作但是mysql -h your_hostname -u root test導(dǎo)致access denied,那么在user表中你可能沒有你的主機(jī)的正確名字。這里的一個(gè)普遍的問題是在user表?xiàng)l目中的host值指定一個(gè)唯一的主機(jī)名,但是你系統(tǒng)的名字解析例程返回一個(gè)完全正規(guī)的域名(或相反)。例如,如果你在user表中有一個(gè)主機(jī)是'tcx'的條目,但是你的 dns告訴mysql你的主機(jī)名是'tcx.subnet.se',條目將不工作。嘗試把一個(gè)條目加到user表中,它包含你主機(jī)的ip數(shù)字作為host列的值。(另外,你可以把一個(gè)條目加到user表中,它有包含一個(gè)通配符如'tcx.%'的host值。然而,使用以“%”結(jié)尾的主機(jī)名是不安全的并且不推薦!) 
如果mysql -u user_name test工作但是mysql -u user_name other_db_name不工作,對other_db_name,你在db表中沒有沒有一個(gè)條目列出。 
當(dāng)在服務(wù)器機(jī)器上執(zhí)行mysql -u user_name db_name時(shí),它工作,但是在其它客戶機(jī)器上執(zhí)行mysql -h host_name -u user_name db_name時(shí),它卻不工作,你沒有把客戶機(jī)器列在user表或db表中。 
如果你不能弄明白你為什么得到access denied,從user表中刪除所有host包含通配符值的條目(包含“%”或“_”的條目)。一個(gè)很普遍的錯誤是插入用host='%'和user='some user'插入一個(gè)新條目,認(rèn)為這將允許你指定localhost從同一臺機(jī)器進(jìn)行連接。它不工作的原因是缺省權(quán)限包括一個(gè)有host='localhost'和user=''的條目,因?yàn)槟莻€(gè)條目一個(gè)比'%'更具體的host值'localhost',當(dāng)從localhost連接時(shí),它用于指向新條目!正確的步驟是插入host='localhost'和user='some_user'的第2個(gè)條目,或刪除host='localhost'和user=''條目。 
如果你得到下列錯誤,你可以有一個(gè)與db或host表有關(guān)的問題: 
access to database denied

如果從db表中選擇了在host列有空值的條目,保證在host表中有一個(gè)或多個(gè)相應(yīng)的條目,指定運(yùn)用db表中的哪些主機(jī)。如果在使用sql命令select ... into outfile或load data infile時(shí),你得到錯誤,在user表中的你的條目可能啟用file權(quán)限。 

記住,客戶程序?qū)⑹褂迷谂渲梦募颦h(huán)境變量被指定了的連接參數(shù)。如果當(dāng)你不在命令行上指定他們時(shí),一個(gè)客戶似乎正在發(fā)送錯誤的缺省連接參數(shù),檢查你的環(huán)境和在你的主目錄下的“.my.cnf”文件。你也可以檢查系統(tǒng)范圍的mysql配置文件,盡管更不可能將在那里指定那個(gè)客戶的連接參數(shù)。見4.15.4 選項(xiàng)文件。如果當(dāng)你沒有任何選項(xiàng)運(yùn)行一個(gè)客戶時(shí),你得到access denied,確認(rèn)你沒在任何選項(xiàng)文件里指定一個(gè)舊的口令!見4.15.4 選項(xiàng)文件。 
如果任何其它事情失敗,用調(diào)試選項(xiàng)(例如,--debug=d,general,query)啟動mysqld守護(hù)進(jìn)程。這將打印有關(guān)嘗試連接的主機(jī)和用戶信息,和發(fā)出的每個(gè)命令的信息。見g.1 調(diào)試一個(gè)mysql服務(wù)器。 
如果你有任何與mysql授權(quán)表的其它問題,而且覺得你必須郵寄這個(gè)問題到郵寄表,總是提供一個(gè)mysql授權(quán)表的傾倒副本(dump)。你可用mysqldump mysql命令傾倒數(shù)據(jù)庫表。象平時(shí)一樣,用mysqlbug腳本郵寄你的問題。在一些情況下你可能用--skip-grant-tables重啟mysqld以便能運(yùn)行mysqldump。 

6.14 怎樣使mysql安全以對抗解密高手
當(dāng)你連接一個(gè)mysql服務(wù)器時(shí),你通常應(yīng)該使用一個(gè)口令。口令不以明文在連接上傳輸。 

所有其它信息作為能被任何人讀懂的文本被傳輸。如果你擔(dān)心這個(gè),你可使用壓縮協(xié)議(mysql3.22和以上版本)使事情變得更難。甚至為了使一切更安全,你應(yīng)該安裝ssh(見http://www.cs.hut.fi/ssh)。用它,你能在一個(gè)mysql服務(wù)器與一個(gè)mysql客戶之間得到一個(gè)加密的tcp/ip連接。 

為了使一個(gè)mysql系統(tǒng)安全,強(qiáng)烈要求你考慮下列建議: 

對所有mysql用戶使用口令。記住,如果other_user沒有口令,任何人能簡單地用mysql -u other_user db_name作為任何其它的人登錄。對客戶機(jī)/服務(wù)器應(yīng)用程序,客戶可以指定任何用戶名是常見的做法。在你運(yùn)行它以前,你可以通過編輯mysql_install_db腳本改變所有用戶的口令,或僅僅mysql root的口令,象這樣: 
shell> mysql -u root mysql
mysql> update user set password=password('new_password')
           where user='root';
mysql> flush privileges;

不要作為unix的root用戶運(yùn)行mysql守護(hù)進(jìn)程。mysqld能以任何用戶運(yùn)行,你也可以創(chuàng)造一個(gè)新的unix用戶mysql使一切更安全。如果你作為其它unix用戶運(yùn)行mysqld,你不需要改變在user表中的root用戶名,因?yàn)閙ysql用戶名與unix 用戶名沒關(guān)系。你可以作為其它unix用戶編輯mysql.server啟動腳本mysqld。通常這用su命令完成。對于更多的細(xì)節(jié),見18.8 怎樣作為一個(gè)一般用戶運(yùn)行mysql。 
如果你把一個(gè)unix root用戶口令放在mysql.server腳本中,確保這個(gè)腳本只能對root是可讀的。 
檢查那個(gè)運(yùn)行mysqld的unix用戶是唯一的在數(shù)據(jù)庫目錄下有讀/寫權(quán)限的用戶。 
不要把process權(quán)限給所有用戶。mysqladmin processlist的輸出顯示出當(dāng)前執(zhí)行的查詢正文,如果另外的用戶發(fā)出一個(gè)update user set password=password('not_secure')查詢,被允許執(zhí)行那個(gè)命令的任何用戶可能看得到。mysqld為有process權(quán)限的用戶保留一個(gè)額外的連接, 以便一個(gè)mysql root用戶能登錄并檢查,即使所有的正常連接在使用。 
不要把file權(quán)限給所有的用戶。有這權(quán)限的任何用戶能在擁有mysqld守護(hù)進(jìn)程權(quán)限的文件系統(tǒng)那里寫一個(gè)文件!為了使這更安全一些,用select ... into outfile生成的所有文件對每個(gè)人是可讀的,并且你不能覆蓋已經(jīng)存在的文件。file權(quán)限也可以被用來讀取任何作為運(yùn)行服務(wù)器的unix用戶可存取的文件。這可能被濫用,例如,通過使用load data裝載“/etc/passwd”進(jìn)一個(gè)數(shù)據(jù)庫表,然后它能用select被讀入。 
如果你不信任你的dns,你應(yīng)該在授權(quán)表中使用ip數(shù)字而不是主機(jī)名。原則上講,--secure選項(xiàng)對mysqld應(yīng)該使主機(jī)名更安全。在任何情況下,你應(yīng)該非常小心地使用包含通配符的主機(jī)名! 

下列mysqld選項(xiàng)影響安全: 

--secure 
       由gethostbyname()系統(tǒng)調(diào)用返回的ip數(shù)字被檢查,確保他們解析回到原來的主機(jī)名。這對某些外人通過模仿其它主機(jī)獲得存取權(quán)限變得更難。這個(gè)選項(xiàng)也增加一些聰明的主機(jī)名檢查。在mysql3.21里,選擇缺省是關(guān)掉的,因?yàn)樗袝r(shí)它花很長時(shí)間執(zhí)行反向解析。mysql 3.22緩存主機(jī)名并缺省地啟用了這個(gè)選項(xiàng)。 
--skip-grant-tables 
       這個(gè)選項(xiàng)導(dǎo)致服務(wù)器根本不使用權(quán)限系統(tǒng)。這給每個(gè)人以完全存取所有的數(shù)據(jù)庫的權(quán)力!(通過執(zhí)行mysqladmin reload,你能告訴一個(gè)正在運(yùn)行的服務(wù)器再次開始使用授權(quán)表。) 
--skip-name-resolve 
       主機(jī)名不被解析。所有在授權(quán)表的host的列值必須是ip數(shù)字或localhost。 
--skip-networking 
       在網(wǎng)絡(luò)上不允許tcp/ip連接。所有到mysqld的連接必須經(jīng)由unix套接字進(jìn)行。這個(gè)選項(xiàng)對使用mit-pthreads的系統(tǒng)是不合適的,因?yàn)閙it-pthreads包不支持unix套接字。 


責(zé)任編輯:eight(2001-06-07 09:40)
  • 本文來源于網(wǎng)頁設(shè)計(jì)愛好者web開發(fā)社區(qū)http://www.html.org.cn收集整理,歡迎訪問。
  • 發(fā)表評論 共有條評論
    用戶名: 密碼:
    驗(yàn)證碼: 匿名發(fā)表
    主站蜘蛛池模板: 延安市| 永修县| 苍南县| 泰安市| 祁门县| 江达县| 澄迈县| 乌鲁木齐县| 高阳县| 邓州市| 行唐县| 闸北区| 朔州市| 那曲县| 贵溪市| 五大连池市| 房山区| 珲春市| 宝山区| 勃利县| 河东区| 上饶县| 志丹县| 宁阳县| 玉山县| 吴忠市| 建水县| 霞浦县| 伊金霍洛旗| 正镶白旗| 南溪县| 宁乡县| 浮梁县| 濮阳市| 全南县| 长宁县| 托克托县| 金秀| 祁门县| 萝北县| 驻马店市|