PostgreSQL

PostgreSQL テーブル、ビューへのアクセス権限を調べる

information_schema.role_table_grantsを参照する事で確認する事ができます。以下はonline_userがアクセスできるテーブルの一覧です。
※注意点として、スーパーユーザ属性を持つユーザは、全てのオブジェクトにアクセスできますが、以下SQLの結果には出てきません。(但しスーパーユーザ自身が作成したテーブルについては出てきます)

テーブルやビューへのアクセス権限確認SQL(簡易版)
SELECT grantor,grantee,table_catalog,table_schema, table_name, privilege_type 
FROM information_schema.role_table_grants
where grantee='online_user'
;
myposdb=> SELECT grantor,grantee,table_catalog,table_schema, table_name, privilege_type
myposdb-> FROM information_schema.role_table_grants t where t.grantee='online_user'
myposdb-> ;
 grantor |   grantee   | table_catalog | table_schema | table_name | privilege_type
---------+-------------+---------------+--------------+------------+----------------
 sooni   | online_user | myposdb       | sooni        | ex04       | SELECT
(1 row)
テーブルやビューへのアクセス権限確認SQL(オブジェクトタイプ出力版)

上記の簡易版(role_table_grantsのみの参照)ではテーブルなのか、VIEWなのか判断つかないためpg_classを結合します。

select 
g.table_catalog,g.grantor,g.grantee,g.table_schema,g.table_name
,case c.relkind
 when 'r' then 'TABLE'
 when 't' then 'TOAST'
 when 'v' then 'VIEW'
 when 'm' then 'MaterializedView'
 when 'c' then 'CompositeType'
 when 'f' then 'ForeignTable'
 when 'p' then 'PartitionTable' 
 when 'I' then 'PartitionIndex'  
  else concat(c.relkind,'')
end relkind_dec
, g.privilege_type 
from information_schema.role_table_grants g inner join pg_class c
on g.table_name = c.relname
inner join pg_namespace p on c.relnamespace = p.oid
and g.table_schema = p.nspname
where grantee='online_user'
order by grantee,table_schema,relkind_dec,table_name,privilege_type
;
 table_catalog |  grantor   |   grantee   | table_schema |  table_name   | relkind_dec | privilege_type
---------------+------------+-------------+--------------+---------------+-------------+----------------
 myposdb       | batch_user | online_user | prjschema    | batch_tbl     | TABLE       | DELETE
 myposdb       | batch_user | online_user | prjschema    | batch_tbl     | TABLE       | INSERT
 myposdb       | batch_user | online_user | prjschema    | batch_tbl     | TABLE       | REFERENCES
 myposdb       | batch_user | online_user | prjschema    | batch_tbl     | TABLE       | SELECT
 myposdb       | batch_user | online_user | prjschema    | batch_tbl     | TABLE       | TRIGGER
 myposdb       | batch_user | online_user | prjschema    | batch_tbl     | TABLE       | TRUNCATE
 myposdb       | batch_user | online_user | prjschema    | batch_tbl     | TABLE       | UPDATE
 myposdb       | sooni      | online_user | sooni        | ex02          | TABLE       | INSERT
 myposdb       | sooni      | online_user | sooni        | ex02          | TABLE       | SELECT
 myposdb       | sooni      | online_user | sooni        | ex04          | TABLE       | INSERT
 myposdb       | sooni      | online_user | sooni        | ex04          | TABLE       | SELECT
 myposdb       | sooni      | online_user | sooni        | address_gaiku | VIEW        | SELECT
(12 行)

myposdb=#

ここで注意点があります。これは各「テーブル」や「ビュー」に対してのアクセス権限を確認しているだけで、実際には対象のテーブルやビューが存在する「スキーマ」に対するアクセス権限も確認が必要です。例えば上記の状態で、online_userからsooni.ex4テーブルをselectしてみます。

myposdb=> select count(*) from sooni.ex04;
ERROR:  permission denied for schema sooni
行 1: select count(*) from sooni.ex04;
                           ^

このようにエラーとなってしまう場合があります。これはonline_userロールから、sooniスキーマへアクセスできる権限が付与されていないためです。以下SQLでスキーマへのアクセス権限を確認します。

スキーマへのアクセス権限を確認するSQL
select n.nspname as "schema",pg_catalog.pg_get_userbyid(n.nspowner) as "owner"
,n.nspacl
from pg_catalog.pg_namespace n
where n.nspname !~ '^pg_' and n.nspname <> 'information_schema'
order by 1;

以下確認するとsooniスキーマに対し、アクセス権限を保有しているのはsooniロールとudonmanロールのみである事がわかります。
nspaclフィールドはACL(Access Control List)と呼称されるようで、スキーマ(schema)に対して設定されたユーザーやロールのアクセス権限を表すリストになります。

スキーマへのアクセス権限確認SQL実行例
-- 
-- ACLの見方は以下の通り
-- {ユーザーまたはロール=アクセス権限/スキーマのオーナー}
-- 
  schema   |  owner   |                  nspacl
-----------+----------+------------------------------------------
 prjschema | prjadmin | {prjadmin=UC/prjadmin,sooni=UC/prjadmin}
 public    | postgres | {postgres=UC/postgres,=UC/postgres}
 sooni     | sooni    | {sooni=UC/sooni,udonman=U/sooni}
 udonman   | sooni    |
(4 行)

myposdb=>
スキーマへのアクセス権限を付与する
grant usage on schema sooni to online_user
;

スキーマのオーナであるsooniから権限付与

myposdb=# select current_user;
 current_user
--------------
 sooni
(1 行)

myposdb=# grant usage on schema sooni to online_user;
GRANT

myposdb=> select n.nspname as "schema",pg_catalog.pg_get_userbyid(n.nspowner) as "owner"
myposdb-> ,n.nspacl
myposdb-> from pg_catalog.pg_namespace n
myposdb-> where n.nspname !~ '^pg_' and n.nspname <> 'information_schema'
myposdb-> order by 1;
  schema   |  owner   |                        nspacl
-----------+----------+------------------------------------------------------
 prjschema | prjadmin | {prjadmin=UC/prjadmin,sooni=UC/prjadmin}
 public    | postgres | {postgres=UC/postgres,=UC/postgres}
 sooni     | sooni    | {sooni=UC/sooni,udonman=U/sooni,online_user=U/sooni}
 udonman   | sooni    |
(4 行)

myposdb=>
online_userから再度アクセス
myposdb=> select sooni.ex04;
ERROR:  missing FROM-clause entry for table "sooni"
行 1: select sooni.ex04;
             ^
myposdb=>
--
-- 再度実行
--                    ^
myposdb=>  select * from sooni.ex04;
 c1
-----
 100
(1 行)

今度はアクセスできること確認できました。

スポンサーリンク
コピペで使う