Sql 向用户Oracle授予更新权限

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',

我想将更新权授予表customer上的经理,但仅授予其为经理的客户


例如,我有一个表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_配置文件_组织_单位整数: