PostgreSQL

PostgreSQL permission denied to create role 発生時の対応方法

以下は一般ユーザ’sooni’から新しくユーザ(dabada)の作成を試みてエラーが発生した状況です。

myposdb=> create user dabada password 'dadabada'
myposdb-> ;
ERROR:  permission denied to create role
myposdb=>

まず、権限まわりを疑いたくなるのでgrant文が真っ先に思い浮かぶのですが間違いです。ここはalter user(もしくはalter role)を使いcreaterole属性を付与する事でこちらのエラーを回避します。(ロールの属性とは『ある特別な管理操作の可不可を決めるも』のです。これに対し、オブジェクトへのアクセスを制御するのが権限で、grant/revokeを使い権限の付与、はく奪を行います。)

createrole属性を付与する

以下はpostgres(スーパーユーザ属性保持者)ユーザで行う必要があります。これでsooniユーザからも「create user」を実行する事ができるようになります。ただし既にsooniでログインしている場合、再度ログインし直さないと属性付与は繁栄されませんので注意してください。

alter user sooni with CREATEROLE
;
確認方法1 PSQLのコマンド\duにて確認する
myposdb=# \du
                                    List of roles
  Role name  |                         Attributes                         | Member of
-------------+------------------------------------------------------------+-----------
 online_user |                                                            | {}
 postgres    | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 sooni       | Create role                                                | {}
 udonman     |                                                            | {}


myposdb=#
確認方法2  SQLでシステムカタログ(pg_authid)を参照し確認する
select oid,rolname,rolsuper,rolcreaterole,rolcreatedb from pg_roles
where rolname='sooni'
;
myposdb=# select oid,rolname,rolsuper,rolcreaterole,rolcreatedb from pg_roles
myposdb-# where rolname='sooni'
myposdb-# ;
  oid  | rolname | rolsuper | rolcreaterole | rolcreatedb
-------+---------+----------+---------------+-------------
 16384 | sooni   | f        | t             | f
(1 row)


myposdb=#
確認方法3  SQLでシステムカタログ(pg_roles)を参照し確認する
SELECT oid,rolname
,case  rolsuper when 'true' then '〇' else '×' end as "super"
,case  rolinherit when 'true' then '〇' else '×' end as "inherit"
,case  rolcreaterole when 'true' then '〇' else '×' end as "createRole"
,case  rolcreatedb when 'true' then '〇' else '×' end as "createDb"
,case  rolcanlogin when 'true' then '〇' else '×' end as "canLogin"
,case  rolreplication when 'true' then '〇' else '×' end as "replication"
,rolconnlimit as "connLimit"
FROM pg_roles where rolcanlogin = true 
and rolname='sooni'
;
  oid  | rolname | super | inherit | createRole | createDb | canLogin | replication | connLimit
-------+---------+-------+---------+------------+----------+----------+-------------+-----------
 16384 | sooni   | ×    | 〇      |         | ×       | 〇       | ×          |        -1
(1 行)


myposdb=>

createrole属性を外す場合

alter user sooni with NOCREATEROLE
;
myposdb=# alter user sooni with NOCREATEROLE
myposdb-# ;
ALTER ROLE
myposdb=# alter user sooni with NOCREATEROLE
myposdb-# ;
ALTER ROLE
myposdb=# select oid,rolname,rolsuper,rolcreaterole,rolcreatedb from pg_roles
myposdb-# where rolname='sooni'
myposdb-# ;
  oid  | rolname | rolsuper | rolcreaterole | rolcreatedb
-------+---------+----------+---------------+-------------
 16384 | sooni   | f        | f             | f
(1 row)


myposdb=#
スポンサーリンク