#!/usr/local/bin/perl # # $Header: emdb/sysman/admin/scripts/dv/realmviolations.pl /st_emdbsa_11.2/1 2009/02/12 23:34:24 hpalitan Exp $ # # realmviolations.pl # # Copyright (c) 2008, 2009, Oracle and/or its affiliates.All rights reserved. # # NAME # realmviolations.pl - # # DESCRIPTION # # # NOTES # # # MODIFIED (MM/DD/YY) # hpalitan 01/15/09 - Bug #7716543 # hpalitan 10/29/08 - Check if the DB is DV enable before running metric # sql # amahalin 09/12/08 - # hpalitan 08/31/08 - Collect Database Vault Realm Violations # hpalitan 08/31/08 - Creation # use strict; use Oraperl; use DBI; require "emd_common.pl"; require "semd_common.pl"; if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug --> ++++ Welcome to Database Vault Realm Violation Debugging ++++ "); } # Declare the subroutines sub trim($); sub checkForPatch($$); # -------------------------------------------------------------------- # +++ VARIABLES # -------------------------------------------------------------------- # GENERAL my @fetch_row; my $lda; my $audit_trail_sql; my $audit_trail_cur; my $audit_trail_value; my $timestamp_last_run=""; my $mode = 0; my $realm_key = ""; my $realm_scanned_till_id = "0"; my $command_rule_key = ""; my $command_rule_scanned_till_id = "0"; # Used to check if DB is DV enabled my @is_dv_enabled_fetch_row; my $is_dv_enabled_lda; my $is_dv_enabled_cur; my $is_dv_enabled = "-1"; my $is_dv_enabled_sql; # OUTPUT my $violationsList=""; # INPUT # The DB Connection info is passed in by the metric definition my %stdinArgs = get_stdinvars(); my $username = $stdinArgs{"EM_TARGET_USERNAME"}; my $password = $stdinArgs{"EM_TARGET_PASSWORD"}; my $address = $ENV{EM_TARGET_ADDRESS}; my $role = $ENV{EM_TARGET_ROLE}; my $state_root = $ENV{EM_AGENT_STATE_DIR}; my $targetGuid = $ENV{EM_TARGET_GUID}; if($role =~ /SYSDBA/i) { $mode = 2; } elsif($role =~ /SYSOPER/i) { $mode = 4; } if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug username : $username"); EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug address : $address"); EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug role : $role"); EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug state_root : $state_root"); EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug targetGuid : $targetGuid"); } # -------------------------------------------------------------------- # +++ Code snippet to check if Target DB is DV enabled # -------------------------------------------------------------------- $is_dv_enabled_lda = DBI->connect('dbi:Oracle:', "$username@".$address, "$password", {ora_session_mode => $mode, PrintError => 0, RaiseError => 0}) or die (filterOraError("em_error=Could not connect to $username/$address: $DBI::errstr\n", $DBI::err)); register_metric_call($is_dv_enabled_lda); #$is_dv_enabled_sql = "select case when (((select count(*) from dba_users where username =\'DVSYS\' and user_id = 1279990)> 0)) then decode(value,\'TRUE\',1,\'FALSE\',0) else -1 end into dv_status from v\$option where parameter = \'Oracle Database Vault\'"; #$is_dv_enabled_sql = "select decode(value,'TRUE',1,'FALSE',0) as dv_status from v\$option where parameter = 'Oracle Database Vault'"; #sql shoulds run independend of $is_dv_enabled_sql = "select count(*) from dba_users where username ='DVSYS' and user_id = 1279990"; $is_dv_enabled_cur = $is_dv_enabled_lda->prepare($is_dv_enabled_sql) or die (filterOraError("em_error=prepare($is_dv_enabled_sql): $DBI::errstr\n", $DBI::err)); $is_dv_enabled_cur->execute() or die (filterOraError("em_error=is_dv_enabled_cur->execute(): $DBI::errstr\n", $DBI::err)); while (my ($is_dv_enabled1) = $is_dv_enabled_cur->fetchrow_array()) # keep fetching until there's nothing left { $is_dv_enabled = trim($is_dv_enabled1); } $is_dv_enabled_lda->disconnect or warn "disconnect $DBI::errstr\n"; if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug is_dv_enabled : $is_dv_enabled"); } if ($is_dv_enabled == "1") { } else { if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug Database Vault is not enabled on $address"); } exit 0; } # -------------------------------------------------------------------- my $separator = $^O =~ m/MSWin32/ ? "\\" : "\/"; # # Location of the offsets state file is # $EMDROOT/sysman/emd/state/. # my $scannedFile = $state_root.$separator."sysman".$separator."emd".$separator."state".$separator."$targetGuid"."_dv_realm_violations.log"; if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug separator : $separator"); EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug scannedFile : $scannedFile"); } #print "\n State file: $scannedFile \n"; # ------------------------------------------------------------------ # Open scanned file for reading (if scanned file does not exist, create it.) # ------------------------------------------------------------------ if (!open(SCANNED, "+>> $scannedFile")) { EMAGENT_PERL_ERROR("DatabaseVaultRealmViolation: $targetGuid; Cannot open $scannedFile for read/write."); exit 1; } # seek to top of file seek(SCANNED, 0, 0); # file only contains a single line with two numbers: a timestamp and a count # get these and close the scanned file my $cnt=0; while () { if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug Row $cnt : $_"); } my @pos = split('~', $_); my $pos = \@pos; if ($cnt == 0) { $realm_key = $pos->[0]; $realm_scanned_till_id = $pos->[1]; } # if ($cnt != 0) # { # $command_rule_key = $pos->[0]; # $command_rule_scanned_till_id = $pos->[1]; # } $cnt += 1; } close(SCANNED); if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug realm_scanned_till_id : $realm_scanned_till_id"); # EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug command_rule_scanned_till_id : $command_rule_scanned_till_id"); } # -------------------------------------------------------------------- # +++ Establish Target DB Connection # -------------------------------------------------------------------- #print "1"; $lda = DBI->connect('dbi:Oracle:', "$username@".$address, "$password", {ora_session_mode => $mode, PrintError => 0, RaiseError => 0}) or die (filterOraError("em_error=Could not connect to $username/$address: $DBI::errstr\n", $DBI::err)); register_metric_call($lda); # --------------------------------- # +++ Get realm violations # --------------------------------- #print "2"; $audit_trail_sql = "select * from (select id#, action_object_name, action_command, TO_CHAR(CAST(timestamp AS TIMESTAMP) , 'YYYY-MM-DD HH24:MI:SS TZD') timestamp from dvsys.audit_trail\$ where id# > ". $realm_scanned_till_id ." and returncode <> 0 and action between 10003 and 10004 order by id# asc) "; #$audit_trail_sql = "select * from (select id#, action_object_name, action_command, TO_CHAR(CAST(timestamp AS TIMESTAMP) , 'YYYY-MM-DD HH24:MI:SS TZD') timestamp from dvsys.audit_trail\$ where id#>0 and action between 10003 and 10004 order by id# asc) where rownum<10"; #$audit_trail_sql = "select null, null, null, null from dvsys.audit_trail\$ where 1=2 and id# > ". $realm_scanned_till_id ." and action between 10003 and 10004 order by id# asc"; #$audit_trail_sql = "select * from dvsys.audit_trail\$"; $audit_trail_cur = $lda->prepare($audit_trail_sql) or die (checkForPatch("em_error=prepare($audit_trail_sql): $DBI::errstr\n", $DBI::err)); if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug Passed prepare of audit_trail_sql"); } $audit_trail_cur->execute() or die (checkForPatch("em_error=audit_trail_cur->execute(): $DBI::errstr\n", $DBI::err)); if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug Passed execute of audit_trail_sql"); } # ------------------------------------------ # +++ Fetch realm violations from resultset # ------------------------------------------ #print "3"; my $maxid = $realm_scanned_till_id ; my $fmtline=""; $cnt=1; my $action_object_name_1 = ""; my $action_command_1 = ""; my $timestamp_1 = ""; while (my ($id, $action_object_name, $action_command, $timestamp) = $audit_trail_cur->fetchrow_array()) # keep fetching until # there's nothing left { $action_object_name = trim($action_object_name); $action_command = trim($action_command); $timestamp = trim($timestamp); if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug >>> $action_object_name|$action_command|$timestamp"); EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug <<< $action_object_name_1|$action_command_1|$timestamp_1"); } if(($action_object_name eq $action_object_name_1) && ($timestamp eq $timestamp_1)) { # if($action_command eq $action_command_1) # { #if (EMAGENT_isPerlDebugEnabled()) #{ # EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug Duplicate attempted violation, no need to report"); #} #Duplicate attempted violation, no need to report. # }else{ #if (EMAGENT_isPerlDebugEnabled()) #{ # EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug Realm name and time is the same, however error message is different"); #} if($action_command ne $action_command_1) { $fmtline = "em_result=$action_object_name|$action_command|$timestamp.$cnt\n"; $cnt += 1; } }else{ #if (EMAGENT_isPerlDebugEnabled()) #{ # EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug different violation"); #} $fmtline = "em_result=$action_object_name|$action_command|$timestamp\n"; $cnt = 1; } $action_object_name_1 = $action_object_name; $action_command_1 = $action_command; $timestamp_1 = $timestamp; if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug fmtline $fmtline"); } if($fmtline ne "") { #if (EMAGENT_isPerlDebugEnabled()) #{ # EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug fmtline is not empty"); #} $violationsList .= $fmtline; if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug violationsList $violationsList"); } } if($id > $maxid) { $maxid = $id; } $fmtline=""; } #$violationsList .= "\n"; if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug maxid : $maxid"); } # -------------------------------------------------------------------- # Reopen scanned file and write out new offset (log size), line number, # and time # # -------------------------------------------------------------------- open (SCANNED, "+> $scannedFile") or die "em_error=Cannot open $scannedFile"; print SCANNED "realm_key~$maxid"."\n"; #print SCANNED "command_rule_key~$command_rule_scanned_till_id"."\n"; close(SCANNED); if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug violationsList:\n$violationsList"); } # -------------------------------------------------------------------- # +++ Print Results # # This returns the results to the agent, which will look for a # standard output line that starts with em_result. The '|' character # is the delimiter between values. # -------------------------------------------------------------------- print $violationsList; # -------------------------------------------------------------------- # +++ Disconnect from the Target DB # -------------------------------------------------------------------- $lda->disconnect or warn "disconnect $DBI::errstr\n"; # Perl trim function to remove whitespace from the start and end of the string sub trim($) { my $string = shift; $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; } sub checkForPatch($$) { my $argsListSize = @_; my $userErrMsg = shift(@_); my $inOraError = shift(@_); if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug userErrMsg : $userErrMsg"); EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug inOraError :$inOraError"); } my $isErrorSkiped; $isErrorSkiped = filterOraError($userErrMsg, $inOraError); if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug isErrorSkiped: $isErrorSkiped"); } if($isErrorSkiped =~ m/^<<>>/){ if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug isErrorSkiped: $isErrorSkiped"); } return $isErrorSkiped; } if($inOraError =~ m/1031/){ if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug inOraError: $inOraError"); EMD_PERL_DEBUG ("\"Database Vault Manageability patch for Enterprise Manager\" has not been applied to this database. Refer to support note 760748.1 for more details"); # EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug em_error=Oracle Enterprise Manager requires patch #7319691 on this target. The patch can be downloaded from https://metalink.oracle.com"); } # print "Oracle Enterprise Manager requires patch #7319691 on this target. The patch can be downloaded from https://metalink.oracle.com"; print "\"Database Vault Manageability patch for Enterprise Manager\" has not been applied to this database. Refer to support note 760748.1 for more details"; exit 1; } if (EMAGENT_isPerlDebugEnabled()) { EMD_PERL_DEBUG ("DatabaseVaultRealmViolation:Debug inOraError: $inOraError"); } return $inOraError; } exit 0;