This is a continuation of my previous post about VPD.
The requirement: I have a table like
All set!. Time to test the VPD.
So, No email is visible!
Anything less than 20 in id_col is can not be updated.
The requirement: I have a table like
test_vpd (id_col INTEGER, name_col VARCHAR2(30),contact_no NUMBER,
email VARCHAR2(50), city VARCHAR2(50))
The user JAMES can not view any email address and also, He can not modify any rows where id_col is less than 20.
oracle@ubuntu-desktop:~$ sqlplus / as sysdba SQL*Plus: Release 10.2.0.1.0 - Production on Wed Jul 27 16:13:34 2011 Copyright (c) 1982, 2005, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options SQL> /* Granting scott, the owner of the table a create contetx privilege */ SQL> GRANT CREATE ANY CONTEXT TO scott; Grant succeeded.
Now, It's time to create the table and some sample data with SCOTT user.
SQL> /* Creating a conetxt */
SQL> CREATE OR REPLACE CONTEXT saubhik_test_context USING test_vpd_pkg;
Context created.
SQL> CREATE TABLE test_vpd (id_col INTEGER, name_col VARCHAR2(30),contact_no NUMBER, email VARCHAR2(50), city VARCHAR2(50));
Table created.
SQL> ed
Wrote file afiedt.buf
1 INSERT INTO test_vpd SELECT rownum,initcap(substr(object_name,1,30)),object_id,owner||'@mail.com',object_type
2 FROM all_objects
3* WHERE rownum<50 data-blogger-escaped-sql=""> /
49 rows created.
SQL> commit;
Commit complete.
SQL> set line 180
SQL> SELECT * FROM test_vpd;
ID_COL NAME_COL CONTACT_NO EMAIL CITY
---------- ------------------------------ ---------- -------------------------------------------------- --------------------------------------------------
1 Dual 258 SYS@mail.com TABLE
2 Dual 259 PUBLIC@mail.com SYNONYM
3 System_Privilege_Map 311 SYS@mail.com TABLE
4 System_Privilege_Map 313 PUBLIC@mail.com SYNONYM
5 Table_Privilege_Map 314 SYS@mail.com TABLE
6 Table_Privilege_Map 316 PUBLIC@mail.com SYNONYM
7 Stmt_Audit_Option_Map 317 SYS@mail.com TABLE
8 Stmt_Audit_Option_Map 319 PUBLIC@mail.com SYNONYM
9 Ol$ 452 OUTLN@mail.com TABLE
10 Ol$Hints 453 OUTLN@mail.com TABLE
11 Ol$Nodes 456 OUTLN@mail.com TABLE
ID_COL NAME_COL CONTACT_NO EMAIL CITY
---------- ------------------------------ ---------- -------------------------------------------------- --------------------------------------------------
12 Map_Object 604 SYS@mail.com TABLE
13 Map_Object 605 PUBLIC@mail.com SYNONYM
14 Re$Nv_List 886 SYS@mail.com TYPE
15 Standard 887 SYS@mail.com PACKAGE
16 Dbms_Standard 889 SYS@mail.com PACKAGE
17 Dbms_Standard 890 PUBLIC@mail.com SYNONYM
18 V_$Map_Library 900 SYS@mail.com VIEW
19 V$Map_Library 901 PUBLIC@mail.com SYNONYM
20 V_$Map_File 902 SYS@mail.com VIEW
21 V$Map_File 903 PUBLIC@mail.com SYNONYM
22 V_$Map_File_Extent 904 SYS@mail.com VIEW
.............................................................................................................................................................................
...............................................................................................................................................
Now, It's time to write a package to setup the VPD from scott
SQL> ed
Wrote file afiedt.buf
1 CREATE OR REPLACE
2 PACKAGE test_vpd_pkg
3 AS
4 --This procedure sets the application context.
5 --------------------------------------------
6 PROCEDURE set_app_context;
7 --This function builds the predicate (the where caluse).
8 --------------------------------------------------------
9 --This where caluse filters the rows and determines which can be accessed.
10 -----------------------------------------------------------------------
11 --Two parameters pi_schema and pi_name is NOT used anywhere, still those are mandetory!
12 FUNCTION the_predicate1(
13 pi_schema IN VARCHAR2,
14 pi_name IN VARCHAR2)
15 RETURN VARCHAR2;
16 FUNCTION the_predicate2(
17 pi_schema IN VARCHAR2,
18 pi_name IN VARCHAR2)
19 RETURN VARCHAR2;
20* END test_vpd_pkg;
21 /
Package created.
SQL> ed
Wrote file afiedt.buf
1 CREATE OR REPLACE
2 PACKAGE BODY test_vpd_pkg
3 AS
4 c_context_name VARCHAR2(30):= 'saubhik_test_context';
5 c_attribute_name VARCHAR2(30):= 'ID_COL';
6 PROCEDURE set_app_context
7 IS
8 v_user_name VARCHAR2(30);
9 BEGIN
10 SELECT USER INTO v_user_name FROM dual;
11 DBMS_SESSION.SET_CONTEXT (namespace=>c_context_name, attribute=>c_attribute_name,value=>v_user_name);
12 END set_app_context;
13 FUNCTION the_predicate1(
14 pi_schema IN VARCHAR2,
15 pi_name IN VARCHAR2)
16 RETURN VARCHAR2
17 IS
18 v_context_value VARCHAR2(200):=SYS_CONTEXT(c_context_name,c_attribute_name);
19 v_restriction VARCHAR2(2000);
20 BEGIN
21 IF v_context_value = 'JAMES' THEN
22 v_restriction:= ' ID_COL > 20';
23 ELSE
24 v_restriction:= NULL;
25 END IF;
26 RETURN v_restriction;
27 END the_predicate1;
28 FUNCTION the_predicate2(
29 pi_schema IN VARCHAR2,
30 pi_name IN VARCHAR2)
31 RETURN VARCHAR2
32 IS
33 v_context_value VARCHAR2(200):=SYS_CONTEXT(c_context_name,c_attribute_name);
34 v_restriction VARCHAR2(2000);
35 BEGIN
36 IF v_context_value = 'JAMES' THEN
37 v_restriction:= ' 1=2';
38 ELSE
39 v_restriction:= NULL;
40 END IF;
41 RETURN v_restriction;
42 END the_predicate2;
43* END test_vpd_pkg;
44 /
Package body created.
SQL>
Now, add the policy, and a logon trigger for JAMES from sys.SQL> BEGIN
DBMS_RLS.ADD_POLICY ( OBJECT_SCHEMA => 'SCOTT'
,OBJECT_NAME => 'TEST_VPD'
,POLICY_NAME => 'TEST_VPD_POLICY1'
,FUNCTION_SCHEMA => 'SCOTT'
,POLICY_FUNCTION => 'TEST_VPD_PKG.THE_PREDICATE1'
,STATEMENT_TYPES =>'UPDATE, DELETE' --You can add select also if required.
,UPDATE_CHECK => FALSE
,ENABLE => TRUE
);
END; 2 3 4 5 6 7 8 9 10 11
12 /
PL/SQL procedure successfully completed.
SQL> BEGIN
DBMS_RLS.ADD_POLICY ( OBJECT_SCHEMA => 'SCOTT'
,OBJECT_NAME => 'TEST_VPD'
,POLICY_NAME => 'TEST_VPD_POLICY2'
,FUNCTION_SCHEMA => 'SCOTT'
,POLICY_FUNCTION => 'TEST_VPD_PKG.THE_PREDICATE2'
,SEC_RELEVANT_COLS=>'EMAIL'
,SEC_RELEVANT_COLS_OPT=>dbms_rls.ALL_ROWS
,UPDATE_CHECK => FALSE
,ENABLE => TRUE
);
END; 2 3 4 5 6 7 8 9 10 11 12
13 /
PL/SQL procedure successfully completed.
SQL>
SQL> ed
Wrote file afiedt.buf
1 CREATE OR REPLACE TRIGGER test_vpd_trig
2 AFTER LOGON ON DATABASE
3 BEGIN
4 SCOTT.test_vpd_pkg.set_app_context;
5* END;
6 /
Trigger created.
SQL> CREATE USER JAMES IDENTIFIED BY james;
User created.
SQL> GRANT connect, resource to james;
Grant succeeded.
SQL> GRANT select,update,delete on scott.test_vpd to james;
Grant succeeded.
SQL>
All set!. Time to test the VPD.
oracle@ubuntu-desktop:~$ sqlplus james/james
SQL*Plus: Release 10.2.0.1.0 - Production on Wed Jul 27 18:41:21 2011
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> SET line 200
SQL> SELECT * FROM scott.test_vpd;
ID_COL NAME_COL CONTACT_NO E CITY
---------- ------------------------------ ---------- - --------------------------------------------------
1 Dual 258 TABLE
2 Dual 259 SYNONYM
3 System_Privilege_Map 311 TABLE
4 System_Privilege_Map 313 SYNONYM
5 Table_Privilege_Map 314 TABLE
6 Table_Privilege_Map 316 SYNONYM
7 Stmt_Audit_Option_Map 317 TABLE
8 Stmt_Audit_Option_Map 319 SYNONYM
9 Ol$ 452 TABLE
10 Ol$Hints 453 TABLE
11 Ol$Nodes 456 TABLE
So, No email is visible!
SQL> ed Wrote file afiedt.buf 1 UPDATE scott.test_vpd 2 SET name_col='Saubhik' 3* WHERE id_col=1 SQL> / 0 rows updated. SQL> ed Wrote file afiedt.buf 1 UPDATE scott.test_vpd 2 SET name_col='Saubhik' 3* WHERE id_col=21 SQL> / 1 row updated. SQL> ed Wrote file afiedt.buf 1 UPDATE scott.test_vpd 2 SET name_col='Saubhik' 3* WHERE id_col=20 SQL> / 0 rows updated. SQL>
Anything less than 20 in id_col is can not be updated.