#!/usr/local/bin/perl
# 
# $Header: iFileRefPerm.pl 12-jan-2007.12:11:49 manosing Exp $
#
# iFileRefPerm.pl
# 
# Copyright (c) 2004, 2006, Oracle. All rights reserved.  
#
#    NAME
#      iFileRefPerm.pl - <one-line expansion of the name>
#
#    DESCRIPTION
#      <short description of component this file declares/defines>
#
#    NOTES
#      <other useful comments, qualifications, etc.>
#
#    MODIFIED   (MM/DD/YY)
#    manosing    01/12/07 - XbranchMerge manosing_lastpols from main
#    manosing    12/28/06 - flood control for windows policy
#    manosing    12/21/06 - adding check for "0()
#    dsukhwal    12/13/05 - handle init.ora location in windows 
#    dsukhwal    05/13/05 - limit number of rows pushed 
#    dsukhwal    05/04/05 - handle win32 cases 
#    dkjain      03/08/05 - Fixed bug-4224875 
#    dsukhwal    02/15/05 - exceptional cases in file_perm usage 
#    dkjain      12/25/04 - Add permissions checking for upto third level of reference
#    dkjain      10/31/04 - Fixed unable to connect
#    dkjain      10/08/04 - dkjain_esa_impl_init
#    dkjain      10/08/04 - Creation
# 
 require "emd_common.pl";
 require "semd_common.pl";
 require "$ENV{EMDROOT}/sysman/admin/scripts/db/esaDbUtils.pl";
 require "$ENV{EMDROOT}/sysman/admin/scripts/db/esaUtils.pl";

 my $dsn = "dbi:Oracle:" ;
 my %stdinArgs = get_stdinvars();
 my $username = $stdinArgs{"EM_TARGET_USERNAME"};
 my $password = $stdinArgs{"EM_TARGET_PASSWORD"};
 my $oracleHome = $ENV{EM_TARGET_ORACLE_HOME};
 my $dbSid = $ENV{DB_SID};
 my $address = $ENV{EM_TARGET_ADDRESS};
 my $role = $ENV{EM_TARGET_ROLE};
 my $mode = 0;
 my $maxCount;

 if($^O eq "MSWin32"){ 
    $maxCount = $ENV{'NIFILEMAX'};
 }else{
    $maxCount = $ENV{'IFILEMAX'};
 }
 
 if($role =~ /SYSDBA/i)
 {
   $mode = 2;
 }
 elsif($role =~ /SYSOPER/i)
 {
    $mode = 4;
 }
 my $table = "v\$parameter";  
 my $value = "value";
 my $name = "name";
 my $rowNum = 0;

 my $dbh = open_db_connection("dbi:Oracle:", "$username@".$address,$password,$mode); 
 my @spfile = getValue($dbh,$value,$name, "spfile",$table);

 my @firstLevelList ;
 my @secondLevelList ;
 my @thirdLevelList ;
 my $level ;
 if($spfile[0] eq ""){
   # That means spfile was not used to mount the db. Let query pfile at default location
   in_pfile();
 } 
 close_db_connection($dbh);
 exit(0);

 sub in_pfile() {
 my $file ;

 $level = 1 ;
 my $pfile;
 if($^O =~ "MSWin32") {
   $table = "v\$version" ;
   my $sth = $dbh->prepare_cached("SELECT banner FROM $table where banner like '%Oracle%' ")
         or die print "em_error=Couldn't prepare statement: $dbh->errstr" ;
   $sth->execute()
         or die print "em_error=Couldn't execute statement: $sth->errstr" ;
   my @edition = $sth->fetchrow_array();
   if( ($edition[0] =~ m/10g/) && !(($edition[0] =~ m/10\.1/)) ){#should match 10gR2 and above
                                                    #will need modification after rdbms version 11
       $pfile = "$oracleHome\\database\\init$dbSid.ora";
   }
   else{
       my @db_name = getValue($dbh, "value","name", "db_name", 'v$parameter');
       $pfile = "$oracleHome\\admin\\".$db_name[0]."\\pfile\\init$dbSid.ora";
   } 
  }
  else {
   $pfile = "$oracleHome/dbs/init$dbSid.ora"; #default location and default name for unixes
  }
 parse_ifile_line($pfile);
 
 $level = 2 ;
 foreach $file (@firstLevelList)
 {
   parse_ifile_line($file);
 }
 
 $level = 3 ;
 foreach $file (@secondLevelList)
 {
   parse_ifile_line($file);
 }
}
 sub parse_ifile_line {
  my $iFile = shift ;
  unless (open ( FILE, $iFile)){
      return ;
  }
  my $line ;
  my @splitLine ;
  my $permMode ;
  my @info = <FILE> ;

  foreach $line (@info){
   if(($line =~ /^\s*[^#]*\.ifile/i)||($line =~ /^\s*ifile/i)){
     @splitLine = split(/=/,$line);
     $splitLine[1] = remove_pound($splitLine[1]); 
     $splitLine[1] = trim_whitespace($splitLine[1]);
     if($^O eq "linux"){
         $permMode = file_perm($splitLine[1]);
    	 if($permMode >= 0){
           $permMode = $permMode & 0777;
    	   if($permMode & 006){
             if(check_existence($splitLine[1])  &&  compareNegInf($rowNum,$maxCount)){
               printf "em_result=oh_ifile_perm|%03o|$splitLine[1]\n",$permMode;  
               $rowNum++;
             }
           }
         }
     }
     elsif($^O eq "MSWin32"){
        if(!compareNegInf($rowNum, $maxCount)){
            exit(0);
        }
        if(check_existence($splitLine[1])){
            my $users = win32_file_perm($splitLine[1]);
            if($users != -1){
                if($users ne "0()"){
                    print "em_result=nt_oh_ifile_perm|$users|$splitLine[1]\n";
                    $rowNum++;
                }
            }
        }
     }
  }
  }
 }

 sub remove_pound{
 my $line = shift ;
 my @tmp ;

 if($line =~ "#"){
 @tmp = split(/#/,$line);
   return $tmp[0] ;  
 }
 return $line ;
}

 sub trim_whitespace($){
   my $string = shift;
   $string =~ s/^\s+//; 
   $string =~ s/\s+$//;
   if(($string =~ "'")||($string =~ '"')){
     my $len = length($string);
     $string = substr($string,1,$len-2);
   } 
   return $string;
 } 
 
 sub check_existence{
   my $iFile = shift ;
   my $notFound = 1 ;
   my @completeList = (@firstLevelList,@secondLevelList,@thirdLevelList) ;
   foreach $file (@completeList){
     if($iFile eq $file){
      $notFound = 0 ;
      return $notFound ;       
     }
   } 
   if($level == 1){
     my $len = @firstLevelList ;
     $firstLevelList[$len] = $iFile ;
     return $notFound ;
   }
   elsif($level == 2){
     my $len = @secondLevelList ;
     $secondLevelList[$len] = $iFile ;
     return $notFound ;
   }
   else{
     my $len = @thirdLevelList ;
     $thirdLevelList[$len] = $iFile ;
     return $notFound ;
   }
 }
