Edit D:\app\Administrator\product\11.2.0\dbhome_1\sysman\admin\scripts\esaWin32Util.pl
#!/usr/local/bin/perl # # $Header: esaWin32Util.pl 06-jan-2007.08:05:10 dsukhwal Exp $ # # esaWin32Util.pl # # Copyright (c) 2005, 2007, Oracle. All rights reserved. # # NAME # esaWin32Util.pl - <one-line expansion of the name> # # DESCRIPTION # This module is to expose the APIs printACLs, fileType, win32_file_perm and win32_file_owner # # NOTES # <other useful comments, qualifications, etc.> # # MODIFIED (MM/DD/YY) # dsukhwal 01/06/07 - XbranchMerge manosing_ntpol from main # manosing 12/13/06 - modify GetVolumeInformation call # sejain 09/20/06 - bug-5362371 : fixing issue with volume-name length # rrawat 04/26/06 - Bug-5158358 # dsukhwal 01/12/06 - use TieRegistry # dsukhwal 12/13/05 - add trailing slash to driveletter for # filesystemtype # dsukhwal 11/16/05 - Check NTFS filesystem # dsukhwal 08/23/05 - fix windows errors # dsukhwal 06/17/05 - dsukhwal_win32_policies_3 # dsukhwal 05/01/05 - Creation # use strict; if(!($^O eq "MSWin32")){ exit(0); } use Win32::FileSecurity qw(Get EnumerateRights); use Win32API::File qw( :ALL ); use Win32::NetAdmin qw(LocalGroupGetMembersWithDomain); use Win32::TieRegistry ; my $oldDirCmd = $ENV{'DIRCMD'}; #to be restored later $ENV{'DIRCMD'} = ""; sub fileType{ #first argument is the file whose type you want to know. #returns "file" if it is not a directory, and "directory" if it is a directory #returns "error" if it does not exist, or there is some other error #Would work in UNIX like systems as well my $fileName = shift; if(opendir(FH, $fileName)){ close FH; return "directory"; } else{ if(open(FH, $fileName)){ close FH; return "file"; } else{ return "error"; } } } sub win32_file_owner{#first argument is the file whose owner you want to know my $fileName = shift; my $owner = ""; my $i = 0; if(fileType($fileName) eq "error"){#some error occurred, or the file does not exist return -1; } # / is not an allowed character in an NTFS filename # substitute all / with \ to get the correct filename $fileName =~ s/\//\\/g; if(fileType($fileName) eq "file"){#it is not a directory my $systemCommand = "cmd /c \"dir /q $fileName \" |"; if (!open(CHECKER, "$systemCommand")) { return -1; } my @lines = <CHECKER>; my $usefulLine = $lines[5]; my @tokens = split(/\s+/, $usefulLine); if(@tokens == 5){#for now, it will be assumed that only the owner and filename can get stuck together. #as and when new cases are discovered, they will be rectified my $onlyName = winFileName($fileName); my $givenName = $tokens[4]; $owner; if($givenName =~ /^(.*)$onlyName$/i){ $owner = $1; } else{ } } elsif(@tokens == 6){ $owner = $tokens[4]; } else{ } } elsif(fileType($fileName) eq "directory"){#it is a directory my $onlyName = winFileName($fileName); my $systemCommand = qq(cmd /c "dir /q /ad $fileName " |); if (!open(CHECKER, "$systemCommand")) { return -1; } $systemCommand =~ s/\|/\!/g; my @lines = <CHECKER>; #contains the lines generated by dir shift (@lines);#assuming that 5 lines are header, and two are tail shift (@lines); shift (@lines); shift (@lines); shift (@lines); pop(@lines); pop(@lines); #assuming that . will be the first entry in the directory listing $_ = shift(@lines); if(m/(.*)(\s+)(\S+)(\s*)\.$/){ s/(.*)(\s+)(\S+)(\s*)\.$/$3/; $owner = $_; } else{#the dir command gave some UNIMAginable output. Giving up. return -1; } } chomp $owner; return $owner; } sub winFileName{#first arguments is the file path #returns the last part of the filename(after removal of the containing directory) $_ = shift; s/^(.*)\\(.*)$/$2/; return $_; } sub printACLs{ #first argument is the filename #second argument is the property #third(optional) argument is the maximum number of rows to print(defaults to 200) #returns the number of rows it printed my $fileName = shift; my $prop = shift; my $maxCount = shift;#will not print more than $maxCount rows, no matter what if(!defined($maxCount)){ $maxCount=200; } my ($res, $numRows) = getACLs($fileName, $maxCount); if($res == -1){ return -1; } my %hash = %$res; my $user;my $right; foreach $user (keys %hash){ my $arrRef = $hash{$user}; my @rightsArray = @$arrRef; foreach $right (@rightsArray){ my $translatedRight = translate($right); print "em_result=$prop|$fileName|$user:$translatedRight\n"; } } return $numRows; } sub win32_file_perm{ #first argument is the filename #returns the string made up of the number of users having critical permissions on the file, followed by the #user names(upto a maximum of 512 characters) my $fileName = shift; my ($res, $numRows) = getACLs($fileName, 1000);#1000 is the maximum number of rows getACLs will return. #This is to prevent overload on the agent if($res == -1){ return -1; } my @usersWithCritRights; my %hash = %$res; my $user; foreach $user (keys %hash){ my $arrRef = $hash{$user}; my @rightsArray = @$arrRef; foreach (@rightsArray){ if( (/DELETE/i) || (/WRITE_DAC/i) || (/WRITE_OWNER/i) || (/CHANGE/i) || (/ADD/i) || (/FULL/i) ){ push(@usersWithCritRights, $user); last; } } } my $i=0; foreach (@usersWithCritRights){ $i++; } my $concat = (scalar @usersWithCritRights)."(".join(", ",@usersWithCritRights).")"; return $concat; } sub getACLs{ #first argument is the filename #second(optional) argument is the maximum number of entries to return in the hash(defaults to 200) #return -1 if there is any error in getting the ACLs my $fileName = shift; my $maxCount = shift;#will not return more than $maxCount rows, no matter what if(!defined($maxCount)){ $maxCount=200; } my $count = 0; my $owner = win32_file_owner($fileName); if($owner == -1){ return -1; } my $driveLetter = $fileName; if (!($driveLetter =~ m/(.*):(.*)/)){ return -1; #Windows NT filenames without colons are not supported } $driveLetter =~ s/(.*?)(:)(.*)/$1$2/; $driveLetter = $driveLetter."/";#sometimes, GetVolumeInformation prefers the trailing slash my $osVolName; my $ouSerialNum; my $ouMaxNameLen; my $ouFsFlags; my $osFsType; #Removing the third arument to GetVolumeInformation as it is causing issue if volume-name is more than 8 chars GetVolumeInformation( $driveLetter, $osVolName,'', $ouSerialNum, $ouMaxNameLen, $ouFsFlags, $osFsType, 8 ); if (!($osFsType =~ 'NTFS')){ return -1;#the filesystem is not NTFS, forget about ACLs } my %hash; my $name;my $mask;my $entry; my %resultHash; if ( Get( $fileName, \%hash ) ) { while( ($name, $mask) = each %hash ) { #check whether $name is the owner of $filename if(lc($name) eq lc($owner)){ next; } else{ my @rights; EnumerateRights($mask, \@rights ); $count+=@rights; if($count < $maxCount){ $resultHash{$name} = \@rights; next; } else{ splice(@rights, $maxCount - $count + @rights); $resultHash{$name} = \@rights; last; } } } } return (\%resultHash, $count); } sub translate{ #first argument is a windows privilege name. Returns the name in a more readable format $_ = shift; $_ = uc($_); if(/STANDARD_RIGHTS_READ/i) {return "Standard Rights Read";} elsif(/DELETE/i) {return "Delete";} elsif(/READ_CONTROL/i) {return "Read File Attribute";} elsif(/WRITE_DAC/i) {return "Change DACL";} elsif(/WRITE_OWNER/i) {return "Take Ownership";} elsif(/SYNCHRONIZE/i) {return "Synchronize";} elsif(/STANDARD_RIGHTS_REQUIRED/i) {return "Standard Rights Required";} elsif(/STANDARD_RIGHTS_WRITE/i) {return "Standard Rights Write";} elsif(/STANDARD_RIGHTS_EXECUTE/i) {return "Standard Rights Execute";} elsif(/STANDARD_RIGHTS_ALL/i) {return "Standard Rights All";} elsif(/GENERIC_READ/i) {return "Generic Read";} elsif(/GENERIC_EXECUTE/i) {return "Generic Execute";} elsif(/READ/i) {return "Read";} elsif(/CHANGE/i) {return "Change";} elsif(/ADD/i) {return "Add";} elsif(/FULL/i) {return "Full";} else {return $_;} } sub win32_comma_sep_files_perm{#the subroutine comma_separated_files should suffice for file owner, as the file_owner #subroutine can be used with linux as well as MSWin32 #first argument is the comma separated files list #second argument is the maximum number of rows that are to be printed(if -1, no limit on the number of rows) #third argument is the property. #the subroutine prints the permissions of the files my $commFilesList = shift; my $maxCount = shift; my $property = shift; my $fileName; $commFilesList =~ s/\s+//g; my @fileList = split(/,/, $commFilesList); if( defined($maxCount) && ($maxCount >= 0) ){ splice(@fileList, $maxCount); }#keep at most maxCount entries foreach $fileName (@fileList){ my $perm = check_512char(win32_file_perm($fileName)); if($perm != -1){ print "em_result=$property|$perm|$fileName\n"; } } } $ENV{'DIRCMD'} = $oldDirCmd; 1;
Ms-Dos/Windows
Unix
Write backup
jsp File Browser version 1.2 by
www.vonloesch.de