mysql: Показати ГРАНТИ для всіх користувачів


87

MySQL SHOW GRANTSпоказує дозволи поточного користувача.

Чи є спосіб увійти як root та показати дозволи всіх користувачів?

Відповіді:


45

Нічого вбудованого. Однак у вас є два варіанти:

  • Використовуйте common_schema«s 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 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
Martin Vegter

2
@MartinVegter, ти встановив common_schema? Завантажте тут і встановіть, дотримуючись цих інструкцій .
Шломі Ноач

1
@ShlomiNoach, Коли ви говорите, що "нічого вбудованого" ... Чи є помилки з information_schema.user_privileges?
Печер'є

2
Вибачте, але немає такої речі, як "загальна_схема". Його не існує.
Брендан Берд

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 та інших таблиць, щоб отримати повне уявлення.


5
Вибачте, це не повинна бути прийнятою відповіддю. information_schema.user_privilegesперелічує лише привілеї на рівні користувача, наприклад SUPER, RELOADтощо. Він також перераховує всебічні гранти DML на зразок SELECT. У ньому не перелічено специфічні для бази даних, спеціальні для таблиць, для стовпців привілеї. Там Фор грант GRANT SELECT ON mydb.* TO myuser@localhostзовсім НЕ показує на information_schema.user_privileges. common_schemaРішення , представлене вище наповнювачі даних user_privilegesі інших таблиць , щоб дати вам повну картину.
Shlomi Noach

11

Цей фрагмент оболонки Linux циклічно працює за всіма користувачами MySQL та робить показ SHARTS для кожного:

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. Застереження: Вихід також містить дозволи та кореневий користувач MySQL! Видаліть ці рядки, якщо ви не хочете, щоб користувач root MySQL мінявся.


6
Ви можете додати детальну інформацію про те, що це робить, або як це відповідає на питання. Показ простого коду нікому не допомагає зрозуміти, чому працює ваше рішення.
Макс Вернон

Де я можу дати пароль?
Міан Асбат Ахмад

Для введення пароля можна скористатися Option File або прапором --password команди mysql.
mleu

Чи не вдалося б дати один корінний пароль та запустити запит, щоб отримати всі користувачі грантів?
Міан Асбат Ахмад

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 і побачити unhashed виходу.
Печер'є

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

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

Перевага такого підходу полягає в тому, що вам не потрібно встановлювати додаткове програмне забезпечення.


0

Якщо ви часто управляєте базами даних, ви, ймовірно, захочете зберігати чіткі привілеї. Ви можете використовувати збережену процедуру для швидкого запуску чека. Цей приклад працює в mariadb, можливо, знадобиться налаштування для роботи зі стандартною версією mysql.

Використання відповіді Мансура Алі з невеликим налаштуванням упорядкування стовпців та додавання в порядку замовлення для кращого упорядкування результатів.

Використання кореневого логіна:

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.

Використання, використовуючи кореневий логін:

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'); наприклад.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.