web-dev-qa-db-fra.com

mysql: Afficher les GRANTs pour tous les utilisateurs

MySQL's SHOW GRANTS affiche les autorisations de l'utilisateur actuel.

Existe-t-il un moyen de se connecter en tant que root et d'afficher les autorisations de tous les utilisateurs?

97
Adam Matan

Rien de intégré. Vous avez cependant deux options:

  • Utilisation common_schema's sql_show_grants vue. Par exemple, vous pouvez interroger:

    SELECT sql_grants FROM common_schema.sql_show_grants;
    

    Ou vous pouvez interroger des utilisateurs particuliers, par exemple:

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

    À installer common_schema, suivez les instructions ici .

    Avertissement: je suis l'auteur de cet outil.

  • Utilisez la boîte à outils Percona pt-show-grants , par exemple:

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

Dans les deux cas, vous pouvez demander la commande GRANT ou la commande REVOKE (opposée).

Le premier cas nécessite que vous installiez un schéma, le second nécessite que vous installiez les scripts Perl + les dépendances.

47
Shlomi Noach
select * from information_schema.user_privileges;

ÉDITER:

Comme mentionné par Shlomi Noach:

Il ne répertorie pas les privilèges spécifiques à la base de données, spécifiques à la table, spécifiques aux colonnes et spécifiques à la routine. Par conséquent, la subvention GRANT SELECT ON mydb. * TO myuser @ localhost ne s'affiche pas dans information_schema.user_privileges. La solution common_schema présentée ci-dessus regroupe les données des privilèges utilisateur et d'autres tables pour vous donner une image complète.

91
rumburak

Ce fragment du shell Linux boucle sur tous les utilisateurs MySQL et fait un SHOW GRANTS pour chacun:

mysql --silent --skip-column-names --execute "select concat('\'',User,'\'@\'',Host,'\'') as User from mysql.user" | sort | \
while read u
 do echo "-- $u"; mysql --silent --skip-column-names --execute "show grants for $u" | sed 's/$/;/'
done

Fonctionne mieux si vous pouvez vous connecter à MySQL sans mot de passe.

La sortie est formatée pour pouvoir être exécutée dans un shell MySQL. Attention: la sortie contient également les autorisations et le mot de passe de l'utilisateur root MySQL! Supprimez ces lignes si vous ne voulez pas que l'utilisateur root MySQL soit changé.

13
mleu

Un liner (changer -uroot à -u$USER_NAME pour une utilisation avec un autre utilisateur) dans un bash Unix (à cause des backticks):

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

ou sans backticks et avec mot de passe en ligne (l'espace devant la commande l'exclut de l'historique Bash dans Ubuntu):

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

Sous Windows:

mysql -uroot -p -se"SELECT CONCAT('SHOW GRANTS FOR \'',user,'\'@\'',Host,'\';') FROM mysql.user;" > grants.sql
mysql -uroot -p < grants.sql
del grants.sql
10
inemanja

select * from mysql.user;

Peut vous donner la liste d'utilisateurs et les privilèges attribués à chacun d'eux, nécessite un accès à mysql.user table cependant et root utilisateur l'a.

9
Mahesh Patil

Si vous pouvez exécuter les instructions SELECT suivantes sans pour autant Erreur:

/* 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;

n'hésitez pas à utiliser le code suivant (ci-dessous), écrit en syntaxe .sql.

J'ai conçu cette requête dans le but de recréer des instructions GRANT pour toutes les autorisations existantes (pour un entretien fréquent pendant la migration de la base de données). Il y a quelques problèmes à résoudre, comme la liaison utilisateur-mot de passe, mais parce que nous mettons fréquemment à jour les mots de passe, ce n'était pas dans la portée de ce projet.

/* 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 */

Heureux de répondre/vérifier toutes les questions ou préoccupations

4
Cavallo

Cela vous donnera une meilleure vue ...

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)
2
Mansur Ali

La commande SHOW GRANTS [FOR user] peut afficher tout utilisateur de votre choix. Voir ici pour plus de détails.

1
Eugen Konkov

Comme mentionné dans cette réponse , vous pouvez exécuter l'ensemble de commandes suivant pour répertorier les privilèges spécifiques à la base de données, à la table, à la colonne et à la routine de tous les utilisateurs. Notez que vous devez l'exécuter à partir du shell, pas de l'invite de commande 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

L'avantage de cette approche est que vous n'avez pas besoin d'installer de logiciel supplémentaire.

1
billyw

Si vous administrez souvent des bases de données, vous souhaiterez probablement conserver des privilèges restreints. Vous pouvez utiliser une procédure stockée pour exécuter rapidement une vérification. Cet exemple fonctionne dans mariadb peut avoir besoin d'un Tweak pour fonctionner avec la version mysql standard.

Utiliser la réponse de Mansur ALi avec un petit Tweak pour réorganiser les colonnes et ajouter un certain ordre pour mieux organiser la sortie.

En utilisant une connexion 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 ;

Vous pouvez modifier la procédure pour vérifier la table mysql.user à la place.

Utilisation, en utilisant une connexion root:

USE mysql;
CALL ShowPrivs();

J'ai utilisé mysql workbench sur Ubuntu pour exécuter la partie procédure de création de cette réponse.

En aparté et un peu hors du sujet ici, mais, vous pouvez également avoir une procédure pour afficher les hôtes ou utilisateurs inconnus. Un exemple pour les hôtes inconnus:

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 ;

Note d'utilisation: Fournissez une chaîne d'hôtes séparés par des virgules afin qu'un seul ensemble de '' soit utilisé:

CALL ShowUnknownHosts('knownhost1,knownhost2');

Vous pouvez également créer la variable de colonne en incluant un autre paramètre dans la procédure et l'appeler avec ShowUnknownHosts (user, 'user1, user2'); par exemple.

0
Chris