#  MakeAccounts.pl
#  Example 4.4:
#  ----------------------------------------
#  From "Win32 Perl Scripting: Administrators Handbook" by Dave Roth
#  Published by New Riders Publishing.
#  ISBN # 1-57870-215-1
#
#  This script recreates accounts from a configuration file.
#  Example_4_3.pl creates such configuration files.
#
print "From the book 'Win32 Perl Scripting: The Administrator's Handbook' by Dave Roth\n\n";


use Win32::Lanman;

$File = shift( @ARGV ) || die "No config file specified\n";
$Machine = Win32::NodeName() unless( $Machine = shift( @ARGV ) );
( $Machine = "\\\\$Machine" ) =~ s/^\\{2,}/\\\\/;

if( ProcessFile( $File, \%Config ) )
{
    foreach my $Account ( keys( %Config ) )
    {
        print "Creating $Machine\\$Config{$Account}->{netname}...";
        if( CreateAccount( $Machine, $Config{$Account} ) )
        {
            print "Success";
        }
        else
        {
            print "failure: ";
            print Win32::FormatMessage( Win32::Lanman::GetLastError() );
        }
        print "\n";
    }
}

sub CreateAccount
{
    my( $Machine, $Account ) = @_;
    my $Result = 0;

    # Is this a machine account?
    if( $Account->{name} =~ /\$$/ )
    {
        # Follow the rules to create a machine account...
        $Account->{name} = uc $Account->{name};
        ($Account->{password}) = ( lc $Account->{name} =~ /^(.{0,14})/ );
        $Account->{password} =~ s/\$$//;
    }

    $Result = Win32::Lanman::NetUserAdd( $Machine, $Account );

    return( $Result );
}

sub ProcessFile
{
    my( $File, $AccountList ) = @_;
    my $iResult = 0;

    if( open( ACCOUNTDATA, "<$File" ) )
    {
        $iResult = ParseAccounts( *ACCOUNTDATA, $AccountList );
        close( ACCOUNTDATA );
    }
    else
    {
        print "Unable to open '$File': $!\n";
    }
    return( $iResult );
}

sub ParseAccounts
{
    my( $FileHandle, $AccountList ) = @_;
    my $AccountName = "";
    my $iTotal = 0;

    while( $Line = <$FileHandle> )
    {
        my( $Name, $Value );

        next if( $Line =~ /^\s*[#;]/ );
        next if( $Line =~ /^\s*$/ );
        if( ( $Name ) = ( $Line =~ /^\s*\[\s*(.*?)\s*\]/ ) )
        {
            $AccountName = lc $Name;
            $iTotal++;
            next;
        }
        next if( "" eq $AccountName );

        ( $Name, $Value ) = ( $Line =~ /^\s*(.*?)=(.*)\s*$/ );
        if( "" ne $Name )
        {
            $Name = lc $Name;
            $Value =~ s/\\x(\w{2})/pack("c",hex($1))/ge;
            $AccountList->{$AccountName}->{$Name} = $Value;
        }
    }
    return( $iTotal );
}

# For some reason Win32::Lanman forgot to export this constant
sub STYPE_SPECIAL
{
    return( 0x80000000 );
}
