#  Disable.pl
#  Example 2.3:
#  ----------------------------------------
#  From "Win32 Perl Scripting: Administrators Handbook" by Dave Roth
#  Published by New Riders Publishing.
#  ISBN # 1-57870-215-1
#
print "From the book 'Win32 Perl Scripting: The Administrator's Handbook' by Dave Roth\n\n";


use Win32;
use Getopt::Long;
use Win32::NetAdmin;
use Win32::AdminMisc;

Configure( \%Config );
if( $Config{help} )
{
  Syntax();
  exit();
}

if( "" ne $Config{domain} )
{   
  # Must first assign some value to the machine key otherwise
  # GetDomainController() will fail.
  $Config{machine} = "";
  Win32::NetAdmin::GetDomainController( '', 
                                        $Config{domain}, 
                                        $Config{machine} );
}
elsif( "" eq $Config{machine} )
{
  # Must first assign some value to the machine key otherwise
  # GetDomainController() will fail.
  $Config{machine} = "";
  Win32::NetAdmin::GetDomainController( '', 
                                        Win32::DomainName(), 
                                        $Config{machine} );
}

foreach my $Account ( @{$Config{accounts}} )
{
  if( $Account =~ /\*$/ )
  {
    my( $Prefix ) = ( $Account =~ /^(.*)\*$/ );
    my @Users;
    Win32::AdminMisc::GetUsers( $Config{machine}, $Prefix, \@Users );
    map
    {
      $AccountList{lc $_} = 1;
    } ( @Users );
  }
  else
  {
    $AccountList{lc $Account} = 1;
  }
}

# Notice that we use a hash (%AccountList) to track the users we 
# are working on. This is a simple hack to prevent us from 
# processing the same user more than once (if the user passed
# in the same account name multiple times).
foreach my $Account ( keys( %AccountList ) )
{
  print ( ( $Config{enable} )? "Enabling" : "Disabling" );
  print " '$Config{machine}\\$Account'...";
  if( Win32::AdminMisc::UserGetMiscAttributes( $Config{machine}, 
                                               $Account, 
                                               \%Attrib ) )
  {
    my $Flag;
    if( $Config{enable} )
    {
      $Flag = $Attrib{USER_FLAGS} & ~UF_ACCOUNTDISABLE;
    }
    else
    {
      $Flag = $Attrib{USER_FLAGS} | UF_ACCOUNTDISABLE;
    }

    $Result = Win32::AdminMisc::UserSetMiscAttributes( $Config{machine},
                                                 $Account, 
                                                 USER_FLAGS => $Flag );
  }

  if( $Result )
  {
    print "successful.\n";
  }
  else
  {
    my $Error =  Win32::FormatMessage( Win32::NetAdmin::GetError() );
    $Error =~ s/\r|\n//g;
    print "failed to delete ($Error)\n";
  }
}

sub Configure
{
  my( $Config ) = @_;
  
  $Config->{enable} = 1;
  Getopt::Long::Configure( "prefix_pattern=(-|\/)" );
  $Result = GetOptions( $Config, 
                         qw(
                             machine|m=s
                             domain|d=s
                             enable|e
                             help|?
                         )
                     );
  
  $Config->{help} = 1 if( ! $Result );
  $Config->{enable} = ! $Config->{enable};
  if( "" ne $Config->{machine} )
  {
    $Config->{machine} = "\\\\$Config->{machine}";
    $Config->{machine} =~ s/^(\\\\)+/\\\\/;
  }  
  push( @{$Config->{accounts}}, @ARGV );
  $Config->{help} = 1 if( ! scalar @{$Config->{accounts}} );
}

sub Syntax
{
  my( $Script ) = ( $0 =~ /([^\\\/]*?)$/ );
  my( $Line ) = "-" x length( $Script );
  
  print <<EOT;

$Script
$Line
Disables an account.

Syntax:
    perl $Script [-e] [-m machine | -d domain] Account [ Account2 ... ]
        -e..........Enables a disabled account.
        -m Machine..Specify a machine where the user account lives.
        -d Domain...Specify a domain where the user account lives.
        Account.....The name of the account (the userid).
                    This account can end with a * char to indicate
                    all accounts that begin with the specified string.
 	If no domain or machine is specified then the current domain
        is used.
EOT
}

