队 我正在使用亚马逊红移。以下是版本:
PostgreSQL 8.0.2 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3), Redshift 1.0.748
我想删除一个用户帐户。如果此用户可以访问任何表/模式/数据库,那么必须首先撤销它,然后它将允许我们删除用户。在红移中,“掉落所有;”不管用。因此,我需要在删除之前以编程方式找出授予用户的访问权限。
例如我在2个架构上授予此用户访问权限。但是在撤销它时,我需要使用一些FOR ..LOOP然后找出该用户有权访问的模式并撤销它,而不是手动(如下所示)。 Coudl你能帮帮我吗?我需要编写一个小程序,其中需要创建一个游标并存储这两个模式,在FOR..loop下,我需要调用它们并逐个撤销它们。如果您提供此功能,我可以使用它来撤销其他表格授权,数据库授权等。
redshift=# GRANT all on schema schema44 to proj_user1;
GRANT
redshift=# grant all on schema proj_schema1 to proj_user1;
GRANT
redshift=#
redshift=# select nspname from pg_catalog.pg_namespace where array_to_string(nspacl,',') like '%proj_user1%';
nspname
--------------
schema44
proj_schema1
(2 rows)
redshift=# revoke all on schema schema44 from proj_user1;
REVOKE
redshift=# revoke all on schema proj_schema1 from proj_user1;
REVOKE
redshift=# select nspname from pg_catalog.pg_namespace where array_to_string(nspacl,',') like '%proj_user1%';
nspname
---------
(0 rows)
谢谢
答案 0 :(得分:3)
Redshift中没有提供循环功能的脚本。您可以从psql运行以下查询,并使用输出作为脚本来删除用户。
此查询构建对象的撤消cmds:
select
'revoke ' || substring(
case when charindex('r',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',select ' else '' end
||case when charindex('w',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',update ' else '' end
||case when charindex('a',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',insert ' else '' end
||case when charindex('d',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',delete ' else '' end
||case when charindex('R',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',rule ' else '' end
||case when charindex('x',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',references ' else '' end
||case when charindex('t',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',trigger ' else '' end
||case when charindex('X',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',execute ' else '' end
||case when charindex('U',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',usage ' else '' end
||case when charindex('C',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',create ' else '' end
||case when charindex('T',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',temporary ' else '' end
, 2,10000)
|| ' on '||namespace||'.'||item ||' from "'||pu.usename||'";' 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_user pu on array_to_string(relacl, '|') like '%'||pu.usename||'%'
where relacl is not null
and pu.usename='<username>'
order by 1;
然后您需要更改任何表所有权:
select 'alter table '||schemaname||'.'||tablename||' owner to <newowner>;' from pg_tables where tableowner = '<username>';
您无法更改视图的所有权,因此您必须删除它们:
select 'drop view '||schemaname||'.'||viewname||' ;' from pg_views where viewowner = '<username>';
您需要从任何群组中删除用户:
select 'alter group '||nvl(groname,'default')||' drop user '||usename||';' from pg_user u left join pg_group g on ','||array_to_string(grolist,',')||',' like '%,'||cast(usesysid as varchar(10))||',%' where usename='<username>' ;
最后从模式中删除:
select
'revoke ' || substring(
case when charindex('U',split_part(split_part(array_to_string(nspacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',usage ' else '' end
||case when charindex('C',split_part(split_part(array_to_string(nspacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',create ' else '' end
, 2,10000)
|| ' on schema '||nspname||' from "'||pu.usename||'";'
from pg_namespace pn,pg_user pu
where pu.usename='<username>' and array_to_string(nspacl,',') like '%'||pu.usename||'%'
and nspowner > 1 ;