Auditing


BY SESSION

Specify BY SESSION if you want Oracle Database to write a single record for all SQL statements of the same type issued and operations of the same type executed on the same schema objects in the same session.



BY ACCESS

Specify BY ACCESS if you want Oracle Database to write one record for each audited statement and operation.



WHENEVER SUCCESSFUL/NOT SUCCESSFUL

Specify WHENEVER SUCCESSFUL to audit only SQL statements and operations that succeed.

Specify WHENEVER NOT SUCCESSFUL to audit only statements and operations that fail or result in errors.

If you omit this clause, then Oracle Database performs the audit regardless of success or failure.


To Review the Contents of the Audit Trail

  SELECT 
      TO_CHAR(TIMESTAMP,'MM/DD HH24:MI') TIMESTAMP, 
      SUBSTR(OS_USERNAME,1,20) OS_USERNAME, 
      SUBSTR(USERNAME,1,20) USERNAME, 
      SUBSTR(TERMINAL,1,20) TERMINAL, 
      ACTION_NAME, 
      RETURNpre 
    FROM 
      SYS.DBA_AUDIT_SESSION 
   WHERE 
     USERNAME LIKE 'USERNAME%' 
     AND TIMESTAMP BETWEEN SYSDATE-7 AND SYSDATE 
   ORDER BY 
    TIMESTAMP DESC; 

The RETURNpre column is the number associated with the ORA- error pre that was returned to the client computer:


What are we auditing?

   SELECT  * FROM DBA_STMT_AUDIT_OPTS where user_name = 'A157584'
   

What can we audit?

  Select * from audit_actions
  

Turn off auditing options

SQL> noaudit insert table; 

SQL> noaudit execute procedure; 

SQL>  noaudit select table; 

Noaudit succeeded.

Last logon � CIB

select username, max(logon_time) from ORACLE.SUCCESSFUL_LOGINS group by username order by username; 

Failed logon with password

col os_username form a15 
col username form a15 
col userhost form a15 
select os_username,  username, userhost,  to_char(timestamp,'mm/dd/yyyy hh24:mi:ss') logon_time, action_name, returnpre from dba_audit_session 
where returnpre =1017; 
set lines 90
set pages 60

ttitle 'PDGPRD01: Monthly Report Oracle Viewer Usage/Users'

break on year on month skip 1 on report

compute sum of tally on month report

  SELECT to_char(timestamp,'YYYY') year,
         to_char(timestamp,'MON')  month,
         a.username username,
         nvl(b.name, b.name)     name,
         COUNT (*) tally
    FROM dba_audit_session a, a157584.users b
   WHERE a.username NOT IN ('A157584', 'SYSTEM', 'SYS', 'DBSNMP','PDG','PDGDEV','PDGSC','PUBLIC','PDG5C3T#1','A','OEM')
         AND a.username = b.username(+)
         and to_char(timestamp,'YYYY') = '2011'
GROUP BY a.username, b.name, to_char(timestamp,'YYYY'), to_char(timestamp,'MON'), to_char(timestamp,'MM')
ORDER BY 1,to_char(timestamp,'MM')
/

select * from dba_audit_session where to_char(timestamp,'YYYY-MM-DD')  between '2015-11-10' and '2015-11-17'

set lines 300
set pages 25

col OS_USERNAME form a20
col userhost form a20

select os_username,  username, userhost,  to_char(timestamp,'mm/dd/yyyy hh24:mi:ss') logon_time, action_name, returnpre from dba_audit_session; 

Moving the Database Audit Trail to a Different Tablespace

The SET_AUDIT_TRAIL_LOCATION procedure allows you to alter the location of the standard and/or fine-grained database audit trail. It does not currently allow the alteration of the OS audit trail, although the documentation suggests this may happen in future. The procedure accepts two parameters.
�	AUDIT_TRAIL_TYPE: They type of audit trail that is to be moved.
�	AUDIT_TRAIL_LOCATION_VALUE: The tablespace the audit trail tables should be moved to.
The AUDIT_TRAIL_TYPE parameter is specified using one of three constants.
�	DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD: Standard audit trail (AUD$).
�	DBMS_AUDIT_MGMT.AUDIT_TRAIL_FGA_STD: Fine-grained audit trail (FGA_LOG$).
�	DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD: Both standard and fine-grained audit trails.

Let's see this in action. First check the current location of the audit trail tables.

CONN / AS SYSDBA

SELECT table_name, tablespace_name
FROM   dba_tables
WHERE  table_name IN ('AUD$', 'FGA_LOG$')
ORDER BY table_name;

TABLE_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------
AUD$                           SYSTEM
FGA_LOG$                       SYSTEM

SQL>

Next, create a new tablespace to hold the audit trail.

CREATE TABLESPACE audit_aux
  DATAFILE '/u01/app/oracle/oradata/DB11G/audit_aux01.dbf'
  SIZE 1M AUTOEXTEND ON NEXT 1M;

Then we move the standard audit trail to the new tablespace.

BEGIN
  DBMS_AUDIT_MGMT.set_audit_trail_location(
    audit_trail_type           => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,
    audit_trail_location_value => 'AUDIT_AUX');
END;
/

PL/SQL procedure successfully completed.

SQL>

-- Check locations.
SELECT table_name, tablespace_name
FROM   dba_tables
WHERE  table_name IN ('AUD$', 'FGA_LOG$')
ORDER BY table_name;

TABLE_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------
AUD$                           AUDIT_AUX
FGA_LOG$                       SYSTEM

SQL>

Next we move the fine-grained audit trail.

BEGIN
  DBMS_AUDIT_MGMT.set_audit_trail_location(
    audit_trail_type           => DBMS_AUDIT_MGMT.AUDIT_TRAIL_FGA_STD,
    audit_trail_location_value => 'AUDIT_AUX');
END;
/

PL/SQL procedure successfully completed.

SQL>


alter system set audit_trail=db_extended scope=spfile; 

select count(*) from DBA_AUDIT_TRAIL where USERNAME = 'EXIMADMIN'; 

audit update table, delete table, insert table by EXIMADMIN by access; 

noaudit select table, update table, delete table, insert table by EXIMADMIN by access; 

select ACTION_NAME from dba_audit_trail where USERNAME = 'EXIMADMIN'; 

14:52:15 sys@EXMPPD01:PRI>noaudit select table by EXIMADMIN; 

Noaudit succeeded. 

select count(*) from DBA_AUDIT_TRAIL where USERNAME = 'EXIMADMIN' and action = 3 


select action_name, audit_option from DBA_AUDIT_STATEMENT where grantee = 'EXIMADMIN' 


Not knowing exactly what you did -- I cannot point out what you did wrong. However, I can show you how to do this correctly.

I simply: 

1. set audit_trail=true; and restarted. 
2. ran the following: 

SQL> @connect "/ as sysdba" 
SQL> set termout off 
SQL> GET afiedt.buf NOLIST 
SQL> set termout on 
SQL>  
SQL> truncate table aud$; 

Table truncated. 

SQL> audit table by access; 

Audit succeeded.

SQL> audit alter table by access; 

Audit succeeded. 

SQL>  
SQL> @connect / 
SQL> set termout off 
SQL> GET afiedt.buf NOLIST 
SQL> set termout on 
SQL> create table audit_tab ( x int ); 

Table created. 

SQL> select username, action_name from dba_audit_trail; 

USERNAME                       ACTION_NAME 
------------------------------ --------------------------- 
OPS$TKYTE                      CREATE TABLE 


SQL>  
SQL> alter table audit_tab add y date; 

Table altered. 

SQL> select username, action_name from dba_audit_trail; 

USERNAME                       ACTION_NAME 
------------------------------ --------------------------- 
OPS$TKYTE                      CREATE TABLE 
OPS$TKYTE                      ALTER TABLE 

SQL> 
SQL>  
SQL> drop table audit_tab; 

Table dropped. 

SQL> select username, action_name from dba_audit_trail; 

USERNAME                       ACTION_NAME 
------------------------------ --------------------------- 
OPS$TKYTE                      CREATE TABLE 
OPS$TKYTE                      ALTER TABLE 
OPS$TKYTE                      DROP TABLE 

As you can see -- the create and drop (covered by the AUDIT TABLE BY ACCESS) as well as the ALTER (covered by the AUDIT ALTER TABLE BY ACCESS) were recorded. I can only assume that in your attempts -- you entered many different audit commands and that is why the create table audit is hanging about. To see what is in effect:

SQL> select * from dba_priv_audit_opts; 

no rows selected 

SQL> select * from dba_stmt_audit_opts; 

USER_NAME                      PROXY_NAME                     AUDIT_OPTION                             SUCCESS    FAILURE 
------------------------------ ------------------------------ ---------------------------------------- ---------- ---------- 
                                                              ALTER TABLE                              BY ACCESS  BY ACCESS 
                                                              TABLE                                    BY ACCESS  BY ACCESS 

that shows I have table and alter table and if I:

SQL> @connect "/ as sysdba" 
SQL> set termout off 
SQL> GET afiedt.buf NOLIST 
SQL> set termout on 
SQL> 
SQL> noaudit table; 

Noaudit succeeded. 

SQL> noaudit alter table; 

Noaudit succeeded. 

SQL> truncate table aud$; 

Table truncated. 

SQL>  
SQL> @connect / 
SQL> set termout off 
SQL> GET afiedt.buf NOLIST 
SQL> set termout on 
SQL> create table audit_tab ( x int ); 

Table created. 

SQL> select username, action_name from dba_audit_trail; 

no rows selected 

SQL>  
SQL> alter table audit_tab add y date; 

Table altered. 

SQL> select username, action_name from dba_audit_trail; 

no rows selected 

SQL>  
SQL>  
SQL> drop table audit_tab; 

Table dropped. 

SQL> select username, action_name from dba_audit_trail; 

no rows selected 

I'm no longer auditing. >

What auditing are we doing at a statment level

16:18:52 sys@EXMPPD01:PRI> select * from DBA_STMT_AUDIT_OPTS where user_name = 'EXIMADMIN'; 
USER_NAME PROXY_NAME AUDIT_OPTION SUCCESS FAILURE ------------------------------ ------------------------------ ---------------------------------------- ---------- ---------- EXIMADMIN INSERT TABLE BY ACCESS BY ACCESS EXIMADMIN UPDATE TABLE BY ACCESS BY ACCESS EXIMADMIN DELETE TABLE BY ACCESS BY ACCESS

Summary - What are we auditing

Statement level

Auditing will be done at statement level. Statements that can be audited are found in STMT_AUDIT_OPTION_MAP.

SQL> audit table by scott;

Audit records can be found in DBA_STMT_AUDIT_OPTS.

SQL> select * from DBA_STMT_AUDIT_OPTS;

Object level

Auditing will be done at object level. These objects can be audited: tables, views, sequences, packages, stored procedures and stored functions.

SQL> audit insert, update, delete on scott.emp by hr;

Audit records can be found in DBA_OBJ_AUDIT_OPTS.

SQL> select * from DBA_OBJ_AUDIT_OPTS;

Privilege level

Auditing will be done at privilege level. All system privileges that are found in SYSTEM_PRIVILEGE_MAP can be audited.

SQL> audit create tablespace, alter tablespace by all;

Specify ALL PRIVILEGES to audit all system privileges. Audit records can be found in DBA_PRIV_AUDIT_OPTS.

SQL> select * from DBA_PRIV_AUDIT_OPTS;

   truncate table sys.aud$;

 select table_name,tablespace_name from dba_tables where table_name='AUD$';


-- Recolcate aud$

  begin 
 dbms_audit_mgmt.set_audit_trail_location( 
  audit_trail_type            => dbms_audit_mgmt.audit_trail_aud_std, 
  audit_trail_location_value  => 'SYSAUX'); 
end; 
/ 

-- Initialize the cleanup, and to define the oldest record to leave in the table (Here 30 days):

begin 
DBMS_AUDIT_MGMT.INIT_CLEANUP(audit_trail_type=> DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD, 
                              default_cleanup_interval=>720); 
   
DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(audit_trail_type  => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD, 
                                               last_archive_time => SYSTIMESTAMP-90); 
end;
/ 

BEGIN 
  DBMS_AUDIT_MGMT.CREATE_PURGE_JOB(audit_trail_type=> DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD, 
                                     audit_trail_purge_interval => 168, 
                                     audit_trail_purge_name=> 'PURGE_AUD_JOB', 
                                     use_last_arch_timestamp => TRUE); 
   END; 
    / 

SELECT * FROM   dba_audit_mgmt_config_params  

BEGIN 
  DBMS_AUDIT_MGMT.set_last_archive_timestamp( 
    audit_trail_type  => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD, 
    last_archive_time => SYSTIMESTAMP); 
END; 
/

SELECT * FROM dba_audit_mgmt_last_arch_ts; 

set echo off feedback off verify off trimspool on
set pagesize 50000 linesize 300
column filename new_val filename
select '/tmp/audit_trail.xls' filename from dual;

SET MARKUP HTML ON
spool &filename
select * from dba_audit_trail
where EXTENDED_TIMESTAMP between
    to_Timestamp('20/04/2020 00:00:00.413164', 'dd/mm/yyyy hh24:mi:ss.FF') and
    to_Timestamp('26/04/2020 23:59:26.413164', 'dd/mm/yyyy hh24:mi:ss.FF');
spool off
SET MARKUP HTML OFF
clear columns breaks
set feedback on trimspool on

  Minimalistic Oracle
Minimalistic Oracle contains a collection of practical examples from my encounters with Oracle technologies. When relevant, I also write about other technologies, like Linux or PostgreSQL. Many of the posts starts with "how to" since they derive directly from my own personal experience. My goal is to provide simple examples, so that they can be easily adapted to other situations.

Friday, November 1, 2013
How to audit CREATE SESSION

Audit all session connecting to the database:

audit create session [ whenever successful | not successful ];

To audit sessions created by a specific user:
audit create session by SCOTT [ whenever successful | not successful ];

If you omit the condition "whenever successful/not successful", Oracle will audit all connections, regardless of their success or failure.


To disable auditing:
noaudit create session;
noaudit create session by scott;

To verify that the auditing options has indeed been set:
SELECT * 
 FROM DBA_PRIV_AUDIT_OPTS 
 WHERE USER_NAME = 'SCOTT';

Result:
USER_NAME PROXY_NAME  PRIVILEGE SUCCESS FAILURE
SCOTT   CREATE SESSION  BY ACCESS BY ACCESS

The view DBA_PRIV_AUDIT_OPTS gives you "current system privileges being audited across the system and by user".
Note that a NULL value in the user_name column of DBA_PRIV_AUDIT_OPTS means system-wide auditing.
  

  How to use sqlerrm to reveal the meaning of audit information

As an example, the audit information may look like the following:

ALTER SESSION SET NLS_DATE_FORMAT='DD.MM.YYYY HH24:MI:SS';

SELECT
os_username,
userhost,
timestamp,
returnpre
FROM dba_audit_session
WHERE action_name = 'LOGON'
AND returnpre > 0
AND trunc(timestamp) = to_date('08.07.2013', 'DD.MM.YYYY')
AND username = 'TSF'
ORDER BY timestamp DESC;

OS_USERNAME USERHOST       TIMESTAMP            RETURNpre
----------- -----------    -------------------  ---------- 
billyb      CHM06071130    08.07.2013 12:24:07  1017  
billyb      CHM06071130    08.07.2013 10:06:06  28000  
You can use the sqlerrm keyword to print the meaning of a return pre, like this:

exec dbms_output.put_line(sqlerrm(-1017)) ;
exec dbms_output.put_line(sqlerrm(-28000)) ;

These commands will yield:

ORA-01017: invalid username/password; logon denied
ORA-28000: the account is locked
  

Audit Queries

  set lines 300
set pages 66

col user_name for a25
cOL audit_trail     FORMAT A20
COL last_archive_ts FORMAT A40

ttitle 'Last Archive Timestamp'

SELECT audit_trail, last_archive_ts FROM dba_audit_mgmt_last_arch_ts;

col cleanup_time form a40

ttitle 'Clean-up Events over the Past Week'

select * from (SELECT * FROM DBA_AUDIT_MGMT_CLEAN_EVENTS order by  cleanup_time desc) where rownum < =7;

ttitle 'DBA Privilege Options'
select user_name, privilege, success, failure from dba_priv_audit_opts order by user_name, privilege;

ttitle 'DBA Statement Options'
select user_name, audit_option, success, failure from dba_stmt_audit_opts order by user_name, audit_option;

col parameter_name form a40
col parameter_value form a40

ttitle 'Configuration Parameters'
SELECT * FROM dba_audit_mgmt_config_params where audit_trail = 'STANDARD AUDIT TRAIL';

col JOB_FREQUENCY form a30
col job_name form a30

ttitle 'Return information on cleanup jobs'
select * from dba_audit_mgmt_cleanup_jobs where audit_trail = 'STANDARD AUDIT TRAIL';

prompt 'Clean-up Initialization Done?"
SET SERVEROUTPUT ON
BEGIN
  IF DBMS_AUDIT_MGMT.is_cleanup_initialized(DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD) THEN
    DBMS_OUTPUT.put_line('YES');
  ELSE
    DBMS_OUTPUT.put_line('NO');
  END IF;

END;
/

ttitle off

Satya BlogSpot