use Win32::Perms; %PERM = ( R => 0, W => 1, X => 2, D => 3, P => 4, O => 5, A => 6, ); %MAP = ( 'FILE_READ_DATA' => 'R', 'GENERIC_READ' => 'R', 'KEY_READ' => 'R', 'FILE_WRITE_DATA' => 'W', 'KEY_WRITE' => 'W', 'GENERIC_WRITE' => 'W', 'DELETE' => 'D', 'FILE_DELETE_CHILD' => 'D', 'FILE_EXECUTE' => 'X', 'FILE_TRAVERSE' => 'X', 'GENERIC_EXECUTE' => 'X', 'CHANGE_PERMISSION' => 'P', 'TAKE_OWNERSHIP' => 'O', 'FILE_ALL_ACCESS' => 'A', 'GENERIC_ALL' => 'A', 'STANDARD_RIGHTS_ALL' => 'A', ); $Path = "." unless( $Path = $ARGV[0] ); print "\nDumping permissions for '$Path':\n"; GetPerms( $Path ); print "\n\n"; sub GetPerms { my( $Path ) = @_; my( $Acct, @List ); my( $Perm ) = new Win32::Perms( $Path ); if( ! $Perm ) { print "Can not obtain permissions for '$Path'\n"; return; }; $Perm->Dump( \@List ); foreach $Acct ( @List ) { my( $Perm ); my( @String ) = split( //, "-" x scalar( keys( %PERM ) ) ); my( $Mask, @M, @F ); my( $DaclType ); next if( $Acct->{Entry} ne "DACL" ); $iTotal++; DecodeMask( $Acct, \@M, \@F ); foreach $Mask ( @M ) { $Perm |= 2**$PERM{ $MAP{$Mask} }; } foreach $Mask ( keys( %PERM ) ) { $String[$PERM{$Mask}] = $Mask if( $Perm & 2**$PERM{$Mask} ) ; } $DaclType = $Acct->{ObjectName}; if( 2 == $Acct->{ObjectType} ) { # We have either a file or directory. Therefore we need to # figure out if this DACL represents an object (file) or # a container (dir)... if( $Acct->{Flag} & DIR ) { $DaclType = "Directory"; } else { $DaclType = "File"; } } printf( " % 20s % -11s %s\n", $Acct->{Account}, "($DaclType)", join( '', @String ) ); } if( ! $iTotal ) { print "\t Everyone has full permissions.\n"; } }