MySQL的SHOW GRANTS显示当前用户的权限。

是否可以以root用户身份登录并显示所有用户的权限?

#1 楼

没有内置的。不过,您有两个选择:



使用common_schema的sql_show_grants视图。例如,您可以查询:

 SELECT sql_grants FROM common_schema.sql_show_grants;
 


,也可以查询特定用户,例如示例:

 SELECT sql_grants FROM common_schema.sql_show_grants WHERE user='app';
 


要安装common_schema,请按照此处的说明进行操作。

免责声明:我是该工具的作者。


使用Percona Toolkit的pt-show-grants,例如:

pt-show-grants --host localhost --user root --ask-pass



在这两种情况下,您都可以请求GRANT命令或REVOKE(相反)命令。

第一种情况要求您安装模式,后者需要安装PERL脚本+依赖关系。

评论


您能否详细描述如何使用common_schema的sql_show_grants视图?我收到错误ERROR 1146(42S02):表'common_schema.sql_show_grants'不存在

–马丁·维格特(Martin Vegter)
13-10-24在19:52

@MartinVegter,您安装了common_schema吗?在此处下载并按照以下说明进行安装。

– Shlomi Noach
13-10-25在5:04

@ThorSummoner,很遗憾,MySQL的group_concat_max_len的默认值为1024。它是最早更改的默认值之一,建议您将其设置为较高的值,例如1,000,000或更高。在我的博客中进一步查看

– Shlomi Noach
2015年12月5日,12:28

抱歉,没有'common_schema'这样的东西。它不存在。

–布兰登·伯德(Brendan Byrd)
17年9月22日在21:00

链接sql_show_grants损坏

– Cyzanfar
18年1月6日在2:13

#2 楼

select * from information_schema.user_privileges;


编辑:

如Shlomi Noach所述:


它没有列出特定于数据库,特定于表的列特定于
例程特定的特权。因此,授予myuser @ localhost的GRANT SELECT ON
mydb。*不会显示在information_schema.user_privileges中。上面介绍的common_schema解决方案
汇总了user_privileges和其他表中的数据
以提供完整的图片。


评论


抱歉,该答案不应该被接受。 information_schema.user_privileges仅列出用户级别的特权,例如SUPER,RELOAD等。它还列出诸如SELECT之类的全方位DML授予。它没有列出特定于数据库,特定于表,特定于列,特定于例程的特权。因此,授予myuser @ localhost的GRANT SELECT ON mydb。*授予不会显示在information_schema.user_privileges上。上面介绍的common_schema解决方案汇总了user_privileges和其他表中的数据,从而为您提供了完整的视图。

– Shlomi Noach
2015年7月9日在11:22

common_schema在官方的MySQL表集中不存在,所以我不同意删除此处的复选标记。并非每个人都有权安装这样的自定义数据库。

–布兰登·伯德(Brendan Byrd)
10月20日15:33

#3 楼

此Linux Shell片段遍历所有MySQL用户,并为每个MySQL用户执行一个SHOW GRANTS:如果您无需密码即可连接到MySQL,则效果最佳。

输出已格式化,因此可以在MySQL shell中运行。
警告:输出还包含MySQL根用户权限和密码!如果您不想更改MySQL root用户,请删除这些行。

评论


您可能要添加一些有关此功能或其回答方式的详细信息。仅显示一堆代码并不能帮助任何人理解您的解决方案为何起作用。

– Max Vernon♦
2013年9月9日23:13

在哪里可以输入密码?

–Mian Asbat Ahmad
17年2月1日在15:05

要提供密码,可以使用选项文件或mysql命令的--password标志。

–mleu
17年2月2日在13:08



不能给出一个root密码并运行查询以获取所有用户的授权吗?

–Mian Asbat Ahmad
17年2月3日,11:33

您可以流式传输请求以仅建立一个连接,并使用模式400根拥有的凭据文件。我的版本:mysql --defaults-file = / auth / root-mysql.cnf --batch --skip-column-names --execute“从mysql.user中选择用户,主机” |同时读取用户主机;做回显“ SHOW GRANTS FOR'$ {user}” @“ $ {host}”;”;完成| mysql --defaults-file = / auth / root-mysql.cnf --batch | sed's / ^授予/-授予/

–BaseZen
18年5月16日在19:05



#4 楼

Unix bash中的一个衬里(将-uroot更改为-u$USER_NAME,以便与其他用户一起使用)(由于反引号):命令前面的命令将其从Ubuntu的Bash历史记录中排除):

mysql -uroot -p -sNe"`mysql -uroot -p -se"SELECT CONCAT('SHOW GRANTS FOR \'',user,'\'@\'',host,'\';') FROM mysql.user;"`"


在Windows中:

 mysql -uroot -p"$PASSWORD" -sNe"$(mysql -uroot -p"$PASSWORD" -se"SELECT CONCAT('SHOW GRANTS FOR \'',user,'\'@\'',host,'\';') FROM mysql.user;")"


#5 楼

select * from mysql.user;

可以为您提供用户列表和分配给每个用户的特权,尽管mysql.user用户需要访问root表。

评论


这仅为您提供“顶级”(服务器级别)特权。在特定模式上设置的权限位于mysql.db中。特定表的权限位于mysql.tables_priv中,依此类推。所以这不是那么简单。

– Shlomi Noach
2012年8月28日在12:40

对于彩虹表的恶作剧,将mysql.user中的select *的密码哈希值放入crackstation.net中,并查看未隐藏的输出。

–起搏器
15年7月7日在8:30



#6 楼

如果可以正确运行以下SELECT语句:

/* User-Specific Grants     */   SELECT * FROM mysql.user;
/* Database-Specific Grants */   SELECT * FROM mysql.db;
/* Table-Specific Grants    */   SELECT * FROM mysql.tables_priv;
/* Column-Specific Grants   */   SELECT * FROM mysql.columns_priv;


,请随时使用以下以.sql语法编写的代码。

我设计此查询的目的是尝试为所有现有权限重建GRANT语句(以在数据库迁移期间频繁维护)。
有一些问题需要解决,例如用户密码链接,但由于我们经常更新密码,因此不在此项目范围内。

/* Get All Grants/Permissions for MySQL Instance */

/* [Database.Table.Column]-Specific Grants */
SELECT
    CONCAT("`",gcl.Db,"`") AS 'Database(s) Affected',
    CONCAT("`",gcl.Table_name,"`") AS 'Table(s) Affected',
    gcl.User AS 'User-Account(s) Affected',
    IF(gcl.Host='%','ALL',gcl.Host) AS 'Remote-IP(s) Affected',
    CONCAT("GRANT ",UPPER(gcl.Column_priv)," (",GROUP_CONCAT(gcl.Column_name),") ",
                 "ON `",gcl.Db,"`.`",gcl.Table_name,"` ",
                 "TO '",gcl.User,"'@'",gcl.Host,"';") AS 'GRANT Statement (Reconstructed)'
FROM mysql.columns_priv gcl
GROUP BY CONCAT(gcl.Db,gcl.Table_name,gcl.User,gcl.Host)
/* SELECT * FROM mysql.columns_priv */

UNION

/* [Database.Table]-Specific Grants */
SELECT
    CONCAT("`",gtb.Db,"`") AS 'Database(s) Affected',
    CONCAT("`",gtb.Table_name,"`") AS 'Table(s) Affected',
    gtb.User AS 'User-Account(s) Affected',
    IF(gtb.Host='%','ALL',gtb.Host) AS 'Remote-IP(s) Affected',
    CONCAT(
        "GRANT ",UPPER(gtb.Table_priv)," ",
        "ON `",gtb.Db,"`.`",gtb.Table_name,"` ",
        "TO '",gtb.User,"'@'",gtb.Host,"';"
    ) AS 'GRANT Statement (Reconstructed)'
FROM mysql.tables_priv gtb
WHERE gtb.Table_priv!=''
/* SELECT * FROM mysql.tables_priv */

UNION

/* Database-Specific Grants */
SELECT
    CONCAT("`",gdb.Db,"`") AS 'Database(s) Affected',
    "ALL" AS 'Table(s) Affected',
    gdb.User AS 'User-Account(s) Affected',
    IF(gdb.Host='%','ALL',gdb.Host) AS 'Remote-IP(s) Affected',
    CONCAT(
        'GRANT ',
        CONCAT_WS(',',
            IF(gdb.Select_priv='Y','SELECT',NULL),
            IF(gdb.Insert_priv='Y','INSERT',NULL),
            IF(gdb.Update_priv='Y','UPDATE',NULL),
            IF(gdb.Delete_priv='Y','DELETE',NULL),
            IF(gdb.Create_priv='Y','CREATE',NULL),
            IF(gdb.Drop_priv='Y','DROP',NULL),
            IF(gdb.Grant_priv='Y','GRANT',NULL),
            IF(gdb.References_priv='Y','REFERENCES',NULL),
            IF(gdb.Index_priv='Y','INDEX',NULL),
            IF(gdb.Alter_priv='Y','ALTER',NULL),
            IF(gdb.Create_tmp_table_priv='Y','CREATE TEMPORARY TABLES',NULL),
            IF(gdb.Lock_tables_priv='Y','LOCK TABLES',NULL),
            IF(gdb.Create_view_priv='Y','CREATE VIEW',NULL),
            IF(gdb.Show_view_priv='Y','SHOW VIEW',NULL),
            IF(gdb.Create_routine_priv='Y','CREATE ROUTINE',NULL),
            IF(gdb.Alter_routine_priv='Y','ALTER ROUTINE',NULL),
            IF(gdb.Execute_priv='Y','EXECUTE',NULL),
            IF(gdb.Event_priv='Y','EVENT',NULL),
            IF(gdb.Trigger_priv='Y','TRIGGER',NULL)
        ),
        " ON `",gdb.Db,"`.* TO '",gdb.User,"'@'",gdb.Host,"';"
    ) AS 'GRANT Statement (Reconstructed)'
FROM mysql.db gdb
WHERE gdb.Db != ''
/* SELECT * FROM mysql.db */

UNION

/* User-Specific Grants */
SELECT
    "ALL" AS 'Database(s) Affected',
    "ALL" AS 'Table(s) Affected',
    gus.User AS 'User-Account(s) Affected',
    IF(gus.Host='%','ALL',gus.Host) AS 'Remote-IP(s) Affected',
    CONCAT(
        "GRANT ",
        IF((gus.Select_priv='N')&(gus.Insert_priv='N')&(gus.Update_priv='N')&(gus.Delete_priv='N')&(gus.Create_priv='N')&(gus.Drop_priv='N')&(gus.Reload_priv='N')&(gus.Shutdown_priv='N')&(gus.Process_priv='N')&(gus.File_priv='N')&(gus.References_priv='N')&(gus.Index_priv='N')&(gus.Alter_priv='N')&(gus.Show_db_priv='N')&(gus.Super_priv='N')&(gus.Create_tmp_table_priv='N')&(gus.Lock_tables_priv='N')&(gus.Execute_priv='N')&(gus.Repl_slave_priv='N')&(gus.Repl_client_priv='N')&(gus.Create_view_priv='N')&(gus.Show_view_priv='N')&(gus.Create_routine_priv='N')&(gus.Alter_routine_priv='N')&(gus.Create_user_priv='N')&(gus.Event_priv='N')&(gus.Trigger_priv='N')&(gus.Create_tablespace_priv='N')&(gus.Grant_priv='N'),
            "USAGE",
            IF((gus.Select_priv='Y')&(gus.Insert_priv='Y')&(gus.Update_priv='Y')&(gus.Delete_priv='Y')&(gus.Create_priv='Y')&(gus.Drop_priv='Y')&(gus.Reload_priv='Y')&(gus.Shutdown_priv='Y')&(gus.Process_priv='Y')&(gus.File_priv='Y')&(gus.References_priv='Y')&(gus.Index_priv='Y')&(gus.Alter_priv='Y')&(gus.Show_db_priv='Y')&(gus.Super_priv='Y')&(gus.Create_tmp_table_priv='Y')&(gus.Lock_tables_priv='Y')&(gus.Execute_priv='Y')&(gus.Repl_slave_priv='Y')&(gus.Repl_client_priv='Y')&(gus.Create_view_priv='Y')&(gus.Show_view_priv='Y')&(gus.Create_routine_priv='Y')&(gus.Alter_routine_priv='Y')&(gus.Create_user_priv='Y')&(gus.Event_priv='Y')&(gus.Trigger_priv='Y')&(gus.Create_tablespace_priv='Y')&(gus.Grant_priv='Y'),
                "ALL PRIVILEGES",
                CONCAT_WS(',',
                    IF(gus.Select_priv='Y','SELECT',NULL),
                    IF(gus.Insert_priv='Y','INSERT',NULL),
                    IF(gus.Update_priv='Y','UPDATE',NULL),
                    IF(gus.Delete_priv='Y','DELETE',NULL),
                    IF(gus.Create_priv='Y','CREATE',NULL),
                    IF(gus.Drop_priv='Y','DROP',NULL),
                    IF(gus.Reload_priv='Y','RELOAD',NULL),
                    IF(gus.Shutdown_priv='Y','SHUTDOWN',NULL),
                    IF(gus.Process_priv='Y','PROCESS',NULL),
                    IF(gus.File_priv='Y','FILE',NULL),
                    IF(gus.References_priv='Y','REFERENCES',NULL),
                    IF(gus.Index_priv='Y','INDEX',NULL),
                    IF(gus.Alter_priv='Y','ALTER',NULL),
                    IF(gus.Show_db_priv='Y','SHOW DATABASES',NULL),
                    IF(gus.Super_priv='Y','SUPER',NULL),
                    IF(gus.Create_tmp_table_priv='Y','CREATE TEMPORARY TABLES',NULL),
                    IF(gus.Lock_tables_priv='Y','LOCK TABLES',NULL),
                    IF(gus.Execute_priv='Y','EXECUTE',NULL),
                    IF(gus.Repl_slave_priv='Y','REPLICATION SLAVE',NULL),
                    IF(gus.Repl_client_priv='Y','REPLICATION CLIENT',NULL),
                    IF(gus.Create_view_priv='Y','CREATE VIEW',NULL),
                    IF(gus.Show_view_priv='Y','SHOW VIEW',NULL),
                    IF(gus.Create_routine_priv='Y','CREATE ROUTINE',NULL),
                    IF(gus.Alter_routine_priv='Y','ALTER ROUTINE',NULL),
                    IF(gus.Create_user_priv='Y','CREATE USER',NULL),
                    IF(gus.Event_priv='Y','EVENT',NULL),
                    IF(gus.Trigger_priv='Y','TRIGGER',NULL),
                    IF(gus.Create_tablespace_priv='Y','CREATE TABLESPACE',NULL)
                )
            )
        ),
        " ON *.* TO '",gus.User,"'@'",gus.Host,"' REQUIRE ",
        CASE gus.ssl_type
            WHEN 'ANY' THEN
                "SSL "
            WHEN 'X509' THEN
                "X509 "
            WHEN 'SPECIFIED' THEN
                CONCAT_WS("AND ",
                    IF((LENGTH(gus.ssl_cipher)>0),CONCAT("CIPHER '",CONVERT(gus.ssl_cipher USING utf8),"' "),NULL),
                    IF((LENGTH(gus.x509_issuer)>0),CONCAT("ISSUER '",CONVERT(gus.ssl_cipher USING utf8),"' "),NULL),
                    IF((LENGTH(gus.x509_subject)>0),CONCAT("SUBJECT '",CONVERT(gus.ssl_cipher USING utf8),"' "),NULL)
                )
            ELSE "NONE "
        END,
        "WITH ",
        IF(gus.Grant_priv='Y',"GRANT OPTION ",""),
        "MAX_QUERIES_PER_HOUR ",gus.max_questions," ",
        "MAX_CONNECTIONS_PER_HOUR ",gus.max_connections," ",
        "MAX_UPDATES_PER_HOUR ",gus.max_updates," ",
        "MAX_USER_CONNECTIONS ",gus.max_user_connections,
        ";"
    ) AS 'GRANT Statement (Reconstructed)'
FROM mysql.user gus
WHERE gus.Password != ''
/* SELECT * FROM mysql.user gus */

/* TODO: */
/* SELECT * FROM mysql.host ghs */
/* SELECT * FROM mysql.procs_priv gpr */


很高兴回答/验证任何问题或疑虑

评论


我知道这不是犹太洁食,但是...您的脚本很棒!现在,我要做的就是使其自动化。我会热身

–hanzo2001
18-09-26在16:34

#7 楼

这将为您提供更好的视图...

mysql> select Host, Db, User, Insert_priv, Update_priv, Delete_priv, Create_tmp_table_priv, Alter_priv from mysql.db limit 1;
+------+------+------+-------------+-------------+-------------+-----------------------+------------+
| Host | Db   | User | Insert_priv | Update_priv | Delete_priv | Create_tmp_table_priv | Alter_priv |
+------+------+------+-------------+-------------+-------------+-----------------------+------------+
| %    | test |      | Y           | Y           | Y           | Y                     | Y          |
+------+------+------+-------------+-------------+-------------+-----------------------+------------+
1 row in set (0.00 sec)


评论


到目前为止,这是最好的答案。谢谢!

–Player1
6月12日14:08

#8 楼

如该答案中所述,您可以运行以下命令集以列出所有用户的特定于数据库,特定于表,特定于列和特定于例程的特权。请注意,您需要从外壳程序而不是MySQL命令提示符处运行它。

mysql -u root --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql -u root --skip-column-names -A


这种方法的优点是您不需要安装其他软件。 。

#9 楼

命令SHOW GRANTS [FOR user]可能会显示您想要的任何用户。有关更多详细信息,请参见此处。

#10 楼

如果您经常管理数据库,则可能需要保持严格的特权。您可以使用存储过程来快速运行检查。此示例在mariadb中工作,可能需要进行调整才能使用标准mysql版本。

使用Mansur Ali的答案,并稍作调整即可重新排序列并添加一些排序以更好地组织输出。 br />
使用root用户登录:

USE mysql;
DELIMITER //

CREATE PROCEDURE ShowPrivs(start, end)
BEGIN
    SELECT Db, User, Host, Insert_priv, Update_priv, Delete_priv, Create_tmp_table_priv, Alter_priv FROM mysql.db order by Db, Host, User ASC;
END;
//

DELIMITER ;


您可以更改检查mysql.user表的过程。

用法,使用root登录名:

USE mysql;
CALL ShowPrivs();


我在Ubuntu上使用mysql workbench来运行此答案的创建过程部分。

除了此处的主题之外,您还可以使用一个过程来显示未知的主机或用户。未知主机的示例:

USE mysql;

DELIMITER //
CREATE PROCEDURE `ShowUnknownHosts`(IN Hosts_String VARCHAR(200))
BEGIN
    SELECT user,host FROM user
    WHERE FIND_IN_SET(host, Hosts_String) = 0;
END//

DELIMITER ;


使用说明:提供一串由逗号分隔的主机,因此仅使用一组'':

CALL ShowUnknownHosts('knownhost1,knownhost2');


还可以通过在过程中包括另一个参数来使列变量可变,并使用ShowUnknownHosts(user,'user1,user2')进行调用例如。