#! c:\perl\bin\perl.exe #--------------------------------------------------------- # share.pl # Retrieves share information from NT/2K systems # # usage: share.pl -h # # Copyright 2000/2001 H. Carvey keydet89@yahoo.com #--------------------------------------------------------- use strict; use Win32::AdminMisc; use Win32::Lanman; use Win32::Perms; use Getopt::Long; Win32::Perms::LookupDC(0); my %config = (); Getopt::Long::Configure("prefix_pattern=(-|\/)"); GetOptions(\%config, qw(system|s=s verbose|v file|f help|?|h)); if (!%config || $config{help}) { \usage(); exit 1; } my $server = $config{system} || Win32::NodeName; my @shares; my @enumshare; if (Win32::Lanman::NetShareEnum("\\\\$server",\@shares)) { foreach my $share (@shares) { push(@enumshare,{name => ${$share}{'netname'},path => ${$share}{'path'}, remark => ${$share}{'remark'},max => ${$share}{'max_uses'}, current => ${$share}{'current_uses'}}); } foreach my $share (sort ({lc $a->{name} cmp lc $b->{name}}@enumshare)) { my @perms = getPerms("\\\\$server\\".$share->{name}); if (@perms) { print "\n"; printf "%-15s %-20s %-15s\n","Share","Group/User","Permissions"; printf "%-15s %-20s %-15s\n","-" x 10,"-" x 10,"-" x 12; my $elements = @perms; my ($group,$permlist) = (split(/:/,$perms[0]))[0,2]; printf "%-15s %-20s %-15s\n",$share->{name},$group,$permlist; # deal appropriately with if ($elements > 1) { foreach my $tag (1..$elements-1) { my ($group,$permlist) = (split(/:/,$perms[$tag]))[0,2]; printf "%-15s %-20s %-15s\n","",$group,$permlist; } } if ($config{verbose}) { print "\nVerbose Output for ".$share->{name}."\n"; print "-" x 50,"\n"; print "Path : ".$share->{path}." "; if ($share->{path} =~ m/^\w:\\/) { print "(Root share)"; my $file = "\\\\$server\\".$share->{name}."\\autorun.inf"; if (-e $file) { print "\nWarning: Autorun.inf file detected on drive root!!"; } } print "\n"; print "Remark : ".$share->{remark}."\n"; print "Current uses: ".$share->{current}."\n"; my $max; ($share->{max} == -1)?($max = "Max Allowed"):($max = $share->{max}); print "Max Uses : ".$max."\n"; if (my %hash = Win32::AdminMisc::GetVolumeInfo("\\\\$server\\".$share->{name})) { print "FileSystem : ".$hash{FileSystemName}."\n"; } } print "\n"; } else { printf "%-15s %-20s %-15s\n",$share,"",""; print "\n"; } } \files($server) if ($config{file}); } else { my $err = Win32::FormatMessage Win32::Lanman::GetLastError(); $err = Win32::Lanman::GetLastError() if ($err eq ""); $err = "Server service not enabled, no shares available" if ($err == 2114); print "NetShareEnum error: ".$err."\n"; } sub files { my $server = $_[0]; my @info; if(Win32::Lanman::NetFileEnum("\\\\$server", '', '', \@info)) { print "\nOpen Files\n\n"; printf "%-15s %-20s %-15s\n","Id","User","Path"; printf "%-15s %-20s %-15s\n","-" x 4,"-" x 5,"-" x 5; foreach my $info (@info) { my @keys = keys(%$info); printf "%-15s %-20s %-15s\n",${$info}{id},${$info}{username},${$info}{pathname}; } } else { my $err = Win32::FormatMessage Win32::Lanman::GetLastError(); $err = Win32::Lanman::GetLastError() if ($err eq ""); print "NetShareEnum error: ".$err."\n"; } } sub getPerms { my($obj) = $_[0]; my($Acct,@List,$iTotal,$p); my(@perms) = (); my($Perm) = new Win32::Perms($obj); my (%PERM) = (R => 0, W => 1, X => 2, D => 3, P => 4, O => 5, A => 6,); my(%MAP) = ( 'FILE_READ_DATA' => 'R', 'GENERIC_READ' => 'R', 'KEY_READ' => 'R', 'DIR_READ' => 'R', 'KEY_QUERY_VALUE' => 'R', 'FILE_WRITE_DATA' => 'W', 'KEY_WRITE' => 'W', 'KEY_SET_VALUE' => 'W', 'GENERIC_WRITE' => 'W', 'FILE_APPEND_DATA' => 'W', 'DIR_ADD_SUBDIR' => 'W', 'DIR_ADD_FILE' => 'W', 'DELETE' => 'D', 'FILE_DELETE_CHILD' => 'D', 'FILE_EXECUTE' => 'X', 'FILE_TRAVERSE' => 'X', 'GENERIC_EXECUTE' => 'X', 'DIR_TRAVERSE' => 'X', 'DIR_EXECUTE' => 'X', 'CHANGE_PERMISSION' => 'P', 'TAKE_OWNERSHIP' => 'O', 'FILE_ALL_ACCESS' => 'A', 'GENERIC_ALL' => 'A', 'DIR_ALL_ACCESS' => 'A', 'STANDARD_RIGHTS_ALL' => 'A'); if(!$Perm) { # push(@perms,"Can not obtain permissions for '$obj'"); # return @perms; return undef; }; $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)... ($Acct->{Flag} & DIR) ? ($DaclType = "Directory") : ($DaclType = "File"); } $p = join('',@String); push(@perms,"$Acct->{Account}:$DaclType:$p"); } if(!$iTotal) { push(@perms,"Everyone::------A"); } return @perms; } sub usage { print STDERR "\nShare.pl -- retrieve share information from an NT/2K system.\n\n"; print STDERR "Usage: [perl] share.pl [-s system] [-vfh/?]\n"; print STDERR "\n"; print STDERR " -s System to query (default: localhost).\n"; print STDERR " -f Retrieve information on open files.\n"; print STDERR " -v Verbose output.\n"; print STDERR " -h Help (also -?).\n"; print STDERR "\n"; print STDERR "Copyright 2000/2001 H. Carvey keydet89\@yahoo.com.\n"; }