以下は一般ユーザ’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=#