信息系统项目管理师_2024年软考学习应考交流_信息系统项目管理师考试

 找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 2078|回复: 9
打印 上一主题 下一主题

[转帖]MySQL提供的权限

  [复制链接]

该用户从未签到

升级  30.8%

跳转到指定楼层
楼主
发表于 2006-4-9 17:19:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
<p>权限信息用<code>user</code>、<code>db</code>、<code>host</code>、<code>tables_priv</code>和<code>columns_priv</code>表被存储在<code>mysql</code>数据库中(即在名为<code>mysql</code>的数据库中)。在<strong>MySQL</strong>启动时,服务器读入这些数据库表内容。 </p><p>本手册所用的涉及由<strong>MySQL</strong>提供的权限名称显示在下表,还有在授权表中每个权限的表列名称和每个权限有关的上下文: </p><table class="p4" width="100%" border="1" nosave="#101090"><tbody><tr><td><strong>权限</strong> </td><td><strong>列</strong> </td><td><strong>上下文</strong> </td></tr><tr><td><strong>select</strong> </td><td><code>Select_priv</code> </td><td>表</td></tr><tr><td><strong>insert</strong> </td><td><code>Insert_priv</code> </td><td>表</td></tr><tr><td><strong>update</strong> </td><td><code>Update_priv</code> </td><td>表</td></tr><tr><td><strong>delete</strong> </td><td><code>Delete_priv</code> </td><td>表</td></tr><tr><td><strong>index</strong> </td><td><code>Index_priv</code> </td><td>表</td></tr><tr><td><strong>alter</strong> </td><td><code>Alter_priv</code> </td><td>表</td></tr><tr><td><strong>create</strong> </td><td><code>Create_priv</code> </td><td>数据库、表或索引</td></tr><tr><td><strong>drop</strong> </td><td><code>Drop_priv</code> </td><td>数据库或表</td></tr><tr><td><strong>grant</strong> </td><td><code>Grant_priv</code> </td><td>数据库或表</td></tr><tr><td><strong>references</strong> </td><td><code>References_priv</code> </td><td>数据库或表</td></tr><tr><td><strong>reload</strong> </td><td><code>Reload_priv</code> </td><td>服务器管理</td></tr><tr><td><strong>shutdown</strong> </td><td><code>Shutdown_priv</code> </td><td>服务器管理</td></tr><tr><td><strong>process</strong> </td><td><code>rocess_priv</code> </td><td>服务器管理</td></tr><tr><td><strong>file</strong> </td><td><code>File_priv</code> </td><td>在服务器上的文件存取</td></tr></tbody></table><p><strong>select</strong>、<strong>insert</strong>、<strong>update</strong>和<strong>delete</strong>权限允许你在一个数据库现有的表上实施操作。 </p><p><code>SELECT</code>语句只有在他们真正从一个表中检索行是才需要<strong>select</strong>权限,你可以执行某个<code>SELECT</code>语句,甚至没有任何到服务器上的数据库里的存取任何东西的许可。例如,你可使用<code>mysql</code>客户作为一个简单的计算器: </p><pre>mysql&gt; SELECT 1+1;
mysql&gt; SELECT PI()*2;
</pre>
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 顶 踩

该用户从未签到

升级  30.8%

沙发
 楼主| 发表于 2006-4-9 17:19:24 | 只看该作者
<p><strong>index</strong>权限允许你创建或抛弃(删除)索引。 </p><p><strong>alter</strong>权限允许你使用<code>ALTER TABLE</code>。 </p><p><strong>create</strong>和<strong>drop</strong>权限允许你创建新的数据库和表,或抛弃(删除)现存的数据库和表。 </p><p>注意:如果你将<code>mysql</code>数据库的<strong>drop</strong>权限授予一个用户,该用户能抛弃存储了<strong>MySQL</strong>存取权限的数据库! </p><p><strong>grant</strong>权限允许你把你自己拥有的那些权限授给其他的用户。 </p><p><strong>file</strong>权限给予你用<code>LOAD DATA INFILE</code>和<code>SELECT ... INTO OUTFILE</code>语句读和写服务器上的文件,任何被授予这个权限的用户都能读或写<strong>MySQL</strong>服务器能读或写的任何文件。 </p><p>其余的权限用于管理性操作,它使用<code>mysqladmin</code>程序实施。下表显示<code>mysqladmin</code>支配每个管理性权限允许你执行的命令: </p><table class="p4" width="100%" border="1" nosave="#101090"><tbody><tr><td><strong>优惠</strong> </td><td><strong>权限拥有者允许执行的命令</strong> </td></tr><tr><td><strong>reload</strong> </td><td><code>reload</code>, <code>refresh</code>, <code>flush-privileges</code>, <code>flush-hosts</code>, <code>flush-logs</code>, <code>flush-tables</code> </td></tr><tr><td><strong>shutdown</strong> </td><td><code>shutdown</code> </td></tr><tr><td><strong>precess</strong> </td><td><code>processlist</code>, <code>kill</code> </td></tr></tbody></table><p><code>reload</code>命令告诉服务器再读入授权表,<code>refresh</code>命令清洗所有表并打开和关闭记录文件,<code>flush-privileges</code>是<code>reload</code>的一个同义词,其它<code>flush-*</code>命令执行类似<code>refresh</code>的功能,但是范围更有限,并且在某些情况下可能更好用。例如,如果你只是想清洗记录文件,<code>flush-logs</code>比<code>refresh</code>是更好的选择。 </p><p><code>shutdown</code>命令关掉服务器。 </p><p><code>processlist</code>命令显示在服务器内执行的线程的信息。<code>kill</code>命令杀死服务器线程。你总是能显示或杀死你自己的线程,但是你需要<strong>process</strong>权限来显示或杀死其他用户启动的线程。 </p><p>总的说来,只授予权限给需要他们的那些用户是一个好主意,但是你应该在授予某个权限时试验特定的警告: </p><ul><li><strong>grant</strong>权限允许用户放弃他们的权限给其他用户。2个有不同的权限并有<strong>grant</strong>权限的用户可以合并权限。 </li><li><strong>alter</strong>权限可以用于通过重新命名表来推翻权限系统。 </li><li><strong>file</strong>权限可以被滥用在服务器上读取任何世界可读(world-readable,即任何人可读)的文件到一张数据库表,然后其内容能用<code>SELECT</code>被存取。 </li><li><strong>shutdown</strong>权限通过终止服务器可以被滥用完全拒绝为其他用户服务, 。 </li><li><strong>precess</strong>权限能被用来察看当前执行的查询的普通文本,包括设定或改变口令查询。 </li><li>在<code>mysql</code>数据库上的权限能被用来改变口令和其他存取权限信息。(口令被加密存储,所以一个恶意的用户不能简单地读取他们。然而,有足够的权限,同一个用户能用不同的一个代替一个口令。) </li></ul><p>有一些事情你不能用<strong>MySQL</strong>权限系统做到: </p><ul><li>你不能明显地指定一个给定用户应该被拒绝存取。即,你不能明显地匹配一个用户并且然后拒绝连接。 </li><li>你不能指定一个用户有权创建立或抛弃一个数据库中的表,也不能创建或抛弃数据库本身。</li></ul>

该用户从未签到

升级  30.8%

藤椅
 楼主| 发表于 2006-4-9 17:20:42 | 只看该作者
<font color="#800080">权限系统工作原理</font><p><strong>MySQL</strong>权限系统保证所有的用户可以严格地做他们假定被允许做的事情。当你连接一个<strong>MySQL</strong>服务器时, 你的身份由<strong>你从那连接的主机</strong>和<strong>你指定的用户名</strong>来决定,系统根据你的身份和<strong>你想做什么</strong>来授予权限。 </p><p><strong>MySQL</strong>在认定身份中考虑你的主机名和用户名字,是因为有很小的原因假定一个给定的用户在因特网上属于同一个人。例如,用户从<code>whitehouse.gov</code>连接的<code>bill</code>不必和从<code>mosoft.com</code>连接<code>bill</code>是同一个人。 <strong>MySQL</strong>通过允许你区分在不同的主机上碰巧有同样名字用户来处理它:你可以对从<code>whitehouse.gov</code>连接授与<code>bill</code>一个权限集,而为从<code>microsoft.com</code>的连接授予一个不同的权限集。 </p><p><strong>MySQL</strong>存取控制包含2个阶段: </p><ul><li>阶段1:服务器检查你是否允许连接。 </li><li>阶段2:假定你能连接,服务器检查你发出的每个请求。看你是否有足够的权限实施它。例如,如果你从数据库中一个表精选(select)行或从数据库抛弃一个表,服务器确定你对表有<strong>select</strong>权限或对数据库有<strong>drop</strong>权限。 </li></ul><p>服务器在存取控制的两个阶段使用在<code>mysql</code>的数据库中的<code>user</code>、<code>db</code>和<code>host</code>表,在这些授权表中字段如下: </p><table width="100%" border="1" nosave="#101090"><tbody><tr><td><strong>表名称</strong> </td><td><code>user</code> </td><td><code>db</code> </td><td><code>host</code> </td></tr><tr><td><strong>范围字段</strong> </td><td><code>Host</code> </td><td><code>Host</code> </td><td><code>Host</code> </td></tr><tr><td></td><td><code>User</code> </td><td><code>Db</code> </td><td><code>Db</code> </td></tr><tr><td></td><td><code>assword</code> </td><td><code>User</code> </td><td></td></tr><tr><td><strong>权限字段</strong> </td><td><code>Select_priv</code> </td><td><code>Select_priv</code> </td><td><code>Select_priv</code> </td></tr><tr><td></td><td><code>Insert_priv</code> </td><td><code>Insert_priv</code> </td><td><code>Insert_priv</code> </td></tr><tr><td></td><td><code>Update_priv</code> </td><td><code>Update_priv</code> </td><td><code>Update_priv</code> </td></tr><tr><td></td><td><code>Delete_priv</code> </td><td><code>Delete_priv</code> </td><td><code>Delete_priv</code> </td></tr><tr><td></td><td><code>Index_priv</code> </td><td><code>Index_priv</code> </td><td><code>Index_priv</code> </td></tr><tr><td></td><td><code>Alter_priv</code> </td><td><code>Alter_priv</code> </td><td><code>Alter_priv</code> </td></tr><tr><td></td><td><code>Create_priv</code> </td><td><code>Create_priv</code> </td><td><code>Create_priv</code> </td></tr><tr><td></td><td><code>Drop_priv</code> </td><td><code>Drop_priv</code> </td><td><code>Drop_priv</code> </td></tr><tr><td></td><td><code>Grant_priv</code> </td><td><code>Grant_priv</code> </td><td><code>Grant_priv</code> </td></tr><tr><td></td><td><code>Reload_priv</code> </td><td></td><td></td></tr><tr><td></td><td><code>Shutdown_priv</code> </td><td></td><td></td></tr><tr><td></td><td><code>rocess_priv</code> </td><td></td><td></td></tr><tr><td></td><td><code>File_priv</code> </td><td></td><td></td></tr></tbody></table>

该用户从未签到

升级  30.8%

板凳
 楼主| 发表于 2006-4-9 17:21:15 | 只看该作者
<p>对存取控制的第二阶段(请求证实),如果请求涉及表,服务器可以另外参考<code>tables_priv</code>和<code>columns_priv</code>表。这些表的字段如下: </p><table width="100%" border="1" nosave="#101090"><tbody><tr><td><strong>表名称</strong></td><td><code>tables_priv</code> </td><td><code>columns_priv</code> </td></tr><tr><td><strong>范围字段</strong> </td><td><code>Host</code> </td><td><code>Host</code> </td></tr><tr><td></td><td><code>Db</code> </td><td><code>Db</code> </td></tr><tr><td></td><td><code>User</code> </td><td><code>User</code> </td></tr><tr><td></td><td><code>Table_name</code> </td><td><code>Table_name</code> </td></tr><tr><td></td><td></td><td><code>Column_name</code> </td></tr><tr><td><strong>权限字段</strong> </td><td><code>Table_priv</code> </td><td><code>Column_priv</code> </td></tr><tr><td></td><td><code>Column_priv</code> </td><td></td></tr><tr><td><strong>其他字段</strong> </td><td><code>Timestamp</code> </td><td><code>Timestamp</code> </td></tr><tr><td></td><td><code>Grantor</code> </td><td></td></tr></tbody></table><p>每个授权表包含范围字段和权限字段。 </p><p>范围字段决定表中每个条目的范围,即,条目适用的上下文。例如, 一个<code>user</code>表条目的<code>Host</code>和<code>User</code>值为<code>'thomas.loc.gov'</code>和<code>'bob'</code>将被用于证实来自主机<code>thomas.loc.gov</code>的<code>bob</code>对服务器的连接。同样,一个<code>db</code>表条目的<code>Host</code>、<code>User</code>和<code>Db</code>字段的值是<code>'thomas.loc.gov'</code>、<code>'bob'</code>和<code>'reports'</code>将用在<code>bob</code>从主机联接<code>thomas.loc.gov</code>存取<code>reports</code>数据库的时候。 <code>tables_priv</code>和<code>columns_priv</code>表包含范围字段,指出每个条目适用的表或表/列的组合。 </p><p><a name="IDX129"></a>对于检查存取的用途,比较<code>Host</code>值是忽略大小写的。<code>User</code>、<code>asswor</code>d、<code>Db</code>和<code>Table_name</code>值是区分大小写的。<code>Column_name</code>值在<strong>MySQL</strong>3.22.12或以后版本是忽略大小写的。 </p><p>权限字段指出由一个表条目授予的权限,即,可实施什么操作。服务器组合各种的授权表的信息形成一个用户权限的完整描述。</p>

该用户从未签到

升级  30.8%

报纸
 楼主| 发表于 2006-4-9 17:21:48 | 只看该作者
<p>范围字段是字符串,如下所述;每个字段的缺省值是空字符串: </p><table width="100%" border="1" nosave="#101090"><tbody><tr><td><strong>字段名</strong> </td><td><strong>类型</strong> </td></tr><tr><td><code>Host</code> </td><td><code>CHAR(60)</code> </td></tr><tr><td><code>User</code> </td><td><code>CHAR(16)</code> </td></tr><tr><td><code>assword</code> </td><td><code>CHAR(16)</code> </td></tr><tr><td><code>Db</code> </td><td><code>CHAR(64)</code> </td><td>(<code>tables_priv</code>和<code>columns_priv</code>表为<code>CHAR(60)</code>)</td></tr></tbody></table><p>在<code>user</code>、<code>db</code>和<code>host</code>表中,所有权限字段被声明为<code>ENUM('N','Y')</code>--每一个都可有值<code>'N'</code>或<code>'Y'</code>,并且缺省值是<code>'N'</code>. </p><p>在<code>tables_priv</code>和<code>columns_priv</code>表中,权限字段被声明为<code>SET</code>字段: </p><table width="100%" border="1" nosave="#101090"><tbody><tr><td><strong>表名</strong> </td><td><strong>字段名</strong> </td><td><strong>可能的集合成员</strong> </td></tr><tr><td><code>tables_priv</code> </td><td><code>Table_priv</code> </td><td><code>'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'</code> </td></tr><tr><td><code>tables_priv</code> </td><td><code>Column_priv</code> </td><td><code>'Select', 'Insert', 'Update', 'References'</code> </td></tr><tr><td><code>columns_priv</code> </td><td><code>Column_priv</code> </td><td><code>'Select', 'Insert', 'Update', 'References'</code> </td></tr></tbody></table><p>简单地说,服务器使用这样的授权表: </p><ul><li><code>user</code>表范围字段决定是否允许或拒绝到来的连接。对于允许的连接,权限字段指出用户的全局(超级用户)权限。 </li><li><code>db</code>和<code>host</code>表一起使用: </li><ul><li><code>db</code>表范围字段决定用户能从哪个主机存取哪个数据库。权限字段决定允许哪个操作。 </li><li>当你想要一个给定的<code>db</code>条目应用于若干主机时,<code>host</code>表作为<code>db</code>表的扩展被使用。例如,如果你想要一个用户能在你的网络从若干主机使用一个数据库,在用户的<code>db</code>表的<code>Host</code>条目设为空值,然后将那些主机的每一个移入<code>host</code>表。<code>tables_priv</code>和<code>columns_priv</code>表类似于<code>db</code>表,但是更精致:他们在表和列级应用而非在数据库级。 </li></ul></ul><p>注意管理权限(<strong>reload</strong>, <strong>shutdown</strong>, 等等)仅在<code>user</code>表中被指定。这是因为管理性操作是服务器本身的操作并且不是特定数据库,因此没有理由在其他授权表中列出这样的权限。事实上,只需要请教<code>user</code>表来决定你是否执行一个管理操作。 </p><p><strong>file</strong>权限也仅在<code>user</code>表中指定。它不是管理性权限,但你读或谢在服务器主机上的文件的的能力独立于你正在存取的数据库。 </p>
[此贴子已经被作者于2006-4-9 17:22:23编辑过]

该用户从未签到

升级  30.8%

地板
 楼主| 发表于 2006-4-9 17:23:28 | 只看该作者
<p>当你试图联接一个<strong>MySQL</strong>服务器时,服务器基于你的身份和你是否能通过供应正确的口令验证身份来接受或拒绝连接。如果不是,服务器完全具结你的存取,否则,服务器接受连接,然后进入阶段2并且等待请求。 </p><p>你的身份基于2个信息: </p><ul><li>你从那个主机连接 </li><li>你的<strong>MySQL</strong>用户名 </li></ul><p>身份检查使用3个<code>user</code>表(<code>Host</code>, <code>User</code>和<code>assword</code>)范围字段执行。服务器只有在一个<code>user</code>表条目匹配你的主机名和用户名并且你提供了正确的口令时才接受连接。 </p><p>在<code>user</code>表范围字段可以如下被指定: </p><ul><li>一个<code>Host</code>值可以是主机名或一个IP数字,或<code>'localhost'</code>指出本地主机。 </li><li><a name="IDX130"></a>你可以在<code>Host</code>字段里使用通配符字符<samp>“%”</samp>和<samp>“_”</samp>。 </li><li>一个<code>Host</code>值<code>'%'</code>匹配任何主机名,一个空白<code>Host</code>值等价于<code>'%'</code>。注意这些值匹配<em>能创建一个连接到你的服务器的任何主机!</em> </li><li><a name="IDX131"></a>通配符字符在<code>User</code>字段中不允许,但是你能指定空白的值,它匹配任何名字。如果<code>user</code>表匹配到来的连接的条目有一个空白的用户名,用户被认为是匿名用户(没有名字的用户),而非客户实际指定的名字。这意味着一个空白的用户名被用于在连接期间的进一步的存取检查(即,在阶段2期间)。 </li><li><code>assword</code>字段可以是空白的。这不意味着匹配任何口令,它意味着用户必须不指定一个口令进行连接。 </li></ul><p><a name="IDX132"></a>非空白<code>assword</code>值代表加密的口令。 <strong>MySQL</strong>不以任何人可以看的纯文本格式存储口令,相反,正在试图联接的一个用户提供的口令被加密(使用<code>ASSWORD()</code>函数),并且与存储了<code>user</code>表中的已经加密的版本比较。如果他们匹配,口令是正确的。 </p><p>下面的例子显示出各种<code>user</code>表中<code>Host</code>和<code>User</code>条目的值的组合如何应用于到来的连接: </p><table width="100%" border="1" nosave="#101090"><tbody><tr><td><code>Host</code> <strong>值</strong> </td><td><code>User</code> <strong>值</strong> </td><td><strong>被条目匹配的连接</strong> </td></tr><tr><td><code>'thomas.loc.gov'</code> </td><td><code>'fred'</code> </td><td><code>fred</code>, 从<code>thomas.loc.gov</code> 连接</td></tr><tr><td><code>'thomas.loc.gov'</code> </td><td><code>''</code> </td><td>任何用户, 从<code>thomas.loc.gov</code>连接 </td></tr><tr><td><code>'%'</code> </td><td><code>'fred'</code> </td><td><code>fred</code>, 从任何主机连接</td></tr><tr><td><code>'%'</code> </td><td><code>''</code> </td><td>任何用户, 从任何主机连接</td></tr><tr><td><code>'%.loc.gov'</code> </td><td><code>'fred'</code> </td><td><code>fred</code>, 从在<code>loc.gov</code>域的任何主机连接</td></tr><tr><td><code>'x.y.%'</code> </td><td><code>'fred'</code> </td><td><code>fred</code>, 从<code>x.y.net</code>、<code>x.y.com</code>,<code>x.y.edu</code>等联接。(这或许无用)</td></tr><tr><td><code>'144.155.166.177'</code> </td><td><code>'fred'</code> </td><td><code>fred</code>, 从<code>有144.155.166.177</code> IP 地址的主机连接</td></tr><tr><td><code>'144.155.166.%'</code> </td><td><code>'fred'</code> </td><td><code>fred</code>, 从<code>144.155.166</code> C类子网的任何主机连接</td></tr></tbody></table>

该用户从未签到

升级  30.8%

7
 楼主| 发表于 2006-4-9 17:23:46 | 只看该作者
<p>既然你能在<code>Host</code>字段使用IP通配符值(例如,<code>'144.155.166.%'</code>匹配在一个子网上的每台主机),有可能某人可能企图探究这种能力,通过命名一台主机为<code>144.155.166.somewhere.com</code>。为了阻止这样的企图,<strong>MySQL</strong>不允许匹配以数字和一个点起始的主机名,这样,如果你用一个命名为类似<code>1.2.foo.com</code>的主机,它的名字决不会匹配授权表中<code>Host</code>列。只有一个IP数字能匹配IP通配符值。 </p><p>一个到来的连接可以被在<code>user</code>表中的超过一个条目匹配。例如,一个由<code>fred</code>从<code>thomas.loc.gov</code>的连接匹配多个条目如上所述。如果超过一个匹配,服务器怎么选择使用哪个条目呢?服务器在启动时读入<code>user</code>表后通过排序来解决这个问题,然后当一个用户试图连接时,以排序的顺序浏览条目,第一个匹配的条目被使用。 </p><p><code>user</code>表排序工作如下,假定<code>user</code>表看起来像这样: </p><pre>+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| %         | root     | ...
| %         | jeffrey  | ...
| localhost | root     | ...
| localhost |          | ...
+-----------+----------+-
</pre><p>当服务器在表中读取时,它以最特定的<code>Host</code>值为先的次序排列(<code>'%'</code>在<code>Host</code>列里意味着“任何主机”并且是最不特定的)。有相同<code>Host</code>值的条目以最特定的<code>User</code>值为先的次序排列(一个空白<code>User</code>值意味着“任何用户”并且是最不特定的)。最终排序的<code>user</code>表看起来像这样: </p><pre>+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| localhost | root     | ...
| localhost |          | ...
| %         | jeffrey  | ...
| %         | root     | ...
+-----------+----------+-
</pre><p><a name="IDX133"></a>当一个连接被尝试时,服务器浏览排序的条目并使用找到的第一个匹配。对于由<code>jeffrey</code>从<code>localhost</code>的一个连接,在<code>Host</code>列的<code>'localhost'</code>条目首先匹配。那些有空白用户名的条目匹配连接的主机名和用户名。(<code>'%'/'jeffrey'</code>条目也将匹配,但是它不是在表中的第一匹配。)</p><p>这是另外一个例子。假定<code>user</code>表看起来像这样: </p><pre>+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| %              | jeffrey  | ...
| thomas.loc.gov |          | ...
+----------------+----------+-
</pre><p>排序后的表看起来像这样: </p><pre>+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| thomas.loc.gov |          | ...
| %              | jeffrey  | ...
+----------------+----------+-
</pre><p>一个由<code>jeffrey</code>从<code>thomas.loc.gov</code>的连接被第一个条目匹配,而一个由<code>jeffrey</code>从<code>whitehouse.gov</code>的连接被第二个匹配。 </p><p>普遍的误解是认为,对一个给定的用户名,当服务器试图对连接寻找匹配时,明确命名那个用户的所有条目将首先被使用。这明显不是事实。先前的例子说明了这点,在那里一个由<code>jeffrey</code>从<code>thomas.loc.gov</code>的连接没被包含<code>'jeffrey'</code>作为<code>User</code>字段值的条目匹配,但是由没有用户名的题目匹配! </p><p>如果你有服务器连接的问题,打印出<code>user</code>表并且手工排序它看看第一个匹配在哪儿进行。</p>

该用户从未签到

升级  30.8%

8
 楼主| 发表于 2006-4-9 17:24:18 | 只看该作者
<p><code>user</code>表在一个全局基础上授予赋予你的权限,该权限不管当前的数据库是什么均适用。例如,如果<code>user</code>表授予你<strong>delete</strong>权限, 你可以删除在服务器主机上从任何数据库删除行!换句话说,<code>user</code>表权限是超级用户权限。只把<code>user</code>表的权限授予超级用户如服务器或数据库主管是明智的。对其他用户,你应该把在<code>user</code>表中的权限设成<code>'N'</code>并且仅在一个特定数据库的基础上授权, 使用<code>db</code>和<code>host</code>表。 </p><p><a name="IDX136"></a><code>db</code>和<code>host</code>表授予数据库特定的权限。在范围字段的值可以如下被指定: </p><ul><li>通配符字符<samp>“%”</samp>和<samp>“_”</samp>可被用于两个表的<code>Host</code>和<code>Db</code>字段。 </li><li>在<code>db</code>表的<code>'%'Host</code>值意味着“任何主机”,在<code>db</code>表中一个空白<code>Host</code>值意味着“对进一步的信息咨询<code>host</code>表”。 </li><li>在<code>host</code>表的一个<code>'%'</code>或空白<code>Host</code>值意味着“任何主机”。 </li><li>在两个表中的一个<code>'%'</code>或空白<code>Db</code>值意味着“任何数据库”。 </li><li>在两个表中的一个空白<code>User</code>值匹配匿名用户。 </li></ul><p><a name="IDX139"></a><code>db</code>和<code>host</code>表在服务器启动时被读取和排序(同时它读<code>user</code>表)。<code>db</code>表在<code>Host</code>、<code>Db</code>和<code>User</code>范围字段上排序,并且<code>host</code>表在<code>Host</code>和<code>Db</code>范围字段上排序。对于<code>user</code>表,排序首先放置最特定的值然后最后最不特定的值,并且当服务器寻找匹配入条目时,它使用它找到的第一个匹配。 </p><p><code>tables_priv</code>和<code>columns_priv</code>表授予表和列特定的权限。在范围字段的值可以如下被指定: </p><ul><li>通配符<samp>“%”</samp>和<samp>“_”</samp>可用在使用在两个表的<code>Host</code>字段。 </li><li>在两个表中的一个<code>'%'</code>或空白<code>Host</code>意味着“任何主机”。 </li><li>在两个表中的<code>Db</code>、<code>Table_name</code>和<code>Column_name</code>字段不能包含通配符或空白。 </li></ul><p><code>tables_priv</code>和<code>columns_priv</code>表在<code>Host</code>、<code>Db</code>和<code>User</code>字段上被排序。这类似于<code>db</code>表的排序,尽管因为只有<code>Host</code>字段可以包含通配符,但排序更简单。 </p><p>请求证实进程在下面描述。(如果你熟悉存取检查的源代码,你会注意到这里的描述与在代码使用的算法略有不同。描述等价于代码实际做的东西;它只是不同于使解释更简单。)</p><p>对管理请求(<strong>shutdown</strong>、<strong>reload</strong>等等),服务器仅检查<code>user</code>表条目,因为那是唯一指定管理权限的表。如果条目许可请求的操作,存取被授权了,否则拒绝。例如,如果你想要执行<code>mysqladmin shutdown</code>,但是你的<code>user</code>表条目没有为你授予<strong>shutdown</strong>权限,存取甚至不用检查<code>db</code>或<code>host</code>表就被拒绝。(因为他们不包含<code>Shutdown_priv</code>行列,没有这样做的必要。)</p><p>对数据库有关的请求(<strong>insert</strong>、<strong>update</strong>等等),服务器首先通过查找<code>user</code>表条目来检查用户的全局(超级用户)权限。如果条目允许请求的操作,存取被授权。如果在<code>user</code>表中全局权限不够,服务器通过检查<code>db</code>和<code>host</code>表确定特定的用户数据库权限: </p><ol><li>服务器在<code>db</code>表的<code>Host</code>、<code>Db</code>和<code>User</code>字段上查找一个匹配。 <code>Host</code>和<code>User</code>对应连接用户的主机名和<strong>MySQL</strong>用户名。<code>Db</code>字段对应用户想要存取的数据库。如果没有<code>Host</code>和<code>User</code>的条目,存取被拒绝。 </li><li>如果<code>db</code>表中的条目有一个匹配而且它的<code>Host</code>字段不是空白的,该条目定义用户的数据库特定的权限。 </li><li>如果匹配的<code>db</code>表的条目的<code>Host</code>字段是空白的,它表示<code>host</code>表列举主机应该被允许存取数据库的主机。在这种情况下,在<code>host</code>表中作进一步查找以发现<code>Host</code>和<code>Db</code>字段上的匹配。如果没有<code>host</code>表条目匹配,存取被拒绝。如果有匹配,用户数据库特定的权限以在<code>db</code>和<code>host</code>表的条目的权限,即在两个条目都是<code>'Y'</code>的权限的交集(<em>而不是</em>并集!)计算。(这样你可以授予在<code>db</code>表条目中的一般权限,然后用<code>host</code>表条目按一个主机一个主机为基础地有选择地限制它们。) </li></ol><p>在确定了由<code>db</code>和<code>host</code>表条目授予的数据库特定的权限后,服务器把他们加到由<code>user</code>表授予的全局权限中。如果结果允许请求的操作,存取被授权。否则,服务器检查在<code>tables_priv</code>和<code>columns_priv</code>表中的用户的表和列权限并把它们加到用户权限中。基于此结果允许或拒绝存取。 </p><p>用布尔术语表示,前面关于一个用户权限如何计算的描述可以这样总结: </p><pre>global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges
</pre><p>它可能不明显,为什么呢,如果全局<code>user</code>条目的权限最初发现对请求的操作不够,服务器以后把这些权限加到数据库、表和列的特定权限。原因是一个请求可能要求超过一种类型的权限。例如,如果你执行一个<code>INSERT ... SELECT</code>语句,你就都要<strong>insert</strong>和<strong>select</strong>权限。你的权限必须如此以便<code>user</code>表条目授予一个权限而<code>db</code>表条目授予另一个。在这种情况下,你有必要的权限执行请求,但是服务器不能自己把两个表区别开来;两个条目授予的权限必须组合起来。 </p><p><code>host</code>表能被用来维护一个“安全”服务器列表。在TcX,<code>host</code>表包含一个在本地的网络上所有的机器的表,这些被授予所有的权限。 </p><p>你也可以使用<code>host</code>表指定<em>不</em>安全的主机。假定你有一台机器<code>public.your.domain</code>,它位于你不认为是安全的一个公共区域,你可以用下列的<code>host</code>表条目子允许除了那台机器外的网络上所有主机的存取: </p><pre>+--------------------+----+-
| Host               | Db | ...
+--------------------+----+-
| public.your.domain | %  | ... (所有权限设为 'N')
| %.your.domain      | %  | ... (所有权限设为 'Y')
+--------------------+----+-
</pre><p>当然,你应该总是测试你在授权表中的条目(例如,使用<code>mysqlaccess</code>)让你确保你的存取权限实际上以你认为的方式被设置。 </p>

该用户从未签到

升级  30.8%

9
 楼主| 发表于 2006-4-9 17:24:56 | 只看该作者
有2个不同的方法增加用户:通过使用<code>GRANT</code>语句或通过直接操作<strong>MySQL</strong>授权表。比较好的方法是使用<code>GRANT</code>语句,因为他们是更简明并且好像错误少些。 <p>下面的例子显示出如何使用<code>mysql</code>客户安装新用户。这些例子假定权限根据以前的章节描述的缺省被安装。这意味着为了改变,你必须在<code>mysqld</code>正在运行同一台机器上,你必须作为<strong>MySQL</strong> <code>root</code>用户连接,并且<code>root</code>用户必须对<code>mysql</code>数据库有<strong>insert</strong>权限和<strong>reload</strong>管理权限。另外,如果你改变了<code>root</code>用户口令,你必须如下的<code>mysql</code>命令指定它。 </p><p>你可以通过发出<code>GRANT</code>语句增加新用户: </p><pre>shell&gt; mysql --user=root mysql
mysql&gt; GRANT ALL PRIVILEGES ON *.* TO monty@localhost
           IDENTIFIED BY 'something' WITH GRANT OPTION;
mysql&gt; GRANT ALL PRIVILEGES ON *.* TO monty@"%"
           IDENTIFIED BY 'something' WITH GRANT OPTION;
mysql&gt; GRANT RELOAD,PROCESS ON *.* TO admin@localhost;
mysql&gt; GRANT USAGE ON *.* TO dummy@localhost;
</pre><p>这些<code>GRANT</code>语句安装3个新用户: </p><dl compact="true"><dt><code>monty</code> </dt><dd>可以从任何地方连接服务器的一个完全的超级用户,但是必须使用一个口令(<code>'something'</code>做这个。注意,我们必须对<code>monty@localhost</code>和<code>monty@"%"</code>发出<code>GRANT</code>语句。如果我们增加<code>localhost</code>条目,对<code>localhost</code>的匿名用户条目在我们从本地主机连接接时由<code>mysql_install_db</code>创建的条目将优先考虑,因为它有更特定的<code>Host</code>字段值,所以以<code>user</code>表排列顺序看更早到来。 </dd><dt><code>admin</code> </dt><dd>可以从<code>localhost</code>没有一个口令进行连接并且被授予<strong>reload</strong>和<strong>process</strong>管理权限的用户。这允许用户执行<code>mysqladmin reload</code>、<code>mysqladmin refresh</code>和<code>mysqladmin flush-*</code>命令,还有<code>mysqladmin processlist</code>。没有授予数据库有关的权限。他们能在以后通过发出另一个<code>GRANT</code>语句授权。 </dd><dt><code>dummy</code> </dt><dd>可以不用一个口令连接的一个用户,但是只能从本地主机。全局权限被设置为<code>'N'</code>--<code>USAGE</code>权限类型允许你无需权限就可设置一个用户。它假定你将在以后授予数据库相关的权限。 </dd></dl><p>你也可以直接通过发出<code>INSERT</code>语句增加同样的用户存取信息,然后告诉服务器再次装入授权表: </p><pre>shell&gt; mysql --user=root mysql
mysql&gt; INSERT INTO user VALUES('localhost','monty',PASSWORD('something'),
                'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y')
mysql&gt; INSERT INTO user VALUES('%','monty',PASSWORD('something'),
                'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y')
mysql&gt; INSERT INTO user SET Host='localhost',User='admin',
                 Reload_priv='Y', Process_priv='Y';
mysql&gt; INSERT INTO user (Host,User,Password)
                        VALUES('localhost','dummy','');
mysql&gt; FLUSH PRIVILEGES;
</pre><p>取决于你的<strong>MySQL</strong>版本,对上述,你可能必须使用一个不同数目<code>'Y'</code>值(在3.22.11以前的版本有更少的权限列)。对<code>admin</code>用户,只用在3.22.11开始的版本具有的更加可读的<code>INSERT</code>扩充的语法。 </p><p>注意,为了设置一个超级用户,你只需创造一个<code>user</code>表条目,其权限字段设为<code>'Y'</code>。不需要<code>db</code>或<code>host</code>表的条目。 </p><p>在<code>user</code>表中的权限列不是由最后一个<code>INSERT</code>语句明确设置的(对<code>dummy</code>用户),因此那些列被赋予缺省值<code>'N'</code>。这是<code>GRANT USAGE</code>做的同样的事情。 </p><p>下列例子增加一个用户<code>custom</code>,他能从主机<code>localhost</code>、<code>server.domain</code>和<code>whitehouse.gov</code>连接。他只想要从<code>localhost</code>存取<code>bankaccount</code>数据库,从<code>whitehouse.gov</code>存取<code>expenses</code>数据库和从所有3台主机存取<code>customer</code>数据库。他想要从所有3台主机上使用口令<code>stupid</code>。 </p><p>为了使用<code>GRANT</code>语句设置个用户的权限,运行这些命令: </p><pre>shell&gt; mysql --user=root mysql
mysql&gt; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
           ON bankaccount.*
           TO custom@localhost
           IDENTIFIED BY 'stupid';
mysql&gt; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
           ON expenses.*
           TO custom@whitehouse.gov
           IDENTIFIED BY 'stupid';
mysql&gt; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
           ON customer.*
           TO custom@'%'
           IDENTIFIED BY 'stupid';
</pre><p>通过直接修改授权表设置用户权限,运行这些命令(注意,在结束时<code>FLUSH PRIVILEGES</code>): </p><pre>shell&gt; mysql --user=root mysql
mysql&gt; INSERT INTO user (Host,User,Password)
       VALUES('localhost','custom',PASSWORD('stupid'));
mysql&gt; INSERT INTO user (Host,User,Password)
       VALUES('server.domain','custom',PASSWORD('stupid'));
mysql&gt; INSERT INTO user (Host,User,Password)
       VALUES('whitehouse.gov','custom',PASSWORD('stupid'));
mysql&gt; 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&gt; 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&gt; 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&gt; FLUSH PRIVILEGES;
</pre><p>头3个<code>INSERT</code>语句增加<code>user</code>表条目,允许用户<code>custom</code>用给定口令从不同的主机进行连接,但是没有授予任何许可(所有权限被设置为缺省值<code>'N'</code>)。后3个<code>INSERT</code>语句增加<code>db</code>表条目,授予<code>custom</code>以<code>bankaccount</code>、<code>expenses</code>和<code>customer</code>数据库权限,但是只能在从正确的主机存取时。通常,在授权表直接被修改时,服务器必须被告知再次装入他们(用<code>FLUSH PRIVILEGES</code>)以便使权限修改生效。</p><p>如果你想要给特定的用户从一个给定的域上的任何机器上存取权限,你可以发出一个如下的<code>GRANT</code>语句: </p><pre>mysql&gt; GRANT ...
           ON *.*
           TO myusername@"%.mydomainname.com"
           IDENTIFIED BY 'mypassword';
</pre><p>为了通过直接修改授权表做同样的事情,这样做: </p><pre>mysql&gt; INSERT INTO user VALUES ('%.mydomainname.com', 'myusername',
           PASSWORD('mypassword'),...);
mysql&gt; FLUSH PRIVILEGES;
</pre><p>你也可以使用<code>xmysqladmin</code>、<code>mysql_webadmin</code>甚至<code>xmysql</code>在授权表中插入、改变和更新值。</p>

该用户从未签到

升级  30.8%

10
 楼主| 发表于 2006-4-9 17:26:26 | 只看该作者
<font color="#800080">使MySQL安全以对抗解密高手</font><p>当你连接一个<strong>MySQL</strong>服务器时,你通常应该使用一个口令。口令不以明文在连接上传输。 </p><p>所有其它信息作为能被任何人读懂的文本被传输。如果你担心这个,你可使用压缩协议(<strong>MySQL</strong>3.22和以上版本)使事情变得更难。甚至为了使一切更安全,你应该安装<code>ssh</code>(见<a href="http://www.cs.hut.fi/ssh">http://www.cs.hut.fi/ssh</a>)。用它,你能在一个<strong>MySQL</strong>服务器与一个<strong>MySQL</strong>客户之间得到一个加密的TCP/IP连接。 </p><p>为了使一个<strong>MySQL</strong>系统安全,强烈要求你考虑下列建议: </p><ul><li>对所有<strong>MySQL</strong>用户使用口令。记住,如果<code>other_user</code>没有口令,任何人能简单地用<code>mysql -u other_user db_name</code>作为任何其它的人登录。对客户机/服务器应用程序,客户可以指定任何用户名是常见的做法。在你运行它以前,你可以通过编辑<code>mysql_install_db</code>脚本改变所有用户的口令,或仅仅<strong>MySQL</strong> <code>root</code>的口令,象这样: <pre>shell&gt; mysql -u root mysql
mysql&gt; UPDATE user SET Password=PASSWORD('new_password')
           WHERE user='root';
mysql&gt; FLUSH PRIVILEGES;
</pre></li><li>不要作为Unix的<code>root</code>用户运行<strong>MySQL</strong>守护进程。<code>mysqld</code>能以任何用户运行,你也可以创造一个新的Unix用户<code>mysql</code>使一切更安全。如果你作为其它Unix用户运行<code>mysqld</code>,你不需要改变在<code>user</code>表中的<code>root</code>用户名,因为<strong>MySQL</strong>用户名与Unix 用户名没关系。你可以作为其它Unix用户编辑<code>mysql.server</code>启动脚本<code>mysqld</code>。通常这用<code>su</code>命令完成。 </li><li>如果你把一个Unix<code> root</code>用户口令放在<code>mysql.server</code>脚本中,确保这个脚本只能对<code>root</code>是可读的。 </li><li>检查那个运行<code>mysqld</code>的Unix用户是唯一的在数据库目录下有读/写权限的用户。 </li><li>不要把<strong>process</strong>权限给所有用户。<code>mysqladmin processlist</code>的输出显示出当前执行的查询正文,如果另外的用户发出一个<code>UPDATE user SET password=PASSWORD('not_secure')</code>查询,被允许执行那个命令的任何用户可能看得到。<code>mysqld</code>为有<strong>process</strong>权限的用户保留一个额外的连接, 以便一个<strong>MySQL</strong> <code>root</code>用户能登录并检查,即使所有的正常连接在使用。 </li><li>不要把<strong>file</strong>权限给所有的用户。有这权限的任何用户能在<code>拥有mysqld</code>守护进程权限的文件系统那里写一个文件!为了使这更安全一些,用<code>SELECT ... INTO OUTFILE</code>生成的所有文件对每个人是可读的,并且你不能覆盖已经存在的文件。<strong>file</strong>权限也可以被用来读取任何作为运行服务器的Unix用户可存取的文件。这可能被滥用,例如,通过使用<code>LOAD DATA</code>装载<tt>“/etc/passwd”</tt>进一个数据库表,然后它能用<code>SELECT</code>被读<code>入。</code> </li><li>如果你不信任你的DNS,你应该在授权表中使用IP数字而不是主机名。原则上讲,<code>--secure</code>选项对<code>mysqld</code>应该使主机名更安全。在任何情况下,你应该非常小心地使用包含通配符的主机名! </li></ul><p>下列<code>mysqld</code>选项影响安全: </p><dl compact="true"><dt><code>--secure</code> </dt><dd>由<code>gethostbyname()</code>系统调用返回的IP数字被检查,确保他们解析回到原来的主机名。这对某些外人通过模仿其它主机获得存取权限变得更难。这个选项也增加一些聪明的主机名检查。在<strong>MySQL</strong>3.21里,选择缺省是关掉的,因为它有时它花很长时间执行反向解析。<strong>MySQL</strong> 3.22缓存主机名并缺省地启用了这个选项。 </dd><dt><code>--skip-grant-tables</code> </dt><dd>这个选项导致服务器根本不使用权限系统。这给每个人以<em>完全存取</em>所有的数据库的权力!(通过执行<code>mysqladmin reload</code>,你能告诉一个正在运行的服务器再次开始使用授权表。) </dd><dt><code>--skip-name-resolve</code> </dt><dd>主机名不被解析。所有在授权表的<code>Host</code>的列值必须是IP数字或<code>localhost</code>。 </dd><dt><code>--skip-networking</code> </dt><dd>在网络上不允许TCP/IP连接。所有到<code>mysqld</code>的连接必须经由Unix套接字进行。这个选项对使用MIT-pthreads的系统是不合适的,因为MIT-pthreads包不支持Unix套接字。</dd></dl>
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

小黑屋|手机版|Archiver|信息系统项目管理师_软考交流平台. ( 鄂ICP备11002878号-1  公安备案号:42011102001150

GMT+8, 2025-7-5 20:42

Software by Discuz! X3.2

© 2001-2013 SKIN BY DSVUE

快速回复 返回顶部 返回列表