Sql 向用户Oracle授予更新权限
我想将更新权授予表customer上的经理,但仅授予其为经理的客户Sql 向用户Oracle授予更新权限,sql,oracle,security,plsql,Sql,Oracle,Security,Plsql,我想将更新权授予表customer上的经理,但仅授予其为经理的客户 例如,我有一个表Custumer,我用CREATE user命令创建了一个用户“Jean”,因此我希望“Jean”可以修改它所管理的所有客户。我找到了RLS的这个示例,但现在编辑来满足您的简单用户需求已经太晚了。此示例适用于具有许多和各种角色的用户,这些角色可以从组织树继承。但我希望你明白了 BEGIN DBMS_RLS.DROP_POLICY (object_schema => 'CHS',
例如,我有一个表Custumer,我用CREATE user命令创建了一个用户“Jean”,因此我希望“Jean”可以修改它所管理的所有客户。我找到了RLS的这个示例,但现在编辑来满足您的简单用户需求已经太晚了。此示例适用于具有许多和各种角色的用户,这些角色可以从组织树继承。但我希望你明白了
BEGIN
DBMS_RLS.DROP_POLICY (object_schema => 'CHS',
object_name => 'CASE_FILE',
policy_name => 'CASE_FILE_READ');
DBMS_RLS.DROP_POLICY (object_schema => 'CHS',
object_name => 'CASE_FILE',
policy_name => 'CASE_FILE_WRITE');
DBMS_RLS.DROP_POLICY (object_schema => 'CHS',
object_name => 'CASE_FILE',
policy_name => 'CASE_FILE_REGISTER');
END;
CREATE OR REPLACE PACKAGE chs_security_policies AS
ROLE_CRUM CONSTANT VARCHAR2(5) := 'CRUM';
ROLE_CRUO CONSTANT VARCHAR2(5) := 'CRUO';
ROLE_HOU CONSTANT VARCHAR2(5) := 'HOU';
ROLE_DCO CONSTANT VARCHAR2(5) := 'DCO';
ROLE_SA CONSTANT VARCHAR2(5) := 'SA';
ROLE_CA CONSTANT VARCHAR2(5) := 'CA';
CHS_ORG_TREE CONSTANT CHAR(5) := 'CHS01';
READ_ACCESS CONSTANT INTEGER := 63;
WRITE_ACCESS CONSTANT INTEGER := 42;
INSERT_ACCESS CONSTANT INTEGER := 64;
ORG_CASCADE CONSTANT INTEGER := 2060;
CASE_SPECIFIC CONSTANT INTEGER := 48;
QUARANTINED_ACCESS CONSTANT INTEGER := 128;
FINALISED_ACCESS CONSTANT INTEGER := 256;
READ_ONLY CONSTANT INTEGER := 21;
READ_CASE_ORG_UNITS CONSTANT INTEGER := 16;
READ_GROUP_ORG_UNITS CONSTANT INTEGER := 4;
READ_WORLD_ORG_UNITS CONSTANT INTEGER := 1;
FUNCTION case_file_read (i_schema IN VARCHAR2, i_object IN VARCHAR2)
RETURN VARCHAR2;
FUNCTION case_file_write (i_schema IN VARCHAR2, i_object IN VARCHAR2)
RETURN VARCHAR2;
FUNCTION case_file_register (i_schema IN VARCHAR2, i_object IN VARCHAR2)
RETURN VARCHAR2;
FUNCTION case_file_filter (i_schema IN VARCHAR2, i_object IN VARCHAR2, i_access_requested INTEGER)
RETURN VARCHAR2;
FUNCTION check_case_access (i_case_file_id IN INTEGER, i_mgr_org_unit IN INTEGER, i_dco_person_id in varchar2)
RETURN INTEGER
DETERMINISTIC;
FUNCTION default_priv_mask (i_person_id in varchar2)
RETURN INTEGER
DETERMINISTIC;
FUNCTION decode_role (i_case_file_id IN INTEGER, i_mgr_org_unit IN INTEGER, i_dco_person_id in varchar2)
RETURN VARCHAR2
DETERMINISTIC;
FUNCTION check_proxy_access (i_case_file_id IN case_file.case_file_id%type
, i_dco_person_id IN case_file.dco_person_id%type
, i_mgr_org_unit IN case_file.mgr_org_unit%type
, i_proxy_person_id IN case_file.dco_person_id%type)
RETURN INTEGER
DETERMINISTIC;
END chs_security_policies;
CREATE OR REPLACE PACKAGE BODY chs_security_policies AS
FUNCTION case_file_read (i_schema IN VARCHAR2, i_object IN VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
RETURN case_file_filter(i_schema, i_object, READ_ACCESS);
END case_file_read;
FUNCTION case_file_write (i_schema IN VARCHAR2, i_object IN VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
RETURN case_file_filter(i_schema, i_object, WRITE_ACCESS);
END case_file_write;
FUNCTION case_file_register (i_schema IN VARCHAR2, i_object IN VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
RETURN case_file_filter(i_schema, i_object, INSERT_ACCESS);
END case_file_register;
FUNCTION case_file_filter (i_schema IN VARCHAR2, i_object IN VARCHAR2, i_access_requested INTEGER)
RETURN VARCHAR2
IS
o_filter_predicate VARCHAR2(200) := '';
BEGIN
CASE lower(i_object)
WHEN 'case_file' THEN
o_filter_predicate :=
'BITAND(chs_security_policies.check_case_access(case_file_id, mgr_org_unit, dco_person_id), '||i_access_requested||') <> 0 ';
WHEN 'case_file_h' THEN
o_filter_predicate :=
'BITAND(chs_security_policies.check_case_access(case_file_id, mgr_org_unit, dco_person_id), '||i_access_requested||') <> 0 ';
END CASE;
RETURN o_filter_predicate;
END case_file_filter;
FUNCTION check_proxy_access (i_case_file_id IN case_file.case_file_id%type
, i_dco_person_id IN case_file.dco_person_id%type
, i_mgr_org_unit IN case_file.mgr_org_unit%type
, i_proxy_person_id IN case_file.dco_person_id%type)
RETURN INTEGER
DETERMINISTIC
IS
o_has_access INTEGER := 0;
v_prev_person varchar2(8) := SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER');
BEGIN
dbms_session.set_identifier(i_proxy_person_id);
IF BITAND(check_case_access(i_case_file_id, i_mgr_org_unit, i_dco_person_id), READ_ACCESS) <> 0
THEN
o_has_access := 1;
END IF;
dbms_session.set_identifier(v_prev_person);
RETURN o_has_access;
END check_proxy_access;
FUNCTION check_case_access(i_case_file_id in INTEGER, i_mgr_org_unit in INTEGER, i_dco_person_id in varchar2)
RETURN INTEGER
DETERMINISTIC
IS
o_access_granted INTEGER := 0;
v_curr_person varchar2(8) := SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER');
v_single_priv INTEGER := 0;
v_profile_org_unit INTEGER := 0;
v_quarantine_ok varchar2(1);
v_finalise_ok varchar2(1);
v_is_participant varchar2(1);
v_local_role access_role.role_code%type;
cursor user_privs is
select
d.priv_id,
b.org_unit_id,
c.role_code
from
access_user a
,access_profile b
,access_role c
,access_role_priv d
,access_priv e
where
a.person_id = v_curr_person
and a.active_flag = 'Y'
and b.person_id = a.person_id
and c.role_code = b.role_code
and d.role_code = b.role_code
and e.priv_id = d.priv_id
;
BEGIN
IF v_curr_person is null
THEN
RETURN 0;
END IF;
select
case
when exists
(select
*
from
complainant a
where
a.case_file_id = i_case_file_id
and a.person_id = v_curr_person
and a.active_flag = 'Y'
)
then 'Y'
else 'N'
end
into
v_is_participant
from
dual
;
IF v_is_participant = 'Y'
THEN
RETURN 0;
END IF;
select
case
when exists
(select
*
from
respondent a
where
a.case_file_id = i_case_file_id
and a.person_id = v_curr_person
and a.person_type <> 'U'
and a.active_flag = 'Y'
)
then 'Y'
else 'N'
end
into
v_is_participant
from
dual
;
IF v_is_participant = 'Y'
THEN
RETURN 0;
END IF;
v_quarantine_ok := 'N';
v_finalise_ok := 'N';
open user_privs;
loop
fetch user_privs into v_single_priv,
v_profile_org_unit,
v_local_role;
exit when user_privs%notfound;
IF v_single_priv = QUARANTINED_ACCESS
THEN
v_quarantine_ok := 'Y';
continue;
END IF;
IF v_single_priv = FINALISED_ACCESS
THEN
v_finalise_ok := 'Y';
continue;
END IF;
IF bitand(v_single_priv, ORG_CASCADE) <> 0
THEN
select
case
when i_mgr_org_unit in (
select
a.org_unit_child
from
org_rel a
connect by nocycle
a.org_rel_type_code = CHS_ORG_TREE and
prior
a.org_unit_child = a.org_unit_parent
start with
a.org_unit_child = v_profile_org_unit
and a.org_rel_type_code = CHS_ORG_TREE)
then v_single_priv
else 0
end
into
v_single_priv
from
dual
;
END IF;
IF bitand(v_single_priv, CASE_SPECIFIC) <> 0
THEN
IF v_local_role = 'CA'
THEN
select
case
when exists
(select
*
from
case_assistant a
where
a.case_file_id = i_case_file_id
and a.case_assistant_id = v_curr_person
and sysdate between a.access_from and a.access_to
)
then v_single_priv
else 0
end
into
v_single_priv
from
dual
;
IF v_single_priv <> 0
THEN
v_quarantine_ok := 'Y';
END IF;
ELSE
IF v_curr_person <> i_dco_person_id
THEN
v_single_priv := 0;
END IF;
END IF;
END IF;
o_access_granted := (o_access_granted + v_single_priv - bitand(o_access_granted, v_single_priv));
end loop;
close user_privs;
IF o_access_granted = 0 THEN
RETURN o_access_granted;
END IF;
IF (v_quarantine_ok = 'N' AND (i_dco_person_id <> v_curr_person
OR BITAND(o_access_granted,CASE_SPECIFIC) = 0)) THEN
select
case
when exists
(select
*
from
quarantine a
where
a.case_file_id = i_case_file_id
and a.active_flag = 'Y'
)
then 0
else o_access_granted
end
into
o_access_granted
from
dual
;
END IF;
IF o_access_granted = 0 THEN
RETURN o_access_granted;
END IF;
IF v_finalise_ok = 'N' THEN
select
case
when exists
(select
*
from
finalise a
where
a.case_file_id = i_case_file_id
)
then 0
else o_access_granted
end
into
o_access_granted
from
dual
;
END IF;
IF v_finalise_ok = 'Y' THEN
select
case
when exists
(select
*
from
finalise a
where
a.case_file_id = i_case_file_id
)
then BITAND(o_access_granted, READ_ONLY)
else o_access_granted
end
into
o_access_granted
from
dual
;
END IF;
RETURN o_access_granted;
END check_case_access;
FUNCTION decode_role(i_case_file_id IN INTEGER, i_mgr_org_unit IN INTEGER, i_dco_person_id in varchar2)
RETURN VARCHAR2
DETERMINISTIC
IS
v_curr_person varchar2(8) := SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER');
v_access_granted INTEGER := 0;
o_role_used access_role.role_code%type;
BEGIN
v_access_granted := check_case_access(i_case_file_id, i_mgr_org_unit, i_dco_person_id);
IF BITAND(v_access_granted, READ_CASE_ORG_UNITS ) <> 0 THEN
IF v_curr_person = i_dco_person_id THEN
o_role_used := ROLE_DCO;
ELSE
o_role_used := ROLE_CA;
END IF;
ELSE
IF BITAND(v_access_granted, READ_GROUP_ORG_UNITS) <> 0 THEN
o_role_used := ROLE_HOU;
ELSE
IF BITAND(v_access_granted, READ_WORLD_ORG_UNITS) <> 0 THEN
select
case
when exists
(select
*
from
access_profile a
where
a.person_id = v_curr_person
and a.role_code = ROLE_CRUM
)
then ROLE_CRUM
else ROLE_CRUO
end
into
o_role_used
from
dual
;
END IF;
END IF;
END IF;
RETURN o_role_used;
END decode_role;
FUNCTION default_priv_mask(i_person_id in varchar2)
RETURN INTEGER
DETERMINISTIC
IS
o_access_available INTEGER := 0;
v_single_priv INTEGER := 0;
cursor user_privs is
select
d.priv_id
from
access_user a
,access_profile b
,access_role c
,access_role_priv d
,access_priv e
where
a.person_id = i_person_id
and a.active_flag = 'Y'
and b.person_id = a.person_id
and c.role_code = b.role_code
and d.role_code = b.role_code
and e.priv_id = d.priv_id
;
BEGIN
open user_privs;
loop
fetch user_privs into v_single_priv;
exit when user_privs%notfound;
o_access_available := (o_access_available + v_single_priv - bitand(o_access_available, v_single_priv));
end loop;
close user_privs;
RETURN o_access_available;
END default_priv_mask;
END chs_security_policies;
/
BEGIN
DBMS_RLS.ADD_POLICY (object_schema => 'CHS',
object_name => 'CASE_FILE',
policy_name => 'CASE_FILE_READ',
function_schema => 'CHS',
statement_types => 'SELECT',
policy_function => 'chs_security_policies.case_file_read');
DBMS_RLS.ADD_POLICY (object_schema => 'CHS',
object_name => 'CASE_FILE',
policy_name => 'CASE_FILE_WRITE',
function_schema => 'CHS',
statement_types => 'UPDATE,DELETE',
policy_function => 'chs_security_policies.case_file_write');
DBMS_RLS.ADD_POLICY (object_schema => 'CHS',
object_name => 'CASE_FILE',
policy_name => 'CASE_FILE_REGISTER',
function_schema => 'CHS',
statement_types => 'INSERT',
policy_function => 'chs_security_policies.case_file_register');
END;
开始
DBMS_RLS.DROP_策略(对象_架构=>'CHS',
对象名称=>“案例文件”,
策略名称=>“案例文件读取”);
DBMS_RLS.DROP_策略(对象_架构=>'CHS',
对象名称=>“案例文件”,
策略_name=>CASE_FILE_WRITE');
DBMS_RLS.DROP_策略(对象_架构=>'CHS',
对象名称=>“案例文件”,
策略_name=>CASE_FILE_REGISTER');
结束;
根据需要创建或替换程序包chs\u安全\u策略
ROLE_CRUM常数VARCHAR2(5):=“CRUM”;
ROLE_CRUO常数VARCHAR2(5):='CRUO';
ROLE_HOU常量VARCHAR2(5):='HOU';
ROLE_DCO常量VARCHAR2(5):=“DCO”;
角色_SA常数VARCHAR2(5):=“SA”;
角色_CA常量VARCHAR2(5):=“CA”;
CHS_组织树常量字符(5):=“CHS01”;
读取访问常量整数:=63;
写入访问常量整数:=42;
插入访问常量整数:=64;
组织级联常数整数:=2060;
特定于案例的常量整数:=48;
隔离访问常量整数:=128;
最终确定的_访问常量整数:=256;
只读常量整数:=21;
读取\案例\组织\单位常量整数:=16;
读取组组织单位常量整数=4;
读取世界组织单位常量整数:=1;
函数case_file_read(VARCHAR2中的i_模式,VARCHAR2中的i_对象)
返回VARCHAR2;
函数case\u file\u write(VARCHAR2中的i\u模式,VARCHAR2中的i\u对象)
返回VARCHAR2;
函数案例\文件\寄存器(VARCHAR2中的i\模式,VARCHAR2中的i\对象)
返回VARCHAR2;
函数case_file_filter(VARCHAR2中的i_模式,VARCHAR2中的i_对象,i_访问请求的整数)
返回VARCHAR2;
函数检查案例访问(整数形式的案例文件id、整数形式的经理组织单元、varchar2形式的dco人员id)
返回整数
确定性;
函数默认的私有掩码(varchar2中的个人id)
返回整数
确定性;
函数解码角色(整数形式的i_案例\文件\ id、整数形式的i_经理\组织\单位、varchar2形式的i_dco \人员\ id)
返回VARCHAR2
确定性;
函数检查\u代理\u访问(案例文件中的案例文件\u id。案例文件\u id%类型
,案例文件中的i_dco_person_id。dco_person_id%类型
,案例文件中的i_mgr_组织单位。mgr_组织单位%type
,i_proxy_person_id(在case_file.dco_person_id%类型中)
返回整数
确定性;
结束chs_安全_政策;
根据需要创建或替换包体chs\U安全\U策略
函数case_file_read(VARCHAR2中的i_模式,VARCHAR2中的i_对象)
返回VARCHAR2
是
开始
返回案例\文件\过滤器(i\模式、i\对象、读取\访问);
结束案例文件读取;
函数case\u file\u write(VARCHAR2中的i\u模式,VARCHAR2中的i\u对象)
返回VARCHAR2
是
开始
返回案例\文件\过滤器(i\模式、i\对象、写入\访问);
结束案例文件写入;
函数案例\文件\寄存器(VARCHAR2中的i\模式,VARCHAR2中的i\对象)
返回VARCHAR2
是
开始
返回案例\文件\过滤器(i\模式、i\对象、插入\访问);
结束案例\文件\寄存器;
函数case_file_filter(VARCHAR2中的i_模式,VARCHAR2中的i_对象,i_访问请求的整数)
返回VARCHAR2
是
o_filter_谓词VARCHAR2(200):='';
开始
下格(i_对象)
“案例文件”是什么时候
o_filter_谓词:=
“BITAND(chs|U安全|策略。检查|U案例|U访问(案例|U文件|id、经理|组织|单位、dco|U人员|id),”| i|U访问|U请求|||0”;
当“案例文件”出现时
o_filter_谓词:=
“BITAND(chs|U安全|策略。检查|U案例|U访问(案例|U文件|id、经理|组织|单位、dco|U人员|id),”| i|U访问|U请求|||0”;
终例;
返回o_filter_谓词;
结束案例文件过滤器;
函数检查\u代理\u访问(案例文件中的案例文件\u id。案例文件\u id%类型
,案例文件中的i_dco_person_id。dco_person_id%类型
,案例文件中的i_mgr_组织单位。mgr_组织单位%type
,i_proxy_person_id(在case_file.dco_person_id%类型中)
返回整数
确定性
是
o_有_访问整数:=0;
v_prev_person varchar2(8):=SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER');
开始
dbms_session.set_标识符(i_proxy_person_id);
如果BITAND(检查案例访问(案例文件id、经理组织单位、dco人员id)0
然后
o_具有_访问权限:=1;
如果结束;
dbms_session.set_标识符(v_prev_person);
返回o_有权访问;
结束检查\u代理\u访问;
函数检查案例访问(整数形式的案例文件id、整数形式的经理组织单元、varchar2形式的dco人员id)
返回整数
确定性
是
o\u访问\u授予的整数:=0;
v_curr_person varchar2(8):=SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER');
v_single_priv INTEGER:=0;
v_配置文件_组织_单位整数: