http://qs321.pair.com?node_id=238740
Category: Win32 Stuff
Author/Contact Info Martin Hylerstedt
Description:

I was asked to have a look at security issues for a group of Windows computers, and one of the things I thought about was shared directories. Which directories are visible? I could click away in the network browser but that would be tiresome. Why not practically extract and report it in some language? I work mostly with Windows, and play around sometimes with ActivePerl (5.8.0). There is the package Win32::NetResource available, let's have a look at it... And already in the documentation is what I want; "Enumerating all resources on a particular host".

Usage: Give computername(s) as arguments to script. If no arguments given, it uses computernames hardcoded into the script.

I adjust it somewhat, to go over an array of computer names to check, and write it to a text file. Hmm, why not display it more nicely? use Tk;

A hierarchical listing (HList) would be nice. Could also use a Tree.

Oops, a gotcha. The script barfs if a sharename contains periods (.), since period (.) is the default separator in the entrypath for a Tk::HList and Tk::Tree. The solution was to configure the HList to use something else as a separator. A forward slash (/) would be good, since a / would/could not be used in a sharename. See also the $hlist->add in the inner foreach loop where the children are added.

Wouldn't it be nice to make it more visible which is what? The computername looking different from the sharename? This I wrestled with for a while. I didn't want to make the whole HList bold, only the toplevel nodes. Look, look, look, browse, browse, browse. Tk::ItemStyle to the rescue!

The trick was to

  1. Create a font ($boldfont) with the weight bold
  2. Create a style ($boldstyle) which uses the bold font
  3. For the widgets where I want it, apply the -style.

By wrapping the HList in Scrolled, scrollbars will appear if necessary. To make it more readable, do the rest of the settings with a -configure for the widget.

When I'd removed all comments, notes, tests and "debugging" prints, I was impressed and almost disappointed that the script was only thirty-odd lines. I decided to post it here at Perlmonks as an example (hints) for Win32::NetResource and Perl/Tk.

Now that this is working, I'm thinking of expanding it to display the permissions for the shares (NetShareGetInfo), maybe also flag if the permissions are Everyone-Full Control.

use strict;
use Win32::NetResource qw(:DEFAULT GetSharedResources GetError);
use Tk;
use Tk::HList;
use Tk::ItemStyle;
my @names; 
if(@ARGV) {@names = @ARGV;} else
{
    @names = ("computer1", "computer2", "computer3", "computer4");
}
my $mw = MainWindow->new();
$mw->title("Visible shares");
$mw->resizable("false", "false");
my $hlist = $mw->Scrolled('HList',-scrollbars => "osoe");
my $boldfont = $mw -> fontCreate(-weight => 'bold');
my $boldstyle = $hlist->ItemStyle("text", -font => $boldfont);
$hlist->configure(-width => 50, -height => 40, -separator => '/');
foreach (@names) {
    if (GetSharedResources(my $resources, RESOURCETYPE_ANY,
               { RemoteName => "\\\\" . $_ }))
    {
    $hlist->add("$_", '-text' => "$_", -style => $boldstyle);
    
    foreach my $href (@$resources) {
        my $sharename = (split(/\\/, $href->{RemoteName}))[-1];
        $hlist->add("$_/$href->{RemoteName}", '-text' => "$sharename")
+;
    }
    } # if ends
} #foreach ends
$hlist->pack(); 
MainLoop;