?? manual_privilege_system.html
字號(hào):
<p>如果你想要初始的權(quán)限不同于上面描述的那些,在你運(yùn)行<code>mysql_install_db</code>之前,你可以修改它。
</p>
<p>為了完全重建權(quán)限表,刪除在包含<code>mysql</code>數(shù)據(jù)庫(kù)的目錄下所有<tt>“*.frm”</tt>,<tt>“*.MYI”</tt>和<tt>“*.MYD”</tt>文件。(這是在數(shù)據(jù)庫(kù)目錄下面命名為<tt>“mysql”</tt>的目錄,當(dāng)你運(yùn)行<code>mysqld
--help</code>時(shí),它被列出。)然后運(yùn)行<code>mysql_install_db</code>腳本,可能在首先編輯它擁有你想要的權(quán)限之后。
</p>
<p><strong>注意</strong>:對(duì)于比<strong>MySQL</strong> 3.22.10舊的版本,你不應(yīng)該刪除<tt>“*.frm”</tt>文件。如果你偶然做了,你應(yīng)該在運(yùn)行<code>mysql_install_db</code>之前你的<strong>MySQL</strong>分發(fā)中拷回它們。
</p>
<h2><a NAME="Adding_users" HREF="manual_toc.html#Adding_users">6.11 向MySQL增加新用戶(hù)權(quán)限</a></h2>
<p>你可以有2個(gè)不同的方法增加用戶(hù):通過(guò)使用<code>GRANT</code>語(yǔ)句或通過(guò)直接操作<strong>MySQL</strong>授權(quán)表。比較好的方法是使用<code>GRANT</code>語(yǔ)句,因?yàn)樗麄兪歉?jiǎn)明并且好像錯(cuò)誤少些。
</p>
<p>下面的例子顯示出如何使用<code>mysql</code>客戶(hù)安裝新用戶(hù)。這些例子假定權(quán)限根據(jù)以前的章節(jié)描述的缺省被安裝。這意味著為了改變,你必須在<code>mysqld</code>正在運(yùn)行同一臺(tái)機(jī)器上,你必須作為<strong>MySQL</strong>
<code>root</code>用戶(hù)連接,并且<code>root</code>用戶(hù)必須對(duì)<code>mysql</code>數(shù)據(jù)庫(kù)有<strong>insert</strong>權(quán)限和<strong>reload</strong>管理權(quán)限。另外,如果你改變了<code>root</code>用戶(hù)口令,你必須如下的<code>mysql</code>命令指定它。
</p>
<p>你可以通過(guò)發(fā)出<code>GRANT</code>語(yǔ)句增加新用戶(hù): </p>
<pre>shell> mysql --user=root mysql
mysql> GRANT ALL PRIVILEGES ON *.* TO monty@localhost
IDENTIFIED BY 'something' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO monty@"%"
IDENTIFIED BY 'something' WITH GRANT OPTION;
mysql> GRANT RELOAD,PROCESS ON *.* TO admin@localhost;
mysql> GRANT USAGE ON *.* TO dummy@localhost;
</pre>
<p>這些<code>GRANT</code>語(yǔ)句安裝3個(gè)新用戶(hù):
<dl COMPACT="Adding_users">
<dt><code>monty</code> </dt>
<dd>可以從任何地方連接服務(wù)器的一個(gè)完全的超級(jí)用戶(hù),但是必須使用一個(gè)口令(<code>'something'</code>做這個(gè)。注意,我們必須對(duì)<code>monty@localhost</code>和<code>monty@"%"</code>發(fā)出<code>GRANT</code>語(yǔ)句。如果我們?cè)黾?lt;code>localhost</code>條目,對(duì)<code>localhost</code>的匿名用戶(hù)條目在我們從本地主機(jī)連接接時(shí)由<code>mysql_install_db</code>創(chuàng)建的條目將優(yōu)先考慮,因?yàn)樗懈囟ǖ?lt;code>Host</code>字段值,所以以<code>user</code>表排列順序看更早到來(lái)。</dd>
<dt><code>admin</code> </dt>
<dd>可以從<code>localhost</code>沒(méi)有一個(gè)口令進(jìn)行連接并且被授予<strong>reload</strong>和<strong>process</strong>管理權(quán)限的用戶(hù)。這允許用戶(hù)執(zhí)行<code>mysqladmin
reload</code>、<code>mysqladmin refresh</code>和<code>mysqladmin flush-*</code>命令,還有<code>mysqladmin
processlist</code>。沒(méi)有授予數(shù)據(jù)庫(kù)有關(guān)的權(quán)限。他們能在以后通過(guò)發(fā)出另一個(gè)<code>GRANT</code>語(yǔ)句授權(quán)。
</dd>
<dt><code>dummy</code> </dt>
<dd>可以不用一個(gè)口令連接的一個(gè)用戶(hù),但是只能從本地主機(jī)。全局權(quán)限被設(shè)置為<code>'N'</code>--<code>USAGE</code>權(quán)限類(lèi)型允許你無(wú)需權(quán)限就可設(shè)置一個(gè)用戶(hù)。它假定你將在以后授予數(shù)據(jù)庫(kù)相關(guān)的權(quán)限。
</dd>
</dl>
<p>你也可以直接通過(guò)發(fā)出<code>INSERT</code>語(yǔ)句增加同樣的用戶(hù)存取信息,然后告訴服務(wù)器再次裝入授權(quán)表:
</p>
<pre>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;
</pre>
<p>取決于你的<strong>MySQL</strong>版本,對(duì)上述,你可能必須使用一個(gè)不同數(shù)目<code>'Y'</code>值(在3.22.11以前的版本有更少的權(quán)限列)。對(duì)<code>admin</code>用戶(hù),只用在3.22.11開(kāi)始的版本具有的更加可讀的<code>INSERT</code>擴(kuò)充的語(yǔ)法。
</p>
<p>注意,為了設(shè)置一個(gè)超級(jí)用戶(hù),你只需創(chuàng)造一個(gè)<code>user</code>表?xiàng)l目,其權(quán)限字段設(shè)為<code>'Y'</code>。不需要<code>db</code>或<code>host</code>表的條目。
</p>
<p>在<code>user</code>表中的權(quán)限列不是由最后一個(gè)<code>INSERT</code>語(yǔ)句明確設(shè)置的(對(duì)<code>dummy</code>用戶(hù)),因此那些列被賦予缺省值<code>'N'</code>。這是<code>GRANT
USAGE</code>做的同樣的事情。 </p>
<p>下列例子增加一個(gè)用戶(hù)<code>custom</code>,他能從主機(jī)<code>localhost</code>、<code>server.domain</code>和<code>whitehouse.gov</code>連接。他只想要從<code>localhost</code>存取<code>bankaccount</code>數(shù)據(jù)庫(kù),從<code>whitehouse.gov</code>存取<code>expenses</code>數(shù)據(jù)庫(kù)和從所有3臺(tái)主機(jī)存取<code>customer</code>數(shù)據(jù)庫(kù)。他想要從所有3臺(tái)主機(jī)上使用口令<code>stupid</code>。
</p>
<p>為了使用<code>GRANT</code>語(yǔ)句設(shè)置個(gè)用戶(hù)的權(quán)限,運(yùn)行這些命令: </p>
<pre>shell> mysql --user=root mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
ON bankaccount.*
TO custom@localhost
IDENTIFIED BY 'stupid';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
ON expenses.*
TO custom@whitehouse.gov
IDENTIFIED BY 'stupid';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
ON customer.*
TO custom@'%'
IDENTIFIED BY 'stupid';
</pre>
<p>通過(guò)直接修改授權(quán)表設(shè)置用戶(hù)權(quán)限,運(yùn)行這些命令(注意,在結(jié)束時(shí)<code>FLUSH
PRIVILEGES</code>): </p>
<pre>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;
</pre>
<p>頭3個(gè)<code>INSERT</code>語(yǔ)句增加<code>user</code>表?xiàng)l目,允許用戶(hù)<code>custom</code>用給定口令從不同的主機(jī)進(jìn)行連接,但是沒(méi)有授予任何許可(所有權(quán)限被設(shè)置為缺省值<code>'N'</code>)。后3個(gè)<code>INSERT</code>語(yǔ)句增加<code>db</code>表?xiàng)l目,授予<code>custom</code>以<code>bankaccount</code>、<code>expenses</code>和<code>customer</code>數(shù)據(jù)庫(kù)權(quán)限,但是只能在從正確的主機(jī)存取時(shí)。通常,在授權(quán)表直接被修改時(shí),服務(wù)器必須被告知再次裝入他們(用<code>FLUSH
PRIVILEGES</code>)以便使權(quán)限修改生效。</p>
<p>如果你想要給特定的用戶(hù)從一個(gè)給定的域上的任何機(jī)器上存取權(quán)限,你可以發(fā)出一個(gè)如下的<code>GRANT</code>語(yǔ)句:
</p>
<pre>mysql> GRANT ...
ON *.*
TO myusername@"%.mydomainname.com"
IDENTIFIED BY 'mypassword';
</pre>
<p>為了通過(guò)直接修改授權(quán)表做同樣的事情,這樣做: </p>
<pre>mysql> INSERT INTO user VALUES ('%.mydomainname.com', 'myusername',
PASSWORD('mypassword'),...);
mysql> FLUSH PRIVILEGES;
</pre>
<p>你也可以使用<code>xmysqladmin</code>、<code>mysql_webadmin</code>甚至<code>xmysql</code>在授權(quán)表中插入、改變和更新值。你可以在<strong>MySQL</strong>的<a HREF="http://www.mysql.com/Contrib/">Contrib目錄</a>找到這些實(shí)用程序。 </p>
<h2><a NAME="Passwords" HREF="manual_toc.html#Passwords">6.12 怎樣設(shè)置口令</a></h2>
<p>在前面小節(jié)的例子里說(shuō)明了一個(gè)重要的原則:當(dāng)你使用<code>INSERT</code>或<code>UPDATE</code>語(yǔ)句存儲(chǔ)一個(gè)非空的口令時(shí),你必須使用<code>PASSWORD()</code>函數(shù)加密它。這是因?yàn)樵?lt;code>user</code>表中以加密形式存儲(chǔ)口令,而不是作為純文本。如果你忘記這個(gè)事實(shí),你可能像這樣試圖設(shè)置口令:
</p>
<pre>shell> mysql -u root mysql
mysql> INSERT INTO user (Host,User,Password) VALUES('%','jeffrey','biscuit');
mysql> FLUSH PRIVILEGES
</pre>
<p>結(jié)果是純文本值<code>'biscuit'</code>作為口令被存儲(chǔ)在<code>user</code>表中。在用戶(hù)<code>jeffrey</code>試圖用這個(gè)口令連接服務(wù)器時(shí),<code>mysql</code>客戶(hù)用<code>PASSWORD()</code>加密它并且將結(jié)果送給服務(wù)器,服務(wù)器比較在<code>user</code>表中的值(它是純文本值<code>'biscuit'</code>)和加密的口令(<em>而不是</em>
<code>'biscuit'</code>),比較失敗并且服務(wù)器拒絕連接: </p>
<pre>shell> mysql -u jeffrey -pbiscuit test
Access denied
</pre>
<p>因?yàn)楫?dāng)他們被插入<code>user</code>表時(shí),口令必須被加密,<code>相反,INSERT</code>語(yǔ)句應(yīng)該象這樣被指定:
</p>
<pre>mysql> INSERT INTO user (Host,User,Password)
VALUES('%','jeffrey',PASSWORD('biscuit'));
</pre>
<p>當(dāng)你使用<code>SET PASSWORD</code>語(yǔ)句時(shí),你也必須使用<code>PASSWORD()</code>函數(shù):
</p>
<pre>mysql> SET PASSWORD FOR jeffrey@"%" = PASSWORD('biscuit');
</pre>
<p>如果你使用<code>GRANT ... IDENTIFIED BY</code>語(yǔ)句或<code>mysqladmin password</code>命令設(shè)置口令,<code>PASSWORD()</code>函數(shù)是不必要的。他們都考慮到為你加密口令,多以你可像這樣指定一個(gè)口令<code>'biscuit'</code>:
</p>
<pre>mysql> GRANT USAGE ON *.* TO jeffrey@"%" IDENTIFIED BY 'biscuit';
</pre>
<p>或</p>
<pre>shell> mysqladmin -u jeffrey password biscuit
</pre>
<p>注意: <code>PASSWORD()</code>不是以在Unix口令加密的同樣方法施行口令加密。你不應(yīng)該假定如果你的Unix口令和你的<strong>MySQL</strong>口令是一樣的,<code>PASSWORD()</code>將導(dǎo)致與在Unix口令文件被存儲(chǔ)的同樣的加密值。見(jiàn)<a HREF="manual_Privilege_system.html#User_names">6.2 MySQL 用戶(hù)名和口令</a>。 </p>
<h2><a NAME="Access_denied" HREF="manual_toc.html#Access_denied">6.13 <code>Access denied</code>錯(cuò)誤的原因</a></h2>
<p>當(dāng)你試著聯(lián)接<strong>MySQL</strong>服務(wù)器時(shí),如果你碰到<code>Access
denied</code>錯(cuò)誤,顯示在下面的表指出一些你能用來(lái)更正這個(gè)問(wèn)題的動(dòng)作:
<ul>
<li>你是在安裝<strong>MySQL</strong>以后運(yùn)行<code>mysql_install_db</code>的腳本,來(lái)設(shè)置初始授權(quán)表內(nèi)容嗎?如果不是,這樣做。見(jiàn)<a HREF="manual_Privilege_system.html#Default_privileges">6.10 設(shè)置初始MySQL權(quán)限</a>。通過(guò)執(zhí)行這個(gè)命令測(cè)試初始權(quán)限:
<pre>shell> mysql -u root test
</pre>
<p>服務(wù)器應(yīng)該讓你無(wú)誤地連接。你也應(yīng)該保證你在<strong>MySQL</strong>數(shù)據(jù)庫(kù)目錄有一個(gè)文件<tt>“user.MYD”</tt>。通常,它是<tt>“PATH/var/mysql/user.MYD”</tt>,在此<code>PATH</code>是<strong>MySQL</strong>安裝根目錄的路徑。
</p>
</li>
<li>在一個(gè)新的安裝以后,你應(yīng)該連接服務(wù)器并且設(shè)置你的用戶(hù)及其存取許可:
<pre>shell> mysql -u root mysql
</pre>
<p>服務(wù)器應(yīng)該讓你連接,因?yàn)?lt;strong>MySQL</strong> <code>root</code>用戶(hù)初始時(shí)沒(méi)有口令。既然那也是一個(gè)安全風(fēng)險(xiǎn),當(dāng)你正在設(shè)置其他<strong>MySQL</strong>用戶(hù)時(shí),設(shè)定<code>root</code>口令是一件重要的事請(qǐng)。如果你作為<code>root</code>嘗試連接并且得到這個(gè)錯(cuò)誤:
</p>
<pre>Access denied for user: '@unknown' to database mysql
</pre>
<p>這意味著,你沒(méi)有一個(gè)條目在<code>user</code>表中的一個(gè)<code>User</code>列值為<code>'root'</code>并且<code>mysqld</code>不能為你的客庫(kù)解析主機(jī)名。在這種情況下,你必須用<code>--skip-grant-tables</code>選項(xiàng)重啟服務(wù)器并且編輯你的<tt>“/etc/hosts”</tt>或<tt>“\windows\hosts”</tt>文件為你的主機(jī)增加一個(gè)條目。
</p>
</li>
<li><a NAME="IDX148"></a>如果你從一個(gè)3.22.11以前的版本更新一個(gè)現(xiàn)存的<strong>MySQL</strong>安裝到3.22.11版或以后版本,你運(yùn)行了<code>mysql_fix_privilege_tables</code>腳本嗎?如果沒(méi)有,運(yùn)行它。在<code>GRANT</code>語(yǔ)句變得能工作時(shí),授權(quán)表的結(jié)構(gòu)用<strong>MySQL</strong>
3.22.11修改 。 </li>
<li>如果你直接對(duì)授權(quán)表做修改(使用<code>INSERT</code>或<code>UPDATE</code>語(yǔ)句)并且你的改變似乎被忽略,記住,你必須發(fā)出一個(gè)<code>FLUSH
PRIVILEGES</code>語(yǔ)句或執(zhí)行一個(gè)<code>mysqladmin flush-privileges</code>命令導(dǎo)致服務(wù)器再次讀入表,否則你的改變要道下一次服務(wù)器被重啟時(shí)再生效。記住在你設(shè)定<code>root</code>口令以后,你將不需要指定它,直到在你清洗(flush)權(quán)限以后,因?yàn)榉?wù)器仍然不會(huì)知道你改變了口令!
</li>
<li>如果你的權(quán)限似乎在一個(gè)會(huì)話(huà)(session)當(dāng)中改變了,可能是一個(gè)超級(jí)用戶(hù)改變了他們。再次裝入授權(quán)表作用于新客戶(hù)連接,但是它也影響現(xiàn)存的連接,如<a HREF="manual_Privilege_system.html#Privilege_changes">6.9 權(quán)限改變何時(shí)生效</a>小節(jié)所述。
</li>
<li>為了測(cè)試,用<code>--skip-grant-tables</code>選項(xiàng)啟動(dòng)<code>mysqld</code>守護(hù)進(jìn)程,然后你可以改變<strong>MySQL</strong>授權(quán)表并且使用<code>mysqlaccess</code>腳本檢查你的修改是否有如期的效果。當(dāng)你對(duì)你的改變滿(mǎn)意時(shí),執(zhí)行<code>mysqladmin
flush-privileges</code>告訴<code>mysqld</code>服務(wù)器開(kāi)始使用新的權(quán)限表。<strong>注意:</strong>再次裝入授權(quán)表覆蓋了<code>--skip-grant-tables</code>選項(xiàng)。這允許你告訴服務(wù)器開(kāi)始使用授權(quán)表,而不用停掉并重啟它。
</li>
<li>如果你有一個(gè)Perl、Python或ODBC程序的存取問(wèn)題,試著用<code>mysql -u
user_name db_name</code>或<code>mysql -u user_name -pyour_pass db_name</code>與服務(wù)器連接。如果你能用<code>mysql</code>客戶(hù)連接,這是你程序的一個(gè)問(wèn)題而不是存取權(quán)限的問(wèn)題。(注意在<code>-p</code>和口令之間沒(méi)有空格;你也能使用<code>--password=your_pass</code>句法指定口令。)</li>
<li>如果你不能讓口令工作,記得如果你用<code>INSERT</code>, <code>UPDATE</code>或<code>SET
PASSWORD</code>語(yǔ)句設(shè)置口令,你必須使用<code>PASSWORD()</code>函數(shù)。如果你用<code>GRANT
... INDENTIFIED BY</code>語(yǔ)句或<code>mysqladmin password</code>命令指定口令,<code>PASSWORD()</code>函數(shù)是不需要的。見(jiàn)<a HREF="manual_Privilege_system.html#Passwords">6.12 怎樣設(shè)置口令</a>。 </li>
<li><code>localhost</code>是你本地主機(jī)名的一個(gè)同義詞,并且也是如果你不明確地指定主機(jī)而客戶(hù)嘗試連接的缺省主機(jī)。然而,如果你正在運(yùn)行于一個(gè)使用MIT-pthreads的系統(tǒng)上,連接<code>localhost</code>是不行的(<code>localhost</code>連接使用Unix套接字進(jìn)行,它沒(méi)被
MIT-pthreads支持),為了在這樣的系統(tǒng)上避免這個(gè)問(wèn)題,你應(yīng)該使用<code>--host</code>選項(xiàng)明確地命名服務(wù)器主機(jī),這將做一個(gè)
TCP/IP連接到<code>mysqld</code>服務(wù)器。在這種情況下,你必須有在服務(wù)器主機(jī)上的<code>user</code>表中條目的你真實(shí)的主機(jī)名。(即使你在服務(wù)器同一臺(tái)的主機(jī)上運(yùn)行一個(gè)客戶(hù)程序,這也是真的。)</li>
<li>當(dāng)嘗試用<code>mysql -u user_name db_name</code>與數(shù)據(jù)庫(kù)連接時(shí),如果你得到一個(gè)<code>Access
denied</code>錯(cuò)誤,你可能有與<code>user</code>桌有關(guān)的問(wèn)題,通過(guò)執(zhí)行<code>mysql
-u root mysql</code>并且發(fā)出下面的SQL語(yǔ)句檢查: <pre>mysql> SELECT * FROM u
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -