CREATE TABLE scott.user_allowed ( ua_id NUMBER, oracle_user VARCHAR2(50) ); Table created. insert into scott.user_allowed (ua_id, oracle_user) values (1, 'SCOTT'); insert into scott.user_allowed (ua_id, oracle_user) values (2, 'OTHERUSER'); 1 row created. 1 row created. commit; CREATE TABLE scott.user_data ( ud_id NUMBER, ud_user_id NUMBER, ud_data VARCHAR2(2000) ); Table created. insert into scott.user_data (ud_id, ud_user_id, ud_data) values (1, 1, 'SCOTT DATA'); insert into scott.user_data (ud_id, ud_user_id, ud_data) values (2, 2, 'OTHERUSER DATA'); 1 row created. 1 row created. commit; select ud_id, ud_user_id, ud_data from user_data; 2 rows selected.
CREATE OR REPLACE FUNCTION sys.scott_predicate_allow ( obj_schema IN VARCHAR2, obj_name IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN return 'ud_id in (SELECT ud_id FROM scott.user_data ud, scott.user_allowed ua WHERE ud.ud_user_id = ua.ua_id AND upper(ua.oracle_user) = upper(USER))'; END scott_predicate_allow; / Function created.
BEGIN SYS.DBMS_RLS.ADD_POLICY ( Object_schema => 'SCOTT' ,Object_name => 'USER_DATA' ,policy_name => 'SCOTT_ALLOW_USER_DATA' ,function_schema => 'SYS' ,policy_function => 'SCOTT_PREDICATE_ALLOW' ,statement_types => 'SELECT,INSERT,UPDATE,DELETE,INDEX ' ,policy_type => dbms_rls.dynamic ,long_predicate => FALSE ,sec_relevant_cols => 'UD_ID,UD_USER_ID,UD_DATA' ,sec_relevant_cols_opt => NULL ,update_check => FALSE ,enable => TRUE ); END; / PL/SQL procedure successfully completed.
select ud_id, ud_user_id, ud_data from user_data; ORA-28113: policy predicate has error
ORA-28108: circular security policies detected
create or replace type sys.number_table is table of number; / Type created. CREATE OR REPLACE PACKAGE SYS.SCOTT_ALLOWED AS allowed_id number_table:=number_table(); function get_allowed_id return number_table; END SCOTT_ALLOWED; / Package created. CREATE OR REPLACE PACKAGE BODY SYS.SCOTT_ALLOWED AS function get_allowed_id return number_table is begin return allowed_id; end; END SCOTT_ALLOWED; / Package body created. CREATE OR REPLACE FUNCTION sys.scott_predicate_allow ( obj_schema IN VARCHAR2, obj_name IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN scott_allowed.allowed_id:=number_table(); select ud_id bulk collect into scott_allowed.allowed_id from scott.user_data ud, scott.user_allowed ua where ud.ud_user_id = ua.ua_id and upper(ua.oracle_user) = upper(USER); return 'EXISTS (SELECT 1 FROM TABLE(scott_allowed.get_allowed_id) a WHERE a.column_value = ud_id)'; END scott_predicate_allow; / Function created.
select ud_id, ud_user_id, ud_data from user_data; 1 row selected.
Source: https://habr.com/ru/post/159413/
All Articles