mysql: Zeige GRANTs für alle Benutzer


87

MySQL SHOW GRANTSzeigt die Berechtigungen des aktuellen Benutzers.

Gibt es eine Möglichkeit, sich als root anzumelden und die Berechtigungen aller Benutzer anzuzeigen?

Antworten:


45

Nichts eingebaut. Sie haben jedoch zwei Möglichkeiten:

  • Verwenden Sie common_schemadie sql_show_grants- Ansicht von. Beispielsweise können Sie Folgendes abfragen:

    SELECT sql_grants FROM common_schema.sql_show_grants;

    Oder Sie können nach bestimmten Benutzern abfragen, zum Beispiel:

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

    common_schemaBefolgen Sie zur Installation die Anweisungen hier .

    Haftungsausschluss: Ich bin Autor dieses Tools.

  • Verwenden Sie das Percona Toolkit pt-show-grants, zum Beispiel:

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

In beiden Fällen können Sie den GRANTBefehl oder den REVOKE(entgegengesetzten) Befehl anfordern.

Für den ersten Fall müssen Sie ein Schema installieren, für den zweiten Fall müssen Sie PERL-Skripte und Abhängigkeiten installieren.


11
Könnten Sie bitte genauer beschreiben, wie Sie die sql_show_grants-Ansicht von common_schema verwenden? Ich erhalte eine FehlermeldungERROR 1146 (42S02): Table 'common_schema.sql_show_grants' doesn't exist
Martin Vegter

2
@MartinVegter, hast du common_schema installiert? Laden Sie es hier herunter und installieren Sie es gemäß diesen Anweisungen .
Shlomi Noach

1
@ShlomiNoach, Wenn du sagst, dass "nichts eingebaut ist" ... Gibt es irgendwelche Fehler mit information_schema.user_privileges?
Pacerier

2
Entschuldigung, aber es gibt kein "common_schema". Es existiert nicht.
Brendan Byrd

2
link sql_show_grants broken
Cyzanfar

81
select * from information_schema.user_privileges;

BEARBEITEN:

Wie von Shlomi Noach erwähnt:

Es werden keine datenbankspezifischen, tabellenspezifischen, spaltenspezifischen und routinenspezifischen Berechtigungen aufgelistet. Daher wird der Grant GRANT SELECT ON mydb. * TO myuser @ localhost nicht in information_schema.user_privileges angezeigt. Die oben dargestellte common_schema-Lösung aggregiert die Daten aus user_privileges und anderen Tabellen, um ein vollständiges Bild zu erhalten.


5
Entschuldigung, es sollte nicht die akzeptierte Antwort sein. information_schema.user_privilegeslistet nur Privilegien auf Benutzerebene, wie zum Beispiel SUPER, RELOADetc. Es listet auch Allround-DML gewährt gerne SELECT. Es spielt keine Liste Datenbank spezifische, Tisch sepcific, Spalte spezifische Routine spezifische Privilegien. Es gibt daher die Gewährung GRANT SELECT ON mydb.* TO myuser@localhostnicht nicht zeigen , auf information_schema.user_privileges. Die common_schemaoben dargestellte Lösung aggregiert Daten aus user_privilegesund anderen Tabellen, um ein vollständiges Bild zu erhalten.
Shlomi Noach

11

Dieses Linux-Shell-Fragment durchläuft alle MySQL-Benutzer und führt jeweils eine SHOW GRANTS aus:

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

Funktioniert am besten, wenn Sie sich ohne Passwort mit MySQL verbinden können.

Die Ausgabe ist so formatiert, dass sie in einer MySQL-Shell ausgeführt werden kann. Achtung: Die Ausgabe enthält auch die MySQL-Root-Benutzerrechte und das Passwort! Entfernen Sie diese Zeilen, wenn Sie nicht möchten, dass der MySQL-Root-Benutzer geändert wird.


6
Möglicherweise möchten Sie einige Details dazu hinzufügen, was dies bewirkt oder wie die Frage beantwortet wird. Nur eine Reihe von Code anzuzeigen, hilft niemandem zu verstehen, warum Ihre Lösung funktioniert.
Max Vernon

Wo kann ich ein Passwort vergeben?
Mian Asbat Ahmad

Um ein Kennwort eingeben , kann man eine verwenden Option Datei oder die --password Flagge des mysql - Befehl.
mleu

Wäre es nicht möglich, ein einziges Root-Passwort anzugeben und die Abfrage auszuführen, um allen Benutzern Berechtigungen zu erteilen?
Mian Asbat Ahmad

2
Sie können die Anforderungen streamen, um nur eine Verbindung herzustellen, und eine Anmeldeinformationsdatei im Modus 400 als Root verwenden. Meine Version:mysql --defaults-file=/auth/root-mysql.cnf --batch --skip-column-names --execute "SELECT User, Host from mysql.user" | while read user host; do echo "SHOW GRANTS FOR '${user}'@'${host}';"; done | mysql --defaults-file=/auth/root-mysql.cnf --batch | sed 's/^Grants for/-- Grants for/'
BaseZen

9

select * from mysql.user;

Kann Ihnen Benutzerlisten und Berechtigungen geben, die jedem von ihnen zugewiesen sind. Erfordert jedoch Zugriff auf die mysql.userTabelle und der rootBenutzer hat diese.


4
Dies gibt Ihnen nur die "oberste Ebene" (Serverebene) Berechtigungen. Berechtigungen, die für bestimmte Schemas festgelegt wurden, befinden sich in mysql.db. Berechtigungen für bestimmte Tabellen sind in mysql.tables_privund so weiter. Es ist also nicht so einfach.
Shlomi Noach

Werfen Sie für Spielereien mit Regenbogentabellen Ihre Passwort-Hashes von select * from mysql.userin crackstation.net und sehen Sie sich die unverarbeitete Ausgabe an.
Pacerier

8

Einen Liner (Wechsel -urootzu -u$USER_NAMEfür die Verwendung mit anderen Benutzern) in einer Unix bash (wegen der Backticks):

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

oder ohne Backticks und mit Passwort inline (Leerzeichen vor dem Befehl schließt es aus dem Bash-Verlauf in Ubuntu aus):

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

In 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

4

Wenn Sie die folgenden SELECT - Anweisungen ausführen , ohne Fehler:

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

Dann können Sie den folgenden Code (unten) verwenden, der in SQL-Syntax geschrieben ist.

Ich habe diese Abfrage entworfen, um GRANT-Anweisungen für alle vorhandenen Berechtigungen neu zu erstellen (für häufige Wartung während der Datenbankmigration). Es gibt einige Probleme, die behandelt werden müssen, z. B. das Verknüpfen von Benutzern und Kennwörtern. Da wir Kennwörter jedoch häufig aktualisieren, lag dies nicht im Rahmen dieses Projekts.

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

Gerne beantworten / überprüfen wir Ihre Fragen oder Bedenken


Ich weiß, das ist nicht koscher, aber ... dein Drehbuch ist unglaublich! Jetzt muss ich es nur noch automatisieren. Ich
wärme

2

Dies gibt Ihnen eine bessere Sicht ...

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)

1

Der Befehl SHOW GRANTS [FOR user]kann einen beliebigen Benutzer anzeigen. Siehe hier für mehr Details.


0

Wie in dieser Antwort erwähnt , können Sie die folgenden Befehle ausführen, um die datenbankspezifischen, tabellenspezifischen, spaltenspezifischen und routinenspezifischen Berechtigungen aller Benutzer aufzulisten. Beachten Sie, dass Sie dies über die Shell ausführen müssen, nicht über die MySQL-Eingabeaufforderung.

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

Der Vorteil dieses Ansatzes ist, dass Sie keine zusätzliche Software installieren müssen.


0

Wenn Sie Datenbanken häufig verwalten, möchten Sie wahrscheinlich strenge Berechtigungen behalten. Sie können eine gespeicherte Prozedur verwenden, um schnell eine Überprüfung durchzuführen. Dieses Beispiel funktioniert in Mariadb. Möglicherweise ist eine Optimierung erforderlich, um mit der Standard-MySQL-Version zu arbeiten.

Verwenden Sie die Antwort von Mansur Ali mit einem kleinen Tweak, um die Spalten neu zu ordnen, und fügen Sie einige Ordnungen hinzu, um die Ausgabe besser zu organisieren.

Verwenden eines Root-Logins:

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 ;

Sie können die Prozedur ändern, um stattdessen die Tabelle mysql.user zu überprüfen.

Verwendung mit einem Root-Login:

USE mysql;
CALL ShowPrivs();

Ich habe die MySQL-Workbench unter Ubuntu verwendet, um den Erstellungsprozedur-Teil dieser Antwort auszuführen.

Nebenbei bemerkt und ein wenig abseits des Themas, könnten Sie aber auch eine Prozedur haben, um unbekannte Hosts oder Benutzer anzuzeigen. Ein Beispiel für unbekannte Hosts:

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 ;

Hinweis zur Verwendung: Geben Sie eine Reihe von Hosts an, die durch Kommas getrennt sind, sodass nur ein Satz von '' verwendet wird:

CALL ShowUnknownHosts('knownhost1,knownhost2');

Sie können die Spaltenvariable auch ändern, indem Sie einen weiteren Parameter in die Prozedur aufnehmen und ihn mit ShowUnknownHosts (user, 'user1, user2') aufrufen. zum Beispiel.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.