怎样在授权表项中指定本地主机名 & Y9 d c& a: c- a, S0 }3 ` 如果您使用<a href="http://vip.hackbase.com/" target="_blank" >服务</A>器的主机名而非localhost,通常存在从该<a href="http://vip.hackbase.com/" target="_blank" >服务</A>器主机连接的问题。这可能是由于在授权表中指定名字的方法和名字分解器例程( name reslover routine)向程序报告名字的方法之间的错误匹配。如果分解器报告了一个非限定的名字(如p i t - v i per),但授权表包含了具有全限定的名字的项(如p i t - v i per. s n a k e . n e t,反之亦然),则发生错误匹配。9 c) p8 }1 k' I3 m4 ]# f2 v
为了确定这种情况是否正在系统中发生,可试着用-h 选项连接到本地<a href="http://vip.hackbase.com/" target="_blank" >服务</A>器,该选项指定了主机的名字。然后查看<a href="http://vip.hackbase.com/" target="_blank" >服务</A>器的常规日志文件。它是怎样报告主机名的?是以非限定形式还是限定形式?不论它是哪种形式,都将告诉您在发布GRANT 语句时需要怎样指定用户说明符的主机名部分。 " d8 s% r) p0 E2 g/ ~9 e 可以同时列出许多被授予的单个权限。例如,如果想让用户能读取和修改已有表的内容,但又不允许创建新表或删除表,可按如下授权:% V9 |' f4 @* \+ X% [. M' F ]
GRANT SELECT,INSERT,DELETE,UPDATE ON samp<a href="http://www3.hackbase.com/network/server/200501229652_1.htm#" target="_blank" >_</A>db.* TO jennie@%* t/ K! e, v e. X0 Z1 P7 h& t
IDENTIFIEDBY "boron" 0 X( J8 v: m- d# q$ H1 L) D$ }* @ 对于更小粒度( f i n e - g r a i n e d)的访问控制,可以在单个表上授权,甚至在表的单个列上授权。当存在要对用户隐藏的表时,或者,当只允许用户修改特定列时,列专有的权限是有用的。假定历史同盟会中有一些志愿者利用您作为同盟会秘书应履行的职责来帮助您工作。这是一个好消息,但您决定首先给新的助手授予对member 表只读的权限(该表中包含了<a href="http://vip.hackbase.com/" target="_blank" ><a href="http://www3.hackbase.com/News/vip" target="_blank" >会员</A></A>资格的信息),然后再对他们增加授予该表的expiration 列的列专有UPDATE权限。也就是说,您的助手可以在人们更新其<a href="http://vip.hackbase.com/" target="_blank" ><a href="http://www3.hackbase.com/News/vip" target="_blank" >会员</A></A>资格时进行更改截止日期的工作。设置此MySQL用户的语句如下:% P' |8 G7 t; u0 z3 w+ R3 e f& m
<img src="http://www3.hackbase.com/UpLoadFiles/NewsPhoto/a11a50-1.JPG">% I: X2 n) k2 z
第一条语句授予对整个member 表的读访问权并设置口令。第二条语句增加UPDATE权限,但只是对expiration 列。此时不必要再指定口令,因为在第一条语句中已经完成了。 7 }( Q& R t/ F+ s% T 如果想要为多个列授予列专有的权限,可指定一个列清单,并用逗号将这些列分隔。例如,为了给assistant 用户增加对member 表地址列的UPDATE权限,可以使用下列语句。新的权限将被增加到对该用户来说已经存在的所有列上: 9 o# C: o% D. }* [: _! z. e GRANT UPDATE (street,city,state,zip) ON samp<a href="http://www3.hackbase.com/network/server/200501229652_1.htm#" target="_blank" >_</A>db.member7 n2 K' j" i( j) x5 I6 b% G$ ~% Z
TO assistant@localhost! ~7 Y% D/ ^& l, K$ n: ^
通常,不要给用户授予比实际需要更大的权限。但是,当您想要使用户能够创建存储中间结果的临时表,而又不允许用户在包含有他们不能修改的数据的<a href="http://hackbase.com/hacker" target="_blank" >数据库</A>中这样做时,就有了要在<a href="http://hackbase.com/hacker" target="_blank" >数据库</A>上授予相当多的许可权限的理由。您可以建立一个单独的<a href="http://hackbase.com/hacker" target="_blank" >数据库</A>(笔者称它为 ) h! U, U9 g7 @2 Zt m p)并授予用户该<a href="http://hackbase.com/hacker" target="_blank" >数据库</A>的所有权限。例如,如果想要mars.net 域的主机中的任何用户都能够使用tmp <a href="http://hackbase.com/hacker" target="_blank" >数据库</A>,可发布下列GRANT 语句: 9 L2 G, ?) Y4 K' a; r GRANT ALL ON tmp.* TO ""@%.mars.net2 J0 n" B, N6 K
在完成这些之后,用户可使用tmp.tbl<a href="http://www3.hackbase.com/network/server/200501229652_1.htm#" target="_blank" >_</A>name 格式的名字创建和引用tmp <a href="http://hackbase.com/hacker" target="_blank" >数据库</A>中的表(用户说明符中的“” 创建一个匿名用户项,任何用户都与空白用户名相匹配)。 & `4 u, t! H) N! @7 A; ?4 V 3. 允许用户管理权限吗 & ?" Y5 f$ X M! a0 R 通过授予<a href="http://hackbase.com/hacker" target="_blank" >数据库</A>所有者<a href="http://hackbase.com/hacker" target="_blank" >数据库</A>的所有权限并在操作时指定WITH GRANT OPTION,可以允许<a href="http://hackbase.com/hacker" target="_blank" >数据库</A>所有者控制对该<a href="http://hackbase.com/hacker" target="_blank" >数据库</A>的访问。例如,如果要让alicia 能在big.corp.com 域的所有主机中进行连接并管理sales <a href="http://hackbase.com/hacker" target="_blank" >数据库</A>中所有表的权限,应使用下列GRANT 语句: 4 L' d# T& y8 e" d* O<img src="http://www3.hackbase.com/UpLoadFiles/NewsPhoto/a11a50-2.JPG">2 o R6 L7 i1 G; z% y
实际上,WITH GRANT OPTION 子句允许将访问的权利授予给另一个用户。要知道,具有GRANT 权限的两个用户可以相互授予自己的权限。如果只给一个用户授予SELECT 权限而给另一个用户除SELECT 外还授予了GRANT 和其他的权限,则第二个用户可以使第一个用户“强大”起来。+ d. V4 s6 e& c# _0 \0 f/ B
9 ^9 j6 B h2 Q" x' O<FONT color=#ff0000>取消权限和删除用户0 c0 W6 }7 C6 y+ d9 C
4 z* z: i+ Z8 E! @- ^0 y
</FONT> 为了收回某个用户的权限,可使用REVOKE 语句。除了要用FROM 替换TO 并且没有IDENTIFIEDBY 或WITH GRANT OPTION 子句外,REVOKE 的语法与GRANT 语句非常相似: : J' G6 y# I0 n9 S9 k! ^( j REVOKE privileges (columns) ON what FROM user 0 L9 F# E4 }# r: {' s3 n; ` user 部分必须与您想要取消其权限的用户的原始GRANT 语句的user 部分相匹配。priv i l e g e s 部分不需要匹配,您可用GRANT 语句授权,然后用REVOKE 语句取消其中的一部分。REVOKE 语句只删除权限,不删除用户。用户的项仍然保留在user 表中,即使您取消了该用户的所有权限也是如此。这意味着该用户仍然可连接到<a href="http://vip.hackbase.com/" target="_blank" >服务</A>器上。要想删除整个用户,必须用DELETE 语句将该用户的记录从user 表中直接删除:# f2 u# j1 k1 i: c2 U
<img src="http://www3.hackbase.com/UpLoadFiles/NewsPhoto/a11a50-3.JPG">: L/ ^; f3 ]. o- t6 E2 N5 `, M' E
DELETE 语句删除该用户的项, FLUSH 语句告诉<a href="http://vip.hackbase.com/" target="_blank" >服务</A>器重新加载授权表(当使用GRANT 或REVOKE 语句,而不是直接修改授权表时,这些表将自动重新加载)。 4 `7 v1 o' ]% r 11.4 节将讨论为什么删除user 表项的原因。( R% R( r8 ?! }
一个权限难题,第一部分 ; I' [6 H; U% G% I# T 下面是一个在MySQL邮件清单中反复出现的情况:一位新的MySQL管理员给某用户增加一个项,使用了主机名部分,该部分是用一个模式来指定的。例如:3 H+ Z! D5 Z0 j: S2 M
GRANT ALL ON samp<a href="http://www3.hackbase.com/network/server/200501229652_1.htm#" target="_blank" >_</A>db.* TO fred@%.snake.net IDENTIFIEDBY "cocoa" 6 y* y& c% D$ f) {1 g: T( f 这里的意图是允许用户fred 从snake.net 域的所有主机中进行连接,并且具有对samp<a href="http://www3.hackbase.com/network/server/200501229652_1.htm#" target="_blank" >_</A>db <a href="http://hackbase.com/hacker" target="_blank" >数据库</A>的所有权限。事实上, fred 能够从那些主机中连接(除了<a href="http://vip.hackbase.com/" target="_blank" >服务</A>器主机本身外)。当fred 试着从<a href="http://vip.hackbase.com/" target="_blank" >服务</A>器主机中进行连接时,该企图以“访问被拒绝”的消息而告失败。 3 P# w1 z. r' S即使用户指定了正确的口令也是如此。 0 X7 a2 i5 N n. M 如果授权表中包含了由my<a href="http://hackbase.com/hacker" target="_blank" >sql</A><a href="http://www3.hackbase.com/network/server/200501229652_1.htm#" target="_blank" >_</A>install<a href="http://www3.hackbase.com/network/server/200501229652_1.htm#" target="_blank" >_</A>db 安装脚本安装的缺省项,这种情况也会发生。其原因是,当<a href="http://vip.hackbase.com/" target="_blank" >服务</A>器验证fred 连接的企图时,一个匿名用户项( anonymous-user entry)比fred 项优先。匿名用户项要求该用户不用口令来连接,并且一个口令错误匹配发生。 & v2 a& Q9 q& ^2 z; s/ ^该问题的另一个背景将在第12章“权限难题,第二部分”中给出。目前,只要说修正此问题的方法是从user 表中删除匿名用户项就足够了,我们不能用R E V O K E,因为该命令只删除权限。要想完全摆脱这些匿名项,执行如下操作: . Q& g) T3 g" k! n* G9 Z! c) I4 [ % my<a href="http://hackbase.com/hacker" target="_blank" >sql</A>-uroot my<a href="http://hackbase.com/hacker" target="_blank" >sql</A> my<a href="http://hackbase.com/hacker" target="_blank" >sql</A>> DELETE FROM user where User=""; 4 E0 R4 a. N/ t& \0 l my<a href="http://hackbase.com/hacker" target="_blank" >sql</A>>FLUSH PRIVILEGES; & \4 w* n# G, B 现在,当fred 试图从本地主机连接时成功了。