------------------------------------------------------触发器做审计、系统触发器----------------------------------------------------------------------------------------------
系统级触发器 触发事件表:
触发器事件 触发时间 触发条件
Logon After 用户登录成功后
Logoff Before 用户退出登录前
Startup After 数据库启动后
Shutdown Before数据库关闭前
Servererror After系统发生故障后
Logon/Logoff触发器可以用来记录用户登入和退出的时间。
数据库启动和关闭触发器可以用来进行一些数据库启动后和关闭前的前处理和后处理。
Servererror触发器可以用于记录某些重要的错误信息,以便于跟踪系统,发现故障。
触发器
1、DML审计,记录到日志表 ; 阻止DML操作,抛出异常
2、系统触发器:审计用户登录、退出、启库、停库、系统错误等
3、DDL触发器禁止用户DDL
1、DML审计,记录到日志表 ; 阻止DML操作,抛出异常
①DML审计,记录到日志表 ;(当然我也可以用FGA见点击打开链接)
create table t2 as select * from emp;
create table aud_tmp(exec_time date,exec_type varchar2(10),exec_user varchar2(20));
create or replace trigger tri_t2_after_row
after update or insert or delete
on t2 for each row
begin
if updating then
insert into aud_tmp values(sysdate,'update',SYS_context('USERENV','CURRENT_USER'));
elsif inserting then
insert into aud_tmp values(sysdate,'insert',SYS_context('USERENV','CURRENT_USER'));
else
insert into aud_tmp values(sysdate,'delete',SYS_context('USERENV','CURRENT_USER'));
end if;
end;
②禁止DML操作T1表 触发器直接抛出错误中断DML操作
create or replace trigger tr_no_dml before update or delete or insert on t1
begin
if updating
then
raise_application_error(-20001,'不允许做UPDATE操作!');
elsif inserting
then
raise_application_error(-20002,'不允许做insert操作!');
else
raise_application_error(-20003,'不允许做delete操作!');
end if;
end;
2、系统触发器:审计用户登录、退出、启库、停库、系统错误等
创建记录日志的表
CREATE TABLE log_audit (
login_date DATE,
logoff_date date,
username VARCHAR2(20),
user_ip varchar2(20),
error_code varchar2(15)
);
①审计用户登录、退出
----logon/logoff on database只能在sys用户下做
create or replace TRIGGER logon_audit AFTER LOGON ON DATABASE
BEGIN
if user not in ('SYS','SYSMAN')
then
insert into log_audit(login_date,username,user_ip) values(sysdate,user,ora_client_ip_address);
end if;
END;
create or replace TRIGGER logoff_audit BEFORE LOGOFF ON DATABASE
BEGIN
if user not in ('SYS','SYSMAN')
THEN
insert into log_audit (logoff_date,username,user_ip) values(sysdate,user,ora_client_ip_address);
end if;
END;
②审计停库
create table log_table(sid number,
serial# number,
username varchar2(30),
action varchar2(8),
log_time varchar2(19));
create or replace trigger dbshutdown
before shutdown on database
declare
v_sid v$mystat.sid%type;
v_serial# v$session.serial#%type;
v_username v$session.username%type;
begin
select sid into v_sid from v$mystat where rownum=1;
select serial#,username
into v_serial#,v_username
from v$session
where sid=v_sid;
insert into scott.log_table
values (v_sid,v_serial#,v_username,'ShutDown',to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'));
end dbshutdown;
③错误跟踪的触发器
CREATE OR REPLACE TRIGGER log_errors AFTER SERVERERROR ON DATABASE
BEGIN
IF (IS_SERVERERROR (1017)) THEN
insert into log_audit (login_date,USERNAME,USER_IP,error_code) values(sysdate,ora_login_user,ora_client_ip_address,'ORA-1017');
ELSIF (IS_SERVERERROR (2449)) THEN
insert into log_audit (login_date,USERNAME,USER_IP,error_code) values(sysdate,ora_login_user,ora_client_ip_address,'ORA-2449');
END IF;
END;
3、DDL触发器禁止用户做DDL(不能做在sys上 只能拿普通用户做)
-------------------------------------------------------------------------------------------
create or replace trigger DDL_TR
before alter or drop or rename on schema
begin
raise_application_error(-20030,'系统正在运行,不能做DDL,别捣乱!');
end;
附:
系统事件函数:
函数名称 类型 描述
ora_client_ip_address VARCHAR2 客户端的IP地址
ora_database_name VARCHAR2(50) 数据库名称
ora_dict_obj_name VARCHAR2(30) DDL发生的对象名称
ora_dict_obj_owner VARCHAR2(30) DDL发生对象的宿主
ora_dict_obj_type VARCHAR2(20) 对象类别
ora_is_alter_column(column_name IN VARCHAR2) BOOLEAN 当某列被修改的时候返回真,否则返回假
ora_is_drop_column(column_name IN VARCHAR2) BOOLEAN 当某列被删除的时候返回真,否则返回假
ora_login_user VARCHAR2(30) 登录的用户名
ora_sysevent VARCHAR2(20) 系统事件的名称
is_servererror(error_num in integer) BOLEAN返回系统是否产生某个错误
ORACLE 8I开始,提供了一个新的函数“SYS_CONTEXT”。
通过使用SYS_CONTEXT函数可以获得一些和用户相关的信息,比如:
SELECT sys_context('USERENV','TERMINAL') FROM DUAL;
用户环境的取值包括:
TERMINAL: 客户端操作系统终端的名称
LANGUAGE: NLS_LANG的值
LANG : ISO字符集的名称.
SESSIONID: SESSION的ID
INSTANCE: 实例的ID
ISDBA: 是否具有DBA权限
CLIENT_INFO: 64字节的用户信息,可以用DBMS_APPLICATION_INFO设置的值:
NLS_TERRITORY:当前SESSION的 territory
NLS_CURRENCY: 当前SESSION的货币符
NLS_CALENDAR: 当前SESSION的历法
NLS_DATE_FORMAT:当前SESSION的日期格式
NLS_DATE_LANGUAGE :显示日期的语言
NLS_SORT:排序方式(BINARY 或者linguistic)
CURRENT_USER:当前SESSION拥有权限的用户的名称(比如说当前SESSION是SYS,但是正在执行system.myproc,那么current_user就是system)
CURRENT_USERID :当前SESSION拥有的权限的用户的ID
SESSION_USER:session所属的用户名
SESSION_USERID:当前SESSION所属的用户id
CURRENT_SCHEMA:当前SESSION缺省的SCHEMA名称,可以用SESSION SET CURRENT_SCHEMA 语句修改.
CURRENT_SCHEMAID :当前SESSION缺省的SCHEMA的ID
PROXY_USER:打开当前SESSION的用户的名称
PROXY_USERID:打开当前SESSION的用户的ID
DB_DOMAIN:当前数据库的DOMAIN
DB_NAME:当前数据库的名称
HOST:客户端的主机名称
OS_USER:客户端的操作系统用户名
EXTERNAL_NAME:用户的外部名称。对于SSL用户,使用v.503协议,返回的值是证书中的DN
IP_ADDRESS:客户端的IP地址
NETWORK_PROTOCOL:连接串中的PROTOCOL=protocol指明的网络协议
BG_JOB_ID :如果当前的SESSION是由ORACLE后台进程启动的,那么返回JOB_ID,否则返回空值
FG_JOB_ID:如果当前SESSION是由ORACLE客户端进程启动的一个JOB,那么返回JOB_ID,否则返回空值
AUTHENTICATION_TYPE:返回数据库鉴权的方法,返回值包括:
DATABASE: 使用数据库的用户名口令
OS:使用操作系统外部用户鉴权
NETWORK:网络鉴权
PROXY:OCI的代理连接鉴权
AUTHENTICATION_DATA:使用X.503证书鉴权的时候,返回HEX2的证书