Consulta de subvenciones para una tabla en postgres

92

¿Cómo puedo consultar todas las SUBVENCIONES otorgadas a un objeto en postgres?

Por ejemplo, tengo la tabla "mytable":

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

Necesito algo que me dé:

user1: SELECT, INSERT
user2: UPDATE
Markus
fuente

Respuestas:

108

Ya lo encontré:

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

\z mytable from psql le brinda todas las concesiones de una tabla, pero luego tendría que dividirlo por usuario individual.

CPJ
fuente
¿Ejecutaría esto directamente desde el panel sql o desde la línea de comando pg?
Daniel L.VanDenBosch
2
@ DanielL.VanDenBosch: todos los metacomandos, como \z, son para psql. Y psql es la interfaz de línea de comandos para PostgreSQL.
Mike Sherrill 'Cat Recall'
29

Si realmente desea una línea por usuario, puede agrupar por beneficiario (se requiere PG9 + para string_agg)

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

Esto debería generar algo como:

 grantee |   privileges   
---------+----------------
 user1   | INSERT, SELECT
 user2   | UPDATE
(2 rows)
Nicolas Payart
fuente
1
Casi lo que quiero, ¿puedo tener las GRANTsalidas exactas como pg_dump?
brauliobo
26

La consulta a continuación le dará una lista de todos los usuarios y sus permisos en la tabla en un esquema.

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_privilagesPuede encontrar más detalles aquí .

Shruti
fuente
4
Esta es la única respuesta aquí que calcula los permisos obtenidos de la membresía en otros roles, por lo que obtiene mi voto. Por otro lado, diría has_table_privilege(usename, contact(schemaname, '.', tablename), ...)que evite la ambigüedad.
Paul A Jungwirth
Más uno: ¡ESTO ES ORO PURO!
Daniel
9

Esta consulta enumerará todas las tablas en todas las bases de datos y esquemas (descomente las líneas en la WHEREcláusula para filtrar por bases de datos, esquemas o tablas específicas), con los privilegios mostrados en orden para que sea fácil ver si se otorga o no un privilegio específico:

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;

Salida de muestra:

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
fuente
esto da solo las filas que coinciden con el usuario que lo ejecutó ... no todas las subvenciones
Ricky Levi
2

Agregando a la respuesta de @ shruti

Para consultar concesiones para todas las tablas en un esquema para un usuario determinado

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;
vishnu narayanan
fuente
Esto funciona bien, suponiendo que inicie sesión como un usuario con los permisos adecuados. Nitpick: Aconsejo que una combinación cruzada debe escribirse explícitamente, por ejemplo, en FROM pg_tables AS a CROSS JOIN pg_user AS blugar de la forma SQL 92 de hacerlo con una comafrom pg_tables a, pg_user b
Davos
1

Aquí hay un script que genera consultas de concesión para una tabla en particular. Omite los privilegios del propietario.

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
fuente