Category: Win32
Author/Contact Info /tell Discipulus
Description: This is a first working attempt to find and dump difference between folder permission in a tree.

If usr have in a/b/c different permissions that in a/b so permissions for usr in a/b and in a/b/c are dumped.

If user is not found in a/b or in a/b/c this is printed.

Please review it wise monks!
use strict;
use warnings;
use Win32::FileSecurity qw(Get EnumerateRights);
use Data::Compare;

open LOG, ">c:/scripts/acl3.log";
select LOG;

my $basedir = 'C:/inetpub/wwwroot/';
my @sottrarre = split /\//, $basedir;
my $targdir =  'yourfolder/';
my $iniziale = $basedir.$targdir;


my @cartelle = &recursive($iniziale);
my %livelli =  &per_livelli(@cartelle);

    print "PERMESSI DELLA ROOT\n\n";
    &secdump($iniziale);
    print "\n#######\n";

foreach my $lvl(sort keys %livelli){
      foreach my $item(keys %{$livelli{$lvl}} )
      {
        next if $item=~/_private|_vti_cnf|_vti_log|_vti_pvt|_vti_scrip
+t|_vti_txt/;##skip vicious FrontPage dirs
        &compara_madre($item,$lvl);
      }
}
my $now = time();
print "\n\nTEMPO TOTALE TRASCORSO: ",$now-$^T," SECONDI\n\n";
######################################################################
+##########
sub compara_madre{
    my $figlio = shift;
    my $lvl = shift;
    return if $lvl == 0;
    my $madre;
    my $diff;
    if ($figlio =~/[\w\d\.\s-]+\/$/){$diff = $&}
    $madre = $figlio;
    $madre =~s/$diff$//;
    unless (Compare \$livelli{$lvl-1}{$madre}, \$livelli{$lvl}{$figlio
+} ){
            print "################\n#DIFFERENZE TRA:\n$figlio\tFIGLIA
+ DI\n$madre\n################\n";
        foreach my $usr(keys %{$livelli{$lvl}{$figlio}}){
            if (not defined $livelli{$lvl}{$figlio}{$usr})
                {print "nessuna entry in $figlio per $usr\n";return}
            if (not defined $livelli{$lvl-1}{$madre}{$usr})
                {print "nessuna entry in $madre per $usr\n";return}
            if  ($livelli{$lvl}{$figlio}{$usr} != $livelli{$lvl-1}{$ma
+dre}{$usr})
            {
                       print "MADRE: $madre\n";
                       print "\t\tUSER: $usr\n";
                       my @happy;
                       EnumerateRights( $livelli{$lvl-1}{$madre}{$usr}
+, \@happy ) ;
                       print "\n\t",join( "\n\t", @happy ), "\n";

                       print "FIGLIO: $figlio\n";
                       print "\t\tUSER: $usr\n";
                       my @happytoo;
                       EnumerateRights( $livelli{$lvl}{$figlio}{$usr},
+ \@happytoo ) ;
                       print "\n\t",join( "\n\t", @happytoo ), "\n";

            }

          }
          print "\n#######\n";
    }
}
######################################################################
+##########
sub recursive{
 my $root  = shift;

  my @dirs  = ($root);
  for my $path (@dirs){
    opendir ( CART, $path ) or next;   # skip dirs we can't read
    while (my $file = readdir CART) {
      next if $file eq '.' or $file eq '..'; # skip dot files
      next if -l $path.$file;                # skip sym links
        if ( -d $path.$file ) {
             push @dirs, $path.$file."/";     # add dir to list
               }

    }
    closedir CART;
 }
  return @dirs;
}
######################################################################
+##########
sub per_livelli{
    my @dirs = @_;
    my %livelli;
    foreach my $ele (@dirs){
             my @temp = split /\//, $ele;
             $livelli{$#temp-$#sottrarre-1}{$ele}=&filsec($ele);
    }
  return   %livelli;
}
######################################################################
+##########
sub filsec{
        my $cart = shift;
        my %hash;
        next unless -e $cart ;
        if ( Get( $cart, \%hash ) ) {return \%hash;}
        else {print STDERR "Error #", int( $! ), ": $!" ;}
}
######################################################################
+##########
sub secdump{
        my ($cart, $name, $mask, @happy, %hash)= (shift, undef, undef,
+ undef, undef);
        if ( Get( $cart, \%hash ) ) {while( ($name, $mask) = each %has
+h ) {print "$name: $mask\n\t";}}
        else {print( "Error #", int( $! ), ": $!" ) ;}
}