Изменена функция политики VPD - PullRequest
0 голосов
/ 17 декабря 2018

Здравствуйте, я задал этот вопрос вчера, но благодаря вашей помощи я сделал много модификаций, так что теперь я помещаю новую версию своего кода, потому что она улучшается, но все еще не работает.

Предположим, у меня есть следующая таблица, которая называется payroll, созданная пользователем с именем 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

Теперь я хочу добиться следующего: Любой, у кого есть dept = accounting" может выбрать все остальные строки с помощью dept != accounting, но любой пользователь с dept != accounting может только просматривать свою запись.

Теперь я подключен как другой пользователь, не являющийся владельцем таблицы заработной платы, поэтому яподключен как пользователь с именем 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;
/

Учитывая, что пользователи, которые будут пытаться получить доступ к таблице, имеют имена столбца emp_id, теперь:

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

Теперьпроблема (я знаю, что это неправильно), но пока не могу найти решение:

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;
/

И наконец:

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;
/

Теперь, когда пользователь E1 пытается выбрать из платежной ведомостивывод:

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

что я делаю не так ??Он должен вернуть все строки, где dept != accounting

1 Ответ

0 голосов
/ 17 декабря 2018

Благодаря вашей помощи мне, наконец, удалось решить проблему. Она была в переменной vv_dept, когда я сделал следующие изменения:

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;
/
...