#!/usr/bin/perl -wT

#----------------------------------------------------------------------
# heading     : Collaboration
# description : Login script manager
# navigation  : 3000 3375
#----------------------------------------------------------------------

package esmith;

use strict;
use CGI ':all';
use CGI::Carp qw(fatalsToBrowser);

use esmith::cgi;
use esmith::config;
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 ();

$CGI::POST_MAX=1024 * 100;  # max 100K posts
$CGI::DISABLE_UPLOADS = 1;  # no uploads

my %conf;
tie %conf, 'esmith::config';

#------------------------------------------------------------
# examine state parameter and display the appropriate form
#------------------------------------------------------------

my $q = new CGI;

if (! grep (/^state$/, $q->param))
{
    showInitial ($q, '', '');
}

elsif ($q->param ('state') eq "perform")
{
    performAndShowResult ($q);
}

else
{
    esmith::cgi::genStateError ($q, \%conf);
}

exit (0);

#------------------------------------------------------------
# subroutine to display initial form
#------------------------------------------------------------

sub showInitial ($$$)
{
    my ($q, $msg, $netlogon) = @_;

    #------------------------------------------------------------
    # If there's a message, we just finished an operation so show the
    # status report. If no message, this is a new list of accounts.
    #------------------------------------------------------------

    if ($msg eq '')
    {
        esmith::cgi::genHeaderNonCacheable
            ($q, \%conf, 'Modify Windows login script');
    }
    else
    {
        esmith::cgi::genHeaderNonCacheable
            ($q, \%conf, 'Operation status report');

        print $q->p ($msg);
        print $q->hr;
    }

    #------------------------------------------------------------
    # Re-load the netlogon template file if it hasn't been passed
    #------------------------------------------------------------

    if ( $netlogon eq '' )
    {
	if ( -e '/home/e-smith/files/samba/netlogon/netlogon.template' ) 
	{
	    open ( NETLOGON, '< /home/e-smith/files/samba/netlogon/netlogon.template' ) 
                || die 'Couldn\'t open /home/e-smith/files/samba/netlogon/netlogon.template file!'; 
            my @netlogon = <NETLOGON>;
            close NETLOGON;
    
            foreach (@netlogon)
            {
                $netlogon .= $_;
            }
	}
	else
	{
	    $netlogon = "\@ECHO OFF\015\n\015\n";
	}
    }
 
 
    my %driveLabels = ('d' => 'D:','e' => 'E:','f' => 'F:','g' => 'G:','h' => 'H:','i' => 'I:','j' => 'J:','k' => 'K:','l' => 'L:','m' => 'M:','n' => 'N:','o' => 'O:','p' => 'P:','q' => 'Q:','r' => 'R:','s' => 'S:','t' => 'T:','u' => 'U:','v' => 'V:','w' => 'W:','x' => 'X:','y' => 'Y:','z' => 'Z:');

    # Define the WinNTLogonDrive conf value if it hasn't been defined
    if (! defined ( $conf{'WinNTLogonDrive'} ) )
    {
	$conf{'WinNTLogonDrive'} = 'h';
    }

    print $q->start_form (-method => 'POST', -action => $q->url (-absolute => 1));

    print $q->p ('Below you can modify the login script template.');

    print $q->p ("You can use special tags '". 
        $q->tt($q->b('#ifg groupname1, groupname2...')). "', '".
        $q->tt($q->b('#ifu username1, username2...')). "', '".
        $q->tt($q->b('#ifm machinename1, machinename2...')). "', '".
        $q->tt($q->b('#ifa archtype1, archtype2...')). "' and '".
        $q->tt($q->b('#endif')). 
        "' to create blocks of script that are only included ".
        'if those criteria are met.');

    print $q->p ('See this ', $q->a({href => '../loginscriptexample.html'}, 'example'), ' to get a better idea.');


    print $q->table ({border => 0, cellspacing => 0, cellpadding => 4},

         esmith::cgi::genTextRow(
			     $q, $q->textarea (-name     => 'netlogon',
						-override => 1,
						-default  => $netlogon,
						-rows     => 16,
						-columns  => 64)),

        esmith::cgi::genTextRow
            ($q, $q->p ('A drive letter will automatically be mapped to the users home folder. ',
                        'You can specify which drive the clients will use here:')),

        esmith::cgi::genWidgetRow ($q,
                                   "Home Drive",
                                   $q->popup_menu (-name    => 'logonDrive',
                                                   -values  => ['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'],
                                                   -default => $conf {'WinNTLogonDrive'},
                                                   -labels  => \%driveLabels)),

		     $q->Tr (esmith::cgi::genCell
			     ($q, $q->b ($q->submit (-name => 'action', -value => 'Save')))));

    print $q->hidden (-name => 'state', -override => 1, -default => 'perform');
    print $q->end_form;
    esmith::cgi::genFooter ($q);
}

#------------------------------------------------------------
# subroutine to perform actions and display result
#------------------------------------------------------------

sub performAndShowResult ($)
{
    my ($q) = @_;

    my $netlogon = $q->param ('netlogon');
   
    my $logonDrive = $q->param ('logonDrive');

    #------------------------------------
    # Check the file for mis-matched if's
    #------------------------------------

    my $line;
    my $level = 0;
    my $msg = '';
    my @netlogonlist = split( "\n", $netlogon );
    foreach $line (@netlogonlist)
    {
        next if ( $msg ne '' );
        if ( ( index $line, '#if' ) == 0 )
        {
            if ( ( index $line, '#ifg' ) == 0 || ( index $line, '#ifu' ) == 0 ||
                 ( index $line, '#ifa' ) == 0 || ( index $line, '#ifm' ) == 0 )
            {
               $level++;
            }
            else
            {
               $msg = 'Error: Unrecognised #if tag found. '.
                      $q->b('Script NOT saved.');;
            }
        }
        elsif ( ( index $line, '#endif' ) == 0 )
        {
            $level--;
        }
        if ( $msg eq '' && $level < 0 )
        {
            $msg = 'Error: There are misplaced #endif tag(s) or missing '.
                   '#if tag(s). ' . $q->b('Script NOT saved.');;
        }
    }

    if ( $msg eq '' )
    {
        if ( $level != 0 )
        {
            $msg = 'Error: There are misplaced #if tag(s) or missing '.
                   '#endif tag(s). ' . $q->b('Script NOT saved.');
        }
    }


    if ( $msg eq '' )
    {

        #------------------------------------------------------
        # Write the new netlogon file (if there were no errors)
        #------------------------------------------------------
    
        open ( NETLOGON, '> /home/e-smith/files/samba/netlogon/netlogon.template' ) 
            || die 'Couldn\'t open /home/e-smith/files/samba/netlogon/netlogon.template file!'; 
    
        print NETLOGON $netlogon;
    
        close NETLOGON;
        
        $msg = 'Login script successfully saved.';
    }

    #-------------------------------
    # Save the WinNTLogonDrive value
    #-------------------------------

    $conf{'WinNTLogonDrive'} = $logonDrive;

    system ("/sbin/e-smith/signal-event", "conf-logondrive") == 0
        or die ("Error occurred while saving logon drive.\n");

    showInitial( $q, $msg, $netlogon );
}

