2014-02-25 63 views
0

團隊, 我正在使用Amazon redshift。以下是版本:如何使用LOOP撤消訪問 - redshift

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) 

謝謝

回答

3

有沒有在紅移可用腳本,提供循環功能。您可以從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 ; 
+0

謝謝麥克。如果這個用戶可以訪問任何其他數據庫,那麼我需要撤消它(mynewdb1 =#從test_4中撤銷數據庫mynewdb1上的所有內容;)。但我仍然能夠連接這個數據庫(mynewdb1)作爲TEST_4。 (注意:我也從公共場合移除,但是它發生在紅移中)。任何備用? – user3258784

+0

所以你不想放棄用戶,但只是禁用他們連接?我不確定,但我認爲唯一的選擇是放棄它們。 –