三思笔记,涂抹ORACLE/MySQL

涂抹MySQL上市了

  • 博客访问: 3939102
  • 博文数量: 675
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-21 18:08
个人简介

暂无介绍

ITPUB论坛APP

ITPUB论坛APP



APP发帖 享双倍积分

文章分类

全部博文(675)

微信关注

IT168企业级官微



微信号:IT168qiye



系统架构师大会



微信号:SACC2013

分类: MySQL

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.usermysql.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.dbmysql.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数据库中也存在一系列这样的对象,比如TABLESVIEWSCOLUMNS等等,所有能够成功登录到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的用户,全都拥有testtest开头的数据库的几乎所有权限。

这无异存在安全上的隐患,先不说在其中创建的重要对象可被任何人访问,就算该库中没有任何对象,假如有人想恶意破坏DB服务,只要登录数据库后,在该库创建一个超大对象,把空闲空间全部占满,就相当于变相达到了破坏DB服务的目地。对于这类权限没啥好客气的,该咋处理就咋处理吧。

不过如果读者朋友是按照三思在本书中介绍的步骤创建数据库,那就不会存在这种隐患了,还记的第三章中,配置数据库环境时我们做过的操作吗:

(root@localhost) [(none)]> truncate table mysql.db;

Query OK, 0 rows affected (0.00 sec)

直接清空mysql.db表中记录,这两个权限已被删除,隐患早已经被排除啦。

顺便提出一个问题,如果想让所有用户都拥有访问jssdb库中对象的权限,GRANT语句应该怎么写呢,有兴趣的朋友不妨在自己的测试环境中模拟一下吧。

阅读(9835) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册