###############################################################################
#                       AUTH-EXTRA-LIB.PL
#
# This script was written by Selena Sol & Gunther Birznieks. 
# Date Created: 5-10-96
# Date Last Modified: 11-21-98
# Last modified by Michael E. Schechter (mschechter@earthlink.net)
#
#   You may copy this under the terms of the GNU General Public
#   License or the Artistic License which is distributed with
#   copies of Perl v5.x for UNIX.
# 
# Selena Sol may be contacted at selena@extropia.com
#
# Purpose: Provides a supporting set of routines to the
# AUTH-LIB.PL library program.  Provides all of the extra routines
# for registering a user, searching, logging in, etc., etc.
#
# Special Notes: This script relies on mail-lib.pl for sending
# email (if the feature is activated)
#
# It also uses CRYPT inside the AuthEncrytWrap routine.  If your 
# OS does not support Crypt, you can write your own inside AuthEncryptWrap.
#
###############################################################################

# We keep the cosmetic HTML output in a seperate file
# that can be more easily modified outside of the logic 
# related to the code.  The routines in the following file do nothing
# but generate the HTML pages in response to this files actions.

require "$auth_lib/auth-extra-html.pl";

###############################################################################
# Subroutine:  VerifyUser()
#
#	Parameters:
#		$main_script = the script you are calling &GetSessionInfo() from.
#				 *in = a reference to the form data that was read
#					   in with &ReadParse() from cgi-lib.pl.
#
#	Usage:
#		($session, $username, $group, @extra_fields)
#		 = &VerifyUser("script name", *in);
#
#	Output:
#		 $session = session id
#		$username = user name
#		   $group = group information
#	@extra_fields = an array of fields usually consisting of the following:
#				 $name = real name
#				$email = email address
#
# This routine is the heart of everything, it processes
# all the login and registration information if a valid
# session id was not passed to GetSessionInfo in auth-lib.pl.
# Finally, it will return a session id if the user successfully logs
# on.
#
###############################################################################

sub VerifyUser {
	local ($main_script, *in) = @_;
	local ($session, $group, $username, @extra_fields, $bad_logon_message);
	
# If the previous logon had failed, $bad_logon_message will contain a string
# indicating why.  We initialize this string to be empty in case we need it.
	$bad_logon_message = "";
	
# We have 2 ways of authenticating a user: CGI and Server
# based.  CGI Authentication uses this programs routines
# and HTML forms to log the user into the system.  Server
# based authentication uses the WWW Server's built in
# authentication and relies on the Environmental variable
# for the REMOTE_USER name being set.  If you are using
# server based authentication, you will have to modify
# auth-server-lib.pl for your individual setup.

	if ($auth_cgi) {
	
# CGI Authentication determines what to do on the
# basis of what the previous screen was.  This is
# determined by which operational (OP) variable
# was submited (which button was pressed) on each
# screen.

# auth_logon_op is for the login button.

		if ($in{'auth_logon_op'} ne "") {
			($bad_logon_message, $session,
			 $username, $group, @extra_fields) = &CgiLogon($main_script, *in);
		}
		
# public_access_op is for the public access button, if enabled.

		if ($in{'public_access_op'} ne "") {
			local(@fields,$i);
			$username = "PUBLIC";
			$group = "public";
			@fields=($username, $group);
			foreach $i (@auth_extra_fields) {
				push (@fields, "public user");
			}
			$session = &MakeSessionFile(@fields);
		}
		
# auth_search_op is the search for account button.  We check to be
# sure that this is allowed in the setup file as well, to prevent people
# from calling it by just typing it into the query string.

		if (($in{'auth_search_op'} ne "") && $auth_allow_search) {
			&SearchUsers($main_script, *in);
			exit;
		}
		
# auth_search_screen_op is the button to press to bring up the search
# page form.  Again, we check to be sure that searching accounts is allowed.

		if (($in{'auth_search_screen_op'} ne "") && $auth_allow_search) {
			&PrintSearchPage($main_script, *in);
			exit;
		}
		
# auth_register_op is the register button after having entered the
# information for a new account.  We check to be sure that
# registration is allowed in the setup file as well.

		if (($in{'auth_register_op'} ne "") && $auth_allow_register) {
			&RegisterUser($main_script, *in);
			exit;
		}
		
# auth_register_screen_op is the button on the login page (main)
# that brings up the registration form.  Again, check to be sure
# registration is allowed.

		if (($in{'auth_register_screen_op'} ne "") && $auth_allow_register) {
			&PrintRegisterPage;
			exit;
		}
		
# auth_logon_screen_op is the button on many of the other forms that
# takes the user back to the logon screen.

		if ($in{'auth_logon_screen_op'} ne "") {
			&PrintLogonPage($bad_logon_message, $main_script, *in);
			exit;
		}
		
# if we made it this far, it means we are using CGI authentication and 
# and no buttons have been pressed.  We check to be sure that there is
# no session id, and then start up the logon process.

		if ($session eq "") {
			unless ($use_cookies) {
			
# If we are not using cookies to store login information, we print the
# logon page as normal.

				&PrintLogonPage($bad_logon_message, $main_script, *in);
				exit;
			} else {
			
# If we are using cookies, we call in the cookie library, and attempt to
# retrieve the cookie from the user.  If we successfully retrieve the
# cookie, we unscramble the password information and log the user in
# using the &CookieLogon subroutine.

				require ("$auth_lib/cookie-lib.pl");
				if (&GetCompressedCookies("$auth_reg_name")) {
					local($c_user, $c_pword);
					$c_user = $Cookies{'username'};
					$c_pword = $Cookies{'password'};
					$c_pword =~ tr/a-zA-Z0-9/n-za-mN-ZA-M5-90-4/;
					($bad_logon_message, $session, $username, $group,
					 @extra_fields) = &CookieLogon($main_script, $c_user, $c_pword, *in);
				} else {
				
# If we didn't successfullly retrieve the cookie, that means we are dealing
# with either a new user or someone who has lost their cookies ( haha ), and
# thus we provide the logon page.

					&PrintLogonPage($bad_logon_message, $main_script, *in);
					exit;
				}
				
# If we still don't have a session id at this point, we provide the logon page
# again.  This means that we retrieved the cookie, but the data doesn't match
# up with the user file.  We provide the bad_logon_message to let the user
# know what happened.

				if ($session eq "") {
					&PrintLogonPage($bad_logon_message, $main_script, *in);
					exit;
				}
			}
		}
	}
	
# If $auth_server is on, we retrieve the username from the REMOTE_USER
# environment variable, then call the auth-server-lib.pl file to log
# them in.  Note that if you want to use this, you will have to provide
# some routine to do the login in auth-server-lib.pl.

	elsif ($auth_server) {
		$username = $ENV{'REMOTE_USER'};
		if ($username ne "") {
			require "auth-server-lib.pl";
		}
	}
	
# If neither auth_server or auth_cgi were turned on in the setup file,
# it means we are using a "free for all" setup, so we create a default
# session file for the user.

	else {
		local(@fields,$i);
		$username = "public poster";
		$group = "$auth_default_group";
		@fields=($username, $group);
		foreach $i (@auth_extra_fields) {
			push (@fields, "");
		}
		$session = &MakeSessionFile(@fields);
	}
	
# If we made it to this point, we have all the information we need
# to proceed, and we return it back to auth-lib.pl.

	return ($session, $username, $group, @extra_fields);
}

###############################################################################
# Subroutine:  CGILogon()
#
#	Parameters:
#		$main_script = the script you are calling &GetSessionInfo() from.
#				 *in = a reference to the form data that was read
#					   in with &ReadParse() from cgi-lib.pl.
#
#   Usage:
#		($bad_logon_message, $session, $username, $group, @extra_fields) 
#		 = &CGILogon("script name", *in);
#
#   Output:
#		$bad_logon_message = in case the logon fails
#				  $session = session id
#				 $username = user name
#					$group = group information
#			 @extra_fields = an array of fields usually consisting of
#							 the following:
#						$name = real name
#					   $email = email address
#
#  This routine attempts to log the user in.  If the 
#  logon fails, bad_logon_message contains the reason
#  why.  If it is successful, the rest of the returned
#  variables will have valid information.
###############################################################################

sub CgiLogon {
	local ($main_script, *in) = @_;
	local($password, $username, $group, @extra_fields, $user_matched);
	local($form_password, $session, @fields, $bad_logon_message, $temp_pword);

# Initialize all the variables that will be returned to the calling statement.

	$bad_logon_message = "";
	$session = "";
	@fields = ();
	$form_password = $in{"auth_password"};
	$user_matched = 0;
	
# Okay, now we open up the $auth_user_file (from auth.setup), and read through
# it, one line at a time.  On each line, we will split it on our delimiter "|",
# and see if the input user name matches.  If it does, we decrypt the password
# in the user file and compare it to the entered value.  If they match, we create
# a session file using &MakeSessionFile without the password field, since we won't
# need it anymore.  We then close the user file.

	open (USERFILE, "$auth_user_file");
	while (<USERFILE>) {
		chomp($_);
		($password, $username, $group, $first_name, $email) = split(/\|/, $_);
		if ($in{'auth_user_name'} eq $username) {
			$user_matched = 1;
			if (&AuthEncryptWrap ($form_password, $password) eq $password) {
				@fields = split(/\|/, $_);
				shift(@fields);
				$session = &MakeSessionFile(@fields);
			}
		}
	}
	close (USERFILE);
	
# If we matched the the user, but failed to make a session file, the passwords
# didn't match.  If we did't get a user match, the user isn't in the user file.
# We set the bad logon message with the appropriate information.

	if ($user_matched == 1 && $session eq "") {
		$bad_logon_message = "<p><strong>Sorry, Your password did not";
		$bad_logon_message .= " match the username.</strong><p>";
	}
	if ($user_matched == 0) {
		$bad_logon_message = "<p><strong>Sorry, Your username was not";
		$bad_logon_message .= " found.</strong><p>";
	}
	
# If we matched the user, made a session file, want to use cookies in this
# script (set in auth.setup), and the user selected to save their login
# information, we open up the cookie library to write the cookie information
# to the user's browser.  We first scramble the password using ROT-13.

	if ($user_matched && $session && $use_cookies && ($in{'save_info'} eq "on")) {
		require ("$auth_lib/cookie-lib.pl");
			$temp_pword = $in{'auth_password'};
			$temp_pword =~ tr/a-zA-Z0-9/n-za-mN-ZA-M5-90-4/;
			&SetCookieExpDate("$cookie_end_date");
			&SetCompressedCookies("$auth_reg_name", 'username', "$in{'auth_user_name'}",
								  'password', "$temp_pword");
	}
	
# We are now done with this subroutine, so we return the information to the
# calling statement.

	return ($bad_logon_message, $session, @fields);
}

###############################################################################
# Subroutine:  CookieLogon()
#
#	Parameters:
#		$main_script = the script you are calling &GetSessionInfo() from.
#			$ck_user = the username retrieved from the cookie.
#		   $ck_pword = the password (unscrambled) retrieved from the cookie.
#				 *in = a reference to the form data that was read
#					   in with &ReadParse() from cgi-lib.pl.
#
#   Usage:
#		($bad_logon_message, $session, $username, $group, @extra_fields) 
#		 = &CookieLogon("script name", "cookie_user", "cookie_password", *in);
#
#   Output:
#		$bad_logon_message = in case the logon fails
#				  $session = session id
#				 $username = user name
#					$group = group information
#			 @extra_fields = an array of fields usually consisting of
#							 the following:
#						$name = real name
#					   $email = email address
#
#  This routine attempts to log the user in if they have elected to 
#  use cookies to save their login information, and cookie use is
#  enabled.  If the logon fails, bad_logon_message contains the reason
#  why.  If it is successful, the rest of the returned
#  variables will have valid information.
###############################################################################

sub CookieLogon {
	local ($main_script, $ck_user, $ck_pword, *in) = @_;
	local($password, $username, $group, @extra_fields, $user_matched);
	local($session, @fields, $bad_logon_message);

# Initialize all the variables that will be returned to the calling statement.

	$bad_logon_message = "";
	$session = "";
	@fields = ();
	$user_matched = 0;
	
# Okay, now we open up the $auth_user_file (from auth.setup), and read through
# it, one line at a time.  On each line, we will split it on our delimiter "|",
# and see if the cookie user name matches.  If it does, we decrypt the password
# in the user file and compare it to the cookie value.  If they match, we create
# a session file using &MakeSessionFile without the password field, since we won't
# need it anymore.  We then close the user file.

	open (USERFILE, "$auth_user_file");
	while (<USERFILE>) {
		chomp($_);
		($password, $username, $group, $first_name, $email) = split(/\|/, $_);
		if ($ck_user eq $username) {
			$user_matched = 1;
			if (&AuthEncryptWrap ($ck_pword, $password) eq $password) {
				@fields = split(/\|/, $_);
				shift(@fields);
				$session = &MakeSessionFile(@fields);
			}
		}
	}
	close (USERFILE);
	
# If we matched the the user, but failed to make a session file, the passwords
# didn't match.  If we did't get a user match, the user isn't in the user file.
# We set the bad logon message with the appropriate information.

	if ($user_matched == 1 && $session eq "") {
		$bad_logon_message = "<p><strong>Sorry, Your password did not";
		$bad_logon_message .= " match the username.</strong><p>";
	}
	if ($user_matched == 0) {
		$bad_logon_message = "<p><strong>Sorry, Your username was not";
		$bad_logon_message .= " found.</strong><p>";
	}
	
# We are now done with this subroutine, so we return the information to the
# calling statement.

	return ($bad_logon_message, $session, @fields);
}

###############################################################################
# Subroutine:  MakeSessionFile()
#
#	Parameters:
#		@fields = a list of fields that make up the user session file
#
#	Usage:
#		$session = &MakeSessionFile(@fields);
#
#   Output:
#		$session = session id
#
#  This routine makes a session file on the basis of the
#  fields passed from the user file, such as username, group,
#  real name, email, etc.
###############################################################################

sub MakeSessionFile {
	local(@fields) = @_;
	local($session, $session_file);
	
# Okay, we want to make this whole thing low maintenance, so first, clean up
# any old session files that may be laying around.

	&RemoveOldSessions;
	
# Now, we need to have a session id, and these next lines generate that
# randomly.  It does some interesting things to make as sure as possible
# that we won't end up with two session files of the same name.

	srand($$|time);
	$session = int(rand(60000));
	$session = unpack("H*", pack("Nnn", time, $$, $session));
	$session_file = "$session.dat";

# Okay, we have named the session file, so lets fill it up.  We open it
# and in the process create it, and then print all of the values in
# the @fields array delimited by "|".  We then close the file and return
# the session id number.

	open (SESSIONFILE, ">$auth_session_dir/$session_file");
	print SESSIONFILE join ("\|", @fields);
	print SESSIONFILE "\n";
	close (SESSIONFILE);
	return ($session);
}

###############################################################################
# Subroutine: RemoveOldSessions()
#
#	Parameters:
#		None.
#
#	Usage:
#		&RemoveOldSessions;
#
#	Output:
#		None.
#
# This routine removes old session files based on their age, and whether they
# are older than the number of days specified in $auth_session_length
# (auth.setup).
###############################################################################

sub RemoveOldSessions {
	local(@files, $file);

# Okay, we first open up the $auth_session_dir from auth.setup, and read
# in all files that don't start or end with ".", i.e., are not "." or "..".
# We the close the directory, and go through all the files that were returned.
# We make sure that they end in .dat (which is how our session files are created),
# and if they do, and are older than the number of days specified by
# $auth_session_length, we delete them.

	opendir(SESSIONDIR, "$auth_session_dir");
	@files = grep(!/^\.\.?$/,readdir(SESSIONDIR));
	closedir(SESSIONDIR);
	foreach $file (@files) {
		$file =~ /^(\w+\.dat)/o;
		$file = $1;
		if (-M "$auth_session_dir/$file" > $auth_session_length) {
			unlink("$auth_session_dir/$file");
		}
	}
}

###############################################################################
# Subroutine: SearchUsers()
#
#	Parameters:
#		$main_script = the script you are calling &GetSessionInfo() from.
#				 *in = a reference to the form data that was read
#					   in with &ReadParse() from cgi-lib.pl.
#
#   Usage:
#     &SearchUsers($main_script, *in);
#
#   Output:
#     HTML printed out indicating failure or, if successful,
#     indicating the username(s) that matched the email
#     address.
#
#  This routine performs the search on the users in the user
#  file to allow a user to find his userid if it gets lost.
#  The search is performed on email address.
###############################################################################

sub SearchUsers {
	local($main_script, *in) = @_;
	local($user_matched, $field_num, $username, @extra_fields);
	local($auth_email, $user_list, $form_tags);

# First, get the non-authorization form variables as hidden fields (HTML).

	$form_tags = &PrintCurrentFormVars(*in);

# We prepare to search by initializing some things.  We first
# read in the email address supplied, lowercase it, and remove
# any spaces.  We also initialize $user_match and $field_num.

	$auth_email = $in{'auth_email'};
	$auth_email =~ tr/A-Z/a-z/;
	$auth_email =~ s/ //g;
	$user_match = "";
	$field_num = 0;
	
# Go through the @auth_extra_fields (auth.setup) and find the
# index of auth_email.

	foreach (@auth_extra_fields) {
		if ($_ eq "auth_email") {
			last;
		}
		$field_num++;
    }

# Open up the user file, and read through it one line at a time.
# chomp it to remove the new line character, lowercase the entire
# string, and then split the line.  Get the user name, and then
# remove the first three fields (password, username, and group, which
# are required minimums) from the line.  Check to see if the email
# entered by the user now matches the indexed value in the fields.
# If it does, add the username in a "|" delimited string.
# Close the file when we get to the end.

	open (USERFILE, "$auth_user_file");
	while (<USERFILE>) {
		chomp($_);
		tr/A-Z/a-z/;
		@extra_fields = split(/\|/, $_);
		$username = $extra_fields[1];
		shift(@extra_fields);
		shift(@extra_fields);
		shift(@extra_fields);
		$email =~ s/ //g;
		if ($auth_email eq $extra_fields[$field_num]) {
			$user_match .= $username . "|";
		}
	}
	close (USERFILE);

# If the $user_match string is not empty, we found at least one
# match, so we create an HTML $user_list by replacing "|" with "<p>",
# and then we print out the results.  If it is empty, we let the
# user know that no match was found.

	if ($user_match ne "") {
		$user_list = $user_match;
		$user_list =~ s/\|/<p>/g;
		&HTMLPrintSearchResults ($main_script, $form_tags, $user_list);
	} else {
		&HTMLPrintNoSearchResults($main_script, $form_tags);
	}
}

###############################################################################
# Subroutine:  RegisterUser()
#
#  Parameters:
#		$main_script = the script you are calling &GetSessionInfo() from.
#				 *in = a reference to the form data that was read
#					   in with &ReadParse() from cgi-lib.pl.
#
#	Usage:
#		&RegisterUser($main_script, *in);
#
#	Output:
#		HTML indicating Registration success or failure
#
# This routine registers the user and goes through
# many checks before it finally writes the user information
# down into a user data file or emails it to the system
# admin depending on how previous variables were set.
###############################################################################

sub RegisterUser {
	local($main_script, *in) = @_;
	local($x, @form_vars, $group, @f, @write_fields, $password);
	local($form_tags, $user_matched, $userfile,$user_email,$real_password);
	local($random, $salt, @my_mail_fields, $subject, $message, $normal_print);

# Get all the non-authorization form variables into hidden input fields (HTML);

	$form_tags = &PrintCurrentFormVars(*in);

# Initialize some variables that will be used later.

	$group = $auth_default_group;
	@form_vars = ('auth_user_name', @auth_extra_fields);
	$normal_print = 1;

# If we are not generating passwords for our users, push their entered password
# values onto the form variables array.

	unless ($auth_generate_password) {
		push(@form_vars, "auth_password1");
		push(@form_vars, "auth_password2");
	}

# Go through the registration information, and make sure no "|"s were used.

	foreach $x (@form_vars) {
		if ($in{"$x"} eq "" || $in{"$x"} =~ /\|/) {
			&HTMLPrintRegisterNoValidValues($main_script, $form_tags);
			exit;
		}
		if ($x eq "auth_email") {
			$user_email = $in{"$x"};
		}
	}

# If user is allowed to set password, check the two instances to be sure
# there were no typos.  If they don't match, print error HTML page.

	if ($in{'auth_password1'} ne $in{'auth_password2'}) {
		&HTMLPrintRegisterNoPasswordMatch($main_script, $form_tags);
		exit;
	}

# If we don't want to allow duplicate user names, which is a very good idea,
# open up the user file, go through it line by line, and see if there are
# any matches for the username entered.  If there is, set a flag.  Then, look
# through the alternate users file if one is defined, looking for the same thing.
# If the flag got set at any point, print error HTML page.

	if ($auth_check_duplicates) {
		open (USERFILE, "$auth_user_file");
		$user_matched = 0;
		while (<USERFILE>) {
			chomp($_);
			@f = split(/\|/, $_);
			if ($f[1] eq $in{'auth_user_name'}) {
				$user_matched = 1;
				last;
			}
		}
		close (USERFILE);
		if ($auth_alt_user_file ne "") {
			open (USERFILE, "$auth_alt_user_file");
			while (<USERFILE>) {
				chomp($_);
				@f = split(/\|/, $_);
				if ($f[1] eq $in{'auth_user_name'}) {
					$user_matched = 1;
					last;
				}
			}
			close (USERFILE);
		}
		if ($user_matched == 1) {
			&HTMLPrintRegisterFoundDuplicate($main_script, $form_tags);
			exit;
		}
	}

# Seed the random number generator

	srand(time|$$);

# Generate the password if one is not
# entered.  Encrypt the password and make up
# the record that would be written to the user data
# file or sent in email to an administrator

	unless ($auth_generate_password) {
		$password = $in{"auth_password1"};
	} else {
		$random = "abcdefghijklmnopqrstuvwxyz1234567890";
		$password = "";
		for (1..6) {
			$password .= substr($random,int(rand(36)),1);
		}
	}
	$real_password = $password;
	$salt = "";
	$random = "abcdefghijklmnopqrstuvwxyz1234567890";
	for (1..2) {
		$salt .= substr($random,int(rand(36)),1);
	}
	$password = &AuthEncryptWrap ($password, $salt);
	@write_fields = ($password, $in{'auth_user_name'}, $group);
	foreach (@auth_extra_fields) {
		push(@write_fields, $in{"$_"});
	}

# If we have enabled allowing users to register themselves,
# let's go ahead and add them.  We first get the lock file for the
# user database.  If we have defined an alternate users file, we will
# add the entry to that instead of the standard user file.  Open the
# file, make the addition, close, and release the file lock.

	if ($auth_add_register) {
		&AuthGetFileLock ("$auth_user_file.lock");
		$user_file = $auth_user_file;
		if ($auth_alt_user_file ne "") {
			$user_file = $auth_alt_user_file;
		}
		open (USERFILE, ">>$user_file");
		print USERFILE join("\|", @write_fields) . "\n";
		close (USERFILE);
		&AuthReleaseFileLock ("$auth_user_file.lock");
	}

# If we have turned on email notifications for registration purposes,
# and have defined our email addresses, make an email notification to
# go to the administrator and send it out.

	if ($auth_email_register && ($auth_admin_from_address ne "" &&
		$auth_admin_email_address ne "")) {
		require "$auth_lib/mail-lib.pl";
		$subject = "Register User - $auth_reg_name";
		$message = "The following person has submitted registration for the ";
		$message .= "$auth_reg_name\n\n";
		$message .= "         Name:  $write_fields[3]\n";
		$message .= "    User Name:  $write_fields[1]\n";
		$message .= "Email Address:  $write_fields[4]\n";
		$message .= "Access  Level:  $write_fields[2]\n";
		&send_mail($auth_admin_from_address, $auth_admin_email_address,
				   $subject, $message);
	}

# If we are using cookies to save login info, and the user has selected to
# save theirs, scramble the password using ROT-13, set the cookie expiration
# date, and then set the cookie.

	if ($use_cookies && ($in{'save_info'} eq "on")) {
		require ("$auth_lib/cookie-lib.pl");
		$temp_pword = $real_password;
		$temp_pword =~ tr/a-zA-Z0-9/n-za-mN-ZA-M5-90-4/;
		&SetCookieExpDate("$cookie_end_date");
		&SetCompressedCookies("$auth_reg_name", 'username', "$in{'auth_user_name'}",
							  'password', "$temp_pword");
	}

# If we are generating passwords, we need to be able to notify the user of
# what their password is.  If we are allowing emails, we send them an email
# with this information.  Otherwise, we set a flag to print out a different
# form of the registration success page.

	if ($auth_generate_password) {
		$subject = "Registered User Password";
		$message = $auth_password_message;
		$message .= " $real_password.\n\n\n";
		if ($auth_email_register) {
			require "$auth_lib/mail-lib.pl";
			&send_mail($auth_admin_from_address, $user_email, $subject, $message);
		} else {
			$normal_print = 0;
		}
	}

# If we didn't turn off the flag due to password generation with no email
# enabled, print one HTML page.  Otherwise, print a different one.

	if ($normal_print) {
		&HTMLPrintRegisterSuccess ($main_script, $form_tags);
	} else {
		&HTMLPrintRegisterPassword ($main_script, $message, $form_tags);
	}
}

###############################################################################
# Subroutine:  PrintCurrentFormVars()
#
#	Parameters:
#		*form_vars = a reference to the form variables related
#					 to the main script that called the authentication
#					 routines in the first place.
#
#	Usage:
#		$form_tags = &PrintCurrentFormVars(*formvars);
#
#	Output:
#		Hidden field tags related to the form information we
#		want to preserve.
#
#  This routine takes the pre-existing form variables and 
#  makes them into hidden variables for inserting into the
#  form.  This is how the routine keeps old form variables
#  related to the program intact while all the CGI forms
#  relating to login get passed around.
#  All variables with AUTH in them are not duplicated since
#  they are related to this script.
###############################################################################

sub PrintCurrentFormVars {
	local(*form_vars) = @_;
	local($x,$y,$form_tags);
	$form_tags = "";

# Go through all of the form variables, and see if they do not contain
# "auth_".  If they do not, add a hidden input HTML tag for their values.

	foreach $x (keys %form_vars) {
		if (!($x =~ /auth_/i)) {
			$y = $form_vars{"$x"};
			$form_tags .= qq!<input type=hidden name=$x value="$y">\n!;
		}
	}
	return ($form_tags);
}

###############################################################################
# Subroutine:  AuthGetFileLock()
# 
#	Parameters:
#		$lock_file = filename to use as a temporary lock file
#
#	Usage:
#		&AuthGetFileLock("lockfilename");
# 
#   Output:
#      None.  It checks for the existance of a lock file
#      and if it finds it, it waits until the lock file
#      disappears.  After the lock file is gone, it opens
#      the lock file up itself.
#
#  This routine locks a file so that no one else
#  can get to it while it is being written to.
#
#  Note: we do not use FLOCK because FLOCK is not
#  implemented on some systems.  You may use it by
#  uncommenting the flock line if you so desire.
#
###############################################################################

sub AuthGetFileLock {
	local ($lock_file) = @_;
	local ($endtime);

# We set $endtime, the time to wait for the lock file to disapper, to
# 60 seconds.

	$endtime = time + 60;

# If the lock file exists, wait no more than 60 seconds.  At 60 seconds,
# go ahead and assume the previous process hung, and take over.

	while (-e $lock_file && time < $endtime) {}
	open(LOCK_FILE, ">$lock_file");
#	flock(LOCK_FILE, 2);
}

###############################################################################
# Subroutine:  AuthReleaseFileLock()
#
#	Parameters:
#		$lock_file = filename to use as a temporary lock file
#
#	Usage:
#		&AuthReleaseFileLock($lock_file);
#
#	Output:
#		None. Removes the lock file.
# 
#  This routine releases the lock file when we are
#  done with the original file.
#  Note: FLOCK is not used because it is not implemented on
#  Some systems.  You may use it by uncommenting the flock
#  line if you desire.
###############################################################################

sub AuthReleaseFileLock {
	local ($lock_file) = @_;

#	flock(LOCK_FILE, 8);
	close(LOCK_FILE);
	unlink($lock_file);
}

###############################################################################
# Subroutine:  AuthEncryptWrap()
#
#	Parameters:
#		$field = field to encrypt
#		 $salt = salt value to use for encryption
#
#	Usage:
#		$cryptedpassword = &AuthEncryptWrap($password, $salt);
#
#	Output:
#		Encrypted password
#
#  This routine wraps the crypt routine around 
#  a wrapper routine so that if a system does not
#  support the CRYPT routine, you may implement your own
#  in here.
###############################################################################

sub AuthEncryptWrap {
	local ($field, $salt) = @_;
	$field = crypt ($field, $salt);
	return ($field);
}
1;
