#  MakePerms.pl
#  Example 4.6:
#  ----------------------------------------
#  From "Win32 Perl Scripting: Administrators Handbook" by Dave Roth
#  Published by New Riders Publishing.
#  ISBN # 1-57870-215-1
#
#  This script reapplies permissions on objects from a backup file.
#  Example_4_5.pl generates the permission backup file.
#
print "From the book 'Win32 Perl Scripting: The Administrator's Handbook' by Dave Roth\n\n";


use Win32::Perms;

$DELIMITER = ";";
Win32::Perms::LookupDC( 0 );
$File = shift( @ARGV ) || die "No config file specified\n";
$Machine = Win32::NodeName() unless( $Machine = shift( @ARGV ) );
( $Machine = "\\\\$Machine" ) =~ s/^\\{2,}/\\\\/;

if( ProcessFile( $File, \%Config ) )
{
    foreach my $Object ( keys( %Config ) )
    {
        print "Creating $Machine\\$Object...";
        if( ApplyPerms( $Machine, $Config{$Object} ) )
        {
            print "Success";
        }
        else
        {
            print "failure: ";
            print Win32::FormatMessage( Win32::Lanman::GetLastError() );
        }
        print "\n";
    }
}

sub ApplyPerms
{
    my( $Machine, $PermObject ) = @_;
    my $Perm;
    my @Acl;

    return( 0 ) unless( $Perm = new Win32::Perms( $PermObject->{path} ) );
    $Perm->Remove( -1 );
    $Perm->Owner( $PermObject->{owner} ) if( defined $PermObject->{owner} );
    $Perm->Group( $PermObject->{group} ) if( defined $PermObject->{group} );
    foreach my $Ace ( @{$PermObject->{dacl}}, @{$PermObject->{sacl}} )
    {
        my( $Account, $Access, $Flags, $Mask ) = split( $DELIMITER, $Ace );
        $Perm->Add( $Account, eval( uc $Mask ), eval( uc $Access ), eval( uc $Flags ) );
    }
    $Perm->Set();
    print "\n";
}

sub ProcessFile
{
    my( $File, $PermList ) = @_;
    my $iResult = 0;

    if( open( PERMSDATA, "<$File" ) )
    {
        $iResult = ParsePerms( *PERMSDATA, $PermList );
        close( PERMSDATA );
    }
    else
    {
        print "Unable to open '$File': $!\n";
    }
    return( $iResult );
}

sub ParsePerms
{
    my( $FileHandle, $PermList ) = @_;
    my $ObjectName = "";
    my $iTotal = 0;

    while( $Line = <$FileHandle> )
    {
        my( $Name, $Value );

        next if( $Line =~ /^\s*[#;]/ );
        next if( $Line =~ /^\s*$/ );
        if( ( $Name ) = ( $Line =~ /^\s*\[\s*(.*?)\s*\]/ ) )
        {
            $ObjectName = lc $Name;
            $iTotal++;
            $PermList->{$ObjectName}->{path} = $ObjectName;
            next;
        }
        next if( "" eq $ObjectName );

        ( $Name, $Value ) = ( $Line =~ /^\s*(.*?)=(.*)\s*$/ );
        if( "" ne $Name )
        {
            $Name = lc $Name;
            if( ( "dacl" eq $Name ) || ( "sacl" eq $Name ) )
            {
                push( @{$PermList->{$ObjectName}->{$Name}}, $Value );
            }
            else
            {
                $PermList->{$ObjectName}->{$Name} = $Value;
            }
        }
    }
    return( $iTotal );
}
