MySQL的权限排序问题

MySQL的权限排序问题

实验:因权限表具有通配符,对权限进行排序后,匹配时引来的问题。

授权表中的通配符

  1. user表中User为空值表示匹配任意user name,也表示匿名用户。
  2. user表中Host部分用户可以使用通配符”%”和”_”在host name或者IP地址中,这些具有和模式匹配LIKE相同的意义。
  3. db表中,Host、User与user表中表示方法一致,同时Db列也可以具有通配符。
  4. tables_priv、columns_priv和procs_priv表中,只有Host列可以具有通配符。

账户登录的匹配:

由于具有通配符,这就会发生一个用户连接server可以匹配多个账户的事情发生。例如创建了账户’’@localhost和’yz’@’%’,当用户’yz’@localhost登录时两个账户都可以匹配。这样就面临着选择哪一个账户作为登录账户的问题。MySQL为解决这个问题,对user表中的记录做了排序。排序方法如下:

先按最具体的(most-specific)Host值排序。原义的host_name和IP地址算是最具体的(IP地址的具体级别specificity是不受子网掩码影响的,192.168.1.13和192.168.1.0/255.255.255.0被认为是同一具体级别)。匹配符’%’算是最不具体的级别。空字符’’也表明任意host,但排在’%’后面。有相同Host值的行首先以最具体的User值排序(空User值意味着“任何用户”并且是最不具体的)。对于具有相同具体级别的Host和User值,排序是不确定。

采用上述方法,当’yz’@localhost登录时,匹配的就是账号’’@localhost。如果用用账户’yz’@’%’的密码试图登录,可能会被告知Access denied for user 'yz'@'localhost',因为MySQL选取的登录账户是’’@localhost。

不过MySQL也比较奇怪,登录后使用select user()发现

+--------------+

| user()       |

+--------------+

| yz@localhost |

+--------------+

使用show grants;可以看到下面结果,账户是’’@localhost。

+------------------------------------------------+

| Grants for @localhost            |

+------------------------------------------------+

| GRANT USAGE ON . TO ''@'localhost'  |

| GRANT CREATE ON `privtest`.* TO ''@'localhost' |

+------------------------------------------------+

问题1,同一账户不同db_name授权信息引发的问题:

账户行为还好,不会引起太大的坑。db中的排序不注意可能就会导致MySQL结果不一致,用户权限可能‘丢失’,导致用户无法正常工作,服务故障。

db表在Host、Db和User范围列上排序,也是按照具体到不具体排序,而且匹配到第一条符合的记录后,就返回。首先其排序是不稳定排序,这会导致插入一条不相关的记录,导致其他记录排序变化,权限表现变化,部分原有权限‘丢失’。即使是稳定排序,也会导致逻辑上应该有的权限没有,例如

grant select on aaa.* to yz@localhost;

grant create on `aa%` to yz@localhost;

grant insert on `aaa%` to yz@localhost;

       MySQL在做权限检查时,只会返回匹配到的第一条记录,即用户yz@localhost对aaa数据库只有select权限,不会有create和insert权限。从这个角度讲即使排序稳定,插入新的权限信息也可能会导致之前的权限‘丢失’。

相关知识:

1、mysql的权限验证有global,db,table,column多个纬度。
2、在global和db纬度中,mysql按内部权重,从大到小读取所有授权,获取第一个匹配(权重最大的)的作为内部授权验证。
3、db纬度的权重计算方法如下:
    3.1 分别按照hostname,dbname,username计算。
    3.2 单个字符串若不存在通配符权重为0x80,若存在通配符,则权重为第一个通配符出现的位置,最大为0x7F
    3.3 举例 GRANT CREATE ON `tt_`.* TO 'tt'@‘%’ 这条授权的权重为0x010380,其中’%’为0x01 ’tt_’为0x03 ’tt’为0x80
4、当前mysql内部大部分排序采用快速排序,这是一种不稳定的排序算法。

问题2 不同账户之间授权信息引发的问题:

实验:MySQL在db层验证权限时,是否会对db中所有账户权限信息都做逐一匹配。

结论:从效果上MySQL会逐一匹配db表中的信息,遇到能匹配的就返回,导致拥护show grants的权限信息可能与实际权限不一致。(table层也是这样)

MySQL排序先后为Host、Db、User,前面user表在匹配时会发生匹配多条记录,那么在db层匹配时,同时可匹配的账户是否也会在db层发生匹配。实验:

同时创建

’yz’@’%’和’yz’@localhost账号。

对’yz’@’%’赋予权限:

grant create on yzdb to 'yz'@'%';

登录yz@localhost,执行下面语句,可以看到权限信息仅Usage。这个时候试着创建database yzdb,会发现其具有创建yzdb的权限。

mysql> show grants;

+----------------------------------------+

| Grants for yz@localhost                |

+----------------------------------------+

| GRANT USAGE ON . TO 'yz'@'localhost' |

+----------------------------------------+

mysql> create database yzdb;

Query OK, 1 row affected (0.02 sec)

当撤销'yz'@'%'的创建yzdb权限,'yz'@'localhost'也会失去该权限。

在测试中,’’@localhost账户不会拥有'yz'@'%'的上述权限。在这里匹配时,’yz’不等同于’’。

上述情况也会产生权限‘丢失’问题,show grants中有的权限可能因为其他账户授权信息引发‘丢失’。

时间: 2024-10-03 03:17:31

MySQL的权限排序问题的相关文章

MySQL中文参考手册7(MySQL 存取权限系统) grant 设置密码 password

mysql|word|参考|参考手册|中文 MySQL中文参考手册7(MySQL 存取权限系统)转载 译者:晏子 [返回][转发] 译者:晏子 (clyan@sohu.com)主页:http://linuxdb.yeah.net6 MySQL 存取权限系统MySQL有一个先进但非标准的安全/权限系统.本节描述它的工作原理.  6.1 权限系统做什么MySQL权限系统的主要功能是证实连接到一台给定主机的一个用户,并且赋予该用户在一个数据库上select. insert.update和delete的

MYSQL教程:MySQL服务器权限表

MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化.这些权限表分别user,db,table_priv,columns_priv和host.下面分别介绍一下这些表的结构和内容: user权限表:记录允许连接到服务器的用户帐号信息,里面的权限是全局级的. db权限表:记录各个帐号在各个数据库上的操作权限. table_priv权限表:记录数据表级的操作权限. columns_priv权限表:记录数据列级的操作权限. ho

MySQL用户权限(Host,User,Password)管理(mysql.user)

1:新增用户: 注:mysql数据库下user表中,Host和User为两个主键列(primary key),已经各版本下非空未设置默认字段. 登录后,切换db: mysql> use mysql; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed 新增用

配置Mysql用户权限命令

查看用户权限:show grants for occ@localhost; 查看用户列表:select host,user,password from user; 先对密码加密:select password('testpwd');这样执行后 会得到一串字符串 赋予用户权限:grant all on fox.* to huli@localhost identified by password '*61DE32B297DFFDD9B848CB8F21C4BC0EDA6A48E1'; 插销用户权限:

mysql全局权限账户%登录不上ERROR 1045 (28000): Access denied for user 'mhz'@'localhost' (using password: YES)

mysql全局权限账户%登录不上 ERROR 1045 (28000): Access denied for user 'mhz'@'localhost' (using password: YES)  解决 查看错误提示  有主机名字的就必须赋值主机名 mysql> GRANT ALL PRIVILEGES ON *.* TO 'mhz'@'mgr2' IDENTIFIED BY 'mhz' WITH GRANT OPTION; Query OK, 0 rows affected (0.00 s

MySQL用户权限管理详解_Mysql

用户权限管理主要有以下作用: 1. 可以限制用户访问哪些库.哪些表 2. 可以限制用户对哪些表执行SELECT.CREATE.DELETE.DELETE.ALTER等操作 3. 可以限制用户登录的IP或域名 4. 可以限制用户自己的权限是否可以授权给别的用户 一.用户授权 复制代码 代码如下: mysql> grant all privileges on *.* to 'yangxin'@'%' identified by 'yangxin123456' with grant option;  

mysql远程权限设置的方法

mysql默认只允许本地登录,以下操作可使用户拥有远程权限,以root用户为例. 命令状态下 一.允许用户在任意IP登录,并拥有所有数据库的所有权限: GRANT ALL PRIVILEGES ON *.* TO "root"@"%" IDENTIFIED BY "password" WITH GRANT OPTION; 二.允许用户在指定IP登录,并拥有所有数据库的所有权限: GRANT ALL PRIVILEGES ON *.* TO &qu

MySQL账号权限建议

原则 1.只给满足条件的`最小权限` 2.密码符合一定规则的复杂度: 长度大于11位包括大小写字母.数字.和# @ $等特殊字符 root 账号 强烈建议限制在127.0.0.1本地登录 这里延伸一个MySQL socket连接的问题 A Unix socket file is used if you do not specify a host name or if you specify the special host name localhost mysql连接的时候没有指定hostnam

查看 MySQL 用户权限

查看当前用户(自己)权限: show grants; 查看其他 MySQL 用户权限: show grants for aaa@localhost;