oracle 登录触发器/审计方法,用于识别使用sys/系统连接的程序/包/模块/过程

a1o7rhls  于 2023-08-03  发布在  Oracle
关注(0)|答案(1)|浏览(94)

在我的数据库中,许多程序/模块使用sys/system连接来执行数据操作。
例如:sys/ as sysdba
执行dml,ddl或任何用户要求。
我想用其他用户替换此连接字符串。有没有什么方法可以识别这些程序/模块/过程/包,这些程序/模块/过程/包是通过sys/system运行的?
我的要求是找到所有使用sys/system连接字符串的程序

6za6bjd0

6za6bjd01#

当然。虽然标准的审计会为你提供一些信息,但它是相当有限的。您需要一个登录触发器来捕获丰富的会话信息并将其记入日志。下面是一个例子:

CREATE OR REPLACE TRIGGER SYS.LOG_SYS_CONNECTIONS
AFTER LOGON
ON DATABASE
DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  IF USER != 'SYS' OR SYS_CONTEXT('USERENV','SESSIONID') IN (0,4294967295) -- background processes
  THEN
    NULL;
  ELSE
    EXECUTE IMMEDIATE '
       INSERT INTO sys.sys_connection_log
              (s.username,
               s.client_os_user,
               s.process,
               s.machine,
               s.program,
               s.service_name,
               s.sid,
               s.serial#,
               s.logon_time,
               cix.authentication_type,
               cix.client_charset,
               cix.client_version,
               cix.client_driver,
               SYS_CONTEXT(''USERENV'',''PROXY_USER'') proxy_user,
               SYS_CONTEXT(''USERENV'',''DBLINK_INFO'') dblink_info,
               SYS_CONTEXT(''USERENV'',''AUTHENTICATED_IDENTITY'') authenticated_identity,
               SYS_CONTEXT(''USERENV'',''AUTHENTICATION_METHOD'') authentication_method
          FROM v$session s
               OUTER APPLY (SELECT MAX(NULLIF(authentication_type,''Unknown'')) authentication_type,
                                   MAX(NULLIF(client_charset,''Unknown'')) client_charset,
                                   MAX(NULLIF(client_version,''Unknown'')) client_version,
                                   MAX(NULLIF(client_driver,''Unknown'')) client_driver
                              FROM v$session_connect_info ci
                             WHERE ci.sid = s.sid
                               AND ci.serial# = s.serial#) cix
         WHERE sid = SYS_CONTEXT(''USERENV'',''SID'')
    ';
    
    COMMIT;
  END IF;
EXCEPTION 
  WHEN OTHERS THEN
    NULL;
END;
/

字符串
显然,您需要创建日志记录表(在我的示例中为sys_connection_log)。几点注意事项:
1.为了防止后台进程出现问题,我们检查audsid(SYS_CONTEXT('USERENV','SESSIONID')返回v$session.audsid,对于后台进程,它是0或0,4294967295),如果它是后台进程,则不执行任何操作。只是格外小心。我们可以简单地查询v$session并查看TYPE,但这允许我们甚至不需要一个查询就退出。
1.插入本身被 Package 在一个动态EXECUTE IMMEDIATE块中。虽然这不是绝对必要的,因为SQL没有任何动态性,但这是一种安全措施。如果您的SQL有任何问题,或者如果您的日志记录表被删除,或者任何可能导致SQL解析失败的情况,您都不希望触发器变得无效,并可能阻止登录的发生。这样,任何解析失败都会在触发器中引发一个异常,然后我们处理它,什么也不做(WHEN OTHERS THEN NULL)。
1.我们使用一个自治事务,这样就可以提交insert。这对于登录触发器可能不是必需的,因为Oracle可能仍然有一个隐式提交,它将跟随触发器,因为它是一个系统事件,但为了确保,我们希望确保我们的记录被保留。在没有PRAGMA AUTONOMOUS_TRANSACTION的触发器中不能执行提交。

相关问题