关于MySQL绕过授予information_schema中对象时报ERROR 1044(4200)错误

这个问题是微信群中网友关于MySQL权限的讨论,有这么一个业务需求(下面是他的原话):

因为MySQL的很多功能都依赖主键,我想用zabbix用户,来监控业务数据库的所有表,是否都建立了主键。

监控的语句是:

FROM  information_schema.tables t1
    LEFT OUTER JOIN information_schema.table_constraints t2
          ON t1.table_schema = t2.table_schema
            AND t1.table_name = t2.table_name
            AND t2.constraint_name IN ( 'PRIMARY' )
WHERE t2.table_name IS NULL
    AND t1.table_schema NOT IN ( 'information_schema', 'myawr', 'mysql',
                  'performance_schema',
                  'slowlog', 'sys', 'test' )
    AND t1.table_type = 'BASE TABLE' 

但是我不希望zabbix用户,能读取业务库的数据。一旦不给zabbix用户读取业务库数据的权限,那么information_schema.TABLES 和 information_schema.TABLE_CONSTRAINTS 就不包含业务库的表信息了,也就统计不出来业务库的表是否有建主键。有没有什么办法,即让zabbix不能读取业务库数据,又能监控是否业务库的表没有建立主键?

首先,我们要知道一个事实:information_schema下的视图没法授权给某个用户。如下所示

mysql> GRANT SELECT ON information_schema.TABLES TO test@'%';
ERROR 1044 (42000): Access denied for user 'root'@'localhost' to database 'information_schema'

关于这个问题,可以参考mos上这篇文章:Why Setting Privileges on INFORMATION_SCHEMA does not Work (文档 ID 1941558.1)

APPLIES TO:

MySQL Server - Version 5.6 and later

Information in this document applies to any platform.

GOAL

To determine how MySQL privileges work for INFORMATION_SCHEMA.

SOLUTION

A simple GRANT statement would be something like:

mysql> grant select,execute on information_schema.* to 'dbadm'@'localhost';

ERROR 1044 (42000): Access denied for user 'root'@'localhost' to database 'information_schema'

The error indicates that the super user does not have the privileges to change the information_schema access privileges.

Which seems to go against what is normally the case for the root account which has SUPER privileges.

The reason for this error is that the information_schema database is actually a virtual database that is built when the service is started.

It is made up of tables and views designed to keep track of the server meta-data, that is, details of all the tables, procedures etc. in the database server.

So looking specifically at the above command, there is an attempt to add SELECT and EXECUTE privileges to this specialised database.

The SELECT option is not required however, because all users have the ability to read the tables in the information_schema database, so this is redundant.

The EXECUTE option does not make sense, because you are not allowed to create procedures in this special database.

There is also no capability to modify the tables in terms of INSERT, UPDATE, DELETE etc., so privileges are hard coded instead of managed per user.

那么怎么解决这个授权问题呢? 直接授权不行,那么我们只能绕过这个问题,间接实现授权。思路如下:首先创建一个存储过程(用户数据库),此存储过程找出没有主键的表的数量,然后将其授予test用户。

DELIMITER //
CREATE DEFINER=`root`@`localhost` PROCEDURE `moitor_without_primarykey`()
BEGIN
   SELECT COUNT(*)
FROM  information_schema.tables t1
    LEFT OUTER JOIN information_schema.table_constraints t2
          ON t1.table_schema = t2.table_schema
            AND t1.table_name = t2.table_name
            AND t2.constraint_name IN ( 'PRIMARY' )
WHERE t2.table_name IS NULL
    AND t1.table_schema NOT IN ( 'information_schema', 'myawr', 'mysql',
                  'performance_schema',
                  'slowlog', 'sys', 'test' )
    AND t1.table_type = 'BASE TABLE';
END //
DELIMITER ;

mysql> GRANT EXECUTE ON PROCEDURE moitor_without_primarykey TO 'test'@'%';
Query OK, 0 rows affected (0.02 sec)

此时test就能间接的去查询information_schema下的对象了。

mysql> select current_user();
+----------------+
| current_user() |
+----------------+
| test@%     |
+----------------+
1 row in set (0.00 sec)

mysql> call moitor_without_primarykey;
+----------+
| COUNT(*) |
+----------+
|    6 |
+----------+
1 row in set (0.02 sec)

Query OK, 0 rows affected (0.02 sec)

查看test用户的权限。

mysql> show grants for test@'%';
+-------------------------------------------------------------------------------+
| Grants for test@%                               |
+-------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `test`@`%`                       |
| GRANT EXECUTE ON PROCEDURE `zabbix`.`moitor_without_primarykey` TO `test`@`%` |
+-------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

到此这篇关于关于MySQL绕过授予information_schema中对象时报ERROR 1044(4200)错误的文章就介绍到这了,更多相关mysql ERROR 1044(4200)内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2020-10-13

mysql ERROR 1044 (42000): Access denied for user ''@'localhost' to database

1. 问题描述: 在MySQL控制台下创建数据库出现以下信息: mysql> CREATE DATABASE python; ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'python' 2. 解决方法: 执行以下命令进入控制台: mysql --user=root -p 输入root用户的密码即可进入mysql控制台: 创建数据库: create database python; 显示所有数据库:

mysql出现ERROR 1819 (HY000)的解决方法

ERROR 1819 (HY000): Your password does not satisfy the current policy requirements,出现这个问题怎么办?不用着急,下面给出答案. 为了加强安全性,MySQL5.7为root用户随机生成了一个密码,在error log中,关于error log的位置,如果安装的是RPM包,则默认是/var/log/mysqld.log. 一般可通过log_error设置 mysql> select @@log_error; +---

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock'

错误信息: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) 出现问题原因: 有可能是 my.cnf 配置文件中设置了 [mysqld] 的参数 socket ,而没有设置[client]的参数socket mysql.sock 文件有什么用: mysql 支持 socket 和 TCP/IP 连接.那么 mysql.sock 这个文件有什么用呢?连接local

MySQL出现SQL Error (2013)连接错误的解决方法

现象描述 今天用heidisql登陆虚拟机的MySQL,登陆不上去.等待约一两分钟后出现错误提示:SQL Error (2013): Lost connection to MySQL server at 'waiting for initial communication packet', system error: 0,如下图所示: 开始以为是远程TCP/IP  root只能通过localhost访问 ,后来新建用户,改为%后还是无果.尝试修改my.ini配置问题后问题消失. 解决办法 在my

mysql输入中文出现ERROR 1366的解决方法

MySQL输入中文出现如下错误: ERROR 1366: 1366: Incorrect string value: '\xE6\xB0\xB4\xE7\x94\xB5...' for column 'introduce' at row 1 这是因为mysql编码的问题 打开mysql mysql -u root -p 输入密码后,输入下面这一行代码来显示mysql当前使用的编码: SHOW VARIABLES LIKE 'character%'; 由上 图能看出,database和server

MySql 修改密码后的错误快速解决方法

设置好密码后,使用数据库时出现如下错误: ERROR 1820 (HY000): You must reset your password using ALTER USER statement befo re executing this statement. You must SET PASSWORD before executing this statement的解决方法 今天在MySql5.6操作时报错:You must SET PASSWORD before executing this

mysql安装时出现各种常见问题的解决方法

小编为大家整理许多mysql安装时出现各种常见问题的解决方法,供大家参考,具体内容如下 问题一: 当各位在安装.重装时出现could not start the service mysql error:0 原因: 卸载mysql时并没有完全删除相关文件和服务,需要手动清除. 安装到最后一步execute时不能启动服务的解决方法: 首先,在管理工具->服务里面将MySQL的服务给停止(有的是没有安装成功,有这个服务,但是已经停止了的),win+R->cmd,打开命令提示符窗口,输入命令:sc d

php查询mysql大量数据造成内存不足的解决方法

本文实例分析了php查询mysql大量数据造成内存不足的解决方法.分享给大家供大家参考.具体分析如下: 一.问题 使用php查询mysql大数据量的时候,程序尚未执行完毕,跳出警告: Fatal error:  Allowed memory size of 100663296 bytes exhausted (tried to allocate 103 bytes) 错误提示:php所分配到的100M内存被占用完毕. 二.解决方法: 最简单的解决办法是:在执行文件的头部增加: ini_set('

解决中文乱码的几种解决方法(推荐)

首先说明我的特殊情况: 1. 前台jsp中,我使用的是 form post 请求,设置了 enctype="multipart/form-data" ,页面编码格式都是utf-8 2. 后台中,我使用的是commons-fileUpload组件,ServletFileUpload 解析form表单和文件, 3. 设置 request.setCharacterEncoding("UTF-8"); 4. 设置了ServletFileUpload .setHeaderEn

C3P0连接池+MySQL的配置及wait_timeout问题的解决方法

 一.配置环境 spring4.2.4+mybatis3.2.8+c3p0-0.9.1.2+Mysql5.6.24 二.c3p0的配置详解及spring+c3p0配置 1.配置详解 官方文档 : http://www.mchange.com/projects/c3p0/index.html <c3p0-config> < default-config> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数.Default: 3 --> <property

php版微信公众平台回复中文出现乱码问题的解决方法

本文实例分析了php版微信公众平台回复中文出现乱码问题的解决方法.分享给大家供大家参考,具体如下: 微信公众平开发时碰到回复中文乱码了,这个问题小编发现是编码问题,其实只要把编码转成utf8就可以解决了,具体来看看. 很多微信公众平台的自动回复程序都是 ThinkWechat.class.php 这个类开发的,今天碰到一个莫名其妙的乱码问题,查问题发现是GB2312编码导致,所以要修改源码. 先增加一个方法: /** * 检测是否UTF-8 * @param $str * @return boo

安装python3的时候就是输入python3死活没有反应的解决方法

我用brew安装python3 装完了发现 输入python3毫无反应,检查了 $PATH 也没有任何问题 这个时候回去看安装过程,发现安装时有一个错误: ERROR:The `brew link` step did not complete successfully The formula built, but is not symlinked into /usr/local Could not symlink lib/pkgconfig/python-3.6.pc (好像是这个,安装的时候忘

MySQL无法存储Emoji表情问题的解决方法分析

本文实例讲述了MySQL无法存储Emoji表情问题的解决方法.分享给大家供大家参考,具体如下: 数据插入的时候报错: 1366 - Incorrect string value: '\xF0\x9F\x98\x81' for column 'job' at row 23 解决办法: 1.修改配置文件my.ini[D:\Program Files\MySQL\MySQL Server 5.5]: [mysql] default-character-set=utf8mb4 [mysqld] char

读写json中文ASCII乱码问题的解决方法

今天要帮前端写一个小后台,就是读取数据然后转成json送给他,让他去展示.数据很简单,但是处理的时候遇到了一个问题,文件中涉及到了中文的处理,每次处理完写的json格式就是ASCII码,完全没办法用.代码如下: # -*- coding: utf-8 -*- import json import codecs f = codecs.open('data.txt', 'r', 'utf-8') content = json.load(f) print content[0]['id'] jsdata