Technical Article

Share Permissions

,

Use this Perl script to produce an audit report of both share permissions and NTFS permissions of the shared folders. To report share permissions:
Use shareperms.pl -p -SMyServer1 to report on a single server.
Or use shareperms.pl -p -SMyServer1,MyServer2 for multiple servers.
You can also use a text file as input: shareperms.pl -p -CServers.txt
To report NTFS permissions use -n instead of -p. Script is designed to be run remotely producing csv output. The script uses RMTSHARE and FILEACL utilities available from Microsoft. Reporting share permissions is fast, however NTFS permissions can take longer depending on number of folders and ACLs. To limit output you can add /NOINHERITED parameter to FILEACL statement, see FILEACL /? for details.

#Program: Reports Share and Share NTFS Permissions by parsing RMTSHARE and fileacl output
#Download rmtshare from Microsoft:
#ftp://ftp.microsoft.com/bussys/winnt/winnt-public/reskit/nt40/i386/RMTSHAR.EXE
#Download fileacl from Microsoft:
#http://download.microsoft.com/download/d/2/b/d2b03e72-bf82-419e-b855-a84820daf069/fileacl.exe
#Author: Chad Miller cmille19@tampabay.rr.com
#Created: June 11 2006

use strict;
use Getopt::Std;

Main: {
  my ($report,$serversAR) = getOpts();
  my $shareRef = getShares($serversAR);
  removeNoPerms($shareRef);
  if ($$report eq 'n') {
    getShareNTFS($shareRef);
  }
  if ($$report eq 'p') {
    getSharePerms($shareRef);
  }
 } #Main

#######################
sub getOpts {
  my %opts;
  my @servers;
  my $report;

  getopts('hpnS:C:', \%opts);
  
   #Help or missing Server or Config file
   if ($opts{'h'} or !defined $opts{S} and !defined $opts{C}
        or !defined $opts{p} and !defined $opts{n}) {
    printUsage();
   }
   
  #Share Permissions -p
  if (exists $opts{p}) {
    $report = 'p';
   }
   
  #Share NTFS Permissions -n
  if (exists $opts{n}) {
    $report = 'n';
   }

  #Servers specified with -S parameter
   if (exists $opts{S}) {
    if (defined $opts{S}) {
      @servers = split(/\s*,\s*/, $opts{S});
    }
   }
   
   #Config file specified with -C parameter
   if (exists $opts{C}) {
    if (defined $opts{C}) {
      open (FH, $opts{C}) || die "Couldn't open file: $!";
      while ( <FH> )
      {
        chomp;
        push @servers, $_;
      }
      close(VALIDFILE);
    }
   }

   return (\$report,\@servers);
} #getOpts

#######################
sub getShares {
  my $serversAR = shift;
  #Used to filter out everything except share lines
  my $regex = '(ADMIN\$|IPC\$|print\$|CDROM|The\s{1}command|Share\s{1}name|---|^\s+)';
  my %share;

  foreach my $server (@$serversAR) {
   #execute rmtshare \\<servername> and grep the output
    my @rs = grep !/$regex/i, `rmtshare \\\\$server`;
    foreach (@rs) {
        #/(\S+)(\s+)(.*)(  )/gm;
        /(\S+)(\s+)(.*\\)(\S*)(\s{1}\S+)?/;
        my $shr = $1;
        #my $path = $3;
        my $path = $3.$4.$5;
        $path =~ s/\s+$//;
       my $entry = $share{$server};
       $entry->{$shr} = $path; #Share, Path
       $share{$server} = $entry;
    }
  }
  \%share; #return hash of users
   #print Dumper(\%share);
} #getShares

#######################
sub removeNoPerms {
#Since rmtshare returns share without permissions
#Run rmtshare with the share name arg if ouptput includes
#No permissions, remove it from the shareRef
  my $shareRef = shift;

    for my $server ( sort keys %$shareRef ) {
        for my $share ( sort keys %{$shareRef->{ $server }} ) {
          if (grep /^No\s{1}permissions/, `rmtshare \\\\$server\\\"$share\"`) {
            delete $shareRef->{ $server }->{ $share };
          }
        }
    }

#  print Dumper($shareRef);
} #removeNoPerms

#######################
sub getShareNTFS {
  my $shareRef = shift;

    for my $server ( sort keys %$shareRef ) {
        for my $share ( sort keys %{$shareRef->{ $server }} ) {
          my $path = $shareRef->{ $server }->{ $share };
          $path =~ s/:/\$/;  #Replace : with $ to allow run remotely
           my @rs = `fileacl "\\\\$server\\$path" /SUB`;
            foreach (@rs) {
              s/;/,/; #Replace ; with , to produce csv output
              s/^\\\\$server\\//; #Remove server name from directory path
              s/:/,/; #Replace : with , to produce csv output
              s/^(\w{1})(\$)/$1:/; #Replace drive letter $ w/ drive letter :
              print "$server,$share,$_";
            }
         }
    }

  #print Dumper($shareRef);
} #getShareNTFS

#######################
sub getSharePerms {
  my $shareRef = shift;
  #Used to filter out everything except share permission lines
  my $regex = '(FULL\s{1}CONTROL|CHANGE|READ)';

  for my $server ( sort keys %$shareRef ) {
    for my $share ( sort keys %{$shareRef->{ $server }} ) {
      my $path = $shareRef->{ $server }->{ $share };
      my @rs = grep /$regex/i, `rmtshare \\\\$server\\\"$share\"`;
      foreach (@rs) {
        s/^\s+//;  #Remove leading space
        s/\s+$//;  #Remove trailing space
        /^(.*)(:)(\s+)(.*)/gm; #match anything($1) colon($2) space($3) anything($4)
        print "$server,$share,$path,$1,$4\n";
      }
    }
  }
} #getSharePerms

#######################
sub printUsage {
  print << '--Usage--';
Usage:
perl sharentfs.pl {server(s)|Config file}
   [-h Print Usage info]
   [-p Report Share Permissions]
   [-n Report Share NTFS Permissions]
   [-S Server(s) CSV of servers]
   [-C Config file listing servers]
--Usage--
  exit;
} #printUsage

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating