mysql: แสดง GRANT สำหรับผู้ใช้ทั้งหมด


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 แล้วหรือยัง ดาวน์โหลดที่นี่และติดตั้งตามคำแนะนำเหล่านี้
Shlomi Noach

1
@ShlomiNoach เมื่อคุณพูดว่า "ไม่มีอะไรในตัว" ... มีข้อผิดพลาดinformation_schema.user_privilegesหรือไม่?
Pacerier

2
ขออภัยไม่มีสิ่งเช่น 'common_schema' มันไม่มีอยู่จริง
Brendan Byrd

2
ลิงค์ sql_show_grants เสีย
Cyzanfar

81
select * from information_schema.user_privileges;

แก้ไข:

ดังกล่าวโดย Shlomi Noach:

มันไม่ได้แสดงสิทธิพิเศษเฉพาะฐานข้อมูลตารางเฉพาะคอลัมน์เฉพาะเจาะจง ดังนั้นการให้สิทธิ์ GRANT SELECT ON mydb. * TO myuser @ localhost ไม่แสดงใน information_schema.user_privileges วิธีแก้ปัญหา common_schema ที่แสดงด้านบนจะรวบรวมข้อมูลจาก user_privileges และตารางอื่น ๆ เพื่อให้ภาพเต็ม


5
ขออภัยไม่ควรเป็นคำตอบที่ยอมรับได้ information_schema.user_privilegesแสดงเฉพาะสิทธิ์ของผู้ใช้ระดับเช่นSUPER, RELOADฯลฯ SELECTมันยังแสดงทุกรอบทุนดราก้อนเช่น มันไม่ได้แสดงรายการสิทธิพิเศษเฉพาะฐานข้อมูล, ตาราง, คอลัมน์, เฉพาะคอลัมน์ ก่อนมี, ทุนGRANT SELECT ON mydb.* TO myuser@localhostไม่ได้information_schema.user_privilegesแสดงใน common_schemaวิธีการแก้ปัญหาดังกล่าวข้างต้นที่นำเสนอข้อมูลจากมวลuser_privilegesและตารางอื่น ๆ เพื่อให้คุณได้ภาพเต็ม
Shlomi Noach

11

ส่วนของเชลล์ของ Linux นี้วนผู้ใช้ MySQL ทั้งหมดและแสดง GRANTSสำหรับแต่ละคน:

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 ของ MySQL และรหัสผ่าน! ลบบรรทัดเหล่านั้นหากคุณไม่ต้องการให้ผู้ใช้รูท MySQL เปลี่ยน


6
คุณอาจต้องการเพิ่มรายละเอียดบางอย่างเกี่ยวกับสิ่งนี้หรือตอบคำถาม การแสดงรหัสจำนวนมากไม่ได้ช่วยให้ใครเข้าใจว่าทำไมโซลูชันของคุณถึงใช้งานได้
Max Vernon

ฉันจะให้รหัสผ่านได้ที่ไหน
Mian Asbat Ahmad

เพื่อให้รหัสผ่านหนึ่งอาจใช้ไฟล์ตัวเลือกหรือ-ธงรหัสผ่านของคำสั่ง mysql
mleu

เป็นไปไม่ได้ที่จะให้รหัสผ่านรูทเดียวและเรียกใช้คิวรีเพื่อให้ผู้ใช้ทั้งหมดได้รับ
Mian Asbat Ahmad

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
สิ่งนี้ให้สิทธิ์ "ระดับบนสุด" (ระดับเซิร์ฟเวอร์) เท่านั้น สิทธิพิเศษตั้งอยู่บน schemas mysql.dbเฉพาะใน สิทธิ์บนตารางที่ระบุอยู่ในmysql.tables_privและอื่น ๆ ดังนั้นมันจึงไม่ใช่เรื่องง่าย
Shlomi Noach

สำหรับ shenanigans ตารางสายรุ้งให้ใส่รหัสผ่านแฮชของคุณจากselect * from mysql.userลงในcrackstation.netและดูผลลัพธ์ที่ไม่ได้แฮช
Pacerier

8

สายการบินหนึ่ง (เปลี่ยน-urootเป็น-u$USER_NAMEเพื่อใช้กับผู้ใช้รายอื่น) ใน Unash bash (เพราะแบ็คคิก):

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

หรือไม่มี backticks และรหัสผ่านแบบอินไลน์ (เว้นวรรคด้านหน้าคำสั่งจะแยกออกจาก Bash history ใน 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 */

ยินดีที่จะตอบ / ตรวจสอบคำถามหรือข้อสงสัย


ฉันรู้ว่านี่ไม่ใช่เพียว แต่ ... สคริปต์ของคุณน่าทึ่ง! ตอนนี้สิ่งที่ฉันต้องทำคือการทำให้เป็นอัตโนมัติ ฉันจะอุ่นเครื่องทุบตีของฉัน
hanzo2001

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)


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 อาจต้องใช้ tweak เพื่อทำงานกับเวอร์ชัน mysql มาตรฐาน

ใช้คำตอบจาก Mansur Ali ด้วยการปรับแต่งเล็กน้อยการจัดเรียงคอลัมน์ใหม่และเพิ่มบางคำสั่งเพื่อให้จัดระเบียบเอาต์พุตได้ดีขึ้น

ใช้ล็อกอินรูท:

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 (ผู้ใช้, 'user1, user2'); ตัวอย่างเช่น.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.