5.3.2 数据库
数据库级别的权限,主要用于控制帐户('user'@'host')操作某个数据库的权限,在这一粒度对用户做了授权后,用户就拥有了该数据库下[所有]对象的[所有]权限。
数据库级别的权限信息记录在mysql.db表。在介绍mysql.db表之前,这里三思想先特别提一下mysql.host表,这个表也与数据库粒度的权限有关联,它的功能相对奇特,是用于控制某些主机(host)是否拥有操作某个数据库的权限,在可设置的权限方面跟mysql.db几乎一模一样。
mysql.host表在MySQL5.5及之前版本中的处境很特别,默认情况下GRANT/REVOKE语句并不触发对该表数据的读写,因此多数情况下该表都没啥用,极易被忽略。不过在应对某些特定场景下,DBA可以手动操作(insert/update/delete)该表来实现某些特殊的需求。比如说只希望某些主机拥有操作某个数据库的权限时,mysql.user完全派不上用场(它是针对全局的嘛,管不到db这么细的粒度),那么使用mysql.host就可以轻松实现,因为该表对权限的验证正是使用host这个纬度。
当然啦,这个需求使用mysql.db表也可以实现,mysql.db表是通过user+host两个纬度来验证权限,比mysql.host多了一个纬度,不过由于MySQL数据库的权限字典表能够支持通配符,并且user列可以为空(代表所有用户),通过灵活设置也可以实现mysql.host表的功能,我想也正是基于此,从5.6版本开始,mysql.host表已被明确废弃。不过如果您在使用之前版本的数据库,如果场景适当,倒是仍可以用用mysql.host表。
还是说回到mysql.db表吧,功能前头已经说过了,不过出于加深印象的目的,我再重复说一遍大家没什么意见吧,有意见也不要紧,我的邮箱地址网上都写着哪,有啥抱怨的话尽管发,GMAIL邮箱,空间有好个G哪。
我个人感觉将数据库级权限与全局级权限对比起来更好理解,全局级权限大家都知道了吧,用来控制用户操作所有数据库的权限(以及管理MySQL服务的权限),数据都是保存在mysql.user字典表中。若只希望授予用户操作某个数据库的权限,该怎么办呢,那就该mysql.db出马啦,你要问mysql.user和mysql.db差在哪,对比一下两个字典表的表结构您就明白啦:
mysql.user表 | mysql.db表 |
Host | Host |
User | User |
Password |
|
| Db |
Select_priv | Select_priv |
Insert_priv | Insert_priv |
Update_priv | Update_priv |
Delete_priv | Delete_priv |
Create_priv | Create_priv |
Drop_priv | Drop_priv |
Reload_priv | Grant_priv |
References_priv | References_priv |
Index_priv | Index_priv |
Alter_priv | Alter_priv |
Create_tmp_table_priv | Create_tmp_table_priv |
Lock_tables_priv | Lock_tables_priv |
Create_view_priv | Create_view_priv |
Show_view_priv | Show_view_priv |
Create_routine_priv | Create_routine_priv |
Alter_routine_priv | Alter_routine_priv |
Execute_priv | Execute_priv |
Event_priv | Event_priv |
Trigger_priv | Trigger_priv |
Shutdown_priv |
|
Process_priv .......... .......... .......... |
|
表5-4 全局和库级权限对应表
你看,mysql.db表中有的列,在mysql.user中几乎全都有,而mysql.user中有的列则有一堆mysql.db表中都不存在呀,看看前面章节中介绍的权限说明,多出的列正是MySQL服务级的管理权限,说mysql.db是mysql.user表的子集都不为过。mysql.db相比mysql.user多出的"Db"列,不正是用来指定要管理的目标数据库嘛。
授予用户某个数据库的管理权限,执行GRANT语句时,相比全局就得缩小授权范围,把全局时指定的*.*改成dbname.*就行啦。例如,创建jss_database用户,并授予jssdb库下创建对象的权限,执行命令如下:
(system@localhost) [(none)]> grant create on jssdb.* to jss_db;
Query OK, 0 rows affected (0.00 sec)
创建成功,查看jss_db用户在各字典表的记录明细,以便我们能够更清晰的理解,权限字典表在用户权限环境所起到的作用。
先来刚刚创建的用户,在mysql.user全局权限表中的信息:
(system@localhost) [(none)]> select * from mysql.user where user='jss_database'\G
*************************** 1. row ***************************
Host: %
User: jss_database
Password:
Select_priv: N
Insert_priv: N
Update_priv: N
Delete_priv: N
Create_priv: N
Drop_priv: N
Reload_priv: N
Shutdown_priv: N
.............
............
操作类权限都是"N"(相当于仅拥有USAGE权限),这就对了,允许该用户登录MySQL数据库。那么操作jssdb数据库的权限写在哪了呢,再看看mysql.db库级权限字典表吧:
(system@localhost) [(none)]> select * from mysql.db where user='jss_db'\G
*************************** 1. row ***************************
Host: %
Db: jssdb
User: jss_db
Select_priv: N
Insert_priv: N
Update_priv: N
Delete_priv: N
Create_priv: Y
Drop_priv: N
Grant_priv: N
References_priv: N
Index_priv: N
Alter_priv: N
Create_tmp_table_priv: N
Lock_tables_priv: N
Create_view_priv: N
Show_view_priv: N
Create_routine_priv: N
Alter_routine_priv: N
Execute_priv: N
Event_priv: N
Trigger_priv: N
1 row in set (0.00 sec)
这下就比较清晰了,"Db"表显示了可操作的库名,"Create_priv"列值显示"Y",表示这个用户拥有指定库中对象的创建权限。
下面再通过该用户连接到MySQL数据库中看一下吧。使用jss_db用户登录,查看当前可访问的数据库:
(jss_db@192.168.30.243) [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| jssdb |
+--------------------+
2 rows in set (0.00 sec)
jssdb库倒是列出来了,但是,好奇怪呀,不是说只授予了jssdb库的权限吗,怎么还能看到information_schema库呢,别急,咱们马上就会提到这一点。
5.3.2.1 并不存在的 INFORMATION_SCHEMA 库熟悉ORACLE数据库的朋友想必知道,在ORACLE数据库中有一堆v$*视图、user_*、all_*等字典表,所有能够成功连接数据库的用户都可以访问这些对象(无须额外授权),MySQL数据库中也存在一系列这样的对象,比如TABLES、VIEWS、COLUMNS等等,所有能够成功登录到MySQL数据库的用户都能访问。
想一想,这些对象在哪呢,没错,正是在INFORMATION_SCHEMA数据库下。即然这类对象能够被访问,那么INFORMATION_SCHEMA库自然也就能被所有用户看到啦,这样才符合逻辑。
需要注意的是,MySQL中的INFORMATION_SCHEMA并不是真正的数据库,在操作系统层并没有与之对应的物理文件,这个数据库及库中的对象,全是由MySQL自动维护的一系列虚拟对象,这些对象用户能看却不能改(不能直接改),并且与ORACLE数据库中的数据字典表类似,用户查询这些对象中的记录时,看到的都是自己有权限看到的对象。比如说拥有jssdb库创建权限的jss_db用户,能够在INFORMATION_SCHEMA数据库的TABLES/COLUMNS等对象中,查看jssdb库中所有表和列的信息,但是因为没有视图/过程这类对象的操作权限,那么访问VIEWS字典表时,就查看不到记录啦。
INFORMATION_SCHEMA库中对象的另一特殊之处在于,用户不能对INFORMATION_SCHEMA数据库中的对象做授权。比如将information_schema.tables表对象的select权限授予某个用户,这样操作肯定会失败,即使是管理员用户也不行。
5.3.2.2 有趣的 test 库除了INFORMATION_SCHEMA这样的虚拟库外,MySQL数据库中的test库的默认权限也需要引起DBA们注意。
新建MySQL数据库后,默认创建的test数据库权限比较怪异,所有可连接的用户都能够拥有权限访问该库,并操作其中的对象。这是怎么实现的呢,其实很简单,查看库级权限字典表,mysql.db您就明白了:
mysql> select * from mysql.db where db like 'test%'\G;
*************************** 1. row ***************************
Host: %
Db: test
User:
Select_priv: Y
Insert_priv: Y
Update_priv: Y
Delete_priv: Y
Create_priv: Y
Drop_priv: Y
Grant_priv: N
References_priv: Y
Index_priv: Y
Alter_priv: Y
Create_tmp_table_priv: Y
Lock_tables_priv: Y
Create_view_priv: Y
Show_view_priv: Y
Create_routine_priv: Y
Alter_routine_priv: N
Execute_priv: N
Event_priv: Y
Trigger_priv: Y
*************************** 2. row ***************************
Host: %
Db: test\_%
User:
Select_priv: Y
Insert_priv: Y
Update_priv: Y
Delete_priv: Y
Create_priv: Y
Drop_priv: Y
Grant_priv: N
References_priv: Y
Index_priv: Y
Alter_priv: Y
Create_tmp_table_priv: Y
Lock_tables_priv: Y
Create_view_priv: Y
Show_view_priv: Y
Create_routine_priv: Y
Alter_routine_priv: N
Execute_priv: N
Event_priv: Y
Trigger_priv: Y
2 rows in set (0.00 sec)
你看,从权限上来看,host为%,user为空,这就说明了不限制的,所有能连接到MySQL的用户,全都拥有test及test开头的数据库的几乎所有权限。
这无异存在安全上的隐患,先不说在其中创建的重要对象可被任何人访问,就算该库中没有任何对象,假如有人想恶意破坏DB服务,只要登录数据库后,在该库创建一个超大对象,把空闲空间全部占满,就相当于变相达到了破坏DB服务的目地。对于这类权限没啥好客气的,该咋处理就咋处理吧。
不过如果读者朋友是按照三思在本书中介绍的步骤创建数据库,那就不会存在这种隐患了,还记的第三章中,配置数据库环境时我们做过的操作吗:
(root@localhost) [(none)]> truncate table mysql.db;
Query OK, 0 rows affected (0.00 sec)
直接清空mysql.db表中记录,这两个权限已被删除,隐患早已经被排除啦。
顺便提出一个问题,如果想让所有用户都拥有访问jssdb库中对象的权限,GRANT语句应该怎么写呢,有兴趣的朋友不妨在自己的测试环境中模拟一下吧。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7607759/viewspace-1202465/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/7607759/viewspace-1202465/