Database’ in güvenliğinin sağlanması için belirli periyotlar arasında şirketlerin güvenlik birimleri aracılığıyla (özellikle bankalar bu konuda en hassas olan kurumlardır) database’ deki kullanıcıların yetkileri sorgulanır ve fazla olduğu düşünülen yetkilerin revoke edilmesi istenir. Ancak production sistemlerde yetki almak kimi aman çokda kolay olmamaktadır. Yetki revoke edildiğinde uygulamanın bu durumdan etkilenip etkilenmeyeceği, ilgili user tarafından bu yetkinin kullanılıp kullanılmadığı tam olarak kestirilemediği durumlar olabiliyor. Hal böyle oluncada yetkiyi revoke etmeye cesaret edilemediği durumlar yaşanmıyor değil 
Oracle 12c ile birlikte aslında bu soruna cevap bulunmuş oldu. Dbms_privilege_capture paketi ile kullanılan user hangi yetkinin kullanıldığını capture eden faydalı bir package’ dir. Privilege kullanıldığı zaman capture edildiğinden dolayı bu paket aracılığıyla toplanan yetkiler kullanılan yetkiler olarak yorumlanmalıdır.
Şimdi bu işlemi nasıl yapabileceğimiz den ve dbms_capture_privilege paketinin kullanımından bahsedelim.
DBMS_PRIVILEGE_CAPTURE paketinin spec’ ine baktığınız da 5 adet procedureden oluştuğunu görebilirsiniz.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | CREATE OR REPLACE PACKAGE SYS.dbms_privilege_capture AS  -- Capture Types   g_database            CONSTANT NUMBER := 1;   g_role                CONSTANT NUMBER := 2;   g_context             CONSTANT NUMBER := 3;   g_role_and_context    CONSTANT NUMBER := 4;   PROCEDURE create_capture(     name            IN  VARCHAR2,     description     IN  VARCHAR2 DEFAULT NULL,     type            IN  NUMBER DEFAULT G_DATABASE,     roles           IN  role_name_list DEFAULT role_name_list(),     condition       IN  VARCHAR2   DEFAULT NULL);   PROCEDURE drop_capture(name  IN VARCHAR2);   PROCEDURE enable_capture(name  IN VARCHAR2);   PROCEDURE disable_capture(name IN VARCHAR2);   PROCEDURE generate_result(name IN VARCHAR2); END; / | 
Procedurelerin nasıl kullanılacağına geçmeden önce bu procedurelerin ne amaçla kullanıldığından sonrasında da özellikle create_capture procedurundaki input ların neler olduğuna bakalım.
•	Create  Capture :
Analiz edilmek için privilege ilgili olarak spesifik bir takım conditionlar da belirtilerek policy’ nin create edilmesini sağlar. 
Policy create edlirken input olarak belirlenmesi gereken bazı alanlar bulunmaktadır ;
Name : Oluşturulması istenilen policy’ e verilecek olan ismi ifade eder. 30 karakter uzunluğunda istediğiniz ismi verebilirsiniz.
Description : Oluşturulacak olan policy ile (varsa) açıklama girebileceğiniz alandır. 1024 karaktere kadar bu alana açıklama yazabilirsiniz.
Type : Privilege analizi ile ilgili oractle tarafından belirlenmiş olan 4 farklı type bulunmaktadır. Dolayısıyla policy oluşturmak istediğiniz de bu 4 adet policy’ den size en uygun olanı seçmek durumundasınız. Bu type’ ların ne olduğuna bakalım ;
G_DATABASE : Database içerisinde kullanılan tüm privilege’ ları capture etmek istediğiniz de bunu kullanabilirsiniz. SYS userı kapsam dışıdır. SYS’ nin kullandığı privilege’ ları capture edemezsiniz.
G_ROLE : Spesifik bir role veya rol içerisindeki bir privilege capture edilmek istenildiğinde bu type’ ı kullanabilirsiniz.
G_CONTEXT : Condition parametresi ile spesifik olarak bir koşul belirlenmiş olan privilege’ lerin capture edilmesini sağlar.
G_ROLE_AND_CONTEXT : G_role ve g_context’ in birleşimini ifade etmektedir. Capture edilmek istenilen privilege bir role içerisindeyse ve condition parametresi ile spesifik bir koşula göre capture edilmek isteniyorsa bu type ‘ ı kullanabiliriz.
Roles : Spesifik olarak capture edilmek istenilen rollerin tanımlandığı kısım.
Condition : Capture edilecek olan role ile ilgili spesifik olarak koşulların tanımlandığı kısım.
•	Enable Capture :
Create edilen procedure’ un aktivite edilmesini sağlar. Policy ‘ in enable edilmesinden sonra policy yetkileri capture etmeye başlayacaktır. 
•	Disable Capture :
Create edilen policy’ nin disable edilerek capture işleminin stop edilmesini sağlar. 
•	Drop Capture: 
Create edilmiş olan policy’ nin drop edilmesini sağlar. 
•	Generate Result :
Oluşturulan policy ile birlikte capture edilen yetkilerin ilgili view’ ler aracılığıyla görüntülenmesini sağlar. 
DBMS_PRIVILEGE_CAPTURE İle İlgili performans Viewleri
Dbms_privilege_capture paketi ile kullanılan yetkilerin caprure edilmesi sonrasında generate_result ile aşağıdaki listede belirtilmiş olan view’ lerden sonuçları gözlemleyebilirsiniz. Toplamda 16 adet bu amaçla kullanabileceğimiz view bulunmaktadır. Kulanılan yetkiler, kullanımayan yetkiler, system yetkileri, object yetkileri vs gibi bilgiler için ayrı ayrı viewler oluşturulmuştur. Reference kısmında belirtmiş olduğum oracle dökümanından bu viewler ile ilgili detaylı bilgiye ulaşabilirsiniz. Aşağıdaki örnek de de viewlerin bir kısmının ne için kullanıldığını örnek üzerinden açıklamaya çalıştım.
DBA_PRIV_CAPTURES
DBA_USED_OBJPRIVS
DBA_USED_OBJPRIVS_PATH
DBA_USED_PRIVS
DBA_USED_PUBPRIVS
DBA_USED_SYSPRIVS
DBA_USED_SYSPRIVS_PATH
DBA_USED_USERPRIVS
DBA_USED_USERPRIVS_PATH
DBA_UNUSED_OBJPRIVS
DBA_UNUSED_OBJPRIVS_PATH
DBA_UNUSED_PRIVS
DBA_UNUSED_SYSPRIVS
DBA_UNUSED_SYSPRIVS_PATH
DBA_UNUSED_USERPRIVS
DBA_UNUSED_USERPRIVS_PATH
Dbms_privilege_capture paketinin kullanımı ile ilgili örneklere bakalım. Burada örnek olarak bir durumu uçtan uca test edelim ancak sonrasında paketin kullanımı ile ilgili farklı örnekleride script olarak veriyor olacağım.
Bir örnek ile devam edelim ;
Databasede kullanılan tüm yetkileri capture etmeye çalışalım ;
| 1 2 3 4 5 6 7 | ===> BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE(         name         => 'full_priv_used_auditing',         description  => 'Databasasedeki tum yetkileri capture edelim',         type         => DBMS_PRIVILEGE_CAPTURE.G_DATABASE); END;  PL/SQL procedure successfully completed. | 
Oluşturmuş olduğumuz policy’ i enable ederek capture işlemini başlatalım ;
| 1 2 3 4 | ===> begin  DBMS_PRIVILEGE_CAPTURE.ENABLE_CAPTURE ('full_priv_used_auditing'); end;  PL/SQL procedure successfully completed. | 
Şimdi sample işlemler yapalım farklı userlar ile ;
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | [SID=dbatest:oracle@Rhel70 ~]$ sqlplus / as sysdba  SQL*Plus: Release 12.1.0.2.0 Production on Thu Feb 25 13:51:17 2016 Copyright (c) 1982, 2014, Oracle.  All rights reserved. Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options SQL> select name from v$pdbs; NAME ------------------------------ PDB$SEED PLUG1_DB SQL> alter session set container =dbatest_plug2_db; Session altered. SQL> conn kamil/kamil@plug1_db; Connected. SQL> select count(*) from dba_tables;    COUNT(*) ----------       2350 SQL> create table capture_test as select * from dba_tables;  Table created. SQL> drop table capture_test ; Table dropped. SQL> create user test identified by test ; User created. SQL> grant resource , dba , unlimited tablespace to test ; Grant succeeded. SQL> create table test.a1 as select * from dba_tables ; Table created. SQL> drop table test.a1;  Table dropped. SQL> conn test/test@plug1_db; Connected. SQL> select count (*) from v$session;   COUNT(*) ----------         63 SQL> grant export full database to kamil; Grant succeeded. SQL> revoke  export full database from kamil; Revoke succeeded. SQL> create table a2 as select * from dba_tables ; Table created. SQL> create index kamil.indx_a2_1 on test.a2 (owner); Index created. SQL>  create index kamil.indx_a2_2 on test.a2 (table_name ); Index created. SQL> drop index kamil.indx_a2_2; Index dropped. | 
Policy’ imizi disable edelim. Artık capture etme işlemini durdurabiliriz.
| 1 2 3 4 | ===> begin  DBMS_PRIVILEGE_CAPTURE.DISABLE_CAPTURE ('full_priv_used_auditing'); end;  PL/SQL procedure successfully completed. | 
Şimdi raporu generate edelim ;
| 1 2 3 4 | ===> begin  DBMS_PRIVILEGE_CAPTURE.GENERATE_RESULT  ('full_priv_used_auditing'); end;  PL/SQL procedure successfully completed. | 
Şimdide yukarıda belirttiğimiz viewleri kontrol edelim, hangi policy’ lerimiz var, hangi yetkiler kim tarafından kullanılmış vs.
Database’ de oluşturulmuş olan policy’ leri select etmek için ;
| 1 2 3 4 5 6 7 8 9 10 11 | ===> column name format a25 ===> column DESCRIPTION format a45 ===> column TYPE format a8 ===> select name, description, type, enabled from DBA_PRIV_CAPTURES NAME                      DESCRIPTION                                   TYPE     ENABLED ------------------------- --------------------------------------------- -------- ------- full_priv_used_auditing   Databasasedeki tum yetkileri capture edelim   DATABASE N ORA$DEPENDENCY                                                          DATABASE N 2 rows selected. | 
Database’ de hangi object yetkilerinin kullanıldığını görmek için ;
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ===> column username format a8 ===> column used_role format a13 ===> column OBJ_PRIV format a8 ===> column OBJECT_OWNER format a12 ===> column OBJECT_NAME format a11 ===> column object_type format a11 ===> select username, used_role, obj_priv, object_owner, object_name,         object_type from DBA_USED_OBJPRIVS where username in ('KAMIL','TEST') USERNAME USED_ROLE     OBJ_PRIV OBJECT_OWNER OBJECT_NAME OBJECT_TYPE -------- ------------- -------- ------------ ----------- ----------- KAMIL    PUBLIC        SELECT   SYS          DUAL        TABLE KAMIL    PUBLIC        EXECUTE  SYS          DBMS_OUTPUT PACKAGE KAMIL    PUBLIC        SELECT   SYS          NLS_SESSION VIEW KAMIL    CAPTURE_ADMIN EXECUTE  SYS          DBMS_PRIVIL PACKAGE 4 rows selected. | 
Userın yetkisi olupda kullanılmayan object yetkileri select etmek için ;
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ===> column username format a8 ===> column capture format a13 ===> column OBJ_PRIV format a8 ===> column OBJECT_OWNER format a12 ===> column OBJECT_NAME format a11 ===> select capture, username, obj_priv, object_owner,object_name  from DBA_UNUSED_OBJPRIVS where username in ('KAMIL','TEST') CAPTURE       USERNAME OBJ_PRIV OBJECT_OWNER OBJECT_NAME ------------- -------- -------- ------------ ----------- full_priv_use KAMIL    SELECT   SYS          PDB_ALERTS full_priv_use KAMIL    SELECT   SYS          V_$DIAG_HM_ full_priv_use KAMIL    SELECT   SYS          V_$DIAG_AMS ... ... ... | 
User üzerinde olup da kullanılmayan role ve system yetkilerini select etmek için ;
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ===> column username format a8 ===> column capture format a13 ===> column ROLENAME format a10 ===> column SYS_PRIV format a35 ===> select capture,username,ROLENAME,SYS_PRIV from DBA_UNUSED_SYSPRIVS       where username in ('KAMIL','TEST') CAPTURE       USERNAME ROLENAME   SYS_PRIV                            ------------- -------- ---------- ----------------------------------- full_priv_use KAMIL               CREATE PLUGGABLE DATABASE full_priv_use KAMIL               DROP ROLLBACK SEGMENT full_priv_use KAMIL               CREATE TABLE full_priv_use KAMIL               CREATE ANY CLUSTER full_priv_use KAMIL               CREATE PROCEDURE full_priv_use KAMIL               CREATE ANY PROCEDURE full_priv_use KAMIL               EXECUTE ANY PROCEDURE ... ... | 
Analiz edilen policy içerisinde kullanılmayan yetkileri system privilege grant pathleri ile birlikte listelemek için ;
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ===> column username format a10 ===> column capture format a13 ===> column SYS_PRIV format a20 ===> column PATH format a20 ===> select capture, username, sys_priv, path  from DBA_UNUSED_SYSPRIVS_PATH  where username in ('KAMIL','TEST') CAPTURE       USERNAME   SYS_PRIV             PATH                 ------------- ---------- -------------------- -------------------- full_priv_use KAMIL      CREATE INDEXTYPE     PATH(KAMIL,RESOURCE; full_priv_use KAMIL      CREATE OPERATOR      PATH(KAMIL,RESOURCE; full_priv_use KAMIL      CREATE TYPE          PATH(KAMIL,RESOURCE; full_priv_use KAMIL      CREATE TRIGGER       PATH(KAMIL,RESOURCE; ... ... | 
Bu şekilde kritik bir userdan bir yetkiyi almadan önce bir süre izleyerek hangi yetkileri kullandığından emin olabilirsiniz.
Policy create ederken condition olarak neler verebiliriz onunla ilgili bikaç örnek verelim;
Spesifik bir role ün kullanımını izlemek istersek ;
| 1 2 3 4 5 6 7 8 | ===> BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE(        name         => 'capture_dba_role_used',        description  => 'PUBLIC rolünde nelerin kim tarafından kullanılıyor',        type         => DBMS_PRIVILEGE_CAPTURE.G_ROLE,        roles        => role_name_list('DBA')); END;  PL/SQL procedure successfully completed. | 
Birden fazla role ün kullanımını izlemek istersek de;
| 1 2 3 4 5 6 7 8 | ===> BEGIN  DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE(   name          => 'dba_pdb_dba_privs_capture',   description   => 'DBA vd PDB_DBA Rolelerinin kullanimarini capture eder',   type          => DBMS_PRIVILEGE_CAPTURE.G_ROLE,   roles         => role_name_list('DBA', 'PDB_DBA')) ; END;  PL/SQL procedure successfully completed. | 
Belirlenen spesifik rollerin yine belirlenen bazı userlar tarafından kullanılıp kullanılmadığını izlemek için;
| 1 2 3 4 5 6 7 8 9 | ===> BEGIN   DBMS_PRIVILEGE_CAPTURE.create_capture(     name        => 'role_cond_pol',     type        => DBMS_PRIVILEGE_CAPTURE.g_role_and_context,     roles       => role_name_list('DBA', 'PDB_DBA'),     condition   => 'SYS_CONTEXT(''USERENV'', ''SESSION_USER'') IN (''TEST'',''KAMIL'')'   ); END;  PL/SQL procedure successfully completed. | 
X bir userın sqlplus kullanarak gelen connectionlarında kullandığı yetkileri görmek icin ;
| 1 2 3 4 5 6 7 8 | ===> BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE(   name         => 'kamil_sqlplus_privs_capture',   type         => DBMS_PRIVILEGE_CAPTURE.G_CONTEXT,   condition    => 'SYS_CONTEXT(''USERENV'', ''MODULE'') = ''sqlplus'' AND                    SYS_CONTEXT(''USERENV'', ''SESSION_USER'') = ''KAMIL'''); END;  PL/SQL procedure successfully completed. | 
X bir userın spesifik bir ip’ den geldiğindeki kullandığı yetkileri yakalamak icin ;
| 1 2 3 4 5 6 7 8 | ===> BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE(   name         => 'kamil_spsfik_ip_capture',   type         => DBMS_PRIVILEGE_CAPTURE.G_CONTEXT,   condition    => 'SYS_CONTEXT(''USERENV'', ''IP_ADDRESS'')=''192.0.2.1'' AND                    SYS_CONTEXT(''USERENV'', ''SESSION_USER'') = ''KAMIL'''); END;  PL/SQL procedure successfully completed. | 
Son olarak iki user’ın 2 spesifik iki role’ ü kullanıp kullanmadığını capture etmek istersek de ;
| 1 2 3 4 5 6 7 8 9 10 | ===> BEGIN   DBMS_PRIVILEGE_CAPTURE.create_capture(     name        => 'iki_user_iki_role_capture',     type        => DBMS_PRIVILEGE_CAPTURE.g_role_and_context,     roles       => role_name_list('DBA', 'PDB_DBA'),     condition   => 'SYS_CONTEXT(''USERENV'', ''SESSION_USER'') IN  (''TEST'',''KAMIL'')'   ); END;  PL/SQL procedure successfully completed. | 
scriptlerini kullanabiliriz. Yaptığımız demo ve yukarıdaki verdiğimiz örnekler paketin kullanımının anlaşılması için yeterli olacaktır diye düşünüyorum. Dbms_privilege_capture paketi ile çalışırken alabileceğiniz muhtemel hatalardan da kısaca bahsedelim ;
| 1 2 3 4 5 6 7 8 9 10 11 | ===> BEGIN   DBMS_PRIVILEGE_CAPTURE.enable_capture('capture_dba_role_used'); END; BEGIN   DBMS_PRIVILEGE_CAPTURE.enable_capture('capture_dba_role_used'); END; Error at line 1 ORA-47935: Another privilege capture is enabled. ORA-06512: konum "SYS.DBMS_PRIVILEGE_CAPTURE",  satır 28 ORA-06512: konum  satır 2 Script Terminated on line 22. | 
Oluşturmuş olduğunuz policy’ leri enable etmeye çalışırken yukarıdaki gibi bir hata alabilirsiniz. Nedeni capture etmeye çalıştığınız privilege’ ların başka bir policy içerisinden zaten capture ediliyor olmasındandır. Buda duplicate iş yapmamanız açısından oluşturulmuş güzel bir kontrol noktasıdır.
| 1 2 3 4 5 6 7 8 9 10 11 | ===> Begin   DBMS_PRIVILEGE_CAPTURE.drop_capture('dba_roles_capture_pol'); end; Begin   DBMS_PRIVILEGE_CAPTURE.drop_capture('dba_roles_capture_pol'); end; Error at line 2 ORA-47932: Privilege capture string is still enabled. ORA-06512: konum "SYS.DBMS_PRIVILEGE_CAPTURE",  satır 48 ORA-06512: konum  satır 2 Script Terminated on line 45. | 
Yukarıdaki hata da enable durumda olan bir policy’ i drop etmeye çalıştığınız da alacağınız bir hatadır. Enable durumdaki bir policy’ si drop etmek istiyorsanız önce disable etmeniz gerekecektir.
Son olarak, test için bir sürü policy create ettik, temizlik yapalım ve oluşturduğumuz policy’ leri drop edelim. Policy’ lerimiz;
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ===> column name format a30 ===> select name, enabled from DBA_PRIV_CAPTURES order by 2 desc NAME                           ENABLED ------------------------------ ------- dba_roles_capture_pol          Y capture_dba_role_used          N kamil_sqlplus_privs_capture    N ORA$DEPENDENCY                 N dba_pdb_dba_privs_capture      N role_cond_pol                  N iki_user_iki_role_capture      N full_priv_used_auditing        N kamil_spsfik_ip_capture        N 9 rows selected. | 
Drop edelim;
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ===> BEGIN   DBMS_PRIVILEGE_CAPTURE.disable_capture('dba_roles_capture_pol'); END;  PL/SQL procedure successfully completed. ===> Begin   DBMS_PRIVILEGE_CAPTURE.drop_capture('dba_roles_capture_pol');   DBMS_PRIVILEGE_CAPTURE.drop_capture('capture_dba_role_used');        DBMS_PRIVILEGE_CAPTURE.drop_capture('kamil_sqlplus_privs_capture');    DBMS_PRIVILEGE_CAPTURE.drop_capture('dba_pdb_dba_privs_capture');    DBMS_PRIVILEGE_CAPTURE.drop_capture('role_cond_pol');     DBMS_PRIVILEGE_CAPTURE.drop_capture('iki_user_iki_role_capture');    DBMS_PRIVILEGE_CAPTURE.drop_capture('full_priv_used_auditing');    DBMS_PRIVILEGE_CAPTURE.drop_capture('kamil_spsfik_ip_capture'); end;  PL/SQL procedure successfully completed. | 
Reference;
https://docs.oracle.com/database/121/DVADM/priv_analysis.htm#DVADM673
http://docs.oracle.com/database/121/ARPLS/d_priv_prof.htm#ARPLS74343
 
	
			

 
		  