#!/usr/bin/perl -w 
#
# $Id: benutzerantrag_check.pl,v 1.3 1997/06/12 18:05:21 webadm Exp $
#
#
# DESCRIPTION: benutzerantrag_check.pl - read CGI-Input from
#   benutzerantrag.pl and return errors or a control-msg
# URL: none yet
#
# AUTHOR: Cord Beermann (cord@Wunder-Nett.org)
#
# Thanks to: Ralf Begemann (begemann@cc.fh-lippe.de)
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#
# A Perl script is "correct" if it gets the job done before your boss fires
# you.
# ('Programming Perl Second Edition' by Larry Wall, Tom Christiansen
#   & Randal. L. Schwartz)
#
# Bugs and shortcomings
# none yet
#
# Todo
# * write instructions
#
### Configuration ###
#
#
### End of Configuration ###

# Initialize Variables
use vars qw ! $s!;

# include perl-modules
use CGI::Carp;
use CGI qw(:standard);
use CGI qw(:shortcuts);

# initialize the CGI-Module and load the form-input
$query = new CGI;
$query->autoEscape(undef);

# Print out a content-type for HTTP/1.0 compatibility and the HTML-Head
print $query->header;
print $query->start_html(-"title"=>'Benutzerantrag',
                         -"author"=>'gnats@thalassa.cc.fh-lippe.de',
                         -"base"=>'true',
                         -"text"=>'#000000',
                         -"BGCOLOR"=>'#FFFFF7');

print "\n";
print(h1('Benutzerantrag f&uuml;r die zentralen Rechneranlagen der FH Lippe'),
      hr
      );

# check if we got a referer from the client
if ($query->referer) {
    # if we don't get the expected source call error-routine
    unless ($query->referer eq
	    'http://www.fh-lippe.de/local-bin/benutzerantrag.pl') {
	error('Sie haben das Formular nicht korrekt aufgerufen, bitte wenden
	      Sie Sich an die Benutzerberatung.');
    }
} else {
    # if there is no referer call error-routine
    error('Ihr Browser ist falsch konfiguriert, oder nicht zum
	  Ausf&uuml;llen dieses Formulars geeignet, deaktivieren Sie den
	  Proxy und versuchen Sie es erneut.');
}

# check the input fields for correctness. If not correct call error-routine
error('Sie haben keinen Namen angegeben') unless $query->param('name');
error('Doppelpunkte und Semikola sind im Namen nicht erlaubt.') if
    $query->param('name') =~ /[\:\;]/;
if ($query->param('oe')) {
    if (($query->param('oe') eq 'Sonstige') && !$query->param('sonstige')) {
	error('Sie haben bei Fachbereich oder Organisationseinheit <EM>andere
	      Hochschule</EM> ausgew&auml;hlt, aber das Zusatzfeld nicht
	      ausgef&uuml;llt.') 
    } else {
	error('Doppelpunkte und Semikola sind im Zusatzfeld <EM>andere
	      Hochschule</EM> nicht erlaubt.') if $query->param('name') =~
	      /[\:\;]/;
    }
} else {
    error('Sie haben nicht angegeben, welchem Fachbereich oder welcher 
	  Organisationseinheit Sie angeh&ouml;ren.');
}

if ($query->param('status')) {
    if ($query->param('status') ne 'Studentin / Student') {
	if ($query->param('telefond')) {
	    error('Sie haben eine falsche dienstliche Telefonnummer
		  angegeben') if (length($query->param('telefond')) != 3 ||
				  $query->param('telefond') =~ /[^\d]/);
	} else {
	    error('Sie haben Ihre dienstliche Telefonnummer nicht
		  angegeben');
	}
    } else {
	if ($query->param('matrikel')) {
	    error('Sie haben eine falsche Matrikelnummer angegeben') if
		(length($query->param('matrikel')) != 8 ||
		 $query->param('matrikel') =~ /[^\d]/);
	} else {
	    error('Sie haben keine Matrikelnummer angegeben');
	}
    }
} else {
    error('Sie haben Ihren Status an der Hochschule nicht angegeben');
}

if ($query->param('login')) {
    error('Benutzername <EM>' . $query->param('login') . '</EM> ist zu kurz
	  (min. 4 Zeichen)') if (length($query->param('login')) < 4);
    error('Benutzername <EM>' . $query->param('login') . '</EM> ist zu lang
	  (max. 8 Zeichen)') if (length($query->param('login')) > 8);
    error('Benutzername <EM>' . $query->param('login') . '</EM> enth&auml;lt
	  eine Zahl am Anfang (Benutzername mu&szlig; mit einem Buchstaben
	  beginnen)') if ($query->param('login') =~ /^\d/);
    error('Benutzername <EM>' . $query->param('login') . '</EM> enth&auml;lt
	  illegale Zeichen (nur Kleinbuchstaben und Zahlen erlaubt)') unless
	  ($query->param('login') =~ /^[a-z0-9]*$/);
    # check if the given login-name is available on all systems
    $unixrealname = isfhlippeunixuser($query->param('login'));
    $ntrealname = isfhlippentuser($query->param('login'));
    $novellrealname = isfhlippenovelluser($query->param('login'));
    if ($unixrealname and $ntrealname and $novellrealname) {
	error('Der Benutzername <EM>' . $query->param('login') . "</EM> ist
	      belegt. Bitte suchen Sie Sich einen anderen Benutzernamen
	      aus.");
    } else {
	# if login-name is available on some systems, give output and tell
	# who put down the login on the other systems
	if ($unixrealname) {
	    chomp($unixrealname);
	    error('Der Benutzername <EM>' . $query->param('login') . "</EM>
		  ist bereits von '$unixrealname' belegt. Wenn dieses Ihr
		  UNIX-Zugang ist, k&ouml;nnen Sie in der Benutzerberatung
		  einen Zugang f&uuml;r ein anderes System unter demselben
		  Namen beantragen.");
	}
	if ($ntrealname) {
	    chomp($ntrealname);
	    error('Der Benutzername <EM>' . $query->param('login') . "</EM>
		  ist auf dem Windows-NT-System bereits von '$ntrealname'
		  belegt.  Wenn dieses Ihr NT-Zugang ist, k&ouml;nnen Sie in
		  der Benutzerberatung einen Zugang f&uuml;r ein anderes
		  System unter demselben Namen beantragen.");
	} elsif ($novellrealname) {
	    chomp($novellrealname);
	    error('Der Benutzername <EM>' . $query->param('login') . "</EM>
		  ist auf dem Novell-System bereits von '$novellrealname'
		  belegt.  Wenn dieses Ihr Novell-Zugang ist, k&ouml;nnen
		  Sie in der Benutzerberatung einen Zugang f&uuml;r ein
		  anderes System unter demselben Namen beantragen.");
	}
    }
    error('Der Benutzername <EM>' . $query->param('login') . '</EM> ist
	  reserviert')
	if &isreserved($query->param('login'),$query->param('inode'));
    error('Der Benutzername <EM>' . $query->param('login') . '</EM> ist nicht
	  verf&uuml;gbar') if &isfhlippehost($query->param('login'));
} else {
    error('Sie haben keinen Benutzernamen angegeben');
}

unless ($query->param('password1') || $query->param('password2')) {
    error('Sie haben kein Pa&szlig;wort angegeben');
} else {
    error('Die Felder Pa&szlig;wort und Pa&szlig;wort Abgleich sind nicht
	identisch') unless ($query->param('password1') eq
	$query->param('password2'));
    error('Ihr Pa&szlig;wort ist zu kurz (min. 6 Zeichen)') if
	(length($query->param('password1')) < 6);
    error('Ihr Pa&szlig;wort enth&auml;lt illegale Zeichen') unless
	($query->param('password1') =~
	 /^[A-Za-z0-9\,\.\-\;\:\_\+\*\?\=\(\)\/&\!\"\$\%]+$/);
    error('Ihr Pa&szlig;wort enth&auml;lt keine Buchstaben') unless
	($query->param('password1') =~ /[A-Za-z]/);
    error('Ihr Pa&szlig;wort enth&auml;lt keine Zahlen oder Sonderzeichen')
	unless ($query->param('password1') =~
		/[0-9\,\.\-\;\:\_\+\*\?\=\(\)\/&\!\"\$\%]/);
    error('Sie haben das Beispiel als Pa&szlig;wort eingegeben. Bitte denken
	  Sie Sich ein anderes Pa&szlig;wort aus.') if
	($query->param('password1') eq 'S1MvdFH');
    error('Sie haben Ihren Benutzernamen im Pa&szlig;wort verwendet. Diese
	  Methode f&uuml;hrt zu <em>ratbaren</em> Pa&szlig;w&ouml;rtern.
	  Bitte denken Sie Sich ein besseres Pa&szlig;wort aus.') if
	($query->param('password1') =~ $query->param('login'));
    foreach $foo (split /\s/, $query->param('name')) {
	error('Sie haben Teile Ihres Namens im Pa&szlig;wort verwendet. Diese
	      Methode f&uuml;hrt zu <em>ratbaren</em> Pa&szlig;w&ouml;rtern.
	      Bitte denken Sie Sich ein besseres Pa&szlig;wort aus.') if
	    ($query->param('password1') =~ /$foo/i);
    }
#    $password = crypt($query->param('password1'), 'jo');
    $password = $query->param('password1');
}

if ($query->param('plz')) {
    error('Sie haben eine falsche Postleitzahl angegeben') if
	(length($query->param('plz')) != 5 ||
	 $query->param('plz') =~ /[^\d]/);
} else {
    error('Sie haben keine Postleitzahl angegeben') 
}

error('Sie haben keinen Ort angegeben') unless $query->param('ort');

# if an error occured print this for jumping back WITH all given variables
if ($error) {
    print '</ul>';
    print $query->startform(-action=>'/local-bin/benutzerantrag.pl');
    print '<INPUT TYPE="HIDDEN" NAME="name" VALUE="' . $query->param('name') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="status" VALUE="' . $query->param('status') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="matrikel" VALUE="' . $query->param('matrikel') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="telefond" VALUE="' . $query->param('telefond') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="oe" VALUE="' . $query->param('oe') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="sonstige" VALUE="' . $query->param('sonstige') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="login" VALUE="' . $query->param('login') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="password1" VALUE="' .$query->param('password1') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="password2" VALUE="' .$query->param('password2') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="strasse" VALUE="' . $query->param('strasse') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="plz" VALUE="' . $query->param('plz') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="ort" VALUE="' . $query->param('ort') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="telefonp" VALUE="' . $query->param('telefonp') . '">';
    print '<p>Bitte dr&uuml;cken Sie nun ';
    print '<INPUT TYPE="submit" NAME="Zur&uuml;ck" VALUE="Zur&uuml;ck">';
    print ' und korrigieren Sie Ihre Angaben.</p>';
} else {
    # if there is no error touch a file to reserve the login-name
    open(LOGIN, '>/var/infosystems/www/security/login/' .
	 $query->param('login')) or
	die('open /var/infosystems/www/security/login/' .
	    "$query->param('login'): $!");
    close (LOGIN);

    # get inode number to lock/unlock changes if there is an error
    $inode = (stat('/var/infosystems/www/security/login/' .
			$query->param('login')))[1];

    # All correct, give the input back for a last check
    print p('Bitte &uuml;berpr&uuml;fen Sie Ihre Angaben noch einmal.'), 
	  hr;
    print $query->startform(-action=>'/local-bin/benutzerantrag_print.pl');
    print '<pre>';
    print '<INPUT TYPE="HIDDEN" NAME="name" VALUE="' . $query->param('name') . '">';
    print 'Name:                  ' . $query->param('name') . "\n";
    print '<INPUT TYPE="HIDDEN" NAME="status" VALUE="' . $query->param('status') . '">';
    print 'Status:                ' . $query->param('status') . "\n";
    if ($query->param('status') eq 'Studentin / Student') {
	print '<INPUT TYPE="HIDDEN" NAME="matrikel" VALUE="' . $query->param('matrikel') . '">';
	print 'Matrikelnummer:        ' . $query->param('matrikel') . "\n";
    } else {
	print '<INPUT TYPE="HIDDEN" NAME="telefond" VALUE="' . $query->param('telefond') . '">';
	print 'Telefon dienstlich:    ' . $query->param('telefond') . "\n";
    }
    if ($query->param('oe') eq 'andere Hochschule') {
	print '<INPUT TYPE="HIDDEN" NAME="oe" VALUE="andere Hochschule - ' . $query->param('sonstige') . '">';
	print 'andere Hochschule:     ' . $query->param('sonstige') . "\n";
    } else {
	print '<INPUT TYPE="HIDDEN" NAME="oe" VALUE="' . $query->param('oe') . '">';
	print 'Organisationseinheit:  ' . $query->param('oe') . "\n";
    }
    print '<INPUT TYPE="HIDDEN" NAME="login" VALUE="' . $query->param('login') . '">';
    print 'Benutzername:		' . $query->param('login');
    print '<INPUT TYPE="HIDDEN" NAME="password" VALUE="' . $password . '">' . "\n";
    print '<INPUT TYPE="HIDDEN" NAME="strasse" VALUE="' . $query->param('strasse') . '">';
    print 'Stra&szlig;e:                ' . $query->param('strasse');
    print '<INPUT TYPE="HIDDEN" NAME="plz" VALUE="' . $query->param('plz') . '">' . "\n";
    print '<INPUT TYPE="HIDDEN" NAME="ort" VALUE="' . $query->param('ort') . '">';
    print 'Wohnort:               ' . $query->param('plz') . ' ' . $query->param('ort') . "\n";
    print '<INPUT TYPE="HIDDEN" NAME="telefonp" VALUE="' . $query->param('telefonp') . '">';
    print 'Telefon privat:        ' . $query->param('telefonp') . "\n";
    print '<INPUT TYPE="HIDDEN" NAME="inode" VALUE="' . $inode . '">';
    print '</pre><hr>';
    print '<p>Wenn alle Angaben korrekt sind, k&ouml;nnen Sie nun den Antrag ';
    print 'ausdrucken. Dr&uuml;cken Sie dazu einen der Kn&ouml;pfe unten.</p>';
    print '<INPUT TYPE="submit" NAME="raum" VALUE="Raum 304">';
    print '<INPUT TYPE="submit" NAME="raum" VALUE="Raum 342">';
    print '<INPUT TYPE="submit" NAME="raum" VALUE="Raum 343">';
    print '<INPUT TYPE="submit" NAME="raum" VALUE="Raum 344">';
    print '<INPUT TYPE="submit" NAME="raum" VALUE="Raum 364">';
    print '</FORM>';

    print $query->startform(-action=>'/local-bin/benutzerantrag.pl');
    print '<INPUT TYPE="HIDDEN" NAME="name" VALUE="' . $query->param('name') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="status" VALUE="' . $query->param('status') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="matrikel" VALUE="' . $query->param('matrikel') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="telefond" VALUE="' . $query->param('telefond') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="oe" VALUE="' . $query->param('oe') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="login" VALUE="' . $query->param('login') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="password1" VALUE="' .$query->param('password1') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="password2" VALUE="' .$query->param('password2') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="strasse" VALUE="' . $query->param('strasse') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="plz" VALUE="' . $query->param('plz') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="ort" VALUE="' . $query->param('ort') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="telefonp" VALUE="' . $query->param('telefonp') . '">';
    print '<INPUT TYPE="HIDDEN" NAME="inode" VALUE="' . $inode . '">';
    print '<p>Wenn Sie fehlerhafte Angaben gefunden haben, dr&uuml;cken Sie';
    print '<INPUT TYPE="submit" NAME="Zur&uuml;ck" VALUE="Zur&uuml;ck">';
    print ' und korrigieren Sie Ihre Angaben.</p>';
}

print(hr,
      p('Wenn Sie Probleme mit diesem Formular haben, oder etwaige
	Fehlermeldungen nicht verstehen, suchen Sie bitte die',
	a({href=>'/fhl/dvz/loesungen/misc/benutzerberatung.html'},
	  'Benutzerberatung' ) , 'auf.' ));
				      

print "</BODY></HTML>\n";

# ------------------------------------------------------------

# subroutine to check if the given name is a hostname
sub isfhlippehost {
    my $name = shift(@_);
    # list of all subdomains which should be checked
    my @subdomains = qw(fh-lippe.de adm.fh-lippe.de arch.fh-lippe.de
			bib.fh-lippe.de cc.fh-lippe.de ce.fh-lippe.de
			des.fh-lippe.de ee.fh-lippe.de ft.fh-lippe.de
			ia.fh-lippe.de me.fh-lippe.de noc.fh-lippe.de
			pe.fh-lippe.de phy.fh-lippe.de stud.fh-lippe.de);
    foreach $subdomain (@subdomains) {
	return 1 if (gethostbyname($name . '.' . $subdomain));
    }
    undef;
}

# subroutine to check if the given name is a user in the NIS+-tables
sub isfhlippeunixuser {
    my $name = shift(@_);
    # list of all nis-domains to check
    my @nisdomains = qw(passwd.org_dir.fh-lippe.de
			passwd.org_dir.cc.fh-lippe.de 
			passwd.org_dir.ce.fh-lippe.de
			);
    foreach $nisdomain (@nisdomains) {
	if (`/usr/bin/nismatch -c name=$name $nisdomain` > 0) {
	    # get the realname if exist and return it.
	    $retvalue = `/usr/bin/niscat $nisdomain |/usr/bin/grep '^$name:' |cut -f5 -d\:`;
	    return $retvalue;
	}
    }
    undef;
}

# subroutine to check if the given name is a Novell-User
# the file must be updated by hand :-/
sub isfhlippenovelluser {
    my $name = shift(@_);
    open(NOVELLUSER, '/var/infosystems/www/security/benutzer.novell.txt') or
	die('open /var/infosystems/www/security/benutzer.novell.txt: $!');
    while (<NOVELLUSER>) {
	($login,$realname) = (split /:/);
	if ($login eq $name) {
	    # Return name of the user
	    return ($realname);
	}
    }
    close (NOVELLUSER);
    undef;
}

# subroutine to check if the given name is a NT-User
# the file must be updated by hand :-/
sub isfhlippentuser {
    my $name = shift(@_);
    open(NTUSER, '/var/infosystems/www/security/benutzer.nt.txt') or
	die('open /var/infosystems/www/security/benutzer.nt.txt: $!');
    while (<NTUSER>) {
	($login,$realname) = (split /\,/)[0,1];
	if ($login =~ /^$name$/i) {
	    # return Realname
	    return ($realname);
	}
    }
    close (NTUSER);
    undef;
}

# subroutine to check if the given name is proposed before
sub isreserved {
    my $name = shift(@_);
    my $inode = shift(@_);
    foreach $i ("$name", "$name.0", "$name.1", "$name.2", "$name.3",
		"$name.4", "$name.5", "$name.6", "$name.7", "$name.8",
		"$name.9") {
	if (-e '/var/infosystems/www/security/login/' . $i) {
	    unless ((stat('/var/infosystems/www/security/login/' . $i))[1] eq $inode) {
		return 1
	    } else {
		last;
	    }
	}
    }
    undef;
}

# error subroutine
sub error {
    # get input to $text
    my $text = shift(@_);
    # if this routine is called the first time print this.
    unless ($error) {
	print "<H2>Fehler im Benutzerantrag</h2>\n";
	print "<P>Es sind die folgenden Fehler aufgetreten:</p>\n";
	print '<UL>';
	$error=1;
    }
    # print $text
    print "<li>$text</li>\n";
}
