Trợ cấp truy vấn cho một bảng trong postgres


92

Làm cách nào để truy vấn tất cả GRANTS được cấp cho một đối tượng trong postgres?

Ví dụ, tôi có bảng "mytable":

GRANT SELECT, INSERT ON mytable TO user1
GRANT UPDATE ON mytable TO user2 

Tôi cần những thứ mang lại cho tôi:

user1: SELECT, INSERT
user2: UPDATE

Câu trả lời:


108

Tôi đã tìm thấy nó:

SELECT grantee, privilege_type 
FROM information_schema.role_table_grants 
WHERE table_name='mytable'

97

\z mytable từ psql cung cấp cho bạn tất cả các khoản trợ cấp từ một bảng, nhưng sau đó bạn phải chia nhỏ nó theo từng người dùng.


bạn sẽ chạy nó trực tiếp từ ngăn sql hay dòng lệnh pg?
Daniel L. VanDenBosch

2
@ DanielL.VanDenBosch: tất cả các lệnh meta, như \zlà dành cho psql. Và psql là giao diện dòng lệnh của PostgreSQL.
Mike Sherrill 'Cat Recall'

29

Nếu bạn thực sự muốn một dòng cho mỗi người dùng, bạn có thể nhóm theo người được cấp (yêu cầu PG9 + cho string_agg)

SELECT grantee, string_agg(privilege_type, ', ') AS privileges
FROM information_schema.role_table_grants 
WHERE table_name='mytable'   
GROUP BY grantee;

Điều này sẽ xuất ra một cái gì đó như:

 grantee |   privileges   
---------+----------------
 user1   | INSERT, SELECT
 user2   | UPDATE
(2 rows)

1
Gần như những gì tôi muốn, tôi có thể có GRANTkết quả đầu ra chính xác như pg_dump không?
brauliobo

26

Truy vấn bên dưới sẽ cung cấp cho bạn danh sách tất cả người dùng và quyền của họ trên bảng trong một lược đồ.

select a.schemaname, a.tablename, b.usename,
  HAS_TABLE_PRIVILEGE(usename, quote_ident(schemaname) || '.' || quote_ident(tablename), 'select') as has_select,
  HAS_TABLE_PRIVILEGE(usename, quote_ident(schemaname) || '.' || quote_ident(tablename), 'insert') as has_insert,
  HAS_TABLE_PRIVILEGE(usename, quote_ident(schemaname) || '.' || quote_ident(tablename), 'update') as has_update,
  HAS_TABLE_PRIVILEGE(usename, quote_ident(schemaname) || '.' || quote_ident(tablename), 'delete') as has_delete, 
  HAS_TABLE_PRIVILEGE(usename, quote_ident(schemaname) || '.' || quote_ident(tablename), 'references') as has_references 
from pg_tables a, pg_user b 
where a.schemaname = 'your_schema_name' and a.tablename='your_table_name';

has_table_privilagesthể tìm thấy thêm chi tiết tại đây .


4
Đây là câu trả lời duy nhất ở đây tính toán các quyền có được từ tư cách thành viên trong các vai trò khác, vì vậy nó nhận được phiếu bầu của tôi. Mặt khác, tôi sẽ nói has_table_privilege(usename, contact(schemaname, '.', tablename), ...)để tránh sự mơ hồ.
Paul A Jungwirth

Plus One - ĐÂY LÀ VÀNG TINH KHIẾT!
Daniel

9

Truy vấn này sẽ liệt kê tất cả các bảng trong tất cả các cơ sở dữ liệu và lược đồ (bỏ ghi chú (các) dòng trong WHEREmệnh đề để lọc các cơ sở dữ liệu, lược đồ hoặc bảng cụ thể), với các đặc quyền được hiển thị theo thứ tự để dễ dàng xem một đặc quyền cụ thể có được cấp hay không:

SELECT grantee
      ,table_catalog
      ,table_schema
      ,table_name
      ,string_agg(privilege_type, ', ' ORDER BY privilege_type) AS privileges
FROM information_schema.role_table_grants 
WHERE grantee != 'postgres' 
--  and table_catalog = 'somedatabase' /* uncomment line to filter database */
--  and table_schema  = 'someschema'   /* uncomment line to filter schema  */
--  and table_name    = 'sometable'    /* uncomment line to filter table  */
GROUP BY 1, 2, 3, 4;

Đầu ra mẫu:

grantee |table_catalog   |table_schema  |table_name     |privileges     |
--------|----------------|--------------|---------------|---------------|
PUBLIC  |adventure_works |pg_catalog    |pg_sequence    |SELECT         |
PUBLIC  |adventure_works |pg_catalog    |pg_sequences   |SELECT         |
PUBLIC  |adventure_works |pg_catalog    |pg_settings    |SELECT, UPDATE |
...

này chỉ cung cấp cho các hàng phù hợp với người dùng thực hiện nó ... không phải tất cả các khoản tài trợ
Ricky Levi

2

Thêm vào câu trả lời của @ shruti

Để truy vấn các khoản trợ cấp cho tất cả các bảng trong lược đồ cho một người dùng nhất định

select a.tablename, 
       b.usename, 
       HAS_TABLE_PRIVILEGE(usename,tablename, 'select') as select,
       HAS_TABLE_PRIVILEGE(usename,tablename, 'insert') as insert, 
       HAS_TABLE_PRIVILEGE(usename,tablename, 'update') as update, 
       HAS_TABLE_PRIVILEGE(usename,tablename, 'delete') as delete, 
       HAS_TABLE_PRIVILEGE(usename,tablename, 'references') as references 
from pg_tables a, 
     pg_user b 
where schemaname='your_schema_name' 
      and b.usename='your_user_name' 
order by tablename;

Điều này hoạt động tốt, giả sử bạn đăng nhập với tư cách là người dùng có quyền thích hợp. Nitpick: Tôi khuyên rằng một chéo tham gia nên được viết một cách rõ ràng, ví dụ FROM pg_tables AS a CROSS JOIN pg_user AS bchứ không phải là cách SQL 92 để làm việc đó với một dấu phẩyfrom pg_tables a, pg_user b
Davos

1

Đây là một tập lệnh tạo truy vấn cấp cho một bảng cụ thể. Nó bỏ qua các đặc quyền của chủ sở hữu.

SELECT 
    format (
      'GRANT %s ON TABLE %I.%I TO %I%s;',
      string_agg(tg.privilege_type, ', '),
      tg.table_schema,
      tg.table_name,
      tg.grantee,
      CASE
        WHEN tg.is_grantable = 'YES' 
        THEN ' WITH GRANT OPTION' 
        ELSE '' 
      END
    )
  FROM information_schema.role_table_grants tg
  JOIN pg_tables t ON t.schemaname = tg.table_schema AND t.tablename = tg.table_name
  WHERE
    tg.table_schema = 'myschema' AND
    tg.table_name='mytable' AND
    t.tableowner <> tg.grantee
  GROUP BY tg.table_schema, tg.table_name, tg.grantee, tg.is_grantable;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.