MySQL SHOW GRANTS
pokazuje uprawnienia bieżącego użytkownika.
Czy istnieje sposób na zalogowanie się jako root i pokazanie uprawnień wszystkich użytkowników?
MySQL SHOW GRANTS
pokazuje uprawnienia bieżącego użytkownika.
Czy istnieje sposób na zalogowanie się jako root i pokazanie uprawnień wszystkich użytkowników?
Odpowiedzi:
Nic wbudowanego. Masz jednak dwie opcje:
Stosowanie common_schema
„s sql_show_grants widok. Na przykład możesz zapytać:
SELECT sql_grants FROM common_schema.sql_show_grants;
Lub możesz zapytać o konkretnych użytkowników, na przykład:
SELECT sql_grants FROM common_schema.sql_show_grants WHERE user='app';
Aby zainstalować common_schema
, postępuj zgodnie z instrukcjami tutaj .
Oświadczenie: Jestem autorem tego narzędzia.
Użyj Percona Toolkit pt-show-grants
, na przykład:
pt-show-grants --host localhost --user root --ask-pass
W obu przypadkach możesz poprosić o GRANT
polecenie lub REVOKE
(przeciwnie) polecenie.
Pierwszy przypadek wymaga zainstalowania schematu, drugi wymaga zainstalowania skryptów PERL + zależności.
information_schema.user_privileges
?
select * from information_schema.user_privileges;
EDYTOWAĆ:
Jak wspomniała Shlomi Noach:
Nie ma w nim wykazu uprawnień dotyczących bazy danych, tabeli, kolumny, procedury. Dlatego przydział GRANT SELECT ON mydb. * TO myuser @ localhost nie jest wyświetlany w pliku information_schema.user_privileges. Przedstawione powyżej rozwiązanie common_schema agreguje dane z user_privileges i innych tabel w celu uzyskania pełnego obrazu.
information_schema.user_privileges
tylko wymienia przywileje na poziomie użytkownika, takie jak SUPER
, RELOAD
itd. Zawiera też wszechstronną dotacje DML podoba SELECT
. Robi nie listy, table-sepcific, kolumn specyficzne rutynowe specyficzne przywileje specyficzne dla bazy danych. Dlatego granty GRANT SELECT ON mydb.* TO myuser@localhost
nie są wyświetlane information_schema.user_privileges
. common_schema
Rozwiązanie przedstawione powyżej dane kruszyw z user_privileges
i innych tabel w celu uzyskania pełnego obrazu.
Ten fragment powłoki Linuksa zapętla się nad wszystkimi użytkownikami MySQL i wykonuje POKAŻ GRANTY dla każdego:
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
Działa najlepiej, jeśli możesz połączyć się z MySQL bez hasła.
Dane wyjściowe są sformatowane, aby można je było uruchomić w powłoce MySQL. Uwaga: Dane wyjściowe zawierają również uprawnienia użytkownika root MySQL i hasło! Usuń te linie, jeśli nie chcesz, aby użytkownik root MySQL został zmieniony.
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/'
select * from mysql.user;
Może dać Ci listę użytkowników i uprawnienia przypisane do każdego z nich, wymaga jednak dostępu do mysql.user
tabeli i root
użytkownik ją ma.
mysql.db
. Uprawnienia do określonych tabel są mysql.tables_priv
włączone i tak dalej. To nie jest takie proste.
select * from mysql.user
do crackstation.net i zobacz niezakończone dane wyjściowe.
Jedna linijka (zmiana -uroot
na -u$USER_NAME
do użytku z innym użytkownikiem) w uniksowym bashu (z powodu backticks):
mysql -uroot -p -sNe"`mysql -uroot -p -se"SELECT CONCAT('SHOW GRANTS FOR \'',user,'\'@\'',host,'\';') FROM mysql.user;"`"
lub bez znaków wstecznych iz wbudowanym hasłem (spacja przed poleceniem wyklucza go z historii Bash w Ubuntu):
mysql -uroot -p"$PASSWORD" -sNe"$(mysql -uroot -p"$PASSWORD" -se"SELECT CONCAT('SHOW GRANTS FOR \'',user,'\'@\'',host,'\';') FROM mysql.user;")"
W systemie 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
Jeśli możesz uruchomić następujące instrukcje SELECT bez błędu:
/* 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;
wtedy możesz użyć następującego kodu (poniżej), napisanego w składni .sql.
Zaprojektowałem to zapytanie, próbując odbudować instrukcje GRANT dla wszystkich istniejących uprawnień (do częstej konserwacji podczas migracji bazy danych). Należy poradzić sobie z kilkoma problemami, takimi jak łączenie hasła użytkownika, ale ponieważ często aktualizujemy hasła, nie było to przedmiotem tego projektu.
/* 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 */
Z przyjemnością odpowiem / zweryfikuję wszelkie pytania lub wątpliwości
To da ci lepszy widok ...
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)
Polecenie SHOW GRANTS [FOR user]
może pokazywać dowolnego użytkownika. Zobacz tutaj po więcej szczegółów.
Jak wspomniano w tej odpowiedzi , można uruchomić następujący zestaw poleceń, aby wyświetlić uprawnienia wszystkich użytkowników dotyczące bazy danych, tabeli, kolumny i procedury. Pamiętaj, że musisz uruchomić to z powłoki, a nie z wiersza poleceń 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
Zaletą tego podejścia jest to, że nie trzeba instalować dodatkowego oprogramowania.
Jeśli często administrujesz bazami danych, prawdopodobnie będziesz chciał zachować wąskie uprawnienia. Możesz użyć procedury składowanej, aby szybko uruchomić sprawdzanie. Ten przykład działa w mariadbie. Może być konieczne dostosowanie do pracy ze standardową wersją mysql.
Korzystając z odpowiedzi Mansur Ali, z drobnymi poprawkami zmieniającymi kolejność kolumn i dodając kolejność, aby lepiej uporządkować dane wyjściowe.
Korzystanie z logowania roota:
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 ;
Zamiast tego możesz zmienić procedurę sprawdzania tabeli mysql.user.
Użycie przy użyciu loginu root:
USE mysql;
CALL ShowPrivs();
Użyłem mysql workbench na Ubuntu, aby uruchomić procedurę tworzenia części tej odpowiedzi.
Na marginesie i trochę poza tym tematem, ale możesz również mieć procedurę pokazującą nieznanych hostów lub użytkowników. Przykład dla nieznanych hostów:
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 ;
Uwaga dotycząca użycia: Podaj ciąg hostów oddzielonych przecinkami, aby użyć tylko jednego zestawu „”:
CALL ShowUnknownHosts('knownhost1,knownhost2');
Można również zmienić kolumnę, włączając inny parametr do procedury i wywołując ją za pomocą ShowUnknownHosts (użytkownik, „użytkownik1, użytkownik2”); na przykład.
ERROR 1146 (42S02): Table 'common_schema.sql_show_grants' doesn't exist