VPD policy function Modified

限于喜欢 提交于 2019-12-24 20:13:30

问题


Hello, I have asked this question yesterday but thanks to your help, I did a lot of modifications so now I'm putting the new version of my code because it's getting better but still not working.

Let's assume i have the following table which is called payroll created by a user called PCM

EMP_ID               DEPT                      TOTAL      TAXES
-------------------- -------------------- ---------- ----------
E1                   accounting                 2400        100 
E2                   sales                      2500         75 
E3                   research                   3000        110 
E4                   operations                 4200        120 
E5                   sales                      4800        130 
E6                   sales                      2500         75 
E7                   accounting                 5200        140 
E8                   accounting                 2700        105

Now what i want to achieve is the following: Anyone with the dept = accounting" can select all other rows with dept != accounting but anyone with dept != accounting can only view his/her record.

Now I'm connected as another user not the owner of the payroll table so I'm connected as a user called ANNE:

CREATE OR REPLACE CONTEXT payroll_ctx USING payroll_ctx_pkg;
CREATE OR REPLACE PACKAGE payroll_ctx_pkg IS 
  PROCEDURE set_dept;
 END;
/
CREATE OR REPLACE PACKAGE BODY payroll_ctx_pkg IS
  PROCEDURE set_dept
  AS
    v_dept varchar2(400);
  BEGIN
     SELECT dept INTO v_dept FROM PCM.PAYROLL
        WHERE EMP_ID = SYS_CONTEXT('USERENV', 'SESSION_USER');
     DBMS_SESSION.SET_CONTEXT('payroll_ctx', 'dept', v_dept);
  EXCEPTION
   WHEN NO_DATA_FOUND THEN
   DBMS_SESSION.SET_CONTEXT('payroll_ctx', 'dept', 'NO');
  END set_dept;
END;
/

Considering that the users who will try to access the table have the names of the emp_id column,now:

CREATE TRIGGER set_dept_trig AFTER LOGON ON DATABASE
 BEGIN
  ANNE.payroll_ctx_pkg.set_dept;
 END;
/

Now the problem(i know it's wrong) but can't find the solution yet:

CREATE OR REPLACE PACKAGE security_package AS 
FUNCTION sec_fun (D1 VARCHAR2, D2 VARCHAR2) 
RETURN VARCHAR2; 
END;
/
CREATE OR REPLACE PACKAGE BODY security_package AS 
FUNCTION sec_fun (D1 VARCHAR2, D2 VARCHAR2) 
RETURN VARCHAR2
IS
    vv_dept varchar2(400);
    V_ID varchar2(400);
begin
    V_ID := SYS_CONTEXT('USERENV', 'SESSION_USER');
    vv_dept := 'SYS_CONTEXT(''payroll_ctx'', ''dept'')';
    if (vv_dept != 'accounting') then
    RETURN 'EMP_ID = ' || CHR(39)||V_ID||CHR(39);
    ELSE
    RETURN 'DEPT != ' || CHR(39)||vv_dept||CHR(39);
  END IF;
    EXCEPTION
  WHEN NO_DATA_FOUND
  THEN
    RETURN '1 = 0';
end sec_fun;
end security_package;
/

And Finally:

BEGIN
 DBMS_RLS.ADD_POLICY (
  object_schema    => 'PCM', 
  object_name      => 'PAYROLL', 
  policy_name      => 'payroll_policy', 
  function_schema  => 'ANNE',
  policy_function  => 'security_package.sec_fun',
  statement_types  => 'select');
END;
/

Now when a user E1 tries to select from payroll the output is:

EMP_ID               DEPT                      TOTAL      TAXES
-------------------- -------------------- ---------- ----------
E1                   accounting                 2400        100 

what I'm doing wrong?? It's supposed to return all rows where dept != accounting


回答1:


Thanks to your helping i finally managed to solve the problem, It was in the variable vv_dept when i made the following modifications it worked out:

CREATE OR REPLACE PACKAGE security_package AS 
FUNCTION sec_fun (D1 VARCHAR2, D2 VARCHAR2) 
RETURN VARCHAR2; 
END;
/
CREATE OR REPLACE PACKAGE BODY security_package AS 
FUNCTION sec_fun (D1 VARCHAR2, D2 VARCHAR2) 
RETURN VARCHAR2
IS
    V_ID varchar2(400);
begin
    V_ID := SYS_CONTEXT('USERENV', 'SESSION_USER');
    if (SYS_CONTEXT('payroll_ctx','dept') = 'accounting') then
    RETURN 'DEPT != ' || CHR(39)||SYS_CONTEXT('payroll_ctx','dept')||CHR(39);
    ELSE
        RETURN 'EMP_ID = ' || CHR(39)||V_ID||CHR(39);
  END IF;
    EXCEPTION
  WHEN NO_DATA_FOUND
  THEN
    RETURN '1 = 0';
end sec_fun;
end security_package;
/


来源:https://stackoverflow.com/questions/53816394/vpd-policy-function-modified

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!