mysql: Показать GRANT для всех пользователей

87

MySQL SHOW GRANTSпоказывает права текущего пользователя.

Есть ли способ войти в систему как root и показать разрешения всех пользователей?

Адам Матан
источник

Ответы:

45

Ничего встроенного. У вас есть два варианта:

  • Используйте 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's pt-show-grants, например:

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

В обоих случаях вы можете запросить GRANTкоманду или REVOKE(противоположную) команду.

В первом случае требуется установка схемы, во втором - сценарии PERL + зависимости.

Шломи Ноах
источник
11
Не могли бы вы более подробно описать, как использовать представление sql_show_grants для common_schema? Я получаю сообщение об ошибкеERROR 1146 (42S02): Table 'common_schema.sql_show_grants' doesn't exist
Мартин Вегтер,
2
@MartinVegter, вы установили common_schema? Загрузите здесь и установите, следуя этим инструкциям .
Шломи Ноах
1
@ShlomiNoach, когда вы говорите, что "ничего не встроено" ... Есть ошибки с information_schema.user_privileges?
Пейсер
2
Извините, но нет такой вещи, как "common_schema". Не существует
Брендан Берд
2
ссылка sql_show_grants нарушена
Cyzanfar
81
select * from information_schema.user_privileges;

РЕДАКТИРОВАТЬ:

Как упомянул Шломи Ноах:

В нем не перечислены привилегии, относящиеся к базе данных, таблице, столбцу, рутине. Поэтому грант GRANT SELECT ON mydb. * TO myuser @ localhost не отображается в information_schema.user_privileges. Представленное выше решение common_schema объединяет данные из user_privileges и других таблиц, чтобы получить полную картину.

rumburak
источник
5
Извините, это не должен быть принятый ответ. information_schema.user_privilegesтолько перечисляет привилегии уровня пользователя, такие как SUPER, RELOADи т. д. Он также перечисляет всесторонние гранты DML как SELECT. В нем не перечислены привилегии, относящиеся к базе данных, таблицам, столбцам и рутинам. Там Фор грант GRANT SELECT ON mydb.* TO myuser@localhostвовсе не показывает на information_schema.user_privileges. common_schemaРешение , представленное выше заполнители данных user_privilegesи других таблиц , чтобы дать вам полную картину.
Шломи Ноах
11

Этот фрагмент оболочки Linux зацикливается на всех пользователях MySQL и делает ПОКАЗЫВАЕТ для каждого:

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

Лучше всего работает, если вы можете подключиться к MySQL без пароля.

Вывод отформатирован, поэтому его можно запускать в оболочке MySQL. Внимание! Выходные данные также содержат права пользователя root и пароль для пользователя root! Удалите эти строки, если вы не хотите, чтобы пользователь MySQL был изменен.

mleu
источник
6
Вы можете добавить некоторые подробности о том, что это делает или как он отвечает на вопрос. Простое отображение кода не поможет никому понять, почему ваше решение работает.
Макс Вернон,
Где я могу дать пароль?
Миан Асбат Ахмад
Для того, чтобы ввести пароль можно использовать Option File или --password флаг команды MySQL.
Мле
Разве нельзя было бы дать один пароль root и выполнить запрос, чтобы получить все права пользователей?
Миан Асбат Ахмад
2
Можно выполнить потоковую передачу запросов, чтобы установить только одно соединение, и использовать файл учетных данных, принадлежащий корневому режиму режима 400. Моя версия: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;

Может дать вам список пользователей и привилегии, назначенные для каждого из них, требует доступа к mysql.userтаблице, хотя и у rootпользователя есть.

Махеш Патил
источник
4
Это дает вам только привилегии «верхнего уровня» (уровня сервера). Привилегии, установленные для определенных схем, находятся в mysql.db. Привилегии на конкретные таблицы есть mysql.tables_privи тд. Так что не все так просто.
Шломи Ноах
Для махинаций с радужными таблицами, бросьте хеши паролей select * from mysql.userв crackstation.net и посмотрите не зашифрованный вывод.
Pacerier
8

Один вкладыш (изменение -urootк -u$USER_NAMEдля использования с другими пользователями) в Баш Unix (из - за кавычку):

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

или без обратных галочек и со встроенным паролем (пробел перед командой исключает его из истории Bash в Ubuntu):

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

В 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
источник
4

Если вы можете запустить следующие операторы 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 */

Рады ответить / проверить любые вопросы или проблемы

Кавалло
источник
Я знаю, что это не кошерно, но ... ваш сценарий потрясающий! Теперь все, что мне нужно сделать, это автоматизировать это. Я
согрею
2

Это даст вам лучший вид ...

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

Команда SHOW GRANTS [FOR user]может показать любого пользователя, которого вы хотите. Смотрите здесь для более подробной информации.

Евгений Коньков
источник
0

Как упоминалось в этом ответе , вы можете запустить следующий набор команд, чтобы получить список привилегий для всех пользователей, связанных с базой данных, таблицами, столбцами и процедурами. Обратите внимание, что вам нужно запустить это из оболочки, а не из командной строки 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

Преимущество этого подхода в том, что вам не нужно устанавливать дополнительное программное обеспечение.

billyw
источник
0

Если вы часто администрируете базы данных, вы, вероятно, захотите сохранить жесткие привилегии. Вы можете использовать хранимую процедуру, чтобы быстро запустить проверку. Этот пример работает в mariadb, возможно, потребуется настроить для работы со стандартной версией mysql.

Воспользовавшись ответом Мансура Али, немного изменив порядок столбцов и добавив их в некоторый порядок, чтобы лучше организовать вывод.

Используя 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();

Я использовал mysql workbench в Ubuntu, чтобы выполнить процедуру создания части этого ответа.

Помимо этого и немного не по теме, но у вас также может быть процедура для показа неизвестных хостов или пользователей. Пример для неизвестных хостов:

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'); например.

Крис
источник