mysql: Pokaż GRANT dla wszystkich użytkowników

87

MySQL SHOW GRANTSpokazuje uprawnienia bieżącego użytkownika.

Czy istnieje sposób na zalogowanie się jako root i pokazanie uprawnień wszystkich użytkowników?

Adam Matan
źródło

Odpowiedzi:

45

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 GRANTpolecenie lub REVOKE(przeciwnie) polecenie.

Pierwszy przypadek wymaga zainstalowania schematu, drugi wymaga zainstalowania skryptów PERL + zależności.

Shlomi Noach
źródło
11
Czy mógłbyś bardziej szczegółowo opisać, jak korzystać z widoku sql_show_grants common_schema? ERROR 1146 (42S02): Table 'common_schema.sql_show_grants' doesn't exist
Pojawia
2
@MartinVegter, czy zainstalowałeś common_schema? Pobierz tutaj i zainstaluj zgodnie z tymi instrukcjami .
Shlomi Noach,
1
@ShlomiNoach, Kiedy mówisz, że nie ma „nic wbudowanego” ... Czy są jakieś błędy information_schema.user_privileges?
Pacerier
2
Przykro nam, ale nie ma czegoś takiego jak „wspólna_schema”. Nie istnieje.
Brendan Byrd
2
link sql_show_grants uszkodzony
Cyzanfar
81
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.

rumburak
źródło
5
Przepraszamy, to nie powinna być zaakceptowana odpowiedź. information_schema.user_privilegestylko wymienia przywileje na poziomie użytkownika, takie jak SUPER, RELOADitd. 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@localhostnie wyświetlane information_schema.user_privileges. common_schemaRozwiązanie przedstawione powyżej dane kruszyw z user_privilegesi innych tabel w celu uzyskania pełnego obrazu.
Shlomi Noach,
11

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.

mleu
źródło
6
Możesz dodać kilka szczegółów na temat tego, co to robi lub jak odpowiada na pytanie. Samo wyświetlenie zestawu kodu nie pomaga nikomu zrozumieć, dlaczego Twoje rozwiązanie działa.
Max Vernon
Gdzie mogę podać hasło?
Mian Asbat Ahmad
Aby podać hasło, można użyć pliku opcji lub flagi --password polecenia mysql.
mleu
Czy nie byłoby możliwe podanie jednego hasła roota i uruchomienie zapytania, aby uzyskać zgodę wszystkich użytkowników?
Mian Asbat Ahmad
2
Możesz przesyłać strumieniowo żądania w celu nawiązania tylko jednego połączenia i użyć pliku poświadczeń root trybu 400. Moja wersja: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;

Może dać Ci listę użytkowników i uprawnienia przypisane do każdego z nich, wymaga jednak dostępu do mysql.usertabeli i rootużytkownik ją ma.

Mahesh Patil
źródło
4
Daje to tylko uprawnienia „najwyższego poziomu” (na poziomie serwera). Dostępne są uprawnienia określone dla określonych schematów mysql.db. Uprawnienia do określonych tabel są mysql.tables_privwłączone i tak dalej. To nie jest takie proste.
Shlomi Noach
W przypadku shenaniganów z tabeli tęczy, wrzuć skróty swojego hasła select * from mysql.userdo crackstation.net i zobacz niezakończone dane wyjściowe.
Pacerier,
8

Jedna linijka (zmiana -urootna -u$USER_NAMEdo 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
inemanja
źródło
4

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

Cavallo
źródło
Wiem, że to nie jest koszerne, ale ... twój skrypt jest niesamowity! Teraz muszę tylko to zautomatyzować.
Rozgrzeję
2

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)
Mansur Ali
źródło
1

Polecenie SHOW GRANTS [FOR user]może pokazywać dowolnego użytkownika. Zobacz tutaj po więcej szczegółów.

Eugen Konkov
źródło
0

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.

billyw
źródło
0

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.

Chris
źródło