mysql: Tampilkan GRANT untuk semua pengguna

87

MySQL SHOW GRANTSmenunjukkan izin dari pengguna saat ini.

Apakah ada cara untuk login sebagai root dan menunjukkan izin semua pengguna?

Adam Matan
sumber

Jawaban:

45

Tidak ada yang built-in. Anda memiliki dua opsi:

  • Gunakan common_schema's sql_show_grants pandangan. Misalnya, Anda dapat meminta:

    SELECT sql_grants FROM common_schema.sql_show_grants;

    Atau Anda dapat meminta pengguna tertentu, misalnya:

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

    Untuk menginstal common_schema, ikuti instruksi di sini .

    Penafian: Saya penulis alat ini.

  • Gunakan Percona Toolkit's pt-show-grants, misalnya:

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

Dalam kedua kasus Anda dapat meminta GRANTperintah atau perintah REVOKE(berlawanan).

Kasus pertama mengharuskan Anda menginstal skema, yang terakhir mengharuskan Anda menginstal skrip + dependensi PERL.

Shlomi Noach
sumber
11
Bisakah Anda jelaskan secara lebih rinci cara menggunakan tampilan sql_show_grants common_schema? Saya mendapatkan kesalahanERROR 1146 (42S02): Table 'common_schema.sql_show_grants' doesn't exist
Martin Vegter
2
@ MartinVegter, sudahkah Anda menginstal common_schema? Unduh di sini dan instal mengikuti petunjuk ini .
Shlomi Noach
1
@ShlomiNoach, Ketika Anda mengatakan bahwa "tidak ada bawaan" ... Apakah ada kesalahan dengan information_schema.user_privileges?
Pacerier
2
Maaf, tetapi tidak ada yang namanya 'common_schema'. Itu tidak ada.
Brendan Byrd
2
tautan sql_show_grants broken
Cyzanfar
81
select * from information_schema.user_privileges;

SUNTING:

Seperti yang disebutkan oleh Shlomi Noach:

Itu tidak mencantumkan hak istimewa khusus-spesifik-tabel, khusus-tabel, khusus-kolom, dan khusus-rutin. Oleh karena itu, hibah GRANT SELECT ON mydb. * KE myuser @ localhost tidak muncul di information_schema.user_privileges. Solusi common_schema yang disajikan di atas mengagregasi data dari user_privileges dan tabel lain untuk memberi Anda gambaran lengkap.

rumburak
sumber
5
Maaf, itu seharusnya bukan jawaban yang diterima. information_schema.user_privilegeshanya mencantumkan hak istimewa tingkat pengguna, seperti SUPER, RELOADdll. Ia juga mencantumkan hibah DML serba seperti SELECT. Itu tidak mencantumkan basis data spesifik, khusus tabel, khusus kolom, khusus rutin. Ada kedepan, hibah GRANT SELECT ON mydb.* TO myuser@localhosttidak tidak ditampilkan di information_schema.user_privileges. The common_schemasolusi yang disajikan di atas Data agregat dari user_privilegesdan tabel lain untuk memberikan gambaran lengkap.
Shlomi Noach
11

Fragmen shell Linux ini melingkupi semua pengguna MySQL dan melakukan SHOW GRANTS untuk masing-masing:

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

Berfungsi paling baik jika Anda dapat terhubung ke MySQL tanpa kata sandi.

Output diformat sehingga dapat dijalankan di shell MySQL. Perhatian: Keluaran juga berisi izin dan kata sandi pengguna root MySQL! Hapus baris-baris itu jika Anda tidak ingin pengguna root MySQL diubah.

mleu
sumber
6
Anda mungkin ingin menambahkan beberapa detail tentang apa yang dilakukan atau bagaimana ini menjawab pertanyaan. Hanya menampilkan banyak kode tidak membantu orang memahami mengapa solusi Anda bekerja.
Max Vernon
Di mana saya bisa memberikan kata sandi?
Mian Asbat Ahmad
Untuk memberikan kata sandi, orang dapat menggunakan File Opsi atau bendera --password dari perintah mysql.
mleu
Apakah tidak mungkin untuk memberikan satu kata sandi root dan menjalankan kueri untuk mendapatkan semua hibah pengguna?
Mian Asbat Ahmad
2
Anda dapat melakukan streaming permintaan hanya untuk membuat satu koneksi, dan menggunakan mode 400 file yang dimiliki root. Versi saya: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;

Dapat memberi Anda Daftar pengguna dan Hak yang ditugaskan untuk masing-masing, memerlukan akses ke mysql.usertabel dan rootpengguna memilikinya.

Mahesh Patil
sumber
4
Ini hanya memberi Anda hak "tingkat atas" (tingkat server). Hak istimewa yang ditetapkan pada skema tertentu ada di mysql.db. Hak istimewa pada tabel tertentu ada mysql.tables_priv, dan seterusnya. Jadi tidak sesederhana itu.
Shlomi Noach
Untuk shenanigans tabel pelangi, lempar hash kata sandi Anda dari select * from mysql.userke crackstation.net dan lihat output yang tidak rusak.
Pacerier
8

One liner (ubah -urootmenjadi -u$USER_NAMEuntuk digunakan dengan pengguna lain) di bash Unix (karena backticks):

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

atau tanpa backticks dan dengan kata sandi inline (ruang di depan perintah mengecualikannya dari Bash history di Ubuntu):

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

Di 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
sumber
4

Jika Anda dapat menjalankan pernyataan SELECT berikut tanpa kesalahan:

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

maka jangan ragu untuk menggunakan kode berikut (di bawah), yang ditulis dalam sintaks .sql.

Saya merancang kueri ini dalam upaya membangun kembali pernyataan GRANT untuk semua izin yang ada (untuk pemeliharaan rutin selama migrasi basis data). Ada beberapa masalah yang harus ditangani, seperti penautan kata sandi pengguna, tetapi karena kami sering memperbarui kata sandi, itu tidak termasuk dalam ruang lingkup proyek ini.

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

Dengan senang hati menjawab / memverifikasi semua pertanyaan atau masalah

Cavallo
sumber
Saya tahu ini bukan halal, tapi ... skrip Anda luar biasa! Sekarang, yang harus saya lakukan adalah mengotomatiskannya. Saya akan menghangatkan pesta saya
hanzo2001
2

Ini akan memberi Anda pandangan yang lebih baik ...

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
sumber
1

Perintah SHOW GRANTS [FOR user]dapat menampilkan pengguna yang Anda inginkan. Lihat di sini untuk detail lebih lanjut.

Eugen Konkov
sumber
0

Seperti yang disebutkan dalam jawaban ini , Anda dapat menjalankan serangkaian perintah berikut untuk membuat daftar hak basis data spesifik, spesifik tabel, khusus kolom, dan khusus rutin semua pengguna. Perhatikan bahwa Anda perlu menjalankan ini dari shell, bukan command prompt 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

Keuntungan dari pendekatan ini adalah Anda tidak perlu menginstal perangkat lunak tambahan.

billyw
sumber
0

Jika Anda sering mengelola basis data, Anda mungkin ingin tetap memiliki hak istimewa yang ketat. Anda dapat menggunakan prosedur tersimpan untuk menjalankan pemeriksaan dengan cepat. Contoh ini berfungsi di mariadb mungkin perlu tweak untuk bekerja dengan versi mysql standar.

Menggunakan jawaban dari Mansur Ali dengan sedikit tweak penataan ulang kolom dan menambahkan beberapa pemesanan untuk lebih mengatur output.

Menggunakan login 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 ;

Anda bisa mengubah prosedur untuk memeriksa tabel mysql.user sebagai gantinya.

Penggunaan, menggunakan login root:

USE mysql;
CALL ShowPrivs();

Saya menggunakan meja kerja mysql di Ubuntu untuk menjalankan bagian create procedure dari jawaban ini.

Sebagai tambahan dan sedikit keluar dari topik di sini tetapi, Anda juga bisa memiliki prosedur untuk menunjukkan host atau pengguna yang tidak dikenal. Contoh untuk host yang tidak dikenal:

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 ;

Catatan penggunaan: Berikan string host yang dipisahkan oleh koma sehingga hanya satu set '' yang digunakan:

CALL ShowUnknownHosts('knownhost1,knownhost2');

Anda juga bisa membuat variabel kolom dengan memasukkan parameter lain dalam prosedur dan menyebutnya dengan ShowUnknownHosts (pengguna, 'user1, user2'); sebagai contoh.

Chris
sumber