#!/usr/bin/perl -w

my $netlogonTemplate = $ARGV[0];
my $netlogonFile = $ARGV[1];
my $curUser = $ARGV[2];
my $curMachine = $ARGV[3];
my $curArch = $ARGV[4];
my $time = $ARGV[5];

die "Netlogon template argument missing.\n" unless defined ($netlogonTemplate);
die "Netlogon file argument missing.\n" unless defined ($netlogonFile);
die "User argument missing.\n" unless defined ($curUser);
die "Machine argument missing.\n" unless defined ($curMachine);
die "Arch argument missing.\n" unless defined ($curArch);
die "Time argument missing.\n" unless defined ($time);

package esmith;

use strict;
use esmith::AccountsDB;
use esmith::util;

BEGIN
{
    # Clear PATH and related environment variables so that calls to
    # external programs do not cause results to be tainted. See
    # "perlsec" manual page for details.

    $ENV {'PATH'} = '';
    $ENV {'SHELL'} = '/bin/bash';
    delete $ENV {'ENV'};
}

esmith::util::setRealToEffective ();

my $a = esmith::AccountsDB->open_ro() ||
    die "Couldn't open AccountsDB\n";

# ------------------------------------------------
# Open and read in the template netlogon.bat file.
# ------------------------------------------------

open ( INFILE, "< $netlogonTemplate" ) ||
    die "Couldn't open the input file '$netlogonTemplate' : $!\n";

my @infile = <INFILE>;

close ( INFILE );

# --------------------------------------------------
# Open an output file for the generated batch script
# --------------------------------------------------

open ( NETLOGON, "> $netlogonFile" ) || 
    die "Couldn't open the output batch file: '$netlogonFile' : $!\n";

print NETLOGON "\@REM $curUser logging in from a $curArch box \015\n";
print NETLOGON "\@REM called $curMachine on $time\015\n";

my $line;
my @activelevels = ( 1 );
my $level = 0;

foreach $line ( @infile ) 
{
    if ( ( index $line, '#if' ) == 0 )
    {
        if ( $activelevels[ $level ] )
        {
            if ( ( index $line, '#ifg' ) == 0 )
            {
               $level++;
               my $grouplist = $line;

               ### Clean the line and get a list of groups:
               $grouplist =~ s/\#ifg|\s|\n|\015//g;
               my @groups = split ( ',', $grouplist );

               ### Check if the curUser is in any of the groups:
               $activelevels[ $level ] = 0;
               my $group;
               foreach $group ( @groups )
               {
                  if ( !$activelevels[ $level ] )
                  {
                     $activelevels[ $level ] = $a->is_user_in_group($curUser, $group);
                  }
               }

               ### If the user is in the list, add a comment to the batch file:
               if ( $activelevels[ $level ] )
               {
                  print NETLOGON "REM $line";
               }
            }
            elsif ( ( index $line, '#ifu' ) == 0 )
            {
               $level++;
               my $userlist = $line;

               ### Clean the line and get a list of users:
               $userlist =~ s/\#ifu|\s|\n|\015//g;
               my @users = split ( ',', $userlist );

               ### Check if the curUser matches any in the list:
               $activelevels[ $level ] = 0;
               my $user;
               foreach $user ( @users )
               {
                  if ( !$activelevels[ $level ] )
                  {
                     $activelevels[ $level ] = ( $curUser eq $user );
                  }
               }

               ### If the user is in the list, add a comment to the batch file:
               if ( $activelevels[ $level ] )
               {
                  print NETLOGON "REM $line";
               }
            }
            elsif ( ( index $line, '#ifm' ) == 0 )
            {
               $level++;
               my $machinelist = $line;

               ### Clean the line and get a list of machines:
               $machinelist =~ s/\#ifm|\s|\n|\015//g;
               my @machines = split ( ',', $machinelist );

               ### Check if the curMachine matches any in the list:
               $activelevels[ $level ] = 0;
               my $machine;
               foreach $machine ( @machines )
               {
                  if ( !$activelevels[ $level ] )
                  {
                     $activelevels[ $level ] = ( $curMachine eq $machine );
                  }
               }

               ### If the machine is in the list, add a comment to the batch file:
               if ( $activelevels[ $level ] )
               {
                  print NETLOGON "REM $line";
               }
            }
            elsif ( ( index $line, '#ifa' ) == 0 )
            {
               $level++;
               my $archlist = $line;

               ### Clean the line and get a list of architectures:
               $archlist =~ s/\#ifa|\s|\n|\015//g;
               my @archs = split ( ',', $archlist );

               ### Check if the curArch matches any in the list:
               $activelevels[ $level ] = 0;
               my $arch;
               foreach $arch ( @archs )
               {
                  if ( !$activelevels[ $level ] )
                  {
                     $activelevels[ $level ] = ( $curArch eq $arch );
                  }
               }

               ### If the arch is in the list, add a comment to the batch file:
               if ( $activelevels[ $level ] )
               {
                  print NETLOGON "REM $line";
               }
            }
            else
            {
               die "Unknown '#if' statement found!\n";
            }

        }
        else
        {
            $level++;
            $activelevels[ $level ] = 0;
        }
    }
    elsif ( ( index $line, '#endif' ) == 0 ) 
    {
        die "Stray '#endif' found!\n" unless ( $level > 0 );
        if ( $activelevels[ $level ] )
        {
            print NETLOGON "REM $line";
        }
        $level--;
    }
    elsif ( $activelevels[ $level ] )
    {
        print NETLOGON "$line";
    }
}

die "Not enough '#endif' lines in template!\n" unless $level == 0;

close ( NETLOGON );

chmod ( 0744, "$netlogonFile" );

exit (0);