0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Amazon Redshift ユーザ管理SQL

Posted at

ログイン中のユーザ

select current_user;

ロール

ロールとは、簡単に言えばユーザーのようなもので「データベース全体に対する権限」と「オブジェクトに対する権限」の 2 通りの権限を持ちます。
通常、データベースのログインに使用しているのもこのロールです。

なぜ、ユーザーといわず、あえてロールかというと、ロールにはユーザーとグループという概念が内包されているからです。
ユーザーもグループもどちらもロールとして作られるものですが、ユーザーはグループに属し、グループの権限を継承することができます。
なのでロールとユーザーはイコールではなく、ロールというくくりの中にユーザーとグループがいることになります。

SELECT * FROM pg_roles;

検索

ユーザ一覧

Query

select usesysid as user_id,
       usename as username,
       usecreatedb as db_create,
       usesuper as is_superuser,
       valuntil as password_expiration
from pg_user
order by user_id

Columns
user_id - id of the user
username - user name
db_create - flag indicating if user can create new databases
is_superuser - flag if user have superuser privileges
password_expiration - date of user password expiration
Rows
One row represents one user in the database
Scope of rows: all users in the database
Ordered by user id

ユーザが保持するテーブル権限

その1

SELECT 
 use.usename as subject, 
 nsp.nspname as namespace, 
 c.relname as item, 
 c.relkind as type, 
 use2.usename as owner, 
 c.relacl 
 FROM 
 pg_user use 
 cross join pg_class c 
 left join pg_namespace nsp on (c.relnamespace = nsp.oid) 
 left join pg_user use2 on (c.relowner = use2.usesysid)
 WHERE 
 c.relowner = use.usesysid  
 and  nsp.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
 ORDER BY   subject,   namespace,   item 

その2

WITH 
usrs as (SELECT * FROM pg_user),
objs as (
  SELECT 
    schemaname, 't' AS obj_type,
    tablename AS objectname,
    schemaname + '.' + tablename AS fullobj
  FROM pg_tables
  WHERE schemaname not in ('pg_internal')
  UNION
  SELECT 
    schemaname, 'v' AS obj_type, 
    viewname AS objectname, 
    schemaname + '.' + viewname AS fullobj 
  FROM pg_views
  WHERE schemaname NOT IN ('pg_internal')
),
query as (
  SELECT 
    schemaname,
    objectname,
    usename,
    HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'select') AS sel,
    HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'insert') AS ins,
    HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'update') AS upd,
    HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'delete') AS del,
    HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'references') AS ref
  FROM objs, usrs
  ORDER BY fullobj
)
SELECT * FROM query
WHERE (
  sel = TRUE 
  OR ins = TRUE 
  OR upd = TRUE 
  OR del = TRUE 
  OR ref = TRUE
) AND schemaname != 'information_schema'
 AND schemaname != 'pg_catalog'
;

その3 ユーザごとのスキーマ権限

SELECT
    u.usename,
    s.schemaname,
    has_schema_privilege(u.usename,s.schemaname,'create') AS user_has_select_permission,
    has_schema_privilege(u.usename,s.schemaname,'usage') AS user_has_usage_permission
FROM
    pg_user u
CROSS JOIN
    (SELECT DISTINCT schemaname FROM pg_tables) s
WHERE
    s.schemaname NOT IN ('pg_catalog', 'pg_internal', 'information_schema')
--    u.usename = 'cm_user1'
order by
    u.usename, s.schemaname
;

その4

SELECT
  use.usename as subject, 
  nsp.nspname as namespace, 
  c.relname as item, 
  c.relkind as type, 
  use2.usename as owner, 
  c.relacl 
FROM
  pg_user use 
  cross join pg_class c 
  left join pg_namespace nsp on (c.relnamespace = nsp.oid) 
  left join pg_user use2 on (c.relowner = use2.usesysid)
WHERE
  c.relowner = use.usesysid  
  and nsp.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
--  and nsp.nspname in('public','staging','xxxxxxxx') /** 任意のスキーマを指定 */
  and type in('r','v')
ORDER BY
  subject,namespace,item;

グループ

グループの作成

CREATE GROUP - Amazon Redshift

CREATE GROUP cmawsgroup;

ユーザーのグループへの追加

所定のグループへユーザーを追加する際はALTER GROUPコマンドを使います。

ALTER GROUP cmawsgroup ADD USER testuser1;

グループからのユーザーの削除

ユーザーの追加同様、削除もALTER GROUPコマンドを使います。

ALTER GROUP cmawsgroup DROP USER testuser3;

グループに所属するユーザーの一覧を確認する

SELECT * FROM pg_group;

グループに付与した権限

Since grants are per object you need to query permissions of all objects. Here you can see the relacl that lists permissions and the grant statement generated to grant those permissions:

select relacl , 
'grant ' || substring(
            case when charindex('r',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)) > 0 then ',select ' else '' end 
          ||case when charindex('w',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)) > 0 then ',update ' else '' end 
          ||case when charindex('a',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)) > 0 then ',insert ' else '' end 
          ||case when charindex('d',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)) > 0 then ',delete ' else '' end 
          ||case when charindex('R',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)) > 0 then ',rule ' else '' end 
          ||case when charindex('x',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)) > 0 then ',references ' else '' end 
          ||case when charindex('t',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)) > 0 then ',trigger ' else '' end 
          ||case when charindex('X',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)) > 0 then ',execute ' else '' end 
          ||case when charindex('U',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)) > 0 then ',usage ' else '' end 
          ||case when charindex('C',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)) > 0 then ',create ' else '' end 
          ||case when charindex('T',split_part(split_part(array_to_string(relacl, '|'),pu.groname,2 ) ,'/',1)) > 0 then ',temporary ' else '' end 
       , 2,10000)
|| ' on '||namespace||'.'||item ||' to "'||pu.groname||'";' as grantsql
from 
(SELECT 
 use.usename as subject, 
 nsp.nspname as namespace, 
 c.relname as item, 
 c.relkind as type, 
 use2.usename as owner, 
 c.relacl 
FROM 
pg_user use 
 cross join pg_class c 
 left join pg_namespace nsp on (c.relnamespace = nsp.oid) 
 left join pg_user use2 on (c.relowner = use2.usesysid)
WHERE 
 c.relowner = use.usesysid  
 and  nsp.nspname   NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
ORDER BY 
 subject,   namespace,   item 
) join pg_group pu on array_to_string(relacl, '|') like '%'||pu.groname||'%' 
where relacl is not null
--  and pu.groname='group1'
order by 2
;

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?