This document discusses new architecture and security features in Oracle Database 12c. It introduces container databases (CDBs) which allow for multiple pluggable databases (PDBs). It describes how common and local users, privileges, roles, and data dictionaries are implemented and managed across CDBs and PDBs. It also covers new PL/SQL privilege checking, code-based access control, unplugging and plugging PDBs into different CDBs, cloning PDBs, and upgrading databases to 12c.
Automating Google Workspace (GWS) & more with Apps Script
Â
Database 12c
1. parallel
Architecture Changes and New Security
Features in Oracle Database 12c
Zoran PavloviÄ, Security Team Lead, Parallel
Maja Veselica, Security Consultant, Parallel
2. parallel
About the Authors
Zoran PavloviÄ, Security Team Lead
Zoran Pavlovic works for Parallel as a security team
leader. He has worked as an external instructor for
Oracle University across EMEA region. As an active
member of the Oracle community and a long-time
database security enthusiast, Zoran frequently delivers
technical presentations and demonstrations about
Oracle technologies in Serbia, Croatia, Bulgaria, and
online across the Globe. He is an Oracle Certified
Professional, Oracle Certified Expert and Oracle
Certified Specialist for Database, Security and Java.
When Zoran is not helping customers solve various
problems in Oracle Database, he enjoys learning more
about how Oracle Database works and (beta) testing
Oracle products
Twitter: @orclarchitect
3. parallel
About the Authors
Maja Veselica, Security Consultant
Maja Veselica, MSc in Software Engineering, works
for Parallel d.o.o. Belgrade, as Security Consultant and
Education Manager. She is an instructor for numerous
Oracle courses and a regular speaker at Oracle User
Group conferences (SrOUG, HrOUG, BGOUG). She
possesses several Oracle certificates, such as: Oracle
Certified Professional, Oracle Certified Expert and
Oracle Certified Specialist for Database, Security and
Java. When Maja is not helping customers solve
various challenges using Oracle technologies, she
enjoys (beta) testing Oracle products.
Twitter: @orapassion
11. parallel
Create PDB from Seed
$ sqlplus / as sysdba
SQL*Plus: Release 12.1.0.1.0 Production on Fri May 04 19:45:12 2013
Copyright (c) 1982, 2012, Oracle. All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining, Real Application Testing and
Unified Auditing options
SQL> CREATE PLUGGABLE DATABASE pdb1 ADMIN USER pdb1_admin
2 IDENTIFIED BY oracle_4U ROLES=(CONNECT)
3 FILE_NAME_CONVERT=('/u01/app/oracle/oradata/cdb1/pdbseed'
4 ,'/u01/app/oracle/oradata/cdb1/pdb1');
Pluggable database created.
cdb1
root pdb1seed Clone
12. parallel
Unplug PDB from CDB
SQL> ALTER PLUGGABLE DATABASE pdb1 UNPLUG INTO âpdb1.xmlâ;
cdb1
root seed pdb1Unplug
pdb1.xml
SQL> DROP PLUGGABLE DATABASE pdb1 KEEP DATAFILES;
pdb1
SQL> ALTER PLUGGABLE DATABASE pdb1 OPEN READ ONLY;
13. parallel
Plug Unplugged PDB in CDB
cdb2
root seed
pdb1.xml
pdb1 pdb1Plug-In
SQL> DBMS_PDB.CHECK_PLUG_COMPATIBILITY(pdb_descr_file =>
â/stage/pdb1.xmlâ, store_report => TRUE);
SQL> CREATE PLUGGABLE DATABASE pdb1 USING '/stage/pdb1.xml'
NOCOPY;
SQL> ALTER PLUGGABLE DATABASE pdb1 OPEN READ WRITE;
18. parallel
CDB
root pdb1
Common and Local Users
pdb2
c##zoransys loc_usr1 loc_usr2
c##zoran
sys
c##zoran
sys
Common users are users
created in root container,
that have same identity
across all containers.
Local users are users
that are created and exist
in only one PDB. They
canât be created in root.
19. parallel
cdb1
root pdb1
Common and Local Users
c##zoransys
mgrc##zoran
sys
SQL> CONNECT / AS SYSDBA
Connected.
SQL> CREATE USER c##zoran
IDENTIFIED BY oracle1
CONTAINER = ALL;
User created.
SQL> CONNECT
c##zoran/oracle1@pdb1
Connected.
SQL> CREATE USER mgr
IDENTIFIED BY oracle1
CONTAINER = CURRENT;
User created.
loc_usr1
Common user created by common user:
Local user created by common user:
SQL> CONNECT
mgr/oracle1@pdb1
Connected.
SQL> CREATE USER loc_usr1
IDENTIFIED BY password;
User created.
Local user created by local user:
20. parallel
CDB
root pdb1
Common and Local Privileges
pdb2
c##zoran loc_usr1c##zoran
Common privileges are
privileges, that when
granted can be exercised
across all containers.
Local privileges are
privileges, that when
granted can be exercised
in context of a single PDB.
loc_usr2c##zoran
21. parallel
cdb1
Common and Local Privileges
SQL> CONNECT / AS SYSDBA
Connected.
SQL> GRANT SELECT ANY TABLE
TO c##zoran CONTAINER = ALL;
Grant succeeded.
SQL> CONNECT
sys/oracle1@pdb1 AS
SYSDBA
Connected.
SQL> GRANT UPDATE ANY
TABLE TO c##zoran
CONTAINER = CURRENT;
Grant succeeded.
Common privilege granted by common
user to common user:
Local privilege granted by common
user to common user:
SQL> CONNECT
mgr/oracle1@pdb1
Connected.
SQL> GRANT UPDATE ANY
TABLE TO loc_usr1;
Grant succeeded.
Local privilege granted by local user
to local user:
root pdb1
c##zoran loc_usr1c##zoran
22. parallel
Common and Local Roles
Local roles are roles created in
PDB that exist in only one
container. These roles can be
granted only locally to either
common or local users or roles.
Common roles are roles created in
root container, that exist in all
containers. These roles can have
different set of privileges in different
containers, and can be granted to
either common or local users or roles.
CDB
root pdb1 pdb2
c##role1 c##role1
loc_role1
c##role1
loc_role2
23. parallel
cdb1
Adding Privs to Common and Local Roles
SQL> CREATE ROLE c##role1
CONTAINER = ALL;
Role created.
SQL> GRANT SELECT ANY TABLE TO
c##role1 CONTAINER = ALL;
Grant succeeded.
SQL> GRANT CREATE TABLE TO
c##role1;
SQL> CREATE ROLE loc_role1
CONTAINER = CURRENT;
Role created.
SQL> GRANT UPDATE ANY TABLE TO
loc_role1;
Grant succeeded.
SQL> GRANT ALTER USER TO
c##role1;
Grant succeeded.
SQL> GRANT loc_role1 TO
c##role1 CONTAINER = CURRENT;
Grant succeeded.
SQL> GRANT c##role1 TO
loc_role2 CONTAINER = CURRENT;
Grant succeeded.
root pdb1
in root container:
in pdb1 container:
24. parallel
cdb1
Granting Common and Local Roles
SQL> GRANT c##role1 to
c##zoran CONTAINER = ALL;
Grant succeeded.
SQL> GRANT c##role2 to
c##zoran CONTAINER = CURRENT;
Grant succeeded.
SQL> GRANT c##role2 to
c##zoran CONTAINER =
CURRENT;
Grant succeeded.
SQL> GRANT loc_role to
c##zoran CONTAINER =
CURRENT;
Grant succeeded.
SQL> GRANT c##role2 to
loc_usr1 CONTAINER =
CURRENT;
Grant succeeded.
GRANT loc_role to loc_usr1
CONTAINER = CURRENT;
Grant succeeded.
root pdb1
25. parallel
SQL> connect / as sysdba
Connected.
SQL> create user c##zoran identified by oracle1 container=all;
User created.
SQL> grant create session, drop any synonym to c##zoran container=all;
Grant succeeded.
SQL> connect sys/oracle1@pdb1 as sysdba
Connected.
SQL> grant drop any table to c##zoran container=current;
Grant succeeded.
SQL> connect c##zoran/oracle1@pdb1
Connected.
SQL> drop synonym customers_syn;
Synonym dropped.
SQL> drop table gldb.customers;
Table dropped.
SQL> connect c##zoran/oracle1@pdb2
Connected.
SQL> drop synonym test_syn;
Synonym dropped.
SQL> drop table test.a;
drop table test.a
*
ERROR at line 1:
ORA-00942: table or view does not exist
27. parallel
SQL> connect zoran/oracle1
Connected.
SQL> create user maja identified by oracle1;
User created.
SQL> grant create session, create procedure to maja;
Grant succeeded.
SQL> connect maja/oracle1;
Connected.
SQL> select * from session_roles;
No rows selected.
SQL> create or replace procedure evil_proc
3 authid current_user
4 as
5 pragma autonomous_transaction;
6 begin
9 execute immediate 'grant dba to majaâ;
10 end;
11 /
Procedure created.
SQL> grant execute on evil_proc to zoran;
Grant succeeded.
SQL> connect zoran/oracle1
Connected.
SQL> exec maja.evil_proc;
29. parallel
SQL> connect c##zoran/oracle1@pdb1
Connected.
SQL> create user maja identified by oracle1 container=current;
User created.
SQL> grant create session, create procedure to maja container=current;
Grant succeeded.
SQL> connect maja/oracle1@pdb1;
Connected.
SQL> select * from session_roles;
No rows selected.
SQL> create or replace procedure evil_proc
3 authid current_user
4 as
5 pragma autonomous_transaction;
6 begin
9 execute immediate 'grant dba to majaâ;
10 end;
11 /
Procedure created.
SQL> grant execute on evil_proc to c##zoran;
Grant succeeded.
SQL> connect c##zoran/oracle1@pdb1
Connected.
SQL> exec maja.evil_proc;
30. parallel
SQL> exec maja.evil_proc;
ERROR at line 1:
ORA-06598: insufficient INHERIT PRIVILEGES privilege
ORA-06512: at âMAJA.EVIL_PROC", line 1
ORA-06512: at line 1
SQL> grant inherit privileges on user c##zoran to maja;
Grant succeeded.
SQL> exec maja.evil_proc;
PL/SQL procedure successfully completed.
SQL> connect maja/oracle1
Connected.
SQL> select * from session_roles;
ROLE
------------------------------
DBA
SELECT_CATALOG_ROLE
...
19 rows selected.
Inherit Privileges
31. parallel
New PL/SQL Privilege Checking
SQL> create or replace procedure evil_proc
2 authid current_user
3 as
4 pragma autonomous_transaction;
5 begin
6 execute immediate 'grant dba to majaâ;
7 end;
8 /
maja
c##zoran
32. parallel
New PL/SQL Privilege Checking
SQL> create or replace procedure evil_proc
2 authid current_user
3 as
4 pragma autonomous_transaction;
5 begin
6 execute immediate 'grant dba to majaâ;
7 end;
8 /
maja
c##zoran
SQL> GRANT EXECUTE ON MAJA.EVIL_PROC TO
c##zoran;
33. parallel
New PL/SQL Privilege Checking
SQL> create or replace procedure evil_proc
2 authid current_user
3 as
4 pragma autonomous_transaction;
5 begin
6 execute immediate 'grant dba to majaâ;
7 end;
8 /
maja
c##zoran
EXECUTE
34. parallel
New PL/SQL Privilege Checking
EXECUTE
ERROR at line 1:
ORA-06598: insufficient INHERIT PRIVILEGES privilege
ORA-06512: at âmaja.evil_proc", line 1
ORA-06512: at line 1
maja
c##zoran
SQL> create or replace procedure evil_proc
2 authid current_user
3 as
4 pragma autonomous_transaction;
5 begin
6 execute immediate 'grant dba to majaâ;
7 end;
8 /
35. parallel
New PL/SQL Privilege Checking
SQL> GRANT INHERIT PRIVILEGES ON USER c##zoran TO
maja;
maja
c##zoran
SQL> create or replace procedure evil_proc
2 authid current_user
3 as
4 pragma autonomous_transaction;
5 begin
6 execute immediate 'grant dba to majaâ;
7 end;
8 /
36. parallel
New PL/SQL Privilege Checking
EXECUTE
maja
SQL> create or replace procedure evil_proc
2 authid current_user
3 as
4 pragma autonomous_transaction;
5 begin
6 execute immediate 'grant dba to majaâ;
7 end;
8 /
c##zoran
38. parallel
SQL> connect zoran/oracle1
Connected.
SQL> create user mike identified by oracle1;
User created.
SQL> create role proc_role;
Role created.
SQL> grant create session, create procedure, create table to proc_role;
Grant succeeded.
SQL> grant proc_role to mike;
Grant succeeded.
SQL> connect mike/oracle1
Connected.
SQL> create or replace procedure c_table
2 as
3 begin
4 execute immediate âcreate table test(a int)â;
5 end;
6 /
Procedure created.
SQL> exec c_table;
Code Based Access Control
39. parallel
SQL> exec c_table;
BEGIN c_table; END;
*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at âMIKE.C_TABLE", line 4
ORA-06512: at line 1
Code Based Access Control
40. parallel
SQL> connect c##zoran/oracle1@pdb1
Connected.
SQL> create user mike identified by oracle1 container=current;
User created.
SQL> create role proc_role container=current;
Role created.
SQL> grant create session, create procedure, create table to proc_role;
Grant succeeded.
SQL> grant proc_role to mike;
Grant succeeded.
SQL> connect mike/oracle1@pdb1
Connected.
SQL> create or replace procedure c_table
2 as
3 begin
4 execute immediate âcreate table test(a int)â;
5 end;
6 /
Procedure created.
SQL> exec c_table;
Code Based Access Control
41. parallel
SQL> exec c_table;
BEGIN c_table; END;
*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at âMIKE.C_TABLE", line 4
ORA-06512: at line 1
SQL> grant proc_role to procedure c_table;
Grant succeeded.
SQL> exec c_table;
PL/SQL procedure successfully completed.
SQL> desc test
Name Null? Type
----------------- -------- ------------
A NUMBER(38)
Code Based Access Control
42. parallel
SQL> connect c##zoran/oracle1@pdb1
Connected.
SQL> create or replace procedure test
2 authid current_user
3 as
4 begin
5 execute immediate âcreate table tjohn(z int)â;
6 end;
7 /
Procedure created.
SQL> create user john identified by oracle1 container=current;
User created.
SQL> grant create session to john;
Grant succeeded.
SQL> create role test_role container=current;
Role created.
SQL> grant create table to test_role;
Grant succeeded.
SQL> grant test_role to procedure test;
Grant succeeded.
SQL> grant execute on test to john;
Grant succeeded.
Code Based Access Control
43. parallel
SQL> connect john/oracle1@pdb1
Connected.
SQL> exec c##zoran.test;
PL/SQL procedure successfully completed.
SQL> desc tjohn
Name Null? Type
----------------- -------- ------------
Z NUMBER(38)
Code Based Access Control
45. parallel
Data Redaction - Full
DBMS_REDACT.ADD_POLICY
(object_schema => âGLDBâ,
object_name => âCUSTOMERSâ,
policy_name => âCCN_POLICY',
column_name => âCREDIT_CARD',
function_type => DBMS_REDACT.FULL,
expression => â7=7');
NAME CREDIT_CARD
tom 3455647456589132
mike 3734982321225691
john 3472586894975806
CUSTOMERS
NAME CREDIT_CARD
tom 0
mike 0
john 0
SQL> SELECT * FROM CUSTOMERS;
46. parallel
Data Redaction - Partial
DBMS_REDACT.ADD_POLICY
(object_schema => âGLDBâ,
object_name => âCUSTOMERSâ,
policy_name => âCCN_POLICY',
column_name => âCREDIT_CARD',
function_type => DBMS_REDACT.PARTIAL,
function_parameters => 'VVVVVVVVVVVVVVVV,
VVVV-VVVV-VVVV-VVVV, #,1,12â
expression => â7=7');
NAME CREDIT_CARD
tom 3455647456589132
mike 3734982321225691
john 3472586894975806
CUSTOMERS
SQL> SELECT * FROM CUSTOMERS;
NAME CREDIT_CARD
tom ####-####-####-9132
mike ####-####-####-5691
john ####-####-####-5806
47. parallel
Data Redaction - Exemptions
DBMS_REDACT.ADD_POLICY
(object_schema => âGLDBâ,
object_name => âCUSTOMERSâ,
policy_name => âCCN_POLICY',
column_name => âCREDIT_CARD',
function_type =>
DBMS_REDACT.FULL,
expression => â7=7');
NAME CREDIT_CARD
tom 3455647456589132
mike 3734982321225691
john 3472586894975806
CUSTOMERS
RMAN> BACKUP TABLESPACE gltbs;
NAME CREDIT_CARD
tom 3455647456589132
mike 3734982321225691
john 3472586894975806
48. parallel
Data Redaction - Exemptions
DBMS_REDACT.ADD_POLICY
(object_schema => âGLDBâ,
object_name => âCUSTOMERSâ,
policy_name => âCCN_POLICY',
column_name => âCREDIT_CARD',
function_type => DBMS_REDACT.FULL,
expression => â7=7');
NAME CREDIT_CARD
tom 3455647456589132
mike 3734982321225691
john 3472586894975806
CUSTOMERS
NAME CREDIT_CARD
tom 3455647456589132
mike 3734982321225691
john 3472586894975806
SQL> SELECT * FROM CUSTOMERS;
User with EXEMPT REDUCTION POLICY
49. parallel
SQL> connect c##zoran/oracle1@pdb1
Connected.
SQL> BEGIN
2 DBMS_REDACT.ADD_POLICY (object_schema => âGLDBâ,
3 object_name => âCUSTOMERSâ,
4 policy_name => âCCN_POLICY',
5 column_name => âCREDIT_CARD',
6 function_type => DBMS_REDACT.PARTIAL,
7 function_parameters => 'VVVVVVVVVVVVVVVV, VVVV-VVVV-VVVV-VVVV,
#,1,12â
8 expression => â7=7');
9 END;
10 /
PL/SQL procedure successfully completed.
SQL> select * from gldb.customers;
NAME CREDIT_CARD
---------------- --------------------
tom 3455647456589132
mike 3734982321225691
john 3472586894975806
SQL> grant select on gldb.customers to maja;
Grant succeeded.
Data Redaction - Example
50. parallel
SQL> connect maja/oracle1@pdb1
Connected.
SQL> select * from gldb.customers;
NAME CREDIT_CARD
---------------- --------------------
tom ####-####-####-9132
mike ####-####-####-5691
john ####-####-####-5806
SQL> select * from gldb.customers where credit_card like â3472%â;
NAME CREDIT_CARD
---------------- --------------------
john ####-####-####-5806
Data Redaction - Example
51. parallel
None
âą Reduction is
NOT
applied
Full
âą Columns
are
redacted to
constant
values
depending
on column
data type
Partial
âą User-
specified
positions
are replaced
by a user-
specified
character
Regular
Expression
âą Pattern for
matching
and
replacing is
defined and
used for
reduction
Random
âą Preserves
data types
âą Randomizes
output
Available Reduction Types
53. parallel
New Administrative Privileges
PRIVILEGE USERNAME DUTIES
SYSBACKUP SYSBACKUP
Backup and
recovery
operations in
RMAN and SQL.
SYSDG SYSDG
Managing Data
Guard with Data
Guard Broker.
SYSKM SYSKM
Managing keys for
TDE.
Password file
format_12c
54. parallel
New SYSBACKUP Privilege
SQL> connect / as SYSBACKUP
Connected.
SQL> show user
USER is "SYSBACKUP"
SQL> select * from session_privs;
PRIVILEGE
----------------------------------------
SYSBACKUP
SELECT ANY TRANSACTION
SELECT ANY DICTIONARY
RESUMABLE
CREATE ANY DIRECTORY
ALTER DATABASE
AUDIT ANY
CREATE ANY CLUSTER
CREATE ANY TABLE
UNLIMITED TABLESPACE
DROP TABLESPACE
ALTER TABLESPACE
ALTER SESSION
ALTER SYSTEM
14 rows selected.
SQL>
55. parallel
New SYSBACKUP Privilege
$ rman target ââzoran/passwd@orcldb AS SYSBACKUP"â
Recovery Manager: Release 12.1.0.1.0 - Beta on Tue
May 07 17:41:37 2013
Copyright (c) 1982, 2012, Oracle and/or its
affiliates. All rights reserved. connected to
target database: ORCLDB (DBID=1625181741)
RMAN> select user from dual;
using target database control file instead of
recovery catalog
USER
------------------------------
SYSBACKUP
RMAN>
SQL> connect / as SYSBACKUP
Connected.
SQL> SELECT TABLE_NAME FROM DBA_TABLES
2 WHERE OWNER = âGLDBâ;
TABLE_NAME
----------------------------------------
CUSTOMERS
ORDERS
SQL> SELECT * FROM GLDB.CUSTOMERS;
SELECT * FROM GLDB.CUSTOMERS
*
ERROR at line 1:
ORA-01031: insufficient privileges
56. parallel
New SYSDG Privilege
SQL> connect / as SYSDG
Connected.
SQL> show user
USER is âSYSDG"
SQL> select * from session_privs;
PRIVILEGE
---------------------------------------
-
SYSDG
ALTER SYSTEM
ALTER SESSION
ALTER DATABASE
SELECT ANY DICTIONARY
5 rows selected.
SQL>
57. parallel
New SYSKM Privilege
SQL> connect / as SYSKM
Connected.
SQL> show user
USER is âSYSKM"
SQL> select * from session_privs;
PRIVILEGE
----------------------------------------
SYSKM
ADMINISTER KEY MANAGEMENT
2 rows selected.
SQL>
59. parallel
Invisible columns
SQL> create table t(a int);
Table created.
SQL> desc t
Name Null? Type
----------------- -------- ------------
A NUMBER(38)
SQL> insert into t(a) values(1);
1 rows inserted.
SQL> alter table add(b int invisible);
Table altered.
SQL> desc t
Name Null? Type
----------------- -------- ------------
A NUMBER(38)
SQL> select * from t;
A
------------
1
60. parallel
SQL> insert into t(a,b) values(3,5);
1 rows inserted.
SQL> select a,b from t;
A B
------------ -------------
1
3 5
SQL> alter table t modify(b visible);
Table altered.
SQL> desc t
Name Null? Type
----------------- -------- ------------
A NUMBER(38)
B NUMBER(38)
Invisible columns