Postgres의 테이블에 대한 쿼리 부여


96

postgres의 객체에 부여 된 모든 GRANTS를 어떻게 쿼리 할 수 ​​있습니까?

예를 들어 "mytable"테이블이 있습니다.

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

나에게주는 것이 필요합니다.

user1: SELECT, INSERT
user2: UPDATE

답변:


113

이미 찾았습니다.

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

99

\z mytable from psql은 테이블의 모든 권한을 제공하지만 개별 사용자별로 분할해야합니다.


SQL 창이나 pg 명령 줄에서 직접 실행 하시겠습니까?
Daniel L. VanDenBosch

2
@ DanielL.VanDenBosch :와 같은 모든 메타 명령 \z은 psql 용입니다. 그리고 psql은 PostgreSQL에 대한 명령 줄 인터페이스입니다.
Mike Sherrill 'Cat

31

사용자 당 한 줄을 원할 경우 피부 여자별로 그룹화 할 수 있습니다 (string_agg에 PG9 + 필요).

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

다음과 같은 출력이 표시됩니다.

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

1
내가 원하는 거의 GRANTpg_dump 출력과 같은 정확한 s를 가질 수 있습니까?
brauliobo 2016-06-16

27

아래 쿼리는 스키마의 테이블에 대한 모든 사용자 및 해당 권한 목록을 제공합니다.

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_privilages확인할 수 있습니다 .


4
이것은 다른 역할의 멤버십에서 얻은 권한을 계산하는 유일한 대답이므로 내 투표를 얻습니다. 다른 한편으로, 나는 has_table_privilege(usename, contact(schemaname, '.', tablename), ...)모호함을 피하기 위해 말할 것 입니다.
폴 Jungwirth

플러스 원-이것은 순수한 금입니다!
Daniel

9

이 쿼리는 모든 데이터베이스 및 스키마의 모든 테이블을 나열합니다 ( WHERE특정 데이터베이스, 스키마 또는 테이블을 필터링하기 위해 절 에서 줄의 주석 처리 제거 ). 특정 권한이 부여되었는지 여부 :

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;

샘플 출력 :

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

이것은 단지 그것을 실행 한 사용자를 일치하는 행 ... 모든 보조금 제공
리키 레위

2

@shruti의 답변에 추가

지정된 사용자의 스키마에있는 모든 테이블에 대한 권한 부여를 쿼리하려면

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;

이는 적절한 권한이있는 사용자로 로그인한다고 가정하면 잘 작동합니다. Nitpick : FROM pg_tables AS a CROSS JOIN pg_user AS b쉼표를 사용하는 SQL 92 방식보다는 크로스 조인을 명시 적으로 작성해야한다고 조언합니다from pg_tables a, pg_user b
Davos

1

다음은 특정 테이블에 대한 권한 부여 쿼리를 생성하는 스크립트입니다. 소유자의 권한을 생략합니다.

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;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.