Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
Home -> Community -> Mailing Lists -> Oracle-L -> RE: Auditing
Hi
all,
<SPAN
class=651312311-22062001>
In
what follows is the oracle documentation for auding by
triggers:
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001>Auditing Through Database Triggers
You
can use triggers to supplement the built-in auditing features of ORACLE.
Although you can write triggers to record information similar to that recorded
by the AUDIT command, do so only when you need more detailed audit information.
For example, you can use triggers to provide value-based auditing on a per-row
basis for tables.
Note:
In some fields, the ORACLE AUDIT command is considered a security audit
facility, while triggers can provide a financial audit
facility.
When
deciding whether to create a trigger to audit database activity, consider the
advantages that the standard ORACLE database auditing features provide compared
to auditing by triggers:
<SPAN
class=651312311-22062001>· Standard auditing options cover DML and DDL
statements regarding all types of schema objects and structures. In contrast,
triggers can audit only DML statements issued against
tables.
<SPAN
class=651312311-22062001>· All database audit information is recorded
centrally and automatically using the auditing features of
ORACLE.
<SPAN
class=651312311-22062001>· Auditing features enabled using the standard
ORACLE features are easier to declare and maintain and less prone to errors than
are auditing functions defined through triggers.
<SPAN
class=651312311-22062001>· Any changes to existing auditing options can
also be audited to guard against malicious database
activity.
<SPAN
class=651312311-22062001>· Using the database auditing features, you can
generate records once every time an audited statement is issued (BY ACCESS) or
once for every session that issues an audited statement (BY SESSION). Triggers
cannot audit by session; an audit record is generated each time a
trigger-audited table is referenced.
<SPAN
class=651312311-22062001>· Database auditing can audit unsuccessful data
access. In comparison, any audit information generated by a trigger is rolled
back if the triggering statement is rolled back.
<SPAN
class=651312311-22062001>· Connections and disconnections, as well as
session activity (such as physical I/Os, logical I/Os, and deadlocks), can be
recorded by standard database auditing.
When
using triggers to provide sophisticated auditing, normally use AFTER triggers.
By using AFTER triggers, you record auditing information after the triggering
statement is subjected to any applicable integrity constraints, preventing cases
where audit processing is carried out unnecessarily for statements that generate
exceptions to integrity constraints.
When
you should use AFTER row vs. AFTER statement triggers depends on the information
being audited. For example, row triggers provide value-based auditing on a
per-row basis for tables. Triggers can also allow the user to supply a "reason
code" for issuing the audited SQL statement, which can be useful in both row and
statement-level auditing situations.
The
following trigger audits modifications to the EMP table on a per-row basis. It
requires that a "reason code" be stored in a global package variable before the
update. The trigger demonstrates:
<SPAN
class=651312311-22062001>· how triggers can provide value-based
auditing
<SPAN
class=651312311-22062001>· how to use public package
variables
<SPAN
class=651312311-22062001>Comments within the code explain the functionality of
the trigger.
<SPAN
class=651312311-22062001>
CREATE
TRIGGER audit_employee
<SPAN
class=651312311-22062001>
AFTER
INSERT OR DELETE OR UPDATE ON emp
<SPAN
class=651312311-22062001>
FOR
EACH ROW
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001>BEGIN
<SPAN
class=651312311-22062001>
/*
AUDITPACKAGE is a package with a public package
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> variable REASON. REASON could be set by
the
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> application by a command such as
EXECUTE
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> AUDITPACKAGE.SET_REASON(reason_string).
Note that a
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> package variable has state for the
duration of a
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> session and that each session has a
separate copy of
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> all package variables.
*/
<SPAN
class=651312311-22062001>
IF
auditpackage.reason IS NULL THEN
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> raise_application_error(-20201,'Must
specify reason with ',
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001>
'AUDITPACKAGE.SET_REASON(reason_string)');
<SPAN
class=651312311-22062001>
END
IF;
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001>
/*
If the above conditional evaluates to TRUE, the
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> user-specified error number and message is
raised,
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> the trigger stops execution, and the
effects of the
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> triggering statement are rolled back.
Otherwise, a
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> new row is inserted into the pre-defined
auditing
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> table named AUDIT_EMPLOYEE containing the
existing
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> and new values of the EMP table and the
reason code
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> defined by the REASON variable of
AUDITPACKAGE. Note
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> that the "old" values are NULL if
triggering
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> statement is an INSERT and the "new"
values are NULL
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> if the triggering statement is a DELETE.
*/
<SPAN
class=651312311-22062001>
INSERT
INTO audit_employee VALUES
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> (:old.ssn, :old.name,
:old.job_classification, :old.sal,
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> :new.ssn, :new.name,
:new.job_classification, :new.sal,
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001> auditpackage.reason, user, sysdate
);
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001>END;
<SPAN
class=651312311-22062001>Optionally, you can also set the reason code back to
NULL if you want to force the reason code to be set for every update. The
following AFTER statement trigger sets the reason code back to NULL after the
triggering statement is executed:
<SPAN
class=651312311-22062001>
CREATE
TRIGGER audit_employee_reset
<SPAN
class=651312311-22062001>
AFTER
INSERT OR DELETE OR UPDATE ON emp
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001>BEGIN
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001>
auditpackage.set_reason(NULL);
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001>END;
The
previous two triggers are both fired by the same type of SQL statement. However,
the AFTER row trigger is fired once for each row of the table affected by the
triggering statement, while the AFTER statement trigger is fired only once after
the triggering statement execution is completed.
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001>
<SPAN
class=651312311-22062001>Regards,
<SPAN
class=651312311-22062001>Brij.
<FONT face=Tahoma
size=2>-----Original Message-----From: root_at_fatcity.com
[mailto:root_at_fatcity.com]On Behalf Of Nirmal Kumar Muthu
KumaranSent: Friday, June 22, 2001 4:12 PMTo: Multiple
recipients of list ORACLE-LSubject: RE:
Auditing
Hi Norrell,
I just tested ur case.
Can you tell me, how it's possible ,
when doing auditing, oracle will refer to the sys.aud$ table itself, correct?.
If i droped it (even there is a
synonym on that name),
Oracle giving an error, it's not able
to find the sys.aud$ table.
Nirmal,
-----Original Message----- <FONT
face=Arial size=1>From: <FONT face=Arial size=1>Norrell, Brian [SMTP:BNorrell_at_QuadraMed.com] <FONT face=Arial size=1>Sent: <FONT face=Arial size=1>Thursday, June 21, 2001 6:33 PM <FONT face=Arial size=1>To: <FONT face=Arial size=1>Multiple recipients of list ORACLE-L <FONT face=Arial size=1>Subject: <FONT face=Arial size=1>RE: Auditing
Brian Norrell <FONT face=Arial
size=2>Manager, MPI Development <FONT face=Arial
size=2>QuadraMed 511 E John Carpenter
Frwy, Su 500 Irving, TX 75062
(972) 831-6600
-----Original Message----- <FONT
face=Arial size=2>Sent: Thursday, June 21, 2001 6:00 AM <FONT
face=Arial size=2>To: Multiple recipients of list ORACLE-L
This will not work as you can't create triggers
on sys objects. So tell me the way how i
should create triggers on aud$.
-----Original Message----- <FONT
face=Arial size=2>Sharma Sent: Thursday,
June 21, 2001 2:56 PM To: Multiple
recipients of list ORACLE-L
i think u can use triggers such kind of
auditing. create aud$ table with one more
column, and try updating the column as soon <FONT face=Arial
size=2>user fires some sql.
this is just a thought. could find another
opinion.
saurabh -----
Original Message ----- To: Multiple
recipients of list ORACLE-L <ORACLE-L_at_fatcity.com> <FONT
face=Arial size=2>Sent: Thursday, June 21, 2001 11:15 AM
> Hi all there, <FONT face=Arial
size=2>> I am auditing a database where 400 users are concurrently
accessing the > database.
> Now in the table AUD$ we have all the
records of the user transactions.But >
is there any way to store what sort of query he is running so that i
can see <FONT face=Arial
size=2>> the actual text of query which was fired 3 days before.
> Regards, <FONT face=Arial
size=2>> Anand > <FONT
face=Arial size=2>> -- > Please see
the official ORACLE-L FAQ: <A href="http://www.orafaq.com"
target=_blank>http://www.orafaq.com <FONT face=Arial
size=2>> -- > Author: Anand
> INET:
karhadkar_at_rolta.com > <FONT
face=Arial size=2>> Fat City Network Services -- (858)
538-5051 FAX: (858) 538-5051 >
San Diego, California -- Public
Internet access / Mailing Lists >