Kueri memberikan tabel di postgres

97

Bagaimana saya bisa menanyakan semua HIBAH yang diberikan ke objek di postgres?

Misalnya saya punya tabel "mytable":

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

Saya butuh sesuatu yang memberi saya:

user1: SELECT, INSERT
user2: UPDATE
markus
sumber

Jawaban:

113

Saya sudah menemukannya:

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

\z mytable dari psql memberi Anda semua hibah dari tabel, tetapi Anda kemudian harus membaginya dengan pengguna individu.

CPJ
sumber
apakah Anda akan menjalankan ini langsung dari panel sql atau baris perintah pg?
Daniel L. VanDenBosch
2
@ DanielL.VanDenBosch: semua perintah meta, seperti \z, adalah untuk psql. Dan psql adalah antarmuka baris perintah ke PostgreSQL.
Mike Sherrill 'Cat Recall'
31

Jika Anda benar-benar menginginkan satu baris per pengguna, Anda dapat mengelompokkan berdasarkan penerima (memerlukan PG9 + untuk string_agg)

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

Ini harus menghasilkan sesuatu seperti:

 grantee |   privileges   
---------+----------------
 user1   | INSERT, SELECT
 user2   | UPDATE
(2 rows)
Nicolas Payart
sumber
1
Hampir seperti yang saya inginkan, dapatkah saya mendapatkan GRANTkeluaran pg_dump yang sama persis ?
brauliobo
28

Kueri di bawah ini akan memberi Anda daftar semua pengguna dan izin mereka pada tabel dalam skema.

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';

Rincian lebih lanjut has_table_privilagesdapat ditemukan di sini .

shruti
sumber
4
Ini adalah satu-satunya jawaban di sini yang menghitung izin yang diperoleh dari keanggotaan dalam peran lain, jadi ini mendapat suara saya. Di sisi lain, saya akan mengatakan has_table_privilege(usename, contact(schemaname, '.', tablename), ...)untuk menghindari ambiguitas.
Paul A Jungwirth
Plus Satu - INI EMAS MURNI!
Daniel
9

Kueri ini akan mencantumkan semua tabel di semua database dan skema (hapus komentar baris di WHEREklausa untuk memfilter database, skema, atau tabel tertentu), dengan hak istimewa yang diperlihatkan secara berurutan sehingga mudah untuk melihat apakah hak istimewa tertentu diberikan atau tidak:

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;

Output sampel:

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 |
...
isapir
sumber
ini hanya memberikan baris yang cocok dengan pengguna yang mengeksekusinya ... tidak semua hibah
Ricky Levi
2

Menambah jawaban @ shruti

Untuk mengajukan kueri untuk semua tabel dalam skema untuk pengguna tertentu

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;
wisnu narayanan
sumber
Ini berfungsi dengan baik, dengan asumsi Anda masuk sebagai pengguna dengan izin yang sesuai. Nitpick: Saya menyarankan bahwa gabungan silang harus ditulis secara eksplisit, misalnya FROM pg_tables AS a CROSS JOIN pg_user AS bdaripada cara SQL 92 melakukannya dengan komafrom pg_tables a, pg_user b
Davos
1

Berikut adalah skrip yang menghasilkan kueri pemberian untuk tabel tertentu. Ini menghilangkan hak istimewa pemilik.

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;
Sahap Asci
sumber