博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

如何看Oracle数据库的用户登录的记录档案

Posted on 2012-09-19 18:18  奥客  阅读(19092)  评论(1编辑  收藏  举报

如何看数据库的用户登录的记录档案


1 audit
用审记来记录用户的操作信息
2 trigger
用系统触发器来记录用户登录
3 logmnr
从log文件中挖出用户登录信息

推荐使用第3种,不占用系统资源,而且很方便。


===============================

Oracle 中记录用户登录信息

我们可以使用 Oracle Audit 函数来记录用户登录信息,但是如果开放了 Audit 函数将会使Oracle 性能下降,甚至导致 Oracle 崩溃。那我们如何才能记录用户登录信息呢?其实我们可以通过建立触发器的方式来实现。方法如下:
1. 用 sys 用户登录 Oracle
2. 创建记录用户登录信息的表
CREATE TABLE LOG$INFORMATION
(
   ID        NUMBER(10),
   USERNAME VARCHAR2(30),
   LOGINTIME DATE,
   TERMINAL VARCHAR2(50),
   IPADRESS VARCHAR2(20),
   OSUSER    VARCHAR2(30),
   MACHINE   VARCHAR2(64),
   PROGRAM   VARCHAR2(64),
   SID       NUMBER,
   SERIAL#   NUMBER,
   AUSID     NUMBER
)
/

3. 创建一个 Sequence,作为登录信息的主键
CREATE SEQUENCE LOGIN_SEQ
minvalue 1
maxvalue 9999999999
start with 1
increment by 1
cache 20
/

4. 创建触发器,记录用户登录信息
CREATE OR REPLACE TRIGGER LOGIN_RECORD_TR
AFTER logon ON DATABASE
DECLARE
mtSession v$session%ROWTYPE;
CURSOR cSession(iiQuerySid IN NUMBER) IS
    SELECT * FROM v$session
       WHERE audsid = iiQuerySid;
BEGIN
OPEN cSession(userenv('SESSIONID'));
   FETCH cSession INTO mtSession;
      IF cSession%FOUND AND SYS_CONTEXT ('USERENV','IP_ADDRESS') IS NOT NULL THEN
         INSERT INTO log$information(
            id,
            username,
            logintime,
            terminal,
            ipadress,
            osuser,
            machine,
            program,
            sid,
            serial#,
            ausid
         ) VALUES(
            login_seq.nextval,
            USER,
            SYSDATE,
            mtSession.Terminal,
            SYS_CONTEXT ('USERENV','IP_ADDRESS'),
            mtSession.Osuser,
            mtSession.Machine,
            mtSession.Program,
            mtSession.Sid,
            mtSession.Serial#,
            userenv('SESSIONID')
         );
      END IF;
   CLOSE cSession;
EXCEPTION
   WHEN OTHERS THEN
     RAISE;
END;
/

5. 将 SYS.LOG$INFORMATION 授权给需要查看登录记录的用户
Grant select on SYS.LOG$INFORMATION to XXX
/

 

=======================================
审计用户登录和登出
       记录每个用户每次登录数据库和退出数据库的日期和事件。设置步骤如下:

       1. 设置系统审计相关的参数

       2. 重新启动数据库

       3.以SYSTEM帐号登录数据库执行下列语句,设置CONNECT审计并检查是否设置成功:

        SQL> connect system/password

       SQL> audit connect

        SQL> col user_name format a11

        SQL> col audit_option format a14

       SQL> select user_name, audit_option, success, failure

       from sys.dba_stmt_audit_opts;

          USER_NAME   AUDIT_OPTION   SUCCESS    FAILURE

         ----------- -------------- ---------- ----------

             CREATE SESSION BY ACCESS BY ACCESS

    

       4.查询 AUD$表就可以查看到审计结果了

 

       SQL> col userid format a8

       SQL> select sessionid, to_char(timestamp#,'DD-MON-YY:HH24:MI:SS') login,

        userid, to_char(logoff$time,'DD-MON-YY:HH24:MI:SS') logoff

        from sys.aud$ where userid='SCOTT';

 

        SESSIONID LOGIN               USERID   LOGOFF

        ---------- ------------------ -------- ------------------

          132 22-FEB-00:13:55:06 SCOTT    22-FEB-00:14:04:05

       注意:不同的版本的ORACLE数据库AUD$字典会有所不同,实际情况请参照你当前版本的数据库的AUD$表。

       1.4.11 审计SYS用户的操作(ORACLE 9i Release 2)
       在ORACLE 9.2之前,SYS帐户是系统中的一个唯一不受审计的帐户。在ORACLE 9I Release 2和以后的版本中,通过一些设置就可以对SYS帐号进行审计。

       在ORACLE 9.2以后的版本中,可以通过设置AUDIT_SYS_OPERATIONS可以实现对具有SYS/SYSDBA/SYSOPER权限的用户的审计。

       1.4.12 使用WINDOWS 事件管理器来记录审计信息
       和UNIX系统不同,WINDOWS的审计结果不是存储在操作系统文件中,而是直接存储在WINDOWS 事件日志中。本节介绍如何配置数据库审计,并用事件管理器来查看审计记录。

       在WINDOWS下设置数据库审计,需要按照如下的步骤:

       1、配置审计

       首先要确认WINDOWS的事件日志(EVENTLOG)服务是否启动。可以通过“控制面板/管理工具/服务”工具来查看。

       然后通过修改ORACLE的参数(参数修改方法参见前面的关于ORACLE参数文件的描述)AUDIT_TRAIL:

AUDIT_TRAIL=0S

       在WINDFOWS平台下要注意的是:

       不管AUDIT_TRAIL设置为什么值,有部分ORACLE的操作会记录在事件日志中

       在WINDOWS下不支持AUDIT_FILE_DEST参数,如果设置了该参数,数据库会报错

             LRM-00101: UNKNOWN PARAMETER NAME 'AUDIT_FILE_DEST'

             ORA-01078: FAILURE IN PROCESSING SYSTEM PARAMETERS

       在使用审计前,要确保事件日志有足够大的空间来存储审计信息

     

         2、检查是否安装好AUDIT相关的对象

       最简单的检查方法是看看AUD$是否存在。如果AUDIT相关对象安装不正确,可以通过%ORACLE_HOME%\rdbms\admin\cataudit.sql脚本来安装AUDIT相关对象。如果要删除审计,可以执行%ORACLE_HOME%\rdbms\admin\catnoaud.sql。

 

       3、配置审计

 

       在配置审计之前,首先要说明的是,审计是一种会带来额外开销的操作。因此在可能的情况下,尽量减少审计操作。另外,如果打开审计操作,那么对一些数据库事件的审计是缺省的,这些审计事件包括:

       实例关闭

       通过SYSOPER和SYSDBA连接数据库

       在WINDOWS下配置审计的步骤和在UNIX下配置审计类似,这里就不再描述了。审计信息会自动写入WINDOWS的事件日志种,通过事件管理器可以查看日志。

=====================================
如何使用Logmnr方法分析数据库日志


本文用举例的形式来讲解使用Logmnr方法分析数据库日志。

一、安装LogMiner工具

(以下两个脚本以SYSDBA身份运行)

@$ORACLE_HOME\rdbms\admin\dbmslm.sql;

@ $ORACLE_HOME\rdbms\admin\dbmslmd.sql;

第一个脚本用来创建DBMS_LOGMNR包,该包用来分析日志文件。

第二个脚本用来创建DBMS_LOGMNR_D包,该包用来创建数据字典文件。

二、使用LogMiner工具

下面将详细介绍如何使用LogMiner工具。

1、创建数据字典文件(data-dictionary)

(1)首先在init.ora初始化参数文件中,指定数据字典文件的位置,也就是添加一个参数UTL_FILE_DIR,该参数值为服务器中放置数据字典文件的目录。

如:UTL_FILE_DIR = ($ORACLE_HOME\logs) ,重新启动数据库,使新加的参数生效。

(2)创建数据字典文件:

SQL> connect /as sysdba
SQL> execute dbms_logmnr_d.build(dictionary_filename =>
'dict.ora',dictionary_location => 'G:\oracle\logs');

PL/SQL procedure successfully completed

2、创建要分析的日志文件列表:

(1)创建分析列表,即所要分析的日志:

SQL> execute dbms_logmnr.add_logfile(LogFileName =>
'G:\ORACLE\ORADATA\ORADBSP\REDO04.LOG',Options => dbms_logmnr.new);

PL/SQL procedure successfully completeds

 

(2)添加分析日志文件(一次添加1个为宜):

 

SQL>
execute dbms_logmnr.add_logfile(LogFileName =>
'G:\ORACLE\ORADATA\ORADBSP\REDO05.LOG',
Options => dbms_logmnr.ADDFILE);

PL/SQL procedure successfully completed

3、使用logMiner进行日志分析:

(1)无限制条件,即用数据字典文件对要分析的日志文件所有内容做分析:

SQL> execute dbms_logmnr.start_logmnr
(DictFileName => 'G:\oracle\logs\dict.ora');

PL/SQL procedure successfully completed

 

(2)带限制条件:

可以用scn号或时间做限制条件,也可组合使用--分析日志列表中时间从07.02.28从10:00到15:00的内容。

SQL> execute dbms_logmnr.start_logmnr
(startTime => to_date('20070228100000','yyyy-mm-dd hh24:mi:ss'),
endTime => to_date('20070228150000','yyyy-mm-dd hh24:mi:ss'),
DictFileName => 'G:\oracle\logs\dict.ora');

PL/SQL procedure successfully completed

dbms_logmnr.start_logmnr函数的原型为:

PROCEDURE start_logmnr(
startScn INNUMBER default 0 ,
endScnINNUMBER default 0,
startTimeINDATE default '',
endTime INDATE default '',
DictFileNameINVARCHAR2 default '',
Options INBINARY_INTEGER default 0 );

4、分析后释放内存:

SQL> execute dbms_logmnr.end_logmnr;

PL/SQL procedure successfully completed

 

5、其它:

(1)删除日志分析文件:

 

exec dbms_logmnr.add_logfile
('G:\ORACLE\ORADATA\ORADBSP\REDO04.LOG',
dbms_logmnr.removefile);

 

三、查看LogMiner工具分析结果

SQL> select * from dict t where t.table_name like '%LOGMNR%';
--看所有与logmnr相关的视图

TABLE_NAME COMMENTS
------------------------------ ---------------------------
GV$LOGMNR_CALLBACK Synonym for GV_$LOGMNR_CALLBACK
GV$LOGMNR_CONTENTS Synonym for GV_$LOGMNR_CONTENTS
GV$LOGMNR_DICTIONARY Synonym for GV_$LOGMNR_DICTIONARY
GV$LOGMNR_LOGFILESynonym for GV_$LOGMNR_LOGFILE
GV$LOGMNR_LOGSSynonym for GV_$LOGMNR_LOGS
GV$LOGMNR_PARAMETERS Synonym for GV_$LOGMNR_PARAMETERS
GV$LOGMNR_PROCESSSynonym for GV_$LOGMNR_PROCESS
GV$LOGMNR_REGIONSynonym for GV_$LOGMNR_REGION
GV$LOGMNR_SESSIONSynonym for GV_$LOGMNR_SESSION
GV$LOGMNR_STATS Synonym for GV_$LOGMNR_STATS
GV$LOGMNR_TRANSACTIONSynonym for GV_$LOGMNR_TRANSACTION
V$LOGMNR_CALLBACKSynonym for V_$LOGMNR_CALLBACK
V$LOGMNR_CONTENTSSynonym for V_$LOGMNR_CONTENTS
V$LOGMNR_DICTIONARYSynonym for V_$LOGMNR_DICTIONARY
V$LOGMNR_LOGFILESynonym for V_$LOGMNR_LOGFILE
V$LOGMNR_LOGS Synonym for V_$LOGMNR_LOGS
V$LOGMNR_PARAMETERSSynonym for V_$LOGMNR_PARAMETERS
V$LOGMNR_PROCESSSynonym for V_$LOGMNR_PROCESS
V$LOGMNR_REGION Synonym for V_$LOGMNR_REGION
V$LOGMNR_SESSIONSynonym for V_$LOGMNR_SESSION

TABLE_NAME COMMENTS
------------------------------ ------------------------
V$LOGMNR_STATSSynonym for V_$LOGMNR_STATS
V$LOGMNR_TRANSACTION Synonym for V_$LOGMNR_TRANSACTION

GV$LOGMNR_LOGS 是分析日志列表视图:

分析结果在GV$LOGMNR_CONTENTS 视图中,可按以下语句查询:

select scn,timestamp,log_id,seg_owner,seg_type,
table_space,data_blk#,data_obj#,data_objd#,
session#,serial#,username,session_info,
sql_redo,sql_undo from logmnr3 t
where t.sql_redo like 'create%';

如果不能正常查询GV$LOGMNR_CONTENTS视图,并报以下错误,ORA-01306: 在从 v$logmnr_contents 中选择之前必须调用 dbms_logmnr.start_logmnr() 。可采用如下方法:

create table logmnr3 as select * from GV$LOGMNR_CONTENTS;

问题解答:

创建数据字典的目 : 让LogMiner引用涉及到内部数据字典中的部分时为他们实际的名字,而不是系统内部的16进制。数据字典文件是一个文本文件,使用包DBMS_LOGMNR_D来创建。如果我们要分析的数据库中的表有变化,影响到库的数据字典也发生变化,这时就需要重新创建该字典文件。另外一种情况是在分析另外一个数据库文件的重作日志时,也必须要重新生成一遍被分析数据库的数据字典文件。 在使用LogMiner工具分析redo log文件之前,可以使用DBMS_LOGMNR_D 包将数据字典导出为一个文本文件。该字典文件是可选的,但是如果没有它,LogMiner解释出来的语句中关于数据字典中的部分(如表名、列名等)和数值都将是16进制的形式,我们是无法直接理解的。例如,下面的SQL语句:

 

INSERT INTO dm_dj_swry (rydm, rymc) VALUES (00005, '张三');

LogMiner解释出来的结果将是下面这个样子:

insert into Object#308(col#1, col#2)
values (hextoraw('c30rte567e436'),
hextoraw('4a6f686e20446f65'));

       分析Oracle数据库日志文件

DBA需要知道的Oracle 10g的审计内容

  【导读】Oracle 数据库 10g 审计以一种非常详细的级别捕获用户行为,它可以消除手动的、基于触发器的审计。假定用户 Joe 具有更新那张表的权限,并按如下所示的方式更新了表中的一行数据。

Oracle 数据库 10g 审计以一种非常详细的级别捕获用户行为,它可以消除手动的、基于触发器的审计。假定用户 Joe 具有更新那张表的权限,并按如下所示的方式更新了表中的一行数据。
  update SCOTT.EMP set salary = 12000
  where empno = 123456;
  您如何在数据库中跟踪这种行为呢?在 Oracle 9i 数据库及其较低版本中,审计只能捕获“谁”执行此操作,而不能捕获执行了“什么”内容。例如,它让您知道 Joe 更新了 SCOTT 所有的表 EMP,但它不会显示他更新了该表中员工号为 123456 的薪水列。它不会显示更改前的薪水列的值—要捕获如此详细的更改,您将不得不编写您自己的触发器来捕获更改前的值,或使用 Log Miner 将它们从存档日志中检索出来。

  这两种方法都能让您跟踪更改的内容并记录更改前的值,但其成本非常高。使用触发器编写审计数据可能会对性能产生主要的影响;鉴于此,在某些情况下(如在第三方应用中)禁止使用用户定义的触发器。Log Miner 不会影响性能,但它是依赖于存档日志的可用性来跟踪更改的。

  细粒度审计 (FGA),是在 Oracle 9i 中引入的,能够记录 SCN 号和行级的更改以重建旧的数据,但是它们只能用于 select 语句,而不能用于 DML,如 update、insert 和 delete 语句。因此,对于 Oracle 数据库 10g 之前的版本,使用触发器虽然对于以行级跟踪用户初始的更改是没有吸引力的选择,但它也是唯一可靠的方法。

  随着 Oracle 10g 的到来,由于审计能力的两个重大的改变,这些限制也随之而去。由于两种审计类型涉及到—标准审计(在所有版本中均可用)和细粒度审计(在 Oracle 9i 及其以上版本中可用)—我们将分别对它们进行处理,然后看看它们是如何相互补充以提供一个单一的、强大的跟踪功能。


  新特性

  首先,FGA 现在除了支持 select 语句外,还支持 DMA 语句。这些更改都记录在同一个位置,即表 FGA_LOG$ 中,并通过 DBA_FGA_AUDIT_TRAIL 视图显示出来。除了 DML 外,您现在可以选择只有在访问了所有或者甚至很少的相关的列后,才可以触发一个线索。(有关 FGA 在 Oracle 10g 中是如何工作的详细信息,请参阅该主题的我的技术文章的内容。)

  标准审计,是由 SQL 命令 AUDIT 执行的,可用于为特定的对象快速、容易地设置跟踪。例如,如果您想跟踪对 Scott 所拥有的表 EMP 的所有更新,您可以发出如下命令:

        audit UPDATE on SCOTT.EMP by access;

  任何用户每一次更新表 SCOTT.EMP 时,该命令都会把所有的更新记录到审计跟踪表 AUD$ 中,可以通过 DBA_AUDIT_TRAIL 视图来查看。

  这个功能对于 Oracle 10g 之前的版本也是可用的。但是,在那些版本中,写到跟踪中的信息仅限于少数相关的项,如:发出该语句的用户、时间、终端标识号等等;它缺少某些重要的信息,如绑定变量的值。在 Oracle 10g 中,除了以前的版本中所收集到的内容之外,审计操作还捕获了许多这些重要的信息片断。用于审计的原始表 AUD$,包含若干个用于记录它们的新列,相应地,DBA_AUDIT_TRAIL 视图也包含这些列。让我们详细地研究一下。

  EXTENDED_TIMESTAMP。 该列以 TIMESTAMP (6) 格式记录了审计记录的时间戳,它是用格林尼治标准时间(也称为全球统一时间)来记录时间的,其小数点后的秒数到 9 为止,并且带有时区信息。以这种格式存储的时间的一个例子如下所示。2004-3-13 18.10.13.123456000 -5:0日期表示为 2004 年 3 月 13 日,是美国的东部标准时间,它比全球统一时间晚 5 小时(用 -5.0 来表示)。这种以扩展格式显示的时间有助于把审计跟踪精确定位到一个更窄的时间间隔中,从而增强了它们的用途,特别是在数据库横跨多个时区时更是如此。


  GLOBAL_UID 和 PROXY_SESSIONID。 当使用某种身份管理组件如 Oracle Internet Directory 进行身份验证时,用户对数据库的访问权限稍有不同。例如,当将他们访问数据库时,可能将他们视为企业用户。审计这些用户不会在 DBA_AUDIT_TRAIL 视图的 USERNAME 列中记录他们的企业用户标识号,以使该信息无用。在 Oracle 数据库 10g 中,全局(或企业)用户唯一的标识号记录在 GLOBAL_UID 列中,并且没有作进一步的处理或设置。该列可用于查询目录服务器,以查找有关该企业用户的完整的详细信息。

  有时企业用户也许是通过一个代理用户连接到数据库,特别是在多层应用中。可以通过命令为用户提供代理身份验证:

        alter user scott grant connect to appuser;

  该命令将允许用户 SCOTT 以 APPUSER 的身份,作为代理用户连接到数据库。在那种情况下,COMMENT_TEXT 列将通过存储值 PROXY 来记录事实;但是对于 Oracle 9i 而言,代理用户的会话标识号将不会进行记录。在 Oracle 10g 中,PROXY_SESSIONID 列记录了它,用于精确标识代理会话。

  INSTANCE_NUMBER。 在 Oracle 真正应用集群 (RAC) 环境中,它可能有助于知道在进行更改时用户连接的是哪一个特定的例程。在 Oracle 10g 中,该列记录了例程号,它是由该例程的初始化参数文件指定的。

  OS_PROCESS。 在 Oracle 9i 及其较低的版本中,只会在审计跟踪中记录 SID 值;而不会记录操作系统进程标识号。但是,服务器进程的操作系统进程标识号随后可能是必要的,例如,用于交叉引用一个线索文件。在 Oracle 10g 中,该值也记录在该列中。

  TRANSACTIONID。 在此就产生了最关键的信息价格。假定用户发出下面的命令:

        update CLASS set size = 10 where class_id = 123;
        commit;


  该命令获取一个事务项,并且生成一个审计记录。但是,您怎样知道该审计记录真正记录的是什么内容呢?如果记录是一个事务,该事务标识号就会存储在该列中。您可以使用它把审计跟踪与 FLASHBACK_TRANSACTION_QUERY 视图联接起来。下面是该视图中的列的一个小示例:

        select start_scn, start_timestamp,
        commit_scn, commit_timestamp, undo_change#, row_id, undo_sql
        from flashback_transaction_query
        where xid = '<the transaction id>';

  除了记录对该事务所做的通常的统计外,如 undo change#、rowid 等等,Oracle 10g 还可以在 UNDO_SQL 列中记录撤消对事务所作更改 SQL 命令,以及在 ROW_ID 列显示的受影响行的 rowid。

  系统更改号。 最终,它记录更改前的值。您怎样执行该操作呢?按 Oracle 9i 中的 FGA 所指出的那样,更改前的值可以通过闪回查询来获取。但是您需要知道该更改的系统更改号 (SCN),它可以在审计跟踪的该列中捕获到。您可以发出下面的命令:

        select size from class as of SCN 123456
        where where class_id = 123;

  这将显示用户所看到的内容或更改前的值。

  扩展的 DB 审计

  记住我们最初的兴趣:为了捕获用户发出的 SQL 语句,以及在标准审计中无法捕获的绑定变量。在 Oracle 数据库 10g 中进入增强型审计,其中这些任务变得如同更改一个简单的初始化参数一样微不足道。只需把下列代码行放入参数文件中。

        audit_trail = db_extended

  如果使用该参数,该参数将在各列中记录 SQL 文本和绑定变量值。该值在早期的版本中不可用。

  触发器何时是必要的

  避免误检。 审计跟踪是通过来自于原始事务的自治事务生成的。因此,即使原始事务回滚,它们也会提交。


  有一个简单例子演示了这一点。假定我们已在表 CLASS 上为 UPDATE 设置了审计。用户发出一条语句以将数据值从 20 更新为 10,然后将其回滚,如下所示:

        update class set size = 10 where class_id = 123;
        rollback

  现在该列的 SIZE 值将变成 20,而不是 10,好像用户从未做过任何事情。但是,即使回滚,审计跟踪也将捕获该更改。在某些情况下这可能不是人们所想要的,尤其是用户执行了许多回滚时。在这种情况下,您也许不得不使用触发器仅捕获已提交的更改。如果表 CLASS 上有一个触发器用于将记录插入到用户定义的审计线索中,在回滚的基础上审计线索也被回滚。

  捕获之前更改的值。 Oracle 提供的审计跟踪不会显示更改前后的值。例如,上述的更改将创建一个审计记录,它显示了语句和更改的 SCN 号,但没有显示更改前的值 (20)。可以使用闪回查询通过 SCN 号获取该值,但是它依赖于在撤消段中可用的信息。如果该信息无法在由 undo_retention 时间段指定的期限内捕获到,就永远不能检索出先前的值来。使用触发器保证了无需依赖于 undo_retention 时间段即可捕获到该值,并且有时很有用。在这两种环境下,您可以决定继续使用触发器以细粒度的级别来记录审计跟踪。

  统一的审计跟踪

  由于 FGA 和标准审计捕获的是相同类型的信息,当把它们结合起来使用时可以提供许多重要的信息。Oracle 数据库 10g 把这些跟踪合并到一个称为 DBA_COMMON_AUDIT_TRAIL 的通用跟踪中,它是 DBA_AUDIT_TRAIL 视图和 DBA_FGA_AUDIT_TRAIL 视图的一个 UNION ALL 视图。但是,在这两种审计类型之间有一些重大的区别。

  结论

  在 Oracle 10g 中,审计已经从一个单纯的“操作记录者”成长为一个“事实记录机制”,它能以一个非常详细的级别来捕获用户的行为,这可以消除您对手动的、基于触发器的审计的需要。它还结合了标准审计和 FGA 的跟踪,这使其更易于跟踪数据库访问,而不用考虑它是如何生成的。

==============================================================

设置审计的实例:对试图尝试口令的访问的审计
本节讨论的是一个审计的实例,用于记录尝试通过野蛮尝试法破译ORACLE帐号口令的例子:

1. 修改审计相关参数(参照上一节介绍的方法)

2. 重启数据库

3. 设置审计信息

   SQL>AUDIT ALL BY ACCESS WHENEVER NOT SUCCESSFUL

4. 查询AUD$

   SQL> select returncode, action#, userid, userhost, terminal,timestamp

from aud$

    RETURNCODE    ACTION# USERID   USERHOST TERMINAL

   ---------- ---------- -------- -------------------- --------------------

    1017        100      SCOTT    WPRATA-BR

    1017        100      SCOTT    WPRATA-BR

    1017        100      SCOTT    WPRATA-BR

 

ORA-1017的含义为错误的用户名口令。通过查看AUD$表可以清楚地看到WPRATA-BR尝试破译SCOTT的口令。可以通过下面一个存储过程来分析AUD$表,找出可疑的信息:

create or replace procedure AuditLogin(Since Varchar2,Times PLS_Integer)

is

USER_ID VARCHAR2(20);

cursor c1 is select userid,count(*) from sys.aud$ where returncode='1017' and timestamp#>=to_date(Since,'yyyy-mm-dd')

group by userid;

cursor C2 IS Select userhost, terminal,TO_CHAR(timestamp#,'YYYY-MM-DD:HH24:MI:SS')

from sys.aud$ WHERE returncode='1017' and timestamp#>=to_date(Since,'yyyy-mm-dd') AND USERID=USER_ID;

ct PLS_INTEGER;

V_USERHOST VARCHAR2(40);

V_TERMINAL VARCHAR(40);

V_DATE VARCHAR2(40);

BEGIN

    OPEN C1;

    dbms_output.enable(1024000);

    LOOP

      FETCH C1 INTO USER_ID,CT;

      EXIT WHEN C1%NOTFOUND;

      IF(CT>=TIMES) THEN

        DBMS_OUTPUT.PUT_LINE('USER BROKEN ALARM:'||USER_ID);

        OPEN C2;

        LOOP

          FETCH C2 INTO V_USERhOST,V_TERMINAL,V_DATE;

          DBMS_OUTPUT.PUT_LINE(CHR(9)||'HOST:'||V_USERHOST||',TERM:'||V_TERMINAL||',TIME:'||V_DATE);

          EXIT WHEN C2%NOTFOUND;

        END LOOP;

        close c2;

      END IF;

    END LOOP;

    close c1;

END;

/

一下是执行结果:

SQL>set serveroutput on;

SQL> execute auditlogin('2004-01-01',2);

USER BROKEN ALARM:SYS

        HOST:,TERM:XUJI,TIME:2004-09-22:11:08:00

        HOST:,TERM:XUJI,TIME:2004-09-22:11:08:01

        HOST:,TERM:XUJI,TIME:2004-09-22:11:09:29

        HOST:,TERM:XUJI,TIME:2004-09-22:11:09:29

PL/SQL 过程已成功完成。

将审计相关的表移动到其他表空间
由于AUD$表等审计相关的表存放在SYSTEM表空间,因此为了不影响系统的性能,保护SYSTEM表空间,最好把AUD$移动到其他的表空间上。可以使用下面的语句来进行移动:

sql>connect / as sysdba;

sql>alter table aud$ move tablespace <new tablespace>;

sql>alter index I_aud1 rebuild online tablespace <new tablespace>;

SQL> alter table audit$ move tablespace <new tablespace>;

SQL> alter index i_audit rebuild online tablespace <new tablespace>;

SQL> alter table audit_actions move tablespace <new tablespace>;

SQL> alter index i_audit_actions rebuild online tablespace <new tablespace>;