mysql: mostra GRANTs per tutti gli utenti


87

MySQL SHOW GRANTSmostra le autorizzazioni dell'utente corrente.

C'è un modo per accedere come root e mostrare le autorizzazioni di tutti gli utenti?

Risposte:


45

Niente di integrato. Hai due opzioni però:

  • Usa common_schemala vista sql_show_grants . Ad esempio, puoi eseguire una query:

    SELECT sql_grants FROM common_schema.sql_show_grants;

    Oppure puoi eseguire una query per utenti particolari, ad esempio:

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

    Per installare common_schema, segui le istruzioni qui .

    Disclaimer: sono autore di questo strumento.

  • Utilizzare Percona Toolkit pt-show-grants, ad esempio:

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

In entrambi i casi puoi chiedere il GRANTcomando o il comando REVOKE(opposto).

Il primo caso richiede l'installazione di uno schema, il secondo richiede l'installazione di script PERL + dipendenze.


11
Potresti descrivere in modo più dettagliato come utilizzare la vista sql_show_grants di common_schema? Ottengo un erroreERROR 1146 (42S02): Table 'common_schema.sql_show_grants' doesn't exist
Martin Vegter,

2
@MartinVegter, hai installato common_schema? Scarica qui e installa seguendo queste istruzioni .
Shlomi Noach,

1
@ShlomiNoach, Quando dici che non c'è "niente incorporato" ... Ci sono errori con information_schema.user_privileges?
Pacerier,

2
Siamo spiacenti, ma non esiste un "common_schema". Non esiste
Brendan Byrd,

2
link sql_show_grants rotto
Cyzanfar,

81
select * from information_schema.user_privileges;

MODIFICARE:

Come menzionato da Shlomi Noach:

Non elenca i privilegi specifici del database, specifici della tabella, specifici della colonna e specifici della routine. Pertanto, la concessione GRANT SELECT ON mydb. * TO myuser @ localhost non viene visualizzata in information_schema.user_privileges. La soluzione common_schema presentata sopra aggrega i dati da privilegi_utente e altre tabelle per darti il ​​quadro completo.


5
Siamo spiacenti, non dovrebbe essere la risposta accettata. information_schema.user_privilegeselenca solo i privilegi a livello di utente, come SUPER, RELOADecc. Elenca anche concessioni DML a tutto tondo come SELECT. Essa non lista, tavolo-sepcific, privilegi, di routine specifiche per specifici colonne specifiche del database. Pertanto, la sovvenzione GRANT SELECT ON mydb.* TO myuser@localhostnon viene visualizzata information_schema.user_privileges. La common_schemasoluzione presentata sopra aggrega i dati da user_privilegese altre tabelle per darti il ​​quadro completo.
Shlomi Noach,

11

Questo frammento di shell Linux scorre su tutti gli utenti MySQL e fa uno SHOW GRANTS per ciascuno:

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

Funziona meglio se riesci a connetterti a MySQL senza una password.

L'output è formattato in modo da poter essere eseguito in una shell MySQL. Attenzione: l'output contiene anche le autorizzazioni e la password dell'utente root di MySQL! Rimuovere quelle righe se non si desidera che l'utente root di MySQL venga modificato.


6
Potresti voler aggiungere alcuni dettagli su ciò che fa o su come risponde alla domanda. La semplice visualizzazione di un sacco di codice non aiuta nessuno a capire perché la tua soluzione funzioni.
Max Vernon,

Dove posso dare la password?
Mian Asbat Ahmad,

Per fornire una password è possibile utilizzare un file di opzioni o il flag --password del comando mysql.
mleu,

Non sarebbe possibile fornire una password di root ed eseguire la query per ottenere tutte le autorizzazioni degli utenti?
Mian Asbat Ahmad,

2
È possibile eseguire lo streaming delle richieste al fine di stabilire una sola connessione e utilizzare un file di credenziali di proprietà della modalità 400. La mia versione: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;

Può darti un elenco di utenti e privilegi assegnati a ciascuno di essi, tuttavia richiede l'accesso alla mysql.usertabella e l' rootutente ce l'ha.


4
Questo ti dà solo i privilegi di "livello superiore" (livello server). Sono presenti i privilegi impostati su schemi specifici mysql.db. Sono presenti i privilegi su tabelle specifiche mysql.tables_prive così via. Quindi non è così semplice.
Shlomi Noach,

Per imbrogli tavolo arcobaleno, gettare le hash delle password da select * from mysql.userin crackstation.net e vedere l'output unhashed.
Pacerier,

8

Uno di linea (cambiare -uroota -u$USER_NAMEper l'uso con un altro utente) in un colpo Unix (a causa dei backticks):

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

o senza backtick e con password inline (lo spazio davanti al comando lo esclude dalla cronologia di Bash in Ubuntu):

 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

Se è possibile eseguire le seguenti istruzioni SELECT senza errori:

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

quindi sentiti libero di usare il seguente codice (sotto), scritto nella sintassi .sql.

Ho progettato questa query nel tentativo di ricostruire le istruzioni GRANT per tutte le autorizzazioni esistenti (per manutenzione frequente durante la migrazione del database). Vi sono alcuni problemi da risolvere, come il collegamento di password utente, ma poiché aggiorniamo frequentemente le password, non rientravano nell'ambito di questo progetto.

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

Felice di rispondere / verificare eventuali domande o dubbi


So che questo non è kosher, ma ... la tua sceneggiatura è fantastica! Ora, tutto quello che devo fare è automatizzarlo. Mi
scalderò

2

Questo ti darà una visione migliore ...

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

Il comando SHOW GRANTS [FOR user]può mostrare qualsiasi utente desiderato. Vedi qui per maggiori dettagli.


0

Come indicato in questa risposta , è possibile eseguire il seguente set di comandi per elencare i privilegi specifici del database, specifici della tabella, specifici della colonna e specifici della routine di tutti gli utenti. Nota che devi eseguirlo dalla shell, non dal prompt dei comandi di 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

Il vantaggio di questo approccio è che non è necessario installare software aggiuntivo.


0

Se stai amministrando spesso database, probabilmente vorrai mantenere stretti privilegi. È possibile utilizzare una procedura memorizzata per eseguire rapidamente un controllo. Questo esempio funziona in mariadb potrebbe aver bisogno di una modifica per funzionare con la versione standard di mysql.

Usando la risposta di Mansur Ali con una piccola modifica riordinando le colonne e aggiungendo un po 'di ordine per organizzare meglio l'output.

Utilizzando un login di 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 ;

È possibile modificare la procedura per controllare invece la tabella mysql.user.

Utilizzo, usando un login root:

USE mysql;
CALL ShowPrivs();

Ho usato mysql workbench su Ubuntu per eseguire la procedura di creazione parte di questa risposta.

A parte questo e un po 'fuori tema qui, ma potresti anche avere una procedura per mostrare host o utenti sconosciuti. Un esempio per host sconosciuti:

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 ;

Nota di utilizzo: fornire una stringa di host separati da virgole in modo da utilizzare solo un set di "":

CALL ShowUnknownHosts('knownhost1,knownhost2');

È inoltre possibile rendere variabile la colonna includendo un altro parametro nella procedura e chiamarlo con ShowUnknownHosts (utente, "utente1, utente2"); per esempio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.