ACC SHELL

Path : /var/lib/ntp/var/lib/ntp/proc/self/root/usr/bin/
File Upload :
Current File : //var/lib/ntp/var/lib/ntp/proc/self/root/usr/bin/nmbstatus

#!/usr/bin/perl -w
# Copyright (c) 2003-2004 SuSE Linux AG, Nuernberg, Germany.
# All rights reserved.
#
# $Id: nmbstatus,v 1.11 2003/07/29 14:11:44 lmuelle Exp $
#
# Author: Lars Mueller <lmuelle@suse.de>
#         Günther Deschner <gd@suse.de> (minor fixes)

use strict;
use warnings;
use Getopt::Long;
use Pod::Usage;
use File::Basename;

my $basename    = basename( $0);
my $nmblookup   = '/usr/bin/nmblookup';
my $opts 	= '-d0 2> /dev/null';
my $workgroup   = '';

my ($winsServer,$allworkgroups,$seperator,$quiet,$help,$man);
# set defaults
my ($pdc,$bdc,$dmb,$lmb,$members) = ( 0, 0, 0, 0, 0);
my $debuglevel = 3;
GetOptions (
    'winsserver|U=s'    => \$winsServer,
    'workgroup|w=s'     => \$workgroup,
    'pdc|p'             => \$pdc,
    'bdc'               => \$bdc,
    'dmb|d'             => \$dmb,
    'lmb'               => \$lmb,
    'members'           => \$members,
    'allworkgroups'     => \$allworkgroups,
    'print0'            => \$seperator,
    'quiet'             => \$quiet,
    'debuglevel=i'      => \$debuglevel,
    'help'              => \$help,
    'man'               => \$man,
) or pod2usage(2);
pod2usage(1) if $help;
pod2usage(-exitstatus => 0, -verbose => 2) if $man;

sub debug {
    if ($debuglevel >= $_[0]) {
        print STDERR "$_[1]";
        return( 1);
    }
    return( 0);
}

# check syntax
if ( $quiet) {
    unless ( $workgroup) {
        debug( 3, "$basename: Syntax error. You must set a workgroup.\n");
        exit 3;
    }
    my $count = $pdc + $bdc + $lmb + $dmb + $members;
    # more than one option choosen
    if ( $count > 1) {
        debug( 3, "$basename: Syntax error. Only one option is valid.\n");
        debug( 3, "You must choose one between pdc, bdc, dmb, lmb, and members.\n");
        exit 3;
    }
    # none option choosen
    if ( $count == 0) {
        debug( 3, "$basename: Syntax error. Option missing for quiet mode.\n");
        debug( 3, "You must choose one between pdc, bdc, dmb, lmb, and members.\n");
        exit 3;
    }
}

# always upper case the workgroup name
$workgroup = uc( $workgroup);

my %ipAddrsList;
my %workGroups;
my %workGroupsPDC;
my %workGroupsBDC;
my %workGroupsDMB;
my %workGroupsLMB;
my %workGroupsMEM;

open ( NMBLOOKUP, "$nmblookup '*' $opts | ") || die "Can't run $nmblookup '*'\n";
%ipAddrsList = map {$_, 1} grep(s/ \*<00>.*$//s,<NMBLOOKUP>);
close( NMBLOOKUP);

# check if we're root
my $nmblookupOpt = '';
$nmblookupOpt .= ' -r' if ( !$<);
# did we know a WINS server
$nmblookupOpt .= " -U $winsServer -R" if ( $winsServer);

# set output seperator
if ( $seperator) {
    $seperator = "\0";
} else {
    $seperator = "\t";
}

print STDERR "Found " . keys( %ipAddrsList) . " hosts. Collecting additional information. Please wait.\n" unless ( $quiet);
my $progress = 0;
foreach my $ipAddrs ( keys %ipAddrsList)  {
    debug( 15, "$basename: ipAddrs<$ipAddrs>\n");
    print STDERR "." unless ( $quiet);
    my $primaryHostName = undef;
    my $currWorkgroup = undef;
    my $domainController = undef;
    my $domainMaster = undef;
    my $localMaster = undef;
    my @hostNames = ();
    open ( NMBLOOKUP, "$nmblookup $nmblookupOpt -A '$ipAddrs' $opts | ") || die "Can't run $nmblookup -A\n";
    while (<NMBLOOKUP>) {
	next unless my ($name, $state, $group) = /^\t(.{15}) <([0-9a-z]{2})> - .(.{5})/;
	$name =~ s/\s*$//;
	next if $name eq "..__MSBROWSE__." || $name eq "INet~Services" || $name =~ /^IS~/;
        debug( 20, "$basename: name<$name> state<$state> group<$group>\n");
        if ($name && ($group ne 'GROUP' && $state eq '00')) {
            # store the first host name we get
            $primaryHostName = $name unless ( $primaryHostName);
            debug( 20, "$basename: computer found name<$name>\n");
            # store a hostname in a list
            push( @hostNames, $name);
            next;
        }
	if ($name && ($group eq 'GROUP' || $state eq '1b' || $state eq '1d')) {
            last if ( $workgroup ne '' && $name ne $workgroup);
            $currWorkgroup = $name unless ( $currWorkgroup);
            debug( 20, "$basename: currWorkgroup<$currWorkgroup>\n");
        }
        next unless defined($currWorkgroup);
        if ( $state eq '1c') {
            # this is a DC
            $domainController = 1;
            debug( 15, "$basename: DC found for workgroup <$currWorkgroup>\n");
        } elsif ( $state eq '1b') {
            # this is a DMB
            $domainMaster = 1;
            debug( 15, "$basename: DMB found for workgroup <$currWorkgroup>\n");
        } elsif ( $state eq '1d') {
            # this is a LMB
            $localMaster = 1;
            debug( 15, "$basename: LMB found for workgroup <$currWorkgroup>\n");
        }
    }
    close( NMBLOOKUP);

    unless ($primaryHostName) {
	my ($name, $aliases, $type, $length, @addresses) =  gethostbyaddr(pack('C4',split('\.',$ipAddrs)),2);
        $name ||= "unknown";
	$primaryHostName = $name || "unknown";
	push @hostNames, $name;
        debug( 5, "$basename: nis name $name\n");
    }
    
    open(SMB,"smbclient -L '$primaryHostName' -I '$ipAddrs' -N --debuglevel=1 2>&1 |") 
	|| die("Can't do smbclient command.\n");
    my @smb = grep {s/^Domain=\[(.*)] OS=\[.*$/$1/s} <SMB>;
    close SMB;
    if (@smb) {
      $currWorkgroup = $smb[0];
    } else {
      next;
    }

    debug( 15, "$basename: currWorkgroup<$currWorkgroup> primaryHostName<$primaryHostName>\n");

    $workGroups{$currWorkgroup} = 1;
    if ( $domainController && $domainMaster) {
        # it's a PDC
        $workGroupsPDC{$currWorkgroup} .= $seperator if ( $workGroupsPDC{$currWorkgroup});
        $workGroupsPDC{$currWorkgroup} .= $primaryHostName;
    } elsif ( $domainController) {
        # it's a BDC
        $workGroupsBDC{$currWorkgroup} .= $seperator if ( $workGroupsBDC{$currWorkgroup});
        $workGroupsBDC{$currWorkgroup} .= $primaryHostName;
    }
    if ($domainMaster) {
	# this is a DMB
        $workGroupsDMB{$currWorkgroup} .= $seperator if ( $workGroupsLMB{$currWorkgroup});
        $workGroupsDMB{$currWorkgroup} .= $primaryHostName if ( $primaryHostName );
    }
    if ($localMaster) {
        # this is a LMB
        $workGroupsLMB{$currWorkgroup} .= $seperator if ( $workGroupsLMB{$currWorkgroup});
        $workGroupsLMB{$currWorkgroup} .= $primaryHostName if ( $primaryHostName );
    }
    if ( @hostNames) {
        $workGroupsMEM{$currWorkgroup} .= $seperator if ( $workGroupsMEM{$currWorkgroup});
        $workGroupsMEM{$currWorkgroup} .= join( "$seperator", @hostNames);
    }
}
print STDERR "\n" unless ( $quiet);

# undef workgroup if empty
$workgroup = undef if ( $workgroup eq '');

# show all data we found or only one workgroup
my @displayWorkgroups = ();
if ( $quiet || defined($workgroup)) {
    @displayWorkgroups = $workgroup;
} else {
    @displayWorkgroups = keys %workGroups;
}


if ( $pdc + $bdc + $dmb + $lmb + $members == 0 && !defined( $allworkgroups)) {
    $pdc = 1;
    $bdc = 1;
    $dmb = 1;
    $lmb = 1;
    $members = 1;
}

sub printWorkgroup {
    my ($localWorkgroup, $shown) = @_;
    return if ( $shown && ${$shown});
    # only display the workgroup name if not set on the command line
    print "WORKGROUP$seperator" if ( !defined $workgroup && !defined $allworkgroups);
    print "$localWorkgroup\n" unless ( $workgroup);
    ${$shown} = 1;
}

if ( $quiet) {
    exit 0 if ( $pdc > 0 && $workGroupsPDC{$workgroup});
    exit 0 if ( $bdc > 0 && $workGroupsBDC{$workgroup});
    exit 0 if ( $dmb > 0 && $workGroupsDMB{$workgroup});
    exit 0 if ( $lmb > 0 && $workGroupsLMB{$workgroup});
    exit 0 if ( $members >0 && $workGroupsMEM{$workgroup});
    exit 1;
} else {
    my $newLine = undef;
    foreach my $currWorkgroup ( sort @displayWorkgroups) {
        my $workgroupShown = undef;
        my $count = $pdc + $bdc + $dmb + $lmb + $members;
        print "\n" if ( $newLine);
        $newLine = undef;
        if ( $allworkgroups) {
            printWorkgroup( $currWorkgroup);
            next;
        }
        if ( $pdc > 0) {
            $count--;
            if ( $workGroupsPDC{$currWorkgroup}) {
                printWorkgroup( $currWorkgroup, \$workgroupShown);
                print "PDC$seperator$workGroupsPDC{$currWorkgroup}\n";
                $newLine = 1;
            } elsif ( $workgroup && $count < 1) {
                exit 1;
            }
        }
        if ( $bdc > 0) {
            $count--;
            if ( $workGroupsBDC{$currWorkgroup}) {
                printWorkgroup( $currWorkgroup, \$workgroupShown);
                print "BDC$seperator$workGroupsBDC{$currWorkgroup}\n";
                $newLine = 1;
            } elsif ( $workgroup && $count < 1) {
                exit 1;
            }
        }
        if ( $dmb > 0) {
            $count--;
            if ( $workGroupsDMB{$currWorkgroup}) {
                printWorkgroup( $currWorkgroup, \$workgroupShown);
                print "DMB$seperator$workGroupsDMB{$currWorkgroup}\n";
                $newLine = 1;
            } elsif ( $workgroup && $count < 1) {
                exit 1;
            }
        }
        if ( $lmb > 0) {
            $count--;
            if ( $workGroupsLMB{$currWorkgroup}) {
                printWorkgroup( $currWorkgroup, \$workgroupShown);
                print "LMB$seperator$workGroupsLMB{$currWorkgroup}\n";
                $newLine = 1;
            } elsif ( $workgroup && $count < 1) {
                exit 1;
            }
        }
        if ( $members > 0) {
            $count--;
            if ( $workGroupsMEM{$currWorkgroup}) {
                printWorkgroup( $currWorkgroup, \$workgroupShown);
                print "MEMBERS$seperator$workGroupsMEM{$currWorkgroup}\n" ;
                $newLine = 1;
            } elsif ( $workgroup && $count < 1) {
                exit 1;
            }
        }
    }
}


__END__

=head1 NAME

B<nmbstatus> - Lists NMB node status of a UDP network

=head1 SYNOPSIS

nmbstatus [options] 

Options:
--workgroup
--pdc
--bdc
--lmb
--dmb
--members
--quiet
--allworkgroups
--winsserver
--print0
--debug
--help
--man

=head1 GENERAL OPTIONS

=over 8

=item B<--help>

Print a brief help message and exits.Prints a help message.

=item B<--man>

Print the manual page and exit.

=item B<--print0>

Use '\0' instead of a tab stop as seperator between the output.

=item B<--debug>

Use an debuglevel. No debuglevel available yet.

=head1 GENERAL ARGUMENTS

=item B<--workgroup>

Perform all actions on this workgroup name. If no workgroup is set the
information off all available groups is shown.

=item B<--pdc>

If not called in conjunction with B<--quiet> print a line starting with the
acronym PDC followed by the seperator and the netbios name of the PDC if one is
available. If not print nothing and return with 1.

=item B<--bdc>

If not called in conjunction with B<--quiet> print a line starting with the
acronym BDC followed by the seperator and the netbios name of the BDC if one is
available. If not print nothing and return with 1.

=item B<--dmb>

If not called in conjunction with B<--quiet> print a line starting with the
acronym DMB followed by the seperator and the netbios name of the DMB if one is
available. If not print nothing and return with 1.

=item B<--lmb>

If not called in conjunction with B<--quiet> print a line starting with the
acronym LMB followed by the seperator and the netbios name of the LMB if one is
available. If not print nothing and return with 1.

=item B<--members>

If not called in conjunction with B<--quiet> print a line starting with the
word MEMBERS followed by the seperator and the netbios names of the workgroup
members. If not print nothing and return with 1.

=item B<--quiet>

Don't print any information. Just return with 0 if a type - pdc, lmb, dmb, or
members was found. Else return 1.

=item B<--allworkgroups>

List all available workgroups.

=item B<--winsserver>

Use this WINS server to gather the information.

=back

=head1 DESCRIPTION

B<nmbstatus> will detect workgroups, PDCs, BDCs, DMBs, LMBs, and Members of
workgroups in your network.

If more than one type is specizied but only one result found, B<nmbstatus>
nevertheless returns 0.

=head1 AUTHOR

Lars Mueller <lmuelle@suse.de>

If you find any errors in the code please let me know.

=head1 COPYRIGHT

Copyright (c) 2003-2004 SuSE Linux AG. All rights reserved.

This program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.

=cut

ACC SHELL 2018