#!/usr/local/bin/perl # # $Header: lsnrParams.pl 12-jan-2007.12:11:54 manosing Exp $ # # lsnrParams.pl # # Copyright (c) 2004, 2007, Oracle. All rights reserved. # # NAME # lsnrParams.pl - # # DESCRIPTION # # # NOTES # # # MODIFIED (MM/DD/YY) # manosing 01/12/07 - XbranchMerge manosing_lastpols from main # manosing 12/28/06 - flood control for windows policy # manosing 10/09/06 - inbound_connect_timeout # dsukhwal 07/22/05 - parse listener.ora too for hostname # dsukhwal 06/30/05 - support flood control for all policies # dkjain 06/27/05 - Adding check for oms ver # dsukhwal 05/13/05 - limit number of rows pushed # dsukhwal 05/01/05 - handle win32 cases # dsukhwal 03/17/05 - address correct listener # dsukhwal 02/15/05 - exceptional cases in file_perm usage # dsukhwal 12/28/04 - Permissions of backups of listener.ora # dsukhwal 12/28/04 - Query running listener # dsukhwal 12/14/04 - Display permissions in rwx format(bug 4057002) # dsukhwal 11/24/04 - change some extract_parameter_par to line # dsukhwal 11/23/04 - fix lsnrAdmin empty value # dkjain 10/13/04 - NA removed # dkjain 10/08/04 - dkjain_esa_impl_init # dkjain 10/08/04 - Creation # use strict; require "$ENV{EMDROOT}/sysman/admin/scripts/db/esaUtils.pl"; require "$ENV{EMDROOT}/sysman/admin/scripts/db/net/listenerUtil.pl"; use vars qw($NT $S); #both come from db_common.pl require "$ENV{EMDROOT}/sysman/admin/scripts/db/db_common.pl"; $S = qq($S); #$S = "\\"; #$ENV{'SLASH'}=$S; my $name = $ENV{LSNR_NAME}; my $listenerFile = $ENV{'LSNR_ORA_DIR'}.$S."listener.ora"; my $executable= $ENV{LSNR_ORACLE_HOME}.$S."bin".$S."lsnrctl"; my $machine = $ENV{LSNR_MACHINE}; my $port = $ENV{LSNR_PORT}; my $address="(ADDRESS=(PROTOCOL=TCP)(HOST=$machine)(PORT=$port))"; my $tgtOracleHome = $ENV{'LSNR_ORACLE_HOME'}; my $oms_ver=$ENV{OMS_VERSION}; #print "em_result=DEBUG|$oms_ver|NA\n"; if(!($oms_ver =~ "10.1")){ lsnr_host_ip(); #queries running listener. lsnr_trace_file();#queries running listener, uploads 2 properties trace_file_lsnr_own and trace_file_lsnr_perm lsnr_trace_directory();#queries running listener, uploads 2 properties trace_dir_lsnr_perm and trace_dir_lsnr_own lsnr_log_file();#queries running listener, uploads 2 properties log_file_lsnr_own and log_file_lsnr_perm lsnr_ora_perms(); #if(!($oms_ver =~ "10.2.0.2") && !($oms_ver =~ "10.2.0.3")){ #if(!($oms_ver =~ "10.2.0.2")){ lsnr_inbound_connect_timeout(); #} #uploads only for 10gR4 n onwards } #uploads only for 10gR2 n onwards lsnr_admin_status(); #parses the file sub lsnr_host_ip { my @command = ("set current_listener $address", "status"); my $result; my $n; my @hosts; my $maxRows = $ENV{'HOSTNAMEMAX'}; eval { $result = getResult($executable,\@command,$listenerFile,$name); }; if($@) { print "em_error=Failed to run lsnrctl\n"; exit; } ## parse result, remove the line containing "Connecting to", or "Current Listener is " #This is because these lines contain the IP address/hostname supplied by the targets.xml #and is not necessarily the address used by the listener.ora/tnsnames.ora etc. my @resultLines = split(/\n/,$result); for(my $n=0;$n<@resultLines;$n++){ if($resultLines[$n] =~ /(\s+)LSNRCTL>(\s+)Connecting to (.*)/){ $resultLines[$n] = ""; } if($resultLines[$n] =~ /(\s+)LSNRCTL>(\s+)Current Listener is (.*)/){ $resultLines[$n] = ""; } } $result = join("",@resultLines); $result =~ s/\s+//g; #remove blank spaces @hosts = split(/host=/i,$result); shift(@hosts); foreach (@hosts) { s/(.*?)\)(.|\n)*/$1/; } @hosts = uniq_array(@hosts); @hosts = remove_dynamic(@hosts); if(defined($maxRows) && ($maxRows >= 0)){ splice(@hosts, $maxRows); } foreach (@hosts) { print "em_result=host_name|$_|NA\n"; } } #this function gets the listener.ora file for the listener from the status of the running listener. #It then determines the directory by stripping the leading "listener.ora" from it. In this directory, #it searches all files having listener as a substring of their name(*listener* files) and #reports their permissions in octal format sub lsnr_ora_perms{ my @command = ("set current_listener $address", "status"); my $result; my @lines; my $perm; my $lsnr_ora_dir; my $maxRows; if($^O eq "MSWin32"){ $maxRows = $ENV{'NLOPERMMAX'}; }else{ $maxRows = $ENV{'LOPERMMAX'}; } my $rowNum = 0; eval { $result = getResult($executable,\@command,$listenerFile,$name); }; if($@) { print "em_error=Failed to run lsnrctl\n"; exit; } ## parse result @lines = split(/\n/,$result); foreach (@lines) { if (m/Listener Parameter File(\s+)(.*)/i) { my $slashForSplit = s/\\/\\\\/g; my @file_parts = split(/$slashForSplit/, $2); my $lastPart = pop(@file_parts); if(lc($lastPart) eq "listener.ora"){ $lsnr_ora_dir = join($S, @file_parts); } else{ $lsnr_ora_dir = ""; } last; } } if(!$lsnr_ora_dir){ # if lsnrctl status fails to provide the listener.ora directory, #we take the directory supplied in the targets.xml $lsnr_ora_dir = $ENV{'LSNR_ORA_DIR'}; } eval{ opendir(IMD, $lsnr_ora_dir) || die("Cannot open directory"); my @thefiles= readdir(IMD); closedir(IMD); foreach (@thefiles) { if($_ =~ /listener/ ) { if($^O eq "MSWin32"){#platform is win32 if(!compareNegInf($rowNum, $maxRows)){ return; } my $lsnrFile = $lsnr_ora_dir.$S.$_; my $win_perm = check_512char(win32_file_perm($lsnrFile)); if($win_perm != -1) { print "em_result=nt_lsnrora_permission|$lsnrFile|$win_perm\n"; $rowNum++; } } elsif($^O eq "linux"){#platform is linux if(!compareNegInf($rowNum, $maxRows)){ return; } $perm = file_perm($lsnr_ora_dir.$S.$_) & 0777; printf("em_result=lsnrora_permission|$lsnr_ora_dir$S$_|%03o\n",$perm); $rowNum++; } else{ #neither linux nor windows stuff } } } }; } sub lsnr_trace_file { #could have received this information from "lsnrctl show trc_file" also, but status shows the resultant trace file, #made up of information from trace directory and trace file. Hence, better suited for our purposes is "lsnrctl status" my @command = ("status $address"); my $result ; my @lines; my $trc_file; my $perm; my $permMax; my $ownMax = $ENV{'TFOWNMAX'}; my $permRowNum = 0; if($^O eq "MSWin32"){ $permMax = $ENV{'NTFPERMMAX'}; }else{ $permMax = $ENV{'TFPERMMAX'}; } eval { $result = getResult($executable,\@command,$listenerFile,$name); }; if($@) { print "em_error=Failed to run lsnrctl\n"; exit; } ## parse result @lines = split(/\n/,$result); foreach (@lines) { if (m/Listener Trace File(\s+)(.*)/i){ $trc_file = $2; compareOwner("trace_file_lsnr_own", $ownMax, $trc_file, $tgtOracleHome); if($^O eq "linux"){ $perm = file_perm($trc_file); if( ($perm >= 0) && compareNegInf($permRowNum, $permMax) ){ $perm = $perm & 0777; printf ("em_result=trace_file_lsnr_perm|$trc_file|%03o\n",$perm); $permRowNum++; } last; } elsif($^O eq "MSWin32"){ if(!compareNegInf($permRowNum, $permMax)){ return; } my $win_perm = check_512char(win32_file_perm($trc_file)); if($win_perm != -1){ print "em_result=nt_trace_file_lsnr_perm|$trc_file|$win_perm\n"; $permRowNum++; } } else{ #neither mswin32, nor linux stuff } } } } sub lsnr_trace_directory { my @command = ("set current_listener $address", "show trc_directory"); my $result ; my @lines; my $trc_dir; my $perm; my $permMax; my $ownMax = $ENV{'TDOWNMAX'}; my $permRowNum = 0; if($^O eq "MSWin32"){ $permMax = $ENV{'NTDPERMMAX'}; }else{ $permMax = $ENV{'TDPERMMAX'}; } eval { $result = getResult($executable,\@command,$listenerFile,$name); }; if($@) { print "em_error=Failed to run lsnrctl\n"; exit; } ## parse result @lines = split(/\n/,$result); pop(@lines); pop(@lines); $trc_dir = pop(@lines); $trc_dir =~ s/(.*)parameter \"trc_directory\" set to (.*)/$2/i; compareOwner("trace_dir_lsnr_own", $ownMax, $trc_dir, $tgtOracleHome); if($^O eq "linux"){ $perm = file_perm($trc_dir); if( ($perm >= 0) && compareNegInf($permRowNum, $permMax) ){ $perm = $perm & 0777; printf ("em_result=trace_dir_lsnr_perm|$trc_dir|%03o\n",$perm); $permRowNum++; } } elsif($^O eq "MSWin32"){ if(!compareNegInf($permRowNum, $permMax)){ return; } my $win_perm = check_512char(win32_file_perm($trc_dir)); if($win_perm != -1){ print "em_result=nt_trace_dir_lsnr_perm|$trc_dir|$win_perm\n"; $permRowNum++; } } else{ #neither mswin32, nor linux stuff } } sub lsnr_log_file { #could have received this information from "lsnrctl show log_file" also, but status shows the resultant log file, made #up of information from log directory and log file. Hence, better suited for our purposes is "lsnrctl status" my @command = ("set current_listener $address", "status"); my $result ; my @lines; my $log_file; my $perm; my $permMax; my $ownMax = $ENV{'LFOWNMAX'}; my $permRowNum = 0; if($^O eq "MSWin32"){ $permMax = $ENV{'NLFPERMMAX'}; }else{ $permMax = $ENV{'LFPERMMAX'}; } eval { $result = getResult($executable,\@command,$listenerFile,$name); }; if($@) { print "em_error=Failed to run lsnrctl\n"; exit; } ## parse result @lines = split(/\n/,$result); foreach (@lines) { if (m/Listener Log File(\s+)(.*)/i) { $log_file = $2; compareOwner("log_file_lsnr_own", $ownMax, $log_file, $tgtOracleHome); $perm = file_perm($log_file); if($^O eq "linux"){ if( ($perm >= 0) && compareNegInf($permRowNum, $permMax) ){ $perm = $perm & 0777; printf ("em_result=log_file_lsnr_perm|$log_file|%03o\n",$perm); $permRowNum++; } } elsif($^O eq "MSWin32"){ if(!compareNegInf($permRowNum, $permMax)){ return; } my $win_perm = check_512char(win32_file_perm($log_file)); if($win_perm != -1) { print "em_result=nt_log_file_lsnr_perm|$log_file|$win_perm\n"; $permRowNum++; } } else{ #neither mswin32, nor linux stuff } } } } sub parseFile { my ($configFile) = @_; my $CONFIG_FILE_READER; if(!-e $configFile) { print "em_error=File does not exist[$configFile]\n"; return; } open($CONFIG_FILE_READER, $configFile); if(!(defined $CONFIG_FILE_READER)) { print "em_error=File cound not be open for reading [$configFile]\n"; return; } my @info; my $line; while($line = <$CONFIG_FILE_READER>) { chomp($line); push(@info,$line); } close $CONFIG_FILE_READER; return @info; } sub lsnr_admin_status { my $rowNum = 0; my $maxRows = $ENV{'ADMINMAX'}; if(!compareNegInf($rowNum, $maxRows)){ return; } my $paramValue; my $line; my @info = parseFile($listenerFile); if ($@ || $#info < 0) { print "em_error=Failed to read listener.ora file\n"; exit; } foreach $line (@info) { #check for the ADMIN_RESTRICTIONS parameter beginning on a #new line without any leading whitespace. lsnrctl doesnt #recognize the parameter setting otherwise. if ($line =~ /^ADMIN_RESTRICTIONS_(.*)/i) { my @nvpair = split('=', $1); #need to verify presence of '=' and a value after it if ($#nvpair == 1) { if ($nvpair[0] =~ /^$name\s*$/i) { #found ADMIN_RESTRICTIONS_ $paramValue = $nvpair[1]; #trim the leading and trailing spaces $paramValue =~ s/^\s*(.*?)\s*$/$1/; last; } } } } if(defined($paramValue) && ($paramValue ne "")){ print "em_result=listenerAdmin|$paramValue\n"; } else{ print "em_result=listenerAdmin|NONE\n"; } } sub remove_dynamic{ my $CONFIG_FILE_READER; my @hosts; my $host; my %hostHash;#if a host $host is found in listener.ora file, $hostHash{lc($host)} is 1 open($CONFIG_FILE_READER, $listenerFile); if(!(defined $CONFIG_FILE_READER)) { print "em_error=File cound not be open for reading [$listenerFile]\n"; return @_; } my $line; while($line = <$CONFIG_FILE_READER>) { $line =~ s/(.*)#(.*)/$1/; #remove commented out characters $line =~ s/\s+//g;#remove white space if(!($line =~ /host=/i)){ next; } $line =~ s/^(.*)\(host=(.*?)\)(.*)$/$2/i; $hostHash{lc($line)} = 1; } close $CONFIG_FILE_READER; foreach $host (@_){ if(defined($hostHash{lc($host)})){ push(@hosts,$host); } } return @hosts; } sub lsnr_inbound_connect_timeout { my @command = ("set current_listener $address", "show inbound_connect_timeout"); my $result; my $maxRows = $ENV{'INBOUNDMAX'}; eval { $result = getResult($executable,\@command,$listenerFile,$name); }; if($@) { print "em_error=Failed to run lsnrctl\n"; exit; } ## parse result, extract the relevant line my @resultLines = split(/\n/,$result); $result = ""; for(my $n=0;$n<@resultLines;$n++){ if($resultLines[$n] =~ /parameter \"inbound_connect_timeout\" set to/){ $result = $resultLines[$n]; $result =~ s/(.*)parameter \"inbound_connect_timeout\" set to(\s+)(.*)$/$3/i; last; } } if($result eq "") { return; } if($maxRows != 0){#if -1, upload all rows, if >0, upload the one row that is possible. print "em_result=lsnr_inbound_connect_timeout|$result|NA\n"; } }