Concessões de consulta para uma tabela no postgres

92

Como posso consultar todos os GRANTS concedidos a um objeto no postgres?

Por exemplo, tenho a tabela "mytable":

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

Eu preciso de algo que me dê:

user1: SELECT, INSERT
user2: UPDATE
Markus
fonte

Respostas:

108

Já encontrei:

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

\z mytable do psql oferece todas as concessões de uma tabela, mas você terá que dividi-la por usuário individual.

CPJ
fonte
você executaria isso diretamente do painel sql ou da linha de comando da pg?
Daniel L. VanDenBosch
2
@ DanielL.VanDenBosch: todos os meta-comandos, como \z, são para psql. E o psql é a interface de linha de comando do PostgreSQL.
Mike Sherrill 'Cat Recall'
29

Se você realmente deseja uma linha por usuário, pode agrupar por beneficiário (requer 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;

Isso deve resultar em algo como:

 grantee |   privileges   
---------+----------------
 user1   | INSERT, SELECT
 user2   | UPDATE
(2 rows)
Nicolas Payart
fonte
1
Quase o que eu quero, posso ter exatamente GRANTas saídas do pg_dump?
brauliobo
26

A consulta abaixo fornecerá uma lista de todos os usuários e suas permissões na tabela em um 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';

Mais detalhes sobre has_table_privilagespodem ser encontrados aqui .

Shruti
fonte
4
Esta é a única resposta aqui que calcula as permissões obtidas pela participação em outras funções, portanto, ela recebe meu voto. Por outro lado, eu diria has_table_privilege(usename, contact(schemaname, '.', tablename), ...)para evitar ambigüidades.
Paul A Jungwirth
Mais um - ESTE É OURO PURO!
Daniel
9

Esta consulta irá listar todas as tabelas em todos os bancos de dados e esquemas (descomente a (s) linha (s) na WHEREcláusula para filtrar por bancos de dados, esquemas ou tabelas específicos), com os privilégios mostrados em ordem para que seja fácil ver se um privilégio específico é concedido ou não:

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;

Saída de amostra:

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
fonte
isso fornece apenas as linhas que correspondem ao usuário que o executou ... nem todas as concessões
Ricky Levi,
2

Adicionando à resposta de @ shruti

Para consultar concessões para todas as tabelas em um esquema para um determinado usuário

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
fonte
Isso funciona bem, supondo que você efetue login como um usuário com as permissões apropriadas. Nitpick: Aconselho que uma junção cruzada seja escrita explicitamente, por exemplo, FROM pg_tables AS a CROSS JOIN pg_user AS bem vez da maneira SQL 92 de fazer isso com uma vírgulafrom pg_tables a, pg_user b
Davos
1

Aqui está um script que gera consultas de concessão para uma tabela específica. Ele omite os privilégios do proprietário.

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
fonte