Abfragegewährung für eine Tabelle in Postgres


92

Wie kann ich alle GRANTS abfragen, die einem Objekt in Postgres gewährt wurden?

Zum Beispiel habe ich Tabelle "mytable":

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

Ich brauche etwas, das mir gibt:

user1: SELECT, INSERT
user2: UPDATE

Antworten:


106

Ich habe es schon gefunden:

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

96

\z mytable von psql gibt Ihnen alle Zuschüsse aus einer Tabelle, aber Sie müssten sie dann nach einzelnen Benutzern aufteilen.


Würden Sie dies direkt über den SQL-Bereich oder die pg-Befehlszeile ausführen?
Daniel L. VanDenBosch

2
@ DanielL.VanDenBosch: Alle Meta-Befehle sind wie \zfür psql. Und psql ist die Befehlszeilenschnittstelle zu PostgreSQL.
Mike Sherrill 'Cat Recall'

29

Wenn Sie wirklich eine Zeile pro Benutzer möchten, können Sie nach Berechtigten gruppieren (PG9 + für string_agg erforderlich).

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

Dies sollte ungefähr Folgendes ausgeben:

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

1
Fast das, was ich will, kann ich die exakten GRANTs wie pg_dump-Ausgaben haben?
Brauliobo

25

Versuchen Sie die folgende Abfrage. Sie erhalten eine Liste aller Benutzer und ihrer Berechtigungen für die Tabelle.

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 a.tablename='your_table_name';

4
Dies ist die einzige Antwort hier, die Berechtigungen berechnet, die aus der Mitgliedschaft in anderen Rollen erhalten wurden, sodass ich meine Stimme bekomme. Auf der anderen Seite würde ich sagen has_table_privilege(usename, contact(schemaname, '.', tablename), ...), um Mehrdeutigkeiten zu vermeiden.
Paul A Jungwirth

Plus Eins - DAS IST REINES GOLD!
Daniel

8

Diese Abfrage listet alle Tabellen in allen Datenbanken und Schemas auf (kommentieren Sie die Zeile (n) in der WHEREKlausel aus, um nach bestimmten Datenbanken, Schemas oder Tabellen zu filtern), wobei die Berechtigungen der Reihe nach angezeigt werden, damit Sie leicht erkennen können, ob Ein bestimmtes Privileg wird gewährt oder nicht:

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;

Beispielausgabe:

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 |
...

Dies gibt nur die Zeilen, die dem Benutzer entsprechen, der es ausgeführt hat ... nicht alle Zuschüsse
Ricky Levi

2

Hinzufügen zu @ shrutis Antwort

Abfragen von Berechtigungen für alle Tabellen in einem Schema für einen bestimmten Benutzer

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;

Dies funktioniert gut, vorausgesetzt, Sie melden sich als Benutzer mit den entsprechenden Berechtigungen an. Nitpick: Ich rate, dass ein Cross-Join explizit geschrieben werden sollte, z. B. FROM pg_tables AS a CROSS JOIN pg_user AS banstelle der SQL 92-Methode, dies mit einem Komma zu tunfrom pg_tables a, pg_user b
Davos

1

Hier ist ein Skript, das Grant-Abfragen für eine bestimmte Tabelle generiert. Es werden die Privilegien des Besitzers weggelassen.

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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.