ORACLE VPD方案

ORACLE VPD方案DROP USER VPD CASCADE;
DROP ROLE R_VPD;
CREATE USER VPD IDENTIFIED BY VPD;
CREATE ROLE R_VPD;
GRANT RESOURCE TO VPD;
--VPD.VPD_PKG_FILTER.ReturnFilterCol在运行时读取视图ALL_TAB_COLUMNS需要该权限
GRANT SELECT ANY TABLE TO VPD;

--LOCK ALL USERS EXCEPT SYS AND SYSTEM锁定除SYS和SYSTEM的用户
SET SERVEROUT ON
DECLARE
CURSOR CUR_USERS IS SELECT USERNAME FROM DBA_USERS
WHERE USERNAME NOT IN ('SYSTEM','SYS');
BEGIN
FOR R_CUR IN CUR_USERS LOOP
EXECUTE IMMEDIATE 'ALTER USER '||R_CUR.USERNAME||' ACCOUNT LOCK';
END LOOP;
END;
/

-- CREATE TABLE该表用来存储所有VPD用户信息
CREATE TABLE VPD.VPD_JL_USER
(
QXDM VARCHAR2(2) NOT NULL,
USERNAME VARCHAR2(10) NOT NULL,
DESCRIPTION VARCHAR2(50)
);
GRANT SELECT ON VPD.VPD_JL_USER TO PUBLIC;

-- INSERT DATA TO TABLE VPD.VPD_JL_USER
set serverout on
declare
type u_arr is table of varchar2(20);
u_list u_arr default u_arr('user_dc','user_xc','user_cw','user_xw','user_cy','user_hd','user_ft','user_sjs',
'user_mtg','user_ys','user_cp','user_tz','user_sy','user_dx','user_fs','user_hr',
'user_my','user_pg','user_yq','user_kfq','user_xkz','user_sw');
i number default 22;
n number default 0;
v_tmp_insert varchar2(2000);
errcode varchar2(100);
errm varchar2(200);
begin
for i in 1..22 loop
v_tmp_insert := 'INSERT INTO VPD.VPD_JL_USER VALUES('''||trim(to_char(i,'00'))||''','''||upper(u_list(i))||''','''||upper(substr(u_list(i),instr(u_list(i),'_') - length(u_list(i))))||'的VPD用户'')';
begin
execute immediate v_tmp_insert;
EXCEPTION WHEN OTHERS THEN
rollback;
errcode:=sqlcode;
errm:=substr(sqlerrm,1,200);
dbms_output.put_line(errm);
END;
end loop;
COMMIT;
end;
/
SHOW ERR

-- CREATE USERS AND GRANT CREATE SESSION ANF R_VPD ROLE为VPD用户授权,该部分创建用户由上边的IMP用户替代
set serverout on
declare
type u_arr is table of varchar2(20);
u_list u_arr default u_arr('user_dc','user_xc','user_cw','user_xw','user_cy','user_hd','user_ft','user_sjs',
'user_mtg','user_ys','user_cp','user_tz','user_sy','user_dx','user_fs','user_hr',
'user_my','user_pg','user_yq','user_kfq','user_xkz','user_sw');
i number default 22;
n number default 0;
v_tmp_drop varchar2(2000);
v_tmp_create varchar2(2000);
v_tmp_grant varchar2(2000);
v_tmp_grant_select varchar2(2000);--将角色R_VPD赋予所有VPD用户
begin
for i in 1..22 loop
v_tmp_drop := 'DROP USER '||u_list(i);
v_tmp_create := 'CREATE USER '||u_list(i)||' IDENTIFIED BY '||u_list(i);
v_tmp_grant := 'GRANT CREATE SESSION TO '||u_list(i);
v_tmp_grant_select := 'GRANT R_VPD TO '||u_list(i);
begin
select count(*) into n from dba_users where username=upper(u_list(i));
if n>0 then
execute immediate v_tmp_drop;
else
null;
end if;
execute immediate v_tmp_create;
execute immediate v_tmp_grant;
execute immediate v_tmp_grant_select;
END;
end loop;
end;
/

--该包两个函数作用分别为1、返回策略运行的条件;2、判断业务表含有哪个满足条件的过滤字段
CREATE OR REPLACE PACKAGE VPD.VPD_PKG_FILTER
AS
-- Add Filter string into select sql
FUNCTION FilterQxdm(Owner VARCHAR2, Objname VARCHAR2) RETURN VARCHAR2;
-- Return the Filter Column from Tables
FUNCTION ReturnFilterCol(Owner VARCHAR2, Objname VARCHAR2) RETURN VARCHAR2;
END VPD_PKG_FILTER;
/
SHOW ERR

CREATE OR REPLACE PACKAGE BODY VPD.VPD_PKG_FILTER
AS
-- Add Filter string into select sql
FUNCTION FilterQxdm(Owner VARCHAR2, Objname VARCHAR2) RETURN VARCHAR2
IS
v_sql VARCHAR2(2000);
v_str VARCHAR2(30);
BEGIN
v_sql := '''' || SYS_CONTEXT('VPD_CONTEXT', 'QXDM') || '''';
IF (v_sql = '-1') THEN
v_sql := '';
ELSE
v_str := VPD_PKG_FILTER.ReturnFilterCol(Owner,Objname);
CASE v_str
WHEN 'QXDM' THEN
v_sql := 'QXDM = '|| v_sql;
WHEN 'SWJGZZJGDM' THEN
v_sql := 'SUBSTR(SWJGZZJGDM,1,2) = '|| v_sql;
WHEN 'ZHDM' THEN
v_sql := 'ZHDM = '|| v_sql;
END CASE;
END IF;
RETURN v_sql;
END FilterQxdm;
-- Return the Filter Column from Tables
FUNCTION ReturnFilterCol(Owner VARCHAR2, Objname VARCHAR2) RETURN VARCHAR2
IS
v_str VARCHAR2(30);
i_qxdm NUMBER DEFAULT 0;
i_swjg NUMBER DEFAULT 0;
i_zhdm NUMBER DEFAULT 0;
BEGIN
SELECT SUM(DECODE(COLUMN_NAME,'QXDM',1,0)),SUM(DECODE(COLUMN_NAME,'SWJGZZJGDM',1,0)),SUM(DECODE(COLUMN_NAME,'ZHDM',1,0))
INTO i_qxdm,i_swjg,i_zhdm FROM ALL_TAB_COLUMNS
WHERE OWNER = Owner AND TABLE_NAME=Objname;
IF i_qxdm>0 THEN
v_str := 'QXDM';
ELSE
IF i_swjg>0 THEN
v_str := 'SWJGZZJGDM';
ELSE
IF i_zhdm>0 THEN
v_str := 'ZHDM';
ELSE
v_str := 'NULL';
END IF;
END IF;
END IF;
RETURN v_str;
END ReturnFilterCol;

END VPD_PKG_FILTER;
/
SHOW ERR

GRANT EXECUTE ON VPD.VPD_PKG_FILTER TO PUBLIC;
DROP PUBLIC SYNONYM VPD_PKG_FILTER;
CREATE PUBLIC SYNONYM VPD_PKG_FILTER FOR VPD.VPD_PKG_FILTER;

-- GRANT SELECT ON TABLES TO VPD_USERS将含有满足条件过滤字段的业务表授予SELECT权限给所有VPD用户
SET SERVEROUT ON
DECLARE
I NUMBER;
CURSOR CUR_TABS IS SELECT OWNER,OBJECT_NAME FROM ALL_OBJECTS
WHERE OWNER IN ('SBDB','SFDB','BBDB','CFDB','DJDB','DMDB','JCDB','JHDB','JKDB','PGDB',
'PZDB','SPDB','SYDB') AND OBJECT_TYPE IN ('TABLE','VIEW')
ORDER BY OWNER,OBJECT_NAME;
BEGIN
FOR R_CUR IN CUR_TABS LOOP
IF R_CUR.OWNER = 'DMDB' THEN
EXECUTE IMMEDIATE 'GRANT SELECT ON '||R_CUR.OWNER||'.'||R_CUR.OBJECT_NAME||' TO R_VPD';
ELSE
IF VPD_PKG_FILTER.ReturnFilterCol(R_CUR.OWNER,R_CUR.OBJECT_NAME) <> 'NULL' THEN
EXECUTE IMMEDIATE 'GRANT SELECT ON '||R_CUR.OWNER||'.'||R_CUR.OBJECT_NAME||' TO R_VPD';
END IF;
END IF;
END LOOP;
END;
/

--该包作用设置上下文VPD_CONTEXT的参数QXDM的值
CREATE OR REPLACE PACKAGE VPD.VPD_PKG_CONTEXT
AS
-- Fetch user qxdm from table VPD.VPD_JL_USER, set it into sys context;
PROCEDURE Set_Context;
END VPD_PKG_CONTEXT;
/
SHOW ERR

CREATE OR REPLACE PACKAGE BODY VPD.VPD_PKG_CONTEXT
AS
-- Fetch user qxdm from table VPD.VPD_JL_USER, set it into sys context;
PROCEDURE Set_Context
IS
v_qxdm VARCHAR2(2);
BEGIN
SELECT QXDM INTO v_qxdm
FROM VPD.VPD_JL_USER
WHERE USERNAME = SYS_CONTEXT('USERENV','SESSION_USER');
DBMS_SESSION.SET_CONTEXT('VPD_CONTEXT', 'QXDM', v_qxdm);
EXCEPTION WHEN OTHERS THEN
DBMS_SESSION.SET_CONTEXT('VPD_CONTEXT', 'QXDM', '-1');
END Set_Context;
END VPD_PKG_CONTEXT;
/
SHOW ERR

GRANT EXECUTE ON VPD.VPD_PKG_CONTEXT TO PUBLIC;
DROP PUBLIC SYNONYM VPD_PKG_CONTEXT;
CREATE PUBLIC SYNONYM VPD_PKG_CONTEXT FOR VPD.VPD_PKG_CONTEXT;

-- Trigger for login用户登录数据库后触发,调用VPD.VPD_PKG_CONTEXT.Set_Context设置上下文中的参数值
CREATE OR REPLACE TRIGGER VPD.SET_SECURITY_CONTEXT
AFTER LOGON ON DATABASE
BEGIN
VPD.VPD_PKG_CONTEXT.Set_Context;
END;
/
SHOW ERR

DROP CONTEXT VPD_CONTEXT;
CREATE or REPLACE CONTEXT VPD_CONTEXT USING VPD.VPD_PKG_CONTEXT;

--Execute the policy for all tables except sys_tables为所有含有过滤字段的业务表添加策略
SET SERVEROUT ON
DECLARE
I NUMBER;
CURSOR CUR_TABS IS SELECT OWNER,OBJECT_NAME FROM ALL_OBJECTS
WHERE OWNER IN ('SBDB','SFDB','BBDB','CFDB','DJDB','JCDB','JHDB','JKDB','PGDB',
'PZDB','SPDB','SYDB') AND OBJECT_TYPE IN ('TABLE','VIEW')
ORDER BY OWNER,OBJECT_NAME;
BEGIN
FOR R_CUR IN CUR_TABS LOOP
IF VPD_PKG_FILTER.ReturnFilterCol(R_CUR.OWNER,R_CUR.OBJECT_NAME) <> 'NULL' THEN
SELECT COUNT(*) INTO I FROM DBA_POLICIES WHERE OBJECT_OWNER = R_CUR.OWNER AND OBJECT_NAME= R_CUR.OBJECT_NAME;
IF I>0 THEN
DBMS_RLS.DROP_POLICY( R_CUR.OWNER, R_CUR.OBJECT_NAME, 'PLC_'||R_CUR.OBJECT_NAME);
END IF;
DBMS_RLS.ADD_POLICY(R_CUR.OWNER, R_CUR.OBJECT_NAME, 'PLC_'||R_CUR.OBJECT_NAME, 'VPD', 'VPD_PKG_FILTER.FILTERQXDM', 'SELECT');
END IF;
END LOOP;
END;
/

--GRANT EXECUTE ON DBMS_RLS TO PUBLIC;
/*--EXP ALL VPD USERS,THIS STEP SHOULD BE PUT BEFORE DROP DATABASE
HOST
exp system/mana full=n owner=('user_dc','user_xc','user_cw','user_xw','user_cy','user_hd','user_ft','user_sjs',
'user_mtg','user_ys','user_cp','user_tz','user_sy','user_dx','user_fs','user_hr',
'user_my','user_pg','user_yq','user_kfq','user_xkz','user_sw')
grants=n file=/home/oracle/users.dmp log=/home/oracle/users.log
EXIT*/[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/18921899/viewspace-1016954/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/18921899/viewspace-1016954/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值