initial commit of file from CVS for smeserver-loginscript on Sat Sep 7 20:34:19 AEST 2024

This commit is contained in:
Trevor Batley
2024-09-07 20:34:20 +10:00
parent d6d65f9ac8
commit da7439100c
19 changed files with 1119 additions and 2 deletions

View File

@@ -0,0 +1,36 @@
#!/usr/bin/perl -w
#----------------------------------------------------------------------
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#----------------------------------------------------------------------
package esmith;
use strict;
use Errno;
use esmith::config;
use esmith::util;
my %conf;
tie %conf, 'esmith::config';
#------------------------------------------------------------
# Configure login script
#------------------------------------------------------------
esmith::util::processTemplate (\%conf, "/home/e-smith/files/samba/netlogon/netlogon.bat");
exit (0);

View File

View File

@@ -0,0 +1,3 @@
logon drive = { defined($WinNTLogonDrive) ? $WinNTLogonDrive . ':' : 'h:' }

View File

@@ -0,0 +1 @@
root preexec = "/usr/local/bin/generate_netlogon /home/e-smith/files/samba/netlogon/netlogon.template /home/e-smith/files/users/%U/home/netlogon.bat %U %m %a %T"

View File

@@ -0,0 +1,13 @@
@ECHO OFF
REM ******************************************************
REM ** Mapping a drive to the home folder triggers the **
REM ** generation of the login script. Windows NT/2K **
REM ** does this automatically but we need to map the **
REM ** drive manually for the others. **
REM ******************************************************
IF "%OS%"=="Windows_NT" GOTO :SkipHomeMapping
NET USE { defined($WinNTLogonDrive) ? $WinNTLogonDrive . ':' : 'h:' } /home
:SkipHomeMapping

View File

@@ -0,0 +1,5 @@
REM Call the generated login script from the user's home folder:
CALL { defined($WinNTLogonDrive) ? $WinNTLogonDrive . ':' : 'h:' }\netlogon.bat

View File

@@ -0,0 +1,6 @@
@REM #------------------------------------------------------------
@REM # DO NOT MODIFY THIS FILE! It is updated automatically by the
@REM # e-smith server and gateway software. Instead, modify the source
@REM # template in the /etc/e-smith/templates-custom directory. For more
@REM # information, see http://www.e-smith.org.
@REM #------------------------------------------------------------

View File

@@ -0,0 +1,3 @@
@REM #------------------------------------------------------------
@REM # TEMPLATE END
@REM #------------------------------------------------------------

View File

@@ -0,0 +1,250 @@
#!/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->startform (-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->endform;
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 );
}

View File

View File

@@ -0,0 +1,66 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<TITLE>e-smith manager</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#707070" ALINK="#707070" VLINK="#707070"
TOPMARGIN="0" LEFTMARGIN="0" MARGINHEIGHT="0" MARGINWIDTH="0">
<BR CLEAR="ALL">
<DIV STYLE="position: absolute; visibility: inherit; top: 50px; left: 56px; width: 85%; z-index: 2">
<FONT FACE="Helvetica,Arial">
<H2>Example Login Script</H2>
<P>Below is an example login script which utilises all of the special
'<TT><B>#if<I>x</I></B></TT>' tags:
<P>
<TT><PRE>
@ECHO OFF
ECHO Welcome to the XYZ computer network
ECHO -----------------------------------
ECHO.
#ifg finance, receipting
REM Map financedata iBay for finance and receipting groups:
NET USE F: \\server\financedata
#endif
#ifu fred
REM Say hello to Fred
ECHO Hello Fred!
#endif
#ifm fast-pc, speedy, killer-p3
REM Map the IT printer for the above named computers:
NET USE LPT1: \\server\itprn
#endif
#ifa Win95, WinNT
REM Run a virus update check on the Windows NT and 9x PCs:
call \\server\utils\files\virus\update.bat
REM The available Architectures are:
REM WinNT = Windows NT or 2000
REM Win95 = Windows 95 or 98
REM WfWg = Windows for Workgroups
#endif
</PRE></TT>
<P>
<HR>
<FONT SIZE="-1">copyright (c) 1999, 2000 e-smith, inc. all rights reserved.</FONT>
</FONT>
</DIV>
</BODY>
</HTML>

View File

@@ -0,0 +1,239 @@
#!/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::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 %accounts;
tie %accounts, 'esmith::config', '/home/e-smith/db/accounts';
# ------------------------------------------------
# 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 ] = isInGroup($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);
# --------------------------------------------------
# Subroutine to check if a given user is in a group:
# --------------------------------------------------
sub isInGroup($$)
{
my ($user, $group) = @_;
my $value = $accounts{$group};
if ( defined ($value) )
{
my ($type, %properties) = split (/\|/, $value);
if ($type eq 'group')
{
my @members = split (/,/, $properties {'Members'});
my $member;
# TODO: grep (/^$user$/, @members)
foreach $member ( @members )
{
if ( $member eq $user )
{
return 1;
}
}
}
}
return 0;
}