mysql: Mostrar las CONCESIONES para todos los usuarios

87

MySQL SHOW GRANTSmuestra los permisos del usuario actual.

¿Hay alguna manera de iniciar sesión como root y mostrar los permisos de todos los usuarios?

Adam Matan
fuente

Respuestas:

45

Nada incorporado. Sin embargo, tienes dos opciones:

  • Use common_schemala vista sql_show_grants . Por ejemplo, puede consultar:

    SELECT sql_grants FROM common_schema.sql_show_grants;

    O puede consultar usuarios particulares, por ejemplo:

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

    Para instalar common_schema, siga las instrucciones aquí .

    Descargo de responsabilidad: soy autor de esta herramienta.

  • Utilice el kit de herramientas de Percona pt-show-grants, por ejemplo:

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

En ambos casos, puede solicitar el GRANTcomando o el comando REVOKE(opuesto).

El primer caso requiere que instale un esquema, el segundo requiere que instale scripts PERL + dependencias.

Shlomi Noach
fuente
11
¿Podría describir con más detalle cómo usar la vista sql_show_grants de common_schema? Me sale un errorERROR 1146 (42S02): Table 'common_schema.sql_show_grants' doesn't exist
Martin Vegter
2
@ MartinVegter, ¿has instalado common_schema? Descargue aquí e instale siguiendo estas instrucciones .
Shlomi Noach
1
@ShlomiNoach, cuando dices que no hay "nada incorporado" ... ¿Hay algún error con information_schema.user_privileges?
Pacerier
2
Lo sentimos, pero no existe un "esquema_común". No existe
Brendan Byrd
2
enlace sql_show_grants roto
Cyzanfar
81
select * from information_schema.user_privileges;

EDITAR:

Como lo mencionó Shlomi Noach:

No enumera los privilegios específicos de la base de datos, específicos de la tabla, específicos de la columna, específicos de la rutina. Por lo tanto, la concesión GRANT SELECT ON mydb. * TO myuser @ localhost no se muestra en information_schema.user_privileges. La solución common_schema presentada anteriormente agrega los datos de user_privileges y otras tablas para darle una imagen completa.

rumburak
fuente
55
Lo sentimos, no debería ser la respuesta aceptada. information_schema.user_privilegessolo enumera los privilegios a nivel de usuario, como SUPER, RELOADetc. También enumera las concesiones DML completas como SELECT. No , no la lista, tabla, sepcific, privilegios de rutina específicos específicos de la columna-base de datos específica. Por lo tanto, la subvención GRANT SELECT ON mydb.* TO myuser@localhostno se muestra information_schema.user_privileges. La common_schemasolución presentada anteriormente agrega datos de user_privilegesy otras tablas para darle una imagen completa.
Shlomi Noach
11

Este fragmento de shell de Linux recorre todos los usuarios de MySQL y realiza un SHOW GRANTS para cada uno:

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

Funciona mejor si puede conectarse a MySQL sin una contraseña.

La salida está formateada para que pueda ejecutarse en un shell de MySQL. Precaución: ¡La salida también contiene los permisos de usuario raíz y la contraseña de MySQL! Elimine esas líneas si no desea que se cambie el usuario raíz de MySQL.

mleu
fuente
66
Es posible que desee agregar algunos detalles sobre lo que hace o cómo responde la pregunta. Solo mostrar un montón de código no ayuda a nadie a entender por qué funciona su solución.
Max Vernon
¿Dónde puedo dar contraseña?
Mian Asbat Ahmad
Para proporcionar una contraseña, se puede usar un archivo de opciones o el indicador --password del comando mysql.
mleu
¿No sería posible dar una contraseña de root y ejecutar la consulta para obtener todas las subvenciones de los usuarios?
Mian Asbat Ahmad
2
Puede transmitir las solicitudes para hacer una sola conexión y utilizar un archivo de credenciales propiedad del modo 400. Mi versión: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;

Puede darle la lista de usuarios y los privilegios asignados a cada uno de ellos, requiere acceso a la mysql.usertabla y el rootusuario la tiene.

Mahesh Patil
fuente
44
Esto solo le otorga los privilegios de "nivel superior" (nivel de servidor). Los privilegios establecidos en esquemas específicos están en mysql.db. Los privilegios en tablas específicas están en mysql.tables_priv, y así sucesivamente. Entonces no es tan simple.
Shlomi Noach
Para travesuras de mesa arco iris, lanzar sus hashes de contraseñas de select * from mysql.useral crackstation.net y ver la salida sin troceo.
Pacerier
8

Un forro (cambiar -uroota -u$USER_NAMEpara su uso con otro usuario) en una fiesta de Unix (debido a los acentos abiertos):

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

o sin backticks y con contraseña en línea (el espacio delante del comando lo excluye del historial de Bash en Ubuntu):

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

En 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
inemanja
fuente
4

Si puede ejecutar las siguientes instrucciones SELECT sin error:

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

entonces siéntase libre de usar el siguiente código (abajo), escrito en sintaxis .sql.

Diseñé esta consulta en un intento de reconstruir las declaraciones GRANT para todos los permisos existentes (para el mantenimiento frecuente durante la migración de la base de datos). Hay algunos problemas que se deben resolver, como la vinculación de contraseña de usuario, pero debido a que frecuentemente actualizamos las contraseñas, eso no estaba en el alcance de este proyecto.

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

Encantado de responder / verificar cualquier pregunta o inquietud

Cavallo
fuente
Sé que esto no es kosher, pero ... ¡tu guión es increíble! Ahora, todo lo que tengo que hacer es automatizarlo.
Calentaré
2

Esto te dará una mejor vista ...

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)
Mansur Ali
fuente
1

El comando SHOW GRANTS [FOR user]puede mostrar cualquier usuario que desee. Ver aquí para más detalles.

Eugen Konkov
fuente
0

Como se menciona en esta respuesta , puede ejecutar el siguiente conjunto de comandos para enumerar los privilegios específicos de la base de datos, de la tabla, de la columna y de la rutina de todos los usuarios. Tenga en cuenta que debe ejecutar esto desde el shell, no desde el símbolo del sistema 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

La ventaja de este enfoque es que no necesita instalar software adicional.

billyw
fuente
0

Si está administrando bases de datos con frecuencia, es probable que desee mantener privilegios estrictos. Puede usar un procedimiento almacenado para ejecutar rápidamente una verificación. Este ejemplo funciona en mariadb podría necesitar un ajuste para funcionar con la versión estándar de mysql.

Usando la respuesta de Mansur Ali con un pequeño ajuste reordenando las columnas y agregando algunos ordenamientos para organizar mejor la salida.

Usando un inicio de sesión raíz:

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 ;

En su lugar, puede cambiar el procedimiento para verificar la tabla mysql.user.

Uso, utilizando un inicio de sesión raíz:

USE mysql;
CALL ShowPrivs();

Usé mysql workbench en Ubuntu para ejecutar la parte del procedimiento de creación de esta respuesta.

Como un aparte y un poco fuera del tema aquí, pero también podría tener un procedimiento para mostrar hosts o usuarios desconocidos. Un ejemplo para hosts desconocidos:

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 de uso: proporcione una cadena de hosts separados por comas para que solo se use un conjunto de '':

CALL ShowUnknownHosts('knownhost1,knownhost2');

También puede hacer que la columna sea variable al incluir otro parámetro en el procedimiento y llamarlo con ShowUnknownHosts (usuario, 'usuario1, usuario2'); por ejemplo.

Chris
fuente