Merge branch 'develop' into VCL-1087_VCL_CAS_SSO
diff --git a/managementnode/bin/install_perl_libs.pl b/managementnode/bin/install_perl_libs.pl
index 812b957..a61042d 100755
--- a/managementnode/bin/install_perl_libs.pl
+++ b/managementnode/bin/install_perl_libs.pl
@@ -85,6 +85,7 @@
 	'LWP::Protocol::https',
 	'Mail::Mailer',
 	'Mo::builder',
+	'Net::Ping::External',
 	'Net::SSH::Expect',
 	'Object::InsideOut',
 	'RPC::XML',
diff --git a/managementnode/bin/monitor_vcld.pl b/managementnode/bin/monitor_vcld.pl
index fa0b796..503df93 100755
--- a/managementnode/bin/monitor_vcld.pl
+++ b/managementnode/bin/monitor_vcld.pl
@@ -170,27 +170,39 @@
 }
 
 my $current_epoch_seconds = convert_to_epoch_seconds();
-my $lastcheckin_epoch_seconds = convert_to_epoch_seconds($lastcheckin_timestamp);
+my $current_timestamp = makedatestring();
+my $lastcheckin_epoch_seconds = $management_node_info->{lastcheckin_epoch};
 my $lastcheckin_seconds_ago = ($current_epoch_seconds - $lastcheckin_epoch_seconds);
 
+# This message displays the timestamp information from the management node and the database
+my $detailed_ts_message = <<"END_MESSAGE";
+	Current Time = $current_timestamp
+	Current epoch = $current_epoch_seconds
+	Last Checkin Time = $lastcheckin_timestamp
+	Last Checkin epoch = $lastcheckin_epoch_seconds
+END_MESSAGE
+
 if ($lastcheckin_seconds_ago < 0) {
-	print_warning("$management_node_name last checkin time is in the future: $lastcheckin_timestamp, exiting");
+	print_warning("$management_node_name last checkin time is in the future: $lastcheckin_timestamp($lastcheckin_epoch_seconds), exiting");
 }
 elsif ($lastcheckin_seconds_ago < $lastcheckin_warning_seconds) {
-	print_message("$management_node_name last checked in $lastcheckin_seconds_ago seconds ago at $lastcheckin_timestamp");
+	print_message("$management_node_name last checked in $lastcheckin_seconds_ago seconds ago at $lastcheckin_timestamp($lastcheckin_epoch_seconds)");
 }
 elsif ($lastcheckin_seconds_ago >= $lastcheckin_critical_seconds) {
-	my $critical_message = "critical threshold exceeded, $management_node_name last checked in $lastcheckin_seconds_ago seconds ago at $lastcheckin_timestamp";
+	my $critical_message = "critical threshold exceeded, $management_node_name last checked in $lastcheckin_seconds_ago seconds ago at $lastcheckin_timestamp($lastcheckin_epoch_seconds)";
 	# Attempt to restart the vcld service
 	if ($mn_os->restart_service($vcld_service_name)) {
 		print_critical("$critical_message, $vcld_service_name service restarted");
+		print_critical($detailed_ts_message);
 	}
 	else {
 		print_critical("$critical_message, failed to restart $vcld_service_name service");
+		print_critical($detailed_ts_message);
 	}
 }
 else {
-	print_critical("last checkin warning threshold exceeded, $management_node_name last checked in $lastcheckin_seconds_ago seconds ago at $lastcheckin_timestamp");
+	print_critical("last checkin warning threshold exceeded, $management_node_name last checked in $lastcheckin_seconds_ago seconds ago at $lastcheckin_timestamp($lastcheckin_epoch_seconds)");
+	print_critical($detailed_ts_message);
 }
 
 print_message('done');
diff --git a/managementnode/bin/vclmessages.pl b/managementnode/bin/vclmessages.pl
new file mode 100755
index 0000000..20ae532
--- /dev/null
+++ b/managementnode/bin/vclmessages.pl
@@ -0,0 +1,202 @@
+#!/usr/bin/perl -w
+
+use Getopt::Long;
+use YAML;
+use DBI;
+use Data::Dumper;
+
+my $getnames = 0;
+my $dumpmessage = '';
+my $setmessage = '';
+my $resetmessage = '';
+my $htmlfile = '';
+my $subject = '';
+my $help = 0;
+
+GetOptions ('getmessagenames' => \$getnames,
+            'dumpmessage:s' => \$dumpmessage,
+            'resetmessage:s' => \$resetmessage,
+            'setmessage:s' => \$setmessage,
+            'htmlfile:s' => \$htmlfile,
+            'subject:s' => \$subject,
+            'help|?' => \$help);
+
+if ($help ||
+	($getnames == 1 && ($dumpmessage ne '' || $setmessage ne '' || $resetmessage ne '' || $htmlfile ne '' || $subject ne '')) ||
+	($getnames == 0 && $dumpmessage ne '' && ($setmessage ne '' || $resetmessage ne '' || $htmlfile ne '' || $subject ne '')) ||
+	($getnames == 0 && $resetmessage ne '' && ($setmessage ne '' || $dumpmessage ne '' || $htmlfile ne '' || $subject ne '')) ||
+	($getnames == 0 && $setmessage ne '' && ($dumpmessage ne '' || $resetmessage ne '' || $htmlfile eq '' || $subject eq '')) ||
+	($getnames == 0 && $setmessage eq '' && $dumpmessage eq '' && $resetmessage eq ''))
+{
+	print "Usage:\n\n";
+	print "vclmessages.pl --getmessagenames\n";
+	print "vclmessages.pl --dumpmessage '<name of message>'\n";
+	print "vclmessages.pl --setmessage '<name of message>' --htmlfile <filename> --subject <message subject>\n";
+	print "vclmessages.pl --resetmessage '<name of message>'\n\n";
+	print "vclmessages.pl --help|-?\n\n";
+	print "Where\n\n";
+	print "--getmessagenames displays a list of all available names that can be used\n";
+	print "--dumpmessage displays the current value of a message\n";
+	print "--setmessage sets the value of a message to the contents of the specified file\n";
+	print "--resetmessage sets the value of a message back to the original value as distributed with VCL\n\n";
+	print "<name of message> = the name of the message from the database (enclose in single quotes)\n";
+	print "\tuse --getmessagenames to get a list of message names\n\n";
+	print "<filename> = filename (including path) of file containing html contents for email message\n\n";
+	print "<message subject> = subject for email message (enclose in single quotes)\n\n";
+	exit 0;
+}
+
+my $mode = 'getnames';
+$mode = 'dumpmessage' if($dumpmessage ne '');
+$mode = 'setmessage' if($setmessage ne '');
+$mode = 'resetmessage' if($resetmessage ne '');
+
+my $messagename = $dumpmessage;
+$messagename = $setmessage if($mode eq 'setmessage');
+$messagename = $resetmessage if($mode eq 'resetmessage');
+
+my $database = `grep ^database /etc/vcl/vcld.conf | awk -F '=' '{print \$2}'`;
+my $hostname = `grep ^server /etc/vcl/vcld.conf | awk -F '=' '{print \$2}'`;
+my $user = `grep ^LockerWrtUser /etc/vcl/vcld.conf | awk -F '=' '{print \$2}'`;
+my $password = `grep ^wrtPass /etc/vcl/vcld.conf | awk -F '=' '{print \$2}'`;
+
+chomp $database;
+chomp $hostname;
+chomp $user;
+chomp $password;
+
+my $dsn = "DBI:mysql:database=$database;host=$hostname";
+my $dbh = DBI->connect($dsn, $user, $password);
+
+# ================= get names ================
+if($mode eq 'getnames')
+{
+	my $sth = $dbh->prepare(
+		"SELECT name FROM variable WHERE name LIKE 'usermessage%' OR name LIKE 'adminmessage%' ORDER BY name")
+		or die "Error: Failed to prepare database query: $dbh->errstr()";
+	$sth->execute();
+	while (my $ref = $sth->fetchrow_hashref()) {
+		print "$ref->{'name'}\n";
+	}
+	$sth->finish;
+	$sth->finish;
+	$dbh->disconnect;
+	exit 0;
+}
+# ================ dump message ===============
+elsif($mode eq 'dumpmessage')
+{
+	my $sth = $dbh->prepare(
+		"SELECT value FROM variable WHERE name = ?")
+		or die "Error: Failed to prepare database query: $dbh->errstr()";
+	$sth->execute($messagename);
+	if($sth->rows == 0)
+	{
+		print "Error: Failed to find message with name $messagename\n";
+		$sth->finish;
+		$dbh->disconnect;
+		exit 0;
+	}
+	if($sth->rows > 1)
+	{
+		print "Error: Found multiple messages with name $messagename\n";
+		$sth->finish;
+		$dbh->disconnect;
+		exit 0;
+	}
+	my $ref = $sth->fetchrow_hashref();
+	my $data = YAML::Load($ref->{'value'});
+	#print Dumper($data);
+	print "Subject: $data->{'subject'}\n";
+	print "Message:\n";
+	print "$data->{'message'}\n";
+
+	$sth->finish;
+	$dbh->disconnect;
+	exit 0;
+}
+# ================= reset message ===============
+elsif($mode eq 'resetmessage')
+{
+	my $sth = $dbh->prepare(
+		'SELECT value FROM messagereset WHERE name = ?')
+		or die "Error: Failed to prepare database query: $dbh->errstr()";
+	$sth->execute($messagename) or die "Error: failed to query database: $dbh->errstr()";
+	if($sth->rows == 0)
+	{
+		print "Error: Failed to find message with name $messagename\n";
+		$sth->finish;
+		$dbh->disconnect;
+		exit 0;
+	}
+	if($sth->rows > 1)
+	{
+		print "Error: Found multiple messages with name $messagename\n";
+		$sth->finish;
+		$dbh->disconnect;
+		exit 0;
+	}
+
+	my $ref = $sth->fetchrow_hashref();
+	my $message = $ref->{'value'};
+
+	$sth = $dbh->prepare(
+		"UPDATE variable SET value = ?, setby = 'setemail script', timestamp = NOW() WHERE name = ?")
+		or die "Error: Failed to prepare database query: $dbh->errstr()";
+
+	$sth->bind_param(1, $message);
+	$sth->bind_param(2, $messagename);
+	$sth->execute() or die "Error: Failed to update value for $messagename\n";
+
+	$sth->finish;
+	$dbh->disconnect;
+	print "Success: Value reset for $messagename\n";
+}
+# ================= set message ===============
+elsif($mode eq 'setmessage')
+{
+	my $htmlemail;
+	open(my $fh, '<', $htmlfile) or die "Error: failed to open $htmlfile for reading";
+	{
+		local $/;
+		$htmlemail = <$fh>;
+	}
+	close($fh);
+
+	my $sth = $dbh->prepare(
+		'SELECT value FROM variable WHERE name = ?')
+		or die "Error: Failed to prepare database query: $dbh->errstr()";
+	$sth->execute($messagename) or die "Error: failed to query database: $dbh->errstr()";
+	if($sth->rows == 0)
+	{
+		print "Error: Failed to find message with name $messagename\n";
+		$sth->finish;
+		$dbh->disconnect;
+		exit 0;
+	}
+	if($sth->rows > 1)
+	{
+		print "Error: Found multiple messages with name $messagename\n";
+		$sth->finish;
+		$dbh->disconnect;
+		exit 0;
+	}
+
+	my $ref = $sth->fetchrow_hashref();
+	my $data = YAML::Load($ref->{'value'});
+	$data->{'message'} = $htmlemail;
+	$data->{'subject'} = $subject;
+	my $yaml = YAML::Dump($data);
+
+	$sth = $dbh->prepare(
+		"UPDATE variable SET value = ?, setby = 'setemail script', timestamp = NOW() WHERE name = ?")
+		or die "Error: Failed to prepare database query: $dbh->errstr()";
+
+	$sth->bind_param(1, $yaml);
+	$sth->bind_param(2, $messagename);
+	$sth->execute() or die "Error: Failed to update value for $messagename\n";
+
+	$sth->finish;
+	$dbh->disconnect;
+	print "Success: Value for $messagename updated from contents of $htmlfile\n";
+}
diff --git a/managementnode/lib/VCL/DataStructure.pm b/managementnode/lib/VCL/DataStructure.pm
index dd693e3..1b0bf41 100644
--- a/managementnode/lib/VCL/DataStructure.pm
+++ b/managementnode/lib/VCL/DataStructure.pm
@@ -404,6 +404,7 @@
 #$SUBROUTINE_MAPPINGS{image_domain_password} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{password}'; # Explicit subroutine
 $SUBROUTINE_MAPPINGS{image_domain_secret_id} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{secretid}';
 $SUBROUTINE_MAPPINGS{image_domain_username} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{username}';
+$SUBROUTINE_MAPPINGS{image_domain_usedbhostnames} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{usedbhostnames}';
 $SUBROUTINE_MAPPINGS{image_domain_base_ou} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{imageaddomain}{baseOU}';
 $SUBROUTINE_MAPPINGS{image_domain_cryptsecret} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{cryptsecret}{cryptsecret}';
 
@@ -2641,6 +2642,8 @@
 			next;
 		}
 		#notify($ERRORS{'DEBUG'}, 0, "extracted subroutine mapping key from section of input string: '$input_substitute_section' --> '$subroutine_mapping_key'");
+		# skip keys derived from [if ...] and [endif] to prevent creation of mappings from HTML comment conditionals
+		next if ($subroutine_mapping_key =~ /^if / || $subroutine_mapping_key eq "endif");
 		
 		# Attempt to retrieve the substitution value from the DataStructure data
 		# Check if DataStructure.pm implements a matching 'get_' function
@@ -2804,7 +2807,7 @@
 
 =head2 get_domain_credentials
 
- Parameters  : $domain_identifier
+ Parameters  : $imagedomain_id (optional)
  Returns     : array ($username, $domain_password)
  Description : Attempts to determine and decrypt the username and password for
                the domain specified by the argument. 
@@ -2817,23 +2820,25 @@
 		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
 		return 0;
 	}
-	
-	my $domain_identifier = shift;
-	if (!defined($domain_identifier)) {
-		notify($ERRORS{'WARNING'}, 0, "domain identifier argument was not supplied");
-		return;
-	}
-	
+
+	my $reservation_id = $self->reservation_id();
 	my $management_node_id = $self->get_management_node_id();
-	
-	my ($username, $secret_id, $encrypted_password) = get_management_node_ad_domain_credentials($management_node_id, $domain_identifier);
-	return unless $username && $secret_id && $encrypted_password;
-	
+
+	my $imagedomain_id = shift || $self->request_data->{reservation}{$reservation_id}{computer}{currentimage}{imagedomain}{id};
+
+	my ($domain_dns_name, $username, $secret_id, $encrypted_password) = get_management_node_ad_domain_credentials($management_node_id, $imagedomain_id);
+	return unless $domain_dns_name && $username && $secret_id && $encrypted_password;
+
 	my $decrypted_password = $self->mn_os->decrypt_cryptsecret($secret_id, $encrypted_password) || return;
 	my $decrypted_password_length = length($decrypted_password);
 	my $decrypted_password_hidden = '*' x $decrypted_password_length;
-	notify($ERRORS{'DEBUG'}, 0, "retrieved credentials for Active Directory domain: '$decrypted_password_hidden' ($decrypted_password_length characters)");
-	return $decrypted_password;
+	notify($ERRORS{'DEBUG'}, 0, "retrieved credentials for Active Directory domain:\n" .
+               "domain ID: $imagedomain_id:\n" .
+               "domain DNS name: $domain_dns_name:\n" .
+               "domain username: $username:\n" .
+               "domain password: $decrypted_password_hidden ($decrypted_password_length characters)"
+        );
+	return ($domain_dns_name, $username, $decrypted_password);
 }
 
 #//////////////////////////////////////////////////////////////////////////////
diff --git a/managementnode/lib/VCL/Module/OS.pm b/managementnode/lib/VCL/Module/OS.pm
index 276a3b7..24bacca 100644
--- a/managementnode/lib/VCL/Module/OS.pm
+++ b/managementnode/lib/VCL/Module/OS.pm
@@ -4355,6 +4355,10 @@
 				notify($ERRORS{'DEBUG'}, 0, "ignoring Subversion file: $mn_file_path");
 				next MN_FILE;
 			}
+			elsif ($mn_file_path =~ /\.gitignore/i) {
+				notify($ERRORS{'DEBUG'}, 0, "ignoring .gitignore file: $mn_file_path");
+				next MN_FILE;
+			}
 			elsif ($mn_file_path =~ /\/$other_architecture\//) {
 				notify($ERRORS{'DEBUG'}, 0, "ignoring file intended for different computer architecture: $mn_file_path");
 				next MN_FILE;
@@ -4440,12 +4444,14 @@
 		my $router = $server_variable_data->{router};
 		my $netmask = $server_variable_data->{netmask};
 		my @dns = @{$server_variable_data->{dns}};
+
+		my $return = 1;
 		
-		notify($ERRORS{'OK'}, 0, "updated data server request router info") if ($self->data->set_server_request_router($server_variable_data->{router}));
-		notify($ERRORS{'OK'}, 0, "updated data server request netmask info") if ($self->data->set_server_request_netmask($server_variable_data->{netmask}));
-		notify($ERRORS{'OK'}, 0, "updated data server request dns info") if ($self->data->set_server_request_dns_servers(@{$server_variable_data->{dns}}));
+		notify($ERRORS{'OK'}, 0, "updated data server request router info") or $return = 0 if ($self->data->set_server_request_router($server_variable_data->{router}));
+		notify($ERRORS{'OK'}, 0, "updated data server request netmask info") or $return = 0 if ($self->data->set_server_request_netmask($server_variable_data->{netmask}));
+		notify($ERRORS{'OK'}, 0, "updated data server request dns info") or $return = 0 if ($self->data->set_server_request_dns_servers(@{$server_variable_data->{dns}}));
 		notify($ERRORS{'DEBUG'}, 0, "router= $router, netmask= $netmask, dns= @dns");
-		
+		return $return;
 	}
 	else {
 		notify($ERRORS{'DEBUG'}, 0, "data is not set for $variable_name");
diff --git a/managementnode/lib/VCL/Module/OS/Linux.pm b/managementnode/lib/VCL/Module/OS/Linux.pm
index 4fd61b1..4620b6a 100644
--- a/managementnode/lib/VCL/Module/OS/Linux.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux.pm
@@ -6699,20 +6699,30 @@
 		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
 		return;
 	}
-	
+
 	my $computer_name = $self->data->get_computer_short_name();
 	my $public_ip_configuration = $self->data->get_management_node_public_ip_configuration();
-	my @public_dns_servers = shift || $self->data->get_management_node_public_dns_servers();
-	
-	if ($public_ip_configuration !~ /static/i) {	
-		notify($ERRORS{'WARNING'}, 0, "unable to update resolv.conf on $computer_name, management node's IP configuration is set to $public_ip_configuration");
+	my @mn_dns_servers = shift || $self->data->get_management_node_public_dns_servers();
+
+	my @server_request_dns_servers = $self->data->get_server_request_dns_servers();
+
+	my @dns_servers;
+	if (@server_request_dns_servers) {
+		@dns_servers = @server_request_dns_servers;
+		notify($ERRORS{'DEBUG'}, 0, "server request specific DNS servers will be statically set on $computer_name: " . join(", ", @dns_servers));
+	}
+	elsif ($public_ip_configuration =~ /static/i && @mn_dns_servers) {
+		@dns_servers = @mn_dns_servers;
+		notify($ERRORS{'DEBUG'}, 0, "management node IP configuration set to $public_ip_configuration, management node DNS servers will be statically set on $computer_name: " . join(", ", @dns_servers));
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "$computer_name not configured to use static DNS servers:\n" .
+			"management node IP configuration               : $public_ip_configuration\n" .
+			"management node DNS servers configured         : " . (@mn_dns_servers ? 'yes' : 'no')
+		);
 		return;
 	}
-	elsif (!@public_dns_servers) {
-		notify($ERRORS{'WARNING'}, 0, "unable to update resolv.conf on $computer_name, DNS server argument was not provided and management node's public DNS server is not configured");
-		return;
-	}
-	
+
 	my $resolv_conf_path = "/etc/resolv.conf";
 	
 	my @resolv_conf_lines_existing = $self->get_file_contents($resolv_conf_path);
@@ -6725,16 +6735,16 @@
 			push @resolv_conf_lines_new, $line;
 		}
 	}
-	
+
 	# Add a comment marking what was added by VCL
 	my $timestamp = POSIX::strftime("%m-%d-%Y %H:%M:%S", localtime);
 	push @resolv_conf_lines_new, "# $timestamp: The following was added by VCL";
 	
 	# Add a nameserver line for each configured DNS server
-	for my $public_dns_server (@public_dns_servers) {
+	for my $public_dns_server (@dns_servers) {
 		push @resolv_conf_lines_new, "nameserver $public_dns_server";
 	}
-	
+
 	my $resolv_conf_contents_new = join("\n", @resolv_conf_lines_new);
 	if ($self->create_text_file($resolv_conf_path, $resolv_conf_contents_new)) {
 		notify($ERRORS{'DEBUG'}, 0, "updated $resolv_conf_path on $computer_name:\n$resolv_conf_contents_new");
diff --git a/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm b/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm
index 84d3dd0..c3d0b6b 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm
@@ -509,6 +509,13 @@
 			next;
 		}
 		
+		# Ignore the .gitignore files
+		if ($script_file_path =~ /\.gitignore/i) {
+			my $matching_section = $1;
+			notify($ERRORS{'DEBUG'}, 0, "ignoring gitignore file on management node from script directory '$matching_section': $script_file_path");
+			next;
+		}
+		
 		my $command = "chmod +x $script_file_path && $script_file_path $mn_json_file_path";
 		my ($exit_status, $output) = $self->execute($command);
 		if (!defined($output)) {
diff --git a/managementnode/lib/VCL/Module/OS/Windows.pm b/managementnode/lib/VCL/Module/OS/Windows.pm
index 3de1ad3..91eb707 100644
--- a/managementnode/lib/VCL/Module/OS/Windows.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows.pm
@@ -385,6 +385,25 @@
 
 =item *
 
+ If computer is part of Active Directory Domain, unjoin it
+
+=cut
+
+	if ($self->ad_get_current_domain()) {
+		if (!$self->ad_unjoin()) {
+			notify($ERRORS{'WARNING'}, 0, "failed to remove computer from Active Directory domain");
+			return 0;
+		}
+		notify($ERRORS{'DEBUG'}, 0, "computer successfully unjoined from domain, rebooting for change to take effect");
+		# reboot if unjoin successful
+		if (!$self->reboot()) {
+			notify($ERRORS{'WARNING'}, 0, "failed to reboot after unjoining from domain");
+		}
+	}
+
+
+=item *
+
  Set Administrator account password to known value
 
 =cut
@@ -415,20 +434,6 @@
 	if (!$deleted_user_accounts) {
 		notify($ERRORS{'DEBUG'}, 0, "unable to delete user accounts, will try again after reboot");
 	}
-
-=item *
-
- If computer is part of Active Directory Domain, unjoin it
-
-=cut
-
-	if ($self->ad_get_current_domain()) {
-		if (!$self->ad_unjoin()) {
-			notify($ERRORS{'WARNING'}, 0, "failed to remove computer from Active Directory domain");
-			return 0;
-		}
-	}
-
 =item *
 
  Set root as the owner of /home/root
@@ -672,14 +677,27 @@
 		notify($ERRORS{'WARNING'}, 0, "unable to set sshd service startup mode to manual");
 		return 0;
 	}
-	
+
+=item *
+
+ Unmount any NFS shares
+
+=cut
+
+	if (!$self->unmount_nfs_shares()) {
+		notify($ERRORS{'WARNING'}, 0, "unable to unmount NFS shares");
+		return;
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "Call to unmount_nfs_shares returned successfully");
+	}
+
 =back
 
 =cut
 
 	notify($ERRORS{'OK'}, 0, "returning 1");
 	return 1;
-
 } ## end sub pre_capture
 
 #//////////////////////////////////////////////////////////////////////////////
@@ -1087,6 +1105,8 @@
 		return 0;
 	}
 	
+	my $computer_name = $self->data->get_computer_short_name();
+	
 	# Check if custom post_reservation script exists in image
 	my $script_path = '$SYSTEMROOT/vcl_post_reservation.cmd';
 	if ($self->file_exists($script_path)) {
@@ -1097,7 +1117,15 @@
 		notify($ERRORS{'DEBUG'}, 0, "custom post_reservation script does NOT exist in image: $script_path");
 	}
 	
-	return $self->SUPER::post_reservation();
+	$self->SUPER::post_reservation();
+	
+	# Check if the computer is joined to any AD domain
+	my $computer_current_domain_name = $self->ad_get_current_domain();
+	if ($computer_current_domain_name) {
+		$self->ad_delete_computer();
+	}
+	
+	return 1;
 }
 
 #//////////////////////////////////////////////////////////////////////////////
@@ -1117,15 +1145,25 @@
 		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
 		return 0;
 	}
-	
+
 	my $computer_name = $self->data->get_computer_short_name();
-	
+
 	# Check if the computer is joined to any AD domain
 	my $computer_current_domain_name = $self->ad_get_current_domain();
 	if ($computer_current_domain_name) {
-		$self->ad_delete_computer($computer_name, $computer_current_domain_name);
+		# check that node is not a domain controller
+		my $check_dc = $self->ad_check_domain_controller();
+		if (!defined($check_dc) || $check_dc == 0) {
+			# if call to ad_check_domain_controller fails, still attempt to
+			# delete from domain; unusual for node to be a domain controller
+			notify($ERRORS{'DEBUG'}, 0, "attempting to delete computer from domain");
+			$self->ad_delete_computer();
+		}
+		elsif ($check_dc == 1) {
+			notify($ERRORS{'DEBUG'}, 0, "computer is a domain controller, not attempting to delete computer from its own domain");
+		}
 	}
-	
+
 	return $self->SUPER::pre_reload();
 }
 
@@ -1163,6 +1201,14 @@
 		return 0;
 	}
 	
+	if (!$self->unmount_nfs_shares()) {
+		notify($ERRORS{'WARNING'}, 0, "failed to unmount nfs shares");
+		return 0;
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "successfully unmounted any NFS shares");
+	}
+
 	notify($ERRORS{'OK'}, 0, "$computer_node_name has been sanitized");
 	return 1;
 } ## end sub sanitize
@@ -3892,11 +3938,14 @@
 				return 0;
 			}
 			
-			# Set sshd service startup mode to auto
-			if (!$self->set_service_startup_mode('sshd', 'auto')) {
-				notify($ERRORS{'WARNING'}, 0, "reboot not attempted, unable to set sshd service startup mode to auto");
+			# Set sshd service startup mode to manual
+			if (!$self->set_service_startup_mode('sshd', 'manual')) {
+				notify($ERRORS{'WARNING'}, 0, "reboot not attempted, unable to set sshd service startup mode to manual");
 				return 0;
 			}
+			else {
+				notify($ERRORS{'DEBUG'}, 0, "sshd service set to manual start");
+			}
 			
 			# Make sure ping access is enabled from private IP addresses
 			if (!$self->firewall_enable_ping_private()) {
@@ -7027,7 +7076,12 @@
 	if (!$self->delete_files_by_pattern($NODE_CONFIGURATION_DIRECTORY, '.*\.svn.*')) {
 		notify($ERRORS{'WARNING'}, 0, "unable to delete Subversion files under: $NODE_CONFIGURATION_DIRECTORY");
 	}
-	
+
+	# Delete any GitIgnore files which may have been copied
+	if (!$self->delete_files_by_pattern($NODE_CONFIGURATION_DIRECTORY, '.*\.gitignore.*')) {
+		notify($ERRORS{'WARNING'}, 0, "unable to delete GitIgnore files under: $NODE_CONFIGURATION_DIRECTORY");
+	}
+
 	$self->set_file_owner($NODE_CONFIGURATION_DIRECTORY, 'root');
 	
 	# Find any files containing a 'WINDOWS_ROOT_PASSWORD' string and replace it with the root password
@@ -12690,6 +12744,7 @@
 		return;
 	}
 	
+	my $use_database_hostnames = $self->data->get_image_domain_usedbhostnames();
 	my $database_computer_hostname = $self->data->get_computer_hostname();
 	my $system32_path = $self->get_system32_path() || return;
 	
@@ -12726,8 +12781,20 @@
 		$dns_suffix = $2;
 	}
 	
-	# Disable 'Change primary DNS suffix when domain membership changes'
-	$self->reg_add('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters', 'SyncDomainWithMembership', 'REG_DWORD', 0);
+	if ($use_database_hostnames == 1) {
+		$new_computer_name = $database_computer_hostname;
+		notify($ERRORS{'DEBUG'}, 0, "active directory forces using database configured hostname: $new_computer_name");
+		# Enable 'Change primary DNS suffix when domain membership changes'
+		$self->reg_add('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters', 'SyncDomainWithMembership', 'REG_DWORD', 1);
+	}
+	else {
+		# Disable 'Change primary DNS suffix when domain membership changes'
+		$self->reg_add('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters', 'SyncDomainWithMembership', 'REG_DWORD', 0);
+		# Set the DNS suffix registry key
+		if ($dns_suffix) {
+			$self->reg_add('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters', 'NV Domain', 'REG_SZ', $dns_suffix);
+		}
+	}
 	
 	# Assemble the command
 	my $command = "echo | cmd.exe /c \"$system32_path/Wbem/wmic.exe COMPUTERSYSTEM WHERE Name=\\\"%COMPUTERNAME%\\\" Rename \\\"$new_computer_name\\\"\"";
@@ -12745,11 +12812,6 @@
 		return 0;
 	}
 	
-	# Set the DNS suffix registry key
-	if ($dns_suffix) {
-		$self->reg_add('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters', 'NV Domain', 'REG_SZ', $dns_suffix);
-	}
-	
 	return 1;
 }
 
@@ -13780,6 +13842,7 @@
 	my $computer_name	= $self->data->get_computer_short_name();
 	my $image_name	= $self->data->get_image_name();
 	
+	my $image_domain_id = $self->data->get_image_domain_id();
 	my $domain_dns_name = $self->data->get_image_domain_dns_name();
 	my $domain_username = $self->data->get_image_domain_username();
 	my $domain_password = $self->data->get_image_domain_password();
@@ -13812,7 +13875,7 @@
 	notify($ERRORS{'DEBUG'}, 0, "attempting to join $computer_name to AD\n" .
 		"domain DNS name    : $domain_dns_name\n" .
 		"domain user string : $domain_user_string\n" .
-		"domain password    : $domain_password (escaped: $domain_password_escaped)\n" .
+		#"domain password    : $domain_password (escaped: $domain_password_escaped)\n" .
 		"domain computer OU : " . ($computer_ou_dn ? $computer_ou_dn : '<not configured>')
 	);
 	
@@ -13863,12 +13926,17 @@
 \$username = '$domain_user_string'
 \$password = '$domain_password_escaped'
 Write-Host "username (between >*<): `n>\$username<`n"
-Write-Host "password (between >*<): `n>\$password<`n"
 \$ps_credential = New-Object System.Management.Automation.PsCredential(\$username, (ConvertTo-SecureString \$password -AsPlainText -Force))
 Add-Computer -DomainName '$domain_dns_name' -Credential \$ps_credential $domain_computer_command_section -Verbose -ErrorAction Stop
 EOF
+
+# move and uncomment below line to above EOF to include decrypted password in output for debugging
+#Write-Host "password (between >*<): `n>\$password<`n"
+
+	(my $sanitized_password = $domain_password_escaped) =~ s/./*/g;
+	(my $sanitized_script = $ad_powershell_script) =~ s/password = '.*'\n/password = '$sanitized_password'\n/;
 	
-	notify($ERRORS{'DEBUG'}, 0, "attempting to join $computer_name to $domain_dns_name domain using PowerShell script:\n$ad_powershell_script");
+	notify($ERRORS{'DEBUG'}, 0, "attempting to join $computer_name to $domain_dns_name domain using PowerShell script:\n$sanitized_script");
 	my ($exit_status, $output) = $self->run_powershell_as_script($ad_powershell_script, 0, 0); # (path, show output, retain file)
 	if (!defined($output)) {
 		notify($ERRORS{'WARNING'}, 0, "failed to execute PowerShell script to join $computer_name to Active Directory domain");
@@ -13944,6 +14012,8 @@
 		return;
 	}
 	else {
+		$self->set_current_image_tag('addomain_id', $image_domain_id);
+		
 		notify($ERRORS{'DEBUG'}, 0, "successfully joined $computer_name to Active Directory domain: $domain_dns_name, time statistics:\n" .
 			"computer rename reboot : $rename_computer_reboot_duration seconds\n" .
 			"AD join reboot         : $ad_join_reboot_duration seconds\n" .
@@ -14160,7 +14230,19 @@
 		notify($ERRORS{'DEBUG'}, 0, "$computer_name does not need to be removed from AD because it is not currently joined to a domain");
 		return 1;
 	}
-	
+
+	# check that node is not a domain controller
+	my $check_dc = $self->ad_check_domain_controller();
+	if (!defined($check_dc) || $check_dc == 0) {
+		# if call to ad_check_domain_controller fails, still attempt to
+		# delete from domain; unusual for node to be a domain controller
+		notify($ERRORS{'DEBUG'}, 0, "attempting to delete computer from domain");
+	}
+	elsif ($check_dc == 1) {
+		notify($ERRORS{'DEBUG'}, 0, "computer is a domain controller, not attempting to delete computer from its own domain");
+		return 1;
+	}
+
 	# Expected output:
 	# Executing (\\<COMPUTERNAME>\ROOT\CIMV2:Win32_ComputerSystem.Name="<COMPUTERNAME>")->UnJoinDomainOrWorkgroup()
 	# Method execution successful.s
@@ -14270,7 +14352,7 @@
 	#	
 	#	notify($ERRORS{'OK'}, 0, "removed $computer_name from Active Directory domain, output:\n" . join("\n", @$output));
 	
-	$self->ad_delete_computer($computer_name, $computer_current_domain);
+	$self->ad_delete_computer();
 	return 1;
 }
 
@@ -14388,11 +14470,13 @@
 	my $domain_username;
 	my $domain_password;
 	my $image_domain_dns_name = $self->data->get_image_domain_dns_name(0) || '';
-	if (defined($arguments->{domain_dns_name}) && $arguments->{domain_dns_name} ne $image_domain_dns_name) {
+	if (defined($arguments->{domain_dns_name})) {
 		$domain_dns_name = $arguments->{domain_dns_name};
-		($domain_username, $domain_password) = $self->data->get_domain_credentials($domain_dns_name);
+		$domain_username = $arguments->{domain_username};
+		$domain_password = $arguments->{domain_password};
+		
 		if (!defined($domain_username) || !defined($domain_password)) {
-			notify($ERRORS{'WARNING'}, 0, "unable to search domain: $domain_dns_name, domain DNS name argument was specified but credentials could not be determined from existing 'addomain' table entries");
+			notify($ERRORS{'WARNING'}, 0, "unable to search domain: $domain_dns_name, domain DNS name argument was specified but credentials could not be determined");
 			return;
 		}
 	}
@@ -14458,10 +14542,12 @@
 
 Write-Host "domain: $domain_dns_name"
 Write-Host "domain username (between >*<): >\$domain_username<"
-Write-Host "domain password (between >*<): >\$domain_password<"
-
 EOF
 
+# move and uncomment below line to above EOF to include decrypted password in output for debugging
+#Write-Host "domain password (between >*<): >\$domain_password<"
+
+
 	$powershell_script_contents .= <<'EOF';
 $type = [System.DirectoryServices.ActiveDirectory.DirectoryContextType]"Domain"
 $directory_context = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext($type, $domain_dns_name, $domain_username, $domain_password)
@@ -14475,7 +14561,7 @@
    else {
       $exception_message = $_.Exception.Message
    }
-   Write-Host "ERROR: failed to connect to $domain_dns_name domain, username: $domain_username, password: $domain_password, error: $exception_message"
+   Write-Host "ERROR: failed to connect to $domain_dns_name domain, username: $domain_username, error: $exception_message"
    exit
 }
 
@@ -14577,16 +14663,11 @@
 
 =head2 ad_delete_computer
 
- Parameters  : $computer_samaccountname (optional), $domain_dns_name (optional)
+ Parameters  : none
  Returns     : boolean
  Description : Deletes a computer object from the active directory domain with a
-               sAMAccountName attribute matching the argument. If no argument is
-               provided, the short name of the reservation computer is used.
-               
-               The sAMAccountName attribute for computers in Active Directory
-               always end with a dollar sign. The trailing dollar sign does not
-               need to be included in the argumenat. One will be added to the
-               LDAP filter used to search for the object to delete.
+					sAMAccountName attribute matching the short name of the
+					reservation computer that is used.
 
 =cut
 
@@ -14596,28 +14677,64 @@
 		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
 		return;
 	}
+
+	# static variable to track if function being call recursively
+	CORE::state $recursion = 0;
+
+	my $computer_samaccountname = $self->data->get_computer_short_name();
+
+	my ($domain_dns_name, $username, $decrypted_password);
+	my $return;
+
+	if($recursion == 0) {
+		($domain_dns_name, $username, $decrypted_password) = $self->data->get_domain_credentials();
+	}
+	else {
+		my $addomain_id = $self->get_current_image_tag('addomain_id');
+		$addomain_id =~ s/ \(.*$//;
+		if (!defined($addomain_id)) {
+			return 0;
+		}
+		($domain_dns_name, $username, $decrypted_password) = $self->data->get_domain_credentials($addomain_id);
+	}
+	if (!defined($domain_dns_name) || !defined($username) || !defined($decrypted_password)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to get domain credentials for $computer_samaccountname");
+		if ($recursion == 0) {
+			$recursion = 1;
+			$return = $self->ad_delete_computer();
+			$recursion = 0;
+			return $return;
+		}
+		return;
+	}
 	
-	my ($computer_samaccountname, $domain_dns_name) = @_;
-	
-	$computer_samaccountname = $self->data->get_computer_short_name() unless $computer_samaccountname;
-	
-	# Make sure computer samAccountName does not contain a trailing dollar sign
-	# A dollar sign will be present if retrieved directly from AD
 	$computer_samaccountname =~ s/\$*$/\$/g;
-	
 	my $ad_search_arguments = {
 		'ldap_filter' => {
 			'objectClass' => 'computer',
 			'sAMAccountName' => $computer_samaccountname,
-		}
+		},
+		'domain_dns_name' => $domain_dns_name,
+		'domain_username' => $username,
+		'domain_password' => $decrypted_password,
 	};
 	
-	# If a specific domain was specified, retrieve the username and password for that domain
-	if ($domain_dns_name) {
-		$ad_search_arguments->{domain_dns_name} = $domain_dns_name;
-	}
+	#notify($ERRORS{'DEBUG'}, 0, "attempting to delete Active Directory computer object, arguments:\n" . format_data($ad_search_arguments));
 	
-	return $self->ad_search($ad_search_arguments);
+	$return = $self->ad_search($ad_search_arguments);
+	if ($return == 1) {
+		return 1;
+	}
+	elsif ($recursion == 1) {
+		return 0;
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "Failed to delete computer from AD using AD domain info from image; trying again with info from currentimage.txt");
+		$recursion = 1;
+		$return = $self->ad_delete_computer();
+		$recursion = 0;
+		return $return;
+	}
 }
 
 #//////////////////////////////////////////////////////////////////////////////
@@ -14770,6 +14887,50 @@
 
 #//////////////////////////////////////////////////////////////////////////////
 
+=head2 ad_check_domain_controller
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Checks if computer is configured as a domain controller; returns
+               0 if not a domain controller, 1 if a domain controller, and
+               no value on error
+
+=cut
+
+sub ad_check_domain_controller {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+
+	my $system32_path = $self->get_system32_path() || return;
+	my $check_dc_command = "echo | cmd.exe /c \"$system32_path/Wbem/wmic.exe /INTERACTIVE:OFF COMPUTERSYSTEM GET DomainRole\"";
+	my ($check_dc_exit_status, $check_dc_output) = $self->execute($check_dc_command);
+	if (!defined($check_dc_output)) {
+		notify($ERRORS{'DEBUG'}, 0, "failed to check for node being a domain controller");
+		return;
+	}
+	elsif (grep(/ERROR/i, @$check_dc_output)) {
+		notify($ERRORS{'DEBUG'}, 0, "failed to check for node being a domain controller, output:\n" . join("\n", @$check_dc_output));
+		return;
+	}
+	elsif (@{$check_dc_output}[1] =~ /^[0-3]$/) {
+		notify($ERRORS{'OK'}, 0, "node is a not a domain controller");
+		return 0;
+	}
+	elsif (@{$check_dc_output}[1] =~ /^[4-5]$/) {
+		notify($ERRORS{'OK'}, 0, "node is a domain controller");
+		return 1;
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "unexpected output checking for node being a domain controller, output:\n" . join("\n", @$check_dc_output));
+		return;
+	}
+}
+
+#//////////////////////////////////////////////////////////////////////////////
+
 =head2 grant_administrative_access
 
  Parameters  : $username
@@ -14849,6 +15010,277 @@
 
 #//////////////////////////////////////////////////////////////////////////////
 
+=head2 reserve
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Calls parent OS.pm::reserve then mounts NFS shares.
+
+=cut
+
+sub reserve {
+	my $self = shift;
+	if (ref($self) !~ /Windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return 0;
+	}
+	
+	# Call OS.pm's reserve subroutine
+	$self->SUPER::reserve() || return;
+	
+	notify($ERRORS{'OK'}, 0, "beginning Windows reserve tasks");
+	
+	# Attempt to mount NFS shares configured for the management node (Site Configuration > NFS Mounts)
+	$self->mount_nfs_shares();
+	
+	notify($ERRORS{'OK'}, 0, "Windows reserve tasks complete");
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 nfs_mount_share
+
+ Parameters  : $remote_target
+ Returns     : boolean
+ Description : Prepares a Windows image to automatically mount a user's NFS
+               shares when the user logs in.
+               
+               The Windows image is checked to determine if the required Windows
+               features are installed in the image. If not installed, an attempt
+               is made to install them. If any features are installed, a reboot
+               is performed.
+
+=cut
+
+sub nfs_mount_share {
+	my $self = shift;
+	if (ref($self) !~ /Windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
+	my ($remote_target) = @_;
+	if (!$remote_target) {
+		notify($ERRORS{'WARNING'}, 0, "remote NFS target argument was not supplied");
+		return;
+	}
+	
+	# This subroutine may be called multiple times to allow multiple shares to be mounted
+	# If this is not the first call, append to the batch file instead of recreating it
+	my $previously_called = $self->{nfs_mount_share_called};
+	if ($previously_called && !$self->{nfs_mount_share_preparation_complete}) {
+		notify($ERRORS{'DEBUG'}, 0, "skipping subsequent NFS mount attempt, this subroutine was previously called but the preparation tasks failed to complete");
+		return;
+	}
+	
+	$self->{nfs_mount_share_called} = 1;
+	
+	my $username = $self->data->get_user_login_id();
+	my $uid = $self->data->get_user_uid();
+	my $reservation_id = $self->data->get_reservation_id();
+	my $computer_name = $self->data->get_computer_node_name();
+	my $management_node_id = $self->data->get_management_node_id;
+	
+	my $nfs_mount_batch_file_path = 'C:/mount_nfs.cmd';
+	
+	# Only perform the prep tasks the first time this subroutine is called
+	if ($previously_called) {
+		notify($ERRORS{'DEBUG'}, 0, "Windows NFS preparation tasks not necessary, this subroutine was previously executed");
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "beginning Windows NFS preparation tasks");
+		
+		$self->delete_file($nfs_mount_batch_file_path);
+		
+		my $windows_product_name = $self->get_product_name();
+		if ($windows_product_name =~ /(Windows.*Professional)/) {
+			notify($ERRORS{'WARNING'}, 0, "Windows NFS share not mounted, Client for NFS is not available on this edition: $windows_product_name");
+			return 0;
+		}
+		
+		# Check if required Windows features are installed in the image
+		# Attempt to install them if missing
+		# A reboot is required if any features are installed
+		my @required_windows_feature_names = (
+			'ServicesForNFS-ClientOnly',
+			'ClientForNFS-Infrastructure',
+		);
+		
+		my $installed_feature_count = 0;
+		for my $required_windows_feature_name (@required_windows_feature_names) {
+			#notify($ERRORS{'DEBUG'}, 0, "sleeping 10 seconds before installing next Windows feature");
+			#sleep_uninterrupted(10) if $installed_feature_count > 0;
+			
+			if (!$self->is_windows_feature_enabled($required_windows_feature_name)) {
+				if ($self->enable_windows_feature($required_windows_feature_name)) {
+					$self->{windows_nfs_reboot_required} = 1;
+				}
+				else {
+					notify($ERRORS{'WARNING'}, 0, "failed to prepare Windows NFS, '$required_windows_feature_name' Windows feature could not be enabled");
+					return;
+				}
+			}
+			$installed_feature_count++;
+		}
+		
+		# Stop and disable the "TCP/IP NetBIOS Helper" service - it causes delays using NFS shares
+		$self->stop_service('lmhosts');
+		$self->set_service_startup_mode('lmhosts', 'disabled');
+		
+		# Set the anonymous UID
+		$self->set_windows_nfs_client_uid($uid) || return;
+		
+		#if ($self->{windows_nfs_reboot_required}) {
+		#	notify($ERRORS{'DEBUG'}, 0, "attempting to reboot $computer_name to complete the configuration of the NFS Client");
+		#	if (!$self->reboot()) {
+		#		notify($ERRORS{'WARNING'}, 0, "failed to prepare Windows NFS, failed to reboot $computer_name after configuring NFS client");
+		#		return;
+		#	}
+		#}
+		
+		# Attempt to start the NFS client or make sure it's already started
+		$self->start_service('NfsClnt') || return;
+		
+		#if (!$self->start_service('NfsClnt')) {
+		#	if ($self->{windows_nfs_reboot_required}) {
+		#		notify($ERRORS{'WARNING'}, 0, "failed to prepare Windows NFS, failed to start the NFS client, $computer_name was already rebooted");
+		#		return;
+		#	}
+		#	else {
+		#		if (!$self->reboot()) {
+		#			notify($ERRORS{'WARNING'}, 0, "failed to prepare Windows NFS, failed to reboot $computer_name after attempting to start the NFS client");
+		#			return;
+		#		}
+		#		
+		#		if (!$self->start_service('NfsClnt')) {
+		#			notify($ERRORS{'WARNING'}, 0, "failed to prepare Windows NFS, failed to start the NFS client on $computer_name after it was rebooted");
+		#			return;
+		#		}
+		#	}
+		#}
+		#notify($ERRORS{'DEBUG'}, 0, "Windows NFS preparation tasks complete");
+		
+		$self->{nfs_mount_share_preparation_complete} = 1;
+	}
+	
+	my $mount_script_contents;
+	if (!$previously_called) {
+		$mount_script_contents = "nfsadmin.exe client start\r\n";
+	}
+	$mount_script_contents .= "C:\\Windows\\system32\\mount.exe -o mtype=hard $remote_target *";
+	
+	if ($previously_called) {
+		notify($ERRORS{'DEBUG'}, 0, "appending line to $nfs_mount_batch_file_path: $mount_script_contents");
+		if (!$self->append_text_file($nfs_mount_batch_file_path, $mount_script_contents)) {
+			notify($ERRORS{'WARNING'}, 0, "failed to append batch file to mount NFS shares: $nfs_mount_batch_file_path");
+			return;
+		}
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "creating Windows NFS mount batch file: $nfs_mount_batch_file_path, contents:\n$mount_script_contents");
+		if (!$self->create_text_file($nfs_mount_batch_file_path, $mount_script_contents)) {
+			notify($ERRORS{'WARNING'}, 0, "failed to create Windows NFS mount batch file: $nfs_mount_batch_file_path");
+			return;
+		}
+		$self->add_hklm_run_registry_key('VCL Mount NFS', $nfs_mount_batch_file_path) || return;
+		$self->execute("chmod 777 $nfs_mount_batch_file_path");
+	}
+	
+	notify($ERRORS{'DEBUG'}, 0, "finished Windows NFS mount tasks");
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 nfs_unmount_share
+
+ Parameters  : none
+ Returns     : boolean
+ Description : This doesn't actually unmount any shares but deletes the registry
+               key and batch file created to mount NFS shares when a user logs
+               in.
+
+=cut
+
+sub nfs_unmount_share {
+	my $self = shift;
+	if (ref($self) !~ /Windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
+	$self->delete_file('C:/mount_nfs.cmd');
+	$self->delete_hklm_run_registry_key('VCL Mount NFS');
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 set_windows_nfs_client_uid
+
+ Parameters  : $uid_number
+ Returns     : boolean
+ Description : Sets registry values used by the Windows NFS Client to determine
+               which user UID number to use when accessing NFS shares.
+
+=cut
+
+sub set_windows_nfs_client_uid {
+	my $self = shift;
+	if (ref($self) !~ /Windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
+	my $uid = shift || $self->data->get_user_uid();
+	my $computer_name = $self->data->get_computer_node_name();
+	
+	notify($ERRORS{'DEBUG'}, 0, "attempting to configure the Windows NFS Client to use anonymous UID $uid");
+	
+	my $nfs_client_service_name = 'NfsClnt';
+	my $base_key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ClientForNFS\CurrentVersion\Default';
+	my $uid_key = 'AnonymousUid';
+	
+	# Check if UID already set correctly
+	my $existing_uid = $self->reg_query($base_key, $uid_key, 1) || '';
+	if ($existing_uid eq $uid) {
+		notify($ERRORS{'DEBUG'}, 0, "anonymous UID ($existing_uid) value are already set correctly in the registry on $computer_name");
+	}
+	else {
+		# Set the registry keys
+		if (!$self->reg_add($base_key, $uid_key, 'REG_DWORD', $uid)) {
+			notify($ERRORS{'WARNING'}, 0, "failed to set Windows NFS Client anonymous UID in the registry");
+			return;
+		}
+	}
+	
+	# Stop the NFS service, this may fail if something is already mounted
+	if (!$self->{windows_nfs_reboot_required}) {
+		if ($self->stop_service($nfs_client_service_name)) {
+			## Service won't restart immediately after stopping it
+			#sleep_uninterrupted(10);
+			
+			if ($self->start_service($nfs_client_service_name)) {
+				notify($ERRORS{'DEBUG'}, 0, "set Windows NFS Client anonymous UID value in registry and restarted $nfs_client_service_name service");
+			}
+			else {
+				notify($ERRORS{'WARNING'}, 0, "failed to restart Windows NFS Client service, it may be in use, $computer_name will be rebooted");
+				$self->{windows_nfs_reboot_required} = 1;
+			}
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "failed to stop Windows NFS Client service, it may be in use, $computer_name will be rebooted");
+			$self->{windows_nfs_reboot_required} = 1;
+		}
+	}
+	
+	notify($ERRORS{'DEBUG'}, 0, "set Windows NFS Client anonymous UID values in registry");
+	return 1;
+}
+
+#//////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__
 
diff --git a/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm b/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
index 6931318..7678a0d 100644
--- a/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
@@ -1548,7 +1548,7 @@
 
 =head2 vm_unregister
 
- Parameters  : $vm_identifier 
+ Parameters  : $vm_identifier
  Returns     : boolean
  Description : Unregisters the VM indicated by the argument which may either be
                the .vmx file path or VM ID.
@@ -1586,9 +1586,9 @@
 			return 1;
 		}
 		
-		# Power of the VM if it is powered on or the unregister command will fail
+		# Power off the VM if it is powered on or the unregister command will fail
 		my $vm_power_state = $self->get_vm_power_state($vmx_file_path);
-		if ($vm_power_state && $vm_power_state =~ /on/i) {
+		if ($vm_power_state && $vm_power_state !~ /off/i) {
 			if (!$self->vm_power_off($vmx_file_path)) {
 				notify($ERRORS{'WARNING'}, 0, "failed to unregister VM because it could not be powered off: $vmx_file_path");
 				return;
diff --git a/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm b/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
index aa465ff..2ec1574 100644
--- a/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
@@ -1945,7 +1945,7 @@
 	}
 	
 	# The vmx file should be set to executable
-	chmod("0755", "/tmp/$vmx_file_name");
+	chmod(0755, "/tmp/$vmx_file_name");
 	
 	# Copy the temporary vmx file the the VM host
 	$self->vmhost_os->copy_file_to($temp_vmx_file_path, $vmx_file_path) || return;
@@ -5839,6 +5839,13 @@
 		# The VM needs to be registered for get_vm_virtual_disk_file_paths to work
 		@virtual_disks = $self->api->get_vm_virtual_disk_file_paths($vmx_file_path);
 		
+		# Make sure VM is powered off before trying to unregister it
+		if (!$self->api->vm_power_off($vmx_file_path)) {
+			notify($ERRORS{'WARNING'}, 0, "failed to power off VM: $vmx_file_path, VM not deleted");
+			return;
+		}
+		
+		# Unregister the VM
 		if (!$self->api->vm_unregister($vmx_file_path)) {
 			notify($ERRORS{'WARNING'}, 0, "failed to unregister VM: $vmx_file_path, VM not deleted");
 			return;
diff --git a/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm b/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm
index 3657192..4878da4 100644
--- a/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm
@@ -363,6 +363,14 @@
 	
 	my $vmx_path = $vm_view->{summary}{config}{vmPathName};
 	
+	my $vm_power_state = $self->get_vm_power_state($vmx_path);
+	if ($vm_power_state && $vm_power_state !~ /off/i) {
+		if (!$self->vm_power_off($vmx_path)) {
+			notify($ERRORS{'WARNING'}, 0, "failed to unregister VM because it could not be powered off: $vmx_path");
+			return;
+		}
+	}
+	
 	# Override the die handler
 	local $SIG{__DIE__} = sub{};
 	
diff --git a/managementnode/lib/VCL/Module/Provisioning/libvirt.pm b/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
index 44691bc..7f4bf1a 100644
--- a/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
@@ -1736,6 +1736,13 @@
 	
 	my $copy_on_write_file_path = $self->get_copy_on_write_file_path();
 	my $image_type = $self->data->get_vmhost_datastore_imagetype_name();
+	my $vmhost_vmpath = $self->data->get_vmhost_profile_vmpath();
+	my $add_disk_cache = 0;
+	if (! $self->os->nathost_os->is_file_on_local_disk($vmhost_vmpath)) {
+		# set disk cache to none if vmpath on NFS so live migration will work
+		$add_disk_cache = 1;
+	}
+
 	my $disk_driver_name = $self->driver->get_disk_driver_name();
 	my $disk_bus_type = $self->get_master_xml_disk_bus_type();
 	
@@ -1799,6 +1806,13 @@
 	#    Windows, however, expects it to be in so called 'localtime'."
 	my $clock_offset = ($image_os_type =~ /windows/) ? 'localtime' : 'utc';
 	
+	my $cpusockets = $cpu_count;
+	my $cpucores = 1;
+	if($cpu_count > 2) {
+		$cpusockets = 2;
+		$cpucores = ($cpu_count - ($cpu_count % 2)) / 2;
+	}
+
 	my $xml_hashref = {
 		'type' => $domain_type,
 		'description' => [$description],
@@ -1828,14 +1842,11 @@
 				model => {
 					'fallback' => 'allow',
 				},
-				#'topology' => [
-				#	{
-				#		'sockets' => $cpu_count,
-				#		'cores' => '2',
-				#		'threads' => '2',
-				#	}
-				#],
-				
+				topology => {
+					'sockets' => $cpusockets,
+					'cores' => $cpucores,
+					'threads' => 1,
+				},
 			}
 		],
 		'clock' => [
@@ -1908,6 +1919,11 @@
 			}
 		]
 	};
+
+	if ($add_disk_cache) {
+		notify($ERRORS{'DEBUG'}, 0, "vmpath ($vmhost_vmpath) is on NFS; setting disk cache to none");
+		$xml_hashref->{'devices'}[0]{'disk'}[0]{'driver'}{'cache'} = 'none';
+	}
 	
 	notify($ERRORS{'DEBUG'}, 0, "generated domain XML:\n" . format_data($xml_hashref));
 	return hash_to_xml_string($xml_hashref, 'domain');
diff --git a/managementnode/lib/VCL/Module/Provisioning/libvirt/KVM.pm b/managementnode/lib/VCL/Module/Provisioning/libvirt/KVM.pm
index 43741eb..e183690 100644
--- a/managementnode/lib/VCL/Module/Provisioning/libvirt/KVM.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/libvirt/KVM.pm
@@ -621,7 +621,7 @@
 	
 	my $start_time = time;
 	my ($exit_status, $output) = $self->vmhost_os->execute($command, 0, 7200);
-	if (defined($output && grep(/Unknown option.*compat/, @$output))) {
+	if (defined($output) && grep(/Unknown option.*compat/, @$output)) {
 		# Check for older versions which don't support '-o compat=':
 		#    Unknown option 'compat'
 		#    qemu-img: Invalid options for file format 'qcow2'.
diff --git a/managementnode/lib/VCL/utils.pm b/managementnode/lib/VCL/utils.pm
index 0e9a4ea..75cf782 100644
--- a/managementnode/lib/VCL/utils.pm
+++ b/managementnode/lib/VCL/utils.pm
@@ -58,7 +58,7 @@
 use DBI;
 use DBI::Const::GetInfoType;
 use diagnostics;
-use Net::Ping;
+use Net::Ping::External qw(ping);
 use Fcntl qw(:DEFAULT :flock);
 use FindBin;
 use Getopt::Long;
@@ -1270,7 +1270,7 @@
 	my ($package, $filename, $line,       $sub)  = caller(0);
 
 	# Mail::Mailer relies on sendmail as written, this causes a "die" on Windows
-	# TODO: Reqork this subroutine to not rely on sendmail
+	# TODO: Rework this subroutine to not rely on sendmail
 	my $osname = lc($^O);
 	if ($osname =~ /win/i) {
 		notify($ERRORS{'OK'}, 0, "sending mail from Windows not yet supported\n-----\nTo: $to\nSubject: $subject\nFrom: $from\n$mailstring\n-----");
@@ -1306,28 +1306,22 @@
 		$shared_mail_box = $management_node_info->{SHARED_EMAIL_BOX} if $management_node_info->{SHARED_EMAIL_BOX};
 	}
 
+	my $mail_args = {From => $from, To => $to, Subject => $subject};
 	if ($shared_mail_box) {
-		my $bcc = $shared_mail_box;
-		if ($mailer->open({From => $from, To => $to, Bcc => $bcc, Subject => $subject})) {
-			print $mailer $mailstring;
-			$mailer->close();
-			notify($ERRORS{'OK'}, 0, "SUCCESS -- Sending mail To: $to, $subject");
-		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "NOTICE --  Problem sending mail to: $to From");
-		}
-	} ## end if ($shared_mail_box)
+		$mail_args->{Bcc} = $shared_mail_box;
+	}
+	if($mailstring =~ /<html>/ || $mailstring =~ /<html .*>/) {
+		$mail_args->{'Content-Type'} = "text/html";
+		notify($ERRORS{'DEBUG'}, 0, "Encountered message containing <html> tag, adding Content-Type header");
+	}
+	if ($mailer->open($mail_args)) {
+		print $mailer $mailstring;
+		$mailer->close();
+		notify($ERRORS{'OK'}, 0, "SUCCESS -- Sending mail To: $to, $subject");
+	}
 	else {
-		if ($mailer->open({From => $from, To => $to, Subject => $subject,}))
-		{
-			print $mailer $mailstring;
-			$mailer->close();
-			notify($ERRORS{'OK'}, 0, "SUCCESS -- Sending mail To: $to, $subject");
-		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "NOTICE --  Problem sending mail to: $to From");
-		}
-	} ## end else [ if ($shared_mail_box)
+		notify($ERRORS{'WARNING'}, 0, "NOTICE --  Problem sending mail to: $to");
+	}
 } ## end sub mail
 
 #//////////////////////////////////////////////////////////////////////////////
@@ -2131,8 +2125,8 @@
 
  Parameters  : $node
  Returns     : boolean
- Description : Uses Net::Ping to check if a node is responding to ICMP echo
-               ping.
+ Description : Uses Net::Ping::External to check if a node is responding to ICMP
+               echo ping.
 
 =cut
 
@@ -2156,9 +2150,7 @@
 		}
 	}
 	
-	my $p = Net::Ping->new("icmp");
-	my $result = $p->ping($remote_connection_target, 1);
-	$p->close();
+	my $result = ping(host => $remote_connection_target, timeout => 1);
 
 	if ($result) {
 		#notify($ERRORS{'DEBUG'}, 0, "$node_string is responding to ping");
@@ -4623,6 +4615,7 @@
 	my $select_statement = "
 SELECT
 managementnode.*,
+UNIX_TIMESTAMP(managementnode.lastcheckin) as lastcheckin_epoch,
 resource.id AS resource_id,
 state.name AS statename
 FROM
@@ -4962,22 +4955,46 @@
 	}
 
 	# Get current timestamp
-	my $timestamp = makedatestring();
+	my $timestamp;
 
 	# Construct the update statement
 	my $update_statement = "
       UPDATE
 		managementnode
 		SET
-		lastcheckin = \'$timestamp\'
+		lastcheckin = NOW()
 		WHERE
 		id = $management_node_id
    ";
 
+	my $get_unix_timestamp = "
+	  SELECT
+	    UNIX_TIMESTAMP() as EPOC_TIMESTAMP
+    ";
+
 	# Call the database execute subroutine
 	if (database_execute($update_statement)) {
 		# Update successful, return timestamp
-		return $timestamp;
+		my @selected_rows = database_select($get_unix_timestamp);
+
+		# Check to make sure 1 row was returned
+		if (scalar @selected_rows == 0) {
+			notify($ERRORS{'WARNING'}, 0, "zero rows were returned from database select");
+			return 0;
+		}
+		elsif (scalar @selected_rows > 1) {
+			notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " rows were returned from database select");
+			return 0;
+		}
+
+		# Make sure we return undef if the column wasn't found
+		if (defined $selected_rows[0]{EPOC_TIMESTAMP}) {
+			$timestamp = $selected_rows[0]{EPOC_TIMESTAMP};
+			return $timestamp;
+		} else {
+			notify($ERRORS{'CRITICAL'}, 0, "unable to get EPOC_TIMESTAMP from database");
+			return 0;
+		}
 	}
 	else {
 		notify($ERRORS{'CRITICAL'}, 0, "unable to update database, management node id $management_node_id");
@@ -15085,8 +15102,8 @@
 
 =head2 get_management_node_ad_domain_credentials
 
- Parameters  : $management_node_id, $domain_dns_name, $no_cache (optional)
- Returns     : ($username, $secret_id, $encrypted_password)
+ Parameters  : $management_node_id, $domain_id, $no_cache (optional)
+ Returns     : ($domain_dns_name, $username, $secret_id, $encrypted_password)
  Description : Attempts to retrieve the username, encrypted password, and secret
                ID for the domain from the addomain table. This is used if a
                computer needs to be removed from a domain but the reservation
@@ -15096,63 +15113,58 @@
 =cut
 
 sub get_management_node_ad_domain_credentials {
-	my ($management_node_id, $domain_identifier, $no_cache) = @_;
+	my ($management_node_id, $domain_id, $no_cache) = @_;
 	if (!defined($management_node_id)) {
 		notify($ERRORS{'WARNING'}, 0, "management node ID argument was not supplied");
 		return;
 	}
-	elsif (!$domain_identifier) {
+	elsif (!$domain_id) {
 		notify($ERRORS{'WARNING'}, 0, "domain identifier name argument was not specified");
 		return;
 	}
 	
-	if (!$no_cache && defined($ENV{management_node_ad_domain_credentials}{$domain_identifier})) {
-		notify($ERRORS{'DEBUG'}, 0, "returning cached Active Directory credentials for domain: $domain_identifier");
-		return @{$ENV{management_node_ad_domain_credentials}{$domain_identifier}};
+	if (!$no_cache && defined($ENV{management_node_ad_domain_credentials}{$domain_id})) {
+		notify($ERRORS{'DEBUG'}, 0, "returning cached Active Directory credentials for domain: $domain_id");
+		return @{$ENV{management_node_ad_domain_credentials}{$domain_id}};
 	}
 	
 	# Construct the select statement
 	my $select_statement = <<EOF;
 SELECT DISTINCT
+domainDNSName,
 username,
 password,
 secretid
 FROM
 addomain
 WHERE
+addomain.id = $domain_id
 EOF
 	
-	if ($domain_identifier =~ /^\d+$/) {
-		$select_statement .= "addomain.id = $domain_identifier";
-	}
-	else {
-		$select_statement .= "addomain.domainDNSName LIKE '$domain_identifier%'";
-	}
-	
 	# Call the database select subroutine
 	my @selected_rows = database_select($select_statement);
 
 	# Check to make sure 1 row was returned
 	if (scalar @selected_rows == 0) {
-		notify($ERRORS{'DEBUG'}, 0, "Active Directory domain does not exist in the database: $domain_identifier");
+		notify($ERRORS{'DEBUG'}, 0, "Active Directory domain does not exist in the database: $domain_id");
 		return ();
 	}
 
 	# Get the single row returned from the select statement
 	my $row = $selected_rows[0];
+	my $domain_dns_name = $row->{domainDNSName};
 	my $username = $row->{username};
 	my $secret_id = $row->{secretid};
 	my $encrypted_password = $row->{password};
 	
-	
-	
-	notify($ERRORS{'DEBUG'}, 0, "retrieved credentials for domain: $domain_identifier\n" .
+	notify($ERRORS{'DEBUG'}, 0, "retrieved credentials for domain: $domain_id\n" .
+		"domain DNS name    : '$domain_dns_name'\n" .
 		"username           : '$username'\n" .
 		"secret ID          : '$secret_id'\n" .
 		"encrypted password : '$encrypted_password'"
 	);
-	$ENV{management_node_ad_domain_credentials}{$domain_identifier} = [$username, $secret_id, $encrypted_password];
-	return @{$ENV{management_node_ad_domain_credentials}{$domain_identifier}};
+	$ENV{management_node_ad_domain_credentials}{$domain_id} = [$domain_dns_name, $username, $secret_id, $encrypted_password];
+	return @{$ENV{management_node_ad_domain_credentials}{$domain_id}};
 }
 
 #//////////////////////////////////////////////////////////////////////////////
diff --git a/managementnode/tools/ESXi/Scripts/post_initial_connection/.gitignore b/managementnode/tools/ESXi/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ESXi/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/ESXi/Scripts/post_load/.gitignore b/managementnode/tools/ESXi/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ESXi/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/ESXi/Scripts/post_reservation/.gitignore b/managementnode/tools/ESXi/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ESXi/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/ESXi/Scripts/post_reserve/.gitignore b/managementnode/tools/ESXi/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ESXi/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/ESXi/Scripts/pre_capture/.gitignore b/managementnode/tools/ESXi/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ESXi/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/ESXi/Scripts/pre_reload/.gitignore b/managementnode/tools/ESXi/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ESXi/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Linux/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Linux/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Linux/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Linux/Scripts/post_load/.gitignore b/managementnode/tools/Linux/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Linux/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Linux/Scripts/post_reservation/.gitignore b/managementnode/tools/Linux/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Linux/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Linux/Scripts/post_reserve/.gitignore b/managementnode/tools/Linux/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Linux/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Linux/Scripts/pre_capture/.gitignore b/managementnode/tools/Linux/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Linux/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Linux/Scripts/pre_reload/.gitignore b/managementnode/tools/Linux/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Linux/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/ManagementNode/Scripts/post_capture/.gitignore b/managementnode/tools/ManagementNode/Scripts/post_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ManagementNode/Scripts/post_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/ManagementNode/Scripts/post_initial_connection/.gitignore b/managementnode/tools/ManagementNode/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ManagementNode/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/ManagementNode/Scripts/post_load/.gitignore b/managementnode/tools/ManagementNode/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ManagementNode/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/ManagementNode/Scripts/post_reservation/.gitignore b/managementnode/tools/ManagementNode/Scripts/post_reservation/.gitignore
new file mode 100755
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ManagementNode/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/ManagementNode/Scripts/post_reserve/.gitignore b/managementnode/tools/ManagementNode/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ManagementNode/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/ManagementNode/Scripts/pre_capture/.gitignore b/managementnode/tools/ManagementNode/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ManagementNode/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/ManagementNode/Scripts/pre_reload/.gitignore b/managementnode/tools/ManagementNode/Scripts/pre_reload/.gitignore
new file mode 100755
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/ManagementNode/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/OSX/Scripts/post_initial_connection/.gitignore b/managementnode/tools/OSX/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/OSX/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/OSX/Scripts/post_load/.gitignore b/managementnode/tools/OSX/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/OSX/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/OSX/Scripts/post_reservation/.gitignore b/managementnode/tools/OSX/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/OSX/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/OSX/Scripts/post_reserve/.gitignore b/managementnode/tools/OSX/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/OSX/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/OSX/Scripts/pre_capture/.gitignore b/managementnode/tools/OSX/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/OSX/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/OSX/Scripts/pre_reload/.gitignore b/managementnode/tools/OSX/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/OSX/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Ubuntu/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Ubuntu/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Ubuntu/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Ubuntu/Scripts/post_load/.gitignore b/managementnode/tools/Ubuntu/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Ubuntu/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Ubuntu/Scripts/post_reservation/.gitignore b/managementnode/tools/Ubuntu/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Ubuntu/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Ubuntu/Scripts/post_reserve/.gitignore b/managementnode/tools/Ubuntu/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Ubuntu/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Ubuntu/Scripts/pre_capture/.gitignore b/managementnode/tools/Ubuntu/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Ubuntu/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Ubuntu/Scripts/pre_reload/.gitignore b/managementnode/tools/Ubuntu/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Ubuntu/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows/Drivers/.gitignore b/managementnode/tools/Windows/Drivers/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows/Drivers/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows/Logs/.gitignore b/managementnode/tools/Windows/Logs/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows/Logs/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Windows/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows/Scripts/post_load/.gitignore b/managementnode/tools/Windows/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows/Scripts/post_reservation/.gitignore b/managementnode/tools/Windows/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows/Scripts/post_reserve/.gitignore b/managementnode/tools/Windows/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows/Scripts/pre_capture/.gitignore b/managementnode/tools/Windows/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows/Scripts/pre_reload/.gitignore b/managementnode/tools/Windows/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows/Updates/x86/.gitignore b/managementnode/tools/Windows/Updates/x86/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows/Updates/x86/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows/Updates/x86_64/.gitignore b/managementnode/tools/Windows/Updates/x86_64/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows/Updates/x86_64/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows/Utilities/WSName/.gitignore b/managementnode/tools/Windows/Utilities/WSName/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows/Utilities/WSName/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_10/Drivers/.gitignore b/managementnode/tools/Windows_10/Drivers/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_10/Drivers/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_10/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Windows_10/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_10/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_10/Scripts/post_load/.gitignore b/managementnode/tools/Windows_10/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_10/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_10/Scripts/post_reservation/.gitignore b/managementnode/tools/Windows_10/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_10/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_10/Scripts/post_reserve/.gitignore b/managementnode/tools/Windows_10/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_10/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_10/Scripts/pre_capture/.gitignore b/managementnode/tools/Windows_10/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_10/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_10/Scripts/pre_reload/.gitignore b/managementnode/tools/Windows_10/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_10/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_10/Updates/.gitignore b/managementnode/tools/Windows_10/Updates/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_10/Updates/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_10/Utilities/.gitignore b/managementnode/tools/Windows_10/Utilities/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_10/Utilities/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_7/Drivers/.gitignore b/managementnode/tools/Windows_7/Drivers/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_7/Drivers/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_7/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Windows_7/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_7/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_7/Scripts/post_load/.gitignore b/managementnode/tools/Windows_7/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_7/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_7/Scripts/post_reservation/.gitignore b/managementnode/tools/Windows_7/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_7/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_7/Scripts/post_reserve/.gitignore b/managementnode/tools/Windows_7/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_7/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_7/Scripts/pre_capture/.gitignore b/managementnode/tools/Windows_7/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_7/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_7/Scripts/pre_reload/.gitignore b/managementnode/tools/Windows_7/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_7/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_7/Updates/x86/.gitignore b/managementnode/tools/Windows_7/Updates/x86/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_7/Updates/x86/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_7/Updates/x86_64/.gitignore b/managementnode/tools/Windows_7/Updates/x86_64/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_7/Updates/x86_64/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_7/Utilities/.gitignore b/managementnode/tools/Windows_7/Utilities/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_7/Utilities/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_8/Drivers/.gitignore b/managementnode/tools/Windows_8/Drivers/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_8/Drivers/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_8/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Windows_8/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_8/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_8/Scripts/post_load/.gitignore b/managementnode/tools/Windows_8/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_8/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_8/Scripts/post_reservation/.gitignore b/managementnode/tools/Windows_8/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_8/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_8/Scripts/post_reserve/.gitignore b/managementnode/tools/Windows_8/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_8/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_8/Scripts/pre_capture/.gitignore b/managementnode/tools/Windows_8/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_8/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_8/Scripts/pre_reload/.gitignore b/managementnode/tools/Windows_8/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_8/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_8/Updates/.gitignore b/managementnode/tools/Windows_8/Updates/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_8/Updates/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_8/Utilities/.gitignore b/managementnode/tools/Windows_8/Utilities/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_8/Utilities/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2003/Drivers/.gitignore b/managementnode/tools/Windows_Server_2003/Drivers/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2003/Drivers/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2003/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Windows_Server_2003/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2003/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2003/Scripts/post_load/.gitignore b/managementnode/tools/Windows_Server_2003/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2003/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2003/Scripts/post_reservation/.gitignore b/managementnode/tools/Windows_Server_2003/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2003/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2003/Scripts/post_reserve/.gitignore b/managementnode/tools/Windows_Server_2003/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2003/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2003/Scripts/pre_capture/.gitignore b/managementnode/tools/Windows_Server_2003/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2003/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2003/Scripts/pre_reload/.gitignore b/managementnode/tools/Windows_Server_2003/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2003/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2003/Updates/x86/.gitignore b/managementnode/tools/Windows_Server_2003/Updates/x86/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2003/Updates/x86/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2003/Updates/x86_64/.gitignore b/managementnode/tools/Windows_Server_2003/Updates/x86_64/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2003/Updates/x86_64/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2003/Utilities/Sysprep/.gitignore b/managementnode/tools/Windows_Server_2003/Utilities/Sysprep/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2003/Utilities/Sysprep/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2008/Drivers/.gitignore b/managementnode/tools/Windows_Server_2008/Drivers/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2008/Drivers/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2008/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Windows_Server_2008/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2008/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2008/Scripts/post_load/.gitignore b/managementnode/tools/Windows_Server_2008/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2008/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2008/Scripts/post_reservation/.gitignore b/managementnode/tools/Windows_Server_2008/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2008/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2008/Scripts/post_reserve/.gitignore b/managementnode/tools/Windows_Server_2008/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2008/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2008/Scripts/pre_capture/.gitignore b/managementnode/tools/Windows_Server_2008/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2008/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2008/Scripts/pre_reload/.gitignore b/managementnode/tools/Windows_Server_2008/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2008/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2008/Updates/x86/.gitignore b/managementnode/tools/Windows_Server_2008/Updates/x86/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2008/Updates/x86/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2008/Updates/x86_64/.gitignore b/managementnode/tools/Windows_Server_2008/Updates/x86_64/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2008/Updates/x86_64/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2008/Utilities/.gitignore b/managementnode/tools/Windows_Server_2008/Utilities/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2008/Utilities/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2012/Drivers/.gitignore b/managementnode/tools/Windows_Server_2012/Drivers/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2012/Drivers/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2012/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Windows_Server_2012/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2012/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2012/Scripts/post_load/.gitignore b/managementnode/tools/Windows_Server_2012/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2012/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2012/Scripts/post_reservation/.gitignore b/managementnode/tools/Windows_Server_2012/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2012/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2012/Scripts/post_reserve/.gitignore b/managementnode/tools/Windows_Server_2012/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2012/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2012/Scripts/pre_capture/.gitignore b/managementnode/tools/Windows_Server_2012/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2012/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2012/Scripts/pre_reload/.gitignore b/managementnode/tools/Windows_Server_2012/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2012/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2012/Updates/.gitignore b/managementnode/tools/Windows_Server_2012/Updates/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2012/Updates/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2012/Utilities/.gitignore b/managementnode/tools/Windows_Server_2012/Utilities/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2012/Utilities/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2016/Drivers/.gitignore b/managementnode/tools/Windows_Server_2016/Drivers/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2016/Drivers/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2016/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Windows_Server_2016/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2016/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2016/Scripts/post_load/.gitignore b/managementnode/tools/Windows_Server_2016/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2016/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2016/Scripts/post_reservation/.gitignore b/managementnode/tools/Windows_Server_2016/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2016/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2016/Scripts/post_reserve/.gitignore b/managementnode/tools/Windows_Server_2016/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2016/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2016/Scripts/pre_capture/.gitignore b/managementnode/tools/Windows_Server_2016/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2016/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2016/Scripts/pre_reload/.gitignore b/managementnode/tools/Windows_Server_2016/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2016/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2016/Updates/.gitignore b/managementnode/tools/Windows_Server_2016/Updates/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2016/Updates/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Server_2016/Utilities/.gitignore b/managementnode/tools/Windows_Server_2016/Utilities/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Server_2016/Utilities/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_5/Drivers/.gitignore b/managementnode/tools/Windows_Version_5/Drivers/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_5/Drivers/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_5/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Windows_Version_5/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_5/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_5/Scripts/post_load/.gitignore b/managementnode/tools/Windows_Version_5/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_5/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_5/Scripts/post_reservation/.gitignore b/managementnode/tools/Windows_Version_5/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_5/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_5/Scripts/post_reserve/.gitignore b/managementnode/tools/Windows_Version_5/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_5/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_5/Scripts/pre_capture/.gitignore b/managementnode/tools/Windows_Version_5/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_5/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_5/Scripts/pre_reload/.gitignore b/managementnode/tools/Windows_Version_5/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_5/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_5/Updates/x86/.gitignore b/managementnode/tools/Windows_Version_5/Updates/x86/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_5/Updates/x86/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_5/Updates/x86_64/.gitignore b/managementnode/tools/Windows_Version_5/Updates/x86_64/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_5/Updates/x86_64/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_6/Drivers/.gitignore b/managementnode/tools/Windows_Version_6/Drivers/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_6/Drivers/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_6/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Windows_Version_6/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_6/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_6/Scripts/post_load/.gitignore b/managementnode/tools/Windows_Version_6/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_6/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_6/Scripts/post_reservation/.gitignore b/managementnode/tools/Windows_Version_6/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_6/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_6/Scripts/post_reserve/.gitignore b/managementnode/tools/Windows_Version_6/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_6/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_6/Scripts/pre_capture/.gitignore b/managementnode/tools/Windows_Version_6/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_6/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_6/Scripts/pre_reload/.gitignore b/managementnode/tools/Windows_Version_6/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_6/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_6/Updates/x86/.gitignore b/managementnode/tools/Windows_Version_6/Updates/x86/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_6/Updates/x86/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Version_6/Updates/x86_64/.gitignore b/managementnode/tools/Windows_Version_6/Updates/x86_64/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Version_6/Updates/x86_64/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Vista/Drivers/.gitignore b/managementnode/tools/Windows_Vista/Drivers/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Vista/Drivers/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Vista/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Windows_Vista/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Vista/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Vista/Scripts/post_load/.gitignore b/managementnode/tools/Windows_Vista/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Vista/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Vista/Scripts/post_reservation/.gitignore b/managementnode/tools/Windows_Vista/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Vista/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Vista/Scripts/post_reserve/.gitignore b/managementnode/tools/Windows_Vista/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Vista/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Vista/Scripts/pre_capture/.gitignore b/managementnode/tools/Windows_Vista/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Vista/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Vista/Scripts/pre_reload/.gitignore b/managementnode/tools/Windows_Vista/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Vista/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Vista/Updates/x86/.gitignore b/managementnode/tools/Windows_Vista/Updates/x86/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Vista/Updates/x86/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_Vista/Updates/x86_64/.gitignore b/managementnode/tools/Windows_Vista/Updates/x86_64/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_Vista/Updates/x86_64/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_XP/Drivers/.gitignore b/managementnode/tools/Windows_XP/Drivers/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_XP/Drivers/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_XP/Scripts/post_initial_connection/.gitignore b/managementnode/tools/Windows_XP/Scripts/post_initial_connection/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_XP/Scripts/post_initial_connection/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_XP/Scripts/post_load/.gitignore b/managementnode/tools/Windows_XP/Scripts/post_load/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_XP/Scripts/post_load/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_XP/Scripts/post_reservation/.gitignore b/managementnode/tools/Windows_XP/Scripts/post_reservation/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_XP/Scripts/post_reservation/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_XP/Scripts/post_reserve/.gitignore b/managementnode/tools/Windows_XP/Scripts/post_reserve/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_XP/Scripts/post_reserve/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_XP/Scripts/pre_capture/.gitignore b/managementnode/tools/Windows_XP/Scripts/pre_capture/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_XP/Scripts/pre_capture/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_XP/Scripts/pre_reload/.gitignore b/managementnode/tools/Windows_XP/Scripts/pre_reload/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_XP/Scripts/pre_reload/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_XP/Updates/x86/.gitignore b/managementnode/tools/Windows_XP/Updates/x86/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_XP/Updates/x86/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_XP/Updates/x86_64/.gitignore b/managementnode/tools/Windows_XP/Updates/x86_64/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_XP/Updates/x86_64/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/managementnode/tools/Windows_XP/Utilities/Sysprep/.gitignore b/managementnode/tools/Windows_XP/Utilities/Sysprep/.gitignore
new file mode 100644
index 0000000..44c6794
--- /dev/null
+++ b/managementnode/tools/Windows_XP/Utilities/Sysprep/.gitignore
@@ -0,0 +1,11 @@
+#
+# The purpose of this file is to keep this directory from being empty so the
+# directory will be retained in the git repository. The directory is used by
+# the backend code for some scripts used during provisioning, and so needs to
+# be retained.
+#
+
+# Ignore everything in this directory
+*
+# Except this file
+!.gitignore
diff --git a/mysql/update-vcl.sql b/mysql/update-vcl.sql
index ce33548..60ddc8f 100644
--- a/mysql/update-vcl.sql
+++ b/mysql/update-vcl.sql
@@ -878,11 +878,15 @@
   `username` varchar(64) NOT NULL default '',
   `password` varchar(256) NOT NULL default '',
   `secretid` smallint(5) unsigned NOT NULL,
+  `usedbhostnames` tinyint(1) unsigned NOT NULL default '0',
   PRIMARY KEY (`id`),
-  UNIQUE KEY `domainDNSName` (`domainDNSName`),
+  KEY `domainDNSName` (`domainDNSName`),
   KEY `secretid` (`secretid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
+CALL DropExistingIndices('addomain', 'domainDNSName');
+CALL AddIndexIfNotExists('addomain', 'domainDNSName');
+
 -- --------------------------------------------------------
 
 --
@@ -1111,6 +1115,7 @@
 -- Table structure change for table `managementnode`
 -- 
 
+ALTER TABLE `managementnode` CHANGE `lastcheckin` `lastcheckin` timestamp default 0;
 CALL AddColumnIfNotExists('managementnode', 'publicIPconfiguration', "enum('dynamicDHCP','manualDHCP','static') NOT NULL default 'dynamicDHCP'");
 CALL AddColumnIfNotExists('managementnode', 'publicSubnetMask', "varchar(56) default NULL");
 CALL AddColumnIfNotExists('managementnode', 'publicDefaultGateway', "varchar(56) default NULL");
@@ -1124,6 +1129,18 @@
 
 -- --------------------------------------------------------
 
+-- 
+-- Table structure for table `messagereset`
+-- 
+
+CREATE TABLE IF NOT EXISTS `messagereset` (
+  `name` varchar(128) NOT NULL,
+  `value` longtext NOT NULL,
+  PRIMARY KEY (`name`)
+) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+
+-- --------------------------------------------------------
+
 --
 -- Table structure change for table `module`
 --
@@ -1544,12 +1561,14 @@
 CREATE TABLE IF NOT EXISTS `vcldsemaphore` (
   `identifier` varchar(256) NOT NULL,
   `reservationid` mediumint(9) unsigned NOT NULL,
-  `pid` smallint(5) unsigned NOT NULL,
+  `pid` mediumint(8) unsigned NOT NULL,
   `expires` datetime NOT NULL,
   PRIMARY KEY (`identifier`),
   KEY `reservationid` (`reservationid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
+ALTER TABLE `vcldsemaphore` CHANGE `pid` `pid` mediumint(8) unsigned NOT NULL;
+
 -- --------------------------------------------------------
 
 -- 
@@ -1745,6 +1764,30 @@
 -- --------------------------------------------------------
 
 -- 
+-- Inserts for table `messagereset`
+-- 
+
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('adminmessage|image_creation_failed', '---\nmessage: |\n  VCL Image Creation Failed\n  \n  Management node: [management_node_short_name]\n  \n  Request ID: [request_id]\n  Reservation ID: [reservation_id]\n  PID: [process_pid]\n  \n  Image ID: [image_id]\n  Image revision ID: [imagerevision_id]\n  Image name: [image_name]\n  Image display name: [image_prettyname]\n  Image OS package: [image_os_module_perl_package]\n  \n  User ID: [user_id]\n  User login name: [user_login_id]\n  User name: [user_firstname] [user_lastname]\n  User affiliation: [user_affiliation_name]\n  \n  Provisioning module: [computer_provisioning_pretty_name] ([computer_provisioning_name])\n  Provisioning package: [computer_provisioning_module_perl_package]\n  \n  Computer ID: [computer_id]\n  Computer name: [computer_short_name]\n  \n  VM host ID: [vmhost_id]\n  VM host computer ID: [vmhost_computer_id]\n  VM host computer name: [vmhost_short_name]\n  \n  VM host profile ID: [vmhost_profile_id]\n  VM host profile name: [vmhost_profile_name]\nsubject: ''VCL -- NOTICE FAILED Image [image_capture_type] [image_prettyname]''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('adminmessage|image_creation_complete', '---\nmessage: |\n  VCL Image [image_capture_type] Completed\n  \n  Request ID: [request_id]\n  Reservation ID: [reservation_id]\n  PID: [process_pid]\n  \n  Image ID: [image_id]\n  Image name: [image_name]\n  Image size: [image_size]\n  \n  Revision ID: [imagerevision_id]\n  \n  Management node: [management_node_short_name]\n  \n  Username: [user_login_id]\n  User ID: [user_id]\n  \n  Computer ID: [computer_id]\n  Computer name: [computer_short_name]\n  \n  Use Sysprep: [imagemeta_sysprep]\nsubject: ''VCL IMAGE [image_capture_type] Completed: [image_name]''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('adminmessage|image_creation_started', '---\nmessage: |\n  VCL Image Creation Started\n  \n  Request ID: [request_id]\n  Reservation ID: [reservation_id]\n  PID: [process_pid]\n  \n  Image ID: [image_id]\n  Image name: [image_name]\n  Base image size: [image_size]\n  Base revision ID: [imagerevision_id]\n  \n  Management node: [management_node_short_name]\n  \n  Username: [user_login_id]\n  User ID: [user_id]\n  \n  Computer ID: [computer_id]\n  Computer name: [computer_short_name]\n  \n  Use Sysprep: [imagemeta_sysprep]\nsubject: ''VCL IMAGE Creation Started: [image_name]''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|endtime_reached|Global', '---\nmessage: |\n  Your reservation of [image_prettyname] has ended. Thank you for using [user_affiliation_sitewwwaddress].\n  \n  Regards,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- End of reservation''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|reserved|Global', '---\nmessage: |\n  The resources for your VCL reservation have been successfully reserved.\n  Connection will not be allowed until you click the ''Connect'' button on the ''Current Reservations'' page.\n  You must acknowledge the reservation within the next 15 minutes or the resources will be reclaimed for other VCL users.\n  \n  -Visit [user_affiliation_sitewwwaddress]\n  -Select "Current Reservations"\n  -Click the "Connect" button\n  Upon acknowledgement, all of the remaining connection details will be displayed.\n  \n  Thank You,\n  VCL Team\n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] reservation''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|timeout_no_initial_connection|Global', '---\nmessage: |\n  Your reservation has timed out for image [image_prettyname] because no initial connection was made.\n  \n  To make another reservation, please revisit [user_affiliation_sitewwwaddress].\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance\n  please respond with detailed information on the issue\n  and a help ticket will be generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- Reservation Timeout''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|endtime_imminent|Global', '---\nmessage: |\n  You have [notice_interval] until the end of your reservation for image [image_prettyname], please save all work and prepare to exit.\n  \n  Reservation extensions are available if the machine you are on does not have a reservation immediately following.\n  \n  Visit [user_affiliation_sitewwwaddress] and select Current Reservations to edit this reservation.\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ''You have [notice_interval] until the end of your reservation. Please save all work and prepare to log off.''\nsubject: ''VCL -- [notice_interval] until end of reservation''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|production_imagerevision|Global', '---\nmessage: |\n  Revision [imagerevision_revision] of your VCL ''[image_prettyname]'' image has been made production.  Any new reservations for the image will receive this revision by default.\n  \n  If you have any questions, please contact [user_affiliation_helpaddress].\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- Image [image_prettyname] made production''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|timeout_inactivity|Global', '---\nmessage: |\n  Your reservation has timed out due to inactivity for image [image_prettyname].\n  \n  To make another reservation, please revisit:\n  [user_affiliation_sitewwwaddress]\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- reservation timeout''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|image_creation_delayed|Global', '---\nmessage: |\n  We apologize for the inconvenience.\n  Your image creation of [image_prettyname] has been delayed\n  due to a system issue that prevented the automatic completion.\n  \n  The image creation request and the computing resource have\n  been placed in a safe mode. The VCL system administrators\n  have been notified for manual intervention.\n  \n  Once the issues have been resolved, you will be notified\n  by the successful completion email or contacted directly\n  by the VCL system administrators.\n  \n  If you do not receive a response within one business day, please\n  reply to this email.\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- NOTICE DELAY Image Creation [image_prettyname]''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|reinstalled|Global', '---\nmessage: |\n  Your reservation was successfully reinstalled and you can proceed to reconnect. \n  Please revisit the ''Current Reservations'' page for any additional information.\n  \n  Thank You,\n  VCL Team\n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************''\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] reservation reinstalled''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|endtime_reached_imaging|Global', '---\nmessage: |\n  Your imaging reservation of [image_prettyname] has reached it''s scheduled end time.\n  \n  To avoid losing your work we have started an automatic capture of this image. Upon completion of the \n  image capture. You will be notified about the completion of the image capture.\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL Image Reservation - Auto capture started''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|image_creation_success|Global', '---\nmessage: |\n  Your VCL image creation request for [image_prettyname] has succeeded.\n  \n  Please visit [user_affiliation_sitewwwaddress] and you should see an image called [image_prettyname].\n  \n  Please test this image to confirm it works correctly.\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] Image Creation Succeeded''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|image_checkpoint_success|Global', '---\nmessage: |\n  Your VCL image checkpoint creation request for [image_prettyname] has succeeded.\n  \n  You will need to visit the "Current Reservations" page and click "Connect" in order to be able to reconnect to the computer.\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] Image Checkpoint Succeeded''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|timeout_no_acknowledgement|Global', '---\nmessage: |\n  Your reservation has timed out for image [image_prettyname] because no initial connection was made.\n  \n  To make another reservation, please revisit [user_affiliation_sitewwwaddress].\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance\n  please respond with detailed information on the issue\n  and a help ticket will be generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- Reservation Timeout''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|future_endtime|Global', '---\nmessage: |\n  You have [notice_interval] until the scheduled end time of your reservation for image [image_prettyname].\n  \n  Reservation extensions are available if the machine you are on does not have a reservation immediately following.\n  \n  To edit this reservation:\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select Current Reservations\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: "You have [notice_interval] until the scheduled end time of your reservation. VCL Team\\n"\nsubject: ''VCL -- [notice_interval] until end of reservation for [image_prettyname]''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|endtime_imminent_imaging|Global', '---\nmessage: |\n  You have [notice_interval] until the end of your reservation for image [image_prettyname]. \n  \n  At the scheduled end time your imaging reservation will be automatically captured. \n  \n  To prevent this auto capture, visit the VCL site [user_affiliation_sitewwwaddress] manually start the image creation process.\n  \n  Please note this auto capture feature is intended to prevent destorying any work you have done to the image.\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ''You have [notice_interval] until the auto capture process is started.''\nsubject: ''VCL Imaging Reservation -- [notice_interval] until starting auto capture''\n');
+
+-- --------------------------------------------------------
+
+-- 
 -- Inserts for table `module`
 -- 
 
diff --git a/mysql/vcl.sql b/mysql/vcl.sql
index 95d68ca..45db9ea 100644
--- a/mysql/vcl.sql
+++ b/mysql/vcl.sql
@@ -38,8 +38,9 @@
   `username` varchar(64) NOT NULL default '',
   `password` varchar(256) NOT NULL default '',
   `secretid` smallint(5) unsigned NOT NULL,
+  `usedbhostnames` tinyint(1) unsigned NOT NULL default '0',
   PRIMARY KEY (`id`),
-  UNIQUE KEY `domainDNSName` (`domainDNSName`),
+  KEY `domainDNSName` (`domainDNSName`),
   KEY `secretid` (`secretid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
@@ -682,7 +683,7 @@
   `hostname` varchar(50) NOT NULL default '',
   `ownerid` mediumint(8) unsigned NOT NULL default '1',
   `stateid` tinyint(3) unsigned NOT NULL default '0',
-  `lastcheckin` datetime default NULL,
+  `lastcheckin` timestamp default 0,
   `checkininterval` tinyint(3) unsigned NOT NULL default '12',
   `installpath` varchar(100) NOT NULL default '/install',
   `imagelibenable` tinyint(1) unsigned NOT NULL default '0',
@@ -709,6 +710,18 @@
 
 -- --------------------------------------------------------
 
+-- 
+-- Table structure for table `messagereset`
+-- 
+
+CREATE TABLE IF NOT EXISTS `messagereset` (
+  `name` varchar(128) NOT NULL,
+  `value` longtext NOT NULL,
+  PRIMARY KEY (`name`)
+) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+
+-- --------------------------------------------------------
+
 --
 -- Table structure for table `module`
 --
@@ -1481,7 +1494,7 @@
 CREATE TABLE IF NOT EXISTS `vcldsemaphore` (
   `identifier` varchar(256) NOT NULL,
   `reservationid` mediumint(9) unsigned NOT NULL,
-  `pid` smallint(5) unsigned NOT NULL,
+  `pid` mediumint(8) unsigned NOT NULL,
   `expires` datetime NOT NULL,
   PRIMARY KEY (`identifier`),
   KEY `reservationid` (`reservationid`)
@@ -1787,6 +1800,29 @@
 (1, 'none');
 
 -- 
+-- Dumping data for table `messagereset`
+-- 
+
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES
+('adminmessage|image_creation_failed', '---\nmessage: |\n  VCL Image Creation Failed\n  \n  Management node: [management_node_short_name]\n  \n  Request ID: [request_id]\n  Reservation ID: [reservation_id]\n  PID: [process_pid]\n  \n  Image ID: [image_id]\n  Image revision ID: [imagerevision_id]\n  Image name: [image_name]\n  Image display name: [image_prettyname]\n  Image OS package: [image_os_module_perl_package]\n  \n  User ID: [user_id]\n  User login name: [user_login_id]\n  User name: [user_firstname] [user_lastname]\n  User affiliation: [user_affiliation_name]\n  \n  Provisioning module: [computer_provisioning_pretty_name] ([computer_provisioning_name])\n  Provisioning package: [computer_provisioning_module_perl_package]\n  \n  Computer ID: [computer_id]\n  Computer name: [computer_short_name]\n  \n  VM host ID: [vmhost_id]\n  VM host computer ID: [vmhost_computer_id]\n  VM host computer name: [vmhost_short_name]\n  \n  VM host profile ID: [vmhost_profile_id]\n  VM host profile name: [vmhost_profile_name]\nsubject: ''VCL -- NOTICE FAILED Image [image_capture_type] [image_prettyname]''\n'),
+('adminmessage|image_creation_complete', '---\nmessage: |\n  VCL Image [image_capture_type] Completed\n  \n  Request ID: [request_id]\n  Reservation ID: [reservation_id]\n  PID: [process_pid]\n  \n  Image ID: [image_id]\n  Image name: [image_name]\n  Image size: [image_size]\n  \n  Revision ID: [imagerevision_id]\n  \n  Management node: [management_node_short_name]\n  \n  Username: [user_login_id]\n  User ID: [user_id]\n  \n  Computer ID: [computer_id]\n  Computer name: [computer_short_name]\n  \n  Use Sysprep: [imagemeta_sysprep]\nsubject: ''VCL IMAGE [image_capture_type] Completed: [image_name]''\n'),
+('adminmessage|image_creation_started', '---\nmessage: |\n  VCL Image Creation Started\n  \n  Request ID: [request_id]\n  Reservation ID: [reservation_id]\n  PID: [process_pid]\n  \n  Image ID: [image_id]\n  Image name: [image_name]\n  Base image size: [image_size]\n  Base revision ID: [imagerevision_id]\n  \n  Management node: [management_node_short_name]\n  \n  Username: [user_login_id]\n  User ID: [user_id]\n  \n  Computer ID: [computer_id]\n  Computer name: [computer_short_name]\n  \n  Use Sysprep: [imagemeta_sysprep]\nsubject: ''VCL IMAGE Creation Started: [image_name]''\n'),
+('usermessage|endtime_reached|Global', '---\nmessage: |\n  Your reservation of [image_prettyname] has ended. Thank you for using [user_affiliation_sitewwwaddress].\n  \n  Regards,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- End of reservation''\n'),
+('usermessage|reserved|Global', '---\nmessage: |\n  The resources for your VCL reservation have been successfully reserved.\n  Connection will not be allowed until you click the ''Connect'' button on the ''Current Reservations'' page.\n  You must acknowledge the reservation within the next 15 minutes or the resources will be reclaimed for other VCL users.\n  \n  -Visit [user_affiliation_sitewwwaddress]\n  -Select "Current Reservations"\n  -Click the "Connect" button\n  Upon acknowledgement, all of the remaining connection details will be displayed.\n  \n  Thank You,\n  VCL Team\n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] reservation''\n'),
+('usermessage|timeout_no_initial_connection|Global', '---\nmessage: |\n  Your reservation has timed out for image [image_prettyname] because no initial connection was made.\n  \n  To make another reservation, please revisit [user_affiliation_sitewwwaddress].\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance\n  please respond with detailed information on the issue\n  and a help ticket will be generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- Reservation Timeout''\n'),
+('usermessage|endtime_imminent|Global', '---\nmessage: |\n  You have [notice_interval] until the end of your reservation for image [image_prettyname], please save all work and prepare to exit.\n  \n  Reservation extensions are available if the machine you are on does not have a reservation immediately following.\n  \n  Visit [user_affiliation_sitewwwaddress] and select Current Reservations to edit this reservation.\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ''You have [notice_interval] until the end of your reservation. Please save all work and prepare to log off.''\nsubject: ''VCL -- [notice_interval] until end of reservation''\n'),
+('usermessage|production_imagerevision|Global', '---\nmessage: |\n  Revision [imagerevision_revision] of your VCL ''[image_prettyname]'' image has been made production.  Any new reservations for the image will receive this revision by default.\n  \n  If you have any questions, please contact [user_affiliation_helpaddress].\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- Image [image_prettyname] made production''\n'),
+('usermessage|timeout_inactivity|Global', '---\nmessage: |\n  Your reservation has timed out due to inactivity for image [image_prettyname].\n  \n  To make another reservation, please revisit:\n  [user_affiliation_sitewwwaddress]\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- reservation timeout''\n'),
+('usermessage|image_creation_delayed|Global', '---\nmessage: |\n  We apologize for the inconvenience.\n  Your image creation of [image_prettyname] has been delayed\n  due to a system issue that prevented the automatic completion.\n  \n  The image creation request and the computing resource have\n  been placed in a safe mode. The VCL system administrators\n  have been notified for manual intervention.\n  \n  Once the issues have been resolved, you will be notified\n  by the successful completion email or contacted directly\n  by the VCL system administrators.\n  \n  If you do not receive a response within one business day, please\n  reply to this email.\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- NOTICE DELAY Image Creation [image_prettyname]''\n'),
+('usermessage|reinstalled|Global', '---\nmessage: |\n  Your reservation was successfully reinstalled and you can proceed to reconnect. \n  Please revisit the ''Current Reservations'' page for any additional information.\n  \n  Thank You,\n  VCL Team\n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************''\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] reservation reinstalled''\n'),
+('usermessage|endtime_reached_imaging|Global', '---\nmessage: |\n  Your imaging reservation of [image_prettyname] has reached it''s scheduled end time.\n  \n  To avoid losing your work we have started an automatic capture of this image. Upon completion of the \n  image capture. You will be notified about the completion of the image capture.\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL Image Reservation - Auto capture started''\n'),
+('usermessage|image_creation_success|Global', '---\nmessage: |\n  Your VCL image creation request for [image_prettyname] has succeeded.\n  \n  Please visit [user_affiliation_sitewwwaddress] and you should see an image called [image_prettyname].\n  \n  Please test this image to confirm it works correctly.\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] Image Creation Succeeded''\n'),
+('usermessage|image_checkpoint_success|Global', '---\nmessage: |\n  Your VCL image checkpoint creation request for [image_prettyname] has succeeded.\n  \n  You will need to visit the "Current Reservations" page and click "Connect" in order to be able to reconnect to the computer.\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] Image Checkpoint Succeeded''\n'),
+('usermessage|timeout_no_acknowledgement|Global', '---\nmessage: |\n  Your reservation has timed out for image [image_prettyname] because no initial connection was made.\n  \n  To make another reservation, please revisit [user_affiliation_sitewwwaddress].\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance\n  please respond with detailed information on the issue\n  and a help ticket will be generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- Reservation Timeout''\n'),
+('usermessage|future_endtime|Global', '---\nmessage: |\n  You have [notice_interval] until the scheduled end time of your reservation for image [image_prettyname].\n  \n  Reservation extensions are available if the machine you are on does not have a reservation immediately following.\n  \n  To edit this reservation:\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select Current Reservations\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: "You have [notice_interval] until the scheduled end time of your reservation. VCL Team\\n"\nsubject: ''VCL -- [notice_interval] until end of reservation for [image_prettyname]''\n'),
+('usermessage|endtime_imminent_imaging|Global', '---\nmessage: |\n  You have [notice_interval] until the end of your reservation for image [image_prettyname]. \n  \n  At the scheduled end time your imaging reservation will be automatically captured. \n  \n  To prevent this auto capture, visit the VCL site [user_affiliation_sitewwwaddress] manually start the image creation process.\n  \n  Please note this auto capture feature is intended to prevent destorying any work you have done to the image.\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ''You have [notice_interval] until the auto capture process is started.''\nsubject: ''VCL Imaging Reservation -- [notice_interval] until starting auto capture''\n');
+
+-- 
 -- Dumping data for table `module`
 -- 
 
@@ -2103,7 +2139,7 @@
 -- 
 
 INSERT IGNORE INTO `user` (`id`, `uid`, `unityid`, `affiliationid`, `firstname`, `lastname`, `preferredname`, `email`, `emailnotices`, `IMtypeid`, `IMid`, `adminlevelid`, `width`, `height`, `bpp`, `audiomode`, `mapdrives`, `mapprinters`, `mapserial`, `showallgroups`, `lastupdated`) VALUES 
-(1, 101, 'admin', 1, 'vcl', 'admin', '', 'root@localhost', 0, NULL, NULL, 3, 1024, 768, 16, 'local', 1, 1, 1, 1, '2007-05-17 09:58:39'),
+(1, NULL, 'admin', 1, 'vcl', 'admin', '', 'root@localhost', 0, NULL, NULL, 3, 1024, 768, 16, 'local', 1, 1, 1, 1, '2007-05-17 09:58:39'),
 (2, NULL, 'vclreload', 1, 'vcl', 'reload', NULL, '', 0, NULL, NULL, 1, 1024, 768, 16, 'local', 1, 1, 0, 0, '0000-00-00 00:00:00'),
 (3, NULL, 'vclsystem', 1, 'vcl', 'system', NULL, '', 0, NULL, NULL, 1, 1024, 768, 16, 'local', 1, 1, 0, 0, '0000-00-00 00:00:00');
 
diff --git a/vcl-install.sh b/vcl-install.sh
index c67e003..d4eed6c 100755
--- a/vcl-install.sh
+++ b/vcl-install.sh
@@ -178,8 +178,8 @@
 	fi
 	VCL_VERSION=${VCL_VERSION}-RC$RC
 	ARCHIVE=apache-VCL-$VCL_VERSION.tar.bz2
-	ARCHIVEURLPATH="http://people.apache.org/~jfthomps/apache-VCL-${VCL_VERSION}/"
-	SIGPATH="http://people.apache.org/~jfthomps/apache-VCL-${VCL_VERSION}/"
+	ARCHIVEURLPATH="https://people.apache.org/~jfthomps/apache-VCL-${VCL_VERSION}/"
+	SIGPATH="https://people.apache.org/~jfthomps/apache-VCL-${VCL_VERSION}/"
 fi
 
 if [[ $DOALL -eq 1 ]]; then
diff --git a/vcl-upgrade.sh b/vcl-upgrade.sh
index e0ed9db..4998fbf 100755
--- a/vcl-upgrade.sh
+++ b/vcl-upgrade.sh
@@ -73,7 +73,7 @@
 DB_HOST=localhost
 ARCHIVE=apache-VCL-$VCL_VERSION.tar.bz2
 ARCHIVEURLPATH="http://vcl.apache.org/downloads/download.cgi?action=download&filename=%2Fvcl%2F$VCL_VERSION%2F"
-SIGPATH="http://www.apache.org/dist/vcl/$VCL_VERSION/"
+SIGPATH="https://www.apache.org/dist/vcl/$VCL_VERSION/"
 
 DODB=0
 DOWEB=0
@@ -151,8 +151,8 @@
 	fi
 	VCL_VERSION=${VCL_VERSION}-RC$RC
 	ARCHIVE=apache-VCL-$VCL_VERSION.tar.bz2
-	ARCHIVEURLPATH="http://people.apache.org/~jfthomps/apache-VCL-${VCL_VERSION}/"
-	SIGPATH="http://people.apache.org/~jfthomps/apache-VCL-${VCL_VERSION}/"
+	ARCHIVEURLPATH="https://people.apache.org/~jfthomps/apache-VCL-${VCL_VERSION}/"
+	SIGPATH="https://people.apache.org/~jfthomps/apache-VCL-${VCL_VERSION}/"
 fi
 
 if [[ $DOALL -eq 1 ]]; then
diff --git a/web/.gitignore b/web/.gitignore
index 54e45b2..869a44c 100644
--- a/web/.gitignore
+++ b/web/.gitignore
@@ -7,3 +7,7 @@
 .ht-inc/spyc-0.5.1/
 dojo/
 themes/**/css/dojo
+# netbeans project files
+.settings/
+.buildpath
+.project
diff --git a/web/.ht-inc/addomain.php b/web/.ht-inc/addomain.php
index e75639d..7e9f5a1 100644
--- a/web/.ht-inc/addomain.php
+++ b/web/.ht-inc/addomain.php
@@ -204,7 +204,7 @@
 				       . "WHERE cryptkeyid = $cryptkeyid AND "
 				       .       "secretid = $oldsecretid";
 				$qh = doQuery($query);
-				if(! ($row = mysql_fetch_assoc($qh))) {
+				if(! ($row = mysqli_fetch_assoc($qh))) {
 					# generate a new secret
 					$newsecretid = getSecretKeyID('addomain', 'secretid', 0);
 					$delids = array($oldsecretid);
@@ -221,7 +221,7 @@
 					       . "WHERE cs.secretid = $oldsecretid AND "
 					       .       "ck.hosttype = 'managementnode'";
 					$qh = doQuery($query);
-					while($row = mysql_fetch_assoc($qh))
+					while($row = mysqli_fetch_assoc($qh))
 						$secretidset[$row['mnid']][$newsecretid] = 1;
 					$values = getMNcryptkeyUpdates($secretidset, $cryptkeyid);
 					addCryptSecretKeyUpdates($values);
@@ -242,6 +242,9 @@
 			# dnsservers
 			if($data['dnsservers'] != $olddata['dnsservers'])
 				$updates[] = "dnsServers = '{$data['dnsservers']}'";
+			# usedbhostnames
+			if($data['usedbhostnames'] != $olddata['usedbhostnames'])
+			    $updates[] = "usedbhostnames = {$data['usedbhostnames']}";
 			if(count($updates)) {
 				$query = "UPDATE addomain SET "
 				       . implode(', ', $updates)
@@ -346,14 +349,16 @@
 				.	"username, "
 				.	"password, "
 				.	"secretid, "
-				.	"dnsServers) "
+				.	"dnsServers, "
+				.	"usedbhostnames) "
 				.	"VALUES ('{$data['name']}', "
 				.	"$ownerid, "
 				.	"'{$data['domaindnsname']}', "
 				.	"'{$data['username']}', "
 				.	"'$encpass', "
 				.	"$secretid, "
-				.	"'{$data['dnsservers']}')";
+				.	"'{$data['dnsservers']}', "
+				.	"'{$data['usedbhostnames']}')";
 		doQuery($query);
 
 		$rscid = dbLastInsertID();
@@ -423,14 +428,16 @@
 		$errmsg = i("Password must be at least 4 characters long");
 		$h .= labeledFormItem('password', i('Password'), 'password', '^.{4,256}$', 1, '', $errmsg, '', '', '200px'); 
 		# confirm password
-		$h .= labeledFormItem('password2', i('Confirm Password'), 'password', '', 1, '', '', '', '', '200px'); 
+		$h .= labeledFormItem('password2', i('Confirm Password'), 'password', '', 1, '', '', '', '', '200px');
+		# use database hostname checkbox
+		$h .= labeledFormItem('usedbhostnames', i('Use Database Hostnames'), 'check', '', '', '', '', '', '', '', helpIcon('usedbhostnameshelp'));
 		$h .= "<br>\n";
 		# dns server list
 		$ipreg = '(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)';
 		$reg = "^($ipreg,)*($ipreg)$";
 		$errmsg = i("Invalid IP address specified - must be a valid IPV4 address");
 		$h .= labeledFormItem('dnsservers', i('DNS Server(s)'), 'text', $reg, 0, '', $errmsg,
-		                      '', '', '300px', helpIcon('dnsservershelp')); 
+		                      '', '', '300px', helpIcon('dnsservershelp'));
 
 		$h .= "</div>\n"; # center
 		$h .= "</div>\n"; # addomaindlgcontent
@@ -473,6 +480,7 @@
 		$h .= helpTooltip('domaindnsnamehelp', i("domain name registered in DNS for Active Directory Domain (ex: ad.example.com)"));
 		$h .= helpTooltip('usernamehelp', i("These credentials will be used to register reserved computers with AD."));
 		$h .= helpTooltip('dnsservershelp', i("comma delimited list of IP addresses for DNS servers that handle Domain DNS"));
+		$h .= helpTooltip('usedbhostnameshelp', i("Check this option if you like to have the computer object names within AD to match VM hostname stored within the VCL database"));
 		$h .= "</div>\n"; # tooltips
 
 		return $h;
@@ -510,6 +518,7 @@
 		$return["password"] = $_POST['password'];
 		$return["password2"] = $_POST['password2'];
 		$return["dnsservers"] = processInputVar("dnsservers", ARG_STRING);
+		$return["usedbhostnames"] = processInputVar('usedbhostnames', ARG_NUMERIC, 0);
 
 		if(! preg_match("/^([A-Za-z0-9-!@#$%^&\*\(\)_=\+\[\]{}\\\|:;,\.\/\?~` ]){2,30}$/", $return['name'])) {
 			$return['error'] = 1;
@@ -519,10 +528,6 @@
 			$return['error'] = 1;
 			$errormsg[] = i("An AD domain already exists with this name.");
 		}
-		elseif($this->checkExistingField('domainDNSName', $return['domaindnsname'], $return['rscid'])) {
-			$return['error'] = 1;
-			$errormsg[] = i("An AD domain already exists with this Domain DNS Name.");
-		}
 		if(! validateUserid($return['owner'])) {
 			$return['error'] = 1;
 			$errormsg[] = i("Submitted owner is not valid");
@@ -558,6 +563,9 @@
 			}
 		}
 
+		if($return['usedbhostnames'] != 0 && $return['usedbhostnames'] != 1)
+			$return['usedbhostnames'] = 0;
+
 		if($return['error'])
 			$return['errormsg'] = implode('<br>', $errormsg);
 
@@ -586,7 +594,7 @@
 		       .       "ia.imageid = i.id";
 		$qh = doQuery($query);
 		$images = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$images[] = $row['prettyname'];
 		if(count($images))
 			$msg = "This AD Domain cannot be deleted because the following <strong>images</strong> are using it:<br><br>\n" . implode("<br>\n", $images);
diff --git a/web/.ht-inc/authentication.php b/web/.ht-inc/authentication.php
index 55b42bc..b2a3a80 100644
--- a/web/.ht-inc/authentication.php
+++ b/web/.ht-inc/authentication.php
@@ -19,13 +19,21 @@
 /**
  * \file
  */
+
+$authFuncs['local'] = array('test' => function() {return 0;},
+                            'auth' => function() {return NULL;},
+                            'unauth' => 'unauthLocal');
+
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \fn getAuthCookieData($loginid, $valid)
+/// \fn getAuthCookieData($loginid, $authtype, $valid, $shibauthid)
 ///
 /// \param $loginid - login id for user
+/// \param $authtype - type of authentication used; should be an index from the
+/// global $authFuncs array
 /// \param $valid - (optional, default=600) - time in minutes the cookie
 /// should be valid
+/// \param $shibauthid - (optional) id of shibboleth session
 ///
 /// \return on failure, an error message; on success, an array with 2 elements:\n
 /// data - encrypted payload for auth cookie\n
@@ -35,16 +43,16 @@
 /// a timestamp
 ///
 ////////////////////////////////////////////////////////////////////////////////
-function getAuthCookieData($loginid, $valid=600, $shibauthid=0) {
+function getAuthCookieData($loginid, $authtype, $valid=600, $shibauthid=0) {
 	global $keys;
 	$ts = time() + ($valid * 60);
 	$remoteIP = $_SERVER["REMOTE_ADDR"];
 	if(empty($remoteIP))
 		return "Failed to obtain remote IP address for fixed cookie type";
 	if($shibauthid)
-		$cdata = "$loginid|$remoteIP|$ts|$shibauthid";
+		$cdata = "$loginid|$remoteIP|$ts|$authtype|$shibauthid";
 	else
-		$cdata = "$loginid|$remoteIP|$ts";
+		$cdata = "$loginid|$remoteIP|$ts|$authtype";
 
 	# 245 characters can be encrypted; anything over that, and
 	#   openssl_private_encrypt will fail
@@ -76,22 +84,35 @@
 		$cookie = $_COOKIE["VCLAUTH"];
 	$cookie = base64_decode($cookie);
 	if(! openssl_public_decrypt($cookie, $tmp, $keys['public'])) {
+		# cookie is invalid; clear it and return NULL so will get redirected to log in again
+		setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
 		$AUTHERROR["code"] = 3;
 		$AUTHERROR["message"] = "Failed to decrypt auth cookie";
 		return NULL;
 	}
 
+	# $loginid|$remoteIP|$ts|$authtype|$shibauthid (shibauthd optional)
 	$tmparr = explode('|', $tmp);
 	$loginid = $tmparr[0];
 	$remoteIP = $tmparr[1];
 	$ts = $tmparr[2];
-	if(count($tmparr) > 3) {
-		$shibauthed = $tmparr[3];
+
+	# check for old style auth cookie before $authtype was included
+	if(count($tmparr) < 4 || is_numeric($tmparr[3])) {
+		# log user out to get new style auth cookie
+		setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
+		stopSession();
+		dbDisconnect();
+		header("Location: " . BASEURL);
+		exit;
+	}
+	if(count($tmparr) > 4) {
+		$shibauthed = $tmparr[5];
 
 		# check to see if shibauth entry still exists for $shibauthed
 		$query = "SELECT ts FROM shibauth WHERE id = $shibauthed";
 		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_assoc($qh)) {
+		if($row = mysqli_fetch_assoc($qh)) {
 			$shibstart = $row['ts'];
 			# TODO if $shibstart is too old, expire the login session
 		}
@@ -106,18 +127,60 @@
 	}
 
 	if($ts < time()) {
+		# cookie is expired; clear it and return NULL so will get redirected to log in again
+		setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
 		$AUTHERROR["code"] = 4;
 		$AUTHERROR["message"] = "Auth cookie has expired";
 		return NULL;
 	}
 	if($_SERVER["REMOTE_ADDR"] != $remoteIP) {
+		# cookie has wrong IP; clear it and return NULL so will get redirected to log in again
+		setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
+		$AUTHERROR["code"] = 4;
+		$AUTHERROR["message"] = "remote IP in auth cookie doesn't match user's remote IP";
+		return NULL;
+	}
+
+	return $loginid;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getAuthTypeFromAuthCookie()
+///
+/// \return on success, type of authentication used; NULL on failure
+///
+/// \brief parses the VCLAUTH cookie to get the authtype saved in it
+///
+////////////////////////////////////////////////////////////////////////////////
+function getAuthTypeFromAuthCookie() {
+	global $keys, $AUTHERROR;
+	if(! array_key_exists('VCLAUTH', $_COOKIE))
+		return NULL;
+	if(get_magic_quotes_gpc())
+		$cookie = stripslashes($_COOKIE["VCLAUTH"]);
+	else
+		$cookie = $_COOKIE["VCLAUTH"];
+	$cookie = base64_decode($cookie);
+	if(! openssl_public_decrypt($cookie, $tmp, $keys['public'])) {
+		$AUTHERROR["code"] = 3;
+		$AUTHERROR["message"] = "Failed to decrypt auth cookie";
+		return NULL;
+	}
+
+	# $loginid|$remoteIP|$ts|$authtype|$shibauthid (shibauthd optional)
+	$tmparr = explode('|', $tmp);
+	$remoteIP = $tmparr[1];
+	$authtype = $tmparr[3];
+
+	if($_SERVER["REMOTE_ADDR"] != $remoteIP) {
 		//setcookie("ITECSAUTH", "", time() - 10, "/", COOKIEDOMAIN);
 		$AUTHERROR["code"] = 4;
 		$AUTHERROR["message"] = "remote IP in auth cookie doesn't match user's remote IP";
 		return NULL;
 	}
 
-	return $loginid;
+	return $authtype;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -356,120 +419,6 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \fn ldapLogin($authtype, $userid, $passwd)
-///
-/// \param $authtype - index from $authMechs array
-/// \param $userid - userid without affiliation
-/// \param $passwd - submitted password
-///
-/// \brief tries to authenticate user via ldap; calls printLoginPageWithSkin if
-/// authentication fails
-///
-////////////////////////////////////////////////////////////////////////////////
-function ldapLogin($authtype, $userid, $passwd) {
-	global $HTMLheader, $printedHTMLheader, $authMechs, $phpVer;
-	$esc_userid = mysql_real_escape_string($userid);
-	if(! $fh = fsockopen($authMechs[$authtype]['server'], 636, $errno, $errstr, 5)) {
-		printLoginPageWithSkin($authtype, 1);
-		return;
-	}
-	fclose($fh);
-	$ds = ldap_connect("ldaps://{$authMechs[$authtype]['server']}/");
-	if(! $ds) {
-		addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 0);
-		print $HTMLheader;
-		$printedHTMLheader = 1;
-		selectAuth();
-		return;
-	}
-	ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
-	ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
-	if(array_key_exists('lookupuserbeforeauth', $authMechs[$authtype]) &&
-	   $authMechs[$authtype]['lookupuserbeforeauth'] &&
-	   array_key_exists('lookupuserfield', $authMechs[$authtype])) {
-		# in this case, we have to look up what part of the tree the user is in
-		#   before we can actually look up the user
-		$auth = $authMechs[$authtype];
-		if(array_key_exists('masterlogin', $auth) && strlen($auth['masterlogin']))
-			$res = ldap_bind($ds, $auth['masterlogin'], $auth['masterpwd']);
-		else
-			$res = ldap_bind($ds);
-		if(! $res) {
-			addLoginLog($userid, $authtype, $auth['affiliationid'], 0);
-			printLoginPageWithSkin($authtype);
-			return;
-		}
-		$search = ldap_search($ds,
-		                      $auth['binddn'], 
-		                      "{$auth['lookupuserfield']}=$userid",
-		                      array('dn'), 0, 3, 15);
-		if($search) {
-			$tmpdata = ldap_get_entries($ds, $search);
-			if(! $tmpdata['count'] || ! array_key_exists('dn', $tmpdata[0])) {
-				addLoginLog($userid, $authtype, $auth['affiliationid'], 0);
-				printLoginPageWithSkin($authtype);
-				return;
-			}
-			$ldapuser = $tmpdata[0]['dn'];
-		}
-		else {
-			addLoginLog($userid, $authtype, $auth['affiliationid'], 0);
-			printLoginPageWithSkin($authtype);
-			return;
-		}
-	}
-	else
-		$ldapuser = sprintf($authMechs[$authtype]['userid'], $userid);
-	$res = ldap_bind($ds, $ldapuser, $passwd);
-	if(! $res) {
-		// login failed
-		$err = ldap_error($ds);
-		if($err == 'Invalid credentials')
-			addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 0, $err);
-		else
-			addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 0);
-		printLoginPageWithSkin($authtype);
-		return;
-	}
-	else {
-		addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 1);
-		# used to rely on later code to update user info if update timestamp was expired
-		// see if user in our db
-		/*$query = "SELECT id "
-		       . "FROM user "
-		       . "WHERE unityid = '$esc_userid' AND "
-		       .       "affiliationid = {$authMechs[$authtype]['affiliationid']}";
-		$qh = doQuery($query, 101);
-		if(! mysql_num_rows($qh)) {
-			// if not, add user
-			$newid = updateLDAPUser($authtype, $userid);
-			if(is_null($newid))
-				abort(8);
-		}*/
-		# now, we always update the user info
-		$newid = updateLDAPUser($authtype, $userid);
-		if(is_null($newid))
-			abort(8);
-		// get cookie data
-		$cookie = getAuthCookieData("$userid@" . getAffiliationName($authMechs[$authtype]['affiliationid']));
-		// set cookie
-		if(version_compare(PHP_VERSION, "5.2", ">=") == true)
-			setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0, 1);
-		else
-			setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0);
-		# set skin cookie based on affiliation
-		$skin = getAffiliationTheme($authMechs[$authtype]['affiliationid']);
-		$ucskin = strtoupper($skin);
-		setcookie("VCLSKIN", "$ucskin", (time() + (SECINDAY * 31)), "/", COOKIEDOMAIN);
-		// redirect to main page
-		header("Location: " . BASEURL . SCRIPT);
-		dbDisconnect();
-		exit;
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-///
 /// \fn localLogin($userid, $passwd, $authtype)
 ///
 /// \param $userid - userid without affiliation
@@ -485,7 +434,7 @@
 	if(validateLocalAccount($userid, $passwd)) {
 		addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 1);
 		//set cookie
-		$cookie = getAuthCookieData("$userid@local");
+		$cookie = getAuthCookieData("$userid@local", 'local');
 		if(version_compare(PHP_VERSION, "5.2", ">=") == true)
 			setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0, 1);
 		else
@@ -508,6 +457,24 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
+/// \fn unauthLocal
+///
+/// \param $mode - headers or content
+///
+/// \brief for headers, simply returns; for content, prints information that
+/// user has been logged out; VCLAUTH cookie is cleared elsewhere
+///
+////////////////////////////////////////////////////////////////////////////////
+function unauthLocal($mode) {
+	if($mode == 'headers')
+		return;
+	print "<h2>Logout</h2>\n";
+	print "You are now logged out of VCL.<br><br>\n";
+	print "<a href=\"" . BASEURL . SCRIPT . "?mode=selectauth\">Return to Login</a><br><br><br>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
 /// \fn validateLocalAccount($user, $pass)
 ///
 /// \param $user - unityid from user table
@@ -519,7 +486,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function validateLocalAccount($user, $pass) {
-	$user = mysql_real_escape_string($user);
+	$user = vcl_mysql_escape_string($user);
 	$query = "SELECT l.salt "
 	       . "FROM localauth l, "
 	       .      "user u, "
@@ -529,8 +496,8 @@
 	       .       "a.name = 'Local' AND "
 	       .       "l.userid = u.id";
 	$qh = doQuery($query, 101);
-	if(mysql_num_rows($qh) != 1 ||
-	   (! ($row = mysql_fetch_assoc($qh))))
+	if(mysqli_num_rows($qh) != 1 ||
+	   (! ($row = mysqli_fetch_assoc($qh))))
 		return 0;
 
 	$passhash = sha1("$pass{$row['salt']}");
@@ -544,7 +511,7 @@
 	       .       "u.affiliationid = a.id AND "
 	       .       "a.name = 'Local'";
 	$qh = doQuery($query, 101);
-	if(mysql_num_rows($qh) == 1)
+	if(mysqli_num_rows($qh) == 1)
 		return 1;
 	else
 		return 0;
@@ -564,8 +531,8 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function addLoginLog($login, $mech, $affiliationid, $passfail, $code='none') {
-	$login = mysql_real_escape_string($login);
-	$mech = mysql_real_escape_string($mech);
+	$login = vcl_mysql_escape_string($login);
+	$mech = vcl_mysql_escape_string($mech);
 	$query = "INSERT INTO loginlog "
 	       .        "(user, "
 	       .        "authmech, "
@@ -618,8 +585,8 @@
 	       . "LIMIT 3";
 	$qh = doQuery($query, 101);
 	$expire = time() - (SECINDAY * 3);
-	$rows = mysql_num_rows($qh);
-	if($row = mysql_fetch_assoc($qh)) {
+	$rows = mysqli_num_rows($qh);
+	if($row = mysqli_fetch_assoc($qh)) {
 		if($rows >= 3 || datetimeToUnix($row['start']) < $expire) {
 			if(in_array($mode, $noHTMLwrappers))
 				# do a redirect and handle removal on next page load so user can
diff --git a/web/.ht-inc/authmethods/itecsauth.php b/web/.ht-inc/authmethods/itecsauth.php
index ccdb9a4..a271450 100644
--- a/web/.ht-inc/authmethods/itecsauth.php
+++ b/web/.ht-inc/authmethods/itecsauth.php
@@ -22,6 +22,79 @@
  * \file
  */
 
+$authFuncs['itecs'] = array('test' => 'testITECSAuth',
+                            'auth' => 'processITECSAuth',
+                            'unauth' => 'unauthITECS');
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn testITECSAuth()
+///
+/// \return 1 if ITECSAUTH cookie found, 0 if not
+///
+/// \brief tests for existance of authentication information for ITECS auth
+///
+////////////////////////////////////////////////////////////////////////////////
+function testITECSAuth() {
+	if(array_key_exists('ITECSAUTH', $_COOKIE))
+		return 1;
+	return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn processITECSAuth()
+///
+/// \return userid in form of emailaddress@ITECS or NULL
+///
+/// \brief processes authentication information; returns userid or NULL if
+/// unsuccessful
+///
+////////////////////////////////////////////////////////////////////////////////
+function processITECSAuth() {
+	$authdata = authUser();
+	if(! ($error = getAuthError())) {
+		$userid = "{$authdata["email"]}@ITECS";
+		$affilid = getAffiliationID('ITECS');
+		addLoginLog($userid, 'ITECS', $affilid, 1);
+
+		# get cookie data
+		$cookie = getAuthCookieData($userid, 'itecs', 600);
+		# set cookie
+		if(version_compare(PHP_VERSION, "5.2", ">=") == true)
+			setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0, 1);
+		else
+			setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN);
+
+		return $userid;
+	}
+	return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn unauthITECS($mode)
+///
+/// \param $mode - headers or content
+///
+/// \brief for headers mode, destroys authentication information; for content
+/// mode, prints information about having been logged out
+///
+////////////////////////////////////////////////////////////////////////////////
+function unauthITECS($mode) {
+	if($mode == 'headers') {
+		$time = time() - 10;
+		setcookie("ITECSAUTH_RETURN", "", $time, "/", COOKIEDOMAIN);
+		setcookie("ITECSAUTH_CSS", "", $time, "/", COOKIEDOMAIN);
+		setcookie("ITECSAUTH", "", $time, "/", COOKIEDOMAIN);
+	}
+	elseif($mode == 'content') {
+		print "<h2>Logout</h2>\n";
+		print "You are now logged out of VCL.<br><br>\n";
+		print "<a href=\"" . BASEURL . SCRIPT . "?mode=selectauth\">Return to Login</a><br><br><br>\n";
+	}
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// \fn addITECSUser($loginid)
@@ -35,10 +108,10 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function addITECSUser($loginid) {
-	global $mysql_link_vcl, $ENABLE_ITECSAUTH;
+	global $mysqli_link_vcl, $ENABLE_ITECSAUTH;
 	if(! $ENABLE_ITECSAUTH)
 		return NULL;
-	$esc_loginid = mysql_real_escape_string($loginid);
+	$esc_loginid = vcl_mysql_escape_string($loginid);
 	$query = "SELECT id AS uid, "
 	       .        "first, " 
 	       .        "last, "
@@ -49,13 +122,13 @@
 	       . "FROM user "
 	       . "WHERE email = '$esc_loginid'";
 	$qh = doQuery($query, 101, "accounts");
-	if($row = mysql_fetch_assoc($qh)) {
+	if($row = mysqli_fetch_assoc($qh)) {
 		// FIXME test replacing ''s
 		// FIXME do we care if the account is active?
-		$first = mysql_real_escape_string($row['first']);
-		$last = mysql_real_escape_string($row['last']);
-		$loweruser = mysql_real_escape_string(strtolower($row['email']));
-		$email = mysql_real_escape_string($row['email']);
+		$first = vcl_mysql_escape_string($row['first']);
+		$last = vcl_mysql_escape_string($row['last']);
+		$loweruser = vcl_mysql_escape_string(strtolower($row['email']));
+		$email = vcl_mysql_escape_string($row['email']);
 		$query = "INSERT INTO user ("
 		       .        "uid, "
 		       .        "unityid, "
@@ -79,9 +152,9 @@
 		// FIXME might want this logged
 		doQuery($query, 101, 'vcl', 1);
 	}
-	if(mysql_affected_rows($mysql_link_vcl)) {
+	if(mysqli_affected_rows($mysqli_link_vcl)) {
 		$qh = doQuery("SELECT LAST_INSERT_ID() FROM user", 101);
-		if(! $row = mysql_fetch_row($qh)) {
+		if(! $row = mysqli_fetch_row($qh)) {
 			abort(101);
 		}
 		return $row[0];
@@ -104,14 +177,14 @@
 	global $ENABLE_ITECSAUTH;
 	if(! $ENABLE_ITECSAUTH)
 		return 0;
-	$loginid = mysql_real_escape_string($loginid);
+	$loginid = vcl_mysql_escape_string($loginid);
 	$query = "SELECT email "
 	       . "FROM user "
 	       . "WHERE email = '$loginid' AND "
 	       .       "(active = 1 OR "
 	       .       "activated = 0)";
 	$qh = doQuery($query, 101, "accounts");
-	if(mysql_num_rows($qh))
+	if(mysqli_num_rows($qh))
 		return 1;
 	return 0;
 }
@@ -160,7 +233,7 @@
 	       . "FROM user "
 	       . "WHERE email = '$userid'";
 	$qh = doQuery($query, 101, "accounts");
-	if(! ($userData = mysql_fetch_assoc($qh)))
+	if(! ($userData = mysqli_fetch_assoc($qh)))
 		return NULL;
 
 	$now = unixToDatetime(time());
@@ -191,11 +264,11 @@
 	// if get a row
 	//    update db
 	//    update results from select
-	$esc_userid = mysql_real_escape_string($userid);
-	$first = mysql_real_escape_string($userData['first']);
-	$last = mysql_real_escape_string($userData['last']);
-	$email = mysql_real_escape_string($userData['email']);
-	if($user = mysql_fetch_assoc($qh)) {
+	$esc_userid = vcl_mysql_escape_string($userid);
+	$first = vcl_mysql_escape_string($userData['first']);
+	$last = vcl_mysql_escape_string($userData['last']);
+	$email = vcl_mysql_escape_string($userData['email']);
+	if($user = mysqli_fetch_assoc($qh)) {
 		$user["unityid"] = $userid;
 		$user["firstname"] = $userData['first'];
 		$user["lastname"] = $userData["last"];
@@ -240,7 +313,7 @@
 		       . "WHERE u.affiliationid = af.id AND "
 		       .       "u.id = $id";
 		$qh = doQuery($query, 101);
-		$user = mysql_fetch_assoc($qh);
+		$user = mysqli_fetch_assoc($qh);
 
 		# add account to demo group
 		#$demoid = getUserGroupID('demo', getAffiliationID('ITECS'));
diff --git a/web/.ht-inc/authmethods/ldapauth.php b/web/.ht-inc/authmethods/ldapauth.php
index cf415c3..1c2ee53 100644
--- a/web/.ht-inc/authmethods/ldapauth.php
+++ b/web/.ht-inc/authmethods/ldapauth.php
@@ -20,6 +20,143 @@
  * \file
  */
 
+$authFuncs['ldap'] = array('test' => function() {return 0;},
+                           'auth' => function() {return NULL;},
+                           'unauth' => 'unauthLDAP');
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn unauthLDAP($mode)
+///
+/// \param $mode - headers or content
+///
+/// \brief for headers, simply returns; for content, prints information that
+/// user has been logged out; VCLAUTH cookie is cleared elsewhere
+///
+////////////////////////////////////////////////////////////////////////////////
+function unauthLDAP($mode) {
+	if($mode == 'headers')
+		return;
+	print "<h2>" . _('Logout') . "</h2>\n";
+	print _("You are now logged out of VCL.") . "<br><br>\n";
+	print "<a href=\"" . BASEURL . SCRIPT . "?mode=selectauth\">" . _("Return to Login");
+	print "</a><br><br><br>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn ldapLogin($authtype, $userid, $passwd)
+///
+/// \param $authtype - index from $authMechs array
+/// \param $userid - userid without affiliation
+/// \param $passwd - submitted password
+///
+/// \brief tries to authenticate user via ldap; calls printLoginPageWithSkin if
+/// authentication fails
+///
+////////////////////////////////////////////////////////////////////////////////
+function ldapLogin($authtype, $userid, $passwd) {
+	global $HTMLheader, $printedHTMLheader, $authMechs, $phpVer;
+	$esc_userid = vcl_mysql_escape_string($userid);
+	if(! $fh = fsockopen($authMechs[$authtype]['server'], 636, $errno, $errstr, 5)) {
+		printLoginPageWithSkin($authtype, 1);
+		return;
+	}
+	fclose($fh);
+	$ds = ldap_connect("ldaps://{$authMechs[$authtype]['server']}/");
+	if(! $ds) {
+		addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 0);
+		print $HTMLheader;
+		$printedHTMLheader = 1;
+		selectAuth();
+		return;
+	}
+	ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
+	ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
+	if(array_key_exists('lookupuserbeforeauth', $authMechs[$authtype]) &&
+	   $authMechs[$authtype]['lookupuserbeforeauth'] &&
+	   array_key_exists('lookupuserfield', $authMechs[$authtype])) {
+		# in this case, we have to look up what part of the tree the user is in
+		#   before we can actually look up the user
+		$auth = $authMechs[$authtype];
+		if(array_key_exists('masterlogin', $auth) && strlen($auth['masterlogin']))
+			$res = ldap_bind($ds, $auth['masterlogin'], $auth['masterpwd']);
+		else
+			$res = ldap_bind($ds);
+		if(! $res) {
+			addLoginLog($userid, $authtype, $auth['affiliationid'], 0);
+			printLoginPageWithSkin($authtype);
+			return;
+		}
+		$search = ldap_search($ds,
+		                      $auth['binddn'], 
+		                      "{$auth['lookupuserfield']}=$userid",
+		                      array('dn'), 0, 3, 15);
+		if($search) {
+			$tmpdata = ldap_get_entries($ds, $search);
+			if(! $tmpdata['count'] || ! array_key_exists('dn', $tmpdata[0])) {
+				addLoginLog($userid, $authtype, $auth['affiliationid'], 0);
+				printLoginPageWithSkin($authtype);
+				return;
+			}
+			$ldapuser = $tmpdata[0]['dn'];
+		}
+		else {
+			addLoginLog($userid, $authtype, $auth['affiliationid'], 0);
+			printLoginPageWithSkin($authtype);
+			return;
+		}
+	}
+	else
+		$ldapuser = sprintf($authMechs[$authtype]['userid'], $userid);
+	$res = ldap_bind($ds, $ldapuser, $passwd);
+	if(! $res) {
+		// login failed
+		$err = ldap_error($ds);
+		if($err == 'Invalid credentials')
+			addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 0, $err);
+		else
+			addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 0);
+		printLoginPageWithSkin($authtype);
+		return;
+	}
+	else {
+		addLoginLog($userid, $authtype, $authMechs[$authtype]['affiliationid'], 1);
+		# used to rely on later code to update user info if update timestamp was expired
+		// see if user in our db
+		/*$query = "SELECT id "
+		       . "FROM user "
+		       . "WHERE unityid = '$esc_userid' AND "
+		       .       "affiliationid = {$authMechs[$authtype]['affiliationid']}";
+		$qh = doQuery($query, 101);
+		if(! mysqli_num_rows($qh)) {
+			// if not, add user
+			$newid = updateLDAPUser($authtype, $userid);
+			if(is_null($newid))
+				abort(8);
+		}*/
+		# now, we always update the user info
+		$newid = updateLDAPUser($authtype, $userid);
+		if(is_null($newid))
+			abort(8);
+		// get cookie data
+		$cookie = getAuthCookieData("$userid@" . getAffiliationName($authMechs[$authtype]['affiliationid']), 'ldap');
+		// set cookie
+		if(version_compare(PHP_VERSION, "5.2", ">=") == true)
+			setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0, 1);
+		else
+			setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0);
+		# set skin cookie based on affiliation
+		$skin = getAffiliationTheme($authMechs[$authtype]['affiliationid']);
+		$ucskin = strtoupper($skin);
+		setcookie("VCLSKIN", "$ucskin", (time() + (SECINDAY * 31)), "/", COOKIEDOMAIN);
+		// redirect to main page
+		header("Location: " . BASEURL . SCRIPT);
+		dbDisconnect();
+		exit;
+	}
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// \fn addLDAPUser($authtype, $userid)
@@ -34,13 +171,13 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function addLDAPUser($authtype, $userid) {
-	global $authMechs, $mysql_link_vcl;
+	global $authMechs, $mysqli_link_vcl;
 	$data = getLDAPUserData($authtype, $userid);
 	if(is_null($data))
 		return NULL;
 
 	$loweruserid = strtolower($userid);
-	$loweruserid = mysql_real_escape_string($loweruserid);
+	$loweruserid = vcl_mysql_escape_string($loweruserid);
 
 	# check for existance of an expired user if a numericid exists
 	if(array_key_exists('numericid', $data)) {
@@ -53,7 +190,7 @@
 		       .       "unityid != '$loweruserid'";
 		       #.       "affiliationid = {$authMechs[$authtype]['affiliationid']}";
 		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_assoc($qh)) {
+		if($row = mysqli_fetch_assoc($qh)) {
 			# find the authtype for this user
 			foreach($authMechs as $index => $auth) {
 				if($auth['affiliationid'] == $row['affiliationid'] &&
@@ -95,9 +232,9 @@
 	       .        "'{$data['emailnotices']}', "
 	       .        "NOW())";
 	doQuery($query, 101, 'vcl', 1);
-	if(mysql_affected_rows($mysql_link_vcl)) {
+	if(mysqli_affected_rows($mysqli_link_vcl)) {
 		$qh = doQuery("SELECT LAST_INSERT_ID() FROM user", 101);
-		if(! $row = mysql_fetch_row($qh)) {
+		if(! $row = mysqli_fetch_row($qh)) {
 			abort(101);
 		}
 		return $row[0];
@@ -171,7 +308,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 function updateLDAPUser($authtype, $userid) {
 	global $authMechs;
-	$esc_userid = mysql_real_escape_string($userid);
+	$esc_userid = vcl_mysql_escape_string($userid);
 	$userData = getLDAPUserData($authtype, $userid);
 	if(is_null($userData))
 		return NULL;
@@ -213,7 +350,7 @@
 	# check to see if there is a matching entry where uid is NULL but unityid and affiliationid match
 	if(array_key_exists('numericid', $userData) &&
 	   is_numeric($userData['numericid']) &&
-	   ! mysql_num_rows($qh)) {
+	   ! mysqli_num_rows($qh)) {
 		$updateuid = 1;
 		$query = $qbase . "u.unityid = '$esc_userid' AND "
 		       .          "u.affiliationid = $affilid";
@@ -222,7 +359,7 @@
 	// if get a row
 	//    update db
 	//    update results from select
-	if($user = mysql_fetch_assoc($qh)) {
+	if($user = mysqli_fetch_assoc($qh)) {
 		$user["unityid"] = $userid;
 		$user["firstname"] = $userData['first'];
 		$user["lastname"] = $userData["last"];
@@ -277,7 +414,7 @@
 		       . "WHERE u.affiliationid = af.id AND "
 		       .       "u.id = $id";
 		$qh = doQuery($query, 101);
-		if(! $user = mysql_fetch_assoc($qh))
+		if(! $user = mysqli_fetch_assoc($qh))
 			return NULL;
 		$user['sshpublickeys'] = htmlspecialchars($user['sshpublickeys']);
 	}
@@ -305,9 +442,9 @@
 /// \param $userid - a userid without the affiliation part
 ///
 /// \return an array of user information with the following keys:\n
-/// \b first - first name of user (escaped with mysql_real_escape_string)\n
-/// \b last - last name of user (escaped with mysql_real_escape_string)\n
-/// \b email - email address of user (escaped with mysql_real_escape_string)\n
+/// \b first - first name of user (escaped with vcl_mysql_escape_string)\n
+/// \b last - last name of user (escaped with vcl_mysql_escape_string)\n
+/// \b email - email address of user (escaped with vcl_mysql_escape_string)\n
 /// \b emailnotices - 0 or 1, whether or not emails should be sent to user\n
 /// \b numericid - numeric id of user if $authtype is configured to include it
 ///
@@ -315,7 +452,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function getLDAPUserData($authtype, $userid) {
-	global $authMechs, $mysql_link_vcl;
+	global $authMechs, $mysqli_link_vcl;
 	$auth = $authMechs[$authtype];
 	$donumericid = 0;
 	if(array_key_exists('numericid', $auth))
@@ -392,16 +529,16 @@
 		}
 
 		if(array_key_exists(strtolower($auth['firstname']), $data))
-			$return['first'] = mysql_real_escape_string($data[strtolower($auth['firstname'])]);
+			$return['first'] = vcl_mysql_escape_string($data[strtolower($auth['firstname'])]);
 		else
 			$return['first'] = '';
 		if(array_key_exists(strtolower($auth['lastname']), $data))
-			$return['last'] = mysql_real_escape_string($data[strtolower($auth['lastname'])]);
+			$return['last'] = vcl_mysql_escape_string($data[strtolower($auth['lastname'])]);
 		else
 			$return['last'] = '';
 		if($donumericid && is_numeric($data[strtolower($auth['numericid'])]))
 			$return['numericid'] = $data[strtolower($auth['numericid'])];
-		$return['email'] = mysql_real_escape_string($data[strtolower($auth['email'])]);
+		$return['email'] = vcl_mysql_escape_string($data[strtolower($auth['email'])]);
 
 		return $return;
 	}
diff --git a/web/.ht-inc/authmethods/shibauth.php b/web/.ht-inc/authmethods/shibauth.php
index c814925..947035e 100644
--- a/web/.ht-inc/authmethods/shibauth.php
+++ b/web/.ht-inc/authmethods/shibauth.php
@@ -20,6 +20,286 @@
  * \file
  */
 
+$authFuncs['shibboleth'] = array('test' => 'testShibAuth',
+                                 'auth' => 'processShibAuth',
+                                 'unauth' => 'unauthShib');
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn testShibAuth()
+///
+/// \returns 1 if SHIB_EPPN found in $_SERVER; 0 otherwise
+///
+/// \brief checks for authentication information related to Shibboleth
+///
+////////////////////////////////////////////////////////////////////////////////
+function testShibAuth() {
+	// TODO check for other shib variables, if found but EPPN not found, alert user that EPPN is not being released
+	if(array_key_exists('SHIB_EPPN', $_SERVER))
+		return 1;
+	return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn processShibAuth()
+///
+/// \returns userid in userid@AFFILIATION form
+///
+/// \brief processes Shibboleth authentication information
+///
+////////////////////////////////////////////////////////////////////////////////
+function processShibAuth() {
+	# get VCL affiliation from shib affiliation
+	$tmp = explode(';', $_SERVER['SHIB_EPPN']);
+	$tmp = explode('@', $tmp[0]);
+	$username = strtolower($tmp[0]);
+	$shibaffil = vcl_mysql_escape_string(strtolower($tmp[1]));
+	$query = "SELECT name, shibonly FROM affiliation WHERE shibname = '$shibaffil'";
+	$qh = doQuery($query, 101);
+	# if shib affiliation not already in VCL, create affiliation
+	if(! ($row = mysqli_fetch_assoc($qh))) {
+		$affil = strtolower($tmp[1]);
+		$tmp = explode('.', $affil);
+		array_pop($tmp);
+		$affilname = strtoupper(implode('', $tmp));
+		$affilname = preg_replace('/[^A-Z0-9]/', '', $affilname);
+		$query = "SELECT name, "
+				 .        "shibname "
+				 . "FROM affiliation "
+				 . "WHERE name LIKE '$affilname%' "
+				 . "ORDER BY name DESC "
+				 . "LIMIT 1";
+		$qh = doQuery($query, 101);
+		if($row = mysqli_fetch_assoc($qh)) {
+			if(preg_match("/$affilname([0-9]+)/", $row['name'], $matches)) {
+				$cnt = $matches[1];
+				$cnt++;
+				$newaffilname = $affilname . $cnt;
+			}
+			elseif($affilname != strtoupper($row['name']) && $affil != $row['shibname']) {
+				$newaffilname = $affilname;
+			}
+			else {
+				$msg = "Someone tried to log in to VCL using Shibboleth from an IdP "
+					  . "affiliation that could not be automatically added.\n\n"
+					  . "eppn: {$_SERVER['SHIB_EPPN']}\n"
+					  . "givenName: {$_SERVER['SHIB_GIVENNAME']}\n"
+					  . "sn: {$_SERVER['SHIB_SN']}\n";
+				if(array_key_exists('SHIB_MAIL', $_SERVER))
+					$msg .= "mail: {$_SERVER['SHIB_MAIL']}\n\n";
+				$msg .="tried to add VCL affiliation name \"$affilname\" with "
+					  . "shibname \"$affil\"";
+				$mailParams = "-f" . ENVELOPESENDER;
+				mail(ERROREMAIL, "Error with VCL pages (problem adding shib affil)", $msg, '', $mailParams);
+				print "<html><head></head><body>\n";
+				print "<h2>Error encountered</h2>\n";
+				print "You have attempted to log in to VCL using a Shibboleth<br>\n";
+				print "Identity Provider that VCL has not been configured to<br>\n";
+				print "work with. VCL administrators have been notified of the<br>\n";
+				print "problem.<br>\n";
+				print "</body></html>\n";
+				dbDisconnect();
+				exit;
+			}
+		}
+		else
+			$newaffilname = $affilname;
+		$query = "INSERT INTO affiliation "
+				 .        "(name, "
+				 .        "shibname, "
+				 .        "shibonly) "
+				 . "VALUES "
+				 .        "('$newaffilname', "
+				 .        "'" . vcl_mysql_escape_string($affil) . "', "
+				 .        "1)";
+		doQuery($query, 101, 'vcl', 1);
+		unset($row);
+		$row = array('name' => $newaffilname, 'shibonly' => 1);
+	}
+	$affil = $row['name'];
+	$affilid = getAffiliationID($affil);
+
+	# create VCL userid
+	$userid = "$username@$affil";
+
+	if($row['shibonly']) {
+		$userdata = updateShibUser($userid);
+		if(array_key_exists('SHIB_AFFILIATION', $_SERVER))
+			$groups = $_SERVER['SHIB_AFFILIATION'];
+		else
+			$groups = array('shibaffil' => $shibaffil);
+		updateShibGroups($userdata['id'], $groups);
+		$usernid = $userdata['id'];
+	}
+	else {
+		$usernid = getUserlistID($userid, 1);
+		# NCSU specific
+		if(is_null($userid) && $affil == 'NCSU') {
+			$tmp = updateLDAPUser('NCSU LDAP', $username);
+			$usernid = $tmp['id'];
+		}
+		/*if($affil == 'NCSU') {
+			if(array_key_exists('SHIB_AFFILIATION', $_SERVER))
+				$groups = $_SERVER['SHIB_AFFILIATION'];
+			else
+				$groups = array('shibaffil' => $shibaffil);
+			updateShibGroups($usernid, $groups);
+		}*/
+		# end NCSU specific
+		if(is_null($usernid)) {
+			$tmp = updateShibUser($userid);
+			$usernid = $tmp['id'];
+			# call this so that user groups get correctly populated
+			updateUserData($usernid, "numeric", $affilid);
+		}
+	}
+
+	addLoginLog($userid, 'shibboleth', $affilid, 1);
+
+	if($affil == 'UNCG') {
+		$gid = getUserGroupID('All UNCG Users', $affilid);
+		$query = "INSERT IGNORE INTO usergroupmembers "
+				 . "(userid, usergroupid) "
+				 . "VALUES ($usernid, $gid)";
+		doQuery($query, 307);
+	}
+
+	if(array_key_exists('SHIB_LOGOUTURL', $_SERVER))
+		$logouturl = $_SERVER['SHIB_LOGOUTURL'];
+	else
+		$logouturl = '';
+
+	# save data to shibauth table
+	$shibdata = array('Shib-Application-ID' => $_SERVER['Shib-Application-ID'],
+							'Shib-Identity-Provider' => $_SERVER['Shib-Identity-Provider'],
+							#'Shib-AuthnContext-Dec' => $_SERVER['Shib-AuthnContext-Decl'],
+							'SHIB_LOGOUTURL' => $logouturl,
+							'SHIB_EPPN' => $_SERVER['SHIB_EPPN'],
+							#'SHIB_UNAFFILIATION' => $_SERVER['SHIB_UNAFFILIATION'],
+							'SHIB_AFFILIATION' => $_SERVER['SHIB_AFFILIATION'],
+	);
+	$serdata = vcl_mysql_escape_string(serialize($shibdata));
+	$query = "SELECT id "
+			 . "FROM shibauth "
+			 . "WHERE sessid = '{$_SERVER['Shib-Session-ID']}'";
+	$qh = doQuery($query, 101);
+	if($row = mysqli_fetch_assoc($qh)) {
+		$shibauthid = $row['id'];
+	}
+	else {
+		$ts = strtotime($_SERVER['Shib-Authentication-Instant']);
+		$ts = unixToDatetime($ts);
+		$query = "INSERT INTO shibauth "
+				 .        "(userid, " 
+				 .        "ts, "
+				 .        "sessid, "
+				 .        "data) "
+				 . "VALUES "
+				 .        "($usernid, "
+				 .        "'$ts', "
+				 .        "'{$_SERVER['Shib-Session-ID']}', "
+				 .        "'$serdata')";
+		doQuery($query, 101);
+		$qh = doQuery("SELECT LAST_INSERT_ID()", 101);
+		if(! $row = mysqli_fetch_row($qh)) {
+			# todo
+		}
+		$shibauthid = $row[0];
+	}
+
+	# get cookie data
+	$cookie = getAuthCookieData($userid, 'shibboleth', 600, $shibauthid);
+	# set cookie
+	if(version_compare(PHP_VERSION, "5.2", ">=") == true)
+		#setcookie("VCLAUTH", "{$cookie['data']}", $cookie['ts'], "/", COOKIEDOMAIN, 1, 1);
+		setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0, 1);
+	else
+		#setcookie("VCLAUTH", "{$cookie['data']}", $cookie['ts'], "/", COOKIEDOMAIN, 1);
+		setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN);
+
+	# TODO do something to set VCLSKIN cookie based on affiliation
+
+	return $userid;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn unauthShib($mode)
+///
+/// \param $mode - headers or content
+//
+/// \brief for headers, simply returns; for content, prints information that
+/// user has been logged out and an iframe to log user out of Shibboleth if
+/// SHIB_LOGOUTURL was provided; VCLAUTH cookie is cleared elsewhere
+///
+////////////////////////////////////////////////////////////////////////////////
+function unauthShib($mode) {
+	global $user;
+	if($mode == 'headers')
+		return;
+
+	print "<h2>Logout</h2>\n";
+	print "You are now logged out of VCL and other Shibboleth authenticated web sites.<br><br>\n";
+	print "<a href=\"" . BASEURL . SCRIPT . "?mode=selectauth\">Return to Login</a><br><br><br>\n";
+	print "<iframe src=\"https://{$_SERVER['SERVER_NAME']}/Shibboleth.sso/Logout\" class=hidden>\n";
+	print "</iframe>\n";
+	if(array_key_exists('SHIB_LOGOUTURL', $_SERVER)) {
+	  	print "<iframe src=\"{$_SERVER['SHIB_LOGOUTURL']}\" class=hidden>\n";
+		print "</iframe>\n";
+	}
+	$shibdata = getShibauthDataByUser($user['id']);
+	if(array_key_exists('Shib-Identity-Provider', $shibdata) &&
+		! empty($shibdata['Shib-Identity-Provider'])) {
+		$tmp = explode('/', $shibdata['Shib-Identity-Provider']);
+		$idp = "{$tmp[0]}//{$tmp[2]}";
+		print "<iframe src=\"$idp/idp/logout.jsp\" class=hidden>\n";
+		print "</iframe>\n";
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getShibauthDataByUser($userid)
+///
+/// \param $userid - numeric id of a user
+///
+/// \return NULL if id not found in table or array of data with these keys:\n
+/// \b userid - id of user that data belongs to\n
+/// \b ts - datetime of when authdata was created\n
+/// \b sessid - shibboleth session id\n
+/// \b Shib-Application-ID - ??\n
+/// \b Shib-Identity-Provider - ??\n
+/// \b Shib-AuthnContext-Dec - ??\n
+/// \b Shib-logouturl - idp's logout url\n
+/// \b eppn - edu person principal name for user\n
+/// \b unscoped-affiliation - shibboleth unscoped affiliation\n
+/// \b affiliation - shibboleth scoped affiliation
+///
+/// \brief gets entry from shibauth table
+///
+////////////////////////////////////////////////////////////////////////////////
+function getShibauthDataByUser($userid) {
+	$query = "SELECT id, "
+	       .        "userid, "
+	       .        "ts, "
+	       .        "sessid, "
+	       .        "data "
+	       . "FROM shibauth "
+	       . "WHERE userid = $userid AND "
+	       .       "ts > DATE_SUB(NOW(), INTERVAL 12 HOUR) "
+	       . "ORDER BY ts DESC "
+	       . "LIMIT 1";
+	$qh = doQuery($query, 101);
+	if($row = mysqli_fetch_assoc($qh)) {
+		$data = unserialize($row['data']);
+		unset($row['data']);
+		$data2 = array_merge($row, $data);
+		return $data2;
+	}
+	return NULL;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// \fn updateShibUser($userid)
@@ -39,41 +319,46 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function updateShibUser($userid) {
-	global $mysql_link_vcl;
+	global $mysqli_link_vcl;
 	$rc = getAffilidAndLogin($userid, $affilid);
 	if($rc == -1)
 		return NULL;
 
 	$displast = '';
-	if(array_key_exists('displayName', $_SERVER) &&
-	   ! empty($_SERVER['displayName'])) {
-		# split displayName into first and last names
-		if(preg_match('/,/', $_SERVER['displayName'])) {
-			$names = explode(',', $_SERVER['displayName']);
+
+	$displayname = getShibVar('displayName');
+	$givenname = getShibVar('givenName');
+	$sn = getShibVar('sn');
+	$mail = getShibVar('mail');
+
+	if($displayname != '') {
+		# split displayname into first and last names
+		if(preg_match('/,/', $displayname)) {
+			$names = explode(',', $displayname);
 			$user['firstname'] = preg_replace('/^\s+/', '', $names[1]);
 			$user['firstname'] = preg_replace('/\s+$/', '', $user['firstname']);
 			$displast = preg_replace('/^\s+/', '', $names[0]);
 			$displast = preg_replace('/\s+$/', '', $displast);
 		}
 		else {
-			$names = explode(' ', $_SERVER['displayName']);
+			$names = explode(' ', $displayname);
 			$displast = array_pop($names);
 			$user['firstname'] = array_shift($names);
 		}
 	}
-	elseif(array_key_exists('givenName', $_SERVER) &&
-	   ! empty($_SERVER['givenName']))
-		$user['firstname'] = $_SERVER['givenName'];
+	elseif($givenname != '')
+		$user['firstname'] = $givenname;
 	else
 		$user['firstname'] = '';
 
-	if(array_key_exists('sn', $_SERVER) &&
-	   ! empty($_SERVER['sn']))
-		$user["lastname"] = $_SERVER['sn'];
+	if($sn != '')
+		$user["lastname"] = $sn;
 	else
 		$user['lastname'] = $displast;
-	if(array_key_exists('mail', $_SERVER))
-		$user["email"] = $_SERVER['mail'];
+
+	if($mail != '')
+		$user["email"] = $mail;
+
 	$user['unityid'] = $userid;
 	$user['affilid'] = $affilid;
 
@@ -83,7 +368,7 @@
 	       . "WHERE unityid = '$userid' AND "
 	       .       "affiliationid = $affilid";
 	$qh = doQuery($query, 101);
-	if(! $row = mysql_fetch_assoc($qh)) {
+	if(! $row = mysqli_fetch_assoc($qh)) {
 		# add user to our db
 		$user['id'] = addShibUser($user);
 		return $user;
@@ -91,13 +376,13 @@
 
 	# update user's data in db
 	$user['id'] = $row['id'];
-	$first = mysql_real_escape_string($user['firstname']);
-	$last = mysql_real_escape_string($user['lastname']);
+	$first = vcl_mysql_escape_string($user['firstname']);
+	$last = vcl_mysql_escape_string($user['lastname']);
 	$query = "UPDATE user "
 	       . "SET firstname = '$first', "
 	       .     "lastname = '$last', ";
 	if(array_key_exists('email', $user)) {
-		$email = mysql_real_escape_string($user['email']);
+		$email = vcl_mysql_escape_string($user['email']);
 		$query .= "email = '$email', ";
 	}
     $query .=    "lastupdated = NOW(), "
@@ -124,10 +409,10 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function addShibUser($user) {
-	global $mysql_link_vcl;
-	$unityid = mysql_real_escape_string($user['unityid']);
-	$first = mysql_real_escape_string($user['firstname']);
-	$last = mysql_real_escape_string($user['lastname']);
+	global $mysqli_link_vcl;
+	$unityid = vcl_mysql_escape_string($user['unityid']);
+	$first = vcl_mysql_escape_string($user['firstname']);
+	$last = vcl_mysql_escape_string($user['lastname']);
 	$query = "INSERT INTO user "
 	       .        "(unityid, "
 	       .        "affiliationid, "
@@ -143,14 +428,14 @@
 	       .        "'$first', "
 	       .        "'$last', ";
 	if(array_key_exists('email', $user)) {
-		$email = mysql_real_escape_string($user['email']);
+		$email = vcl_mysql_escape_string($user['email']);
 		$query .=    "'$email', ";
 	}
 	$query .=       "0, "
 	       .        "NOW())";
 	doQuery($query, 101, 'vcl', 1);
-	if(mysql_affected_rows($mysql_link_vcl)) {
-		$user['id'] = mysql_insert_id($mysql_link_vcl);
+	if(mysqli_affected_rows($mysqli_link_vcl)) {
+		$user['id'] = mysqli_insert_id($mysqli_link_vcl);
 		return $user['id'];
 	}
 	else
@@ -188,18 +473,23 @@
 		# get id for the group's affiliation
 		$query = "SELECT id FROM affiliation WHERE shibname = '$shibaffil'";
 		$qh = doQuery($query, 101);
-		$row = mysql_fetch_assoc($qh);
+		if(! ($row = mysqli_fetch_assoc($qh))) {
+			$query = "SELECT id FROM affiliation WHERE shibname LIKE '%.$shibaffil'";
+			$qh = doQuery($query, 101);
+			if(! ($row = mysqli_fetch_assoc($qh)))
+				continue;
+		}
 		$affilid = $row['id'];
 		# prepend shib- and escape it for mysql
-		$grp = mysql_real_escape_string("shib-" . $name);
+		$grp = vcl_mysql_escape_string("shib-" . $name);
 		array_push($newusergroups, getUserGroupID($grp, $affilid));
 	}
 
 	$query = "SELECT id, name FROM affiliation WHERE shibname = '$shibaffil'";
 	$qh = doQuery($query, 101);
-	$row = mysql_fetch_assoc($qh);
+	$row = mysqli_fetch_assoc($qh);
 	$affilid = $row['id'];
-	$grp = mysql_real_escape_string("All {$row['name']} Users");
+	$grp = vcl_mysql_escape_string("All {$row['name']} Users");
 	array_push($newusergroups, getUserGroupID($grp, $affilid));
 
 	$newusergroups = array_unique($newusergroups);
@@ -224,7 +514,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function addShibUserStub($affilid, $userid) {
-	global $mysql_link_vcl;
+	global $mysqli_link_vcl;
 	$query = "INSERT INTO user "
 	       .        "(unityid, "
 	       .        "affiliationid, "
@@ -238,10 +528,30 @@
 	       .        "0, "
 	       .        "0)";
 	doQuery($query);
-	if(mysql_affected_rows($mysql_link_vcl))
+	if(mysqli_affected_rows($mysqli_link_vcl))
 		return dbLastInsertID();
 	else
 		return NULL;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getShibVar($key)
+///
+/// \param $key - shib variable to check for
+///
+/// \return value of shib variable or empty string if not found
+///
+/// \brief checks for various forms of $key in $_SERVER
+///
+////////////////////////////////////////////////////////////////////////////////
+function getShibVar($key) {
+	$key2 = "SHIB_" . strtoupper($key);
+	$val = '';
+	if(isset($_SERVER[$key]) && ! empty($_SERVER[$key]))
+		return $_SERVER[$key];
+	elseif(isset($_SERVER[$key2]) && ! empty($_SERVER[$key2]))
+		return $_SERVER[$key2];
+}
+
 ?>
diff --git a/web/.ht-inc/blockallocations.php b/web/.ht-inc/blockallocations.php
index 66ee16f..9bf25e2 100644
--- a/web/.ht-inc/blockallocations.php
+++ b/web/.ht-inc/blockallocations.php
@@ -75,7 +75,7 @@
 	       . "WHERE id in ($inids) AND "
 	       .       "status = 'accepted'";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$blocks[$row['id']] = $row['name'];
 	print "<hr>\n";
 	print "<h2>" . i("Your Active Block Allocations") . "</h2>\n";
@@ -606,7 +606,7 @@
 			return;
 		}
 		$mnid = array_rand($managementnodes);
-		$escname = mysql_real_escape_string($data['name']);
+		$escname = vcl_mysql_escape_string($data['name']);
 		$query = "INSERT INTO blockRequest "
 		       .        "(name, "
 		       .        "imageid, "
@@ -644,7 +644,7 @@
 		       .       "end > NOW() AND "
 		       .       "blockRequestid = $blockreqid";
 		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_assoc($qh)) {
+		if($row = mysqli_fetch_assoc($qh)) {
 			$checkCurBlockTime = 1;
 			$curBlockTime = $row;
 		}
@@ -660,7 +660,7 @@
 		$query = "DELETE FROM blockWebTime WHERE blockRequestid = $blockreqid";
 		doQuery($query, 101);
 
-		$escname = mysql_real_escape_string($data['name']);
+		$escname = vcl_mysql_escape_string($data['name']);
 		$query = "UPDATE blockRequest "
 		       . "SET name = '$escname', " 
 		       .     "imageid = {$data['imageid']}, "
@@ -673,7 +673,7 @@
 		doQuery($query, 101);
 	}
 	elseif($method == 'request') {
-		$esccomments = mysql_real_escape_string($data['comments']);
+		$esccomments = vcl_mysql_escape_string($data['comments']);
 		$query = "INSERT INTO blockRequest "
 		       .        "(name, "
 		       .        "imageid, "
@@ -811,7 +811,7 @@
 		       .       "blockRequestid = $blockreqid AND "
 		       .       "id != {$curBlockTime['id']}";
 		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_assoc($qh)) {
+		if($row = mysqli_fetch_assoc($qh)) {
 			if($curBlockTime['end'] != $row['end']) {
 				# update old end time
 				$query = "UPDATE blockTimes "
@@ -1093,7 +1093,7 @@
 	       .       "u.email != ''";
 	$qh = doQuery($query);
 	$addrs = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$addrs[] = $row['email'];
 	return implode(',', $addrs);
 }
@@ -1119,7 +1119,7 @@
 	$qh = doQuery($query, 101);
 	$skips = array();
 	$noskips = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$key = "{$row['start']}:{$row['end']}";
 		if($row['skip'])
 			$skips[$key] = $row['id'];
@@ -1181,11 +1181,11 @@
 	       . "ORDER BY b.name";
 	$allblockids = array();
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($row['group'] == '') {
 			$query3 = "SELECT name FROM usergroup WHERE id = {$row['usergroupid']}";
 			$qh3 = doQuery($query3, 101);
-			if($row3 = mysql_fetch_assoc($qh3))
+			if($row3 = mysqli_fetch_assoc($qh3))
 				$row['group'] = $row3['name'];
 		}
 		$allblockids[] = $row['id'];
@@ -1200,7 +1200,7 @@
 		        . "ORDER BY start "
 		        . "LIMIT 1";
 		$qh2 = doQuery($query2, 101);
-		if($row2 = mysql_fetch_assoc($qh2)) {
+		if($row2 = mysqli_fetch_assoc($qh2)) {
 			if(array_key_exists('tzoffset', $_SESSION['persistdata'])) {
 				$tmp = date('n/j/y+g:i=A=T', $row2['unixstart']);
 				$blocks[$row['id']]['nextstart'] = str_replace(array('+', '='), array('<br>', '&nbsp;'), $tmp);
@@ -1229,7 +1229,7 @@
 			       . "FROM blockWebDate "
 			       . "WHERE blockRequestid = $id";
 			$qh = doQuery($query, 101);
-			if(! $row = mysql_fetch_assoc($qh))
+			if(! $row = mysqli_fetch_assoc($qh))
 				abort(101);
 			$blocks[$id] = array_merge($request, $row);
 			$wdays = array();
@@ -1250,7 +1250,7 @@
 			       . "WHERE blockRequestid = {$request['id']} "
 			       . "ORDER BY startmeridian, starthour, startminute";
 			$qh = doQuery($query, 101);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				$blocks[$id]['swhour'][$row['order']] = $row['starthour'];
 				$blocks[$id]['swminute'][$row['order']] = $row['startminute'];
 				$blocks[$id]['swmeridian'][$row['order']] = $row['startmeridian'];
@@ -1267,7 +1267,7 @@
 			       . "FROM blockWebDate "
 			       . "WHERE blockRequestid = $id";
 			$qh = doQuery($query, 101);
-			if(! $row = mysql_fetch_assoc($qh))
+			if(! $row = mysqli_fetch_assoc($qh))
 				abort(101);
 			$blocks[$id] = array_merge($request, $row);
 			$query = "SELECT starthour, "
@@ -1281,7 +1281,7 @@
 			       . "WHERE blockRequestid = {$request['id']} "
 			       . "ORDER BY startmeridian, starthour, startminute";
 			$qh = doQuery($query, 101);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				$blocks[$id]['smhour'][$row['order']] = $row['starthour'];
 				$blocks[$id]['smminute'][$row['order']] = $row['startminute'];
 				$blocks[$id]['smmeridian'][$row['order']] = $row['startmeridian'];
@@ -1297,7 +1297,7 @@
 			       . "WHERE blockRequestid = $id "
 			       . "ORDER BY start";
 			$qh = doQuery($query, 101);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				if($row['date'] == '00/00/00')
 					$blocks[$id]['date'][$row['order']] = '';
 				else
@@ -1313,7 +1313,7 @@
 			       . "FROM blockWebTime "
 			       . "WHERE blockRequestid = {$request['id']}";
 			$qh = doQuery($query, 101);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				$blocks[$id]['slhour'][$row['order']] = $row['starthour'];
 				$blocks[$id]['slminute'][$row['order']] = $row['startminute'];
 				$blocks[$id]['slmeridian'][$row['order']] = $row['startmeridian'];
@@ -1528,7 +1528,7 @@
 	       . "ORDER BY b.name";
 	$qh = doQuery($query, 101);
 	$blocks = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$blocks[$row['id']] = $row;
 	if(empty($blocks))
 		return;
@@ -1543,7 +1543,7 @@
 			       . "FROM blockWebDate "
 			       . "WHERE blockRequestid = $id";
 			$qh = doQuery($query, 101);
-			if(! $row = mysql_fetch_assoc($qh))
+			if(! $row = mysqli_fetch_assoc($qh))
 				abort(101);
 			$blocks[$id] = array_merge($request, $row);
 			$wdays = array();
@@ -1564,7 +1564,7 @@
 			       . "WHERE blockRequestid = {$request['id']} "
 			       . "ORDER BY startmeridian, starthour, startminute";
 			$qh = doQuery($query, 101);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				$blocks[$id]['swhour'][$row['order']] = $row['starthour'];
 				$blocks[$id]['swminute'][$row['order']] = $row['startminute'];
 				$blocks[$id]['swmeridian'][$row['order']] = $row['startmeridian'];
@@ -1581,7 +1581,7 @@
 			       . "FROM blockWebDate "
 			       . "WHERE blockRequestid = $id";
 			$qh = doQuery($query, 101);
-			if(! $row = mysql_fetch_assoc($qh))
+			if(! $row = mysqli_fetch_assoc($qh))
 				abort(101);
 			$blocks[$id] = array_merge($request, $row);
 			$query = "SELECT starthour, "
@@ -1595,7 +1595,7 @@
 			       . "WHERE blockRequestid = {$request['id']} "
 			       . "ORDER BY startmeridian, starthour, startminute";
 			$qh = doQuery($query, 101);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				$blocks[$id]['smhour'][$row['order']] = $row['starthour'];
 				$blocks[$id]['smminute'][$row['order']] = $row['startminute'];
 				$blocks[$id]['smmeridian'][$row['order']] = $row['startmeridian'];
@@ -1611,7 +1611,7 @@
 			       . "WHERE blockRequestid = $id "
 			       . "ORDER BY start";
 			$qh = doQuery($query, 101);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				if($row['date'] == '00/00/00')
 					$blocks[$id]['date'][$row['order']] = '';
 				else
@@ -1627,7 +1627,7 @@
 			       . "FROM blockWebTime "
 			       . "WHERE blockRequestid = {$request['id']}";
 			$qh = doQuery($query, 101);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				$blocks[$id]['slhour'][$row['order']] = $row['starthour'];
 				$blocks[$id]['slminute'][$row['order']] = $row['startminute'];
 				$blocks[$id]['slmeridian'][$row['order']] = $row['startmeridian'];
@@ -1823,7 +1823,7 @@
 	$h .= "  </tr>\n";
 	$d = '';
 	$groups = getUserGroups(0, $user['affiliationid']);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($row['repeating'] == 'weekly') {
 			$query2 = "SELECT DATE_FORMAT(start, '%m/%d/%y') AS swdate, "
 			        .        "DATE_FORMAT(end, '%m/%d/%y')AS ewdate, " 
@@ -1833,7 +1833,7 @@
 			        . "FROM blockWebDate "
 			        . "WHERE blockRequestid = {$row['id']}";
 			$qh2 = doQuery($query2, 101);
-			if(! $row2 = mysql_fetch_assoc($qh2))
+			if(! $row2 = mysqli_fetch_assoc($qh2))
 				abort(101);
 			$row = array_merge($row, $row2);
 			$wdays = array();
@@ -1854,7 +1854,7 @@
 			        . "ORDER BY startmeridian, starthour, startminute";
 			$qh2 = doQuery($query2, 101);
 			$row['times'] = array();
-			while($row2 = mysql_fetch_assoc($qh2)) {
+			while($row2 = mysqli_fetch_assoc($qh2)) {
 				$row['swhour'][$row2['order']] = $row2['starthour'];
 				$row['swminute'][$row2['order']] = $row2['startminute'];
 				$row['swmeridian'][$row2['order']] = $row2['startmeridian'];
@@ -1878,7 +1878,7 @@
 			        . "FROM blockWebDate "
 			        . "WHERE blockRequestid = {$row['id']}";
 			$qh2 = doQuery($query2, 101);
-			if(! $row2 = mysql_fetch_assoc($qh2))
+			if(! $row2 = mysqli_fetch_assoc($qh2))
 				abort(101);
 			$row = array_merge($row, $row2);
 			$query2 = "SELECT starthour, "
@@ -1893,7 +1893,7 @@
 			        . "ORDER BY startmeridian, starthour, startminute";
 			$qh2 = doQuery($query2, 101);
 			$row['times'] = array();
-			while($row2 = mysql_fetch_assoc($qh2)) {
+			while($row2 = mysqli_fetch_assoc($qh2)) {
 				$row['smhour'][$row2['order']] = $row2['starthour'];
 				$row['smminute'][$row2['order']] = $row2['startminute'];
 				$row['smmeridian'][$row2['order']] = $row2['startmeridian'];
@@ -1916,7 +1916,7 @@
 			        . "WHERE blockRequestid = {$row['id']} "
 			        . "ORDER BY start";
 			$qh2 = doQuery($query2, 101);
-			while($row2 = mysql_fetch_assoc($qh2)) {
+			while($row2 = mysqli_fetch_assoc($qh2)) {
 				if($row2['date'] == '00/00/00')
 					$row['date'][$row2['order']] = '';
 				else
@@ -1934,7 +1934,7 @@
 			        . "WHERE blockRequestid = {$row['id']}";
 			$qh2 = doQuery($query2, 101);
 			$row['slots'] = array(); # yyyy-mm-dd|hh:mm|hh:mm
-			while($row2 = mysql_fetch_assoc($qh2)) {
+			while($row2 = mysqli_fetch_assoc($qh2)) {
 				$row['slhour'][$row2['order']] = $row2['starthour'];
 				$row['slminute'][$row2['order']] = $row2['startminute'];
 				$row['slmeridian'][$row2['order']] = $row2['startmeridian'];
@@ -2467,7 +2467,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function AJacceptBlockAllocationSubmit() {
-	global $mysql_link_vcl, $user;
+	global $mysqli_link_vcl, $user;
 	$blockid = getContinuationVar('blockid');
 	$comments = getContinuationVar('comments');
 	$validemail = getContinuationVar('validemail');
@@ -2523,9 +2523,9 @@
 	if(! $err) {
 		# update values for block allocation
 		if($validemail)
-			$esccomments = mysql_real_escape_string("COMMENTS: $comments|EMAIL: $emailtext");
+			$esccomments = vcl_mysql_escape_string("COMMENTS: $comments|EMAIL: $emailtext");
 		else
-			$esccomments = mysql_real_escape_string("COMMENTS: $comments|USER NOT EMAILED");
+			$esccomments = vcl_mysql_escape_string("COMMENTS: $comments|USER NOT EMAILED");
 		$query = "UPDATE blockRequest "
 				 . "SET name = '$name', ";
 		if($setusergroup)
@@ -2535,7 +2535,7 @@
 			    .     "managementnodeid = '$mnid' "
 		       . "WHERE id = $blockid";
 		doQuery($query, 101);
-		if(! mysql_affected_rows($mysql_link_vcl)) {
+		if(! mysqli_affected_rows($mysqli_link_vcl)) {
 			$errmsg = i("Error encountered while updating status of block allocation.");
 			$err = 1;
 		}
@@ -2694,7 +2694,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function AJrejectBlockAllocationSubmit() {
-	global $mysql_link_vcl;
+	global $mysqli_link_vcl;
 	$blockid = getContinuationVar('blockid');
 	$comments = getContinuationVar('comments');
 	$validemail = getContinuationVar('validemail');
@@ -2727,16 +2727,16 @@
 	if(! $err) {
 		# update values for block allocation
 		if($validemail)
-			$esccomments = mysql_real_escape_string("COMMENTS: $comments|EMAIL: $emailtext");
+			$esccomments = vcl_mysql_escape_string("COMMENTS: $comments|EMAIL: $emailtext");
 		else
-			$esccomments = mysql_real_escape_string("COMMENTS: $comments|REJECTREASON: $emailtext");
+			$esccomments = vcl_mysql_escape_string("COMMENTS: $comments|REJECTREASON: $emailtext");
 		$query = "UPDATE blockRequest "
 				 . "SET name = 'rejected', "
 				 .     "status = 'rejected', "
 				 .     "comments = '$esccomments' "
 				 . "WHERE id = $blockid";
 		doQuery($query, 101);
-		if(! mysql_affected_rows($mysql_link_vcl)) {
+		if(! mysqli_affected_rows($mysqli_link_vcl)) {
 			$errmsg = i("Error encountered while updating status of block allocation.");
 			$err = 1;
 		}
@@ -2785,7 +2785,7 @@
 	$qh = doQuery($query, 101);
 	$data = array();
 	$items = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$items[] = $row;
 	$cont = addContinuationsEntry('AJtoggleBlockTime', array('blockid' => $blockid));
 	$data['cont'] = $cont;
@@ -2809,7 +2809,7 @@
 	       . "FROM blockTimes "
 	       . "WHERE id = $timeid";
 	$qh = doQuery($query, 101);
-	if(! ($row = mysql_fetch_assoc($qh)) || $row['blockRequestid'] != $blockid) {
+	if(! ($row = mysqli_fetch_assoc($qh)) || $row['blockRequestid'] != $blockid) {
 		$data['error'] = i("Invalid block time submitted");
 		sendJSON($data);
 		return;
@@ -3347,7 +3347,7 @@
 	       . "ORDER BY t.start "
 	       . "LIMIT 1";
 	$qh = doQuery($query, 101);
-	if($data = mysql_fetch_assoc($qh)) {
+	if($data = mysqli_fetch_assoc($qh)) {
 		if(! is_numeric($data['subimages']))
 			$data['subimages'] = 0;
 		$query = "SELECT c.id, "
@@ -3370,7 +3370,7 @@
 		       .       "c.stateid = s.id";
 		$qh = doQuery($query, 101);
 		$data['comps'] = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$data['comps'][$row['id']] = $row;
 		return $data;
 	}
@@ -3454,7 +3454,7 @@
 	       . "WHERE b.id = d.blockRequestid AND "
 	       .       "b.id = $blockid";
 	$qh = doQuery($query, 101);
-	$row = mysql_fetch_assoc($qh);
+	$row = mysqli_fetch_assoc($qh);
 	if(empty($row))
 		return $rt;
 	$row['wdayschecked'] = $rt['wdayschecked'];
@@ -3505,7 +3505,7 @@
 	$blockid = getContinuationVar('blockid');
 	$query = "SELECT repeating FROM blockRequest WHERE id = $blockid";
 	$qh = doQuery($query, 101);
-	if(! ($row = mysql_fetch_assoc($qh))) {
+	if(! ($row = mysqli_fetch_assoc($qh))) {
 		sendJSON(array('error' => i("Error: Failed to fetch start/end times for block allocation.")));
 		return;
 	}
@@ -3524,7 +3524,7 @@
 		$startms = array();
 		$endhs = array();
 		$endms = array();
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			$starth = hour12to24($row['starthour'], $row['startmeridian']);
 			$endh = hour12to24($row['endhour'], $row['endmeridian']);
 			$starths[] = $starth;
@@ -3550,7 +3550,7 @@
 		       . "WHERE blockRequestid = $blockid";
 		$qh = doQuery($query, 101);
 		$data = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$data[$row['order']] = $row;
 		$query = "SELECT MONTH(start) AS month, "
 		       .        "DAY(start) AS day, "
@@ -3566,7 +3566,7 @@
 		$startms = array();
 		$endhs = array();
 		$endms = array();
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			$id = $row['days'];
 			$months[] = $row['month'];
 			$days[] = $row['day'];
@@ -3696,7 +3696,7 @@
 		       . "WHERE stateid IN (2, 3, 6, 8, 11) AND "
 		       .       "type = 'blade'";
 		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_row($qh))
+		if($row = mysqli_fetch_row($qh))
 			$data['total'] = $row[0];
 	}
 	else
@@ -3743,7 +3743,7 @@
 		       .       "u.affiliationid = {$user['affiliationid']}";
 	}
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		for($binstart = $start, $binend = $start + 900, $binindex = 0; 
 		   $binend <= $end;
 		   $binstart += 900, $binend += 900, $binindex++) {
@@ -3770,7 +3770,7 @@
 		       . "WHERE stateid IN (2, 3, 6, 8, 11) AND "
 		       .       "type = 'virtualmachine'";
 		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_row($qh))
+		if($row = mysqli_fetch_row($qh))
 			$data['total'] = $row[0];
 	}
 	else
@@ -3817,7 +3817,7 @@
 		       .       "u.affiliationid = {$user['affiliationid']}";
 	}
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		for($binstart = $start, $binend = $start + 900, $binindex = 0; 
 		   $binend <= $end;
 		   $binstart += 900, $binend += 900, $binindex++) {
@@ -3869,15 +3869,14 @@
 	$first = 1;
 	$firststart = '';
 	$laststart = '';
-	while($row = mysql_fetch_assoc($qh)) {
-		if($first && ! is_null($row['blockStart'])) {
+	while($row = mysqli_fetch_assoc($qh)) {
+		if(is_null($row['blockStart']))
+			continue;
+		if($first) {
 			$firststart = datetimeToUnix($row['blockStart']);
 			$first = 0;
 		}
-		elseif(! is_null($row['blockStart']))
-			$laststart = datetimeToUnix($row['blockStart']);
-		if(is_null($row['blockStart']))
-			continue;
+		$laststart = datetimeToUnix($row['blockStart']);
 		$percent = (int)($row['used'] / $row['allocated'] * 100);
 		$startts = datetimeToUnix($row['blockStart']);
 		$usage[$startts] = array('percent' => $percent,
diff --git a/web/.ht-inc/computer.php b/web/.ht-inc/computer.php
index 6c6668d..3a9e117 100644
--- a/web/.ht-inc/computer.php
+++ b/web/.ht-inc/computer.php
@@ -821,7 +821,7 @@
 		       . "ORDER BY rq.start "
 		       . "LIMIT 1";
 		$qh = doQuery($query);
-		if($row = mysql_fetch_assoc($qh)) {
+		if($row = mysqli_fetch_assoc($qh)) {
 			$cdata = $this->basecdata;
 			$cdata['compid'] = $rscid;
 			$cont = addContinuationsEntry('AJcanceltovmhostinuse', $cdata, 300, 1, 0);
@@ -973,7 +973,7 @@
 				       .       "vm.stateid = 10";
 				$qh = doQuery($query);
 				$vmids = array();
-				while($row = mysql_fetch_assoc($qh))
+				while($row = mysqli_fetch_assoc($qh))
 					$vmids[] = $row['id'];
 				$allids = implode(',', $vmids);
 				if($data['provisioning'] != 'none')  {
@@ -1235,7 +1235,7 @@
 					       .       "vm.vmhostid = v.id";
 					$qh = doQuery($query);
 					$fail = 0;
-					while($row = mysql_fetch_assoc($qh)) {
+					while($row = mysqli_fetch_assoc($qh)) {
 						if(! simpleAddRequest($row['id'], $imageid, $revid, $startdt,
 						                      $enddt, 18, $vclreloadid)) {
 							$fail = 1;
@@ -1357,7 +1357,7 @@
 					       .       "vm.vmhostid = v.id";
 					$qh = doQuery($query);
 					$fails = array();
-					while($row = mysql_fetch_assoc($qh)) {
+					while($row = mysqli_fetch_assoc($qh)) {
 						if(! simpleAddRequest($row['id'], $imageid, $revid, $startdt,
 						                      $enddt, 18, $vclreloadid)) {
 							$fails[] = $row['id'];
@@ -1451,7 +1451,7 @@
 							$qh = doQuery($query);
 							$fails = array();
 							$cnt = 0;
-							while($row = mysql_fetch_assoc($qh)) {
+							while($row = mysqli_fetch_assoc($qh)) {
 								$cnt++;
 								if(! simpleAddRequest($row['id'], $imageid, $revid, $startdt,
 								                      $enddt, 18, $vclreloadid)) {
@@ -1781,7 +1781,7 @@
 			       .       "deleted = 0";
 			$qh = doQuery($query);
 			$exists = array();
-			while($row = mysql_fetch_assoc($qh))
+			while($row = mysqli_fetch_assoc($qh))
 				$exists[] = $row['hostname'];
 			if(count($exists)) {
 				$hosts = implode(', ', $exists);
@@ -2049,7 +2049,7 @@
 				       .       "rq.laststateid NOT IN (1,5,11,12) AND "
 				       .       "rq.userid != $vclreloadid";
 				$qh = doQuery($query);
-				if(mysql_num_rows($qh)) {
+				if(mysqli_num_rows($qh)) {
 					$return['error'] = 1;
 					$errormsg[] = "This computer has an active reservation. NAT settings cannot be changed for computers having<br>active reservations.";
 				}
@@ -2099,7 +2099,7 @@
 				       .       "rq.laststateid NOT IN (1,5,11,12) AND "
 				       .       "rq.userid != $vclreloadid";
 				$qh = doQuery($query);
-				if(mysql_num_rows($qh)) {
+				if(mysqli_num_rows($qh)) {
 					$return['error'] = 1;
 					$errormsg[] = "This computer is the NAT host for other computers that have active reservations. NAT host<br>settings cannot be changed while providing NAT for active reservations.";
 				}
@@ -2140,7 +2140,7 @@
 		if(! empty($compid))
 			$query .= " AND id != $compid";
 		$qh = doQuery($query);
-		if(mysql_num_rows($qh))
+		if(mysqli_num_rows($qh))
 			return 1;
 		return 0;
 	}
@@ -2170,7 +2170,7 @@
 		if(! empty($compid))
 			$query .= " AND id != $compid";
 		$qh = doQuery($query);
-		if(mysql_num_rows($qh))
+		if(mysqli_num_rows($qh))
 			return 1;
 		return 0;
 	}
@@ -2199,7 +2199,7 @@
 		if(! empty($compid))
 			$query .= " AND id != $compid";
 		$qh = doQuery($query);
-		if(mysql_num_rows($qh))
+		if(mysqli_num_rows($qh))
 			return 1;
 		return 0;
 	}
@@ -2377,7 +2377,7 @@
 	///
 	////////////////////////////////////////////////////////////////////////////////
 	function AJcanceltovmhostinuse() {
-		global $mysql_link_vcl;
+		global $mysqli_link_vcl;
 		$compid = getContinuationVar('compid');
 		$type = 'none';
 		$query = "DELETE FROM request "
@@ -2387,7 +2387,7 @@
 		       .              "FROM reservation "
 		       .              "WHERE computerid = $compid)";
 		doQuery($query);
-		if(mysql_affected_rows($mysql_link_vcl))
+		if(mysqli_affected_rows($mysqli_link_vcl))
 			$type = 'future';
 		$query = "UPDATE request rq, "
 		       .         "reservation rs, "
@@ -2399,7 +2399,7 @@
 		       .       "rq.laststateid = ls.id AND "
 		       .       "ls.name = 'tovmhostinuse'";
 		doQuery($query);
-		if(mysql_affected_rows($mysql_link_vcl))
+		if(mysqli_affected_rows($mysqli_link_vcl))
 			$type = 'current';
 		$query = "SELECT rq.start "
 		       . "FROM request rq, "
@@ -2415,7 +2415,7 @@
 		       .       "rq.end > NOW() "
 		       . "ORDER BY rq.start";
 		$qh = doQuery($query);
-		if(mysql_num_rows($qh))
+		if(mysqli_num_rows($qh))
 			$arr = array('status' => 'failed');
 		else {
 			if($type == 'now')
@@ -2477,7 +2477,7 @@
 		       . "ORDER BY rq.start "
 		       . "LIMIT 1";
 		$qh = doQuery($query);
-		if($row = mysql_fetch_assoc($qh)) {
+		if($row = mysqli_fetch_assoc($qh)) {
 			if(! retryGetSemaphore($imageid, $revid, $mnid, $compid, $startdt, $enddt, $row['id']))
 				return 0;
 			# update existing reservation
@@ -2720,7 +2720,7 @@
 			       .       "vm.vmhostid = v.id";
 			$qh = doQuery($query);
 			$fail = 0;
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				if(! simpleAddRequest($row['id'], $imageid, $revid, $startdt,
 				                      $enddt, 18, $vclreloadid)) {
 					$fail = 1;
@@ -2811,7 +2811,7 @@
 			       . "WHERE v.computerid = $compid AND "
 			       .       "vm.vmhostid = v.id";
 			$qh = doQuery($query);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				$checkstart = getExistingChangeStateStartTime($row['id'], 18);
 				if($checkstart) {
 					if($checkstart > $start)
@@ -3069,7 +3069,7 @@
 							 .       "rq.end > '$startstamp' AND "
 							 .       "s.name NOT IN ('complete', 'deleted', 'failed', 'timeout')";
 					$qh = doQuery($query);
-					if(! mysql_num_rows($qh))
+					if(! mysqli_num_rows($qh))
 						$reloadnow[] = $compid;
 					else
 						$reloadasap[] = $compid;
@@ -3160,7 +3160,7 @@
 		       .       "s.name NOT IN ('deleted', 'failed', 'complete') AND "
 		       .       "rq.end > NOW()";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$skipcompids[] = $row['computerid'];
 		$query = "SELECT DISTINCT bc.computerid "
 		       . "FROM blockTimes bt, "
@@ -3173,7 +3173,7 @@
 		       .       "bt.skip = 0 AND "
 		       .       "br.status = 'accepted'";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$skipcompids[] = $row['computerid'];
 		$delids = array_diff($compids, $skipcompids);
 		$msg = '';
@@ -3254,7 +3254,7 @@
 		       .       "s.name NOT IN ('deleted', 'failed', 'complete') AND "
 		       .       "rq.end > NOW()";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$fails[] = $row['computerid'];
 		$delids = array_diff($compids, $fails);
 
@@ -3429,7 +3429,7 @@
 			       .       "rq.stateid NOT IN (1, 5, 11, 12) AND " # TODO might not want 11 (timeout)
 			       .       "rs.computerid IN ($allids)";
 			$qh = doQuery($query);
-			while($row = mysql_fetch_assoc($qh))
+			while($row = mysqli_fetch_assoc($qh))
 				$inusecompids[$row['computerid']] = 1;
 
 			# check initial conditions
@@ -3491,7 +3491,7 @@
 				       . "WHERE h.id IN ($ids) "
 				       . "GROUP BY vh.computerid";
 				$qh = doQuery($query);
-				while($row = mysql_fetch_assoc($qh)) {
+				while($row = mysqli_fetch_assoc($qh)) {
 					if($row['count'])
 						$fails['hasvms'][] = $row['id'];
 					else
@@ -3507,7 +3507,7 @@
 				       . "LEFT JOIN computer h ON (vh.computerid = h.id) "
 				       . "WHERE vm.id IN ($ids)";
 				$qh = doQuery($query);
-				while($row = mysql_fetch_assoc($qh)) {
+				while($row = mysqli_fetch_assoc($qh)) {
 					if($row['stateid'] != 20)
 						$fails['hostfail'][] = $row['id'];
 					else
@@ -3578,7 +3578,7 @@
 				$notes = processInputVar('notes', ARG_STRING);
 				if(get_magic_quotes_gpc())
 					$notes = stripslashes($notes);
-				$notes = mysql_real_escape_string($notes);
+				$notes = vcl_mysql_escape_string($notes);
 				$notes = $user["unityid"] . " " . unixToDatetime(time()) . "@"
 				       . $notes;
 			}
@@ -3634,7 +3634,7 @@
 						       .       "vm.vmhostid = v.id";
 						$qh = doQuery($query);
 						$setnoteids = array();
-						while($row = mysql_fetch_assoc($qh)) {
+						while($row = mysqli_fetch_assoc($qh)) {
 							$checkstart = getExistingChangeStateStartTime($row['id'], 18);
 							if($checkstart) {
 								if($checkstart > $reloadstart)
@@ -3865,7 +3865,7 @@
 			       . "WHERE v.computerid IN ($allids) AND "
 			       .       "vm.vmhostid = v.id";
 			$qh = doQuery($query);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				if(! array_key_exists($row['compid'], $maintvmids))
 					$maintvmids[$row['compid']] = array();
 				if($row['vmstateid'] == 10 &&
@@ -4000,8 +4000,8 @@
 								       . "GROUP BY rs.computerid "
 								       . "ORDER BY start";
 								$qh = doQuery($query);
-								if(mysql_num_rows($qh) == count($allvmids)) {
-									while($row = mysql_fetch_assoc($qh)) {
+								if(mysqli_num_rows($qh) == count($allvmids)) {
+									while($row = mysqli_fetch_assoc($qh)) {
 										$times[$row['start']] = 1;
 										$reqids[] = $row['id'];
 									}
@@ -4022,7 +4022,7 @@
 										       .       "rs.imageid = '{$profiles[$profileid]['imageid']}' AND "
 										       .       "rq.stateid = 21";
 										$qh = doQuery($query);
-										if($row = mysql_fetch_assoc($qh)) {
+										if($row = mysqli_fetch_assoc($qh)) {
 											# node was previously scheduled to be reloaded for vmhostinuse
 											if($times[0] > $start) {
 												# update existing reservations
@@ -4286,7 +4286,7 @@
 		       .       "rq.start <= '$startcheckdt' AND "
 		       .       "rq.end > NOW()";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$fails[] = $row['computerid'];
 
 		$nowids = array_diff($compids, $fails);
@@ -4454,7 +4454,7 @@
 		       .       "rq.laststateid NOT IN (1,5,11,12) AND "
 		       .       "rq.userid != $vclreloadid";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$inusecompids[] = $row['computerid'];
 
 		$tmp = getUserResources(array($this->restype . "Admin"), array("administer"), 0, 1);
@@ -4799,7 +4799,7 @@
 		       .       "s.name NOT IN ('timedout','deleted','complete')";
 		$qh = doQuery($query);
 		$data = array();
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			$msg = "<strong>{$row['hostname']}</strong><br>";
 			if($row['start'] == '') {
 				$msg .= "(No reservations)<br><hr>";
@@ -4888,7 +4888,7 @@
 		       .          "l.start DESC";
 		$qh = doQuery($query);
 		$data = array();
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			if(! is_numeric($row['end']))
 				continue;
 			$msg = "<strong>{$row['hostname']}</strong><br>";
@@ -5076,7 +5076,7 @@
 		       .       "eth1macaddress IN ('$ineth1s')";
 		$qh = doQuery($query);
 		$errmsg = '';
-		if(mysql_num_rows($qh)) {
+		if(mysqli_num_rows($qh)) {
 			$errmsg .= "The specified starting MAC address combined with the number ";
 			$errmsg .= "of computers entered will result in a MAC address already ";
 			$errmsg .= "assigned to another computer.";
diff --git a/web/.ht-inc/conf-default.php b/web/.ht-inc/conf-default.php
index d3e4e18..6993ee2 100644
--- a/web/.ht-inc/conf-default.php
+++ b/web/.ht-inc/conf-default.php
@@ -56,11 +56,18 @@
 
 
 #######################   end required modifications ###########################
+$host = $_SERVER['HTTP_HOST'];
+if (strpos($host, ':')) {
+	$host = substr($host, 0, strpos($host, ':'));
+}
 
+define("SSLOFFLOAD", 0); // set this to 1 to use external load balancer to manage SSL termination
+                         // set the BASEURL and HOMEURL paths to also be plain HTTP
+                         // The VCL application will not force HTTPS urls as HTTPS is enforced at the load balancer
 define("BASEURL", "https://{$_SERVER['HTTP_HOST']}/vcl");   // no trailing slash - all of the URL except /index.php
 define("SCRIPT", "/index.php");                 // this should only be "/index.php" unless you rename index.php to something else
 define("HOMEURL", "https://{$_SERVER['HTTP_HOST']}/vcl/"); // url to go to when someone clicks HOME or Logout
-define("COOKIEDOMAIN", "{$_SERVER['HTTP_HOST']}");       // domain in which cookies are set
+define("COOKIEDOMAIN", "$host");       // domain in which cookies are set
 
 define("DEFAULTGROUP", "adminUsers"); // if a user is in no groups, use reservation
 										  //   length attriubtes from this group
@@ -131,7 +138,7 @@
 	                            "affiliationid" => 1,
 	                            "help" => "Only use Local Account if there are no other options"),
 	/*"Shibboleth (UNC Federation)" => array("type" => "redirect",
-	                     "URL" => "https://federation.northcarolina.edu/wayf/wayf_framed.php?fed=FED_SHIB_UNC_DEV&version=dropdown&entityID=https%3A%2F%2Fvcl.ncsu.edu%2Fsp%2Fshibboleth&return=http%3A%2F%2Fvcl.ncsu.edu%2FShibboleth.sso%2FDS%3FSAMLDS%3D1%26target%3Dhttp%3A%2F%2Fvcl.ncsu.edu%2Fscheduling%2Fshibauth%2F",
+	                     "URL" => "https://federation.northcarolina.edu/wayf/wayf_framed.php?fed=FED_SHIB_UNC_DEV&version=dropdown&entityID=https%3A%2F%2Fvcl.ncsu.edu%2Fsp%2Fshibboleth&return=http%3A%2F%2Fvcl.ncsu.edu%2FShibboleth.sso%2FDS%3FSAMLDS%3D1%26target%3Dhttp%3A%2F%2Fvcl.ncsu.edu%2Fscheduling%2F/",
 	                     "affiliationid" => 0, // this should always be 0 for Shibboleth authentication
 	                     "help" => "Use Shibboleth (UNC Federation) if you are from a University in the UNC system and do not see another method specifically for your university"),*/
 	/*"EXAMPLE1 LDAP" => array("type" => "ldap",
diff --git a/web/.ht-inc/config.php b/web/.ht-inc/config.php
index 3ed2cb2..531424d 100644
--- a/web/.ht-inc/config.php
+++ b/web/.ht-inc/config.php
@@ -65,7 +65,7 @@
 		$query .= "ORDER BY cv.configid, cv.name";
 		$variables = array();
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$variables[$row['configid']][$row['id']] = $row;
 
 		# config subimages
@@ -85,7 +85,7 @@
 			$query .= "AND configid = $id ";
 		$query .= "ORDER BY s.configid, i.prettyname";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$variables[$row['configid']][$row['id']] = $row;
 
 		# configs
@@ -121,7 +121,7 @@
 			$query .= " AND c.deleted = 0";
 		$qh = doQuery($query);
 		$configs = array();
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			if(array_key_exists($row['id'], $variables))
 				$row['variables'] = $variables[$row['id']];
 			else
@@ -166,7 +166,7 @@
 		       .       "c.configtypeid = ct.id AND "
 		       .       "c.deleted = 0";
 		$qh = doQuery($query);
-		if($row = mysql_fetch_assoc($qh))
+		if($row = mysqli_fetch_assoc($qh))
 			return $row;
 		else
 			return NULL;
@@ -245,11 +245,11 @@
 		}
 		$sets = array();
 		if($curdata['name'] != $vars['name']) {
-			$name = mysql_real_escape_string($vars['name']);
+			$name = vcl_mysql_escape_string($vars['name']);
 			$sets[] = "name = '$name'";
 		}
 		if($curdata['data'] != $vars['data']) {
-			$data = mysql_real_escape_string($vars['data']);
+			$data = vcl_mysql_escape_string($vars['data']);
 			$sets[] = "data = '$data'";
 		}
 		if($curdata['ownerid'] != $vars['ownerid'])
@@ -319,11 +319,11 @@
 				}
 				$sets = array();
 				if($vardata['name'] != $newvars[$id]['name']) {
-					$name = mysql_real_escape_string($newvars[$id]['name']);
+					$name = vcl_mysql_escape_string($newvars[$id]['name']);
 					$sets[] = "name = '$name'";
 				}
 				if($vardata['identifier'] != $newvars[$id]['identifier']) {
-					$identifier = mysql_real_escape_string($newvars[$id]['identifier']);
+					$identifier = vcl_mysql_escape_string($newvars[$id]['identifier']);
 					$sets[] = "identifier = '$identifier'";
 				}
 				if($vardata['datatypeid'] != $newvars[$id]['datatypeid']) {
@@ -332,7 +332,7 @@
 					$sets[] = "datatypeid = '{$newvars[$id]['datatypeid']}'";
 				}
 				if($vardata['defaultvalue'] != $newvars[$id]['defaultvalue']) {
-					$defaultvalue = mysql_real_escape_string($newvars[$id]['defaultvalue']);
+					$defaultvalue = vcl_mysql_escape_string($newvars[$id]['defaultvalue']);
 					$sets[] = "defaultvalue = '$defaultvalue'";
 				}
 				if($vardata['required'] != $newvars[$id]['required']) {
@@ -377,9 +377,9 @@
 		$inserts = array();
 		$datatypes = getConfigDataTypes();
 		foreach($newvars as $var) {
-			$name = mysql_real_escape_string($var['name']);
-			$identifier = mysql_real_escape_string($var['identifier']);
-			$defaultvalue = mysql_real_escape_string($var['defaultvalue']);
+			$name = vcl_mysql_escape_string($var['name']);
+			$identifier = vcl_mysql_escape_string($var['identifier']);
+			$defaultvalue = vcl_mysql_escape_string($var['defaultvalue']);
 			if(! array_key_exists($var['datatypeid'], $datatypes))
 				$var['datatypeid'] = $this->findDataTypeID($var['defaultvalue'], $datatypes);
 			$inserts[] = "('$name', "
@@ -407,7 +407,7 @@
 	///
 	////////////////////////////////////////////////////////////////////////////////
 	function addResource($vars) {
-		$name = mysql_real_escape_string($vars['name']);
+		$name = vcl_mysql_escape_string($vars['name']);
 		if($vars['type'] == 'Cluster') {
 			$query = "INSERT INTO config "
 			       .        "(name, "
@@ -436,7 +436,7 @@
 			doQuery($query);
 		}
 		else {
-			$data = mysql_real_escape_string($vars['data']);
+			$data = vcl_mysql_escape_string($vars['data']);
 			$query = "INSERT INTO config "
 			       .        "(name, "
 			       .        "configtypeid, "
@@ -501,10 +501,10 @@
 			return 0;
 		}
 		# check for existance of name
-		$name = mysql_real_escape_string($return['name']);
+		$name = vcl_mysql_escape_string($return['name']);
 		$query = "SELECT id FROM config WHERE name = '$name' AND id != $configid";
 		$qh = doQuery($query);
-		if(mysql_num_rows($qh)) {
+		if(mysqli_num_rows($qh)) {
 			$this->errmsg = "Another config with this name already exists.";
 			return 0;
 		}
@@ -1152,7 +1152,7 @@
 		       .       "c.deleted = 0";
 		$configmaps = array();
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			switch($row['configmaptype']) {
 				case "Image":
 					$row['mapto'] = $row['image'];
@@ -1478,7 +1478,7 @@
 		       .       "configstageid = {$return['stageid']} AND "
 		       .       "id != $configmapid";
 		$qh = doQuery($query);
-		if(mysql_num_rows($qh)) {
+		if(mysqli_num_rows($qh)) {
 			$this->errmsg = "The specified mapping already exists.";
 			return 0;
 		}
@@ -1526,7 +1526,7 @@
 		       .       "c.id in ($inlist)";
 		$configs = array();
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$configs[$row['id']] = $row['name'];
 		return $configs;
 	}
@@ -1542,7 +1542,7 @@
 		$query = "SELECT id, name FROM configstage ORDER BY name";
 		$stages = array();
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$stages[$row['id']] = $row['name'];
 		return $stages;
 	}
@@ -1597,7 +1597,7 @@
 			       .       "ct.prettyname = 'Config' AND "
 			       .       "cm.configid = c.id";
 			$qh = doQuery($query);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				if($row['subid'] == $configid)
 					return $row['config'];
 				if($reccnt < 20) {
@@ -1624,7 +1624,7 @@
 			       .       "ct.prettyname = 'Subimage' AND "
 			       .       "cm.configid = c.id";
 			$qh = doQuery($query);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				if($row['configid'] == $configid)
 					return $row['config'];
 				if($reccnt < 20) {
diff --git a/web/.ht-inc/dashboard.php b/web/.ht-inc/dashboard.php
index 78e469c..3c2df3f 100644
--- a/web/.ht-inc/dashboard.php
+++ b/web/.ht-inc/dashboard.php
@@ -193,22 +193,22 @@
 				 .       "rq.end > NOW()";
 	}
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_row($qh))
+	if($row = mysqli_fetch_row($qh))
 		$data[0]['val'] = $row[0];
 
 	$query = "SELECT COUNT(id) FROM computer WHERE stateid IN (2, 3, 6, 8, 11)";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_row($qh))
+	if($row = mysqli_fetch_row($qh))
 		$data[1]['val'] = $row[0];
 
 	$query = "SELECT COUNT(id) FROM computer WHERE stateid = 8";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_row($qh))
+	if($row = mysqli_fetch_row($qh))
 		$data[2]['val'] = $row[0];
 
 	$query = "SELECT COUNT(id) FROM computer WHERE stateid = 5";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_row($qh))
+	if($row = mysqli_fetch_row($qh))
 		$data[3]['val'] = $row[0];
 	return $data;
 }
@@ -259,7 +259,7 @@
 	}
 	$data = array();
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$data[] = $row;
 	return $data;
 }
@@ -310,7 +310,7 @@
 	}
 	$data = array();
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$data[] = $row;
 	return $data;
 }
@@ -360,7 +360,7 @@
 	}
 	$data = array();
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$data[] = $row;
 	return $data;
 }
@@ -407,7 +407,7 @@
 	}
 	$data = array();
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$data[] = $row;
 	return $data;
 }
@@ -458,7 +458,7 @@
 	}
 	$data = array();
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$data[] = $row;
 	return $data;
 }
@@ -522,7 +522,7 @@
 		       .       "l.userid != $reloadid";
 	}
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($row['stateid'] == 14)
 			$row['stateid'] = $row['laststateid'];
 		if($row['end'] > time() &&
@@ -583,7 +583,7 @@
 				 .       "bt.end > NOW()";
 	}
 	$qh = doQuery($query, 101);
-	$row = mysql_fetch_row($qh);
+	$row = mysqli_fetch_row($qh);
 	$blockcount = $row[0];
 	# computers in blockComputers for active allocations
 	if($affilid == 0) {
@@ -612,7 +612,7 @@
 	$qh = doQuery($query, 101);
 	$total = 0;
 	$used = 0;
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$total++;
 		if($row['stateid'] == 3 || $row['stateid'] == 8)
 			$used++;
@@ -642,7 +642,7 @@
 	}
 	$alloc = 0;
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$alloc += $row['numMachines'];
 	if($alloc)
 		$failed = sprintf('%d / %d (%0.2f %%)', ($alloc - $total), $alloc, (($alloc - $total) / $alloc * 100));
@@ -700,7 +700,7 @@
 	$query .= "ORDER BY rq.start";
 	$qh = doQuery($query, 101);
 	$data = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$tmp = explode('.', $row['computer']);
 		$row['computer'] = $tmp[0];
 		$row['start'] = date('D h:i', $row['start']);
@@ -758,7 +758,7 @@
 	$query .= "ORDER BY rq.start";
 	$qh = doQuery($query, 101);
 	$data = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if(is_null($row['revisioncomments']))
 			$row['revisioncomments'] = '(none)';
 		$tmp = explode('.', $row['computer']);
@@ -816,7 +816,7 @@
 	$current = array();
 	$old = array();
 	$never = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$tmp = explode('.', $row['hostname']);
 		$row['hostname'] = $tmp[0];
 		if($row['checkin'] < 0)
diff --git a/web/.ht-inc/groups.php b/web/.ht-inc/groups.php
index 29ae0f4..306395e 100644
--- a/web/.ht-inc/groups.php
+++ b/web/.ht-inc/groups.php
@@ -1102,7 +1102,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function checkForGroupName($name, $type, $id, $extraid) {
-	$name = mysql_real_escape_string($name);
+	$name = vcl_mysql_escape_string($name);
 	if($type == "user")
 		$query = "SELECT id FROM usergroup "
 		       . "WHERE name = '$name' AND "
@@ -1114,7 +1114,7 @@
 	if(! empty($id))
 		$query .= " AND id != $id";
 	$qh = doQuery($query, 101);
-	if(mysql_num_rows($qh))
+	if(mysqli_num_rows($qh))
 		return 1;
 	return 0;
 }
@@ -1162,7 +1162,7 @@
 		       . "WHERE id = {$data['groupid']}";
 	}
 	doQuery($query, 300);
-	return mysql_affected_rows($GLOBALS['mysql_link_vcl']);
+	return mysqli_affected_rows($GLOBALS['mysqli_link_vcl']);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1221,7 +1221,7 @@
 	}
 	$qh = doQuery($query, 305);
 	clearPrivCache();
-	return mysql_affected_rows($GLOBALS['mysql_link_vcl']);
+	return mysqli_affected_rows($GLOBALS['mysqli_link_vcl']);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1254,7 +1254,7 @@
 		       .       "rg.resourcetypeid = rt.id";
 		$usedby = array();
 		$qh = doQuery($query, 310);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$usedby[] = $row['name'];
 		if(count($usedby)) {
 			$msgs[] = "<h3>Owning User Group for Resource Groups</h3>\n"
@@ -1269,7 +1269,7 @@
 				 .       "ug.affiliationid = a.id";
 		$usedby = array();
 		$qh = doQuery($query, 313);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$usedby[] = $row['name'];
 		if(count($usedby)) {
 			$msgs[] = "<h3>'Editable by' Group for User Groups</h3>\n"
@@ -1281,7 +1281,7 @@
 		       . "WHERE usergroupid = $groupid";
 		$qh = doQuery($query);
 		$usedby = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$usedby[] = getNodePath($row['privnodeid']);
 		if(count($usedby)) {
 			$msgs[] = "<h3>Assigned at Privilege Nodes</h3>\n"
@@ -1294,7 +1294,7 @@
 		       .   "AND status IN ('requested', 'accepted')";
 		$qh = doQuery($query, 311);
 		$usedby = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$usedby[] = $row['name'];
 		if(count($usedby)) {
 			$msgs[] = "<h3>Assigned for Block Allocations</h3>\n"
@@ -1304,7 +1304,7 @@
 		$query = "SELECT name FROM serverprofile WHERE admingroupid = $groupid";
 		$qh = doQuery($query);
 		$usedby = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$usedby[] = $row['name'];
 		if(count($usedby)) {
 			$msgs[] = "<h3>Admin User Group for Server Profiles</h3>\n"
@@ -1314,7 +1314,7 @@
 		$query = "SELECT name FROM serverprofile WHERE logingroupid = $groupid";
 		$qh = doQuery($query);
 		$usedby = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$usedby[] = $row['name'];
 		if(count($usedby)) {
 			$msgs[] = "<h3>Access User Group for Server Profiles</h3>\n"
@@ -1328,7 +1328,7 @@
 		       .       "s.requestid = rq.id";
 		$qh = doQuery($query);
 		$usedby = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$usedby[] = $row['name'];
 		if(count($usedby)) {
 			$msgs[] = "<h3>Admin User Group for Server Requests</h3>\n"
@@ -1342,7 +1342,7 @@
 		       .       "s.requestid = rq.id";
 		$qh = doQuery($query);
 		$usedby = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$usedby[] = $row['name'];
 		if(count($usedby)) {
 			$msgs[] = "<h3>Access User Group for Server Requests</h3>\n"
@@ -1366,7 +1366,7 @@
 	$query = "SELECT hostname FROM managementnode WHERE imagelibgroupid = $groupid";
 	$qh = doQuery($query);
 	$usedby = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$usedby[] = $row['hostname'];
 	if(count($usedby)) {
 		$msgs[] = "<h3>Management Node Image Library Group</h3>\n"
@@ -1376,7 +1376,7 @@
 	$query = "SELECT DISTINCT privnodeid FROM resourcepriv WHERE resourcegroupid = $groupid";
 	$qh = doQuery($query);
 	$usedby = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$usedby[] = getNodePath($row['privnodeid']);
 	if(count($usedby)) {
 		$msgs[] = "<h3>Assigned at Privilege Nodes</h3>\n"
diff --git a/web/.ht-inc/help.php b/web/.ht-inc/help.php
index dd73adb..f632f6b 100644
--- a/web/.ht-inc/help.php
+++ b/web/.ht-inc/help.php
@@ -168,7 +168,7 @@
 	       . "ORDER BY l.finalend DESC "
 	       . "LIMIT 5";
 	$qh = doQuery($query, 290);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		# only include 1 computer from cluster reservations
 		if(array_key_exists($row['id'], $requests))
 			continue;
diff --git a/web/.ht-inc/image.php b/web/.ht-inc/image.php
index 9447aea..8f7bc88 100644
--- a/web/.ht-inc/image.php
+++ b/web/.ht-inc/image.php
@@ -96,6 +96,7 @@
 				$w = 12;
 				break;
 			case 'adauthenabled':
+			case 'maxinitialtime':
 				$w = 9;
 				break;
 			default:
@@ -146,7 +147,7 @@
 			case 'forcheckout':
 				return i("Available for Checkout");
 			case 'maxinitialtime':
-				return i("Max Initial Time");
+				return i("Max Reservation Duration");
 			case 'checkuser':
 				return i("Check Logged in User");
 			case 'rootaccess':
@@ -187,7 +188,7 @@
 		       . "ORDER BY rq.end DESC "
 		       . "LIMIT 1";
 		$qh = doQuery($query);
-		if($row = mysql_fetch_assoc($qh))
+		if($row = mysqli_fetch_assoc($qh))
 			$msgs[] = sprintf(i("There is at least one <strong>reservation</strong> for this image. The latest end time is %s."), prettyDatetime($row['end'], 1));;
 
 		# check blockComputers
@@ -205,7 +206,7 @@
 		       . "ORDER BY bt.end DESC "
 		       . "LIMIT 1";
 		$qh = doQuery($query);
-		if($row = mysql_fetch_assoc($qh))
+		if($row = mysqli_fetch_assoc($qh))
 			$msgs[] = sprintf(i("There is at least one <strong>Block Allocation</strong> with computers currently allocated with this image. Block Allocation %s has the latest end time which is %s."), $row['name'], prettyDatetime($row['end'], 1));
 
 		# check blockRequest
@@ -221,7 +222,7 @@
 		       . "ORDER BY bt.end DESC "
 		       . "LIMIT 1";
 		$qh = doQuery($query);
-		if($row = mysql_fetch_assoc($qh))
+		if($row = mysqli_fetch_assoc($qh))
 			$msgs[] = sprintf(i("There is at least one <strong>Block Allocation</strong> configured to use this image. Block Allocation %s has the latest end time which is %s."), $row['name'], prettyDatetime($row['end'], 1));
 
 		# check serverprofile
@@ -230,7 +231,7 @@
 		       . "WHERE imageid = $rscid";
 		$qh = doQuery($query);
 		$profiles = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$profiles[] = $row['name'];
 		if(count($profiles))
 			$msgs[] = i("The following <strong>Server Profiles</strong> are configured to use this image:") . "<br><br>\n" . implode("<br>\n", $profiles);
@@ -245,7 +246,7 @@
 		       .       "s.imagemetaid = im.id AND "
 		       .       "s.imageid = $rscid";
 		$images = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$images[] = $row['prettyname'];
 		if(count($images))
 			$msgs[] = i("The following <strong>images</strong> have the selected image assigned as a <strong>subimage</strong>:") . "<br><br>\n" . implode("<br>\n", $images);
@@ -255,7 +256,7 @@
 		       . "FROM vmprofile "
 		       . "WHERE imageid = $rscid";
 		$profiles = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$profiles[] = $row['profilename'];
 		if(count($profiles))
 			$msgs[] = i("The following <strong>VM Host Profiles</strong> have the this image selected:") . "<br><br>\n" . implode("<br>\n", $profiles);
@@ -431,6 +432,10 @@
 		$h .= "<div id=\"sethostnamediv\">\n";
 		$h .= labeledFormItem('sethostname', i('Set Computer Hostname'), 'select', $yesno);
 		$h .= "</div>\n";
+		# Max reservation time
+		$tmp = array('0' => 'Default for User');
+		$lengths = $tmp + getReservationLengths(201600);
+		$h .= labeledFormItem('maxinitialtime', i('Max Reservation Duration'), 'select', $lengths);
 		# sysprep
 		if($add) {
 			$h .= "<div id=\"sysprepdiv\">\n";
@@ -799,14 +804,17 @@
 		# forcheckout
 		if($data['checkout'] != $olddata['forcheckout'])
 			$updates[] = "forcheckout = {$data['checkout']}";
+		# maxinitialtime
+		if($data['maxinitialtime'] != $olddata['maxinitialtime'])
+			$updates[] = "maxinitialtime = {$data['maxinitialtime']}";
 		# description
 		if($data['desc'] != $olddata['description']) {
-			$escdesc = mysql_real_escape_string($data['desc']);
+			$escdesc = vcl_mysql_escape_string($data['desc']);
 			$updates[] = "description = '$escdesc'";
 		}
 		# usage
 		if($data['usage'] != $olddata['usage']) {
-			$escusage = mysql_real_escape_string($data['usage']);
+			$escusage = vcl_mysql_escape_string($data['usage']);
 			$updates[] = "`usage` = '$escusage'";
 		}
 
@@ -821,7 +829,7 @@
 		if($olddata['ostype'] == 'windows') {
 			if($data['adauthenabled'] != $olddata['adauthenabled']) {
 				if($data['adauthenabled']) {
-					$esc_baseou = mysql_real_escape_string($data['baseou']);
+					$esc_baseou = vcl_mysql_escape_string($data['baseou']);
 					$query = "INSERT INTO imageaddomain "
 					       .        "(imageid, "
 					       .        "addomainid, "
@@ -841,7 +849,7 @@
 			elseif($data['adauthenabled'] &&
 			       ($data['addomainid'] != $olddata['addomainid'] ||
 			       $data['baseou'] != $olddata['baseOU'])) {
-				$esc_baseou = mysql_real_escape_string($data['baseou']);
+				$esc_baseou = vcl_mysql_escape_string($data['baseou']);
 				$query = "UPDATE imageaddomain "
 				       . "SET addomainid = {$data['addomainid']}, "
 				       .     "baseOU = '$esc_baseou' "
@@ -868,7 +876,7 @@
 					 .        "{$data['sethostname']})";
 			doQuery($query, 101);
 			$qh = doQuery("SELECT LAST_INSERT_ID() FROM imagemeta", 101);
-			if(! $row = mysql_fetch_row($qh))
+			if(! $row = mysqli_fetch_row($qh))
 				abort(101);
 			$imagemetaid = $row[0];
 			$query = "UPDATE image "
@@ -979,7 +987,7 @@
 		       .       "rq.id = rs.requestid";
 		doQuery($query, 101);
 
-		$agree = mysql_real_escape_string(getContinuationVar('agree'));
+		$agree = vcl_mysql_escape_string(getContinuationVar('agree'));
 		$query = "INSERT INTO clickThroughs "
 		       .        "(userid, "
 		       .        "imageid, "
@@ -1095,10 +1103,10 @@
 		       . "ORDER BY revision DESC "
 		       . "LIMIT 1";
 		$qh = doQuery($query, 101);
-		$row = mysql_fetch_assoc($qh);
+		$row = mysqli_fetch_assoc($qh);
 		$newrevision = $row['revision'] + 1;
 		$newname = preg_replace("/{$row['revision']}$/", $newrevision, $row['imagename']);
-		$comments = mysql_real_escape_string($comments);
+		$comments = vcl_mysql_escape_string($comments);
 		$query = "INSERT INTO imagerevision "
 		       .        "(imageid, "
 		       .        "revision, "
@@ -1155,7 +1163,7 @@
 		if($autocaptured)
 			return 1;
 	
-		$agree = mysql_real_escape_string(getContinuationVar('agree'));
+		$agree = vcl_mysql_escape_string(getContinuationVar('agree'));
 		$query = "INSERT INTO clickThroughs "
 		       .        "(userid, "
 		       .        "imageid, "
@@ -1188,9 +1196,9 @@
 	/////////////////////////////////////////////////////////////////////////////
 	function addResource($data) {
 		global $user;
-		$data['desc'] = mysql_real_escape_string($data['desc']);
-		$data['usage'] = mysql_real_escape_string($data['usage']);
-		$data['comments'] = mysql_real_escape_string($data['comments']);
+		$data['desc'] = vcl_mysql_escape_string($data['desc']);
+		$data['usage'] = vcl_mysql_escape_string($data['usage']);
+		$data['comments'] = vcl_mysql_escape_string($data['comments']);
 	
 		# get architecture of base image
 		$query = "SELECT i.architecture "
@@ -1199,7 +1207,7 @@
 		       . "WHERE ir.imageid = i.id AND "
 		       .       "ir.id = {$data['basedoffrevisionid']}";
 		$qh = doQuery($query);
-		$row = mysql_fetch_assoc($qh);
+		$row = mysqli_fetch_assoc($qh);
 		$arch = $row['architecture'];
 	
 		$ownerdata = getUserInfo($data['owner'], 1);
@@ -1244,7 +1252,7 @@
 
 		# ad authentication
 		if($data['adauthenabled']) {
-			$esc_baseou = mysql_real_escape_string($data['baseou']);
+			$esc_baseou = vcl_mysql_escape_string($data['baseou']);
 			$query = "INSERT INTO imageaddomain "
 			       .        "(imageid, "
 			       .        "addomainid, "
@@ -1554,7 +1562,7 @@
 				 . "FROM subimages "
 				 . "WHERE imagemetaid = $imagemetaid";
 		$qh = doQuery($query, 101);
-		$row = mysql_fetch_row($qh);
+		$row = mysqli_fetch_row($qh);
 		if($row[0] == 0) {
 			$rc = checkClearImageMeta($imagemetaid, $imageid, 'subimages');
 			if($rc)
@@ -1570,7 +1578,7 @@
 			$query = "SELECT imageid FROM subimages WHERE imagemetaid = $imagemetaid";
 			$qh = doQuery($query, 101);
 			$subimages = array();
-			while($row = mysql_fetch_assoc($qh))
+			while($row = mysqli_fetch_assoc($qh))
 				$subimages[] = $row['imageid'];
 		}
 	
@@ -1604,6 +1612,7 @@
 	/// \b checkuser - reservations should be checked for a logged in user\n
 	/// \b rootaccess\n
 	/// \b sysprep - use sysprep when capturing revisions of this image\n
+	/// \b maxinitialtime - max time in minutes reservation can be used\n
 	/// \b connectmethodids - ids of assigned connect methods\n
 	/// \b requestid - requestid associated with image capture\n
 	/// \b imageid - id of base image\n
@@ -1635,6 +1644,7 @@
 		$return["checkuser"] = processInputVar("checkuser", ARG_NUMERIC);
 		$return["rootaccess"] = processInputVar("rootaccess", ARG_NUMERIC);
 		$return["sethostname"] = processInputVar("sethostname", ARG_NUMERIC);
+		$return["maxinitialtime"] = processInputVar("maxinitialtime", ARG_NUMERIC);
 		$return["sysprep"] = processInputVar("sysprep", ARG_NUMERIC); # only in add
 		$return["connectmethodids"] = processInputVar("connectmethodids", ARG_STRING); # only in add
 		$return["adauthenabled"] = processInputVar("adauthenabled", ARG_NUMERIC);
@@ -1741,6 +1751,10 @@
 			$return['error'] = 1;
 			$errormsg[] = i("Set Computer Hostname must be Yes or No");
 		}
+		if($return['maxinitialtime'] < 0 || $return['maxinitialtime'] > 201600) {
+			$return['error'] = 1;
+			$errormsg[] = i("Invalid Max Reservation Duration selected");
+		}
 		if($return['mode'] == 'add' && $return['sysprep'] != 0 &&
 		   $return['sysprep'] != 1) {
 			$return['error'] = 1;
@@ -1827,7 +1841,7 @@
 		if(! empty($id))
 			$query .= " AND id != $id";
 		$qh = doQuery($query, 101);
-		if(mysql_num_rows($qh))
+		if(mysqli_num_rows($qh))
 			return 1;
 		return 0;
 	}
@@ -1857,7 +1871,7 @@
 		        . "WHERE name = '$nodename' AND "
 		        .       "parent = 3";
 		$qh = doQuery($query, 101);
-		if(! $row = mysql_fetch_assoc($qh)) {
+		if(! $row = mysqli_fetch_assoc($qh)) {
 			$query2 = "INSERT INTO privnode "
 			        .        "(parent, "
 			        .        "name) "
@@ -1866,7 +1880,7 @@
 			        .        "'$nodename')";
 			doQuery($query2, 101);
 			$qh = doQuery($query, 101);
-			$row = mysql_fetch_assoc($qh);
+			$row = mysqli_fetch_assoc($qh);
 		}
 		$parent = $row['id'];
 		$query = "SELECT id "
@@ -1874,7 +1888,7 @@
 		        . "WHERE name = '{$ownerdata['login']}-$ownerid' AND "
 		        .       "parent = $parent";
 		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_assoc($qh))
+		if($row = mysqli_fetch_assoc($qh))
 			$newnode = $row['id'];
 		else {
 			$query = "INSERT INTO privnode "
@@ -1882,7 +1896,7 @@
 			       . "VALUES ($parent, '{$ownerdata['login']}-$ownerid')";
 			doQuery($query, 101);
 			$qh = doQuery("SELECT LAST_INSERT_ID() FROM privnode", 101);
-			$row = mysql_fetch_row($qh);
+			$row = mysqli_fetch_row($qh);
 			$newnode = $row[0];
 		}
 	
@@ -1895,7 +1909,7 @@
 		        . "FROM usergroup "
 		        . "WHERE name = 'manageNewImages'";
 		$qh = doQuery($query, 101);
-		$row = mysql_fetch_assoc($qh);
+		$row = mysqli_fetch_assoc($qh);
 		$ownergroupid = $row['id'];
 		if($virtual)
 			$prefix = 'newvmimages';
@@ -1907,7 +1921,7 @@
 		       .       "ownerusergroupid = $ownergroupid AND "
 		       .       "resourcetypeid = 13";
 		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_assoc($qh))
+		if($row = mysqli_fetch_assoc($qh))
 			$resourcegroupid = $row['id'];
 		else {
 			$query = "INSERT INTO resourcegroup "
@@ -1919,7 +1933,7 @@
 			       .         "13)";
 			doQuery($query, 305);
 			$qh = doQuery("SELECT LAST_INSERT_ID() FROM resourcegroup", 101);
-			$row = mysql_fetch_row($qh);
+			$row = mysqli_fetch_row($qh);
 			$resourcegroupid = $row[0];
 	
 			// map group to newimages/newvmimages comp group
@@ -1932,7 +1946,7 @@
 			       . "WHERE name = '$rgroupname' AND "
 			       .       "resourcetypeid = 12";
 			$qh = doQuery($query, 101);
-			$row = mysql_fetch_assoc($qh);
+			$row = mysqli_fetch_assoc($qh);
 			$compResGrpid = $row['id'];
 			$query = "INSERT INTO resourcemap "
 			       .        "(resourcegroupid1, "
@@ -1980,7 +1994,7 @@
 		       . "WHERE resourcetypeid = 13 AND "
 		       .       "subid = $imageid";
 		$qh = doQuery($query);
-		if(! ($row = mysql_fetch_assoc($qh)))
+		if(! ($row = mysqli_fetch_assoc($qh)))
 			return;
 		$resid = $row['id'];
 		$olduserdata = getUserInfo($oldownerid, 1, 1);
@@ -1994,7 +2008,7 @@
 		       .       "rgm.resourcegroupid = rg.id AND "
 		       .       "rg.name IN ($oldgroups)";
 		$qh = doQuery($query);
-		if(! ($row = mysql_fetch_assoc($qh)))
+		if(! ($row = mysqli_fetch_assoc($qh)))
 			return;
 		$oldgroup = $row['name'];
 		$oldgroupid = $row['id'];
@@ -2108,7 +2122,7 @@
 			       .       "(cm.OStypeid = ot.id OR "
 			       .        "cm.OSid = o.id)";
 			$qh = doQuery($query, 101);
-			if(! (mysql_num_rows($qh))) {
+			if(! (mysqli_num_rows($qh))) {
 				# not enabled, add entry for method and image revision
 				$query = "INSERT INTO connectmethodmap "
 				       .        "(connectmethodid, "
@@ -2157,7 +2171,7 @@
 		$methods = getContinuationVar('methods');
 		$revids = getContinuationVar('revids');
 		$curmethods = getImageConnectMethods($imageid);
-		$remidlist = mysql_real_escape_string(processInputVar('ids', ARG_STRING));
+		$remidlist = vcl_mysql_escape_string(processInputVar('ids', ARG_STRING));
 		$remids = explode(',', $remidlist);
 		$revid = processInputVar('revid', ARG_NUMERIC);
 		$newimage = getContinuationVar('newimage');
@@ -2199,7 +2213,7 @@
 				       .       "(cm.OStypeid = ot.id OR "
 				       .        "cm.OSid = o.id)";
 				$qh = doQuery($query, 101);
-				if(mysql_num_rows($qh))
+				if(mysqli_num_rows($qh))
 					# if so, add disabled entry for image revision and method
 					$insvals[] = "($id, $revid, 1)";
 			}
@@ -2246,7 +2260,7 @@
 		$comments = htmlspecialchars($comments);
 		if(get_magic_quotes_gpc())
 			$comments = stripslashes($comments);
-		$comments = mysql_real_escape_string($comments);
+		$comments = vcl_mysql_escape_string($comments);
 		$query = "UPDATE imagerevision "
 		       . "SET comments = '$comments' "
 		       . "WHERE id = $revisionid";
@@ -2306,9 +2320,9 @@
 		       .       "rs.imagerevisionid IN ($checkedids) AND "
 		       .       "rq.stateid NOT IN (1, 5, 11, 12)";
 		$qh = doQuery($query);
-		if(mysql_num_rows($qh)) {
+		if(mysqli_num_rows($qh)) {
 			$inuseids = array();
-			while($row = mysql_fetch_assoc($qh))
+			while($row = mysqli_fetch_assoc($qh))
 				$inuseids[] = $row['revision'];
 			$inuseids = implode(',', $inuseids);
 			$rc = array('status' => 'error',
diff --git a/web/.ht-inc/managementnode.php b/web/.ht-inc/managementnode.php
index 2b5b08e..dd49e2c 100644
--- a/web/.ht-inc/managementnode.php
+++ b/web/.ht-inc/managementnode.php
@@ -203,7 +203,7 @@
 		       . "ORDER BY rq.end DESC "
 		       . "LIMIT 1";
 		$qh = doQuery($query);
-		if($row = mysql_fetch_assoc($qh))
+		if($row = mysqli_fetch_assoc($qh))
 			$msgs[] = "There is at least one <strong>reservation</strong> being processed by this management node. The latest end time is " . prettyDatetime($row['end'], 1) . '.';
 
 		# check blockRequest
@@ -219,7 +219,7 @@
 		       . "ORDER BY bt.end DESC "
 		       . "LIMIT 1";
 		$qh = doQuery($query);
-		if($row = mysql_fetch_assoc($qh))
+		if($row = mysqli_fetch_assoc($qh))
 			$msgs[] = "There is at least one <strong>Block Allocation</strong> being handled by this management node. Block Allocation \"{$row['name']}\" has the latest end time which is " . prettyDatetime($row['end'], 1) . '.';
 
 
@@ -246,7 +246,7 @@
 	function toggleDeleteResource($rscid) {
 		$query = "SELECT stateid FROM managementnode WHERE id = $rscid";
 		$qh = doQuery($query);
-		if($row = mysql_fetch_assoc($qh)) {
+		if($row = mysqli_fetch_assoc($qh)) {
 			if($row['stateid'] == 1)
 				$query = "UPDATE managementnode SET stateid = 10 WHERE id = $rscid";
 			else
@@ -514,8 +514,8 @@
 			}
 		}
 		else {
-			$esc = array('sysadminemail' => mysql_real_escape_string($data['sysadminemail']),
-			             'sharedmailbox' => mysql_real_escape_string($data['sharedmailbox']));
+			$esc = array('sysadminemail' => vcl_mysql_escape_string($data['sysadminemail']),
+			             'sharedmailbox' => vcl_mysql_escape_string($data['sharedmailbox']));
 
 			$olddata = getContinuationVar('olddata');
 			$updates = array();
@@ -992,7 +992,7 @@
 				       .       "rq.laststateid NOT IN (1,5,11,12) AND "
 				       .       "rq.userid != $vclreloadid";
 				$qh = doQuery($query);
-				if(mysql_num_rows($qh)) {
+				if(mysqli_num_rows($qh)) {
 					$return['error'] = 1;
 					$errormsg[] = "This management node is the NAT host for computers that have active reservations. NAT host<br>settings cannot be changed while providing NAT for active reservations.";
 				}
@@ -1020,8 +1020,8 @@
 	function addResource($data) {
 		global $user;
 		$ownerid = getUserlistID($data['owner']);
-		$esc = array('sysadminemail' => mysql_real_escape_string($data['sysadminemail']),
-		             'sharedmailbox' => mysql_real_escape_string($data['sharedmailbox']));
+		$esc = array('sysadminemail' => vcl_mysql_escape_string($data['sysadminemail']),
+		             'sharedmailbox' => vcl_mysql_escape_string($data['sharedmailbox']));
 		$keys = array('IPaddress',            'hostname',
 		              'ownerid',              'stateid',
 		              'checkininterval',      'installpath',
@@ -1116,7 +1116,7 @@
 		if($id != 0)
 			$query .= " AND id != $id";
 		$qh = doQuery($query);
-		return mysql_num_rows($qh);
+		return mysqli_num_rows($qh);
 	}
 }
 ?>
diff --git a/web/.ht-inc/oneclick.php b/web/.ht-inc/oneclick.php
index e478fcd..d8b62c9 100755
--- a/web/.ht-inc/oneclick.php
+++ b/web/.ht-inc/oneclick.php
@@ -57,7 +57,7 @@
 	       .       "o.userid = {$user['id']}";
 	$oneclicks = array();
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$oneclicks[$row['id']] = $row;
 
 	print "<H2>" . i("VCL go Configurator") . "</H2>\n";
@@ -322,7 +322,7 @@
 	$qh = doQuery($query, 101);
 	print "<form action=\"" . BASEURL . SCRIPT . "\" method=\"post\" style=\"display: inline;\" onsubmit=\"return validateForm(this);\">\n";
 
-	if(! ($row = mysql_fetch_assoc($qh))) {
+	if(! ($row = mysqli_fetch_assoc($qh))) {
 		print i("VCL go not found") . "\n";
 		return NULL;
 	}
diff --git a/web/.ht-inc/privileges.php b/web/.ht-inc/privileges.php
index 92f6ee3..165e14b 100644
--- a/web/.ht-inc/privileges.php
+++ b/web/.ht-inc/privileges.php
@@ -256,7 +256,7 @@
 		       . "ORDER BY name";
 		$qh = doQuery($query);
 		$orderedgroups = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$orderedgroups[] = $row['id'];
 		foreach($orderedgroups as $id) {
 			printUserPrivRow($id, $i, $privs["usergroups"], $usertypes["users"],
@@ -965,7 +965,7 @@
 		       . "ORDER BY name";
 		$qh = doQuery($query);
 		$orderedgroups = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$orderedgroups[] = $row['id'];
 		foreach($orderedgroups as $id) {
 			$tmpArr = getUserPrivRowHTML($id, $i, $privs["usergroups"],
@@ -1125,7 +1125,7 @@
 	$query = "SELECT id, parent FROM privnode WHERE id > " . DEFAULT_PRIVNODE;
 	$qh = doQuery($query);
 	$data = 'nodedropdata = {';
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		if(checkUserHasPriv('nodeAdmin', $user['id'], $row['id']) &&
 		   ($row['parent'] == DEFAULT_PRIVNODE || checkUserHasPriv('nodeAdmin', $user['id'], $row['parent'])))
 			$data .= "{$row['id']}: '1',";
@@ -1183,7 +1183,7 @@
 	       . "WHERE name = '$newnode' AND "
 	       .       "parent = $parent";
 	$qh = doQuery($query, 335);
-	if(mysql_num_rows($qh)) {
+	if(mysqli_num_rows($qh)) {
 		$text = "A node of that name already exists "
 		      . "under " . $nodeInfo["name"];
 		print "dojo.byId('addChildNodeStatus').innerHTML = '$text';";
@@ -1198,7 +1198,7 @@
 	doQuery($query, 336);
 
 	$qh = doQuery("SELECT LAST_INSERT_ID() FROM privnode", 101);
-	if(! $row = mysql_fetch_row($qh))
+	if(! $row = mysqli_fetch_row($qh))
 		abort(101);
 	$nodeid = $row[0];
 
@@ -1228,7 +1228,7 @@
 function nodeExists($node) {
 	$query = "SELECT id FROM privnode WHERE id = $node";
 	$qh = doQuery($query, 101);
-	if(mysql_num_rows($qh))
+	if(mysqli_num_rows($qh))
 		return 1;
 	else
 		return 0;
@@ -1313,13 +1313,13 @@
 		return;
 	}
 	# check if node matching new name already exists at parent
-	$_newname = mysql_real_escape_string($newname);
+	$_newname = vcl_mysql_escape_string($newname);
 	$query = "SELECT id "
 	       . "FROM privnode "
 	       . "WHERE parent = (SELECT parent FROM privnode WHERE id = $activeNode) AND "
 	       .       "name = '$_newname'";
 	$qh = doQuery($query, 101);
-	if(mysql_num_rows($qh)) {
+	if(mysqli_num_rows($qh)) {
 		$msg = i("A sibling node of that name currently exists");
 		$arr = array('error' => 2, 'message' => $msg);
 		sendJSON($arr);
@@ -1372,7 +1372,7 @@
 	       .       "p2.parent = $newparentid AND "
 	       .       "p2.name = p1.name";
 	$qh = doQuery($query);
-	if($row = mysql_num_rows($qh)) {
+	if($row = mysqli_num_rows($qh)) {
 		$arr = array('status' => 'collision',
 		             'moveid' => $moveid,
 		             'oldparentid' => $oldparentid,
@@ -1494,7 +1494,7 @@
 	print "<INPUT type=hidden name=continuation value=\"$cont\">\n";
 	print "</FORM><br>\n";
 	if(! empty($userid)) {
-		$esc_userid = mysql_real_escape_string($userid);
+		$esc_userid = vcl_mysql_escape_string($userid);
 		if(preg_match('/,/', $userid)) {
 			$mode = 'name';
 			$force = 0;
@@ -1517,8 +1517,8 @@
 		}
 		else {
 			$tmp = explode(',', $userid);
-			$last = mysql_real_escape_string(trim($tmp[0]));
-			$first = mysql_real_escape_string(trim($tmp[1]));
+			$last = vcl_mysql_escape_string(trim($tmp[0]));
+			$first = vcl_mysql_escape_string(trim($tmp[1]));
 			$query = "SELECT CONCAT(u.unityid, '@', a.name) AS unityid "
 			       . "FROM user u, "
 			       .      "affiliation a "
@@ -1528,7 +1528,7 @@
 			       .       "a.id = $affilid";
 		}
 		$qh = doQuery($query, 101);
-		if(! mysql_num_rows($qh)) {
+		if(! mysqli_num_rows($qh)) {
 			if($mode == 'name') {
 				print "<font color=red>User not found</font><br>\n";
 				return;
@@ -1538,13 +1538,13 @@
 		}
 		elseif($force) {
 			$_SESSION['userresources'] = array();
-			$row = mysql_fetch_assoc($qh);
+			$row = mysqli_fetch_assoc($qh);
 			$newtime = unixToDatetime(time() - SECINDAY - 5);
 			$query = "UPDATE user SET lastupdated = '$newtime' WHERE id = {$row['id']}";
 			doQuery($query, 101);
 		}
 		elseif($mode == 'name') {
-			$row = mysql_fetch_assoc($qh);
+			$row = mysqli_fetch_assoc($qh);
 			$userid = $row['unityid'];
 			$esc_userid = $row['unityid'];
 		}
@@ -1659,11 +1659,11 @@
 		       . "ORDER BY p.name, "
 		       .          "upt.name";
 		$qh = doQuery($query, 101);
-		if(mysql_num_rows($qh)) {
+		if(mysqli_num_rows($qh)) {
 			print "Nodes where user is granted privileges:<br>\n";
 			print "<TABLE>\n";
 			$privnodeid = 0;
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				if($privnodeid != $row['privnodeid']) {
 					if($privnodeid) {
 						print "    </TD>\n";
@@ -1699,11 +1699,11 @@
 			       . "ORDER BY p.name, "
 			       .          "upt.name";
 			$qh = doQuery($query, 101);
-			if(mysql_num_rows($qh)) {
+			if(mysqli_num_rows($qh)) {
 				print "Nodes where user's groups are granted privileges:<br>\n";
 				print "<TABLE>\n";
 				$privnodeid = 0;
-				while($row = mysql_fetch_assoc($qh)) {
+				while($row = mysqli_fetch_assoc($qh)) {
 					if($privnodeid != $row['privnodeid']) {
 						if($privnodeid) {
 							print "    </TD>\n";
@@ -1749,7 +1749,7 @@
 		       . "LIMIT 8";
 		$logins = array();
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$logins[] = $row;
 		if(count($logins)) {
 			$logins = array_reverse($logins);
@@ -1814,7 +1814,7 @@
 		       . "ORDER BY l.start DESC "
 		       . "LIMIT 5";
 		$qh = doQuery($query, 290);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			array_push($requests, $row);
 		$requests = array_reverse($requests);
 		if(! empty($requests)) {
@@ -1924,7 +1924,7 @@
 		       . "GROUP BY rq.id "
 		       . "ORDER BY rq.start";
 		$qh = doQuery($query, 290);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			array_push($requests, $row);
 		$requests = array_reverse($requests);
 		if(! empty($requests)) {
@@ -2054,7 +2054,7 @@
 			       . "GROUP BY rq.id "
 			       . "ORDER BY rq.start";
 			$qh = doQuery($query, 290);
-			while($row = mysql_fetch_assoc($qh))
+			while($row = mysqli_fetch_assoc($qh))
 				array_push($requests, $row);
 			$requests = array_reverse($requests);
 			if(! empty($requests)) {
@@ -2156,7 +2156,7 @@
 function recurseGetChildren($node) {
 	$children = array();
 	$qh = doQuery("SELECT id FROM privnode WHERE parent = $node", 340);
-	while($row = mysql_fetch_row($qh)) {
+	while($row = mysqli_fetch_row($qh)) {
 		array_push($children, $row[0]);
 		$children = array_merge($children, recurseGetChildren($row[0]));
 	}
@@ -2444,7 +2444,7 @@
 	       . "LEFT JOIN usergroup g2 ON (g.editusergroupid = g2.id) "
 	       . "WHERE g.id = $usergrpid";
 	$qh = doQuery($query, 101);
-	if(! ($grpdata = mysql_fetch_assoc($qh))) {
+	if(! ($grpdata = mysqli_fetch_assoc($qh))) {
 		# problem getting group members
 		$msg = 'failed to fetch group members';
 		$arr = array('members' => $msg, 'domid' => $domid);
@@ -2620,7 +2620,7 @@
 	       . "WHERE rg.id = $resgrpid AND "
 	       .       "rg.resourcetypeid = rt.id";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh)) {
+	if($row = mysqli_fetch_assoc($qh)) {
 		$type = $row['name'];
 		if($type == 'computer' || $type == 'managementnode')
 			$field = 'hostname';
@@ -2639,7 +2639,7 @@
 			$query .= " AND t.deleted = 0";
 		$qh = doQuery($query, 101);
 		$members = '';
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$members .= "{$row['item']}<br>";
 		if($members == '')
 			$members = '(empty group)';
@@ -2719,7 +2719,7 @@
 		       .       "g.resourcetypeid = t.id "
 		       . "ORDER BY p.privnodeid";
 		$qh = doQuery($query, 350);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			$resourcedata[$row['privnodeid']][] = $row;
 		}
 	}
@@ -2746,7 +2746,7 @@
 		       .       "u.affiliationid = a.id "
 		       . "ORDER BY u.unityid";
 		$qh = doQuery($query, 351);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$privs['users'][$row['unityid']][$row['name']] = 1;
 	}
 	if($type == "usergroups" || $type == "all") {
@@ -2766,7 +2766,7 @@
 		       .       "up.usergroupid IS NOT NULL "
 		       . "ORDER BY g.name";
 		$qh = doQuery($query, 352);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			if(isset($privs["usergroups"][$row["id"]]))
 				$privs["usergroups"][$row["id"]]['privs'][$row['priv']] = 1;
 			else
@@ -2849,7 +2849,7 @@
 		       .       "g.resourcetypeid = t.id AND "
 		       .       "p.type = 'block'";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			if(! isset($allblockdata[$row['privnodeid']]))
 				$allblockdata[$row['privnodeid']] = array();
 			# TODO adding the id at the end will fix the bug where blocking cascaded resource
@@ -2888,7 +2888,7 @@
 		       .       "p.privnodeid = p2.privnodeid AND "
 		       .       "p2.type = 'cascade'";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			if(! isset($allcascadedata[$row['privnodeid']]))
 				$allcascadedata[$row['privnodeid']] = array();
 			$allcascadedata[$row['privnodeid']][] =
@@ -2939,7 +2939,7 @@
 			       .       "t.name = 'block' AND "
 			       .       "u.affiliationid = a.id";
 			$qh = doQuery($query, 355);
-			while($row = mysql_fetch_row($qh))
+			while($row = mysqli_fetch_row($qh))
 				$nodeuserblock[$row[0]][$row[1]] = 1;
 		}
 		static $nodeusercasade;
@@ -2967,7 +2967,7 @@
 			       . 		"up.userid = Cup.userid "
 			       . "ORDER BY up.privnodeid, u.unityid, t.name";
 			$qh = doQuery($query, 356);
-			while($row = mysql_fetch_row($qh))
+			while($row = mysqli_fetch_row($qh))
 				$nodeusercascade[$row[0]][$row[1]][$row[2]] = 1;
 		}
 		$mynodelist = $nodelist;
@@ -3005,7 +3005,7 @@
 			       .       "up.usergroupid IS NOT NULL AND "
 			       .       "t.name = 'block'";
 			$qh = doQuery($query, 357);
-			while($row = mysql_fetch_row($qh))
+			while($row = mysqli_fetch_row($qh))
 				$nodegroupblock[$row[0]][$row[1]] = 1;
 		}
 		static $nodegroupcascade;
@@ -3035,7 +3035,7 @@
 			       . 		"up.usergroupid = Cup.usergroupid "
 			       . "ORDER BY up.privnodeid, g.id, t.name";
 			$qh = doQuery($query, 356);
-			while($row = mysql_fetch_row($qh)) {
+			while($row = mysqli_fetch_row($qh)) {
 				if(! isset($nodegroupcascade[$row[0]][$row[1]])) {
 					$nodegroupcascade[$row[0]][$row[1]] = array('id' => $row[1],
 						                                         'name' => $row[2],
diff --git a/web/.ht-inc/requests.php b/web/.ht-inc/requests.php
index b163c42..565c53c 100644
--- a/web/.ht-inc/requests.php
+++ b/web/.ht-inc/requests.php
@@ -385,7 +385,7 @@
 					       . "WHERE v.id = {$requests[$i]['vmhostid']} AND "
 					       .       "v.computerid = c.id";
 					$qh = doQuery($query, 101);
-					$row = mysql_fetch_assoc($qh);
+					$row = mysqli_fetch_assoc($qh);
 					$vmhost = $row['hostname'];
 				}
 				$text .= "    <TD align=center><a id=\"req{$requests[$i]['id']}\" ";
@@ -2410,7 +2410,7 @@
 		}
 		else {
 			$fields[] = 'name';
-			$name = mysql_real_escape_string($data['name']);
+			$name = vcl_mysql_escape_string($data['name']);
 			$values[] = "'$name'";
 		}
 		if($data['ipaddr'] != '') {
@@ -2472,7 +2472,7 @@
 	       . "ORDER BY id";
 	$qh = doQuery($query);
 	$resids = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if(! array_key_exists($row['imageid'], $resids))
 			$resids[$row['imageid']] = array();
 		$resids[$row['imageid']][] = $row['id'];
@@ -2528,7 +2528,7 @@
 			if(array_key_exists("$cfgsubimgid/$mapid", $vars)) {
 				$sets = array();
 				foreach($vars["$cfgsubimgid/$mapid"] as $varid => $varval) {
-					$_val = mysql_real_escape_string($varval['value']);
+					$_val = vcl_mysql_escape_string($varval['value']);
 					$sets[] = "($instid, $varid, '$_val')";
 				}
 				$query = $qbase2 . implode(',', $sets);
@@ -2781,7 +2781,7 @@
 			       .       "reservationid = {$request['resid']} AND "
 			       .       "timestamp = '" . unixToDatetime($data['ts']) . "'";
 			$qh = doQuery($query, 101);
-			if($row = mysql_fetch_assoc($qh)) {
+			if($row = mysqli_fetch_assoc($qh)) {
 				$reason = $row['additionalinfo'];
 				$text .= "<br>" . i("retrying at state") . " \"$reason\"";
 			}
@@ -2865,7 +2865,7 @@
 				       . "ORDER BY id "
 				       . "LIMIT 1";
 				$qh = doQuery($query, 101);
-				if($row = mysql_fetch_assoc($qh)) {
+				if($row = mysqli_fetch_assoc($qh)) {
 					$reason = $row['additionalInfo'];
 					if(! empty($data))
 						$currtime = $row['ts'] - $data['ts'];
@@ -3353,8 +3353,12 @@
 		return;
 	}
 	# check for max time being reached
+	$imgdata = getImages(1, $request['reservations'][0]['imageid']);
+	$maximglen = $imgdata[$request['reservations'][0]['imageid']]['maxinitialtime'];
 	if($request['forimaging'] && $maxtimes['total'] < 720)
 		$maxcheck = 720;
+	elseif(! $request['forimaging'] && $maximglen)
+		$maxcheck = $maximglen;
 	else
 		$maxcheck = $maxtimes['total'];
 	if(! $openend && ($reslen >= $maxcheck)) {
@@ -3410,6 +3414,11 @@
 	$lengths = array();
 	if($request['forimaging'] && $maxtimes['total'] < 720) # make sure at least 12 hours available for imaging reservations
 		$maxtimes['total'] = 720;
+	elseif(! $request['forimaging'] && $maximglen) {
+		$maxtimes['total'] = $maximglen;
+		$currduration = (datetimeToUnix($request['end']) - datetimeToUnix($request['start'])) / 60;
+		$maxtimes['extend'] = $maximglen - $currduration;
+	}
 	if($timeToNext == -1) {
 		if($nousercheck)
 			$lengths["0"] = "No change";
@@ -3732,7 +3741,7 @@
 			return;
 		}
 		if($servername != $request['servername']) {
-			$servername = mysql_real_escape_string($servername);
+			$servername = vcl_mysql_escape_string($servername);
 			$updateservername = 1;
 		}
 	}
@@ -4132,7 +4141,7 @@
 	if($request['serverrequest']) {
 		$query = "SELECT id FROM serverrequest WHERE requestid = $requestid";
 		$qh = doQuery($query);
-		if($row = mysql_fetch_assoc($qh)) {
+		if($row = mysqli_fetch_assoc($qh)) {
 			$query = "DELETE FROM serverrequest WHERE requestid = $requestid";
 			doQuery($query, 152);
 			deleteVariable("fixedIPsr{$row['id']}");
@@ -4955,7 +4964,7 @@
 	       . "ORDER BY cll.timestamp DESC "
 	       . "LIMIT 1";
 	$qh = doQuery($query);
-	if($row = mysql_fetch_assoc($qh)) {
+	if($row = mysqli_fetch_assoc($qh)) {
 		if(! is_numeric($row['timestamp']))
 			return NULL;
 		if($row['loadstatename'] == 'acknowledgetimeout')
diff --git a/web/.ht-inc/resource.php b/web/.ht-inc/resource.php
index cecd2bb..cc55d09 100644
--- a/web/.ht-inc/resource.php
+++ b/web/.ht-inc/resource.php
@@ -574,7 +574,7 @@
 			       . "FROM `{$this->restype}` "
 			       . "WHERE id = $rscid";
 			$qh = doQuery($query);
-			if($row = mysql_fetch_assoc($qh)) {
+			if($row = mysqli_fetch_assoc($qh)) {
 				$newval = (int)(! (int)$row['deleted']);
 				$query = "UPDATE {$this->restype} "
 				       . "SET deleted = $newval "
@@ -1628,7 +1628,7 @@
 		if($id)
 			$query .= " AND id != $id";
 		$qh = doQuery($query);
-		if(mysql_num_rows($qh))
+		if(mysqli_num_rows($qh))
 			return 1;
 		return 0;
 	}
diff --git a/web/.ht-inc/schedule.php b/web/.ht-inc/schedule.php
index 57da520..d0760e8 100644
--- a/web/.ht-inc/schedule.php
+++ b/web/.ht-inc/schedule.php
@@ -188,7 +188,7 @@
 		       .       "deleted = 0";
 		$qh = doQuery($query);
 		$comps = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$comps[] = $row['hostname'];
 		if(count($comps))
 			$msg = "This schedule cannot be deleted because the following <strong>computers</strong> have it selected as their schedule:<br><br>\n" . implode("<br>\n", $comps);
@@ -445,7 +445,7 @@
 		if(! empty($id))
 			$query .= " AND id != $id";
 		$qh = doQuery($query, 101);
-		if(mysql_num_rows($qh))
+		if(mysqli_num_rows($qh))
 			return 1;
 		return 0;
 	}
diff --git a/web/.ht-inc/secrets-default.php b/web/.ht-inc/secrets-default.php
index abaa171..d6e3b0b 100644
--- a/web/.ht-inc/secrets-default.php
+++ b/web/.ht-inc/secrets-default.php
@@ -21,7 +21,7 @@
 $vclusername = 'vcluser';      # username to access database
 $vclpassword = '';      # password to access database
 
-$cryptkey  = ''; # generate with "openssl rand 32 | base64"
+$cryptkey = ''; # generate with "openssl rand 32 | base64"
 
 $pemkey = ''; # random passphrase - won't ever have to type it so make it long
 ?>
diff --git a/web/.ht-inc/serverprofiles.php b/web/.ht-inc/serverprofiles.php
index 951789e..2de4826 100644
--- a/web/.ht-inc/serverprofiles.php
+++ b/web/.ht-inc/serverprofiles.php
@@ -523,10 +523,10 @@
 		sendJSON($data);
 		return;
 	}
-	$name = mysql_real_escape_string($data['name']);
-	$desc = mysql_real_escape_string($data['desc']);
-	$fixedIP = mysql_real_escape_string($data['fixedIP']);
-	$fixedMAC = mysql_real_escape_string($data['fixedMAC']);
+	$name = vcl_mysql_escape_string($data['name']);
+	$desc = vcl_mysql_escape_string($data['desc']);
+	$fixedIP = vcl_mysql_escape_string($data['fixedIP']);
+	$fixedMAC = vcl_mysql_escape_string($data['fixedMAC']);
 	$ret = array();
 	if($data['profileid'] == 70000) {
 		$query = "INSERT INTO serverprofile "
@@ -626,7 +626,7 @@
 	}
 	$query = "DELETE FROM serverprofile WHERE id = $profileid";
 	doQuery($query, 101);
-	$rows = mysql_affected_rows();
+	$rows = mysqli_affected_rows();
 	if($rows == 0) {
 		$data = array('error' => 1,
 		              'msg' => 'Failed to delete selected server profile');
@@ -864,7 +864,7 @@
 	}
 	$qh = doQuery($query, 101);
 	$groups = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$groups[$row['id']] = $row['name'];
 	$_SESSION['usersessiondata'][$key] = $groups;
 	return $groups;
diff --git a/web/.ht-inc/siteconfig.php b/web/.ht-inc/siteconfig.php
index 96aedda..27d6e0f 100644
--- a/web/.ht-inc/siteconfig.php
+++ b/web/.ht-inc/siteconfig.php
@@ -1292,7 +1292,7 @@
 		$this->values = array();
 		$query = "SELECT id, helpaddress FROM affiliation ORDER BY name";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$this->values[$row['id']] = $row['helpaddress'];
 	}
 
@@ -1310,18 +1310,18 @@
 	///
 	/////////////////////////////////////////////////////////////////////////////
 	function setValue($affilid, $value) {
-		global $mysql_link_vcl;
+		global $mysqli_link_vcl;
 		if($value === NULL)
 			$newval = 'NULL';
 		else {
-			$esc_value = mysql_real_escape_string($value);
+			$esc_value = vcl_mysql_escape_string($value);
 			$newval = "'$esc_value'";
 		}
 		$query = "UPDATE affiliation "
 		       . "SET helpaddress = $newval "
 		       . "WHERE id = $affilid";
 		doQuery($query);
-		$rc = mysql_affected_rows($mysql_link_vcl);
+		$rc = mysqli_affected_rows($mysqli_link_vcl);
 		if($rc == 1)
 			return 1;
 		return 0;
@@ -1339,12 +1339,12 @@
 	///
 	/////////////////////////////////////////////////////////////////////////////
 	function deleteValue($affilid) {
-		global $mysql_link_vcl;
+		global $mysqli_link_vcl;
 		$query = "UPDATE affiliation "
 		       . "SET helpaddress = NULL "
 		       . "WHERE id = $affilid";
 		doQuery($query);
-		$rc = mysql_affected_rows($mysql_link_vcl);
+		$rc = mysqli_affected_rows($mysqli_link_vcl);
 		if($rc == 1)
 			return 1;
 		return 0;
@@ -1391,7 +1391,7 @@
 		$this->values = array();
 		$query = "SELECT id, sitewwwaddress FROM affiliation ORDER BY name";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$this->values[$row['id']] = $row['sitewwwaddress'];
 	}
 
@@ -1409,18 +1409,18 @@
 	///
 	/////////////////////////////////////////////////////////////////////////////
 	function setValue($affilid, $value) {
-		global $mysql_link_vcl;
+		global $mysqli_link_vcl;
 		if($value === NULL)
 			$newval = 'NULL';
 		else {
-			$esc_value = mysql_real_escape_string($value);
+			$esc_value = vcl_mysql_escape_string($value);
 			$newval = "'$esc_value'";
 		}
 		$query = "UPDATE affiliation "
 		       . "SET sitewwwaddress = $newval "
 		       . "WHERE id = $affilid";
 		doQuery($query);
-		$rc = mysql_affected_rows($mysql_link_vcl);
+		$rc = mysqli_affected_rows($mysqli_link_vcl);
 		if($rc == 1)
 			return 1;
 		return 0;
@@ -1438,12 +1438,12 @@
 	///
 	/////////////////////////////////////////////////////////////////////////////
 	function deleteValue($affilid) {
-		global $mysql_link_vcl;
+		global $mysqli_link_vcl;
 		$query = "UPDATE affiliation "
 		       . "SET sitewwwaddress = NULL "
 		       . "WHERE id = $affilid";
 		doQuery($query);
-		$rc = mysql_affected_rows($mysql_link_vcl);
+		$rc = mysqli_affected_rows($mysqli_link_vcl);
 		if($rc == 1)
 			return 1;
 		return 0;
@@ -1498,7 +1498,7 @@
 		       . "LEFT JOIN winKMS k ON (k.affiliationid = a.id) "
 		       . "ORDER BY a.id";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			if(is_null($row['address']) && is_null($row['port'])) {
 				$this->values[$row['id']] = NULL;
 				continue;
@@ -1529,7 +1529,7 @@
 	///
 	/////////////////////////////////////////////////////////////////////////////
 	function setValue($affilid, $value) {
-		global $mysql_link_vcl;
+		global $mysqli_link_vcl;
 		$this->getValues();
 		$values = explode(',', $value);
 		# create datastructure of newly submitted hosts
@@ -1588,7 +1588,7 @@
 		# insert new hosts
 		$values = array();
 		foreach($adds as $host => $port) {
-			$esc_host = mysql_real_escape_string($host);
+			$esc_host = vcl_mysql_escape_string($host);
 			$values[] = "($affilid, '$esc_host', $port)";
 		}
 		$rc1 = 1;
@@ -1597,25 +1597,25 @@
 			       . "(affiliationid, address, port) "
 			       . "VALUES " . implode(',', $values);
 			doQuery($query);
-			$rc1 = mysql_affected_rows($mysql_link_vcl);
+			$rc1 = mysqli_affected_rows($mysqli_link_vcl);
 		}
 		# make changes
 		$rc2 = 1;
 		foreach($changes as $host => $port) {
-			$esc_host = mysql_real_escape_string($host);
+			$esc_host = vcl_mysql_escape_string($host);
 			$query = "UPDATE winKMS "
 			       . "SET port = $port "
 			       . "WHERE address = '$esc_host' AND "
 			       .       "affiliationid = $affilid";
 			doQuery($query);
-			$tmp = mysql_affected_rows($mysql_link_vcl);
+			$tmp = mysqli_affected_rows($mysqli_link_vcl);
 			if($rc2)
 				$rc2 = $tmp;
 		}
 		# delete old hosts
 		$values = array();
 		foreach($rems as $host => $port) {
-			$esc_host = mysql_real_escape_string($host);
+			$esc_host = vcl_mysql_escape_string($host);
 			$values[] = "(affiliationid = $affilid AND "
 			          . "address = '$esc_host' AND "
 			          . "port = $port)";
@@ -1625,7 +1625,7 @@
 			$query = "DELETE FROM winKMS "
 			       . "WHERE " . implode(' OR ', $values);
 			doQuery($query);
-			$rc3 = mysql_affected_rows($mysql_link_vcl);
+			$rc3 = mysqli_affected_rows($mysqli_link_vcl);
 		}
 		if($rc1 == 0 || $rc2 == 0 || $rc3 == 0)
 			return 0;
@@ -1644,11 +1644,11 @@
 	///
 	/////////////////////////////////////////////////////////////////////////////
 	function deleteValue($affilid) {
-		global $mysql_link_vcl;
+		global $mysqli_link_vcl;
 		$query = "DELETE FROM winKMS "
 		       . "WHERE affiliationid = $affilid";
 		doQuery($query);
-		$rc = mysql_affected_rows($mysql_link_vcl);
+		$rc = mysqli_affected_rows($mysqli_link_vcl);
 		if($rc == 1)
 			return 1;
 		return 0;
@@ -1715,7 +1715,7 @@
 		$this->values = array();
 		$query = "SELECT id, theme FROM affiliation ORDER BY name";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$this->values[$row['id']] = $row['theme'];
 	}
 
@@ -1733,13 +1733,13 @@
 	///
 	/////////////////////////////////////////////////////////////////////////////
 	function setValue($affilid, $value) {
-		global $mysql_link_vcl;
-		$esc_value = mysql_real_escape_string($value);
+		global $mysqli_link_vcl;
+		$esc_value = vcl_mysql_escape_string($value);
 		$query = "UPDATE affiliation "
 		       . "SET theme = '$esc_value' "
 		       . "WHERE id = $affilid";
 		doQuery($query);
-		$rc = mysql_affected_rows($mysql_link_vcl);
+		$rc = mysqli_affected_rows($mysqli_link_vcl);
 		if($rc == 1)
 			return 1;
 		return 0;
@@ -1757,12 +1757,12 @@
 	///
 	/////////////////////////////////////////////////////////////////////////////
 	function deleteValue($affilid) {
-		global $mysql_link_vcl;
+		global $mysqli_link_vcl;
 		$query = "UPDATE affiliation "
 		       . "SET theme = NULL "
 		       . "WHERE id = $affilid";
 		doQuery($query);
-		$rc = mysql_affected_rows($mysql_link_vcl);
+		$rc = mysqli_affected_rows($mysqli_link_vcl);
 		if($rc == 1)
 			return 1;
 		return 0;
@@ -1834,7 +1834,7 @@
 		       . "WHERE name NOT IN ('Global', 'Local') "
 		       . "ORDER BY name";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$this->values[$row['id']] = (int)(! $row['shibonly']);
 	}
 
@@ -1852,13 +1852,13 @@
 	///
 	/////////////////////////////////////////////////////////////////////////////
 	function setValue($affilid, $value) {
-		global $mysql_link_vcl;
+		global $mysqli_link_vcl;
 		$value = (int)(! $value);
 		$query = "UPDATE affiliation "
 		       . "SET shibonly = $value "
 		       . "WHERE id = $affilid";
 		doQuery($query);
-		$rc = mysql_affected_rows($mysql_link_vcl);
+		$rc = mysqli_affected_rows($mysqli_link_vcl);
 		if($rc == 1)
 			return 1;
 		return 0;
@@ -1944,7 +1944,7 @@
 		       . "WHERE name NOT IN ('Global', 'Local') "
 		       . "ORDER BY name";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$this->values[$row['id']] = $row['shibname'];
 	}
 
@@ -1962,18 +1962,18 @@
 	///
 	/////////////////////////////////////////////////////////////////////////////
 	function setValue($affilid, $value) {
-		global $mysql_link_vcl;
+		global $mysqli_link_vcl;
 		if($value === NULL)
 			$newval = 'NULL';
 		else {
-			$esc_value = mysql_real_escape_string($value);
+			$esc_value = vcl_mysql_escape_string($value);
 			$newval = "'$esc_value'";
 		}
 		$query = "UPDATE affiliation "
 		       . "SET shibname = $newval "
 		       . "WHERE id = $affilid";
 		doQuery($query);
-		$rc = mysql_affected_rows($mysql_link_vcl);
+		$rc = mysqli_affected_rows($mysqli_link_vcl);
 		if($rc == 1)
 			return 1;
 		return 0;
@@ -1991,12 +1991,12 @@
 	///
 	/////////////////////////////////////////////////////////////////////////////
 	function deleteValue($affilid) {
-		global $mysql_link_vcl;
+		global $mysqli_link_vcl;
 		$query = "UPDATE affiliation "
 		       . "SET shibname = NULL "
 		       . "WHERE id = $affilid";
 		doQuery($query);
-		$rc = mysql_affected_rows($mysql_link_vcl);
+		$rc = mysqli_affected_rows($mysqli_link_vcl);
 		if($rc == 1)
 			return 1;
 		return 0;
@@ -2973,7 +2973,7 @@
 			sendJSON($arr);
 			return;
 		}
-		$_newval = mysql_real_escape_string($newval);
+		$_newval = vcl_mysql_escape_string($newval);
 		$query = "INSERT INTO affiliation (name) VALUES ('$_newval')";
 		doQuery($query);
 		$arr = array('status' => 'success',
@@ -2998,7 +2998,7 @@
 		foreach($tables as $table) {
 			$query = "SELECT affiliationid FROM $table WHERE affiliationid = $key LIMIT 1";
 			$qh = doQuery($query);
-			if(mysql_num_rows($qh)) {
+			if(mysqli_num_rows($qh)) {
 				$used = 1;
 				break;
 			}
@@ -3052,7 +3052,7 @@
 	function updateValue($key, $val) {
 		$tmp = explode('|', $key);
 		$key = $tmp[1];
-		$_val = mysql_real_escape_string($val);
+		$_val = vcl_mysql_escape_string($val);
 		$query = "UPDATE affiliation SET name = '$_val' WHERE id = $key";
 		doQuery($query);
 	}
@@ -3134,6 +3134,15 @@
 
 			if($keyparts[0] == 'adminmessage')
 				$keyparts[2] = 'Global';
+			foreach(array('message', 'subject', 'short_message') as $type) {
+				if(! isset($item[$type]))
+					continue;
+				$test = strip_tags($item[$type]);
+				if($test != $item[$type]) {
+					$item['DBmanagedHTML'] = 1;
+					$item[$type] = '';
+				}
+			}
 			$this->units[$k][$keyparts[2]] = $item;
 		}
 		uasort($this->basekeys, "sortKeepIndex");
@@ -3395,7 +3404,7 @@
 		       .       "value LIKE '%invalidfields%'";
 		$qh = doQuery($query);
 		$invalids = array();
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			$data = Spyc::YAMLLoad($row['value']);
 			if(array_key_exists('invalidfields', $data)) {
 				$invalids[$row['name']] = $data['invalidfields'];
diff --git a/web/.ht-inc/sitemaintenance.php b/web/.ht-inc/sitemaintenance.php
index 6dad773..fe833dc 100644
--- a/web/.ht-inc/sitemaintenance.php
+++ b/web/.ht-inc/sitemaintenance.php
@@ -279,8 +279,8 @@
 		return;
 	}
 
-	$reason = mysql_real_escape_string($data['reason']);
-	$usermessage = mysql_real_escape_string($data['usermessage']);
+	$reason = vcl_mysql_escape_string($data['reason']);
+	$usermessage = vcl_mysql_escape_string($data['usermessage']);
 	$query = "INSERT INTO sitemaintenance "
 	       .        "(start, "
 	       .        "end, "
@@ -413,8 +413,8 @@
 		return;
 	}
 
-	$reason = mysql_real_escape_string($data['reason']);
-	$usermessage = mysql_real_escape_string($data['usermessage']);
+	$reason = vcl_mysql_escape_string($data['reason']);
+	$usermessage = vcl_mysql_escape_string($data['usermessage']);
 	$query = "UPDATE sitemaintenance "
 	       . "SET start = '{$data['startdt']}', "
 	       .     "end = '{$data['enddt']}', "
diff --git a/web/.ht-inc/statistics.php b/web/.ht-inc/statistics.php
index ca81b8b..f30998f 100644
--- a/web/.ht-inc/statistics.php
+++ b/web/.ht-inc/statistics.php
@@ -110,7 +110,7 @@
 		       . "ORDER BY prettyname";
 		$qh = doQuery($query);
 		$provs = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$provs[$row['id']] = $row['prettyname'];
 		$cdata = array('mode' => 'provisioning',
 		               'provs' => $provs);
@@ -292,7 +292,7 @@
 	                 "10hrsplus" => 0);
 	$totalhours = 0;
 	$osusers = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if(! array_key_exists($row["prettyname"], $imageload2less))
 			$imageload2less[$row["prettyname"]] = 0;
 		if(! array_key_exists($row["prettyname"], $imageload2to6))
@@ -665,6 +665,8 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function getStatGraphDayData($start, $end, $affilid, $mode, $provid) {
+	$tz = date_default_timezone_get();
+	date_default_timezone_set('UTC');
 	$startunix = datetimeToUnix($start . " 00:00:00");
 	$endunix = datetimeToUnix($end . " 23:59:59");
 
@@ -676,6 +678,9 @@
 	$addcache = array();
 	$reloadid = getUserlistID('vclreload@Local');
 	$cnt = 0;
+	$prov = "provisioningid = $provid";
+	if($provid == 0)
+		$prov = "(provisioningid IS NULL OR provisioningid = 0)";
 	$query = "SELECT statdate, "
 	       .        "value "
 	       . "FROM statgraphcache "
@@ -683,9 +688,9 @@
 			 .       "affiliationid = $affilid AND "
 	       .       "statdate >= '$start' AND "
 	       .       "statdate <= '$end' AND "
-	       .       "provisioningid = $provid";
+	       .       "$prov";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$cachepts[$row['statdate']] = $row['value'];
 	for($i = $startunix; $i < $endunix; $i += SECINDAY) {
 		$cnt++;
@@ -735,7 +740,7 @@
 				}
 			}
 			$qh = doQuery($query, 295);
-			if($row = mysql_fetch_row($qh))
+			if($row = mysqli_fetch_row($qh))
 				$value = $row[0];
 			else
 				$value = 0;
@@ -749,6 +754,7 @@
 	}
 	if(count($addcache))
 		addToStatGraphCache('totalres', $addcache, $affilid, $provid);
+	date_default_timezone_set($tz);
 	return($data);
 }
 
@@ -843,7 +849,7 @@
 		}
 	}
 	$qh = doQuery($query, 296);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$startmin = ($row['shour'] * 60) + $row['smin'];
 		$endmin = ($row['ehour'] * 60) + $row['emin'];
 
@@ -920,6 +926,8 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function getStatGraphDayConUsersData($start, $end, $affilid, $mode, $provid) {
+	$tz = date_default_timezone_get();
+	date_default_timezone_set('UTC');
 	$startdt = $start . " 00:00:00";
 	$enddt = $end . " 23:59:59";
 	$startunix = datetimeToUnix($startdt);
@@ -942,6 +950,9 @@
 
 	$reloadid = getUserlistID('vclreload@Local');
 	$cnt = 0;
+	$prov = "provisioningid = $provid";
+	if($provid == 0)
+		$prov = "(provisioningid IS NULL OR provisioningid = 0)";
 	$query = "SELECT statdate, "
 	       .        "value "
 	       . "FROM statgraphcache "
@@ -949,12 +960,13 @@
 			 .       "affiliationid = $affilid AND "
 	       .       "statdate >= '$start' AND "
 	       .       "statdate <= '$end' AND "
-	       .       "provisioningid = $provid";
+	       .       "$prov";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$cachepts[$row['statdate']] = $row['value'];
 	if((count($cachepts) + 31) < $daycnt) {
 		$data = array('nodata' => i('(too much computational time required to generate this graph)'));
+		date_default_timezone_set($tz);
 		return $data;
 	}
 	for($daystart = $startunix; $daystart < $endunix; $daystart += SECINDAY) {
@@ -1008,7 +1020,7 @@
 				}
 			}
 			$qh = doQuery($query, 101);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				$unixstart = $row["start"];
 				$unixend = $row["end"];
 				for($binstart = $daystart, $binend = $daystart + 3600, $binindex = 0;
@@ -1038,6 +1050,7 @@
 	}
 	if(count($addcache))
 		addToStatGraphCache('concurres', $addcache, $affilid, $provid);
+	date_default_timezone_set($tz);
 	return($data);
 }
 
@@ -1064,6 +1077,8 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function getStatGraphConBladeUserData($start, $end, $affilid, $mode, $provid) {
+	$tz = date_default_timezone_get();
+	date_default_timezone_set('UTC');
 	$startdt = $start . " 00:00:00";
 	$enddt = $end . " 23:59:59";
 	$startunix = datetimeToUnix($startdt);
@@ -1086,6 +1101,9 @@
 
 	$reloadid = getUserlistID('vclreload@Local');
 	$cnt = 0;
+	$prov = "provisioningid = $provid";
+	if($provid == 0)
+		$prov = "(provisioningid IS NULL OR provisioningid = 0)";
 	$query = "SELECT statdate, "
 	       .        "value "
 	       . "FROM statgraphcache "
@@ -1093,12 +1111,13 @@
 			 .       "affiliationid = $affilid AND "
 	       .       "statdate >= '$start' AND "
 	       .       "statdate <= '$end' AND "
-	       .       "provisioningid = $provid";
+	       .       "$prov";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$cachepts[$row['statdate']] = $row['value'];
 	if((count($cachepts) + 31) < $daycnt) {
 		$data = array('nodata' => i('(too much computational time required to generate this graph)'));
+		date_default_timezone_set($tz);
 		return $data;
 	}
 	for($daystart = $startunix; $daystart < $endunix; $daystart += SECINDAY) {
@@ -1180,7 +1199,7 @@
 			}
 			$qh = doQuery($query, 101);
 			$comps = array();
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				$unixstart = datetimeToUnix($row["start"]);
 				$unixend = datetimeToUnix($row["end"]);
 				for($binstart = $daystart, $binend = $daystart + 3600, $binindex = 0;
@@ -1216,6 +1235,7 @@
 	}
 	if(count($addcache))
 		addToStatGraphCache('concurblade', $addcache, $affilid, $provid);
+	date_default_timezone_set($tz);
 	return($data);
 }
 
@@ -1242,6 +1262,8 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function getStatGraphConVMUserData($start, $end, $affilid, $mode, $provid) {
+	$tz = date_default_timezone_get();
+	date_default_timezone_set('UTC');
 	$startdt = $start . " 00:00:00";
 	$enddt = $end . " 23:59:59";
 	$startunix = datetimeToUnix($startdt);
@@ -1264,6 +1286,9 @@
 
 	$reloadid = getUserlistID('vclreload@Local');
 	$cnt = 0;
+	$prov = "provisioningid = $provid";
+	if($provid == 0)
+		$prov = "(provisioningid IS NULL OR provisioningid = 0)";
 	$query = "SELECT statdate, "
 	       .        "value "
 	       . "FROM statgraphcache "
@@ -1271,12 +1296,13 @@
 			 .       "affiliationid = $affilid AND "
 	       .       "statdate >= '$start' AND "
 	       .       "statdate <= '$end' AND "
-	       .       "provisioningid = $provid";
+	       .       "$prov";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$cachepts[$row['statdate']] = $row['value'];
 	if((count($cachepts) + 31) < $daycnt) {
 		$data = array('nodata' => i('(too much computational time required to generate this graph)'));
+		date_default_timezone_set($tz);
 		return $data;
 	}
 	for($daystart = $startunix; $daystart < $endunix; $daystart += SECINDAY) {
@@ -1348,7 +1374,7 @@
 				}
 			}
 			$qh = doQuery($query, 101);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				$unixstart = datetimeToUnix($row["start"]);
 				$unixend = datetimeToUnix($row["end"]);
 				for($binstart = $daystart, $binend = $daystart + 3600, $binindex = 0;
@@ -1378,6 +1404,7 @@
 	}
 	if(count($addcache))
 		addToStatGraphCache('concurvm', $addcache, $affilid, $provid);
+	date_default_timezone_set($tz);
 	return($data);
 }
 
diff --git a/web/.ht-inc/userpreferences.php b/web/.ht-inc/userpreferences.php
index 3838c99..fcdc6f7 100644
--- a/web/.ht-inc/userpreferences.php
+++ b/web/.ht-inc/userpreferences.php
@@ -490,7 +490,7 @@
 		       . "WHERE u.id = '{$user['id']}' AND "
 		       .       "l.userid = u.id";
 		$qh = doQuery($query, 101);
-		if(! ($row = mysql_fetch_assoc($qh)))
+		if(! ($row = mysqli_fetch_assoc($qh)))
 			abort();
 		$passhash = sha1("{$data['newpassword']}{$row['salt']}");
 		$query = "UPDATE localauth "
@@ -564,7 +564,7 @@
 	if($pubkeyauth == 2 && preg_match('|^[-a-zA-Z0-9\+/ @=\.\n\r]*$|', $pubkeys)) {
 		if(get_magic_quotes_gpc())
 			$pubkeys = stripslashes($pubkeys);
-		$_pubkeys = mysql_real_escape_string($pubkeys);
+		$_pubkeys = vcl_mysql_escape_string($pubkeys);
 		$query = "UPDATE user SET sshpublickeys = '$_pubkeys' WHERE id = {$user['id']}";
 		doQuery($query);
 		$_SESSION['user']['sshpublickeys'] = htmlspecialchars($pubkeys);
diff --git a/web/.ht-inc/utils.php b/web/.ht-inc/utils.php
index 4461ab9..a9928eb 100644
--- a/web/.ht-inc/utils.php
+++ b/web/.ht-inc/utils.php
@@ -125,7 +125,12 @@
 	$days = array(i('Sunday'), i('Monday'), i('Tuesday'), i('Wednesday'), i('Thursday'), i('Friday'), i('Saturday'));
 	$phpVerArr = explode('.', phpversion());
 	$phpVer = $phpVerArr[0];
-	$uniqid = uniqid($_SERVER['HTTP_HOST'] . "-" . getmypid() . "-");
+	
+	$host = $_SERVER['HTTP_HOST'];
+	if(strpos($host, ':')) {
+		$host = substr($host, 0, strpos($host, ':'));
+	}
+	$uniqid = uniqid($host . "-" . getmypid() . "-");
 
 	$passwdArray = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
 	                     'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
@@ -165,11 +170,17 @@
 		if(! is_null($userid))
 			$authed = 1;
 	}
-	elseif(preg_match('/_shibsession/', join(',', array_keys($_COOKIE)))) {
-		# redirect to shibauth directory
-		header('Location: ' . BASEURL . "/shibauth/");
-		dbDisconnect();
-		exit;
+	else {
+		global $authFuncs;
+		foreach($authFuncs as $type) {
+			if($type['test']()) {
+				$userid = $type['auth']();
+				if(! is_null($userid)) {
+					$authed = 1;
+					break;
+				}
+			}
+		}
 	}
 	# end auth check
 
@@ -264,7 +275,7 @@
 	# set up $affilValFunc, $addUserFunc, $updateUserFunc for any shibonly affiliations
 	$query = "SELECT id FROM affiliation WHERE shibonly = 1";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$id = $row['id'];
 		if(! array_key_exists($id, $affilValFunc)) {
 			if(ALLOWADDSHIBUSERS)
@@ -641,13 +652,13 @@
 		$fh = fopen($idfile, 'r');
 		$id = fread($fh, 50);
 		fclose($fh);
-		$_id = mysql_real_escape_string($id);
+		$_id = vcl_mysql_escape_string($id);
 
 		$query = "SELECT id "
 		       . "FROM cryptkey  "
 		       . "WHERE id = '$_id'";
 		$qh = doQuery($query);
-		if($row = mysql_fetch_assoc($qh))
+		if($row = mysqli_fetch_assoc($qh))
 			return;
 	}
 
@@ -738,7 +749,7 @@
 		       .       "end > NOW()";
 		$qh = doQuery($query);
 		$ids = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$ids[] = $row['id'];
 		if(empty($ids)) {
 			dbDisconnect();
@@ -1008,7 +1019,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function abort($errcode, $query="") {
-	global $mysql_link_vcl, $mysql_link_acct, $ERRORS, $user, $mode;
+	global $mysqli_link_vcl, $mysqli_link_acct, $ERRORS, $user, $mode;
 	global $ENABLE_ITECSAUTH, $requestInfo, $aborting;
 	if(! isset($aborting))
 		$aborting = 1;
@@ -1018,11 +1029,11 @@
 		xmlRPCabort($errcode, $query);
 	if(ONLINEDEBUG && checkUserHasPerm('View Debug Information')) {
 		if($errcode >= 100 && $errcode < 400) {
-			print "<font color=red>" . mysql_error($mysql_link_vcl) . "</font><br>\n";
-			error_log(mysql_error($mysql_link_vcl));
+			print "<font color=red>" . mysqli_error($mysqli_link_vcl) . "</font><br>\n";
+			error_log(mysqli_error($mysqli_link_vcl));
 			if($ENABLE_ITECSAUTH) {
-				print "<font color=red>" . mysql_error($mysql_link_acct) . "</font><br>\n";
-				error_log(mysql_error($mysql_link_acct));
+				print "<font color=red>" . mysqli_error($mysqli_link_acct) . "</font><br>\n";
+				error_log(mysqli_error($mysqli_link_acct));
 			}
 			print "$query<br>\n";
 			error_log($query);
@@ -1039,9 +1050,9 @@
 	else {
 		$message = "";
 		if($errcode >= 100 && $errcode < 400) {
-			$message .= mysql_error($mysql_link_vcl) . "\n";
+			$message .= mysqli_error($mysqli_link_vcl) . "\n";
 			if($ENABLE_ITECSAUTH)
-				$message .= mysql_error($mysql_link_acct) . "\n";
+				$message .= mysqli_error($mysqli_link_acct) . "\n";
 			$message .= $query . "\n";
 		}
 		$message .= "ERROR($errcode): " . $ERRORS["$errcode"] . "\n";
@@ -1118,13 +1129,13 @@
 	if(empty($affilid))
 		return 0;
 
-	$escloginid = mysql_real_escape_string($loginid);
+	$escloginid = vcl_mysql_escape_string($loginid);
 	$query = "SELECT id "
 	       . "FROM user "
 	       . "WHERE unityid = '$escloginid' AND "
 	       .       "affiliationid = $affilid";
 	$qh = doQuery($query, 101);
-	if(mysql_num_rows($qh))
+	if(mysqli_num_rows($qh))
 		return 1;
 
 	if($rc == 0 &&
@@ -1134,7 +1145,7 @@
 		       . "FROM affiliation "
 		       . "WHERE id = " . DEFAULT_AFFILID;
 		$qh = doQuery($query);
-		$row = mysql_fetch_assoc($qh);
+		$row = mysqli_fetch_assoc($qh);
 		if($row['shibonly'] == 1)
 			return 0;
 	}
@@ -1190,11 +1201,12 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \fn mysql_connect_plus($host, $user, $pwd)
+/// \fn mysql_connect_plus($host, $user, $pwd, $db)
 ///
 /// \param $host - mysql host
 /// \param $user - userid to use for connection
 /// \param $pwd - password to use for connection
+/// \param $db - database to use after connecting
 ///
 /// \return mysql resource identifier, 0 if failure to connect
 ///
@@ -1203,12 +1215,12 @@
 /// and returns the identifier
 ///
 ////////////////////////////////////////////////////////////////////////////////
-function mysql_connect_plus($host, $user, $pwd) {
+function mysql_connect_plus($host, $user, $pwd, $db) {
 	$timeout = 5;             /* timeout in seconds */
 
 	if($fp = @fsockopen($host, 3306, $errno, $errstr, $timeout)) {
 		fclose($fp);
-		return $link = mysql_connect($host, $user, $pwd);
+		return $link = mysqli_connect($host, $user, $pwd, $db);
 	} else {
 		#print "ERROR: socket timeout<BR>\n";
 		return 0;
@@ -1220,29 +1232,25 @@
 /// \fn dbConnect()
 ///
 /// \brief opens connections to database, the resource identifiers are\n
-/// \b $mysql_link_vcl - for vcl database\n
-/// \b $mysql_link_acct - for accounts database\n
+/// \b $mysqli_link_vcl - for vcl database\n
+/// \b $mysqli_link_acct - for accounts database\n
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function dbConnect() {
-	global $vclhost, $vcldb, $vclusername, $vclpassword, $mysql_link_vcl;
-	global $accthost, $acctusername, $acctpassword, $mysql_link_acct;
+	global $vclhost, $vcldb, $vclusername, $vclpassword, $mysqli_link_vcl;
+	global $accthost, $acctusername, $acctpassword, $mysqli_link_acct;
 	global $ENABLE_ITECSAUTH;
 
 	if($ENABLE_ITECSAUTH) {
 		// open a connection to mysql server for accounts
-		if($mysql_link_acct = mysql_connect_plus($accthost, $acctusername, $acctpassword))
-			mysql_select_db("accounts", $mysql_link_acct);
-		else
+		if(! ($mysqli_link_acct = mysql_connect_plus($accthost, $acctusername, $acctpassword, 'accounts')))
 			$ENABLE_ITECSAUTH = 0;
 	}
 
 	// open a connection to mysql server for vcl
-	if(! $mysql_link_vcl = mysql_connect_plus($vclhost, $vclusername, $vclpassword)) {
+	if(! $mysqli_link_vcl = mysql_connect_plus($vclhost, $vclusername, $vclpassword, $vcldb)) {
 		die("Error connecting to $vclhost.<br>\n");
 	}
-	// select the vcl database
-	mysql_select_db($vcldb, $mysql_link_vcl) or abort(104);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1253,10 +1261,10 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function dbDisconnect() {
-	global $mysql_link_vcl, $mysql_link_acct, $ENABLE_ITECSAUTH;
-	mysql_close($mysql_link_vcl);
+	global $mysqli_link_vcl, $mysqli_link_acct, $ENABLE_ITECSAUTH;
+	mysqli_close($mysqli_link_vcl);
 	if($ENABLE_ITECSAUTH)
-		mysql_close($mysql_link_acct);
+		mysqli_close($mysqli_link_acct);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1274,7 +1282,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function doQuery($query, $errcode=101, $db="vcl", $nolog=0) {
-	global $mysql_link_vcl, $mysql_link_acct, $user, $mode, $ENABLE_ITECSAUTH;
+	global $mysqli_link_vcl, $mysqli_link_acct, $user, $mode, $ENABLE_ITECSAUTH;
 	if($db == "vcl") {
 		if(QUERYLOGGING != 0 && (! $nolog) &&
 		   preg_match('/^(UPDATE|INSERT|DELETE)/', $query) &&
@@ -1295,10 +1303,10 @@
 			   .        "NOW(), "
 			   .        "'$mode', "
 			   .        "'$logquery')";
-			mysql_query($q, $mysql_link_vcl);
+			mysqli_query($mysqli_link_vcl, $q);
 		}
-		for($i = 0; ! ($qh = mysql_query($query, $mysql_link_vcl)) && $i < 3; $i++) {
-			if(mysql_errno() == '1213') # DEADLOCK, sleep and retry
+		for($i = 0; ! ($qh = mysqli_query($mysqli_link_vcl, $query)) && $i < 3; $i++) {
+			if(mysqli_errno($mysqli_link_vcl) == '1213') # DEADLOCK, sleep and retry
 				usleep(50);
 			else
 				abort($errcode, $query);
@@ -1306,7 +1314,7 @@
 	}
 	elseif($db == "accounts") {
 		if($ENABLE_ITECSAUTH)
-			$qh = mysql_query($query, $mysql_link_acct) or abort($errcode, $query);
+			$qh = mysqli_query($mysqli_link_acct, $query) or abort($errcode, $query);
 		else
 			$qh = NULL;
 	}
@@ -1317,14 +1325,31 @@
 ///
 /// \fn dbLastInsertID()
 ///
-/// \return last insert id for $mysql_link_vcl
+/// \return last insert id for $mysqli_link_vcl
 ///
-/// \brief calls mysql_insert_id for $mysql_link_vcl
+/// \brief calls mysqli_insert_id for $mysqli_link_vcl
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function dbLastInsertID() {
-	global $mysql_link_vcl;
-	return mysql_insert_id($mysql_link_vcl);
+	global $mysqli_link_vcl;
+	return mysqli_insert_id($mysqli_link_vcl);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn vcl_mysql_escape_string($string) {
+///
+/// \param $string - string to be escaped
+///
+/// \return escaped string
+///
+/// \brief wrapper for mysqli_real_escape_string so that $mysqli_link_vcl global
+/// variable doesn't have to be included in every function needing to call it
+///
+////////////////////////////////////////////////////////////////////////////////
+function vcl_mysql_escape_string($string) {
+	global $mysqli_link_vcl;
+	return mysqli_real_escape_string($mysqli_link_vcl, $string);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1340,7 +1365,7 @@
 	$query = "SELECT id, name, prettyname, type, installtype FROM OS ORDER BY prettyname";
 	$qh = doQuery($query, "115");
 	$oslist = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$oslist[$row['id']] = $row;
 	return $oslist;
 }
@@ -1412,7 +1437,7 @@
 	       .        "id "
 	       . "FROM imagemeta";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$allmetadata[$row['id']] = $row;
 
 	# get all image revision data
@@ -1436,7 +1461,7 @@
 		$query .=   "i.deleted = 0 AND ";
 	$query .=      "u.affiliationid = a.id";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$id = $row['imageid'];
 		unset($row['imageid']);
 		$allrevisiondata[$id][$row['id']] = $row;
@@ -1491,7 +1516,7 @@
 		$query .= "AND i.deleted = 0 ";
 	$query .= "ORDER BY i.prettyname";
 	$qh = doQuery($query, 120);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if(is_null($row['maxconcurrent']))
 			$row['maxconcurrent'] = 0;
 		$imagelist[$includedeleted][$row["id"]] = $row;
@@ -1518,7 +1543,7 @@
 					        . "FROM subimages "
 					        . "WHERE imagemetaid = $metaid";
 					$qh2 = doQuery($query2, 101);
-					while($row2 = mysql_fetch_assoc($qh2))
+					while($row2 = mysqli_fetch_assoc($qh2))
 						$imagelist[$includedeleted][$row["id"]]["subimages"][] =  $row2["imageid"];
 				}
 			}
@@ -1568,7 +1593,7 @@
 	$fixeddata = array();
 	$query = "SELECT name, value FROM variable WHERE name LIKE 'fixedIPsp%'";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$spid = str_replace('fixedIPsp', '', $row['name']);
 		$fixeddata[$spid] = Spyc::YAMLLoad($row['value']);
 	}
@@ -1604,7 +1629,7 @@
 		$query .= "ORDER BY name";
 	$qh = doQuery($query, 101);
 	$profiles = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$profiles[$row['id']] = $row;
 		if(isset($fixeddata[$row['id']])) {
 			$profiles[$row['id']]['netmask'] = $fixeddata[$row['id']]['netmask'];
@@ -1653,7 +1678,7 @@
 	       .       "s.id IN ($inids)";
 	$qh = doQuery($query, 101);
 	$profiles = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$profiles[$row['id']] = $row['image'];
 	$_SESSION['usersessiondata'][$key] = $profiles;
 	return $profiles;
@@ -1702,7 +1727,7 @@
 	$query .= " ORDER BY revision";
 	$qh = doQuery($query, 101);
 	$return = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$return[$row['id']] = $row;
 	return $return;
 }
@@ -1729,7 +1754,7 @@
 	       . "FROM image "
 	       . "WHERE id = $imageid";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh))
+	if($row = mysqli_fetch_assoc($qh))
 		return $row;
 	else
 		return array('description' => '', 'usage' => '');
@@ -1813,7 +1838,7 @@
 		       .          "disabled";
 
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			if($row['disabled'] &&
 			   isset($allmethods[$row['imageid']][$row['imagerevisionid']][$row['connectmethodid']]))
 				unset($allmethods[$row['imageid']][$row['imagerevisionid']][$row['connectmethodid']]);
@@ -1850,7 +1875,7 @@
 	if(! preg_match('/^en/', $locale)) {
 		$query = "DESC connectmethod";
 		$qh = doQuery($query, 101);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			if($row['Field'] == "description_$locale")
 				$descfield = "description_$locale";
 			if($row['Field'] == "connecttext_$locale")
@@ -1864,7 +1889,7 @@
 	       .        "protocol "
 	       . "FROM connectmethodport";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$row['key'] = "#Port-{$row['protocol']}-{$row['port']}#";
 		$cmports[$row['connectmethodid']][] = $row;
 	}
@@ -1889,7 +1914,7 @@
 	       .          "c.`$descfield`";
 	$methods = array();
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($row['disabled']) {
 		  if(isset($methods[$row['id']]))
 			unset($methods[$row['id']]);
@@ -1916,7 +1941,7 @@
 	$query = "SELECT id, name FROM imagetype ORDER BY name";
 	$qh = doQuery($query);
 	$data = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$data[$row['id']] = $row['name'];
 	return $data;
 }
@@ -1941,14 +1966,14 @@
 	$query = "DESC imagemeta";
 	$qh = doQuery($query, 101);
 	$defaults = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$defaults[$row['Field']] = $row['Default'];
 	# get imagemeta data
 	$query = "SELECT * FROM imagemeta WHERE id = $imagemetaid";
 	$qh = doQuery($query, 101);
-	$row = mysql_fetch_assoc($qh);
+	$row = mysqli_fetch_assoc($qh);
 	$alldefaults = 1;
-	if(mysql_num_rows($qh) == 0)
+	if(mysqli_num_rows($qh) == 0)
 		# it is possible that the imagemeta record could have been deleted before
 		#   this was submitted
 		return 1;
@@ -1999,7 +2024,7 @@
 	       . "FROM imagerevision  "
 	       . "WHERE production = 1";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$alldata[$row['imageid']] = $row['id'];
 	return $alldata[$imageid];
 }
@@ -2100,7 +2125,7 @@
 	else
 		$query .=   "u.usergroupid = $groupid";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		array_push($startnodes, $row["privnodeid"]);
 	}
 	# build data array from userprivtype and userpriv tables to reduce queries
@@ -2115,7 +2140,7 @@
 	       .       "u.userid = $userid AND "
 	       .       "t.name IN ('block','cascade',$inlist)";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$privdataset['user'][$row['privnodeid']][] = $row['name'];
 	$query = "SELECT t.name, "
 	       .        "u.usergroupid, "
@@ -2134,7 +2159,7 @@
 	       . "ORDER BY u.privnodeid, "
 	       .          "u.usergroupid";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$privdataset['usergroup'][$row['privnodeid']][] = array('name' => $row['name'], 'groupid' => $row['usergroupid']);
 
 	# travel up tree looking at privileges granted at parent nodes
@@ -2474,7 +2499,7 @@
 		if(! $includedeleted && $type == 'managementnode')
 			$query .= " AND stateid != (SELECT id FROM state WHERE name = 'deleted') ";
 		$qh = doQuery($query, 101);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			if(! isset($resources[$type][$row["id"]]))
 				$resources[$type][$row["id"]] = $row[$field];
 		}
@@ -2508,7 +2533,7 @@
 	       . "WHERE g.resourcetypeid = t.id AND "
 	       .       "g.ownerusergroupid IN ($groupids)";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if(! isset($resourcegroups[$row["type"]][$row["id"]]))
 			$resourcegroups[$row["type"]][$row["id"]] = $row["name"];
 	}
@@ -2569,7 +2594,7 @@
 		$query .= "AND test = 0 ";*/
 	$query .= "ORDER BY t.$field";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$return[$row["id"]] = $row["name"];
 	}
 	return $return;
@@ -2650,7 +2675,7 @@
 	else
 		$groupid = getResourceGroupID($group);
 	foreach($adds as $type) {
-		$type = mysql_real_escape_string($type);
+		$type = vcl_mysql_escape_string($type);
 		$query = "INSERT IGNORE INTO resourcepriv ("
 		       .        "resourcegroupid, "
 		       .        "privnodeid, "
@@ -2662,7 +2687,7 @@
 		doQuery($query, 377);
 	}
 	foreach($removes as $type) {
-		$type = mysql_real_escape_string($type);
+		$type = vcl_mysql_escape_string($type);
 		$query = "DELETE FROM resourcepriv "
 		       . "WHERE resourcegroupid = $groupid AND "
 		       .       "privnodeid = $node AND "
@@ -2805,7 +2830,7 @@
 	       . "WHERE cryptkeyid = $cryptkeyid AND "
 	       .       "secretid = $secretid";
 	$qh = doQuery($query);
-	if(! ($row = mysql_fetch_assoc($qh)))
+	if(! ($row = mysqli_fetch_assoc($qh)))
 		return NULL;
 	$secret = decryptSecretKey($row['cryptsecret']);
 	if($secret === NULL)
@@ -2834,7 +2859,7 @@
 		       . "FROM cryptkey "
 		       . "WHERE id = $cryptkey";
 		$qh = doQuery($query);
-		if(! ($row = mysql_fetch_assoc($qh)))
+		if(! ($row = mysqli_fetch_assoc($qh)))
 			return NULL;
 		$cryptkey = $row['pubkey'];
 		if($row['algorithmoption'] == 'OAEP' || 1) # OAEP only currently supported option
@@ -2902,7 +2927,7 @@
 function getSecretKeyID($table, $field, $recordid) {
 	$query = "SELECT $field FROM $table WHERE id = $recordid";
 	$qh = doQuery($query);
-	if(($row = mysql_fetch_row($qh)) && $row[0] != 0)
+	if(($row = mysqli_fetch_row($qh)) && $row[0] != 0)
 		return $row[0];
 
 	# generate secret key
@@ -2941,7 +2966,7 @@
 		return NULL;
 	$query = "SELECT secretid FROM cryptsecret WHERE id = $id";
 	$qh = doQuery($query);
-	if(! ($row = mysql_fetch_assoc($qh)))
+	if(! ($row = mysqli_fetch_assoc($qh)))
 		return NULL;
 	# encrypt with all other public keys and write to cryptsecret
 	encryptWebSecretKeys($key, $row['secretid'], $cryptkeyid);
@@ -2994,13 +3019,13 @@
 	$fh = fopen($idfile, 'r');
 	$id = fread($fh, 50);
 	fclose($fh);
-	$_id = mysql_real_escape_string($id);
+	$_id = vcl_mysql_escape_string($id);
 
 	$query = "SELECT id "
 	       . "FROM cryptkey  "
 	       . "WHERE id = '$_id'";
 	$qh = doQuery($query);
-	if($row = mysql_fetch_assoc($qh))
+	if($row = mysqli_fetch_assoc($qh))
 		return $row['id'];
 
 	if($create) {
@@ -3032,7 +3057,7 @@
 	       .       "hosttype = 'web'";
 	$qh = doQuery($query);
 	$values = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$cryptsecret = encryptSecretKey($secret, $row['pubkey']);
 		if($cryptsecret === NULL)
 			continue;
@@ -3079,7 +3104,7 @@
 	       .       "cs.secretid IS NULL AND "
 	       .       "ck.id != $mycryptkeyid";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$secret = decryptSecretKey($row['mycryptsecret']);
 		$encsecret = encryptSecretKey($secret, $row['cryptkey']);
 		$values[] = "({$row['cryptkeyid']}, {$row['secretid']}, '$encsecret', '"
@@ -3122,7 +3147,7 @@
 	       . "WHERE rs.requestid = $requestid AND "
 	       .       "ad.secretid IS NOT NULL";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$secretids[$row['managementnodeid']][$row['secretid']] = 1;
 	# determine any secretids needed from vmprofile
 	$query = "SELECT vp.secretid, "
@@ -3134,7 +3159,7 @@
 	       . "WHERE rs.requestid = $requestid AND "
 	       .       "vp.secretid IS NOT NULL";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$secretids[$row['managementnodeid']][$row['secretid']] = 1;
 
 	$mycryptkeyid = getCryptKeyID();
@@ -3191,7 +3216,7 @@
 		       .       "s.id in ($allsecretids) AND "
 		       .       "cs.secretid IS NULL";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			$secret = decryptSecretKey($row['mycryptsecret']);
 			$encsecret = encryptSecretKey($secret, $row['cryptkey']);
 			$values[] = "({$row['cryptkeyid']}, {$row['secretid']}, '$encsecret', '"
@@ -3355,7 +3380,7 @@
 		$query .= "AND ug.affiliationid = $affiliationid ";
 	$query .= "ORDER BY name";
 	$qh = doQuery($query, 280);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if(! empty($row["owner"]) && ! empty($row['affiliation']))
 			$row['owner'] = "{$row['owner']}@{$row['affiliation']}";
 		if($user['showallgroups'] || $affiliationid == 0)
@@ -3404,7 +3429,7 @@
 	}
 	$qh = doQuery($query, 101);
 	$groups = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$groups[$row['id']] = $row['name'];
 	}
 	return $groups;
@@ -3444,7 +3469,7 @@
 	$query .= "ORDER BY ug.name, "
 	       .           "ugpt.name";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$data[] = $row;
 	return $data;
 }
@@ -3466,7 +3491,7 @@
 	$data = array();
 	$query = "SELECT id, name, help FROM usergroupprivtype ORDER BY name";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$data[$row['id']] = $row;
 	return $data;
 }
@@ -3511,7 +3536,7 @@
 
 	$query .= "ORDER BY t.name, g.name";
 	$qh = doQuery($query, 281);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if(empty($type))
 			$return[$row["id"]]["name"] = $row["type"] . "/" . $row["name"];
 		else
@@ -3555,7 +3580,7 @@
 		       .       "gm.resourceid = r.id AND "
 		       .       "r.resourcetypeid = t.id";
 		$qh = doQuery($query, 282);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$return[$type][$row["id"]][] = $row["groupid"];
 	}
 	return $return;
@@ -3659,7 +3684,7 @@
 	       .          "rgm.resourcegroupid, "
 	       .          $orders;
 	$qh = doQuery($query, 282);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if(isset($row['deleted']) && $row['deleted'] == 1)
 			continue;
 		if(isset($row['deleted2']) && $row['deleted2'] == 1)
@@ -3696,7 +3721,7 @@
 	       .       "u.affiliationid = a.id "
 	       . "ORDER BY u.unityid";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$return[$row["id"]] = $row['user'];
 	}
 	return $return;
@@ -3773,8 +3798,8 @@
 	       . "WHERE unityid = '$loginid' AND "
 	       .       "affiliationid = $affilid";
 	$qh = doQuery($query, 140);
-	if(mysql_num_rows($qh)) {
-		$row = mysql_fetch_row($qh);
+	if(mysqli_num_rows($qh)) {
+		$row = mysqli_fetch_row($qh);
 		return $row[0];
 	}
 	if($noadd)
@@ -3801,7 +3826,7 @@
 	       . "ORDER BY id DESC "
 	       . "LIMIT 1";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh))
+	if($row = mysqli_fetch_assoc($qh))
 		return $row['imageid'];
 	return NULL;
 }
@@ -3820,7 +3845,7 @@
 	$query = "SELECT id, name FROM affiliation ORDER BY name";
 	$qh = doQuery($query, 101);
 	$return = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$return[$row['id']] = $row['name'];
 	return $return;
 }
@@ -3844,8 +3869,8 @@
 		return $cache['unityids'][$userid];
 	$query = "SELECT unityid FROM user WHERE id = $userid";
 	$qh = doQuery($query, 101);
-	if(mysql_num_rows($qh)) {
-		$row = mysql_fetch_row($qh);
+	if(mysqli_num_rows($qh)) {
+		$row = mysqli_fetch_row($qh);
 		$cache['unityids'][$userid] = $row[0];
 		return $row[0];
 	}
@@ -3864,11 +3889,11 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function getAffiliationID($affil) {
-	$affil = mysql_real_escape_string($affil);
+	$affil = vcl_mysql_escape_string($affil);
 	$query = "SELECT id FROM affiliation WHERE name = '$affil'";
 	$qh = doQuery($query, 101);
-	if(mysql_num_rows($qh)) {
-		$row = mysql_fetch_row($qh);
+	if(mysqli_num_rows($qh)) {
+		$row = mysqli_fetch_row($qh);
 		return $row[0];
 	}
 	return NULL;
@@ -3888,8 +3913,8 @@
 function getAffiliationName($affilid) {
 	$query = "SELECT name FROM affiliation WHERE id = $affilid";
 	$qh = doQuery($query, 101);
-	if(mysql_num_rows($qh)) {
-		$row = mysql_fetch_row($qh);
+	if(mysqli_num_rows($qh)) {
+		$row = mysqli_fetch_row($qh);
 		return $row[0];
 	}
 	return NULL;
@@ -3913,7 +3938,7 @@
 	if($affilid)
 		$query .= " WHERE id = $affilid";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$return[$row['id']] = $row['dataUpdateText'];
 	return $return;
 }
@@ -3941,7 +3966,7 @@
 	  	       .       "a2.name = 'Global'";
 	}
 	$qh = doQuery($query);
-	if(($row = mysql_fetch_assoc($qh)) && ! empty($row['theme']))
+	if(($row = mysqli_fetch_assoc($qh)) && ! empty($row['theme']))
 		return $row['theme'];
 	else
 		return DEFAULTTHEME;
@@ -4171,7 +4196,7 @@
 			if(! is_string($value))
 				$return[$index] = $defaultvalue;
 			elseif($addslashes)
-				$return[$index] = mysql_real_escape_string($value);
+				$return[$index] = vcl_mysql_escape_string($value);
 		}
 		return $return;
 	}
@@ -4180,7 +4205,7 @@
 		if(strlen($return) == 0)
 			$return = $defaultvalue;
 		elseif($addslashes)
-			$return = mysql_real_escape_string($return);
+			$return = vcl_mysql_escape_string($return);
 	}
 
 	return $return;
@@ -4273,7 +4298,7 @@
 		$query .= "u.unityid = '$id' AND af.id = $affilid";
 
 	$qh = doQuery($query, "105");
-	if($user = mysql_fetch_assoc($qh)) {
+	if($user = mysqli_fetch_assoc($qh)) {
 		$user['sshpublickeys'] = htmlspecialchars($user['sshpublickeys']);
 		if((datetimeToUnix($user["lastupdated"]) > time() - SECINDAY) ||
 		   $user['unityid'] == 'vclreload' ||
@@ -4349,7 +4374,7 @@
 	}
 	$qh = doQuery($query, "101");
 	$groups = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$groups[$row["usergroupid"]] = $row["name"];
 	}
 	if($includeowned) {
@@ -4368,7 +4393,7 @@
 			       . "WHERE ownerid = $userid";
 		}
 		$qh = doQuery($query, "101");
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			$groups[$row["usergroupid"]] = $row["name"];
 		}
 	}
@@ -4404,7 +4429,7 @@
 	       . "ORDER BY t.name";
 	$perms = array();
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$perms[$row['id']] = $row['name'];
 	return $perms;
 }
@@ -4474,7 +4499,7 @@
 		       . "FROM user "
 		       . "WHERE id = $id";
 		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_assoc($qh)) {
+		if($row = mysqli_fetch_assoc($qh)) {
 			$id = $row['unityid'];
 			$type = 'loginid';
 			$affilid = $row['affiliationid'];
@@ -4536,9 +4561,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 function updateUserPrefs($userid, $preferredname, $width, $height, $bpp, $audio,
                          $mapdrives, $mapprinters, $mapserial, $rdpport) {
-	global $mysql_link_vcl;
-	$preferredname = mysql_real_escape_string($preferredname);
-	$audio = mysql_real_escape_string($audio);
+	global $mysqli_link_vcl;
+	$preferredname = vcl_mysql_escape_string($preferredname);
+	$audio = vcl_mysql_escape_string($audio);
 	if($rdpport == 3389)
 		$rdpport = 'NULL';
 	$query = "UPDATE user SET "
@@ -4553,7 +4578,7 @@
 	       .        "rdpport = $rdpport "
 	       . "WHERE id = $userid";
 	doQuery($query, 270);
-	return mysql_affected_rows($mysql_link_vcl);
+	return mysqli_affected_rows($mysqli_link_vcl);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -4584,7 +4609,7 @@
 	       .                         "WHERE ownerid = $userid))";
 	$qh = doQuery($query, 107);
 	$privileges = array();
-	while($row = mysql_fetch_row($qh))
+	while($row = mysqli_fetch_row($qh))
 		$privileges[] = $row[0];
 	if(in_array("mgmtNodeAdmin", $privileges))
 		$privileges[] = 'managementnodeAdmin';
@@ -4619,7 +4644,7 @@
 	       .       "r.groupid IN ($inids)";
 	$ids = array();
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$ids[] = $row['id'];
 	return $ids;
 }
@@ -4740,7 +4765,7 @@
 			$query .=   "AND rq.id != $requestid ";
 		$query .= "LIMIT 1";
 		$qh = doQuery($query, 101);
-		if(mysql_num_rows($qh)) {
+		if(mysqli_num_rows($qh)) {
 			return debugIsAvailable(-3, 2, $start, $end, $imagerevisionid);
 		}
 
@@ -4750,7 +4775,7 @@
 		       . "WHERE IPaddress = '$ip' AND "
 		       .       "stateid != 1";
 		$qh = doQuery($query, 101);
-		if(mysql_num_rows($qh)) {
+		if(mysqli_num_rows($qh)) {
 			return debugIsAvailable(-4, 16, $start, $end, $imagerevisionid);
 		}
 	}
@@ -4791,7 +4816,7 @@
 			       .       "rq.stateid NOT IN (1,5,11,12,16,17) AND "
 			       .       "rq.userid != $reloadid";
 			$qh = doQuery($query, 101);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				$compids[] = $row['computerid'];
 				if($row['reqid'] == $requestid)
 					$decforedit = 1;
@@ -4813,7 +4838,7 @@
 			       .       "bt.skip != 1 AND "
 			       .       "br.status != 'deleted'";
 			$qh = doQuery($query);
-			if(! $row = mysql_fetch_assoc($qh)) {
+			if(! $row = mysqli_fetch_assoc($qh)) {
 				cleanSemaphore();
 				return debugIsAvailable(0, 3, $start, $end, $imagerevisionid);
 			}
@@ -4883,7 +4908,7 @@
 			       . "FROM computer "
 			       . "WHERE id = $compid";
 			$qh = doQuery($query, 128);
-			$row = mysql_fetch_row($qh);
+			$row = mysqli_fetch_row($qh);
 			if(! in_array($row[0], $scheduleids)) {
 				cleanSemaphore();
 				return debugIsAvailable(0, 7, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids);
@@ -4899,7 +4924,7 @@
 			       . "LEFT JOIN OS ON (i.OSid = OS.id) "
 			       . "WHERE i.id = $imageid";
 			$qh = doQuery($query, 101);
-			if(! ($row = mysql_fetch_assoc($qh))) {
+			if(! ($row = mysqli_fetch_assoc($qh))) {
 				cleanSemaphore();
 				return debugIsAvailable(0, 8, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids);
 			}
@@ -4958,7 +4983,7 @@
 			       .          "network";
 
 			$qh = doQuery($query, 129);
-			while($row = mysql_fetch_assoc($qh)) {
+			while($row = mysqli_fetch_assoc($qh)) {
 				array_push($computerids, $row['id']);
 				if($row['currentimageid'] == $imageid &&
 				   $row['imagerevisionid'] == $requestInfo['imagerevisions'][$key]) {
@@ -4987,7 +5012,7 @@
 		       .       "rq.stateid NOT IN (5, 12, 19) AND " # failed, complete, reload
 		       .       "(rq.stateid != 14 OR rq.laststateid != 19)"; # pending/reload
 		$qh = doQuery($query, 130);
-		while($row = mysql_fetch_row($qh)) {
+		while($row = mysqli_fetch_row($qh)) {
 			array_push($usedComputerids, $row[0]);
 		}
 
@@ -5062,7 +5087,7 @@
 			       .          "c.network";
 			$qh = doQuery($query, 101);
 			$newcompids = array();
-			while($row = mysql_fetch_assoc($qh))
+			while($row = mysqli_fetch_assoc($qh))
 				$newcompids[] = $row['id'];
 			$computerids = $newcompids;
 		}
@@ -5084,7 +5109,7 @@
 			       .       "(type != 'virtualmachine' OR "
 			       .       "vmhostid IS NOT NULL)";
 			$qh = doQuery($query);
-			if(mysql_num_rows($qh)) {
+			if(mysqli_num_rows($qh)) {
 				if($now)
 					return debugIsAvailable(-4, 18, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual);
 				$requestInfo['ipwarning'] = 1;
@@ -5096,14 +5121,14 @@
 			if($requestid)
 				$query .= " AND id != $compid"; # TODO test this
 			$qh = doQuery($query);
-			$cnt = mysql_num_rows($qh);
+			$cnt = mysqli_num_rows($qh);
 			if($cnt > 1) {
 				if($now)
 					return debugIsAvailable(-4, 22, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual);
 				$requestInfo['ipwarning'] = 1;
 			}
 			elseif($cnt == 1) {
-				$row = mysql_fetch_assoc($qh);
+				$row = mysqli_fetch_assoc($qh);
 				$computerids = array($row['id']);
 				$blockids = array();
 			}
@@ -5308,7 +5333,7 @@
 
 	$scheduleids = array();
 	$qh = doQuery($query, 127);
-	while($row = mysql_fetch_row($qh)) {
+	while($row = mysqli_fetch_row($qh)) {
 		array_push($scheduleids, $row[0]);
 	}
 	return $scheduleids;
@@ -5328,7 +5353,7 @@
 function getImagePlatform($imageid) {
 	$query = "SELECT platformid FROM image WHERE id = $imageid";
 	$qh = doQuery($query, 125);
-	if(! $row = mysql_fetch_assoc($qh))
+	if(! $row = mysqli_fetch_assoc($qh))
 		return NULL;
 	return $row['platformid'];
 }
@@ -5356,7 +5381,7 @@
 	       .       "(('$startdt' > (start - INTERVAL 30 MINUTE)) AND ('$startdt' < end))) AND "
 	       .       "end > NOW()";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_row($qh))
+	if($row = mysqli_fetch_row($qh))
 		return true;
 	return false;
 }
@@ -5459,7 +5484,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 function getSemaphore($imageid, $imagerevisionid, $mgmtnodeid, $compid, $start,
                       $end, $requestid=0) {
-	global $mysql_link_vcl, $uniqid;
+	global $mysqli_link_vcl, $uniqid;
 	$query = "INSERT INTO semaphore "
 	       . "SELECT c.id, "
 	       .        "$imageid, "
@@ -5473,7 +5498,7 @@
 	       .       "(s.expires IS NULL OR s.expires < NOW()) "
 	       . "LIMIT 1";
 	doQuery($query);
-	$rc = mysql_affected_rows($mysql_link_vcl);
+	$rc = mysqli_affected_rows($mysqli_link_vcl);
 
 	# check to see if another process allocated this one
 	if($rc) {
@@ -5489,7 +5514,7 @@
 		if($requestid)
 			$query .= " AND rq.id != $requestid";
 		$qh = doQuery($query);
-		$rc2 = mysql_num_rows($qh);
+		$rc2 = mysqli_num_rows($qh);
 		if($rc2) {
 			$query = "DELETE FROM semaphore "
 			       . "WHERE computerid = $compid AND "
@@ -5567,7 +5592,7 @@
 	       .       "l.wasavailable = 1 AND "
 	       .       "l.ending != 'failed'";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$comps[] = $row['computerid'];
 	return $comps;
 }
@@ -5598,7 +5623,7 @@
 	       . "WHERE subid = $resourcesubid AND "
 	       .       "resourcetypeid = $resourcetype1";
 	$qh = doQuery($query, 101);
-	$row = mysql_fetch_row($qh);
+	$row = mysqli_fetch_row($qh);
 	$resourceid = $row[0];
 
 	# get groups $resourceid is in
@@ -5607,7 +5632,7 @@
 	       . "FROM resourcegroupmembers "
 	       . "WHERE resourceid = $resourceid";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_row($qh)) {
+	while($row = mysqli_fetch_row($qh)) {
 		array_push($resourcegroupids, $row[0]);
 	}
 
@@ -5625,7 +5650,7 @@
 	       .       "resourcetypeid1 = $resourcetype1 AND "
 	       .       "resourcetypeid2 = $resourcetype2";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_row($qh)) {
+	while($row = mysqli_fetch_row($qh)) {
 		array_push($type2groupids, $row[0]);
 	}
 
@@ -5637,7 +5662,7 @@
 	       .       "resourcetypeid2 = $resourcetype1 AND "
 	       .       "resourcetypeid1 = $resourcetype2";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_row($qh)) {
+	while($row = mysqli_fetch_row($qh)) {
 		array_push($type2groupids, $row[0]);
 	}
 
@@ -5652,7 +5677,7 @@
 	       . "WHERE m.resourcegroupid IN ($inlist) AND "
 	       .       "m.resourceid = r.id";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_row($qh)) {
+	while($row = mysqli_fetch_row($qh)) {
 		array_push($mappedresources, $row[0]);
 	}
 	return $mappedresources;
@@ -5739,7 +5764,7 @@
 	       .       "r.imageid != $imageid) AND "
 	       .       "r.status = 'accepted'";
 	$qh = doQuery($query, 101);
-	return(mysql_num_rows($qh));
+	return(mysqli_num_rows($qh));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -5790,7 +5815,7 @@
 	       . "ORDER BY u.overlapResCount DESC "
 	       . "LIMIT 1";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh))
+	if($row = mysqli_fetch_assoc($qh))
 		return $row['overlapResCount'];
 	else
 		return 1;
@@ -5812,7 +5837,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function addRequest($forimaging=0, $revisionid=array(), $checkuser=1) {
-	global $requestInfo, $user, $uniqid, $mysql_link_vcl;
+	global $requestInfo, $user, $uniqid, $mysqli_link_vcl;
 	$startstamp = unixToDatetime($requestInfo["start"]);
 	$endstamp = unixToDatetime($requestInfo["end"]);
 	$now = time();
@@ -5829,7 +5854,7 @@
 	addLogEntry($nowfuture, $start, $endstamp, 1, $requestInfo["imageid"]);
 
 	$qh = doQuery("SELECT LAST_INSERT_ID() FROM log", 131);
-	if(! $row = mysql_fetch_row($qh)) {
+	if(! $row = mysqli_fetch_row($qh)) {
 		abort(132);
 	}
 	$logid = $row[0];
@@ -5858,7 +5883,7 @@
 	$qh = doQuery($query, 136);
 
 	$qh = doQuery("SELECT LAST_INSERT_ID() FROM request", 134);
-	if(! $row = mysql_fetch_row($qh)) {
+	if(! $row = mysqli_fetch_row($qh)) {
 		abort(135);
 	}
 	$requestid = $row[0];
@@ -5905,7 +5930,7 @@
 	       . "WHERE expires > NOW() AND "
 	       .       "procid = '$uniqid'";
 	doQuery($query);
-	$cnt = mysql_affected_rows($mysql_link_vcl);
+	$cnt = mysqli_affected_rows($mysqli_link_vcl);
 	if($cnt == 0) {
 		# reached this point SEMTIMEOUT seconds after getting semaphore, clean up and abort
 		$query = "DELETE FROM request WHERE id = $requestid";
@@ -6042,7 +6067,7 @@
 	       . "GROUP BY rs.managementnodeid "
 	       . "ORDER BY count";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$mgmtnodecnt[$row["mnid"]] = $row["count"];
 	}
 	uasort($mgmtnodecnt, "sortKeepIndex");
@@ -6119,7 +6144,7 @@
 	       . "FROM request "
 	       . "WHERE id = $id";
 	$qh = doQuery($query, 165);
-	if(! ($data = mysql_fetch_assoc($qh))) {
+	if(! ($data = mysqli_fetch_assoc($qh))) {
 		if($returnNULL)
 			return NULL;
 		# FIXME handle XMLRPC cases
@@ -6169,7 +6194,7 @@
 	$data["reservations"] = array();
 	$data['passwds'] = array();
 	$resids = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		array_push($data["reservations"], $row);
 		$resids[] = $row['reservationid'];
 		$data['passwds'][$row['reservationid']][$data['userid']] = $row['password'];
@@ -6183,7 +6208,7 @@
 	       . "FROM serverrequest "
 	       . "WHERE requestid = $id";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh)) {
+	if($row = mysqli_fetch_assoc($qh)) {
 		$data['serverrequest'] = 1;
 		$data['servername'] = $row['name'];
 		$data['admingroupid'] = $row['admingroupid'];
@@ -6197,7 +6222,7 @@
 		       . "FROM reservationaccounts "
 		       . "WHERE reservationid IN ($inids)";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$data['passwds'][$row['reservationid']][$row['userid']] = $row['password'];
 	}
 	else
@@ -6222,7 +6247,7 @@
 
 	$query = "SELECT logid FROM request WHERE id = $requestid";
 	$qh = doQuery($query, 146);
-	if(! $row = mysql_fetch_row($qh)) {
+	if(! $row = mysqli_fetch_row($qh)) {
 		abort(148);
 	}
 	$logid = $row[0];
@@ -6349,7 +6374,7 @@
 	if($request['serverrequest']) {
 		$query = "SELECT id FROM serverrequest WHERE requestid = {$request['id']}";
 		$qh = doQuery($query);
-		if($row = mysql_fetch_assoc($qh)) {
+		if($row = mysqli_fetch_assoc($qh)) {
 			$query = "DELETE FROM serverrequest WHERE requestid = {$request['id']}";
 			doQuery($query, 152);
 			deleteVariable("fixedIPsr{$row['id']}");
@@ -6400,7 +6425,7 @@
 		       . "ORDER BY reservations "
 		       . "LIMIT 1";
 		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_assoc($qh))
+		if($row = mysqli_fetch_assoc($qh))
 			$compid = $row["computerid"];
 		else
 			return -1;
@@ -6424,7 +6449,7 @@
 	if($count)
 		$query .= " LIMIT $count";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$resInfo[$row["id"]] = $row;
 	}
 	if(! count($resInfo))
@@ -6506,7 +6531,7 @@
 	       . "WHERE v.computerid = $compid AND "
 	       .       "vm.vmhostid = v.id";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$rc = moveReservationsOffComputer($row['id']);
 		if($rc != 0)
 			# lock computer so that reservations on other VMs on this host do not get moved to it
@@ -6541,7 +6566,7 @@
 	       . "ORDER BY rq.end DESC "
 	       . "LIMIT 1";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh))
+	if($row = mysqli_fetch_assoc($qh))
 		$end = $row['end'];
 	$query = "SELECT UNIX_TIMESTAMP(t.end) as end "
 	       . "FROM blockComputers c, "
@@ -6552,7 +6577,7 @@
 	       . "ORDER BY t.end DESC "
 	       . "LIMIT 1";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh))
+	if($row = mysqli_fetch_assoc($qh))
 		if($row['end'] > $end)
 			$end = $row['end'];
 	return $end;
@@ -6578,7 +6603,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 function getCompFinalVMReservationTime($hostid, $addsemaphores=0,
                                        $notomaintenance=0) {
-	global $uniqid, $mysql_link_vcl;
+	global $uniqid, $mysqli_link_vcl;
 	if($addsemaphores) {
 		$query = "SELECT vm.id "
 		       . "FROM computer vm, "
@@ -6587,7 +6612,7 @@
 		       .       "vm.vmhostid = v.id";
 		$qh = doQuery($query);
 		$compids = array();
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$compids[] = $row['id'];
 		if(empty($compids))
 			return 0;
@@ -6610,7 +6635,7 @@
 		       .       "(s.expires IS NULL OR s.expires < NOW()) "
 		       . "GROUP BY c.id";
 		doQuery($query);
-		$cnt = mysql_affected_rows($mysql_link_vcl);
+		$cnt = mysqli_affected_rows($mysqli_link_vcl);
 		if($cnt != count($compids))
 			return -1;
 	}
@@ -6632,7 +6657,7 @@
 	       . "ORDER BY rq.end DESC "
 	       . "LIMIT 1";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh))
+	if($row = mysqli_fetch_assoc($qh))
 		$end = $row['end'];
 	$query = "SELECT UNIX_TIMESTAMP(t.end) as end "
 	       . "FROM blockComputers c, "
@@ -6647,7 +6672,7 @@
 	       . "ORDER BY t.end DESC "
 	       . "LIMIT 1";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh))
+	if($row = mysqli_fetch_assoc($qh))
 		if($row['end'] > $end)
 			$end = $row['end'];
 	return $end;
@@ -6677,7 +6702,7 @@
 	       . "ORDER BY rq.start "
 	       . "LIMIT 1";
 	$qh = doQuery($query);
-	if($row = mysql_fetch_assoc($qh))
+	if($row = mysqli_fetch_assoc($qh))
 		return datetimeToUnix($row['start']);
 	return 0;
 }
@@ -6862,7 +6887,7 @@
 	$data = array();
 	$foundids = array();
 	$lastreqid = 0;
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($row['id'] != $lastreqid) {
 			$lastreqid = $row['id'];
 			$count++;
@@ -6989,7 +7014,7 @@
 	$tmp = explode(' ', $datetime);
 	list($year, $month, $day) = explode('-', $tmp[0]);
 	list($hour, $min, $sec) = explode(':', $tmp[1]);
-	return mktime($hour, $min, $sec, $month, $day, $year, -1);
+	return mktime($hour, $min, $sec, $month, $day, $year);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -7176,7 +7201,7 @@
 function getDepartmentName($id) {
 	$query = "SELECT name FROM department WHERE id = '$id'";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_row($qh)) {
+	if($row = mysqli_fetch_row($qh)) {
 		return $row[0];
 	}
 	else {
@@ -7198,7 +7223,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 function getImageId($image) {
 	$qh = doQuery("SELECT id FROM image WHERE name = '$image'", 170);
-	if($row = mysql_fetch_row($qh)) {
+	if($row = mysqli_fetch_row($qh)) {
 		return $row[0];
 	}
 	return 0;
@@ -7217,7 +7242,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 function getOSId($os) {
 	$qh = doQuery("SELECT id FROM OS WHERE name = '$os'", 175);
-	if($row = mysql_fetch_row($qh)) {
+	if($row = mysqli_fetch_row($qh)) {
 		return $row[0];
 	}
 	return 0;
@@ -7235,7 +7260,7 @@
 function getStates() {
 	$qh = doQuery("SELECT id, name FROM state", 176);
 	$states = array();
-	while($row = mysql_fetch_row($qh)) {
+	while($row = mysqli_fetch_row($qh)) {
 		$states[$row[0]] = $row[1];
 	}
 	return $states;
@@ -7253,7 +7278,7 @@
 function getPlatforms() {
 	$qh = doQuery("SELECT id, name FROM platform", 178);
 	$platforms = array();
-	while($row = mysql_fetch_row($qh)) {
+	while($row = mysqli_fetch_row($qh)) {
 		$platforms[$row[0]] = $row[1];
 	}
 	return $platforms;
@@ -7281,7 +7306,7 @@
 	       . "ORDER BY p.prettyname";
 	$qh = doQuery($query, 101);
 	$provisioning = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$provisioning[$row['id']] = $row;
 	return $provisioning;
 }
@@ -7305,7 +7330,7 @@
 function getProvisioningTypes() {
 	$query = "SELECT id, prettyname FROM provisioning WHERE name = 'none'";
 	$qh = doQuery($query);
-	$none = mysql_fetch_assoc($qh);
+	$none = mysqli_fetch_assoc($qh);
 	$query = "SELECT p.id, "
 	       .        "p.prettyname, "
 	       .        "o.name AS `type` "
@@ -7319,7 +7344,7 @@
 	$types = array('blade' => array($none['id'] => $none['prettyname']),
 	               'lab' => array(),
 	               'virtualmachine' => array());
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($row['type'] == 'kickstart' || $row['type'] == 'partimage')
 			$types['blade'][$row['id']] = $row['prettyname'];
 		elseif($row['type'] == 'none')
@@ -7364,7 +7389,7 @@
 	       . "ORDER BY s.name";
 	$qh = doQuery($query, 179);
 	$schedules = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$schedules[$row["id"]] = $row;
 		$schedules[$row["id"]]["times"] = array();
 	}
@@ -7375,7 +7400,7 @@
 	       . "ORDER BY scheduleid, "
 	       .          "start";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		array_push($schedules[$row["scheduleid"]]["times"],
 		           array("start" => $row["start"], "end" => $row["end"]));
 	}
@@ -7499,7 +7524,7 @@
 	}
 	$qh = doQuery($query, 101);
 	$return = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if(is_null($row['natpublicIPaddress'])) {
 			$row['nathostenabled'] = 0;
 			$row['natpublicIPaddress'] = '';
@@ -7557,7 +7582,7 @@
 	       .       "c.id in ($inlist)";
 	$qh = doQuery($query);
 	$compgroups = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$compgroups[] = $row['resourcegroupid'];
 	$mngrps = array();
 	foreach($compgroups as $grpid) {
@@ -7650,7 +7675,7 @@
 	       . "WHERE perlpackage LIKE 'VCL::Module::Predictive::%'";
 	$qh = doQuery($query, 101);
 	$modules = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$modules[$row['id']] = $row;
 	return $modules;
 }
@@ -7722,7 +7747,7 @@
 		       .  "AND platformid IN ($platinlist)";
 	}
 	$qh = doQuery($query, 155);
-	while($row = mysql_fetch_row($qh)) {
+	while($row = mysqli_fetch_row($qh)) {
 		array_push($computerids, $row[0]);
 		$times[$row[0]] = array();
 		$scheduleids[$row[0]] = $row[1];
@@ -7770,7 +7795,7 @@
 	$qh = doQuery($query, 156);
 
 	$id = "";
-	while($row = mysql_fetch_row($qh)) {
+	while($row = mysqli_fetch_row($qh)) {
 		if($row[3] == $requestid) {
 			continue;
 		}
@@ -7934,8 +7959,7 @@
 	              0,
 	              $timeval["mon"],
 	              $timeval["mday"],
-	              $timeval["year"],
-	              -1);
+	              $timeval["year"]);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -8016,11 +8040,11 @@
 		$usercomputerids = array_keys($resources["computer"]);
 		# get list of computers' platformids
 		$qh = doQuery("SELECT platformid FROM image WHERE id = $imageid", 110);
-		$row = mysql_fetch_row($qh);
+		$row = mysqli_fetch_row($qh);
 		$platformid = $row[0];
 		$computer_platformids = array();
 		$qh = doQuery("SELECT id, platformid FROM computer", 111);
-		while($row = mysql_fetch_row($qh)) {
+		while($row = mysqli_fetch_row($qh)) {
 			$computer_platformids[$row[0]] = $row[1];
 		}
 		$mappedcomputers = getMappedResources($imageid, "image", "computer");
@@ -8405,7 +8429,7 @@
 	       .          "(c.procspeed * c.procnumber), "
 	       .          "network";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$row['duration'] = $reqduration;
 		$row['startts'] = $start;
 		$row['start'] = $startdt;
@@ -8459,7 +8483,7 @@
 		       . "GROUP BY rq1.id ";
 		$query .= "ORDER BY rs1.computerid, rq1.start, rq1.end";
 		$qh = doQuery($query, 101);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			$row['startts'] = datetimeToUnix($row['start']);
 			if($row['startts'] % 900) {
 				$row['startts'] = $row['startts'] - ($row['startts'] % 900) + 900;
@@ -8518,7 +8542,7 @@
 	$query .=      "(c.type != 'virtualmachine' OR c.vmhostid IS NOT NULL) "
 	       . "GROUP BY rs.computerid";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($row['endts'] % 900) {
 			$row['endts'] = $row['endts'] - ($row['endts'] % 900);
 			$row['duration'] -= 900;
@@ -8574,7 +8598,7 @@
 	if($extendonly)
 		$query .= " HAVING start = '$startdt'";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($usedaysahead && $row['startts'] > $daysahead)
 			continue;
 		if($row['startts'] % 900) {
@@ -8611,7 +8635,7 @@
 		       .    "br.imageid != $imageid) AND ";
 	$query .=      "bc.computerid IN ($newincompids)";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if(isset($slots[$row['compid']]))
 			fATremoveOverlaps($slots, $row['compid'], $row['start'], $row['end'], 0);
 	}
@@ -8640,7 +8664,7 @@
 		elseif(! empty($mac))
 			$query .=   "s.fixedIP = '$mac'";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			if(isset($slots[$row['compid']]))
 				fATremoveOverlaps($slots, $row['compid'], $row['start'], $row['end'], 0);
 		}
@@ -8654,7 +8678,7 @@
 	       . "WHERE start < '$maxenddt' AND "
 	       .       "end > '$minstartdt'";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		foreach(array_keys($slots) AS $compid)
 			fATremoveOverlaps($slots, $compid, $row['start'], $row['end'],
 			                  $row['allowreservations']);
@@ -8810,7 +8834,7 @@
 	if($extendonly)
 		$query .= " AND rq.id != $reqid";
 	$qh = doQuery($query);
-	if(mysql_num_rows($qh) >= $maxoverlap)
+	if(mysqli_num_rows($qh) >= $maxoverlap)
 		return 1;
 	return 0;
 }
@@ -8963,7 +8987,7 @@
 		$query .= "AND c.id = $compid ";
 	$query .= "ORDER BY c.hostname";
 	$qh = doQuery($query, 180);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if(is_null($row['nathostid'])) {
 			$row['natenabled'] = 0;
 			$row['nathost'] = '';
@@ -9054,13 +9078,13 @@
 	#   need this information
 	$query = "SELECT id FROM computerloadstate WHERE loadstatename = 'repeat'";
 	$qh = doQuery($query, 101);
-	if(! $row = mysql_fetch_assoc($qh))
+	if(! $row = mysqli_fetch_assoc($qh))
 		return array();
 	$loadstates['repeatid'] = $row['id'];
 
 	$query = "SELECT `type` FROM computer WHERE id = $compid";
 	$qh = doQuery($query, 101);
-	if(! $row = mysql_fetch_assoc($qh))
+	if(! $row = mysqli_fetch_assoc($qh))
 		return array();
 
 	$type = $row['type'];
@@ -9079,7 +9103,7 @@
 	        . "(SELECT nextstateid FROM computerloadflow WHERE `type` = '$type' "
 	        . "AND nextstateid IS NOT NULL)";
 	$qh = doQuery($query2, 101);
-	if(! $row = mysql_fetch_assoc($qh))
+	if(! $row = mysqli_fetch_assoc($qh))
 		return array();
 	$loadstates['data'][$row['stateid']] = $row;
 	$loadstates['stateids'] = array($row['stateid']);
@@ -9089,7 +9113,7 @@
 		$query2 = $query . "AND cf.computerloadstateid = {$row['nextstateid']} "
 		        . "AND `type` = '$type'";
 		$qh = doQuery($query2, 101);
-		if(! $row = mysql_fetch_assoc($qh)) {
+		if(! $row = mysqli_fetch_assoc($qh)) {
 			$_SESSION['compstateflow'][$key] = $loadstates;
 			return $loadstates;
 		}
@@ -9134,7 +9158,7 @@
 	       .       "rs.requestid = rq.id "
 	       . "LIMIT 1";
 	$qh = doQuery($query, 101);
-	if(! $row = mysql_fetch_assoc($qh))
+	if(! $row = mysqli_fetch_assoc($qh))
 		abort(113);
 	if($row['start'] < $row['reqtime']) {
 		# now
@@ -9157,7 +9181,7 @@
 	$qh = doQuery($query, 101);
 	$last = array();
 	$data = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$data[$row['id']] = $row;
 		if(empty($last)) {
 			if($future)
@@ -9197,7 +9221,7 @@
 	       .        "start > (NOW() - INTERVAL 12 MONTH) AND "
 	       .        "UNIX_TIMESTAMP(loaded) - UNIX_TIMESTAMP(start) < 1800";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh)) {
+	if($row = mysqli_fetch_assoc($qh)) {
 		if(! empty($row['avgloadtime']))
 			return (int)$row['avgloadtime'];
 		else
@@ -9223,7 +9247,7 @@
 		       . "FROM sublog "
 		       . "WHERE computerid = $compid";
 		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_row($qh))
+		if($row = mysqli_fetch_row($qh))
 			$computers[$compid]["counts"] = $row[0];
 		else
 			$computers[$compid]["counts"] = 0;
@@ -9350,7 +9374,7 @@
 	       .       "c2.id NOT IN ($alloccompids) "
 	       . "ORDER BY s.name";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$data['compids'][] = $row['computerid'];
 		$data[$row['computerid']] = $row;
 	}
@@ -9381,7 +9405,7 @@
 	       .       "t.start < '$enddt' AND "
 	       .       "c.blockTimeid = t.id";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		array_push($compids, $row['computerid']);
 	}
 	return $compids;
@@ -9417,7 +9441,7 @@
 	if($id)
 		$query .= " WHERE n.id = $id";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$nathosts[$row['id']] = $row;
 	if($sort)
 		uasort($nathosts, "sortKeepIndex");
@@ -9455,7 +9479,7 @@
 	       . "WHERE n.connectmethodportid = c.id AND "
 	       .       "n.reservationid = $resid";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$ports[$row['connectmethodid']]["#Port-{$row['protocol']}-{$row['privateport']}#"] = $row;
 	return $ports;
 }
@@ -9475,7 +9499,8 @@
 /// \b domaindnsname\n
 /// \b username\n
 /// \b dnsservers\n
-/// \b secretid
+/// \b secretid\n
+/// \b usedbhostnames
 ///
 /// \brief builds an array of AD domains
 ///
@@ -9489,7 +9514,8 @@
 	       .        "ad.domainDNSName AS domaindnsname, "
 	       .        "ad.username, "
 	       .        "ad.dnsServers AS dnsservers, "
-	       .        "ad.secretid "
+	       .        "ad.secretid, "
+	       .        "ad.usedbhostnames "
 	       . "FROM addomain ad, "
 	       .      "affiliation a, "
 	       .      "user u, "
@@ -9505,7 +9531,7 @@
 
 	$qh = doQuery($query);
 	$addomainlist = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$addomainlist[$row['id']] = $row;
 	return $addomainlist;
 }
@@ -9568,7 +9594,7 @@
 		$query .= " AND t.end > '" . unixToDatetime($start) . "'";
 	$query .= " ORDER BY t.start, t.end";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$return[$row['timeid']] = $row;
 		$return[$row['timeid']]['unixstart'] = datetimeToUnix($row['start']);
 		$return[$row['timeid']]['unixend'] = datetimeToUnix($row['end']);
@@ -9577,7 +9603,7 @@
 		        . "FROM blockComputers "
 		        . "WHERE blockTimeid = {$row['timeid']}";
 		$qh2 = doQuery($query2, 101);
-		while($row2 = mysql_fetch_assoc($qh2))
+		while($row2 = mysqli_fetch_assoc($qh2))
 			array_push($return[$row['timeid']]['computerids'], $row2['computerid']);
 	}
 	return $return;
@@ -9631,7 +9657,7 @@
 	       .       "bt.end > '$nowdt' AND "
 	       .       "br.imageid = $imageid";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh))
+	if($row = mysqli_fetch_assoc($qh))
 		return 1;
 	return 0;
 }
@@ -10234,7 +10260,7 @@
 	       .       "u.courseroll = 0";
 	$qh = doQuery($query, 305);
 	$oldusergroups = array();
-	while($row = mysql_fetch_row($qh)) {
+	while($row = mysqli_fetch_row($qh)) {
 		array_push($oldusergroups, $row[0]);
 	}
 	if(count(array_diff($oldusergroups, $newusergroups)) ||
@@ -10282,7 +10308,7 @@
 	       . "WHERE name = '$name' AND "
 	       .       "affiliationid = $affilid";
 	$qh = doQuery($query, 300);
-	if($row = mysql_fetch_row($qh))
+	if($row = mysqli_fetch_row($qh))
 		return $row[0];
 	elseif($noadd)
 		return NULL;
@@ -10298,7 +10324,7 @@
 	       .        "0)";
 	doQuery($query, 301);
 	$qh = doQuery("SELECT LAST_INSERT_ID() FROM usergroup", 302);
-	if(! $row = mysql_fetch_row($qh)) {
+	if(! $row = mysqli_fetch_row($qh)) {
 		abort(303);
 	}
 	return $row[0];
@@ -10331,7 +10357,7 @@
 		       . "WHERE id = $id";
 	}
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_row($qh))
+	if($row = mysqli_fetch_row($qh))
 		return $row[0];
 	return 0;
 }
@@ -10408,7 +10434,7 @@
 	$query .= "ORDER BY m.start";
 	$qh = doQuery($query, 101);
 	$data = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$data[$row['id']] = $row;
 	$_SESSION['usersessiondata'][$key] = $data;
 	return $data;
@@ -10443,7 +10469,7 @@
 	       . "ORDER BY start";
 	$qh = doQuery($query, 101);
 	$data = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$data[] = $row;
 	$_SESSION['usersessiondata'][$key] = $data;
 	return $data;
@@ -10662,13 +10688,13 @@
 	       . "FROM log "
 	       . "WHERE id = $logid";
 	$qh = doQuery($query, 265);
-	if(! $log = mysql_fetch_assoc($qh)) {
+	if(! $log = mysqli_fetch_assoc($qh)) {
 		abort(30);
 	}
 	$log["computerid"] = array();
 	$query = "SELECT computerid FROM sublog WHERE logid = $logid";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		array_push($log["computerid"], $row["computerid"]);
 	}
 	$changed = 0;
@@ -10770,7 +10796,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function addChangeLogEntryOther($logid, $data) {
-	$data = mysql_real_escape_string($data);
+	$data = vcl_mysql_escape_string($data);
 	$query = "INSERT INTO changelog "
 	       .        "(logid, "
 	       .        "timestamp, "
@@ -10806,7 +10832,7 @@
 	       . "FROM computer "
 	       . "WHERE id = $computerid";
 	$qh = doQuery($query, 101);
-	$row = mysql_fetch_assoc($qh);
+	$row = mysqli_fetch_assoc($qh);
 	$predictiveid = $row['predictivemoduleid'];
 	$query = "SELECT c.type, "
 	       .        "v.computerid AS hostid "
@@ -10814,7 +10840,7 @@
 	       . "LEFT JOIN vmhost v ON (c.vmhostid = v.id) "
 	       . "WHERE c.id = $computerid";
 	$qh = doQuery($query, 101);
-	$row = mysql_fetch_assoc($qh);
+	$row = mysqli_fetch_assoc($qh);
 	if($row['type'] == 'virtualmachine')
 		$hostcomputerid = $row['hostid'];
 	else
@@ -10866,7 +10892,7 @@
 	if($subtype == "users" || $subtype == "both") {
 		$query = "SELECT id, name FROM userprivtype WHERE name NOT IN ('configAdmin', 'serverProfileAdmin')";
 		$qh = doQuery($query, 365);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			if($row["name"] == "block" || $row["name"] == "cascade")
 				continue;
 			$types["users"][$row["id"]] = $row["name"];
@@ -10875,7 +10901,7 @@
 	if($subtype == "resources" || $subtype == "both") {
 		$query = "SELECT id, name FROM resourcetype";
 		$qh = doQuery($query, 366);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$types["resources"][$row["id"]] = $row["name"];
 	}
 	return $types;
@@ -10895,7 +10921,7 @@
 function getUserPrivTypeID($type) {
 	$query = "SELECT id FROM userprivtype WHERE name = '$type'";
 	$qh = doQuery($query, 370);
-	if($row = mysql_fetch_row($qh))
+	if($row = mysqli_fetch_row($qh))
 		return $row[0];
 	else
 		return NULL;
@@ -11067,8 +11093,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 function getResourceGroupID($groupname) {
 	list($type, $name) = explode('/', $groupname);
-	$type = mysql_real_escape_string($type);
-	$name = mysql_real_escape_string($name);
+	$type = vcl_mysql_escape_string($type);
+	$name = vcl_mysql_escape_string($name);
 	$query = "SELECT g.id "
 	       . "FROM resourcegroup g, "
 	       .      "resourcetype t "
@@ -11076,7 +11102,7 @@
 	       .       "t.name = '$type' AND "
 	       .       "g.resourcetypeid = t.id";
 	$qh = doQuery($query, 371);
-	if($row = mysql_fetch_row($qh))
+	if($row = mysqli_fetch_row($qh))
 		return $row[0];
 	else
 		return NULL;
@@ -11099,7 +11125,7 @@
 	       . "FROM resourcegroup "
 	       . "WHERE id = $groupid";
 	$qh = doQuery($query);
-	if($row = mysql_fetch_assoc($qh))
+	if($row = mysqli_fetch_assoc($qh))
 		return $row['name'];
 	else
 		return NULL;
@@ -11117,12 +11143,12 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function getResourceTypeID($name) {
-	$name = mysql_real_escape_string($name);
+	$name = vcl_mysql_escape_string($name);
 	$query = "SELECT id "
 	       . "FROM resourcetype "
 	       . "WHERE name = '$name'";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_row($qh))
+	if($row = mysqli_fetch_row($qh))
 		return $row[0];
 	else
 		return NULL;
@@ -11141,7 +11167,7 @@
 function getResourcePrivs() {
 	$query = "show columns from resourcepriv where field = 'type'";
 	$qh = doQuery($query, 101);
-	$row = mysql_fetch_assoc($qh);
+	$row = mysqli_fetch_assoc($qh);
 	preg_match("/^enum\(([a-zA-Z0-9,']+)\)$/", $row['Type'], $matches);
 	$tmp = str_replace("'", '', $matches[1]);
 	return explode(',', $tmp);
@@ -11161,7 +11187,7 @@
 	$query = "SELECT id, prettyname FROM configtype ORDER BY name";
 	$qh = doQuery($query);
 	$types = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$types[$row['id']] = $row['prettyname'];
 	return $types;
 }
@@ -11180,7 +11206,7 @@
 	$query = "SELECT id, name FROM datatype ORDER BY name";
 	$qh = doQuery($query);
 	$types = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$types[$row['id']] = $row['name'];
 	return $types;
 }
@@ -11205,7 +11231,7 @@
 	$query .= "ORDER BY prettyname";
 	$qh = doQuery($query);
 	$types = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$types[$row['id']] = $row['prettyname'];
 	return $types;
 }
@@ -11271,7 +11297,7 @@
 	$qh = doQuery($query);
 	$configs = array();
 	$configids = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$row['configmapid'] = $row['id'];
 		if(is_null($row['subimageid']))
 			$configids[] = $row['configid'];
@@ -11382,7 +11408,7 @@
 	$qh = doQuery($query);
 	$configs = array();
 	$configids = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$row['configmapid'] = $row['id'];
 		if(is_null($row['subimageid']))
 			$configids[] = $row['configid'];
@@ -11452,7 +11478,7 @@
 	       . "ORDER BY cv.configid";
 	$data = array();
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$row['required'] = (int)$row['required'];
 		$row['ask'] = (int)$row['ask'];
 		#$row['defaultvalue'] = htmlspecialchars($row['defaultvalue']);
@@ -11525,7 +11551,7 @@
 	$qh = doQuery($query);
 	$clusters = array();
 	$subimageids = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$children = getConfigClustersRec($row['configsubimageid'], $flat);
 		if(! empty($children)) {
 			if($flat)
@@ -11588,7 +11614,7 @@
 	       .        "a.name = 'Global')";
 	$qh = doQuery($query);
 	$clusters = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($rec < 20)
 			$children = getConfigClustersRec($row['configsubimageid'], $flat, ++$rec);
 		if($rec < 20 && ! empty($children)) {
@@ -11616,7 +11642,7 @@
 	$query = "SELECT id, name FROM OStype ORDER BY name";
 	$qh = doQuery($query);
 	$types = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$types[$row['id']] = $row['name'];
 	return $types;
 }
@@ -11649,7 +11675,7 @@
 	       .       "c.id IN ($inlist)";
 	$configs = array();
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$configs[$row['id']] = $row['name'];
 	return $configs;
 }
@@ -11672,7 +11698,7 @@
 	if(isset($cache['nodes'][$nodeid]))
 		return $cache['nodes'][$nodeid];
 	$qh = doQuery("SELECT id, parent, name FROM privnode", 330);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$cache['nodes'][$row['id']] = $row;
 	if(isset($cache['nodes'][$nodeid]))
 		return $cache['nodes'][$nodeid];
@@ -11849,7 +11875,7 @@
 	if(! empty($resource2inlist))
 		$query .= "AND resourcegroupid2 IN ($resource2inlist) ";
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($resourcetype1 == $row['resourcetypeid1']) {
 			if(array_key_exists($row["resourcegroupid1"], $return))
 				array_push($return[$row["resourcegroupid1"]], $row["resourcegroupid2"]);
@@ -11901,7 +11927,7 @@
 	       . "ORDER BY c.description";
 	$methods = array();
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$methods[$row['id']] = $row;
 	$_SESSION['usersessiondata'][$key] = $methods;
 	return $methods;
@@ -11939,7 +11965,7 @@
 	       . "ORDER BY start "
 	       . "LIMIT 1";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh)) {
+	if($row = mysqli_fetch_assoc($qh)) {
 		$end = datetimeToUnix($request["end"]);
 		$start = datetimeToUnix($row["start"]);
 		return ($start - $end) / 60;
@@ -11984,8 +12010,8 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function cleanSemaphore() {
-	global $mysql_link_vcl, $uniqid;
-	if(! is_resource($mysql_link_vcl) || ! get_resource_type($mysql_link_vcl) == 'mysql link')
+	global $mysqli_link_vcl, $uniqid;
+	if(! is_resource($mysqli_link_vcl) || ! get_resource_type($mysqli_link_vcl) == 'mysql link')
 		return;
 	$query = "DELETE FROM semaphore "
 	       . "WHERE procid = '$uniqid'";
@@ -12093,7 +12119,7 @@
 		$query .= " AND vp.id = $id";
 	$qh = doQuery($query, 101);
 	$ret = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$ret[$row['id']] = $row;
 	return $ret;
 }
@@ -12113,7 +12139,7 @@
 function getENUMvalues($table, $field) {
 	$query = "DESC $table";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($row['Field'] == "$field") {
 			$data = preg_replace(array('/^enum\(/', "/'/", '/\)$/'), array('', '', ''), $row['Type']);
 			$types = explode(',', $data);
@@ -12162,7 +12188,7 @@
 		$contid = md5($mode . $nextmode . $serdata . $user['id'] . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']);
 	else
 		$contid = md5($mode . $nextmode . $serdata . $user['id'] . $_SERVER['REMOTE_ADDR']);
-	$serdata = mysql_real_escape_string($serdata);
+	$serdata = vcl_mysql_escape_string($serdata);
 	$expiretime = unixToDatetime(time() + $duration);
 	$query = "SELECT id, "
 	       .        "parentid "
@@ -12170,7 +12196,7 @@
 	       . "WHERE id = '$contid' AND "
 	       .       "userid = {$user['id']}";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh)) {
+	if($row = mysqli_fetch_assoc($qh)) {
 		# update expiretime
 		$query = "UPDATE continuations "
 		       . "SET expiretime = '$expiretime' "
@@ -12193,7 +12219,7 @@
 			       . "WHERE id = '$continuationid' AND "
 			       .       "userid = {$user['id']}";
 			$qh = doQuery($query, 101);
-			if(! $row = mysql_fetch_assoc($qh))
+			if(! $row = mysqli_fetch_assoc($qh))
 				abort(108);
 			$deletefromid = $row['deletefromid'];
 		}
@@ -12277,7 +12303,7 @@
 	$qh = doQuery($query, 101);
 
 	# return error if it is not there
-	if(! ($row = mysql_fetch_assoc($qh)))
+	if(! ($row = mysqli_fetch_assoc($qh)))
 		return array('error' => 'continuation does not exist');
 
 	# return error if it is expired
@@ -12383,7 +12409,7 @@
 	       . "FROM shibauth "
 	       . "WHERE id = $id";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh)) {
+	if($row = mysqli_fetch_assoc($qh)) {
 		$data = unserialize($row['data']);
 		unset($row['data']);
 		$data2 = array_merge($row, $data);
@@ -12422,7 +12448,7 @@
 	$query .= "FROM variable "
 	       .  "WHERE name = '$key'";
 	$qh = doQuery($query);
-	if($row = mysql_fetch_assoc($qh)) {
+	if($row = mysqli_fetch_assoc($qh)) {
 		if($incparams) {
 			switch($row['serialization']) {
 				case 'yaml':
@@ -12473,7 +12499,7 @@
 	       . "WHERE name REGEXP '$pattern'";
 	$qh = doQuery($query);
 	$ret = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		switch($row['serialization']) {
 			case 'none':
 				$ret[$row['name']] = $row['value'];
@@ -12509,7 +12535,7 @@
 	$update = 0;
 	$query = "SELECT serialization FROM variable WHERE name = '$key'";
 	$qh = doQuery($query);
-	if($row = mysql_fetch_assoc($qh)) {
+	if($row = mysqli_fetch_assoc($qh)) {
 		if($serialization == '')
 			$serialization = $row['serialization'];
 		$update = 1;
@@ -12519,14 +12545,14 @@
 	$_SESSION['variables'][$key] = $data;
 	switch($serialization) {
 		case 'none':
-			$qdata = mysql_real_escape_string($data);
+			$qdata = vcl_mysql_escape_string($data);
 			break;
 		case 'yaml':
 			$yaml = Spyc::YAMLDump($data);
-			$qdata = mysql_real_escape_string($yaml);
+			$qdata = vcl_mysql_escape_string($yaml);
 			break;
 		case 'phpserialize':
-			$qdata = mysql_real_escape_string(serialize($data));
+			$qdata = vcl_mysql_escape_string(serialize($data));
 			break;
 	}
 	if($update)
@@ -12737,7 +12763,7 @@
 		$keyid = $user['id'];
 	if(function_exists($function)) {
 		if(! defined('XMLRPCLOGGING') || XMLRPCLOGGING != 0) {
-			$saveargs = mysql_real_escape_string(serialize($args));
+			$saveargs = vcl_mysql_escape_string(serialize($args));
 			$query = "INSERT INTO xmlrpcLog "
 			       .        "(xmlrpcKeyid, "
 			       .        "timestamp, "
@@ -12778,13 +12804,13 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function xmlRPCabort($errcode, $query='') {
-	global $mysql_link_vcl, $mysql_link_acct, $ERRORS, $user, $mode;
+	global $mysqli_link_vcl, $mysqli_link_acct, $ERRORS, $user, $mode;
 	global $XMLRPCERRORS;
 	if(ONLINEDEBUG && checkUserHasPerm('View Debug Information')) {
 		$msg = '';
 		if($errcode >= 100 && $errcode < 400) {
-			$msg .= "ERROR (" . mysql_errno($mysql_link_vcl) . ") - ";
-			$msg .= mysql_error($mysql_link_vcl) . " $query ";
+			$msg .= "ERROR (" . mysqli_errno($mysqli_link_vcl) . ") - ";
+			$msg .= mysqli_error($mysqli_link_vcl) . " $query ";
 		}
 		$msg .= $ERRORS["$errcode"];
 		$XMLRPCERRORS[100] = $msg;
@@ -12793,8 +12819,8 @@
 	else {
 		$message = "";
 		if($errcode >= 100 && $errcode < 400) {
-			$message .= mysql_error($mysql_link_vcl) . "\n";
-			$message .= mysql_error($mysql_link_acct) . "\n";
+			$message .= mysqli_error($mysqli_link_vcl) . "\n";
+			$message .= mysqli_error($mysqli_link_acct) . "\n";
 			$message .= $query . "\n";
 		}
 		$message .= "ERROR($errcode): " . $ERRORS["$errcode"] . "\n";
@@ -12944,7 +12970,7 @@
 			             'errormsg' => 'existing user group with submitted name and affiliation');
 		}
 		elseif($exists && $doesexist) {
-			$esc_name = mysql_real_escape_string($items['name']);
+			$esc_name = vcl_mysql_escape_string($items['name']);
 			$items['id'] = getUserGroupID($esc_name, $affilid);
 		}
 	}
@@ -13093,7 +13119,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 function sendHeaders() {
 	global $mode, $user, $authed, $oldmode, $actionFunction;
-	global $shibauthed;
+	global $shibauthed, $authFuncs;
 	if(! $authed && $mode == "auth") {
 		header("Location: " . BASEURL . SCRIPT . "?mode=selectauth");
 		dbDisconnect();
@@ -13101,78 +13127,22 @@
 	}
 	switch($mode) {
 		case 'logout':
-			if($shibauthed) {
-				$shibdata = getShibauthData($shibauthed);
-				// TODO make shib-logouturl comparison caseless
-				if(array_key_exists('Shib-logouturl', $shibdata) &&
-				   ! empty($shibdata['Shib-logouturl'])) {
-					dbDisconnect();
-					header("Location: {$shibdata['Shib-logouturl']}");
-					exit;
-				}
-			}
-		case 'shiblogout':
-			setcookie("ITECSAUTH", "", time() - 10, "/", COOKIEDOMAIN);
-			setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
-			if($shibauthed) {
-				$msg = '';
-				$shibdata = getShibauthData($shibauthed);
-				# find and clear shib cookies
-				/*foreach(array_keys($_COOKIE) as $key) {
-					if(preg_match('/^_shibsession[_0-9a-fA-F]+$/', $key))
-						setcookie($key, "", time() - 10, "/", $_SERVER['SERVER_NAME']);
-					elseif(preg_match('/^_shibstate_/', $key))
-						setcookie($key, "", time() - 10, "/", $_SERVER['SERVER_NAME']);
-				}*/
-				doQuery("DELETE FROM shibauth WHERE id = $shibauthed", 101);
+			$authtype = getAuthTypeFromAuthCookie();
+			if(is_null($authtype)) {
 				stopSession();
 				dbDisconnect();
-				if(array_key_exists('Shib-logouturl', $shibdata) &&
-				   ! empty($shibdata['Shib-logouturl'])) {
-					print "<html>\n";
-					print "   <head>\n";
-					print "      <style type=\"text/css\">\n";
-					print "         .red {\n";
-					print "            color: red;\n";
-					print "         }\n";
-					print "         body{\n";
-					print "            margin:0px; color: red;\n";
-					print "         }\n";
-					print "      </style>\n";
-					print "   </head>\n";
-					print "   <body>\n";
-					print "      <span class=red>Done.</span>&nbsp;&nbsp;&nbsp;<a target=\"_top\" href=\"" . BASEURL . "/\">Return to VCL</a>\n";
-					print "   </body>\n";
-					print "</html>\n";
-				}
-				else {
-					print "<html>\n";
-					print "<head>\n";
-					print "<META HTTP-EQUIV=REFRESH CONTENT=\"5;url=" . BASEURL . "\">\n";
-					print "<style type=\"text/css\">\n";
-					print "  .hidden {\n";
-					print "    display: none;\n";
-					print "  }\n";
-					print "</style>\n";
-					print "</head>\n";
-					print "<body>\n";
-					print "Logging out of VCL...";
-					print "<iframe src=\"https://{$_SERVER['SERVER_NAME']}/Shibboleth.sso/Logout\" class=hidden>\n";
-					print "</iframe>\n";
-					if(array_key_exists('Shib-Identity-Provider', $shibdata) &&
-					   ! empty($shibdata['Shib-Identity-Provider'])) {
-						$tmp = explode('/', $shibdata['Shib-Identity-Provider']);
-						$idp = "{$tmp[0]}//{$tmp[2]}";
-						print "<iframe src=\"$idp/idp/logout.jsp\" class=hidden>\n";
-						print "</iframe>\n";
-					}
-					print "</body>\n";
-					print "</html>\n";
-				}
+				header("Location: " . BASEURL . SCRIPT);
 				exit;
 			}
-			header("Location: " . HOMEURL);
+			$authFuncs[$authtype]['unauth']('headers');
+			setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN);
+			$authed = 0;
+			ob_start();
+			printHTMLHeader();
+			$authFuncs[$authtype]['unauth']('content');
+			printHTMLFooter();
 			stopSession();
+			ob_end_flush();
 			dbDisconnect();
 			exit;
 	}
diff --git a/web/.ht-inc/vm.php b/web/.ht-inc/vm.php
index 5375cdf..90c96a5 100644
--- a/web/.ht-inc/vm.php
+++ b/web/.ht-inc/vm.php
@@ -47,7 +47,7 @@
 	print "</div>\n";
 
 	$newmsg = "To create a new Virtual Host, change the state of a computer to<br>\n"
-	        . "'vmhostinuse' under Manage Computers-&gt;Computer Utilities.<br><br>\n";
+	        . "'vmhostinuse' under Manage Computers-&gt;Edit Computer Profiles.<br><br>\n";
 	$vmhosts = getVMHostData();
 	$resources = getUserResources(array("computerAdmin"), array("administer"));
 	foreach($vmhosts as $key => $value) {
@@ -380,7 +380,7 @@
 	$currvms = array();
 	$noaccess = array();
 	$freevms = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($row['vmhostid'] == $vmhostid) {
 			$ids[$row['id']] = $row['hostname'];
 			if(array_key_exists($row['id'], $computers))
@@ -423,7 +423,7 @@
 		       .       "rq.laststateid = 18) AND "
 		       .       "rq.start > NOW()";
 		$qh = doQuery($query, 101);
-		while($row = mysql_fetch_assoc($qh)) {
+		while($row = mysqli_fetch_assoc($qh)) {
 			$movevms[] = array('id' => $row['id'],
 			                 'time' => strtolower($row['start']) . ' ' . date('T'),
 			                 'hostname' => $currvms[$row['computerid']]['name']);
@@ -480,7 +480,7 @@
 		$query .= " AND vh.id = $id";
 	$qh = doQuery($query, 101);
 	$ret = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$ret[$row['id']] = $row;
 		foreach($profiles[$row['vmprofileid']] AS $key => $value) {
 			if(is_null($value))
@@ -524,7 +524,7 @@
 	       . "WHERE id in ($vmlistids)";
 	$qh = doQuery($query, 101);
 	$vmdata = array();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if(! array_key_exists($row['id'], $resources['computer'])) {
 			$fails[] = array('id' => $row['id'], 'name' => $row['hostname'], 'reason' => 'noaccess');
 			unset_by_val($row['id'], $vmids);
@@ -537,7 +537,7 @@
 	$query = "SELECT id FROM vmhost";
 	$vmhosts = array();
 	$qh = doQuery($query, 101);
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$vmhosts[$row['id']] = 1;
 
 	# check to see if there any submitted vms have a hostid of an existing vm host
@@ -616,7 +616,7 @@
 		       . "ORDER BY end DESC "
 		       . "LIMIT 1";
 		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_assoc($qh)) {
+		if($row = mysqli_fetch_assoc($qh)) {
 			$checks[] = array('id' => $compid,
 			                  'hostname' => $compdata[$compid]['hostname'],
 			                  'end' => strtolower($row['end']) . ' ' . date('T'),
@@ -840,11 +840,11 @@
 	else {
 		if(get_magic_quotes_gpc())
 			$newvalue = stripslashes($newvalue);
-		$newvalue2 = mysql_real_escape_string($newvalue);
+		$newvalue2 = vcl_mysql_escape_string($newvalue);
 		$newvalue2 = "'$newvalue2'";
 	}
 
-	$item = mysql_real_escape_string($item);
+	$item = vcl_mysql_escape_string($item);
 	$profile = getVMProfiles($profileid);
 	if($item == 'password') {
 		$pwdlen = strlen($newvalue);
@@ -878,7 +878,7 @@
 			       . "WHERE cryptkeyid = $cryptkeyid AND "
 			       .       "secretid = $secretid";
 			$qh = doQuery($query);
-			if(! ($row = mysql_fetch_assoc($qh))) {
+			if(! ($row = mysqli_fetch_assoc($qh))) {
 				# generate a new secret
 				$newsecretid = getSecretKeyID('vmprofile', 'secretid', 0);
 				$delids = array($secretid);
@@ -895,7 +895,7 @@
 				       . "WHERE cs.secretid = $secretid AND "
 				       .       "ck.hosttype = 'managementnode'";
 				$qh = doQuery($query);
-				while($row = mysql_fetch_assoc($qh))
+				while($row = mysqli_fetch_assoc($qh))
 					$secretidset[$row['mnid']][$newsecretid] = 1;
 				$values = getMNcryptkeyUpdates($secretidset, $cryptkeyid);
 				addCryptSecretKeyUpdates($values);
@@ -946,11 +946,11 @@
 	$newprofile = processInputVar('newname', ARG_STRING);
 	if(get_magic_quotes_gpc()) {
 		$newprofile = stripslashes($newprofile);
-		$newprofile = mysql_real_escape_string($newprofile);
+		$newprofile = vcl_mysql_escape_string($newprofile);
 	}
 	$query = "SELECT id FROM vmprofile WHERE profilename = '$newprofile'";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh)) {
+	if($row = mysqli_fetch_assoc($qh)) {
 		sendJSON(array('failed' => 'exists'));
 		return;
 	}
@@ -994,7 +994,7 @@
 	       .       "s.name IN ('vmhostinuse', 'tovmhostinuse') AND " 
 	       .       "vh.vmprofileid = $profileid";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh)) {
+	if($row = mysqli_fetch_assoc($qh)) {
 		sendJSON(array('failed' => 'inuse'));
 		return;
 	}
diff --git a/web/.ht-inc/xmlrpcWrappers.php b/web/.ht-inc/xmlrpcWrappers.php
index 0ec5c74..33b1587 100644
--- a/web/.ht-inc/xmlrpcWrappers.php
+++ b/web/.ht-inc/xmlrpcWrappers.php
@@ -430,7 +430,7 @@
 			$admingroup = stripslashes($admingroup);
 		if(preg_match('/@/', $admingroup)) {
 			$tmp = explode('@', $admingroup);
-			$escadmingroup = mysql_real_escape_string($tmp[0]);
+			$escadmingroup = vcl_mysql_escape_string($tmp[0]);
 			$affilid = getAffiliationID($tmp[1]);
 			if(is_null($affilid)) {
 				return array('status' => 'error',
@@ -439,7 +439,7 @@
 			}
 		}
 		else {
-			$escadmingroup = mysql_real_escape_string($admingroup);
+			$escadmingroup = vcl_mysql_escape_string($admingroup);
 			$affilid = DEFAULT_AFFILID;
 		}
 		$admingroupid = getUserGroupID($escadmingroup, $affilid, 1);
@@ -457,7 +457,7 @@
 			$logingroup = stripslashes($logingroup);
 		if(preg_match('/@/', $logingroup)) {
 			$tmp = explode('@', $logingroup);
-			$esclogingroup = mysql_real_escape_string($tmp[0]);
+			$esclogingroup = vcl_mysql_escape_string($tmp[0]);
 			$affilid = getAffiliationID($tmp[1]);
 			if(is_null($affilid)) {
 				return array('status' => 'error',
@@ -466,7 +466,7 @@
 			}
 		}
 		else {
-			$esclogingroup = mysql_real_escape_string($logingroup);
+			$esclogingroup = vcl_mysql_escape_string($logingroup);
 			$affilid = DEFAULT_AFFILID;
 		}
 		$logingroupid = getUserGroupID($esclogingroup, $affilid, 1);
@@ -514,7 +514,7 @@
 		                         . "spaces, dashes(-), underscores(_), and periods(.) "
 		                         . "and be up to 255 characters long");
 	}
-	$name = mysql_real_escape_string($name);
+	$name = vcl_mysql_escape_string($name);
 
 	# validate $start
 	if($start != 'now' && ! is_numeric($start)) {
@@ -574,7 +574,7 @@
 	if($userdata != '') {
 		if(get_magic_quotes_gpc())
 			$userdata = stripslashes($userdata);
-		$esc_userdata = mysql_real_escape_string($userdata);
+		$esc_userdata = vcl_mysql_escape_string($userdata);
 		$query = "INSERT INTO variable "
 		       .        "(name, "
 		       .        "serialization, "
@@ -1334,7 +1334,7 @@
 	}
 	$query = "SELECT id FROM request WHERE id = $requestid";
 	$qh = doQuery($query, 101);
-	if(! mysql_num_rows($qh)) {
+	if(! mysqli_num_rows($qh)) {
 		return array('status' => 'error',
 		             'errorcode' => 52,
 		             'errormsg' => 'specified request does not exist');
@@ -1772,13 +1772,13 @@
 		in_array("nodeAdmin", $user["privileges"])) {
 		if(get_magic_quotes_gpc())
 			$nodeName = stripslashes($nodeName);
-		$nodeName = mysql_real_escape_string($nodeName);
+		$nodeName = vcl_mysql_escape_string($nodeName);
 		// does a node with this name already exist?
 		$query = "SELECT id "
 		       . "FROM privnode "
 		       . "WHERE name = '$nodeName' AND parent = $parentNode";
 		$qh = doQuery($query, 335);
-		if(mysql_num_rows($qh))
+		if(mysqli_num_rows($qh))
 			return array('status' => 'success', 'exists' => TRUE);
 		else
 			return array('status' => 'success', 'exists' => FALSE);
@@ -1836,7 +1836,7 @@
 			       . "FROM privnode "
 			       . "WHERE name = '$nodeName' AND parent = $parentNode";
 			$qh = doQuery($query);
-			if(mysql_num_rows($qh)) {
+			if(mysqli_num_rows($qh)) {
 				return array('status' => 'error',
 				             'errorcode' => 82,
 				             'errormsg' => 'A node of that name already exists under ' . $nodeInfo['name']);
@@ -1847,7 +1847,7 @@
 			       .        "($parentNode, '$nodeName')";
 			doQuery($query);
 			$qh = doQuery("SELECT LAST_INSERT_ID() FROM privnode", 101);
-			if(! $row = mysql_fetch_row($qh)) {
+			if(! $row = mysqli_fetch_row($qh)) {
 				return array('status' => 'error',
 				             'errorcode' => 85,
 				             'errormsg' => 'Could not add node to database');
@@ -2470,7 +2470,7 @@
 	       . "LEFT JOIN affiliation euga ON (eug.affiliationid = euga.id) "
 	       . "WHERE ug.id = {$rc['id']}";
 	$qh = doQuery($query, 101);
-	if(! $row = mysql_fetch_assoc($qh)) {
+	if(! $row = mysqli_fetch_assoc($qh)) {
 		return array('status' => 'error',
 		             'errorcode' => 18,
 		             'errormsg' => 'user group with submitted name and affiliation does not exist');
@@ -2607,7 +2607,7 @@
                              $newOwner='', $newManagingGroup='',
                              $newInitialMaxTime='', $newTotalMaxTime='',
                              $newMaxExtendTime='') {
-	global $user, $mysql_link_vcl;
+	global $user, $mysqli_link_vcl;
 	if(! in_array('groupAdmin', $user['privileges'])) {
 		return array('status' => 'error',
 		             'errorcode' => 16,
@@ -2650,7 +2650,7 @@
 	       . "FROM usergroup "
 	       . "WHERE id = {$rc['id']}";
 	$qh = doQuery($query, 101);
-	if(! $row = mysql_fetch_assoc($qh)) {
+	if(! $row = mysqli_fetch_assoc($qh)) {
 		return array('status' => 'error',
 		             'errorcode' => 18,
 		             'errormsg' => 'user group with submitted name and affiliation does not exist');
@@ -2675,7 +2675,7 @@
 			if(get_magic_quotes_gpc())
 				$newName = stripslashes($newName);
 			$validate['name'] = $newName;
-			$tmp = mysql_real_escape_string($newName);
+			$tmp = vcl_mysql_escape_string($newName);
 			$updates[] = "name = '$tmp'";
 		}
 		if(! empty($newAffiliation))
@@ -2694,7 +2694,7 @@
 
 	if($row['custom']) {
 		if(! empty($newOwner)) {
-			$newownerid = getUserlistID(mysql_real_escape_string($newOwner));
+			$newownerid = getUserlistID(vcl_mysql_escape_string($newOwner));
 			$updates[] = "ownerid = $newownerid";
 		}
 		if(! empty($newManagingGroup))
@@ -2732,7 +2732,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function XMLRPCremoveUserGroup($name, $affiliation) {
-	global $user, $mysql_link_vcl;
+	global $user, $mysqli_link_vcl;
 	if(! in_array('groupAdmin', $user['privileges'])) {
 		return array('status' => 'error',
 		             'errorcode' => 16,
@@ -2750,7 +2750,7 @@
 	       . "FROM usergroup "
 	       . "WHERE id = {$rc['id']}";
 	$qh = doQuery($query, 101);
-	if(! $row = mysql_fetch_assoc($qh)) {
+	if(! $row = mysqli_fetch_assoc($qh)) {
 		return array('status' => 'error',
 		             'errorcode' => 18,
 		             'errormsg' => 'user group with submitted name and affiliation does not exist');
@@ -2775,7 +2775,7 @@
 	       . "WHERE id = {$rc['id']}";
 	doQuery($query, 101);
 	# validate something deleted
-	if(mysql_affected_rows($mysql_link_vcl) == 0) {
+	if(mysqli_affected_rows($mysqli_link_vcl) == 0) {
 		return array('status' => 'error',
 		             'errorcode' => 30,
 		             'errormsg' => 'failure while deleting group from database');
@@ -2849,7 +2849,7 @@
 	       . "FROM usergroup "
 	       . "WHERE id = {$rc['id']}";
 	$qh = doQuery($query, 101);
-	if(! $row = mysql_fetch_assoc($qh)) {
+	if(! $row = mysqli_fetch_assoc($qh)) {
 		return array('status' => 'error',
 		             'errorcode' => 18,
 		             'errormsg' => 'user group with submitted name and affiliation does not exist');
@@ -2875,7 +2875,7 @@
 	       .       "u.affiliationid = a.id";
 	$qh = doQuery($query, 101);
 	$members = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$members[] = $row['member'];
 	return array('status' => 'success',
 	             'members' => $members);
@@ -2924,7 +2924,7 @@
 	       . "FROM usergroup "
 	       . "WHERE id = {$rc['id']}";
 	$qh = doQuery($query, 101);
-	if(! $row = mysql_fetch_assoc($qh)) {
+	if(! $row = mysqli_fetch_assoc($qh)) {
 		return array('status' => 'error',
 		             'errorcode' => 18,
 		             'errormsg' => 'user group with submitted name and affiliation does not exist');
@@ -2942,7 +2942,7 @@
 			continue;
 		if(get_magic_quotes_gpc())
 			$_user = stripslashes($_user);
-		$esc_user = mysql_real_escape_string($_user);
+		$esc_user = vcl_mysql_escape_string($_user);
 		if(validateUserid($_user) == 1)
 			addUserGroupMember($esc_user, $rc['id']);
 		else
@@ -3006,7 +3006,7 @@
 	       . "FROM usergroup "
 	       . "WHERE id = {$rc['id']}";
 	$qh = doQuery($query, 101);
-	if(! $row = mysql_fetch_assoc($qh)) {
+	if(! $row = mysqli_fetch_assoc($qh)) {
 		return array('status' => 'error',
 		             'errorcode' => 18,
 		             'errormsg' => 'user group with submitted name and affiliation does not exist');
@@ -3024,7 +3024,7 @@
 			continue;
 		if(get_magic_quotes_gpc())
 			$_user = stripslashes($_user);
-		$esc_user = mysql_real_escape_string($_user);
+		$esc_user = vcl_mysql_escape_string($_user);
 		# check that affiliation of user can be determined because getUserlistID
 		#   will abort if it cannot find it
 		$affilok = 0;
@@ -3135,7 +3135,7 @@
 			             'errorcode' => 87,
 			             'errormsg' => 'Name must be between 3 and 30 characters and can only contain letters, numbers, spaces, and these characters: - . _');
 		}
-		$name = mysql_real_escape_string($name);
+		$name = vcl_mysql_escape_string($name);
 		$data = array('type' => 'resource',
 		              'ownergroup' => $rc['managingGroupID'],
 		              'resourcetypeid' => $typeid,
@@ -3476,7 +3476,7 @@
 	       . "WHERE bt.blockRequestid = br.id AND "
 	       .       "bt.id = $blockTimesid";
 	$qh = doQuery($query, 101);
-	if(! $rqdata = mysql_fetch_assoc($qh)) {
+	if(! $rqdata = mysqli_fetch_assoc($qh)) {
 		return array('status' => 'error',
 		             'errorcode' => 8,
 		             'errormsg' => 'unknown blockTimesid');
@@ -3526,8 +3526,8 @@
 		$blockCompVals = array();
 		$checkstartbase = $unixstart - $imgLoadTime - 300;
 		$reloadstartbase = unixToDatetime($checkstartbase);
-		$rows = mysql_num_rows($qh);
-		while($row = mysql_fetch_assoc($qh)) {
+		$rows = mysqli_num_rows($qh);
+		while($row = mysqli_fetch_assoc($qh)) {
 			if(array_key_exists($row['reqid'], $donereqids))
 				continue;
 			$donereqids[$row['reqid']] = 1;
@@ -3594,7 +3594,7 @@
 	       . "FROM blockComputers "
 	       . "WHERE blockTimeid = $blockTimesid";
 	$qh = doQuery($query, 101);
-	if(! $row = mysql_fetch_assoc($qh)) {
+	if(! $row = mysqli_fetch_assoc($qh)) {
 		return array('status' => 'error',
 		             'errorcode' => 15,
 		             'errormsg' => 'failure to communicate with database');
@@ -3772,7 +3772,7 @@
 	       .       "r.subid = i.id AND "
 	       .       "r.resourcetypeid = 13";
 	$qh = doQuery($query);
-	if(mysql_num_rows($qh) != 1) {
+	if(mysqli_num_rows($qh) != 1) {
 		return array('status' => 'error',
 		             'errorcode' => 91,
 		             'errormsg' => 'Invalid resourceid submitted');
@@ -3823,7 +3823,7 @@
 	# check for existance of $reservationid
 	$query = "SELECT id FROM reservation WHERE id = $reservationid";
 	$qh = doQuery($query);
-	if(! ($row = mysql_fetch_assoc($qh))) {
+	if(! ($row = mysqli_fetch_assoc($qh))) {
 		return array('status' => 'error',
 		             'errorcode' => 101,
 		             'errormsg' => 'Specified reservation does not exist');
@@ -3839,7 +3839,7 @@
 	       . "WHERE rs.id = $reservationid AND "
 	       .       "ad.secretid IS NOT NULL";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$secretids[] = $row['secretid'];
 		$mnid = $row['managementnodeid'];
 	}
@@ -3853,7 +3853,7 @@
 	       . "WHERE rs.id = $reservationid AND "
 	       .       "vp.secretid IS NOT NULL";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		$secretids[] = $row['secretid'];
 		$mnid = $row['managementnodeid'];
 	}
@@ -3884,7 +3884,7 @@
 	       .       "ck.hosttype = 'managementnode' AND "
 	       .       "cs.id IS NULL";
 	$qh = doQuery($query);
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		if($row['mycryptsecret'] == NULL) {
 			$fails[] = $row['secretid'];
 			continue;
@@ -3952,7 +3952,7 @@
 	       .       "o.userid = {$user['id']}";
 	$qh = doQuery($query);
 	//if nothing returned, oneclick does not exist
-	if(! $row = mysql_fetch_assoc($qh)) {
+	if(! $row = mysqli_fetch_assoc($qh)) {
 		return array('status' => 'error',
 		             'errorcode' => 95,
 		             'errormsg' => "The OneClick with ID $oneclickid does not exist.");
@@ -4027,7 +4027,7 @@
 	$result['status'] = 'success';
 	$result['oneclicks'] = array();
 	#$allstates = getStates();
-	while($row = mysql_fetch_assoc($qh)) {
+	while($row = mysqli_fetch_assoc($qh)) {
 		/*if($row['currstateid'] == 14)
 			$state = $allstates[$row['laststateid']];
 		elseif(! is_null($row['currstateid']))
@@ -4208,7 +4208,7 @@
 	       .       "userid = {$user['id']}";
 	$qh = doQuery($query, 101);
 	//if nothing returned, oneclick does not exist or belongs to another user
-	if(! $row = mysql_fetch_assoc($qh)) {
+	if(! $row = mysqli_fetch_assoc($qh)) {
 		return array('status' => 'error',
 		             'errorcode' => 95,
 		             'errormsg' => "The OneClick with ID $oneclickid does not exist.");
@@ -4262,7 +4262,7 @@
 	       .       "userid = {$user['id']}";
 	$qh = doQuery($query, 101);
 	//if nothing returned, oneclick does not exist or belongs to another user
-	if(! $row = mysql_fetch_assoc($qh)) {
+	if(! $row = mysqli_fetch_assoc($qh)) {
 		return array('status' => 'error',
 		             'errorcode' => 95,
 		             'errormsg' => "The OneClick with ID $oneclickid does not exist.");
diff --git a/web/index.php b/web/index.php
index bbdca0a..0d059c9 100644
--- a/web/index.php
+++ b/web/index.php
@@ -20,14 +20,17 @@
 $VCLversion = '2.5';
 
 require_once(".ht-inc/conf.php");
-if(! isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") {
-	header("Location: " . BASEURL . "/");
-	exit;
+
+if (SSLOFFLOAD == 0) {
+    if(! isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") {
+        header("Location: " . BASEURL . "/");
+        exit;
+    }
 }
 
 $user = '';
-$mysql_link_vcl = '';
-$mysql_link_acct = '';
+$mysqli_link_vcl = '';
+$mysqli_link_acct = '';
 $mode = '';
 $oldmode = '';
 $submitErr = '';
diff --git a/web/js/requests.js b/web/js/requests.js
index 8cfe95f..4a28222 100644
--- a/web/js/requests.js
+++ b/web/js/requests.js
@@ -435,8 +435,7 @@
 		else {
 			var tmp = dojo.byId('deploystartday').value;
 			tmp = new Date(tmp * 1000);
-			var offset = tmp.getTimezoneOffset() * 60000;
-			var date = new Date(tmp.getTime() + offset);
+			var date = new Date(tmp.getTime());
 			var hour = parseInt(dojo.byId('deployhour').value);
 			var m = dojo.byId('deploymeridian').value;
 			if(m == 'pm' && hour < 12)
diff --git a/web/js/resources/addomain.js b/web/js/resources/addomain.js
index 4579a24..e782586 100644
--- a/web/js/resources/addomain.js
+++ b/web/js/resources/addomain.js
@@ -41,11 +41,12 @@
 		dojo.byId('editresid').value = data.items.rscid;
 		dijit.byId('name').set('value', data.items.data.name);
 		dijit.byId('owner').set('value', data.items.data.owner);
-
 		dijit.byId('domaindnsname').set('value', data.items.data.domaindnsname);
 		dijit.byId('username').set('value', data.items.data.username);
 		dijit.byId('dnsservers').set('value', data.items.data.dnsservers);
-
+		if(data.items.data.usedbhostnames == 1) {
+			dijit.byId('usedbhostnames').set('checked', data.items.data.usedbhostnames)
+		}
 		dijit.byId('password').set('value', '********');
 		dijit.byId('password2').set('value', 'xxxxxxxx');
 
@@ -58,7 +59,7 @@
 }
 
 function resetEditResource() {
-	var fields = ['name', 'owner', 'domaindnsname', 'username', 'password', 'password2', 'dnsservers'];
+	var fields = ['name', 'owner', 'domaindnsname', 'username', 'password', 'password2', 'usedbhostnames', 'dnsservers'];
 	for(var i = 0; i < fields.length; i++) {
 		dijit.byId(fields[i]).reset();
 	}
@@ -89,7 +90,13 @@
 		dojo.byId('addeditdlgerrmsg').innerHTML = _('Passwords do not match');
 		return;
 	}
-
+	// update usedbhostnames
+	if(dijit.byId('usedbhostnames').get('checked')) {
+		data['usedbhostnames'] = 1;
+	}
+	else {
+		data['usedbhostnames'] = 0;
+	}
 	dijit.byId('addeditbtn').set('disabled', true);
 	RPCwrapper(data, saveResourceCB, 1);
 }
diff --git a/web/js/resources/image.js b/web/js/resources/image.js
index dad3f47..b710c55 100644
--- a/web/js/resources/image.js
+++ b/web/js/resources/image.js
@@ -36,10 +36,29 @@
 		if(value == "1")
 			return '<span class="ready">' + _('true') + '</span>';
 	}
-	if((obj.field == 'maxinitialtime' && value == 0) ||
-	   (obj.field == 'addomain' && value == null) ||
+	if((obj.field == 'addomain' && value == null) ||
 	   (obj.field == 'baseOU' && value == null))
 		return '(' + _('unset') + ')';
+	if(obj.field == 'maxinitialtime') {
+		if(value == 0) {
+			return _('Default for User');
+		}
+		else if(value < 60) {
+			return value + ' ' + _('minutes');
+		}
+		else if(value == 60) {
+			return _('1 hour');
+		}
+		else if(value < 2880) {
+			return parseInt(value / 60) + ' ' + _('hours');
+		}
+		else if(value <= 64800) {
+			return parseInt(value / 1440) + ' ' + _('days');
+		}
+		else {
+			return parseInt(value / 10080) + ' ' + _('weeks');
+		}
+	}
 	return value;
 }
 
@@ -67,6 +86,7 @@
 		dijit.byId('checkuser').set('value', data.items.data.checkuser);
 		dijit.byId('rootaccess').set('value', data.items.data.rootaccess);
 		dijit.byId('sethostname').set('value', data.items.data.sethostname);
+		dijit.byId('maxinitialtime').set('value', data.items.data.maxinitialtime);
 		if(data.items.data.ostype == 'windows' || data.items.data.ostype == 'linux')
 			dojo.removeClass('sethostnamediv', 'hidden');
 		else
@@ -257,6 +277,11 @@
 			return;
 		}
 	}
+	data['maxinitialtime'] = parseInt(dijit.byId('maxinitialtime').get('value'));
+	if(data['maxinitialtime'] < 0 || data['maxinitialtime'] > 201600) {
+		errobj.innerHTML = _('Invalid Max Reservation Duration selected');
+		return;
+	}
 	if(dijit.byId('sysprep')) {
 		data['sysprep'] = parseInt(dijit.byId('sysprep').get('value'));
 		if(data['sysprep'] != 0 && data['sysprep'] != 1) {
@@ -341,6 +366,7 @@
 					resourcegrid.store.setValue(item, 'checkuser', data.items.data.checkuser);
 					resourcegrid.store.setValue(item, 'rootaccess', parseInt(data.items.data.rootaccess));
 					resourcegrid.store.setValue(item, 'sethostname', parseInt(data.items.data.sethostname));
+					resourcegrid.store.setValue(item, 'maxinitialtime', parseInt(data.items.data.maxinitialtime));
 					resourcegrid.store.setValue(item, 'reloadtime', data.items.data.reloadtime);
 					resourcegrid.store.setValue(item, 'adauthenabled', data.items.data.adauthenabled);
 					resourcegrid.store.setValue(item, 'addomainid', data.items.data.addomainid);
diff --git a/web/js/siteconfig.js b/web/js/siteconfig.js
index 072c01f..0be32b5 100644
--- a/web/js/siteconfig.js
+++ b/web/js/siteconfig.js
@@ -685,7 +685,22 @@
 	}
 	dojo.byId('messagesaffil').innerHTML = affiltype;
 	dijit.byId('messagessubject').set('value', item['subject']);
-	dijit.byId('messagesbody').set('value', item['message']);
+	if(('DBmanagedHTML' in item) && item['DBmanagedHTML'] == 1) {
+		dijit.byId('messagesbody').set('value', 'This message body contains HTML that is set directly in the database');
+		dijit.byId('messagesbody').set('disabled', true);
+		dijit.byId('messagessubject').set('disabled', true);
+		dijit.byId('messagesshortmsg').set('disabled', true);
+		dijit.byId('messagessavebtn').set('disabled', true);
+		dijit.byId('messagesdelbtn').set('disabled', true);
+	}
+	else {
+		dijit.byId('messagesbody').set('value', item['message']);
+		dijit.byId('messagesbody').set('disabled', false);
+		dijit.byId('messagessubject').set('disabled', false);
+		dijit.byId('messagesshortmsg').set('disabled', false);
+		dijit.byId('messagessavebtn').set('disabled', false);
+		dijit.byId('messagesdelbtn').set('disabled', false);
+	}
 	if('short_message' in item)
 		dijit.byId('messagesshortmsg').set('value', item['short_message']);
 	else
diff --git a/web/shibauth/index.php b/web/shibauth/index.php
index 0ab553d..c6ad42a 100644
--- a/web/shibauth/index.php
+++ b/web/shibauth/index.php
@@ -1,263 +1,4 @@
 <?php
-/*
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-*/
-
-chdir("..");
-require_once('.ht-inc/conf.php');
-
-require_once('.ht-inc/utils.php');
-require_once('.ht-inc/errors.php');
-function getFooter() {}
-$noHTMLwrappers = array();
-
-dbConnect();
-
-header("Cache-Control: no-cache, must-revalidate");
-header("Expires: Sat, 1 Jan 2000 00:00:00 GMT");
-
-/*
-	# check for eppn; if there, see if it is a user we already have
-	if(array_key_exists('eppn', $_SERVER)) {
-		#$tmp = explode('@', $_SERVER['eppn']);
-		$tmp = explode(';', $_SERVER['eppn']);
-		$tmp = explode('@', $tmp[0]);
-		$query = "SELECT u.firstname, "
-				 .        "u.lastname "
-				 . "FROM user u, "
-				 .      "affiliation a "
-				 . "WHERE u.unityid = '{$tmp[0]}' AND "
-				 .       "a.shibname = '{$tmp[1]}' AND "
-				 .       "u.affiliationid = a.id";
-		$qh = doQuery($query, 101);
-		if($row = mysql_fetch_assoc($qh)) {
-			$_SERVER['sn'] = $row['lastname'];
-			$_SERVER['givenName'] = $row['firstname'];
-		}
-		else {
-*/
-
-if(! array_key_exists('eppn', $_SERVER)) {
-	# check to see if any shib stuff in $_SERVER, if not redirect
-	$keys = array_keys($_SERVER);
-	$allkeys = '{' . implode('{', $keys);
-	if(! preg_match('/\{Shib-/', $allkeys)) {
-		# no shib data, clear _shibsession cookie
-		#print "$allkeys<br>\n";
-		foreach(array_keys($_COOKIE) as $key) {
-			if(preg_match('/^_shibsession[_0-9a-fA-F]+$/', $key))
-				setcookie($key, "", time() - 10, "/", $_SERVER['SERVER_NAME']);
-		}
-		# redirect to main select auth page
-		header("Location: " . BASEURL . SCRIPT . "?mode=selectauth");
-		dbDisconnect();
-		exit;
-	}
-	print "<h2>Error with Shibboleth authentication</h2>\n";
-	print "You have attempted to log in using Shibboleth from an<br>\n";
-	print "institution that does not allow VCL to see your<br><br>\n";
-	print "eduPersonPrincipalName.<br><br>\n";
-	print "You need to contact the administrator of your institution's<br>\n";
-	print "IdP to have eduPersonPrincipalName made available to VCL in<br>\n";
-	print "order to log in using Shibboleth.\n";
-
-	$msg = "Someone tried to log in to VCL using Shibboleth from an IdP "
-	     . "that does not release eppn to us.\n\n"
-	     . "The following data was in \$_SERVER:\n\n";
-	foreach($_SERVER as $key => $val)
-		$msg .= "$key => $val\n";
-	$mailParams = "-f" . ENVELOPESENDER;
-	mail(ERROREMAIL, "Error with VCL pages (eppn not provided)", $msg, '', $mailParams);
-	dbDisconnect();
-	exit;
-}
-
-// open keys
-$fp = fopen(".ht-inc/keys.pem", "r");
-$key = fread($fp, 8192);
-fclose($fp);
-$keys["private"] = openssl_pkey_get_private($key, $pemkey);
-if(! $keys['private'])
-	abort(6);
-$fp = fopen(".ht-inc/pubkey.pem", "r");
-$key = fread($fp, 8192);
-fclose($fp);
-$keys["public"] = openssl_pkey_get_public($key);
-if(! $keys['public'])
-	abort(7);
-
-# get VCL affiliation from shib affiliation
-$tmp = explode(';', $_SERVER['eppn']);
-$tmp = explode('@', $tmp[0]);
-$username = strtolower($tmp[0]);
-$tmp1 = mysql_escape_string(strtolower($tmp[1]));
-$query = "SELECT name, shibonly FROM affiliation WHERE shibname = '$tmp1'";
-$qh = doQuery($query, 101);
-# if shib affiliation not already in VCL, create affiliation
-if(! ($row = mysql_fetch_assoc($qh))) {
-	$affil = strtolower($tmp[1]);
-	$tmp = explode('.', $affil);
-	array_pop($tmp);
-	$affilname = strtoupper(implode('', $tmp));
-	$affilname = preg_replace('/[^A-Z0-9]/', '', $affilname);
-	$query = "SELECT name, "
-	       .        "shibname "
-	       . "FROM affiliation "
-	       . "WHERE name LIKE '$affilname%' "
-	       . "ORDER BY name DESC "
-	       . "LIMIT 1";
-	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_assoc($qh)) {
-		if(preg_match("/$affilname([0-9]+)/", $row['name'], $matches)) {
-			$cnt = $matches[1];
-			$cnt++;
-			$newaffilname = $affilname . $cnt;
-		}
-		elseif($affilname != $row['name'] && $affil != $row['shibname']) {
-			$newaffilname = $affilname;
-		}
-		else {
-			$msg = "Someone tried to log in to VCL using Shibboleth from an IdP "
-			     . "affiliation that could not be automatically added.\n\n"
-			     . "eppn: {$_SERVER['eppn']}\n"
-			     . "givenName: {$_SERVER['givenName']}\n"
-			     . "sn: {$_SERVER['sn']}\n";
-			if(array_key_exists('mail', $_SERVER))
-				$msg .= "mail: {$_SERVER['mail']}\n\n";
-			$msg .="tried to add VCL affiliation name \"$affilname\" with "
-			     . "shibname \"$affil\"";
-			$mailParams = "-f" . ENVELOPESENDER;
-			mail(ERROREMAIL, "Error with VCL pages (problem adding shib affil)", $msg, '', $mailParams);
-			print "<html><head></head><body>\n";
-			print "<h2>Error encountered</h2>\n";
-			print "You have attempted to log in to VCL using a Shibboleth<br>\n";
-			print "Identity Provider that VCL has not been configured to<br>\n";
-			print "work with.  VCL administrators have been notified of the<br>\n";
-			print "problem.<br>\n";
-			print "</body></html>\n";
-			dbDisconnect();
-			exit;
-		}
-	}
-	else
-		$newaffilname = $affilname;
-	$query = "INSERT INTO affiliation "
-	       .        "(name, "
-	       .        "shibname, "
-	       .        "shibonly) "
-	       . "VALUES "
-	       .        "('$newaffilname', "
-	       .        "'" . mysql_escape_string($affil) . "', "
-	       .        "1)";
-	doQuery($query, 101, 'vcl', 1);
-	unset($row);
-	$row = array('name' => $newaffilname, 'shibonly' => 1);
-}
-$affil = $row['name'];
-# create VCL userid
-$userid = "$username@$affil";
-
-if($row['shibonly']) {
-	$userdata = updateShibUser($userid);
-	updateShibGroups($userdata['id'], $_SERVER['affiliation']);
-	$usernid = $userdata['id'];
-}
-else {
-	$usernid = getUserlistID($userid, 1);
-	if(is_null($usernid)) {
-		$tmp = updateShibUser($userid);
-		$usernid = $tmp['id'];
-	}
-}
-
-$affilid = getAffiliationID($affil);
-addLoginLog($userid, 'shibboleth', $affilid, 1);
-
-# uncomment the following and change EXAMPLE1 to match your needs to add all
-# users from a specific affiliation to a particular user group
-/*if($affil == 'EXAMPLE1') {
-	$gid = getUserGroupID('All EXAMPLE1 Users', $affilid);
-	$query = "INSERT IGNORE INTO usergroupmembers "
-	       . "(userid, usergroupid) "
-	       . "VALUES ($usernid, $gid)";
-	doQuery($query, 307);
-}*/
-
-if(array_key_exists('Shib-logouturl', $_SERVER))
-	$logouturl = $_SERVER['Shib-logouturl'];
-else
-	$logouturl = '';
-
-# save data to shibauth table
-$shibdata = array('Shib-Application-ID' => $_SERVER['Shib-Application-ID'],
-                  'Shib-Identity-Provider' => $_SERVER['Shib-Identity-Provider'],
-                  #'Shib-AuthnContext-Dec' => $_SERVER['Shib-AuthnContext-Decl'],
-                  'Shib-logouturl' => $logouturl,
-                  'eppn' => $_SERVER['eppn'],
-                  'unscoped-affiliation' => $_SERVER['unscoped-affiliation'],
-                  'affiliation' => $_SERVER['affiliation'],
-);
-$serdata = mysql_escape_string(serialize($shibdata));
-$query = "SELECT id "
-       . "FROM shibauth "
-       . "WHERE sessid = '{$_SERVER['Shib-Session-ID']}'";
-$qh = doQuery($query, 101);
-if($row = mysql_fetch_assoc($qh)) {
-	$shibauthid = $row['id'];
-}
-else {
-	$ts = strtotime($_SERVER['Shib-Authentication-Instant']);
-	$ts = unixToDatetime($ts);
-	$query = "INSERT INTO shibauth "
-	       .        "(userid, " 
-	       .        "ts, "
-	       .        "sessid, "
-	       .        "data) "
-	       . "VALUES "
-	       .        "($usernid, "
-	       .        "'$ts', "
-	       .        "'{$_SERVER['Shib-Session-ID']}', "
-	       .        "'$serdata')";
-	doQuery($query, 101);
-	$qh = doQuery("SELECT LAST_INSERT_ID() FROM shibauth", 101);
-	if(! $row = mysql_fetch_row($qh)) {
-		# todo
-	}
-	$shibauthid = $row[0];
-}
-
-# get cookie data
-$cookie = getAuthCookieData($userid, 600, $shibauthid);
-# set cookie
-if(version_compare(PHP_VERSION, "5.2", ">=") == true)
-	#setcookie("VCLAUTH", "{$cookie['data']}", $cookie['ts'], "/", COOKIEDOMAIN, 1, 1);
-	setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN, 0, 1);
-else
-	#setcookie("VCLAUTH", "{$cookie['data']}", $cookie['ts'], "/", COOKIEDOMAIN, 1);
-	setcookie("VCLAUTH", "{$cookie['data']}", 0, "/", COOKIEDOMAIN);
-# set skin cookie based on affiliation
-switch($affil) {
-	case 'Example1':
-	case 'EXAMPLE2':
-		$skin = strtoupper($affil);
-		setcookie("VCLSKIN", $skin, (time() + 2678400), "/", COOKIEDOMAIN);
-		break;
-	default:
-		setcookie("VCLSKIN", "default", (time() + 2678400), "/", COOKIEDOMAIN);
-}
-header("Location: " . BASEURL . "/");
-dbDisconnect();
+@require_once('../.ht-inc/conf.php');
+header("Location: " . BASEURL . SCRIPT);
 ?>
diff --git a/web/testsetup.php b/web/testsetup.php
index ba3e5ae..609f0ab 100644
--- a/web/testsetup.php
+++ b/web/testsetup.php
@@ -79,14 +79,18 @@
 
 $includesecrets = 1;
 $includeconf = 1;
+$host = $_SERVER['HTTP_HOST'];
+if (strpos($host, ':')) {
+	$host = substr($host, 0, strpos($host, ':'));
+}
 
-if(! ip2long(getHostbyname($_SERVER['HTTP_HOST']))) {
+if(! ip2long(getHostbyname($host))) {
 	print $header;
 	# php version
 	print "PHP version: " . phpversion() . "<br><br>\n";
-	title("Trying to resolve my hostname ({$_SERVER['HTTP_HOST']})");
+	title("Trying to resolve my hostname ($host)");
 	print "<ul>\n";
-	fail("unable to resolve my hostname; ensure {$_SERVER['HTTP_HOST']} is in DNS or create an entry for it in /etc/hosts");
+	fail("unable to resolve my hostname; ensure $host is in DNS or create an entry for it in /etc/hosts");
 	print "</ul>\n";
 	$includesecrets = 0;
 	$includeconf = 0;
@@ -160,8 +164,7 @@
 
 # conf.php tests
 $createcryptkey = 0;
-if($includeconf && include('.ht-inc/conf.php')) {
-	$host = $_SERVER['HTTP_HOST'];
+if($includeconf && include('.ht-inc/conf.php')) {	
 	if(! defined('COOKIEDOMAIN')) {
 		print $header;
 		# php version
@@ -219,8 +222,10 @@
 	else {
 		if(substr_compare(BASEURL, 'https:', 0, 6, true) == 0)
 			pass("BASEURL correctly set to use https");
+		elseif(SSLOFFLOAD == 1 && substr_compare(BASEURL, 'http:', 0, 5, true) == 0)
+		        pass("BASEURL set to use http as SSL is offloaded to load balancer");
 		else
-			fail("BASEURL is not set to use https. https is required.");
+			fail("BASEURL is not set to use https and SSL offloading is not enabled. https is required.");
 	}
 	print "</ul>\n";
 
diff --git a/web/themes/copydojocss.sh b/web/themes/copydojocss.sh
index f64d78b..635c3a0 100755
--- a/web/themes/copydojocss.sh
+++ b/web/themes/copydojocss.sh
@@ -51,11 +51,18 @@
 fi
 
 cd $path/$skin/css/dojo
-mv tundra.css $skin.css
+if [[ -f tundra.css ]]; then
+	mv tundra.css $skin.css
+fi
+
 if [[ -r tundra.css.commented.css ]]; then
 	mv tundra.css.commented.css $skin.css.commented.css
 fi
-mv tundra_rtl.css ${skin}_rtl.css
+
+if [[ -f tundra_rtl.css ]]; then
+	mv tundra_rtl.css ${skin}_rtl.css
+fi
+
 if [[ -r tundra_rtl.css.commented.css ]]; then
 	mv tundra_rtl.css.commented.css ${skin}_rtl.css.commented.css
 fi