Merge branch 'release-2.5.1'
diff --git a/CHANGELOG b/CHANGELOG
index 46cdda5..c63b40e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,53 @@
+ASF VCL 2.5.1
+
+Dependency changes:
+
+VCL Management Node:
+* updated supported versions of CentOS and Red Hat
+
+Release Notes - VCL - Version 2.5.1
+            
+** Bug
+    * [VCL-1079] - Virtual Hosts page references Computer Utilities
+    * [VCL-1080] - Wrong port can be delivered in RDP file
+    * [VCL-1081] - UID conflict for admin user
+    * [VCL-1082] - monitor_vcld.pl throws incorrect lastcheckin time exception after Daylight Savings Time Roles Back
+    * [VCL-1083] - Data in shares mounted under Linux home directories may be deleted
+    * [VCL-1093] - vSphere_SDK.pm:vm_unregister - failed to unregister VM:
+    * [VCL-1100] - block allocation usage graph does not work correctly for allocations with a single time slot
+    * [VCL-1103] - change vcldsemaphore.pid from smallint to mediumint
+    * [VCL-1105] - Shibboleth authentication broken due to bug in getCryptKeyID
+    * [VCL-1111] - statgraphcache table not correctly being used
+    * [VCL-1113] - image capture for Windows system configured as domain controller fails
+    * [VCL-1116] - use database hostnames for ad joined computers
+    * [VCL-1117] - vcld fails to set fixed IP address for Linux server reservations if management node not set to static
+    * [VCL-1119] - wrong day submitted for future reservations made in the evening
+    * [VCL-1120] - image conversion from vmdk to qcow2 always done twice
+        
+** New Feature
+    * [VCL-1112] - SSL Offload
+        
+** Improvement
+    * [VCL-1041] - Customer facing email notifications are ugly
+    * [VCL-1084] - set cache mode for libvirt VMs
+    * [VCL-1085] - Configuring VCL Website to use custom port
+    * [VCL-1089] - Change ping module to use Net::Ping::External
+    * [VCL-1092] - Change installation script to install these RPM Perl Modules
+    * [VCL-1094] - add .\ to windows user login to prevent automatic use of Microsoft accounts
+    * [VCL-1095] - Move unjoining of Windows VMs from Active Directory to earlier in the deprovision process
+    * [VCL-1096] - Add ability to automatically mount NFS shares under Windows
+    * [VCL-1101] - Change chmod mode from string to octal number value
+    * [VCL-1104] - set cpu topology for libvirt VMs
+    * [VCL-1106] - make PHP code compatible with PHP 7
+    * [VCL-1109] - date duplicated on statistic graph labels for day after daylight saving time rolls back
+    * [VCL-1110] - expose maxinitial time for images in web UI
+    * [VCL-1114] - miscellaneous small web updates
+            
+** Task
+    * [VCL-1097] - add hidden files to empty directories to force them to be included in Git repo
+
+================================================================================
+
 ASF VCL 2.5
 
 Dependency changes:
diff --git a/INSTALLATION b/INSTALLATION
index c5583e8..f6f4a62 100644
--- a/INSTALLATION
+++ b/INSTALLATION
@@ -1,10 +1,10 @@
-Installing VCL 2.5
+Installing VCL 2.5.1
 
-VCL 2.5 is the second release to include an installation script. All you need
-to install VCL is the script. It will download and validate the VCL software and
-then install it. The script can be used to install all three parts of VCL
-(database, web portal, and management node) on a single system or to install
-each part individually on separate systems.
+VCL 2.5.1 can be installed using an installation script. All you need to
+install VCL is the script. It will download and validate the VCL software
+and then install it. The script can be used to install all three parts of
+VCL (database, web portal, and management node) on a single system or to
+install each part individually on separate systems.
 
 Running the installation script with no arguments will step you through
 installing all three parts of VCL.
@@ -52,7 +52,7 @@
 
 
 
-MINUAL INSTALLATION INSTRUCTIONS
+MANUAL INSTALLATION INSTRUCTIONS
 
 The recommended method of installing VCL is to use the installation script. See
 above for additional information. If manual installation is required,
@@ -145,7 +145,7 @@
       Import the vcl.sql file into the database. The vcl.sql file is included in
       the mysql directory within the Apache VCL source code
 
-        mysql vcl < apache-VCL-2.5/mysql/vcl.sql
+        mysql vcl < apache-VCL-2.5.1/mysql/vcl.sql
 
 2. Install and Configure the Web Components
 
@@ -155,8 +155,8 @@
 
    Web Server:
 
-    Apache HTTP Server v1.3 or v2.x with SSL enabled
-    PHP 5.0 or later
+    Apache HTTP Server v2.x with SSL enabled
+    PHP 5.x or 7.x
 
    Required Linux Packages:
 
@@ -167,12 +167,13 @@
    Required PHP Modules:
 
     php
+    php-gettext
     php-json (required if your PHP version is 5.2 or later)
+    php-ldap (if you will be using LDAP authentication)
     php-mysql
     php-openssl
     php-xml
     php-xmlrpc
-    php-ldap (if you will be using LDAP authentication)
 
    A. Install the Required Linux Packages & PHP Modules
 
@@ -225,14 +226,14 @@
       Copy the web directory to a location under the web root of your web
       server and navigate to the destination .ht-inc subdirectory:
 
-        cp -ar apache-VCL-2.5/web/ /var/www/html/vcl-2.5
-        ln -s /var/www/html/vcl-2.5 /var/www/html/vcl
+        cp -ar apache-VCL-2.5.1/web/ /var/www/html/vcl-2.5.1
+        ln -s /var/www/html/vcl-2.5.1 /var/www/html/vcl
         cd /var/www/html/vcl/.ht-inc
 
       If SELinux is enabled, run the following command to set the context of the
       web code to httpd_sys_content_t
 
-        chcon -R -t httpd_sys_content_t /var/www/html/vcl-2.5
+        chcon -R -t httpd_sys_content_t /var/www/html/vcl-2.5.1
 
       Copy secrets-default.php to secrets.php:
 
@@ -353,8 +354,8 @@
    Prerequisites The following management node installation instructions assume
    the instructions in these previous sections have been completed:
 
-    VCL 2.5 Database Installation
-    VCL 2.5 Web Code Installation
+    VCL 2.5.1 Database Installation
+    VCL 2.5.1 Web Code Installation
 
    Supported Operating Systems:
 
@@ -392,11 +393,12 @@
 
    The VCL management node daemon (vcld) is written in Perl and has been tested
    on Perl 5.10 and 5.16. The following Perl modules available from CPAN are
-   also required (see step 2 below for installation instructions):
+   also required (see step B below for installation instructions):
 
     Crypt::CBC - implementation of the cryptographic cipher block chaining mode
     Crypt::OpenSSL::RSA - RSA encoding and decoding, using the openSSL libraries
     Crypt::Rijndael - Crypt::CBC compliant Rijndael encryption module
+    DBD::MySQL - MySQL driver for the Perl5 Database Interface (DBI)
     DBI - Generic Database Interface
     Digest::SHA1 - NIST SHA message digest algorithm
     Exception::Class::Base - base class for exception objects
@@ -408,6 +410,7 @@
     Mail::Mailer - Simple mail agent interface
     Net::Jabber - Jabber perl library
     Net::Netmask - parse, manipulate and lookup IP network blocks
+    Net::Ping::External - Cross-platform Perl interface to "ping" utilities
     Net::SSH::Expect - a wrapper to the ssh executable that is available in
                        system's PATH
     Object::InsideOut - Comprehensive inside-out object support
@@ -421,8 +424,8 @@
       Copy the managementnode directory to the location where you want it to
       reside (typically /usr/local):
 
-        cp -ar apache-VCL-2.5/managementnode /usr/local/vcl-2.5
-        ln -s /usr/local/vcl-2.5 /usr/local/vcl
+        cp -ar apache-VCL-2.5.1/managementnode /usr/local/vcl-2.5.1
+        ln -s /usr/local/vcl-2.5.1 /usr/local/vcl
 
    B. Install the Required Linux Packages & Perl Modules
 
diff --git a/README b/README
index 22dbd62..9a0062e 100644
--- a/README
+++ b/README
@@ -1,10 +1,10 @@
-Apache VCL 2.5
+Apache VCL 2.5.1
 
 ================================================================================
 INSTALLATION
 
 Please see the INSTALLATION file or the installation guide on the Apache VCL
-website. (http://vcl.apache.org/docs/VCL25InstallGuide.html)
+website. (http://vcl.apache.org/docs/VCL251InstallGuide.html)
 
 ================================================================================
 SYSTEM REQUIREMENTS
@@ -14,7 +14,7 @@
 ------------
 
 VCL web server Linux packages:
-* Apache HTTP Server v1.3 or v2.x with SSL enabled
+* Apache HTTP Server v2.x with SSL enabled
 * PHP 5.0 or later
 
 VCL web server PHP modules:
@@ -40,8 +40,7 @@
 
 VCL has been tested on the following operating systems:
 * CentOS release 6.9 (Final)
-* CentOS Linux release 7.3.1611 (Core)
-* Red Hat Enterprise Linux Server release 6.8 (Santiago)
+* CentOS Linux release 7.6.1810 (Core)
 * Red Hat Enterprise Linux Server release 7.3 (Maipo)
 
 Required Linux Packages:
@@ -72,6 +71,7 @@
 * Crypt::CBC
 * Crypt::OpenSSL::RSA
 * Crypt::Rijndael
+* DBD::MySQL
 * DBI
 * Digest::SHA1
 * Exception::Class::Base
@@ -83,6 +83,7 @@
 * Mail::Mailer
 * Net::Jabber
 * Net::Netmask
+* Net::Ping::External
 * Net::SSH::Expect
 * Object::InsideOut
 * RPC::XML::Client
@@ -119,21 +120,11 @@
   http://www.vmware.com/support/developer/viperltoolkit/
   This is not required if provisioning virtual machines on standalone VMware ESX
   or ESXi hosts.
-* Windows XP & Windows Server 2003 bare-metal provisioning
-  The Sysprep utility is required to provision Windows XP and Windows Server
-  2003 bare-metal images. The utility can be downloaded from Microsoft. It is
-  included in newer versions of Windows. Sysprep is not required to provision
-  virtual machine images.
-* Jabber notifications
-  VCL has the ability to send instant message notifications using Jabber. This
-  feature is optional and can be enabled or disabled by configuring the
-  "jabber=[yes|no]" property in the vcld.conf file. If the Jabber notification
-  feature is enabled, the Net::Jabber Perl module is required.
 
 ================================================================================
 BUNDLED 3RD PARTY SOFTWARE
 
-A copy of Dojo Toolkit version 1.6.2 is included in under web/dojo.
+A copy of Dojo Toolkit version 1.6.5 is included in under web/dojo.
 
 Portions of the phpseclib (http://phpseclib.sourceforge.net) project are
 included under web/.ht-inc/phpseclib.
@@ -178,4 +169,4 @@
 The backend management node code also uses the SSH protocol and public key
 authentication to connect to and control compute nodes provisioned by a VCL
 management node server as well as other hosts that comprise a VCL system such as
-hypervisors.
\ No newline at end of file
+hypervisors.
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 8b0afa5..ed3c0a8 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -1,4 +1,4 @@
-VCL 2.5
+VCL 2.5.1
 
 I. Intro and Description
 
@@ -21,27 +21,12 @@
 
 II. Notable Changes
 
-The following are some notable changes from previous releases.
+This is primarily a bug fix release. However, the following are some 
+changes worth highlighting.
 
-Added:
-
-* Support for Windows 10 and Windows Server 2016 images
-* Responsive theme (dropdownmenus) to web site
-* Support for automatically joining Windows images to an Active Directory domain
-* Basic automatic mounting of NFS shares for all users
-* Customization of email messages sent to users on a per-affiliation basis
-* Support for the automatic configuration of ufw and firewalld-based firewalls
-  within Linux images
-* Support for NAT hosts which use ufw os firewalld-based firewalls including
-  Ubuntu and RedHat/CentOS 7 and later
-* Support for the execution of custom scripts on a management node at various
-  stages of the reservation
-* Display of reservation times in the user's own timezone
-
-Removed:
-
-* Server Profiles
-* Use of the Windows Administrator user account for imaging reservations
+* PHP code updated to work with PHP 7.x.
+* Rudimentary NFS file share mounting extended to work with Windows
+* Added method for using HTML in user emails through external script
 
 =================================
 
@@ -84,7 +69,9 @@
 
 If you find a bug, please submit a bug report to our JIRA bug tracking system at
 http://issues.apache.org/jira/browse/VCL (you will need to set up an account
-there if you haven't already done so - it's free to anyone).
+there if you haven't already done so - it's free to anyone). If it is a security
+bug, do not open a JIRA issue. Instead report it in an email to
+security@apache.org.
 
 If you would like to requrest a new feature, you can also submit that in the
 same way through JIRA (just select "New Feature" or "Improvement" as the Issue
diff --git a/UPGRADE b/UPGRADE
index 4256ad1..6b0d8d1 100644
--- a/UPGRADE
+++ b/UPGRADE
@@ -1,10 +1,10 @@
-Upgrading to VCL 2.5
+Upgrading to VCL 2.5.1
 
-VCL 2.5 is the second release to include an upgrade script. All you need to
-upgrade VCL is the script. It will download and validate the VCL software and
-then upgrade your system. The script can be used to upgrade all three parts of
-VCL (database, web portal, and management node) or to upgrade each part
-individually.
+VCL 2.5.1 can be upgraded using an upgrade script. All you need to upgrade
+VCL is the script. It will download and validate the VCL software and then
+upgrade your system. The script can be used to upgrade all three parts of
+VCL (database, web portal, and management node) on a single system or to
+upgrade each part individually on separate systems.
 
 Running the upgrade script with no arguments will step you through upgrading
 all three parts of VCL.
@@ -57,101 +57,93 @@
  2. Create a backup of the VCL database. This will provide a restore point if
     necessary.
 
-    mysqldump vcl > ~/vcl-pre2.5-upgrade.sql
+    mysqldump vcl > ~/vcl-pre2.5.1-upgrade.sql
 
  3. Updates the database schema.
 
-    mysql vcl < /root/apache-VCL-2.5/mysql/update-vcl.sql
+    mysql vcl < /root/apache-VCL-2.5.1/mysql/update-vcl.sql
 
  4. Possibly move old web code. If /var/www/html/vcl is a directory, rename it
-    to /var/www/html/vcl-2.4.2. These instructions assume that you installed the
+    to /var/www/html/vcl-2.5. These instructions assume that you installed the
     VCL web code at /var/www/html/vcl. If you installed it elsewhere, replace
     /var/www/html/vcl with your vcl web root.
 
-    mv /var/www/html/vcl /var/www/html/vcl-2.4.2
+    mv /var/www/html/vcl /var/www/html/vcl-2.5
 
  5. Disable access to the old web code
 
-    echo "Require all denied" > /var/www/html/vcl-2.4.2/.htaccess
+    echo "Require all denied" > /var/www/html/vcl-2.5/.htaccess
 
  6. Copy the new code in place
 
-    cp -ar /root/apache-VCL-2.5/web /var/www/html/vcl-2.5
-    ln -sfn /var/www/html/vcl-2.5 /var/www/html/vcl
+    cp -ar /root/apache-VCL-2.5.1/web /var/www/html/vcl-2.5.1
+    ln -sfn /var/www/html/vcl-2.5.1 /var/www/html/vcl
 
- 7. Copy your 2.4.2 config files
+ 7. Copy your 2.5 config files
 
-    cd /var/www/html/vcl-2.4.2/.ht-inc
+    cd /var/www/html/vcl-2.5/.ht-inc
     cp conf.php secrets.php pubkey.pem keys.pem /var/www/html/vcl/.ht-inc
+    cp cryptkey/cryptkeyid cryptkey/private.pem /var/www/html/vcl/.ht-inc/cryptkey/
 
  8. If you are using SELinux, set the correct context:
 
-    chcon -R -t httpd_sys_content_t /var/www/html/vcl-2.5
-    chcon -t httpd_sys_rw_content_t /var/www/html/vcl-2.5/.ht-inc/maintenance
-    chcon -t httpd_sys_rw_content_t /var/www/html/vcl-2.5/.ht-inc/cryptkey
+    chcon -R -t httpd_sys_content_t /var/www/html/vcl-2.5.1
+    chcon -t httpd_sys_rw_content_t /var/www/html/vcl-2.5.1/.ht-inc/maintenance
+    chcon -t httpd_sys_rw_content_t /var/www/html/vcl-2.5.1/.ht-inc/cryptkey
 
- 9. Update conf.php: the following item needs to be removed from the conf.php
+ 9. Update conf.php: the following item needs to be added to the conf.php
     file:
 
     (don't forget to edit conf.php in the *new* location)
     vim /var/www/html/vcl/.ht-inc/conf.php
 
-    define("MAXVMLIMIT", "100");
+    define("SSLOFFLOAD", 0);
 
-10. Update secrets.php: $cryptkey in secrets.php needs to be generated using
-    openssl. Generate the value and set it in secrets.php:
-
-    openssl rand 32 | base64
-    vim /var/www/html/vcl/.ht-inc/secrets.php
- 
-    $cryptkey = 'xxxxxxxxxxxxxxxxxxxxxxxxx'; # set this to output of
-                                             # "openssl rand 32 | base64"
-
-11. Make the maintenance and cryptkey directories writable by the web server
+10. Make the maintenance and cryptkey directories writable by the web server
     user. Normally this is the apache user, if using a different user change
     below command accordingly.
 
     chown apache /var/www/html/vcl/.ht-inc/maintenance
     chown apache /var/www/html/vcl/.ht-inc/cryptkey
 
-12. Start httpd service
+11. Start httpd service
 
     service httpd start
 
-13. Check testsetup.php: Check that everything is correct by viewing the
+12. Check testsetup.php: Check that everything is correct by viewing the
     testsetup.php script in your browser. This script is located in the same
     directory as the index.php script. I.e.
 
     https://your.site.url/vcl/testsetup.php
 
-14. Copy old management node code:
-    If /usr/local/vcl is a directory, copy it to /usr/local/vcl-2.4.2, rename
-    /usr/local/vcl to /usr/local/vcl-2.5, and create a symlink.
-    If /usr/local/vcl is a symlink to vcl-2.4.2, copy /usr/local/vcl-2.4.2 to
-    /usr/local/vcl-2.5 and update the symlink.
+13. Copy old management node code:
+    If /usr/local/vcl is a directory, copy it to /usr/local/vcl-2.5, rename
+    /usr/local/vcl to /usr/local/vcl-2.5.1, and create a symlink.
+    If /usr/local/vcl is a symlink to vcl-2.5, copy /usr/local/vcl-2.5 to
+    /usr/local/vcl-2.5.1 and update the symlink.
 
     (for directory)
-    cp -ar /usr/local/vcl /usr/local/vcl-2.4.2
-    mv /usr/local/vcl /usr/local/vcl-2.5
-    ln -s /usr/local/vcl-2.5 /usr/local/vcl
+    cp -ar /usr/local/vcl /usr/local/vcl-2.5
+    mv /usr/local/vcl /usr/local/vcl-2.5.1
+    ln -s /usr/local/vcl-2.5.1 /usr/local/vcl
 
     (for symlink)
-    cp -ar /usr/local/vcl-2.4.2 /usr/local/vcl-2.5
-    ln -sfn /usr/local/vcl-2.5 /usr/local/vcl
+    cp -ar /usr/local/vcl-2.5 /usr/local/vcl-2.5.1
+    ln -sfn /usr/local/vcl-2.5.1 /usr/local/vcl
 
-15. Copy the new management node code over the old code:
+14. Copy the new management node code over the old code:
 
-    /bin/cp -ar /root/apache-VCL-2.5/managementnode/* /usr/local/vcl-2.5
+    /bin/cp -ar /root/apache-VCL-2.5.1/managementnode/* /usr/local/vcl-2.5.1
 
-16. Run install_perl_libs.pl to add any new perl library requirements:
+15. Run install_perl_libs.pl to add any new perl library requirements:
 
     /usr/local/vcl/bin/install_perl_libs.pl
 
-17. Start vcld service
+16. Start vcld service
 
     service vcld start
 
-18. Make some test reservations and watch the vcld.log to verify everything is
+17. Make some test reservations and watch the vcld.log to verify everything is
     working correctly.
 
     tail -f /var/log/vcld.log
diff --git a/doap_vcl.rdf b/doap_vcl.rdf
index 427cafa..fa5c1ab 100644
--- a/doap_vcl.rdf
+++ b/doap_vcl.rdf
@@ -40,6 +40,13 @@
     <category rdf:resource="http://projects.apache.org/category/cloud" />
     <release>
       <Version>
+        <name>Apache VCL 2.5.1</name>
+        <created>2019-07-25</created>
+        <revision>2.5.1</revision>
+      </Version>
+    </release>
+    <release>
+      <Version>
         <name>Apache VCL 2.5</name>
         <created>2017-07-27</created>
         <revision>2.5</revision>
diff --git a/managementnode/bin/health_check.pl b/managementnode/bin/health_check.pl
index 9af6b7f..4676837 100755
--- a/managementnode/bin/health_check.pl
+++ b/managementnode/bin/health_check.pl
@@ -43,7 +43,7 @@
 use base qw();
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/bin/install_perl_libs.pl b/managementnode/bin/install_perl_libs.pl
index 812b957..e946948 100755
--- a/managementnode/bin/install_perl_libs.pl
+++ b/managementnode/bin/install_perl_libs.pl
@@ -63,13 +63,20 @@
 	'perl-DBD-MySQL',
 	'perl-DBI',
 	'perl-Digest-SHA1',
+	'perl-Expect',
+	'perl-Frontier-RPC',
+	'perl-Frontier-RPC-Client',
 	'perl-IO-String',
 	'perl-JSON',
+	'perl-LWP-Protocol-https',
 	'perl-MailTools',
+	'perl-Mo',
 	'perl-Net-Jabber',
 	'perl-Net-Netmask',
 	'perl-Net-SSH-Expect',
+	'perl-Object-InsideOut',
 	'perl-RPC-XML',
+	'perl-Scalar-List-Utils',
 	'perl-Text-CSV_XS',
 	'perl-Time-HiRes',
 	'perl-XML-Simple',
@@ -79,20 +86,17 @@
 
 my @PERL_MODULES = (
 	'CPAN',
-	'DBI',
+	'Crypt::CBC',
 	'Digest::SHA1',
 	'Frontier::Client',
+	'IO::String',
 	'LWP::Protocol::https',
-	'Mail::Mailer',
 	'Mo::builder',
+	'Net::Ping::External',
 	'Net::SSH::Expect',
 	'Object::InsideOut',
-	'RPC::XML',
 	'Scalar::Util',
-	'Term::ANSIColor',
-	'Time::HiRes',
-	'URI',
-	'YAML',
+	'Text::CSV_XS',
 );
 	
 # Store the command line options in hash
diff --git a/managementnode/bin/monitor_vcld.pl b/managementnode/bin/monitor_vcld.pl
index fa0b796..9ea636e 100755
--- a/managementnode/bin/monitor_vcld.pl
+++ b/managementnode/bin/monitor_vcld.pl
@@ -53,7 +53,7 @@
 use lib "$FindBin::Bin/../lib";
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 use strict;
 use warnings;
@@ -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/upgrade_database.pl b/managementnode/bin/upgrade_database.pl
index 12cee86..1a6710c 100755
--- a/managementnode/bin/upgrade_database.pl
+++ b/managementnode/bin/upgrade_database.pl
@@ -41,7 +41,7 @@
 use lib "$FindBin::Bin/../lib";
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/bin/vcld b/managementnode/bin/vcld
index 5db965d..2dd919c 100755
--- a/managementnode/bin/vcld
+++ b/managementnode/bin/vcld
@@ -43,7 +43,7 @@
 use base qw();
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/bin/vclmessages.pl b/managementnode/bin/vclmessages.pl
new file mode 100755
index 0000000..caa8458
--- /dev/null
+++ b/managementnode/bin/vclmessages.pl
@@ -0,0 +1,218 @@
+#!/usr/bin/perl -w
+###############################################################################
+# 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.
+###############################################################################
+
+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..558c09f 100644
--- a/managementnode/lib/VCL/DataStructure.pm
+++ b/managementnode/lib/VCL/DataStructure.pm
@@ -66,7 +66,7 @@
 use base qw();
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
@@ -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.pm b/managementnode/lib/VCL/Module.pm
index 1bbfe7b..ea750fe 100644
--- a/managementnode/lib/VCL/Module.pm
+++ b/managementnode/lib/VCL/Module.pm
@@ -74,7 +74,7 @@
 use base qw();
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS.pm b/managementnode/lib/VCL/Module/OS.pm
index 276a3b7..32c25cf 100644
--- a/managementnode/lib/VCL/Module/OS.pm
+++ b/managementnode/lib/VCL/Module/OS.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
@@ -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..dda70ab 100644
--- a/managementnode/lib/VCL/Module/OS/Linux.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::OS);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
@@ -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/ESXi.pm b/managementnode/lib/VCL/Module/OS/Linux/ESXi.pm
index 4aa5371..dfed945 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/ESXi.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/ESXi.pm
@@ -44,7 +44,7 @@
 use base qw(VCL::Module::OS::Linux);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm b/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm
index 84d3dd0..f4a63a8 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm
@@ -44,7 +44,7 @@
 use base qw(VCL::Module::OS::Linux);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
@@ -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/Linux/Ubuntu.pm b/managementnode/lib/VCL/Module/OS/Linux/Ubuntu.pm
index a40564c..3df350b 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/Ubuntu.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/Ubuntu.pm
@@ -39,7 +39,7 @@
 use base qw(VCL::Module::OS::Linux);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
@@ -154,6 +154,7 @@
 
 =cut
 
+=head2 comment out this get_network_configuration to use version of function in Linux.pm
 sub get_network_configuration {
 	my $self = shift;
 	if (ref($self) !~ /VCL::Module/i) {
@@ -238,6 +239,7 @@
 	return $self->{network_configuration};
 		
 }
+=cut
 
 #//////////////////////////////////////////////////////////////////////////////
 
diff --git a/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm b/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm
index 58a2f41..f0be3fa 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm
@@ -35,7 +35,7 @@
 use base qw(VCL::Module::OS::Linux);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Linux/firewall.pm b/managementnode/lib/VCL/Module/OS/Linux/firewall.pm
index 88d89f4..7639ec6 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/firewall.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/firewall.pm
@@ -40,7 +40,7 @@
 use base qw(VCL::Module);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Linux/firewall/firewalld.pm b/managementnode/lib/VCL/Module/OS/Linux/firewall/firewalld.pm
index b7f943d..e927498 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/firewall/firewalld.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/firewall/firewalld.pm
@@ -39,7 +39,7 @@
 use base qw(VCL::Module::OS::Linux::firewall::iptables);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 our @ISA;
 
diff --git a/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm b/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm
index 9a526ab..eb28b48 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm
@@ -39,7 +39,7 @@
 use base qw(VCL::Module::OS::Linux::firewall);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 our @ISA;
 
diff --git a/managementnode/lib/VCL/Module/OS/Linux/firewall/ufw.pm b/managementnode/lib/VCL/Module/OS/Linux/firewall/ufw.pm
index 671b5c6..4b449aa 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/firewall/ufw.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/firewall/ufw.pm
@@ -39,7 +39,7 @@
 use base qw(VCL::Module::OS::Linux::firewall::iptables);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 our @ISA;
 
diff --git a/managementnode/lib/VCL/Module/OS/Linux/init.pm b/managementnode/lib/VCL/Module/OS/Linux/init.pm
index 07811a1..88faed0 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/init.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/init.pm
@@ -40,7 +40,7 @@
 use base qw(VCL::Module);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Linux/init/SysV.pm b/managementnode/lib/VCL/Module/OS/Linux/init/SysV.pm
index 78f8541..810889a 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/init/SysV.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/init/SysV.pm
@@ -42,7 +42,7 @@
 use base qw(VCL::Module::OS::Linux::init);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Linux/init/Upstart.pm b/managementnode/lib/VCL/Module/OS/Linux/init/Upstart.pm
index 64f4ea7..2848b93 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/init/Upstart.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/init/Upstart.pm
@@ -41,7 +41,7 @@
 use base qw(VCL::Module::OS::Linux::init);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Linux/init/systemd.pm b/managementnode/lib/VCL/Module/OS/Linux/init/systemd.pm
index fda195e..5d67587 100644
--- a/managementnode/lib/VCL/Module/OS/Linux/init/systemd.pm
+++ b/managementnode/lib/VCL/Module/OS/Linux/init/systemd.pm
@@ -42,7 +42,7 @@
 use base qw(VCL::Module::OS::Linux::init);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/OSX.pm b/managementnode/lib/VCL/Module/OS/OSX.pm
index 80d8e9d..b58e81d 100644
--- a/managementnode/lib/VCL/Module/OS/OSX.pm
+++ b/managementnode/lib/VCL/Module/OS/OSX.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::OS);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Windows.pm b/managementnode/lib/VCL/Module/OS/Windows.pm
index 3de1ad3..dde48d7 100644
--- a/managementnode/lib/VCL/Module/OS/Windows.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::OS);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
@@ -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
@@ -8299,6 +8353,7 @@
 
 [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU]
 "NoAutoUpdate"=dword:00000001
+"AUOptions"=dword:00000001
 EOF
 
 	# Import the string into the registry
@@ -12690,6 +12745,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 +12782,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 +12813,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 +13843,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 +13876,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 +13927,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 +14013,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 +14231,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 +14353,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 +14471,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 +14543,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 +14562,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 +14664,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 +14678,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 +14888,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 +15011,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/OS/Windows/Version_10/10.pm b/managementnode/lib/VCL/Module/OS/Windows/Version_10/10.pm
index 96b0adb..7558c4a 100644
--- a/managementnode/lib/VCL/Module/OS/Windows/Version_10/10.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows/Version_10/10.pm
@@ -40,7 +40,7 @@
 use base qw(VCL::Module::OS::Windows::Version_6::8);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Windows/Version_10/2016.pm b/managementnode/lib/VCL/Module/OS/Windows/Version_10/2016.pm
index 2cc4041..fe34fea 100644
--- a/managementnode/lib/VCL/Module/OS/Windows/Version_10/2016.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows/Version_10/2016.pm
@@ -40,7 +40,7 @@
 use base qw(VCL::Module::OS::Windows::Version_6::8);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm b/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm
index 86f1659..8604168 100644
--- a/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm
@@ -40,7 +40,7 @@
 use base qw(VCL::Module::OS::Windows);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Windows/Version_5/2003.pm b/managementnode/lib/VCL/Module/OS/Windows/Version_5/2003.pm
index 99c85fc..983213c 100644
--- a/managementnode/lib/VCL/Module/OS/Windows/Version_5/2003.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows/Version_5/2003.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::OS::Windows::Version_5);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Windows/Version_5/XP.pm b/managementnode/lib/VCL/Module/OS/Windows/Version_5/XP.pm
index e342966..a85c4a1 100644
--- a/managementnode/lib/VCL/Module/OS/Windows/Version_5/XP.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows/Version_5/XP.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::OS::Windows::Version_5);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm b/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm
index 90b9991..8c1089e 100644
--- a/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm
@@ -45,7 +45,7 @@
 use base qw(VCL::Module::OS::Windows);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Windows/Version_6/2008.pm b/managementnode/lib/VCL/Module/OS/Windows/Version_6/2008.pm
index 624848c..6958575 100644
--- a/managementnode/lib/VCL/Module/OS/Windows/Version_6/2008.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows/Version_6/2008.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::OS::Windows::Version_6);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Windows/Version_6/2012.pm b/managementnode/lib/VCL/Module/OS/Windows/Version_6/2012.pm
index 43ff5b2..1a00651 100644
--- a/managementnode/lib/VCL/Module/OS/Windows/Version_6/2012.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows/Version_6/2012.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::OS::Windows::Version_6);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Windows/Version_6/7.pm b/managementnode/lib/VCL/Module/OS/Windows/Version_6/7.pm
index cd238d0..6d3903b 100644
--- a/managementnode/lib/VCL/Module/OS/Windows/Version_6/7.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows/Version_6/7.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::OS::Windows::Version_6);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Windows/Version_6/8.pm b/managementnode/lib/VCL/Module/OS/Windows/Version_6/8.pm
index 1bc88e9..aa9bae8 100644
--- a/managementnode/lib/VCL/Module/OS/Windows/Version_6/8.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows/Version_6/8.pm
@@ -39,7 +39,7 @@
 use base qw(VCL::Module::OS::Windows::Version_6);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/OS/Windows/Version_6/Vista.pm b/managementnode/lib/VCL/Module/OS/Windows/Version_6/Vista.pm
index d92b0e4..65376df 100644
--- a/managementnode/lib/VCL/Module/OS/Windows/Version_6/Vista.pm
+++ b/managementnode/lib/VCL/Module/OS/Windows/Version_6/Vista.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::OS::Windows::Version_6);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Predictive.pm b/managementnode/lib/VCL/Module/Predictive.pm
index d9c2d33..8155757 100644
--- a/managementnode/lib/VCL/Module/Predictive.pm
+++ b/managementnode/lib/VCL/Module/Predictive.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Predictive/Level_0.pm b/managementnode/lib/VCL/Module/Predictive/Level_0.pm
index 9a9d9b1..5596f03 100644
--- a/managementnode/lib/VCL/Module/Predictive/Level_0.pm
+++ b/managementnode/lib/VCL/Module/Predictive/Level_0.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::Predictive);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Predictive/Level_1.pm b/managementnode/lib/VCL/Module/Predictive/Level_1.pm
index c60df78..78073e2 100644
--- a/managementnode/lib/VCL/Module/Predictive/Level_1.pm
+++ b/managementnode/lib/VCL/Module/Predictive/Level_1.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::Predictive);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Predictive/Level_2.pm b/managementnode/lib/VCL/Module/Predictive/Level_2.pm
index 16dbdaa..5c3983c 100644
--- a/managementnode/lib/VCL/Module/Predictive/Level_2.pm
+++ b/managementnode/lib/VCL/Module/Predictive/Level_2.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::Predictive);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Provisioning.pm b/managementnode/lib/VCL/Module/Provisioning.pm
index 74157c4..5616bf3 100644
--- a/managementnode/lib/VCL/Module/Provisioning.pm
+++ b/managementnode/lib/VCL/Module/Provisioning.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Provisioning/Lab.pm b/managementnode/lib/VCL/Module/Provisioning/Lab.pm
index d792a5c..c14398d 100644
--- a/managementnode/lib/VCL/Module/Provisioning/Lab.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/Lab.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::Provisioning);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm b/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
index 6931318..bf0f3d0 100644
--- a/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
@@ -47,7 +47,7 @@
 use base qw(VCL::Module::Provisioning::VMware::VMware);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
@@ -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..c19807c 100644
--- a/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
@@ -49,7 +49,7 @@
 use base qw(VCL::Module::Provisioning);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
@@ -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..fc67a31 100644
--- a/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm
@@ -47,7 +47,7 @@
 use base qw(VCL::Module::Provisioning::VMware::VMware);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
@@ -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/VMware/vmware_cmd.pm b/managementnode/lib/VCL/Module/Provisioning/VMware/vmware_cmd.pm
index 24e4559..09086c9 100644
--- a/managementnode/lib/VCL/Module/Provisioning/VMware/vmware_cmd.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/VMware/vmware_cmd.pm
@@ -46,7 +46,7 @@
 use base qw(VCL::Module::Provisioning::VMware::VMware);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Provisioning/docker.pm b/managementnode/lib/VCL/Module/Provisioning/docker.pm
index e202e3b..b8e380b 100644
--- a/managementnode/lib/VCL/Module/Provisioning/docker.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/docker.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::Provisioning);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Provisioning/libvirt.pm b/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
index 44691bc..6f2dea8 100644
--- a/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
@@ -46,7 +46,7 @@
 use base qw(VCL::Module::Provisioning);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
@@ -779,6 +779,44 @@
 		notify($ERRORS{'DEBUG'}, 0, "'$domain_name' domain is not running on $node_name");
 		return 1;
 	}
+	elsif (grep(/SIGKILL: Device or resource busy/i, @$output)) {
+		notify($ERRORS{'DEBUG'}, 0, "Failed to stop '$domain_name' domain; \"SIGKILL: Device or resource busy\" encountered, waiting 30 seconds and trying again");
+		# libvirt could not kill VM, wait and try again
+		sleep 30;
+		my $command2 = "virsh -q list --all";
+		($exit_status, $output) = $self->vmhost_os->execute($command2);
+		my ($id, $name, $state);
+		for my $line (@$output) {
+			($id, $name, $state) = $line =~ /^\s*([\d\-]+)\s+(.+?)\s+(\w+|shut off|in shutdown)$/g;
+			next if (!defined($id));
+			last if ($name eq $domain_name);
+		}
+		if ($name ne $domain_name) {
+			notify($ERRORS{'WARNING'}, 0, "2nd try: $domain_name not found when running 'virsh list' on $node_name");
+			return;
+		}
+		if ($id eq '-') {
+			notify($ERRORS{'DEBUG'}, 0, "'$domain_name' domain now stopped");
+			return 1;
+		}
+		($exit_status, $output) = $self->vmhost_os->execute($command);
+		if (!defined($output)) {
+			notify($ERRORS{'WARNING'}, 0, "2nd try: failed to execute virsh command to destroy '$domain_name' domain on $node_name");
+			return;
+		}
+		elsif ($exit_status eq '0') {
+			notify($ERRORS{'OK'}, 0, "2nd try: destroyed '$domain_name' domain on $node_name");
+			return 1;
+		}
+		elsif (grep(/domain is not running/i, @$output)) {
+			notify($ERRORS{'DEBUG'}, 0, "2nd try: '$domain_name' domain is not running on $node_name");
+			return 1;
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "2nd try: failed to destroy '$domain_name' domain on $node_name\ncommand: $command\nexit status: $exit_status\noutput:\n" . join("\n", @$output));
+			return;
+		}
+	}
 	else {
 		notify($ERRORS{'WARNING'}, 0, "failed to destroy '$domain_name' domain on $node_name\ncommand: $command\nexit status: $exit_status\noutput:\n" . join("\n", @$output));
 		return;
@@ -1736,6 +1774,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->vmhost_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 +1844,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 +1880,11 @@
 				model => {
 					'fallback' => 'allow',
 				},
-				#'topology' => [
-				#	{
-				#		'sockets' => $cpu_count,
-				#		'cores' => '2',
-				#		'threads' => '2',
-				#	}
-				#],
-				
+				topology => {
+					'sockets' => $cpusockets,
+					'cores' => $cpucores,
+					'threads' => 1,
+				},
 			}
 		],
 		'clock' => [
@@ -1908,6 +1957,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..decfb4d 100644
--- a/managementnode/lib/VCL/Module/Provisioning/libvirt/KVM.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/libvirt/KVM.pm
@@ -42,7 +42,7 @@
 use base qw(VCL::Module::Provisioning::libvirt);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
@@ -599,6 +599,14 @@
 		$source_file_paths_string = '"' . join('" "', @source_file_paths) . '"';
 	#}
 	
+	my $parent_file = $source_file_name;
+	$parent_file =~ s/-s[0-9]{3}//;
+	$parent_file = $parent_file . ".vmdk";
+	if ($self->vmhost_os->file_exists("$source_directory_path$parent_file")) {
+		$source_file_paths_string = "$source_directory_path$parent_file";
+		notify($ERRORS{'DEBUG'}, 0, "changing source_file_paths_string from multiple files to $source_directory_path$parent_file");
+	}
+	
 	my $options = '';
 	# VCL-911: If copying to the repository, save the image qcow2 version 0.10, the traditional image format that can be read by any QEMU since 0.10
 	my $repository_image_file_path = $self->get_repository_image_file_path();
@@ -621,7 +629,9 @@
 	
 	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) ||
+	   grep(/Invalid parameter.*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/Module/Provisioning/one.pm b/managementnode/lib/VCL/Module/Provisioning/one.pm
index 10df935..d5921d7 100644
--- a/managementnode/lib/VCL/Module/Provisioning/one.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/one.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::Provisioning);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Provisioning/openstack.pm b/managementnode/lib/VCL/Module/Provisioning/openstack.pm
index f116a42..b2d2ffc 100644
--- a/managementnode/lib/VCL/Module/Provisioning/openstack.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/openstack.pm
@@ -46,7 +46,7 @@
 use base qw(VCL::Module::Provisioning);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Provisioning/vbox.pm b/managementnode/lib/VCL/Module/Provisioning/vbox.pm
index f102588..e7ce229 100644
--- a/managementnode/lib/VCL/Module/Provisioning/vbox.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/vbox.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::Provisioning);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Provisioning/xCAT.pm b/managementnode/lib/VCL/Module/Provisioning/xCAT.pm
index 70eb721..1b06029 100644
--- a/managementnode/lib/VCL/Module/Provisioning/xCAT.pm
+++ b/managementnode/lib/VCL/Module/Provisioning/xCAT.pm
@@ -50,7 +50,7 @@
 use base qw(VCL::Module::Provisioning);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/Semaphore.pm b/managementnode/lib/VCL/Module/Semaphore.pm
index e6d20bf..61d420c 100644
--- a/managementnode/lib/VCL/Module/Semaphore.pm
+++ b/managementnode/lib/VCL/Module/Semaphore.pm
@@ -50,7 +50,7 @@
 use base qw(VCL::Module);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/Module/State.pm b/managementnode/lib/VCL/Module/State.pm
index 91c6604..24dd539 100644
--- a/managementnode/lib/VCL/Module/State.pm
+++ b/managementnode/lib/VCL/Module/State.pm
@@ -44,7 +44,7 @@
 use base qw(VCL::Module);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/blockrequest.pm b/managementnode/lib/VCL/blockrequest.pm
index 7ce9cde..6849f9a 100644
--- a/managementnode/lib/VCL/blockrequest.pm
+++ b/managementnode/lib/VCL/blockrequest.pm
@@ -43,7 +43,7 @@
 use base qw(VCL::Module::State);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/healthcheck.pm b/managementnode/lib/VCL/healthcheck.pm
index 480c688..3158c1b 100644
--- a/managementnode/lib/VCL/healthcheck.pm
+++ b/managementnode/lib/VCL/healthcheck.pm
@@ -43,7 +43,7 @@
 use base qw();
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/image.pm b/managementnode/lib/VCL/image.pm
index 128de2b..9091d1e 100644
--- a/managementnode/lib/VCL/image.pm
+++ b/managementnode/lib/VCL/image.pm
@@ -57,7 +57,7 @@
 use base qw(VCL::Module::State);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/inuse.pm b/managementnode/lib/VCL/inuse.pm
index bd494b4..3c8dbce 100644
--- a/managementnode/lib/VCL/inuse.pm
+++ b/managementnode/lib/VCL/inuse.pm
@@ -71,7 +71,7 @@
 use base qw(VCL::Module::State);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/makeproduction.pm b/managementnode/lib/VCL/makeproduction.pm
index b53d9cd..279a78e 100644
--- a/managementnode/lib/VCL/makeproduction.pm
+++ b/managementnode/lib/VCL/makeproduction.pm
@@ -57,7 +57,7 @@
 use base qw(VCL::Module::State);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/new.pm b/managementnode/lib/VCL/new.pm
index 98f02d1..2573d5a 100644
--- a/managementnode/lib/VCL/new.pm
+++ b/managementnode/lib/VCL/new.pm
@@ -57,7 +57,7 @@
 use base qw(VCL::Module::State);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/reclaim.pm b/managementnode/lib/VCL/reclaim.pm
index 34d56dd..4321edc 100644
--- a/managementnode/lib/VCL/reclaim.pm
+++ b/managementnode/lib/VCL/reclaim.pm
@@ -57,7 +57,7 @@
 use base qw(VCL::Module::State);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/reserved.pm b/managementnode/lib/VCL/reserved.pm
index 363331a..6e51d04 100644
--- a/managementnode/lib/VCL/reserved.pm
+++ b/managementnode/lib/VCL/reserved.pm
@@ -61,7 +61,7 @@
 use base qw(VCL::Module::State);
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
diff --git a/managementnode/lib/VCL/utils.pm b/managementnode/lib/VCL/utils.pm
index 0e9a4ea..5f7b6ae 100644
--- a/managementnode/lib/VCL/utils.pm
+++ b/managementnode/lib/VCL/utils.pm
@@ -43,7 +43,7 @@
 use base qw();
 
 # Specify the version of this module
-our $VERSION = '2.5';
+our $VERSION = '2.5.1';
 
 # Specify the version of Perl to use
 use 5.008000;
@@ -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..da77a52 100644
--- a/mysql/update-vcl.sql
+++ b/mysql/update-vcl.sql
@@ -872,17 +872,25 @@
 CREATE TABLE IF NOT EXISTS `addomain` (
   `id` tinyint(3) unsigned NOT NULL auto_increment,
   `ownerid` mediumint(8) unsigned NOT NULL,
-  `name` varchar(30) NOT NULL default '',
+  `name` varchar(512) NOT NULL default '',
   `domainDNSName` varchar(70) NOT NULL default '',
   `dnsServers` varchar(512) default NULL,
-  `username` varchar(64) NOT NULL default '',
+  `username` varchar(80) 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');
+CALL AddColumnIfNotExists('addomain', 'usedbhostnames', "tinyint(1) unsigned NOT NULL default '0'");
+
+ALTER TABLE `addomain` CHANGE `name` `name` varchar(512) NOT NULL default '';
+ALTER TABLE `addomain` CHANGE `username` `username` varchar(80) NOT NULL default '';
+
 -- --------------------------------------------------------
 
 --
@@ -1020,6 +1028,7 @@
 
 ALTER TABLE `image` CHANGE `basedoffrevisionid` `basedoffrevisionid` mediumint(8) unsigned default NULL;
 CALL AddIndexIfNotExists('image', 'basedoffrevisionid');
+ALTER TABLE `image` CHANGE `maxinitialtime` `maxinitialtime` mediumint(8) unsigned NOT NULL default '0';
 
 -- --------------------------------------------------------
 
@@ -1111,6 +1120,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 +1134,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`
 --
@@ -1306,6 +1328,14 @@
 -- --------------------------------------------------------
 
 --
+-- Table structure for table `resourcegroup`
+--
+
+ALTER TABLE `resourcegroup` CHANGE `name` `name` varchar(60) NOT NULL default '';
+
+-- --------------------------------------------------------
+
+--
 -- Table structure for table `resourcepriv`
 --
 CALL AddManageMapping();
@@ -1544,12 +1574,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 +1777,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..197939f 100644
--- a/mysql/vcl.sql
+++ b/mysql/vcl.sql
@@ -32,14 +32,15 @@
 CREATE TABLE IF NOT EXISTS `addomain` (
   `id` tinyint(3) unsigned NOT NULL auto_increment,
   `ownerid` mediumint(8) unsigned NOT NULL,
-  `name` varchar(30) NOT NULL default '',
+  `name` varchar(512) NOT NULL default '',
   `domainDNSName` varchar(70) NOT NULL default '',
   `dnsServers` varchar(512) default NULL,
-  `username` varchar(64) NOT NULL default '',
+  `username` varchar(80) 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;
 
@@ -52,9 +53,9 @@
 CREATE TABLE IF NOT EXISTS `adminlevel` (
   `id` tinyint(3) unsigned NOT NULL auto_increment,
   `name` varchar(10) NOT NULL default '',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -71,7 +72,7 @@
   `helpaddress` varchar(32) default NULL,
   `shibonly` tinyint(1) unsigned NOT NULL default '0',
   `theme` varchar(50) default NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
@@ -86,7 +87,7 @@
   `computerid` smallint(5) unsigned NOT NULL default '0',
   `imageid` smallint(5) unsigned NOT NULL default '0',
   `reloadrequestid` mediumint(8) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`blockTimeid`,`computerid`),
+  PRIMARY KEY (`blockTimeid`,`computerid`),
   KEY `computerid` (`computerid`),
   KEY `imageid` (`imageid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
@@ -108,13 +109,13 @@
   `managementnodeid` smallint(5) unsigned default NULL,
   `expireTime` datetime NOT NULL,
   `processing` tinyint(1) unsigned NOT NULL,
-  `status` enum('requested','accepted','completed','rejected','deleted') NOT NULL DEFAULT 'accepted',
+  `status` enum('requested','accepted','completed','rejected','deleted') NOT NULL default 'accepted',
   `comments` text,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   KEY `imageid` (`imageid`),
   KEY `groupid` (`groupid`),
   KEY `ownerid` (`ownerid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -129,11 +130,11 @@
   `end` datetime NOT NULL,
   `processed` tinyint(1) unsigned NOT NULL default '0',
   `skip` tinyint(1) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   KEY `start` (`start`),
   KEY `end` (`end`),
   KEY `blockRequestid` (`blockRequestid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -177,7 +178,7 @@
 CREATE TABLE IF NOT EXISTS `changelog` (
   `id` int(10) unsigned NOT NULL auto_increment,
   `logid` int(10) unsigned NOT NULL default '0',
-  `userid` mediumint(8) unsigned DEFAULT NULL,
+  `userid` mediumint(8) unsigned default NULL,
   `reservationid` mediumint(8) unsigned default NULL,
   `start` datetime default NULL,
   `end` datetime default NULL,
@@ -186,13 +187,13 @@
   `wasavailable` tinyint(1) unsigned default NULL,
   `timestamp` datetime NOT NULL default '0000-00-00 00:00:00',
   `other` varchar(255) default NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   KEY `logid` (`logid`),
   KEY `userid` (`userid`),
   KEY `reservationid` (`reservationid`),
   KEY `computerid` (`computerid`),
-  UNIQUE KEY reservation_user_remoteIP (userid,reservationid,remoteIP)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+  UNIQUE KEY `reservation_user_remoteIP` (`userid`,`reservationid`,`remoteIP`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -240,7 +241,7 @@
   `provisioningid` smallint(5) unsigned NOT NULL,
   `drivetype` varchar(4) NOT NULL default 'hda',
   `deleted` tinyint(1) unsigned NOT NULL default '0',
-  `datedeleted` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `datedeleted` datetime NOT NULL default '0000-00-00 00:00:00',
   `notes` text,
   `lastcheck` datetime default NULL,
   `location` varchar(255) default NULL,
@@ -252,10 +253,10 @@
   `hostpub` mediumtext,
   `vmtypeid` tinyint(3) unsigned default NULL,
   `predictivemoduleid` smallint(5) unsigned NOT NULL default '9',
-  PRIMARY KEY  (`id`),
-  UNIQUE KEY `hostname` (`hostname`, `datedeleted`),
-  UNIQUE KEY `eth1macaddress` (`eth1macaddress`, `datedeleted`),
-  UNIQUE KEY `eth0macaddress` (`eth0macaddress`, `datedeleted`),
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `hostname` (`hostname`,`datedeleted`),
+  UNIQUE KEY `eth1macaddress` (`eth1macaddress`,`datedeleted`),
+  UNIQUE KEY `eth0macaddress` (`eth0macaddress`,`datedeleted`),
   KEY `ownerid` (`ownerid`),
   KEY `stateid` (`stateid`),
   KEY `platformid` (`platformid`),
@@ -269,7 +270,7 @@
   KEY `nextimageid` (`nextimageid`),
   KEY `provisioningid` (`provisioningid`),
   KEY `imagerevisionid` (`imagerevisionid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -293,17 +294,17 @@
 -- 
 
 CREATE TABLE IF NOT EXISTS `computerloadlog` (
-  `id` int(12) unsigned NOT NULL auto_increment,
+  `id` int(10) unsigned NOT NULL auto_increment,
   `reservationid` mediumint(8) unsigned NOT NULL,
   `computerid` smallint(8) unsigned NOT NULL,
   `loadstateid` smallint(8) unsigned NOT NULL,
   `timestamp` datetime default NULL,
   `additionalinfo` text,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   KEY `reservationid` (`reservationid`),
   KEY `loadstateid` (`loadstateid`),
   KEY `computerid` (`computerid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -316,9 +317,9 @@
   `loadstatename` varchar(24) NOT NULL,
   `prettyname` varchar(50) default NULL,
   `est` tinyint(2) unsigned default NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `loadstatename` (`loadstatename`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -326,20 +327,20 @@
 -- Table structure for table 'connectlog'
 --
 
-CREATE TABLE IF NOT EXISTS connectlog (
-  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+CREATE TABLE IF NOT EXISTS `connectlog` (
+  `id` int(10) unsigned NOT NULL auto_increment,
   `logid` int(10) unsigned NOT NULL,
   `reservationid` mediumint(8) unsigned NOT NULL,
-  `userid` mediumint(8) unsigned DEFAULT NULL,
+  `userid` mediumint(8) unsigned default NULL,
   `remoteIP` varchar(39) NOT NULL,
   `verified` tinyint(1) NOT NULL,
-  `timestamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
-  PRIMARY KEY (id),
-  UNIQUE KEY reservationid_1 (reservationid,userid,remoteIP),
-  KEY reservationid (reservationid),
-  KEY userid (userid),
-  KEY logid (logid)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+  `timestamp` datetime NOT NULL default '0000-00-00 00:00:00',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `reservationid_1` (`reservationid`,`userid`,`remoteIP`),
+  KEY `reservationid` (`reservationid`),
+  KEY `userid` (`userid`),
+  KEY `logid` (`logid`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -353,10 +354,10 @@
   `description` varchar(255) NOT NULL,
   `connecttext` text NOT NULL,
   `servicename` varchar(32) NOT NULL,
-  `startupscript` varchar(256) DEFAULT NULL,
+  `startupscript` varchar(256) default NULL,
   PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`,`description`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -388,10 +389,10 @@
   `connectmethodid` tinyint(3) unsigned NOT NULL,
   `port` mediumint(8) unsigned NOT NULL,
   `protocol` enum('TCP','UDP') NOT NULL default 'TCP',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `connectmethodid_port_protocol` (`connectmethodid`,`port`,`protocol`),
   KEY `connectmethodid` (`connectmethodid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -409,7 +410,7 @@
   `multicall` tinyint(1) unsigned NOT NULL default '1',
   `parentid` varchar(255) default NULL,
   `deletefromid` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   KEY `parentid` (`parentid`),
   KEY `userid` (`userid`),
   KEY `expiretime` (`expiretime`),
@@ -423,9 +424,9 @@
 -- 
 
 CREATE TABLE IF NOT EXISTS `cryptkey` (
-  `id` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
+  `id` smallint(6) unsigned NOT NULL auto_increment,
   `hostid` smallint(6) unsigned NOT NULL,
-  `hosttype` enum('managementnode','web') NOT NULL DEFAULT 'managementnode',
+  `hosttype` enum('managementnode','web') NOT NULL default 'managementnode',
   `pubkey` varchar(1000) NOT NULL,
   `algorithm` varchar(80) NOT NULL,
   `algorithmoption` varchar(255) NOT NULL,
@@ -441,7 +442,7 @@
 -- 
 
 CREATE TABLE IF NOT EXISTS `cryptsecret` (
-  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
+  `id` mediumint(8) unsigned NOT NULL auto_increment,
   `cryptkeyid` smallint(5) unsigned NOT NULL,
   `secretid` smallint(5) unsigned NOT NULL,
   `cryptsecret` varchar(1000) NOT NULL,
@@ -491,14 +492,14 @@
   `test` tinyint(1) unsigned NOT NULL default '0',
   `lastupdate` datetime default NULL,
   `forcheckout` tinyint(1) unsigned NOT NULL default '1',
-  `maxinitialtime` smallint(5) unsigned NOT NULL default '0',
+  `maxinitialtime` mediumint(8) unsigned NOT NULL default '0',
   `project` enum('vcl','hpc','vclhpc') NOT NULL default 'vcl',
   `size` smallint(5) unsigned NOT NULL default '0',
   `architecture` enum('x86','x86_64') NOT NULL default 'x86',
   `description` text,
   `usage` text,
   `basedoffrevisionid` mediumint(8) unsigned default NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`),
   UNIQUE KEY `prettyname` (`prettyname`),
   KEY `ownerid` (`ownerid`),
@@ -507,7 +508,7 @@
   KEY `imagemetaid` (`imagemetaid`),
   KEY `imagetypeid` (`imagetypeid`),
   KEY `basedoffrevisionid` (`basedoffrevisionid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -537,8 +538,8 @@
   `architecture` varchar(10) default NULL,
   `rootaccess` tinyint(1) unsigned NOT NULL default '1',
   `sethostname` tinyint(1) unsigned default NULL,
-  PRIMARY KEY  (`id`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -557,12 +558,12 @@
   `production` tinyint(1) unsigned NOT NULL,
   `comments` text,
   `imagename` varchar(75) NOT NULL,
-  `autocaptured` tinyint(1) unsigned NOT NULL DEFAULT '0',
-  PRIMARY KEY  (`id`),
+  `autocaptured` tinyint(1) unsigned NOT NULL default '0',
+  PRIMARY KEY (`id`),
   UNIQUE KEY `production` (`production`,`imagename`),
   UNIQUE KEY `imageid` (`imageid`,`revision`),
   KEY `userid` (`userid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -572,7 +573,7 @@
 
 CREATE TABLE IF NOT EXISTS `imagerevisioninfo` (
   `imagerevisionid` mediumint(8) unsigned NOT NULL,
-  `usernames` varchar(512) DEFAULT NULL,
+  `usernames` varchar(512) default NULL,
   `firewallenabled` varchar(20) NOT NULL,
   `timestamp` datetime NOT NULL,
   UNIQUE KEY `imagerevisionid` (`imagerevisionid`)
@@ -587,9 +588,9 @@
 CREATE TABLE IF NOT EXISTS `imagetype` (
   `id` smallint(5) unsigned NOT NULL auto_increment,
   `name` varchar(16) NOT NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -600,9 +601,9 @@
 CREATE TABLE IF NOT EXISTS `IMtype` (
   `id` tinyint(3) unsigned NOT NULL auto_increment,
   `name` varchar(20) NOT NULL default '',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -616,7 +617,7 @@
   `salt` varchar(8) NOT NULL default '',
   `lastupdated` datetime NOT NULL default '0000-00-00 00:00:00',
   `lockedout` tinyint(1) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`userid`)
+  PRIMARY KEY (`userid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
@@ -640,14 +641,14 @@
   `remoteIP` varchar(15) default NULL,
   `imageid` smallint(5) unsigned NOT NULL default '0',
   `size` smallint(5) unsigned NOT NULL default '1450',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   KEY `userid` (`userid`),
   KEY `computerid` (`computerid`),
   KEY `imageid` (`imageid`),
   KEY `finalend` (`finalend`),
   KEY `start` (`start`),
   KEY `wasavailable` (`wasavailable`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -662,7 +663,7 @@
   `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
   `passfail` tinyint(1) unsigned NOT NULL default '0',
   `remoteIP` varchar(15) NOT NULL,
-  `code` enum('none','invalid credentials') NOT NULL DEFAULT 'none',
+  `code` enum('none','invalid credentials') NOT NULL default 'none',
   KEY `user` (`user`),
   KEY `affiliationid` (`affiliationid`),
   KEY `timestamp` (`timestamp`),
@@ -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',
@@ -699,13 +700,25 @@
   `sharedMailBox` varchar(128) default NULL,
   `NOT_STANDALONE` varchar(128) default NULL,
   `availablenetworks` text NOT NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `hostname` (`hostname`),
   KEY `stateid` (`stateid`),
   KEY `ownerid` (`ownerid`),
   KEY `imagelibgroupid` (`imagelibgroupid`),
   KEY `IPaddress` (`IPaddress`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- --------------------------------------------------------
+
+-- 
+-- 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;
 
 -- --------------------------------------------------------
 
@@ -719,9 +732,9 @@
   `prettyname` varchar(70) NOT NULL,
   `description` varchar(255) NOT NULL,
   `perlpackage` varchar(150) NOT NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -733,10 +746,10 @@
   `id` smallint(5) unsigned NOT NULL auto_increment,
   `resourceid` mediumint(8) unsigned NOT NULL,
   `publicIPaddress` varchar(15) NOT NULL,
-  `internalIPaddress` varchar(15) DEFAULT NULL,
-  PRIMARY KEY  (`id`),
+  `internalIPaddress` varchar(15) default NULL,
+  PRIMARY KEY (`id`),
   UNIQUE KEY `resourceid` (`resourceid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -749,9 +762,9 @@
   `nathostresourceid` mediumint(8) unsigned NOT NULL,
   `publicIPaddress` varchar(15) NOT NULL,
   `publicport` smallint(5) unsigned NOT NULL,
-  `internalIPaddress` varchar(15) DEFAULT NULL,
+  `internalIPaddress` varchar(15) default NULL,
   `internalport` smallint(5) unsigned NOT NULL,
-  `protocol` enum('TCP','UDP') NOT NULL DEFAULT 'TCP',
+  `protocol` enum('TCP','UDP') NOT NULL default 'TCP',
   `timestamp` datetime NOT NULL,
   UNIQUE KEY `sublogid` (`sublogid`,`nathostresourceid`,`publicIPaddress`,`publicport`,`internalIPaddress`,`internalport`,`protocol`),
   KEY `logid` (`sublogid`),
@@ -796,13 +809,13 @@
 --
 
 CREATE TABLE IF NOT EXISTS `oneclick` (
-  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `id` int(10) unsigned NOT NULL auto_increment,
   `userid` mediumint(8) unsigned NOT NULL,
   `imageid` smallint(5) unsigned NOT NULL,
   `name` varchar(70) NOT NULL,
   `duration` int(11) NOT NULL,
-  `autologin` tinyint(1) NOT NULL DEFAULT '0',
-  `status` tinyint(4) NOT NULL DEFAULT '1',
+  `autologin` tinyint(1) NOT NULL default '0',
+  `status` tinyint(4) NOT NULL default '1',
   PRIMARY KEY (`id`),
   KEY `userid` (`userid`),
   KEY `imageid` (`imageid`)
@@ -816,7 +829,7 @@
 
 CREATE TABLE IF NOT EXISTS `openstackcomputermap` (
   `instanceid` varchar(50) NOT NULL,
-  `computerid` smallint(5) unsigned DEFAULT NULL,
+  `computerid` smallint(5) unsigned default NULL,
   PRIMARY KEY (`instanceid`),
   UNIQUE KEY `computerid` (`computerid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
@@ -846,16 +859,16 @@
   `prettyname` varchar(64) NOT NULL default '',
   `type` varchar(30) NOT NULL,
   `installtype` varchar(30) NOT NULL default 'image',
-  `minram` mediumint(8) unsigned NOT NULL DEFAULT '512',
+  `minram` mediumint(8) unsigned NOT NULL default '512',
   `sourcepath` varchar(30) default NULL,
   `moduleid` smallint(5) unsigned default NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`),
   UNIQUE KEY `prettyname` (`prettyname`),
   KEY `type` (`type`),
   KEY `installtype` (`installtype`),
   KEY `moduleid` (`moduleid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -866,9 +879,9 @@
 CREATE TABLE IF NOT EXISTS `OSinstalltype` (
   `id` tinyint(3) unsigned NOT NULL auto_increment,
   `name` varchar(30) NOT NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -879,9 +892,9 @@
 CREATE TABLE IF NOT EXISTS `OStype` (
   `id` tinyint(3) unsigned NOT NULL auto_increment,
   `name` varchar(30) NOT NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -892,9 +905,9 @@
 CREATE TABLE IF NOT EXISTS `platform` (
   `id` tinyint(3) unsigned NOT NULL auto_increment,
   `name` varchar(20) NOT NULL default '',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -906,9 +919,9 @@
   `id` mediumint(8) unsigned NOT NULL auto_increment,
   `parent` mediumint(8) unsigned NOT NULL default '0',
   `name` varchar(50) NOT NULL default '',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `parent` (`parent`,`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1 COMMENT='nodes for privilege tree';
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='nodes for privilege tree';
 
 -- --------------------------------------------------------
 
@@ -921,10 +934,10 @@
   `name` varchar(30) NOT NULL,
   `prettyname` varchar(70) NOT NULL,
   `moduleid` smallint(5) unsigned NOT NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   KEY `moduleid` (`moduleid`),
   UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -935,9 +948,9 @@
 CREATE TABLE IF NOT EXISTS `provisioningOSinstalltype` (
   `provisioningid` smallint(5) unsigned NOT NULL,
   `OSinstalltypeid` tinyint(3) unsigned NOT NULL,
-  PRIMARY KEY  (`provisioningid`,`OSinstalltypeid`),
+  PRIMARY KEY (`provisioningid`,`OSinstalltypeid`),
   KEY `OSinstalltypeid` (`OSinstalltypeid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -973,14 +986,14 @@
   `daterequested` datetime NOT NULL default '0000-00-00 00:00:00',
   `datemodified` datetime default NULL,
   `checkuser` tinyint(1) unsigned NOT NULL default '1',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   KEY `userid` (`userid`),
   KEY `stateid` (`stateid`),
   KEY `laststateid` (`laststateid`),
   KEY `logid` (`logid`),
   KEY `start` (`start`),
   KEY `end` (`end`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1000,13 +1013,13 @@
   `pw` varchar(40) default NULL,
   `connectIP` varchar(15) default NULL,
   `connectport` smallint(5) unsigned default NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   KEY `managementnodeid` (`managementnodeid`),
   KEY `imageid` (`imageid`),
   KEY `requestid` (`requestid`),
   KEY `computerid` (`computerid`),
   KEY `imagerevisionid` (`imagerevisionid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1032,9 +1045,9 @@
   `id` mediumint(8) unsigned NOT NULL auto_increment,
   `resourcetypeid` tinyint(5) unsigned NOT NULL default '0',
   `subid` mediumint(8) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `resourcetypeid` (`resourcetypeid`,`subid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1044,13 +1057,13 @@
 
 CREATE TABLE IF NOT EXISTS `resourcegroup` (
   `id` smallint(5) unsigned NOT NULL auto_increment,
-  `name` varchar(50) NOT NULL default '',
+  `name` varchar(60) NOT NULL default '',
   `ownerusergroupid` smallint(5) unsigned NOT NULL default '39',
   `resourcetypeid` tinyint(3) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `resourcetypeid` (`resourcetypeid`,`name`),
   KEY `ownerusergroupid` (`ownerusergroupid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1061,7 +1074,7 @@
 CREATE TABLE IF NOT EXISTS `resourcegroupmembers` (
   `resourceid` mediumint(8) unsigned NOT NULL default '0',
   `resourcegroupid` smallint(5) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`resourceid`,`resourcegroupid`),
+  PRIMARY KEY (`resourceid`,`resourcegroupid`),
   KEY `resourcegroupid` (`resourcegroupid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
@@ -1076,7 +1089,7 @@
   `resourcetypeid1` tinyint(3) unsigned NOT NULL default '13',
   `resourcegroupid2` smallint(5) unsigned NOT NULL default '0',
   `resourcetypeid2` tinyint(3) unsigned NOT NULL default '12',
-  PRIMARY KEY  (`resourcegroupid1`,`resourcegroupid2`),
+  PRIMARY KEY (`resourcegroupid1`,`resourcegroupid2`),
   KEY `resourcetypeid1` (`resourcetypeid1`),
   KEY `resourcetypeid2` (`resourcetypeid2`),
   KEY `resourcegroupid2` (`resourcegroupid2`)
@@ -1093,10 +1106,10 @@
   `resourcegroupid` smallint(5) unsigned NOT NULL default '0',
   `privnodeid` mediumint(8) unsigned NOT NULL default '0',
   `type` enum('block','cascade','available','administer','manageGroup','manageMapping') NOT NULL default 'block',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `resourcegroupid` (`resourcegroupid`,`privnodeid`,`type`),
   KEY `privnodeid` (`privnodeid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1107,9 +1120,9 @@
 CREATE TABLE IF NOT EXISTS `resourcetype` (
   `id` tinyint(5) unsigned NOT NULL auto_increment,
   `name` varchar(50) NOT NULL default '',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1121,10 +1134,10 @@
   `id` tinyint(3) unsigned NOT NULL auto_increment,
   `name` varchar(25) NOT NULL default '',
   `ownerid` mediumint(8) unsigned NOT NULL default '1',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`),
   KEY `ownerid` (`ownerid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1150,7 +1163,7 @@
   `imageid` smallint(5) unsigned NOT NULL,
   `imagerevisionid` mediumint(8) unsigned NOT NULL,
   `managementnodeid` smallint(5) unsigned NOT NULL,
-  `expires` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+  `expires` timestamp NOT NULL default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   `procid` varchar(255) NOT NULL,
   KEY `computerid` (`computerid`),
   KEY `imageid` (`imageid`),
@@ -1178,13 +1191,13 @@
   `admingroupid` smallint(5) unsigned default NULL,
   `logingroupid` smallint(5) unsigned default NULL,
   `monitored` tinyint(1) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   KEY `ownerid` (`ownerid`),
   UNIQUE KEY `name` (`name`),
   KEY `admingroupid` (`admingroupid`),
   KEY `logingroupid` (`logingroupid`),
   KEY `imageid` (`imageid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1202,12 +1215,12 @@
   `admingroupid` smallint(5) unsigned default NULL,
   `logingroupid` smallint(5) unsigned default NULL,
   `monitored` tinyint(1) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `requestid` (`requestid`),
   KEY `admingroupid` (`admingroupid`),
   KEY `logingroupid` (`logingroupid`),
   KEY `serverprofileid` (`serverprofileid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1221,8 +1234,8 @@
   `ts` datetime NOT NULL,
   `sessid` varchar(80) NOT NULL,
   `data` text NOT NULL,
-  PRIMARY KEY  (`id`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1240,11 +1253,11 @@
   `usermessage` text NOT NULL,
   `informhoursahead` smallint(5) unsigned NOT NULL,
   `allowreservations` tinyint(1) unsigned NOT NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   KEY `start` (`start`),
   KEY `end` (`end`),
   KEY `ownerid` (`ownerid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1255,9 +1268,9 @@
 CREATE TABLE IF NOT EXISTS `state` (
   `id` tinyint(3) unsigned NOT NULL auto_increment,
   `name` varchar(20) NOT NULL default '',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1297,7 +1310,7 @@
 -- 
 
 CREATE TABLE IF NOT EXISTS `sublog` (
-  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `id` int(10) unsigned NOT NULL auto_increment,
   `logid` int(10) unsigned NOT NULL default '0',
   `imageid` smallint(5) unsigned NOT NULL default '0',
   `imagerevisionid` mediumint(8) unsigned NOT NULL,
@@ -1352,12 +1365,12 @@
   `validated` tinyint(1) unsigned NOT NULL default '1',
   `usepublickeys` tinyint(1) unsigned NOT NULL default '0',
   `sshpublickeys` text,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `unityid` (`unityid`,`affiliationid`),
   UNIQUE KEY `uid` (`uid`),
   KEY `IMtypeid` (`IMtypeid`),
   KEY `affiliationid` (`affiliationid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1377,12 +1390,12 @@
   `totalmaxtime` mediumint(8) unsigned NOT NULL default '360',
   `maxextendtime` mediumint(8) unsigned NOT NULL default '60',
   `overlapResCount` smallint(5) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`,`affiliationid`),
   KEY `ownerid` (`ownerid`),
   KEY `editusergroupid` (`editusergroupid`),
   KEY `affiliationid` (`affiliationid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1393,7 +1406,7 @@
 CREATE TABLE IF NOT EXISTS `usergroupmembers` (
   `userid` mediumint(8) unsigned NOT NULL default '0',
   `usergroupid` smallint(5) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`userid`,`usergroupid`),
+  PRIMARY KEY (`userid`,`usergroupid`),
   KEY `usergroupid` (`usergroupid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
@@ -1435,12 +1448,12 @@
   `usergroupid` smallint(5) unsigned default NULL,
   `privnodeid` mediumint(8) unsigned NOT NULL default '0',
   `userprivtypeid` smallint(5) unsigned NOT NULL default '0',
-  PRIMARY KEY  (`id`,`privnodeid`,`userprivtypeid`),
+  PRIMARY KEY (`id`,`privnodeid`,`userprivtypeid`),
   UNIQUE KEY `userid` (`userid`,`privnodeid`,`userprivtypeid`),
   UNIQUE KEY `usergroupid` (`usergroupid`,`privnodeid`,`userprivtypeid`),
   KEY `privnodeid` (`privnodeid`),
   KEY `userprivtypeid` (`userprivtypeid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1451,9 +1464,9 @@
 CREATE TABLE IF NOT EXISTS `userprivtype` (
   `id` smallint(5) unsigned NOT NULL auto_increment,
   `name` varchar(50) NOT NULL default '',
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1468,7 +1481,7 @@
   `value` longtext NOT NULL,
   `setby` varchar(128) default NULL,
   `timestamp` datetime NOT NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
@@ -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`)
@@ -1497,10 +1510,10 @@
   `id` smallint(5) unsigned NOT NULL auto_increment,
   `computerid` smallint(5) unsigned NOT NULL,
   `vmprofileid` smallint(5) unsigned NOT NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `computerid_vmprofileid` (`computerid`,`vmprofileid`),
   KEY `vmprofileid` (`vmprofileid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1521,24 +1534,24 @@
   `vmpath` varchar(128) default NULL,
   `virtualswitch0` varchar(80) NOT NULL default 'VMnet0',
   `virtualswitch1` varchar(80) NOT NULL default 'VMnet2',
-  `virtualswitch2` varchar(80) NULL default NULL,
-  `virtualswitch3` varchar(80) NULL default NULL,
+  `virtualswitch2` varchar(80) default NULL,
+  `virtualswitch3` varchar(80) default NULL,
   `vmdisk` enum('dedicated','shared') NOT NULL default 'dedicated',
-  `username` varchar(80) NULL default NULL,
-  `password` varchar(256) NULL default NULL,
-  `secretid` smallint(5) unsigned NULL default NULL,
+  `username` varchar(80) default NULL,
+  `password` varchar(256) default NULL,
+  `secretid` smallint(5) unsigned default NULL,
   `eth0generated` tinyint(1) unsigned NOT NULL default '0',
   `eth1generated` tinyint(1) unsigned NOT NULL default '0',
-  `rsapub` text NULL default NULL,
-  `rsakey` varchar(256) NULL default NULL,
-  `encryptedpasswd` text NULL default NULL,
-  PRIMARY KEY  (`id`),
+  `rsapub` text default NULL,
+  `rsakey` varchar(256) default NULL,
+  `encryptedpasswd` text default NULL,
+  PRIMARY KEY (`id`),
   UNIQUE KEY `profilename` (`profilename`),
   KEY `imageid` (`imageid`),
   KEY `repositoryimagetypeid` (`repositoryimagetypeid`),
   KEY `datastoreimagetypeid` (`datastoreimagetypeid`),
   KEY `secretid` (`secretid`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -1549,9 +1562,9 @@
 CREATE TABLE IF NOT EXISTS `vmtype` (
   `id` tinyint(3) unsigned NOT NULL auto_increment,
   `name` varchar(30) NOT NULL,
-  PRIMARY KEY  (`id`),
+  PRIMARY KEY (`id`),
   UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 -- --------------------------------------------------------
 
@@ -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 d4eed6c..db59978 100755
--- a/vcl-install.sh
+++ b/vcl-install.sh
@@ -69,7 +69,7 @@
 eval set -- "$args"
 
 # ------------------------- variables -------------------------------
-VCL_VERSION=2.5
+VCL_VERSION=2.5.1
 DB_USERNAME=vcluser
 ADMIN_PASSWORD=
 
@@ -450,12 +450,12 @@
 	if [ $? -ne 0 ]; then generic_error "failed to download $ARCHIVE from $ARCHIVEURLPATH"; exit 1; fi
 }
 
-function validate_archive_sha1() {
-	echo "Downloading sha1 file for $VCL_VERSION..."
-	/bin/rm -f $ARCHIVE.sha1
-	wget -q $SIGPATH$ARCHIVE.sha1
+function validate_archive_sha512() {
+	echo "Downloading sha512 file for $VCL_VERSION..."
+	/bin/rm -f $ARCHIVE.sha512
+	wget -q $SIGPATH$ARCHIVE.sha512
 	echo "validating $ARCHIVE"
-	sha1sum -c $ARCHIVE.sha1
+	sha512sum -c $ARCHIVE.sha512
 	return $?
 }
 
@@ -487,19 +487,19 @@
 if [[ ! -f $ARCHIVE ]]; then
 	echo "Downloading VCL $VCL_VERSION..."
 	download_archive
-	validate_archive_sha1
+	validate_archive_sha512
 	if [ $? -ne 0 ]; then generic_error "failed to validate $ARCHIVE"; exit 1; fi;
 	validate_archive_gpg
 	if [ $? -ne 0 ]; then generic_error "failed to validate $ARCHIVE"; exit 1; fi;
 else
 	dir=`pwd`
 	echo "archive for $VCL_VERSION found at $dir/$ARCHIVE"
-	validate_archive_sha1
+	validate_archive_sha512
 	if [ $? -ne 0 ]; then
 		echo "failed to validate $ARCHIVE; downloading again..."
 		/bin/mv -f $ARCHIVE $ARCHIVE.old
 		download_archive
-		validate_archive_sha1
+		validate_archive_sha512
 		if [ $? -ne 0 ]; then generic_error "failed to validate $ARCHIVE"; exit 1; fi;
 		validate_archive_gpg
 		if [ $? -ne 0 ]; then generic_error "failed to validate $ARCHIVE"; exit 1; fi;
diff --git a/vcl-upgrade.sh b/vcl-upgrade.sh
index 4998fbf..a287323 100755
--- a/vcl-upgrade.sh
+++ b/vcl-upgrade.sh
@@ -62,7 +62,7 @@
 eval set -- "$args"
 
 # ------------------------- variables -------------------------------
-VCL_VERSION=2.5
+VCL_VERSION=2.5.1
 OLD_VERSION=""
 DB_NAME=vcl
 WEB_PATH=/var/www/html/vcl
@@ -300,12 +300,12 @@
 	if [ $? -ne 0 ]; then generic_error "failed to download $ARCHIVE from $ARCHIVEURLPATH"; exit 1; fi
 }
 
-function validate_archive_sha1() {
-	echo "Downloading sha1 file for $VCL_VERSION..."
-	/bin/rm -f $ARCHIVE.sha1
-	wget -q $SIGPATH$ARCHIVE.sha1
+function validate_archive_sha512() {
+	echo "Downloading sha512 file for $VCL_VERSION..."
+	/bin/rm -f $ARCHIVE.sha512
+	wget -q $SIGPATH$ARCHIVE.sha512
 	echo "validating $ARCHIVE"
-	sha1sum -c $ARCHIVE.sha1
+	sha512sum -c $ARCHIVE.sha512
 	return $?
 }
 
@@ -586,19 +586,19 @@
 if [[ ! -f $ARCHIVE ]]; then
 	echo "Downloading VCL $VCL_VERSION..."
 	download_archive
-	validate_archive_sha1
+	validate_archive_sha512
 	if [ $? -ne 0 ]; then generic_error "failed to validate $ARCHIVE"; exit 1; fi;
 	validate_archive_gpg
 	if [ $? -ne 0 ]; then generic_error "failed to validate $ARCHIVE"; exit 1; fi;
 else
 	dir=`pwd`
 	echo "archive for $VCL_VERSION found at $dir/$ARCHIVE"
-	validate_archive_sha1
+	validate_archive_sha512
 	if [ $? -ne 0 ]; then
 		echo "failed to validate $ARCHIVE; downloading again..."
 		/bin/mv -f $ARCHIVE $ARCHIVE.old
 		download_archive
-		validate_archive_sha1
+		validate_archive_sha512
 		if [ $? -ne 0 ]; then generic_error "failed to validate $ARCHIVE"; exit 1; fi;
 		validate_archive_gpg
 		if [ $? -ne 0 ]; then generic_error "failed to validate $ARCHIVE"; exit 1; fi;
diff --git a/web/.gitignore b/web/.gitignore
new file mode 100644
index 0000000..869a44c
--- /dev/null
+++ b/web/.gitignore
@@ -0,0 +1,13 @@
+.ht-inc/conf.php
+.ht-inc/cryptkey/cryptkeyid
+.ht-inc/cryptkey/private.pem
+.ht-inc/keys.pem
+.ht-inc/pubkey.pem
+.ht-inc/secrets.php
+.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..f86ebf7 100644
--- a/web/.ht-inc/addomain.php
+++ b/web/.ht-inc/addomain.php
@@ -119,6 +119,8 @@
 				return 'Domain DNS Name';
 			case 'dnsservers':
 				return 'DNS Server(s)';
+			case 'usedbhostnames':
+				return 'Use Database Hostnames';
 		}
 		return ucfirst($field);
 	}
@@ -204,7 +206,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 +223,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 +244,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 +351,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 +430,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 +482,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 +520,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 +530,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 +565,9 @@
 			}
 		}
 
+		if($return['usedbhostnames'] != 0 && $return['usedbhostnames'] != 1)
+			$return['usedbhostnames'] = 0;
+
 		if($return['error'])
 			$return['errormsg'] = implode('<br>', $errormsg);
 
@@ -586,7 +596,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 5c933aa..cb72534 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
@@ -75,23 +83,36 @@
 	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;
-   }
+	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;
+	}
 
-   $tmparr = explode('|', $tmp);
+	# $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
 		}
@@ -105,19 +126,61 @@
 		}
 	}
 
-   if($ts < time()) {
-      $AUTHERROR["code"] = 4;
-      $AUTHERROR["message"] = "Auth cookie has expired";
-      return NULL;
-   }
-   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;
-   }
+	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;
+	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 $authtype;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -351,120 +414,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
@@ -480,7 +429,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
@@ -503,6 +452,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
@@ -514,7 +481,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, "
@@ -524,8 +491,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']}");
@@ -539,7 +506,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;
@@ -559,8 +526,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, "
@@ -613,8 +580,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..3848ebe 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];
@@ -120,7 +257,7 @@
 function validateLDAPUser($type, $loginid) {
 	global $authMechs;
 	$auth = $authMechs[$type];
-	$savehdlr = set_error_handler(create_function('', ''));
+	$savehdlr = set_error_handler(function() {});
 	if(! ($fh = fsockopen($auth['server'], 636, $errno, $errstr, 5)))
 		return -1;
 	set_error_handler($savehdlr);
@@ -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..ed0fffa 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'];
@@ -1448,15 +1448,15 @@
 	$rt .= "title=\"" . i("Block Allocation Times") . "\">\n";
 	$rt .= "<h2>" . i("Block Allocation Times") . "</h2>\n";
 	$rt .= "<table dojoType=\"dojox.grid.DataGrid\" jsId=\"blockTimesGrid\" sortInfo=1 ";
-	$rt .= "style=\"width: 278px; height: 200px;\">\n";
+	$rt .= "style=\"width: 328px; height: 200px;\">\n";
 	$rt .= "<script type=\"dojo/method\" event=\"onStyleRow\" args=\"row\">\n";
 	$rt .= "blockTimeRowStyle(row);\n";
 	$rt .= "</script>\n";
 	$rt .= "<thead>\n";
 	$rt .= "<tr>\n";
-	$rt .= "<th field=\"start\" width=\"65px\" formatter=\"blockTimesGridDate\">" . i("Date") . "</th>\n";
-	$rt .= "<th field=\"start\" width=\"54px\" formatter=\"blockTimesGridStart\">" . i("Start") . "</th>\n";
-	$rt .= "<th field=\"end\" width=\"54px\" formatter=\"blockTimesGridEnd\">" . i("End") . "</th>\n";
+	$rt .= "<th field=\"start\" width=\"70px\" formatter=\"blockTimesGridDate\">" . i("Date") . "</th>\n";
+	$rt .= "<th field=\"start\" width=\"85px\" formatter=\"blockTimesGridStart\">" . i("Start") . "</th>\n";
+	$rt .= "<th field=\"end\" width=\"85px\" formatter=\"blockTimesGridEnd\">" . i("End") . "</th>\n";
 	$rt .= "<th field=\"delbtn\" width=\"60px\">" . i("Skip") . "</th>\n";
 	$rt .= "</tr>\n";
 	$rt .= "</thead>\n";
@@ -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'];
@@ -1741,17 +1741,17 @@
 	$rt .= i("Block Allocation Times") . "\">\n";
 	$rt .= "<h2>" . i("Block Allocation Times") . "</h2>\n";
 	$rt .= "<table dojoType=\"dojox.grid.DataGrid\" jsId=\"blockTimesGrid\" sortInfo=1 ";
-	$rt .= "style=\"width: 278px; height: 200px;\">\n";
+	$rt .= "style=\"width: 328px; height: 200px;\">\n";
 	$rt .= "<script type=\"dojo/method\" event=\"onStyleRow\" args=\"row\">\n";
 	$rt .= "blockTimeRowStyle(row);\n";
 	$rt .= "</script>\n";
 	$rt .= "<thead>\n";
 	$rt .= "<tr>\n";
-	$rt .= "<th field=\"start\" width=\"60px\" formatter=\"blockTimesGridDate\">";
+	$rt .= "<th field=\"start\" width=\"70px\" formatter=\"blockTimesGridDate\">";
 	$rt .= i("Date") . "</th>\n";
-	$rt .= "<th field=\"start\" width=\"54px\" formatter=\"blockTimesGridStart\">";
+	$rt .= "<th field=\"start\" width=\"85px\" formatter=\"blockTimesGridStart\">";
 	$rt .= i("Start") . "</th>\n";
-	$rt .= "<th field=\"end\" width=\"54px\" formatter=\"blockTimesGridEnd\">";
+	$rt .= "<th field=\"end\" width=\"85px\" formatter=\"blockTimesGridEnd\">";
 	$rt .= i("End") . "</th>\n";
 	$rt .= "<th field=\"delbtn\" width=\"60px\">" . i("Skip") . "</th>\n";
 	$rt .= "</tr>\n";
@@ -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;
@@ -3133,35 +3133,41 @@
 	if(! $err) {
 		if($type == 'list') {
 			$slots = processInputVar('slots', ARG_STRING);
-			$return['slots'] = explode(',', $slots);
+			if(! preg_match('/^(\d{8}\|\d{2}:\d{2}\|\d{2}:\d{2})(,(\d{8}\|\d{2}:\d{2}\|\d{2}:\d{2}))*$/', $slots)) {
+				$errmsg = i("Invalid time slot submitted.");
+				$err = 1;
+			}
 			$return['times'] = array();
-			$lastdate = array('day' => '', 'ts' => 0);
-			foreach($return['slots'] as $slot) {
-				$tmp = explode('|', $slot);
-				if(count($tmp) != 3) {
-					$errmsg = i("Invalid date/time submitted.");
-					$err = 1;
-					break;
-				}
-				$date = $tmp[0];
-				if(! $err) {
-					$datets = strtotime($date);
-					if($method != 'edit' && $datets < (time() - SECINDAY)) {
-						$errmsg = i("The date must be today or later.");
+			if(! $err) {
+				$return['slots'] = explode(',', $slots);
+				$lastdate = array('day' => '', 'ts' => 0);
+				foreach($return['slots'] as $slot) {
+					$tmp = explode('|', $slot);
+					if(count($tmp) != 3) {
+						$errmsg = i("Invalid date/time submitted.");
 						$err = 1;
 						break;
 					}
+					$date = $tmp[0];
+					if(! $err) {
+						$datets = strtotime($date);
+						if($method != 'edit' && $datets < (time() - SECINDAY)) {
+							$errmsg = i("The date must be today or later.");
+							$err = 1;
+							break;
+						}
+					}
+					$return['times'][] = "{$tmp[1]}|{$tmp[2]}";
+					if($datets > $lastdate['ts']) {
+						$lastdate['ts'] = $datets;
+						$lastdate['day'] = $date;
+					}
 				}
-				$return['times'][] = "{$tmp[1]}|{$tmp[2]}";
-				if($datets > $lastdate['ts']) {
-					$lastdate['ts'] = $datets;
-					$lastdate['day'] = $date;
+				if(! $err) {
+					$expirets = strtotime("{$lastdate['day']} 23:59:59");
+					$return['expiretime'] = unixToDatetime($expirets);
 				}
 			}
-			if(! $err) {
-				$expirets = strtotime("{$lastdate['day']} 23:59:59");
-				$return['expiretime'] = unixToDatetime($expirets);
-			}
 		}
 		if($type == 'weekly' || $type == 'monthly') {
 			$return['startdate'] = processInputVar('startdate', ARG_NUMERIC);
@@ -3347,7 +3353,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 +3376,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 +3460,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 +3511,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 +3530,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 +3556,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 +3572,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 +3702,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 +3749,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 +3776,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 +3823,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 +3875,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..d1f6ca6 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)) {
@@ -1757,6 +1757,11 @@
 		}
 		# add multiple
 		if($return['mode'] == 'add' && $addmode == 'multiple') {
+			# ensure % in hostname
+			if(! preg_match('/%/', $return['name'])) {
+				$return['error'] = 1;
+				$errormsg[] = "Name must contain % when adding multiple computers";
+			}
 			# startnum/endnum
 			if($return['startnum'] < 0 || $return['startnum'] > 255) {
 				$return['error'] = 1;
@@ -1781,7 +1786,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 +2054,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 +2104,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 +2145,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 +2175,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 +2204,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 +2382,7 @@
 	///
 	////////////////////////////////////////////////////////////////////////////////
 	function AJcanceltovmhostinuse() {
-		global $mysql_link_vcl;
+		global $mysqli_link_vcl;
 		$compid = getContinuationVar('compid');
 		$type = 'none';
 		$query = "DELETE FROM request "
@@ -2387,7 +2392,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 +2404,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 +2420,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 +2482,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 +2725,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 +2816,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 +3074,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 +3165,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 +3178,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 +3259,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 +3434,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 +3496,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 +3512,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 +3583,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 +3639,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 +3870,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 +4005,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 +4027,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
@@ -4280,27 +4285,33 @@
 
 		$query = "SELECT rs.computerid "
 		       . "FROM request rq, "
-		       .      "reservation rs "
+		       .      "reservation rs, "
+		       .      "state s "
 		       . "WHERE rs.requestid = rq.id AND "
+		       .       "rq.stateid = s.id AND "
 		       .       "rs.computerid IN ($allids) AND "
 		       .       "rq.start <= '$startcheckdt' AND "
-		       .       "rq.end > NOW()";
+		       .       "rq.end > NOW() AND "
+		       .       "s.name != 'complete'";
 		$qh = doQuery($query);
-		while($row = mysql_fetch_assoc($qh))
+		while($row = mysqli_fetch_assoc($qh))
 			$fails[] = $row['computerid'];
 
 		$nowids = array_diff($compids, $fails);
-		$allids = implode(',', $nowids);
-		$query = "UPDATE computer "
-		       . "SET provisioningid = $provisioningid "
-		       . "WHERE id in ($allids)";
-		doQuery($query);
+		if(! empty($nowids)) {
+			$allids = implode(',', $nowids);
+			$query = "UPDATE computer "
+			       . "SET provisioningid = $provisioningid "
+			       . "WHERE id in ($allids)";
+			doQuery($query);
+		}
 
 		$resources = getUserResources(array($this->restype . "Admin"), array("administer"));
 		$compdata = $resources[$this->restype];
 
+		$msg = '';
 		if(count($nowids)) {
-			$msg  = "The following computers had their Provisioning Engine set to $provname:<br><br>\n";
+			$msg  .= "The following computers had their Provisioning Engine set to $provname:<br><br>\n";
 			foreach($nowids as $compid)
 				$msg .= "{$compdata[$compid]}<br>\n";
 			$msg .= "<br>";
@@ -4454,7 +4465,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 +4810,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>";
@@ -4872,9 +4883,11 @@
 		       .        "i.prettyname AS image, "
 		       .        "ir.revision, "
 		       .        "c.hostname AS hostname, "
+		       .        "s.IPaddress, "
 		       .        "mn.hostname AS managementnode, "
 		       .        "l.ending, "
-		       .        "CONCAT(u.unityid, '@', a.name) AS username "
+		       .        "CONCAT(u.unityid, '@', a.name) AS username, "
+		       .        "l.requestid "
 		       . "FROM computer c "
 		       . "LEFT JOIN sublog s ON (c.id = s.computerid) "
 		       . "LEFT JOIN image i ON (s.imageid = i.id) "
@@ -4888,7 +4901,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>";
@@ -4907,6 +4920,8 @@
 				$msg .= "End: " . prettyDatetime($row['end'], 1) . "<br>";
 			$msg .= "Management Node: {$row['managementnode']}<br>";
 			$msg .= "Ending: {$row['ending']}<br>";
+			$msg .= "Request ID: {$row['requestid']}<br>";
+			$msg .= "IP Address: {$row['IPaddress']}<br>";
 			$msg .= "<hr>";
 			$data[] = array('name' => $row['hostname'], 'msg' => $msg);
 		}
@@ -5076,7 +5091,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 255991b..cff15a3 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",
@@ -176,9 +183,9 @@
 		$updateUserFuncArgs[$item['affiliationid']] = $key;
 	}
 	elseif($item['type'] == 'local') {
-		$affilValFunc[$item['affiliationid']] = create_function('', 'return 0;');
-		$addUserFunc[$item['affiliationid']] = create_function('', 'return NULL;');
-		$updateUserFunc[$item['affiliationid']] = create_function('', 'return NULL;');
+		$affilValFunc[$item['affiliationid']] = function() {return 0;};
+		$addUserFunc[$item['affiliationid']] = function() {return NULL;};
+		$updateUserFunc[$item['affiliationid']] = function() {return NULL;};
 	}
 }
 
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..9018c20 100644
--- a/web/.ht-inc/dashboard.php
+++ b/web/.ht-inc/dashboard.php
@@ -42,7 +42,7 @@
 
 	# -------- left column ---------
 	print "<div id=\"dashleft\">\n";
-	print addWidget('status', 'Current Status');
+	print addWidget('status', 'Current Status', '(Hover for description)');
 	print addWidget('topimages', 'Top 5 Images in Use', '(Reservations &lt; 24 hours long)');
 	print addWidget('toplongimages', 'Top 5 Long Term Images in Use', '(Reservations &gt; 24 hours long)');
 	print addWidget('toppastimages', 'Top 5 Images From Past Day', '(Reservations with a start<br>time within past 24 hours)');
@@ -168,10 +168,11 @@
 function getStatusData() {
 	$affilid = getDashboardAffilID();
 	$data = array();
-	$data[] = array('key' => 'Active Reservations', 'val' => 0);
-	$data[] = array('key' => 'Online Computers', 'val' => 0, 'tooltip' => 'Computers in states available, reserved,<br>reloading, inuse, or timeout');
-	$data[] = array('key' => 'In Use Computers', 'val' => 0, 'tooltip' => 'Computers in inuse state');
-	$data[] = array('key' => 'Failed Computers', 'val' => 0);
+	$data[0] = array('key' => 'Active Reservations', 'val' => 0, 'tooltip' => 'Reservations currently running');
+	$data[1] = array('key' => 'Active Short Reservations', 'val' => 0, 'tooltip' => 'Reservations with a duration < 24 hours');
+	$data[2] = array('key' => 'Online Computers', 'val' => 0, 'tooltip' => 'Computers in states available, reserved,<br>reloading, inuse, or timeout');
+	$data[3] = array('key' => 'In Use Computers', 'val' => 0, 'tooltip' => 'Computers in inuse state');
+	$data[4] = array('key' => 'Failed Computers', 'val' => 0);
 	$reloadid = getUserlistID('vclreload@Local');
 	if($affilid == 0) {
 		$query = "SELECT COUNT(id) "
@@ -193,23 +194,48 @@
 				 .       "rq.end > NOW()";
 	}
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_row($qh))
+	if($row = mysqli_fetch_row($qh))
 		$data[0]['val'] = $row[0];
 
+	if($affilid == 0) {
+		$query = "SELECT COUNT(id) "
+		       . "FROM request "
+		       . "WHERE userid != $reloadid AND "
+		       .       "stateid NOT IN (1, 5, 10, 12) AND "
+		       .       "start < NOW() AND "
+				 .       "end > NOW() AND "
+		       .       "(UNIX_TIMESTAMP(end) - UNIX_TIMESTAMP(start)) < 86400";
+	}
+	else {
+		$query = "SELECT COUNT(rq.id) "
+		       . "FROM request rq, "
+		       .      "user u "
+		       . "WHERE rq.userid != $reloadid AND "
+		       .       "rq.userid = u.id AND "
+		       .       "u.affiliationid = $affilid AND "
+		       .       "rq.stateid NOT IN (1, 5, 10, 12) AND "
+		       .       "rq.start < NOW() AND "
+				 .       "rq.end > NOW() AND "
+		       .       "(UNIX_TIMESTAMP(end) - UNIX_TIMESTAMP(start)) < 86400";
+	}
+	$qh = doQuery($query, 101);
+	if($row = mysqli_fetch_row($qh))
+		$data[1]['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))
-		$data[1]['val'] = $row[0];
+	if($row = mysqli_fetch_row($qh))
+		$data[2]['val'] = $row[0];
 
 	$query = "SELECT COUNT(id) FROM computer WHERE stateid = 8";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_row($qh))
-		$data[2]['val'] = $row[0];
+	if($row = mysqli_fetch_row($qh))
+		$data[3]['val'] = $row[0];
 
 	$query = "SELECT COUNT(id) FROM computer WHERE stateid = 5";
 	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_row($qh))
-		$data[3]['val'] = $row[0];
+	if($row = mysqli_fetch_row($qh))
+		$data[4]['val'] = $row[0];
 	return $data;
 }
 
@@ -259,7 +285,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 +336,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 +386,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 +433,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 +484,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 +548,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 +609,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 +638,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 +668,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));
@@ -674,6 +700,7 @@
 function getNewReservationData() {
 	$affilid = getDashboardAffilID();
 	$query = "SELECT c.hostname AS computer, "
+	       .        "h.hostname AS vmhost, "
 	       .        "i.prettyname AS image, "
 	       .        "rq.id, "
 	       .        "UNIX_TIMESTAMP(rq.start) AS start, "
@@ -684,6 +711,8 @@
 	       . "FROM request rq "
 	       . "LEFT JOIN reservation rs ON (rs.requestid = rq.id) "
 	       . "LEFT JOIN computer c ON (c.id = rs.computerid) "
+	       . "LEFT JOIN vmhost vh ON (c.vmhostid = vh.id) "
+	       . "LEFT JOIN computer h ON (h.id = vh.computerid) "
 	       . "LEFT JOIN image i ON (i.id = rs.imageid) "
 	       . "LEFT JOIN OS o ON (o.id = i.OSid) "
 	       . "LEFT JOIN state s1 ON (s1.id = rq.stateid) "
@@ -700,9 +729,11 @@
 	$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];
+		$tmp = explode('.', $row['vmhost']);
+		$row['vmhost'] = $tmp[0];
 		$row['start'] = date('D h:i', $row['start']);
 		$tmp = explode('.', $row['managementnode']);
 		$row['managementnode'] = $tmp[0];
@@ -758,7 +789,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 +847,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/doxyfile.xmlrpc b/web/.ht-inc/doxyfile.xmlrpc
index 4880847..f8519e5 100644
--- a/web/.ht-inc/doxyfile.xmlrpc
+++ b/web/.ht-inc/doxyfile.xmlrpc
@@ -1,5 +1,3 @@
-# Doxyfile 1.4.7
-
 #  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.
@@ -14,10 +12,6 @@
 #  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.
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
 PROJECT_NAME           = "VCL XML RPC"
 PROJECT_NUMBER         = 
 OUTPUT_DIRECTORY       = xmlrpcdocs/
@@ -53,9 +47,6 @@
 BUILTIN_STL_SUPPORT    = NO
 DISTRIBUTE_GROUP_DOC   = NO
 SUBGROUPING            = NO
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
 EXTRACT_ALL            = NO
 EXTRACT_PRIVATE        = NO
 EXTRACT_STATIC         = NO
@@ -81,9 +72,6 @@
 MAX_INITIALIZER_LINES  = 30
 SHOW_USED_FILES        = NO
 FILE_VERSION_FILTER    = 
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
 QUIET                  = NO
 WARNINGS               = YES
 WARN_IF_UNDOCUMENTED   = YES
@@ -91,9 +79,6 @@
 WARN_NO_PARAMDOC       = NO
 WARN_FORMAT            = "$file:$line: $text"
 WARN_LOGFILE           = 
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
 INPUT                  = .
 FILE_PATTERNS          = xmlrpcWrappers.php
 RECURSIVE              = NO
@@ -107,9 +92,6 @@
 INPUT_FILTER           = 
 FILTER_PATTERNS        = 
 FILTER_SOURCE_FILES    = NO
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
 SOURCE_BROWSER         = NO
 INLINE_SOURCES         = NO
 STRIP_CODE_COMMENTS    = YES
@@ -118,15 +100,9 @@
 REFERENCES_LINK_SOURCE = YES
 USE_HTAGS              = NO
 VERBATIM_HEADERS       = NO
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
 ALPHABETICAL_INDEX     = NO
 COLS_IN_ALPHA_INDEX    = 5
 IGNORE_PREFIX          = 
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
 GENERATE_HTML          = YES
 HTML_OUTPUT            = .
 HTML_FILE_EXTENSION    = .html
@@ -143,9 +119,6 @@
 ENUM_VALUES_PER_LINE   = 4
 GENERATE_TREEVIEW      = NO
 TREEVIEW_WIDTH         = 250
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
 GENERATE_LATEX         = NO
 LATEX_OUTPUT           = latex
 LATEX_CMD_NAME         = latex
@@ -158,44 +131,26 @@
 USE_PDFLATEX           = NO
 LATEX_BATCHMODE        = NO
 LATEX_HIDE_INDICES     = NO
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
 GENERATE_RTF           = NO
 RTF_OUTPUT             = rtf
 COMPACT_RTF            = NO
 RTF_HYPERLINKS         = NO
 RTF_STYLESHEET_FILE    = 
 RTF_EXTENSIONS_FILE    = 
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
 GENERATE_MAN           = NO
 MAN_OUTPUT             = man
 MAN_EXTENSION          = .3
 MAN_LINKS              = NO
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
 GENERATE_XML           = NO
 XML_OUTPUT             = xml
 XML_SCHEMA             = 
 XML_DTD                = 
 XML_PROGRAMLISTING     = YES
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
 GENERATE_AUTOGEN_DEF   = NO
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
 GENERATE_PERLMOD       = NO
 PERLMOD_LATEX          = NO
 PERLMOD_PRETTY         = YES
 PERLMOD_MAKEVAR_PREFIX = 
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
-#---------------------------------------------------------------------------
 ENABLE_PREPROCESSING   = YES
 MACRO_EXPANSION        = NO
 EXPAND_ONLY_PREDEF     = NO
@@ -205,17 +160,11 @@
 PREDEFINED             = 
 EXPAND_AS_DEFINED      = 
 SKIP_FUNCTION_MACROS   = YES
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references   
-#---------------------------------------------------------------------------
 TAGFILES               = 
 GENERATE_TAGFILE       = 
 ALLEXTERNALS           = NO
 EXTERNAL_GROUPS        = YES
 PERL_PATH              = /usr/bin/perl
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
-#---------------------------------------------------------------------------
 CLASS_DIAGRAMS         = YES
 HIDE_UNDOC_RELATIONS   = YES
 HAVE_DOT               = NO
@@ -238,7 +187,4 @@
 DOT_MULTI_TARGETS      = NO
 GENERATE_LEGEND        = YES
 DOT_CLEANUP            = YES
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine   
-#---------------------------------------------------------------------------
 SEARCHENGINE           = NO
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..b038d97 100644
--- a/web/.ht-inc/help.php
+++ b/web/.ht-inc/help.php
@@ -130,7 +130,7 @@
 		$testname = stripslashes($name);
 	if(! preg_match('/^([-A-Za-z \']{1,} [-A-Za-z \']{2,})*$/', $testname)) {
 		$submitErr |= NAMEERR;
-		$submitErrMsg[NAMEERR] = "Name can only contain letters, spaces, apostrophes ('), and dashes (-)";
+		$submitErrMsg[NAMEERR] = "Name can only contain letters, spaces, apostrophes ('), and dashes (-). Both first and last name must be specified.";
 	}
 	if(! preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/i',
 	   $email)) {
@@ -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;
@@ -186,9 +186,9 @@
 	$recentrequests = "";
 	foreach($requests as $request) {
 		$thisstart = str_replace('&nbsp;', ' ', 
-				prettyDatetime($request["start"]));
+				prettyDatetime($request["start"], 0, 1));
 		$thisend = str_replace('&nbsp;', ' ', 
-				prettyDatetime($request["end"]));
+				prettyDatetime($request["end"], 0, 1));
 		$recentrequests .= "Image: {$request["prettyimage"]}\n"
 		                .  "Computer: {$computers[$request["computerid"]]["hostname"]}\n"
 		                .  "Start: $thisstart\n"
@@ -202,16 +202,79 @@
 		$message .= "User has no recent reservations\n";
 	}
 
+	# login history
+	$query = "SELECT authmech, "
+	       .        "timestamp, "
+	       .        "passfail, "
+	       .        "remoteIP, "
+	       .        "code "
+	       . "FROM loginlog "
+	       . "WHERE (user = '{$user['unityid']}' OR "
+	       .       "user = '{$user['unityid']}@{$user['affiliation']}') AND "
+	       .       "affiliationid = {$user['affiliationid']} "
+	       . "ORDER BY timestamp DESC "
+	       . "LIMIT 5";
+	$methodlen = strlen(i('Authentication Method'));
+	$timelen = strlen(i('Timestamp'));
+	$resultlen = strlen(i('Result'));
+	$remoteiplen = strlen(i('Remote IP'));
+	$extralen = strlen(i('Extra Info'));
+	if(strlen(i('Pass')) > $resultlen)
+		$resultlen = strlen(i('Pass'));
+	if(strlen(i('Fail')) > $resultlen)
+		$resultlen = strlen(i('Fail'));
+	$qh = doQuery($query);
+	$logins = array();
+	while($row = mysql_fetch_assoc($qh)) {
+		$tmp = prettyDatetime($row['timestamp'], 1, 1);
+		$row['timestamp'] = str_replace('&nbsp;', ' ', $tmp);
+		if($row['passfail'])
+			$row['passfail'] = 'Pass';
+		else
+			$row['passfail'] = 'Fail';
+		if(strlen($row['authmech']) > $methodlen)
+			$methodlen = strlen($row['authmech']);
+		if(strlen($row['timestamp']) > $timelen)
+			$timelen = strlen($row['timestamp']);
+		if(strlen($row['remoteIP']) > $remoteiplen)
+			$remoteiplen = strlen($row['remoteIP']);
+		if(strlen($row['code']) > $extralen)
+			$extralen = strlen($row['code']);
+		$logins[] = $row;
+	}
+	if(count($logins)) {
+		$logins = array_reverse($logins);
+		$message .= "-----------------------------------------------\n";
+		$message .= "User's Login History (up to last 5 attempts):\n\n";
+		$message .= sprintf("%-{$methodlen}s | ", i('Authentication Method'));
+		$message .= sprintf("%-{$timelen}s | ", i('Timestamp'));
+		$message .= sprintf("%-{$resultlen}s | ", i('Result'));
+		$message .= sprintf("%-{$remoteiplen}s | ", i('Remote IP'));
+		$message .= sprintf("%-{$extralen}s\n", i('Extra Info'));
+		foreach($logins as $login) {
+			$message .= sprintf("%-{$methodlen}s | ", $login['authmech']);
+			$message .= sprintf("%-{$timelen}s | ", $login['timestamp']);
+			$message .= sprintf("%-{$resultlen}s | ", $login['passfail']);
+			$message .= sprintf("%-{$remoteiplen}s | ", $login['remoteIP']);
+			$message .= sprintf("%-{$extralen}s\n", $login['code']);
+		}
+	}
+	if(isset($_SERVER['HTTP_USER_AGENT'])) {
+		$message .= "-----------------------------------------------\n";
+		$message .= "User agent: {$_SERVER['HTTP_USER_AGENT']}\n";
+	}
+
 	$indrupal = getContinuationVar('indrupal', 0);
 	if(! $indrupal)
 		print "<H2>VCL Help</H2>\n";
 	$mailParams = "-f" . ENVELOPESENDER;
 	if(get_magic_quotes_gpc())
 		$summary = stripslashes($summary);
-	if(! mail(HELPEMAIL, "$summary", $message,
+	$helpemail = getHelpEmail($user['affiliationid']);
+	if(! mail($helpemail, "$summary", $message,
 	   "From: $from\r\nReply-To: $email\r\n", $mailParams)){
 		print "The Server was unable to send mail at this time. Please e-mail ";
-		print "<a href=\"mailto:" . HELPEMAIL . "\">" . HELPEMAIL . "</a> for ";
+		print "<a href=\"mailto:$helpemail\">$helpemail</a> for ";
 		print "help with your problem.";
 	}
 	else {
@@ -220,4 +283,28 @@
 	}
 }
 
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getHelpEmail($affil)
+///
+/// \param $affil - id or name of an affiliation
+///
+/// \return email address for $affil or HELPEMAIL from conf.php if $affil does
+/// not have a specific email address set
+///
+/// \brief gets the email address for support for a $affil
+///
+////////////////////////////////////////////////////////////////////////////////
+function getHelpEmail($affil) {
+	if(is_numeric($affil))
+		$field = 'id';
+	else
+		$field = 'name';
+	$query = "SELECT helpaddress FROM affiliation WHERE $field = '$affil'";
+	$qh = doQuery($query);
+	if($row = mysql_fetch_assoc($qh))
+		if($row['helpaddress'] != '')
+			return $row['helpaddress'];
+	return HELPEMAIL;
+}
 ?>
diff --git a/web/.ht-inc/image.php b/web/.ht-inc/image.php
index 9447aea..329cec8 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);
@@ -365,34 +366,34 @@
 		$h .= "<legend>" . i("Image Description") . "</legend>\n";
 		$h .= i("Description of image (required - users will see this on the <strong>New Reservations</strong> page):");
 		$h .= "<br>\n";
-		$h .= "<textarea dojoType=\"dijit.form.Textarea\" id=\"description\" ";
-		$h .= "style=\"width: 400px; text-align: left;\"></textarea>\n";
+		$h .= "<textarea dojoType=\"dijit.form.Textarea\" id=\"description\">";
+		$h .= "</textarea>\n";
 		$h .= "</fieldset>\n";
 		# usage notes
 		$h .= "<fieldset>\n";
 		$h .= "<legend>" . i("Usage Notes") . "</legend>\n";
 		$msg = i("Optional notes to the user explaining how to use the image (users will see this on the <strong>Connect!</strong> page):");
 		$h .= preg_replace("/(.{1,100}([ \n]|$))/", '\1<br>', $msg);
-		$h .= "<textarea dojoType=\"dijit.form.Textarea\" id=\"usage\" ";
-		$h .= "style=\"width: 400px; text-align: left;\"></textarea>\n";
+		$h .= "<textarea dojoType=\"dijit.form.Textarea\" id=\"usage\">";
+		$h .= "</textarea>\n";
 		$h .= "</fieldset>\n";
 		if($add) {
 			$h .= "<fieldset>\n";
 			$h .= "<legend>" . i("Revision Comments") . "</legend>\n";
 			$msg = i("Notes for yourself and other admins about how the image was setup/installed. These are optional and are not visible to end users.");
 			$h .= preg_replace("/(.{1,80}([ \n]|$))/", '\1<br>', $msg);
-			$h .= "<textarea dojoType=\"dijit.form.Textarea\" id=\"imgcomments\" ";
-			$h .= "style=\"width: 400px; text-align: left;\"></textarea>";
+			$h .= "<textarea dojoType=\"dijit.form.Textarea\" id=\"imgcomments\">";
+			$h .= "</textarea>";
 			$h .= "</fieldset>\n";
 		}
 		# advanced options
 		$h .= "<div dojoType=\"dijit.TitlePane\" title=\"";
 		$h .= i("Advanced Options - leave default values unless you really know what you are doing (click to expand)");
-		$h .= "\" open=\"false\" style=\"width: 460px\" id=\"advancedoptions\" ";
+		$h .= "\" open=\"false\" id=\"advancedoptions\" ";
 		$h .= "onShow=\"delayedEditResize();\" onHide=\"delayedEditResize();\">\n";
 		# RAM
 		$extra = array('smallDelta' => 256, 'largeDelta' => 1024);
-		$h .= labeledFormItem('ram', i('Required RAM'), 'spinner', '{min:512, max:8388607}',
+		$h .= labeledFormItem('ram', i('Required RAM') . ' (MB)', 'spinner', '{min:512, max:8388607}',
 		                      1, 1024, '', '', $extra);
 		# cores
 		$extra = array('smallDelta' => 1, 'largeDelta' => 2);
@@ -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, 0);
 		$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;
@@ -1753,7 +1767,7 @@
 			$extraaddomainid = getContinuationVar('extraaddomainid', 0);
 			$extraaddomainou = getContinuationVar('extraaddomainou', '');
 			if(! array_key_exists($return['addomainid'], $vals) &&
-			   $return['addomainid'] != $extraaddomainid) {
+			   $return['addomainid'] !== $extraaddomainid) {
 				$return['error'] = 1;
 				$errormsg[] = i("Invalid AD Domain submitted");
 			}
@@ -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..714b910 100644
--- a/web/.ht-inc/privileges.php
+++ b/web/.ht-inc/privileges.php
@@ -36,8 +36,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 function viewNodes() {
 	global $user;
-	if(! empty($_COOKIE["VCLACTIVENODE"]) &&
-		nodeExists($_COOKIE['VCLACTIVENODE']))
+	if(isset($_COOKIE["VCLACTIVENODE"]) &&
+	   is_numeric($_COOKIE['VCLACTIVENODE']) &&
+	   $_COOKIE['VCLACTIVENODE'] > 0 &&
+	   $_COOKIE['VCLACTIVENODE'] < 16777216 &&
+	   nodeExists($_COOKIE['VCLACTIVENODE']))
 		$activeNode = $_COOKIE["VCLACTIVENODE"];
 	else {
 		$topNodes = getChildNodes();
@@ -256,7 +259,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 +968,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 +1128,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 +1186,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 +1201,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 +1231,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 +1316,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 +1375,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 +1497,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 +1520,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 +1531,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 +1541,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'];
 		}
@@ -1629,6 +1632,12 @@
 		print "      Total: {$times['total']}<br>\n";
 		print "  </TR>\n";
 
+		$maxconcurrent = getMaxOverlap($userdata['id']);
+		print "  <TR>\n";
+		print "    <TH align=right>Max Overlapping Reservations:</TH>\n";
+		print "    <TD>$maxconcurrent</TD>\n";
+		print "  </TR>\n";
+
 		print "  <TR>\n";
 		print "    <TH align=right style=\"vertical-align: top\">Privileges (found somewhere in the tree):</TH>\n";
 		print "    <TD>\n";
@@ -1659,11 +1668,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 +1708,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";
@@ -1724,6 +1733,30 @@
 		}
 		print "</div>\n";
 
+		# owned images
+		$ownedimages = array();
+		$query = "SELECT prettyname "
+		       . "FROM image "
+		       . "WHERE ownerid = {$userdata['id']} AND "
+		       .       "deleted = 0 "
+		       . "ORDER BY prettyname";
+		$qh = doQuery($query);
+		while($row = mysqli_fetch_row($qh))
+			$ownedimages[] = $row[0];
+		print "<table>\n";
+		print "  <tr>\n";
+		print "    <th style=\"vertical-align: top;\">Images Owned by User:<th>\n";
+		print "    <td>\n";
+		if(count($ownedimages)) {
+			foreach($ownedimages as $image)
+				print "      $image<br>\n";
+		}
+		else
+			print "      None\n";
+		print "    </td>\n";
+		print "  </tr>\n";
+		print "</table>\n";
+
 		# image access
 		print "<table>\n";
 		print "  <tr>\n";
@@ -1749,7 +1782,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 +1847,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 +1957,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 +2087,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 +2189,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 +2477,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 +2653,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 +2672,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 +2752,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 +2779,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 +2799,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 +2882,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 +2921,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 +2972,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 +3000,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 +3038,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 +3068,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 9d8d8ce..c836668 100644
--- a/web/.ht-inc/requests.php
+++ b/web/.ht-inc/requests.php
@@ -276,12 +276,14 @@
 					$text .= getViewRequestHTMLitem('openmoreoptions');
 					$text .= getViewRequestHTMLitem('editoption', $editcont);
 					if(array_key_exists($imageid, $resources['image']) && ! $cluster &&            # imageAdmin access, not a cluster,
+					   $requests[$i]['OSinstalltype'] != 'none' &&
 					   ($requests[$i]['currstateid'] == 8 || $requests[$i]['laststateid'] == 8)) { # reservation has been in inuse state
 						$text .= getViewRequestHTMLitem('endcreateoption', $imgcont);
 					}
 					/*else
 						$text .= getViewRequestHTMLitem('endcreateoptiondisable');*/
 					if(array_key_exists($imageid, $resources['image']) && ! $cluster &&
+					   $requests[$i]['OSinstalltype'] != 'none' &&
 					   $requests[$i]['server'] && ($requests[$i]['currstateid'] == 8 ||
 						($requests[$i]['currstateid'] == 14 && $requests[$i]['laststateid'] == 8))) {
 						$chkcdata = $cdata;
@@ -291,7 +293,8 @@
 					}
 					elseif($requests[$i]['server'] && $requests[$i]['currstateid'] == 24)
 						$text .= getViewRequestHTMLitem('checkpointoptiondisable');
-					if($requests[$i]['currstateid'] == 8 ||
+					if((! $cluster && $requests[$i]['OSinstalltype'] != 'none' &&
+					   $requests[$i]['currstateid'] == 8) ||
 					   (! $cluster &&
 					   $requests[$i]['OSinstalltype'] != 'none' &&
 					   $requests[$i]['currstateid'] != 3 &&
@@ -380,12 +383,12 @@
 			if(checkUserHasPerm('View Debug Information')) {
 				if(! is_null($requests[$i]['vmhostid'])) {
 					$query = "SELECT c.hostname "
-					       . "FROM computer c, " 
+					       . "FROM computer c, "
 					       .      "vmhost v "
 					       . "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']}\" ";
@@ -1329,7 +1332,7 @@
 						$subowner = 1;
 				}
 			}
-			if($subowner || 
+			if($subowner ||
 			   (array_key_exists($id, $imagedata) &&
 			   count($imagedata[$id]['imagerevision']) > 1 &&
 			   ($imagedata[$id]['ownerid'] == $user['id'] ||
@@ -1339,7 +1342,7 @@
 			}
 		}
 	}
-	if(in_array('serverCheckOut', $user['privileges']) && 
+	if(in_array('serverCheckOut', $user['privileges']) &&
 	   count($checkout['image'])) {
 		$serveraccess = 1;
 		/*$extraimages = getServerProfileImages($user['id']);
@@ -1369,7 +1372,7 @@
 							$subowner = 1;
 					}
 				}
-				if($subowner || 
+				if($subowner ||
 				   (array_key_exists($id, $imagedata) &&
 				   count($imagedata[$id]['imagerevision']) > 1 &&
 				   ($imagedata[$id]['ownerid'] == $user['id'] ||
@@ -1884,7 +1887,7 @@
 			$start = unixFloor15($now);
 		if($type == 'basic' || $type == 'imaging') {
 			# compute maxstart based on 11:45 pm on start day
-			$tmp = $now + DAYSAHEAD * SECINDAY; 
+			$tmp = $now + DAYSAHEAD * SECINDAY;
 			$maxstart = mktime(23, 45, 0, date('n', $tmp), date('j', $tmp), date('Y', $tmp));
 			if($start > $maxstart)
 				return;
@@ -1986,7 +1989,7 @@
 	$rc = isAvailable($images, $imageid, $imagerevisionid, $start, $end, 0, 0, 0, 0, $imaging, $fixedIP);
 	if($rc < 1) {
 		$cdata = array('now' => 0,
-		               'start' => $start, 
+		               'start' => $start,
 		               'end' => $end,
 		               'server' => 0,
 		               'imageid' => $imageid);
@@ -2093,6 +2096,45 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
+/// \fn AJfetchRouterDNS()
+///
+/// \brief get router and dns information for a given IP address
+///
+////////////////////////////////////////////////////////////////////////////////
+function AJfetchRouterDNS() {
+	$data = array('status' => 'none');
+	$page = processInputVar('page', ARG_STRING);
+	if($page != 'deploy') {
+		sendJSON($data);
+		return;
+	}
+	$ipaddr = processInputVar('ipaddr', ARG_STRING);
+	# validate fixed IP address
+	if(! validateIPv4addr($ipaddr)) {
+		sendJSON($data);
+		return;
+	}
+	# validate netmask
+	$netmask = processInputVar('netmask', ARG_STRING);
+	$bnetmask = ip2long($netmask);
+	if(! preg_match('/^[1]+0[^1]+$/', sprintf('%032b', $bnetmask))) {
+		sendJSON($data);
+		return;
+	}
+	$network = ip2long($ipaddr) & $bnetmask;
+	$availnets = getVariable('fixedIPavailnetworks', array());
+	$key = long2ip($network) . "/$netmask";
+	if(array_key_exists($key, $availnets)) {
+		$data = array('status' => 'success',
+		              'page' => $page,
+		              'router' => $availnets[$key]['router'],
+		              'dns' => implode(',', $availnets[$key]['dns']));
+	}
+	sendJSON($data);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
 /// \fn AJshowRequestSuggestedTimes()
 ///
 /// \brief builds html to display list of available times the selected image
@@ -2359,7 +2401,8 @@
 		return;
 	}
 	elseif($availablerc == -3) {
-		$msg = i("The IP or MAC address you specified overlaps with another reservation using the same IP or MAC address you specified. Please use a different IP or MAC or select a different time to deploy the server.");
+		#$msg = i("The IP or MAC address you specified overlaps with another reservation using the same IP or MAC address you specified. Please use a different IP or MAC or select a different time to deploy the server.");
+		$msg = i("The IP address you specified overlaps with another reservation using the same IP address. Please use a different IP address or select a different time to deploy the server.");
 		$data = array('err' => 1,
 		              'errmsg' => $msg);
 		sendJSON($data);
@@ -2410,7 +2453,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 +2515,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'];
@@ -2488,7 +2531,7 @@
 		}
 	}
 	$qbase = "INSERT INTO configinstance "
-	       .        "(reservationid, " 
+	       .        "(reservationid, "
 	       .        "configid, "
 	       .        "configmapid, "
 	       .        "configinstancestatusid) "
@@ -2528,7 +2571,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);
@@ -2706,8 +2749,8 @@
 
 	if($request['currstateid'] == 11 ||
 	   ($request['currstateid'] == 12 && $request['laststateid'] == 11))
-		return "<br><span class=\"rederrormsg\">" . 
-		       i("The selected reservation has timed out and is no longer available.") . 
+		return "<br><span class=\"rederrormsg\">" .
+		       i("The selected reservation has timed out and is no longer available.") .
 		       "</span>";
 
 	if($request['imageid'] == $request['compimageid'])
@@ -2781,7 +2824,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 +2908,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'];
@@ -2954,7 +2997,7 @@
 	print "  </TR>\n";
 	print "  <TR>\n";
 	print "    <TH align=right>Start&nbsp;Time:</TH>\n";
-	if(datetimeToUnix($request["start"]) < 
+	if(datetimeToUnix($request["start"]) <
 	   datetimeToUnix($request["daterequested"])) {
 		print "    <TD>" . prettyDatetime($request["daterequested"]) . "</TD>\n";
 	}
@@ -3092,7 +3135,7 @@
 	$request = getRequestInfo($requestid, 1);
 	# check to see if reservation exists
 	if(is_null($request) || $request['stateid'] == 11 || $request['stateid'] == 12 ||
-	   ($request['stateid'] == 14 && 
+	   ($request['stateid'] == 14 &&
 	   ($request['laststateid'] == 11 || $request['laststateid'] == 12))) {
 		sendJSON(array('status' => 'resgone'));
 		return;
@@ -3208,14 +3251,14 @@
 	if($unixstart > $now) {
 		$tzunixstart = $unixstart + ($_SESSION['persistdata']['tzoffset'] * 60);
 		$cdata['modifystart'] = 1;
-		$txt  = i("Modify reservation for") . " <b>{$request['reservations'][0]['prettyimage']}</b> "; 
+		$txt  = i("Modify reservation for") . " <b>{$request['reservations'][0]['prettyimage']}</b> ";
 		$txt .= i("starting") . " " . prettyDatetime($request["start"]) . ": <br>";
 		$h .= preg_replace("/(.{1,60}([ \n]|$))/", '\1<br>', $txt);
 		$days = array();
 		$startday = date('l', $tzunixstart);
 		$cur = time() + ($_SESSION['persistdata']['tzoffset'] * 60);
-		for($end = $cur + DAYSAHEAD * SECINDAY; 
-		    $cur < $end; 
+		for($end = $cur + DAYSAHEAD * SECINDAY;
+		    $cur < $end;
 		    $cur += SECINDAY) {
 			$index = date('Ymd', $cur);
 			$days[$index] = date('l', $cur);
@@ -3353,8 +3396,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)) {
@@ -3367,13 +3414,13 @@
 	// if started, only allow end to be modified
 	# check for following reservations
 	$timeToNext = timeToNextReservation($request);
-	# check for 30 minutes because need 15 minute buffer and min can 
+	# check for 30 minutes because need 15 minute buffer and min can
 	# extend by is 15 min
 	if($timeToNext < 30) {
 		$movedall = 1;
 		$lockedall = 1;
 		if(count($request['reservations']) > 1) {
-			# get semaphore on each existing node in cluster so that nothing 
+			# get semaphore on each existing node in cluster so that nothing
 			# can get moved to the nodes during this process
 
 			$semimageid = getImageId('noimage');
@@ -3410,6 +3457,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 +3784,7 @@
 			return;
 		}
 		if($servername != $request['servername']) {
-			$servername = mysql_real_escape_string($servername);
+			$servername = vcl_mysql_escape_string($servername);
 			$updateservername = 1;
 		}
 	}
@@ -3826,9 +3878,9 @@
 	$rc = isAvailable($images, $imageid, $revisions, $startts,
 	                  $endts, 1, $requestid, 0, 0, 0, $ip, $mac);
 	$data = array();
-	if($rc < 1) { 
+	if($rc < 1) {
 		$cdata = array('now' => 0,
-		               'start' => $startts, 
+		               'start' => $startts,
 		               'end' => $endts,
 		               'server' => $allowindefiniteend,
 		               'imageid' => $imageid,
@@ -3850,7 +3902,8 @@
 			$msgip = " ($ip)";
 		if(! empty($mac))
 			$msgmac = " ($mac)";
-		$h .= sprintf(i("The reserved IP (%s) or MAC address (%s) conflicts with another reservation using the same IP or MAC address. Please select a different time to use the image."), $msgip, $msgmac);
+		#$h .= sprintf(i("The reserved IP (%s) or MAC address (%s) conflicts with another reservation using the same IP or MAC address. Please select a different time to use the image."), $msgip, $msgmac);
+		$h .= sprintf(i("The reserved IP address (%s) conflicts with another reservation using the same IP address. Please select a different time to use the image."), $msgip);
 		$h = preg_replace("/(.{1,60}([ \n]|$))/", '\1<br>', $h);
 		$cdata = getContinuationVar();
 		$cont = addContinuationsEntry('AJsubmitEditRequest', $cdata, SECINDAY, 1, 0);
@@ -3936,7 +3989,7 @@
 		return;
 	}
 	if($request['stateid'] == 11 || $request['stateid'] == 12 ||
-	   ($request['stateid'] == 14 && 
+	   ($request['stateid'] == 14 &&
 	   ($request['laststateid'] == 11 || $request['laststateid'] == 12))) {
 		$data = array('error' => 1,
 		              'refresh' => 1,
@@ -4132,7 +4185,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']}");
@@ -4160,7 +4213,7 @@
 	$requestid = getContinuationVar('requestid');
 	$reqdata = getRequestInfo($requestid, 1);
 	if(is_null($reqdata) || $reqdata['stateid'] == 11 || $reqdata['stateid'] == 12 ||
-	   ($reqdata['stateid'] == 14 && 
+	   ($reqdata['stateid'] == 14 &&
 	   ($reqdata['laststateid'] == 11 || $reqdata['laststateid'] == 12))) {
 		print "resGone('reboot'); ";
 		print "dijit.byId('editResDlg').show();";
@@ -4192,7 +4245,7 @@
 	$requestid = getContinuationVar('requestid');
 	$reqdata = getRequestInfo($requestid, 1);
 	if(is_null($reqdata) || $reqdata['stateid'] == 11 || $reqdata['stateid'] == 12 ||
-	   ($reqdata['stateid'] == 14 && 
+	   ($reqdata['stateid'] == 14 &&
 	   ($reqdata['laststateid'] == 11 || $reqdata['laststateid'] == 12))) {
 		sendJSON(array('status' => 'resgone'));
 		return;
@@ -4301,7 +4354,7 @@
 		return;
 	}
 	if($requestData['stateid'] == 11 || $requestData['stateid'] == 12 ||
-	   ($requestData['stateid'] == 14 && 
+	   ($requestData['stateid'] == 14 &&
 	   ($requestData['laststateid'] == 11 || $requestData['laststateid'] == 12))) {
 		$h = i("This reservation has timed out due to lack of user activity and is no longer available.");
 		sendJSON(array('html' => $h, 'refresh' => 1));
@@ -4374,6 +4427,8 @@
 				$conuser = $user['unityid'];
 			if($requestData['reservations'][0]['domainDNSName'] != '' && ! strlen($passwd))
 				$conuser .= "@" . $requestData['reservations'][0]['domainDNSName'];
+			elseif($requestData['reservations'][0]['OStype'] == 'windows')
+				$conuser = ".\\$conuser";
 			if(! strlen($passwd))
 				$passwd = i('(use your campus password)');
 			if($cluster)
@@ -4400,17 +4455,17 @@
 			$tos = array($conuser,
 			             $passwd,
 			             $res['connectIP']);
-			$msg = preg_replace($froms, $tos, $method['connecttext']); 
+			$msg = preg_replace($froms, $tos, $method['connecttext']);
 			foreach($method['ports'] as $port) {
 				if($usenat && array_key_exists($port['key'], $natports[$cmid]))
-					$msg = preg_replace("/{$port['key']}/", $natports[$cmid][$port['key']]['publicport'], $msg); 
+					$msg = preg_replace("/{$port['key']}/", $natports[$cmid][$port['key']]['publicport'], $msg);
 				else {
 					if((preg_match('/remote desktop/i', $method['description']) ||
-					   preg_match('/RDP/i', $method['description'])) && 
+					   preg_match('/RDP/i', $method['description'])) &&
 					   $port['key'] == '#Port-TCP-3389#')
-						$msg = preg_replace("/{$port['key']}/", $user['rdpport'], $msg); 
+						$msg = preg_replace("/{$port['key']}/", $user['rdpport'], $msg);
 					else
-						$msg = preg_replace("/{$port['key']}/", $port['port'], $msg); 
+						$msg = preg_replace("/{$port['key']}/", $port['port'], $msg);
 				}
 			}
 			#$h .= preg_replace("/(.{1,120}([ ]|$))/", '\1<br>', $msg);
@@ -4421,7 +4476,8 @@
 				#$h .= "<div id=\"connectdiv\">\n";
 				$h .= "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
 				$cdata = array('requestid' => $requestid,
-				               'resid' => $res['reservationid']);
+				               'resid' => $res['reservationid'],
+				               'cmid' => $cmid);
 				$expire = datetimeToUnix($requestData['end']) - $now + 1800; # remaining reservation time plus 30 min
 				$cont = addContinuationsEntry('sendRDPfile', $cdata, $expire);
 				$h .= "<INPUT type=hidden name=continuation value=\"$cont\">\n";
@@ -4619,7 +4675,7 @@
 	$images = removeNoCheckout($resources["image"]);
 	#$extraimages = getServerProfileImages($user['id']);
 	if((! array_key_exists($return['imageid'], $images) &&
-	   /*($return['type'] != 'server' || 
+	   /*($return['type'] != 'server' ||
 		! array_key_exists($return['imageid'], $extraimages)) &&*/
 	   ($return['type'] != 'imaging' ||
 	   ! array_key_exists($return['imageid'], $withnocheckout))) ||
@@ -4660,7 +4716,7 @@
 		$return['revisionids'][$return['imageid']][] = $revids[0];
 	else
 		$return['revisionids'][$return['imageid']][] = getProductionRevisionid($return['imageid']);
-	
+
 	# duration
 	if($return['ending'] == 'duration') {
 		$return['duration'] = processInputVar('duration', ARG_NUMERIC, 0);
@@ -4757,7 +4813,7 @@
 				$return['dnsArr'][] = $dnsaddr;
 				$cnt++;
 			}
-	
+
 			# check that a management node can handle the network
 			$mappedmns = getMnsFromImage($return['imageid']);
 			$mnnets = checkAvailableNetworks($return['ipaddr']);
@@ -4952,7 +5008,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')
@@ -5008,8 +5064,8 @@
 	$cur = time();
 	if(array_key_exists('tzoffset', $_SESSION['persistdata']))
 		$cur += $_SESSION['persistdata']['tzoffset'] * 60;
-	for($end = $cur + DAYSAHEAD * SECINDAY; 
-	    $cur < $end; 
+	for($end = $cur + DAYSAHEAD * SECINDAY;
+	    $cur < $end;
 	    $cur += SECINDAY) {
 		$tmp = getdate($cur);
 		$index = $cur;
@@ -5028,10 +5084,14 @@
 function AJsetImageProduction() {
 	$requestid = getContinuationVar('requestid');
 	$data = getRequestInfo($requestid);
-	foreach($data["reservations"] as $res) {
-		if($res["forcheckout"]) {
-			$prettyimage = $res["prettyimage"];
-			break;
+	if($data['forimaging'])
+		$prettyimage = $data['reservations'][0]['prettyimage'];
+	else {
+		foreach($data["reservations"] as $res) {
+			if($res["forcheckout"]) {
+				$prettyimage = $res["prettyimage"];
+				break;
+			}
 		}
 	}
 	$title = "<big><strong>" . i("Change Test Image to Production") . "</strong></big><br><br>\n";
@@ -5056,10 +5116,14 @@
 function AJsubmitSetImageProduction() {
 	$requestid = getContinuationVar('requestid');
 	$data = getRequestInfo($requestid);
-	foreach($data["reservations"] as $res) {
-		if($res["forcheckout"]) {
-			$prettyimage = $res["prettyimage"];
-			break;
+	if($data['forimaging'])
+		$prettyimage = $data['reservations'][0]['prettyimage'];
+	else {
+		foreach($data["reservations"] as $res) {
+			if($res["forcheckout"]) {
+				$prettyimage = $res["prettyimage"];
+				break;
+			}
 		}
 	}
 	$query = "UPDATE request SET stateid = 17 WHERE id = $requestid";
diff --git a/web/.ht-inc/resource.php b/web/.ht-inc/resource.php
index cecd2bb..04a5e10 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;
 	}
@@ -1731,6 +1731,11 @@
 	               'baserevisionid' => $revid,
 	               'checkpoint' => $checkpoint,
 	               'add' => 1);
+	$cdata['addomainvals'] = array();
+	if(in_array("addomainAdmin", $user["privileges"])) {
+		$vals = getUserResources(array('addomainAdmin'), array("manageGroup"));
+		$cdata['addomainvals'] = $vals['addomain'];
+	}
 	$cont = addContinuationsEntry('AJsaveResource', $cdata, SECINDAY, 0);
 	$arr = array('newcont' => $cont,
 	             'enableupdate' => 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..9d9ad37 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;
@@ -1138,43 +1138,4 @@
 	sendJSON($arr);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \fn AJfetchRouterDNS()
-///
-/// \brief get router and dns information for a given IP address
-///
-////////////////////////////////////////////////////////////////////////////////
-function AJfetchRouterDNS() {
-	$data = array('status' => 'none');
-	$page = processInputVar('page', ARG_STRING);
-	if($page != 'deploy' && $page != 'profile') {
-		sendJSON($data);
-		return;
-	}
-	$ipaddr = processInputVar('ipaddr', ARG_STRING);
-	# validate fixed IP address
-	if(! validateIPv4addr($ipaddr)) {
-		sendJSON($data);
-		return;
-	}
-	# validate netmask
-	$netmask = processInputVar('netmask', ARG_STRING);
-	$bnetmask = ip2long($netmask);
-	if(! preg_match('/^[1]+0[^1]+$/', sprintf('%032b', $bnetmask))) {
-		sendJSON($data);
-		return;
-	}
-	$network = ip2long($ipaddr) & $bnetmask;
-	$availnets = getVariable('fixedIPavailnetworks', array());
-	$key = long2ip($network) . "/$netmask";
-	if(array_key_exists($key, $availnets)) {
-		$data = array('status' => 'success',
-		              'page' => $page,
-		              'router' => $availnets[$key]['router'],
-		              'dns' => implode(',', $availnets[$key]['dns']));
-	}
-	sendJSON($data);
-}
-
 ?>
diff --git a/web/.ht-inc/siteconfig.php b/web/.ht-inc/siteconfig.php
index 96aedda..bda65f2 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);
 	}
@@ -3115,7 +3115,7 @@
 	function __construct($globalopts) {
 		$this->basecdata['obj'] = $this;
 		$this->name = _('Messages');
-		$this->desc = sprintf(_("This section allows for configuration of messages that are sent to users and administrators about things such as reservations and image management. Every message has a default. Additionally, separate messages can be configured for each affiliation. Most of the messages will have parts that are in square brackets. These parts will have data substituted for them before the message is sent. A list of what can be used in squeare brackets can be found at the <a href=\"%s\">Apache VCL web site</a>. Some messages also have a short form that may be sent such as in the form of a popup within a reservation when the reservation is about to end."), "http://vcl.apache.org/docs/message_substitutions.html");
+		$this->desc = sprintf(_("This section allows for configuration of messages that are sent to users and administrators about things such as reservations and image management. Every message has a default. Additionally, separate messages can be configured for each affiliation. Most of the messages will have parts that are in square brackets. These parts will have data substituted for them before the message is sent. A list of what can be used in square brackets can be found at the <a href=\"%s\">Apache VCL web site</a>. Some messages also have a short form that may be sent such as in the form of a popup within a reservation when the reservation is about to end."), "http://vcl.apache.org/docs/message_substitutions.html");
 		$this->affils = getAffiliations();
 		$this->units = array();
 		$this->basekeys = array();
@@ -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/states.php b/web/.ht-inc/states.php
index ae4227c..2e7cb06 100644
--- a/web/.ht-inc/states.php
+++ b/web/.ht-inc/states.php
@@ -150,8 +150,8 @@
                         'AJremGroupFromProfile',
                         'AJaddProfileToGroup',
                         'AJremProfileFromGroup',
-                        'AJserverProfileStoreData',
-                        'AJfetchRouterDNS',*/
+                        'AJserverProfileStoreData',*/
+                        'AJfetchRouterDNS',
                         'AJconfirmDeleteRequest',
                         'AJsubmitDeleteRequest',
                         'AJconfirmRemoveRequest',
@@ -257,6 +257,7 @@
 $actions['mode']['sendRDPfile'] = "sendRDPfile";
 $actions['mode']['AJcheckConnectTimeout'] = "AJcheckConnectTimeout";
 $actions['mode']['AJpreviewClickThrough'] = "AJpreviewClickThrough";
+$actions['mode']['AJfetchRouterDNS'] = "AJfetchRouterDNS";
 #$actions['mode']['connectMindterm'] = "connectMindterm";
 #$actions['mode']['connectRDPapplet'] = "connectRDPapplet";
 $actions['pages']['AJnewRequest'] = "reservations";
@@ -281,6 +282,7 @@
 $actions['pages']['sendRDPfile'] = "reservations";
 $actions['pages']['AJcheckConnectTimeout'] = "reservations";
 $actions['pages']['AJpreviewClickThrough'] = "reservations";
+$actions['pages']['AJfetchRouterDNS'] = "reservations";
 #$actions['pages']['connectMindterm'] = "currentReservations";
 #$actions['pages']['connectRDPapplet'] = "currentReservations";
 
@@ -386,7 +388,6 @@
 $actions['mode']['AJaddProfileToGroup'] = "AJaddProfileToGroup";
 $actions['mode']['AJremProfileFromGroup'] = "AJremProfileFromGroup";
 $actions['mode']['AJserverProfileStoreData'] = "AJserverProfileStoreData";
-$actions['mode']['AJfetchRouterDNS'] = "AJfetchRouterDNS";
 $actions['pages']['serverProfiles'] = "serverProfiles";
 $actions['pages']['AJsaveServerProfile'] = "serverProfiles";
 $actions['pages']['AJserverProfileData'] = "serverProfiles";
@@ -397,8 +398,7 @@
 $actions['pages']['AJremGroupFromProfile'] = "serverProfiles";
 $actions['pages']['AJaddProfileToGroup'] = "serverProfiles";
 $actions['pages']['AJremProfileFromGroup'] = "serverProfiles";
-$actions['pages']['AJserverProfileStoreData'] = "serverProfiles";
-$actions['pages']['AJfetchRouterDNS'] = "serverProfiles";*/
+$actions['pages']['AJserverProfileStoreData'] = "serverProfiles";*/
 
 # time table
 # TODO a few of these belong to new reservation
diff --git a/web/.ht-inc/statistics.php b/web/.ht-inc/statistics.php
index ca81b8b..9d749fe 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);
@@ -213,7 +213,8 @@
 		       .        "l.wasavailable, "
 		       .        "l.ending, "
 		       .        "i.prettyname, "
-		       .        "o.prettyname AS OS "
+		       .        "o.prettyname AS OS, "
+		       .        "o.type AS OStype "
 		       . "FROM log l, "
 		       .      "image i, "
 		       .      "user u, "
@@ -234,7 +235,8 @@
 		       .        "l.wasavailable, "
 		       .        "l.ending, "
 		       .        "i.prettyname, "
-		       .        "o.prettyname AS OS "
+		       .        "o.prettyname AS OS, "
+		       .        "o.type AS OStype "
 		       . "FROM image i, "
 		       .      "user u, "
 		       .      "OS o, "
@@ -282,6 +284,7 @@
 	$imageload6to8 = array();
 	$imageload8more = array();
 	$imagefails = array();
+	$imageostype = array();
 	$lengths = array("30min" => 0,
 	                 "1hour" => 0,
 	                 "2hours" => 0,
@@ -292,7 +295,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))
@@ -301,6 +304,8 @@
 			$imageload6to8[$row["prettyname"]] = 0;
 		if(! array_key_exists($row["prettyname"], $imageload8more))
 			$imageload8more[$row["prettyname"]] = 0;
+		if(! isset($imageostype[$row["prettyname"]]))
+			$imageostype[$row["prettyname"]] = ucfirst($row['OStype']);
 
 		# notavailable
 		if($row["wasavailable"] == 0) {
@@ -452,6 +457,7 @@
 	print "    <TH>" . i("6-8 min wait") . "</TH>\n";
 	print "    <TH>" . i("&gt;= 8 min wait") . "</TH>\n";
 	print "    <TH>" . i("Failures") . "</TH>\n";
+	print "    <TH>" . i("OS Type") . "</TH>\n";
 	print "  </TR>\n";
 	foreach($imagecount as $key => $value) {
 		print "  <TR>\n";
@@ -477,6 +483,7 @@
 		}
 		else
 			print "    <TD align=center>{$imagefails[$key]}</TD>\n";
+		print "    <TD align=center>{$imageostype[$key]}</TD>\n";
 		print "  </TR>\n";
 	}
 	print "</TABLE>\n";
@@ -665,6 +672,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 +685,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 +695,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 +747,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 +761,7 @@
 	}
 	if(count($addcache))
 		addToStatGraphCache('totalres', $addcache, $affilid, $provid);
+	date_default_timezone_set($tz);
 	return($data);
 }
 
@@ -843,7 +856,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 +933,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 +957,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 +967,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 +1027,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 +1057,7 @@
 	}
 	if(count($addcache))
 		addToStatGraphCache('concurres', $addcache, $affilid, $provid);
+	date_default_timezone_set($tz);
 	return($data);
 }
 
@@ -1064,6 +1084,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 +1108,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 +1118,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 +1206,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 +1242,7 @@
 	}
 	if(count($addcache))
 		addToStatGraphCache('concurblade', $addcache, $affilid, $provid);
+	date_default_timezone_set($tz);
 	return($data);
 }
 
@@ -1242,6 +1269,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 +1293,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 +1303,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 +1381,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 +1411,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 feaabef..aaf3cbd 100644
--- a/web/.ht-inc/utils.php
+++ b/web/.ht-inc/utils.php
@@ -56,8 +56,8 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function initGlobals() {
-	global $mode, $user, $remoteIP, $authed, $oldmode, $semid;
-	global $days, $phpVer, $keys, $pemkey, $AUTHERROR;
+	global $mode, $user, $remoteIP, $authed, $oldmode;
+	global $days, $phpVer, $keys, $pemkey, $submitErr, $submitErrMsg;
 	global $passwdArray, $skin, $contdata, $lastmode, $inContinuation;
 	global $ERRORS, $actions;
 	global $affilValFunc, $addUserFunc, $updateUserFunc, $addUserFuncArgs;
@@ -87,7 +87,7 @@
 
 	if(function_exists('openssl_encrypt')) {
 		define('USE_PHPSECLIB', 0);
-		$crytpkey = base64_decode($cryptkey);
+		$cryptkey = base64_decode($cryptkey);
 	}
 	else {
 		define('USE_PHPSECLIB', 1);
@@ -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',
@@ -134,7 +139,10 @@
 	                     's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3',
 	                     '4', '5', '6', '7', '8', '9', '0');
 
-	if(array_key_exists('VCLAUTH', $_COOKIE) || $mode == 'submitLogin') {
+	if(isset($_COOKIE['VCLAUTH']) ||
+	   $mode == 'submitLogin' ||
+	   $mode == 'selectauth' ||
+	   $mode == 'main') {
 		// open keys
 		$fp = fopen(".ht-inc/keys.pem", "r");
 		$key = fread($fp, 8192);
@@ -165,11 +173,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,13 +278,13 @@
 	# 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)
-				$affilValFunc[$id] = create_function('', 'return 1;');
+				$affilValFunc[$id] = function() {return 1;};
 			else
-				$affilValFunc[$id] = create_function('', 'return 0;');
+				$affilValFunc[$id] = function() {return 0;};
 		}
 		if(! array_key_exists($id, $addUserFunc)) {
 			if(ALLOWADDSHIBUSERS) {
@@ -278,10 +292,10 @@
 				$addUserFuncArgs[$id] = $id;
 			}
 			else
-				$addUserFunc[$id] = create_function('', 'return 0;');
+				$addUserFunc[$id] = function() {return 0;};
 		}
 		if(! array_key_exists($id, $updateUserFunc))
-			$updateUserFunc[$id] = create_function('', 'return NULL;');
+			$updateUserFunc[$id] = function() {return NULL;};
 	}
 
 	# include appropriate files
@@ -371,8 +385,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 function checkAccess() {
 	global $mode, $user, $actionFunction, $authMechs;
-	global $itecsauthkey, $ENABLE_ITECSAUTH, $actions, $noHTMLwrappers;
-	global $inContinuation, $docreaders, $apiValidateFunc;
+	global $itecsauthkey, $ENABLE_ITECSAUTH, $actions;
+	global $inContinuation, $apiValidateFunc;
 	if($mode == 'xmlrpccall') {
 		// double check for SSL
 		if(! isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") {
@@ -380,6 +394,11 @@
 			dbDisconnect();
 			exit;
 		}
+		if(! isset($_SERVER['HTTP_X_USER'])) {
+			printXMLRPCerror(3);   # access denied
+			dbDisconnect();
+			exit;
+		}
 		$xmluser = processInputData($_SERVER['HTTP_X_USER'], ARG_STRING, 1);
 		if(! $user = getUserInfo($xmluser)) {
 			// if first call to getUserInfo fails, try calling with $noupdate set
@@ -448,7 +467,7 @@
 						exit;
 					}
 					$search = ldap_search($ds,
-					                      $auth['binddn'], 
+					                      $auth['binddn'],
 					                      "{$auth['lookupuserfield']}={$user['unityid']}",
 					                      array('dn'), 0, 3, 15);
 					if($search) {
@@ -498,7 +517,7 @@
 			elseif($authMechs[$authtype]['type'] == 'redirect') {
 				$affilid = $authMechs[$authtype]['affiliationid'];
 				if(!(isset($apiValidateFunc) && is_array($apiValidateFunc) &&
-				   array_key_exists($affilid, $apiValidateFunc) && 
+				   array_key_exists($affilid, $apiValidateFunc) &&
 				   $apiValidateFunc[$affilid]($xmluser, $xmlpass))) {
 					printXMLRPCerror(3);    # access denied
 					dbDisconnect();
@@ -635,13 +654,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;
 	}
 
@@ -732,7 +751,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();
@@ -745,7 +764,7 @@
 		doQuery($query, 101, 'vcl', 1);
 		dbDisconnect();
 		return;
-	}  
+	}
 	$inmaintenance = 0;
 	$skin = '';
 	foreach($files as $file) {
@@ -758,7 +777,8 @@
 			# check to see if end time has been reached
 			$fh = fopen($file, 'r');
 			$msg = '';
-			while($line = fgetss($fh)) {
+			while($line = fgets($fh)) {
+			    $line = strip_tags($line);
 				if(preg_match("/^END=([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$/", $line, $matches)) {
 					$tmp = "{$matches[1]}-{$matches[2]}-{$matches[3]} {$matches[4]}:{$matches[5]}:00";
 					$end = datetimeToUnix($tmp);
@@ -958,7 +978,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function main() {
-	global $user, $authed, $mode;
+	global $user, $authed;
 	print "<H2>" . i("Welcome to the Virtual Computing Lab") . "</H2>\n";
 	if($authed) {
 		if(! empty($user['lastname']) && ! empty($user['preferredname']))
@@ -1002,7 +1022,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;
@@ -1012,11 +1032,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 "<span class=\"rederrormsg\">" . mysqli_error($mysqli_link_vcl) . "</span><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 "<span class=\"rederrormsg\">" . mysqli_error($mysqli_link_acct) . "</span><br>\n";
+				error_log(mysqli_error($mysqli_link_acct));
 			}
 			print "$query<br>\n";
 			error_log($query);
@@ -1033,9 +1053,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";
@@ -1104,7 +1124,7 @@
 	global $affilValFuncArgs, $affilValFunc;
 	if(empty($loginid))
 		return 0;
-	
+
 	$rc = getAffilidAndLogin($loginid, $affilid);
 	if($rc == -1)
 		return 0;
@@ -1112,25 +1132,25 @@
 	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 &&
-	   ALLOWADDSHIBUSERS == 1 && 
+	   ALLOWADDSHIBUSERS == 1 &&
 	   strpos($loginid, '@')) {
 		$query = "SELECT shibonly "
 		       . "FROM affiliation "
 		       . "WHERE id = " . DEFAULT_AFFILID;
-		$qh = doQuery($query); 
-		$row = mysql_fetch_assoc($qh);
+		$qh = doQuery($query);
+		$row = mysqli_fetch_assoc($qh);
 		if($row['shibonly'] == 1)
-			return 0;           
+			return 0;
 	}
 
 	$valfunc = $affilValFunc[$affilid];
@@ -1184,11 +1204,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
 ///
@@ -1197,12 +1218,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;
@@ -1214,29 +1235,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);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1247,10 +1264,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);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1268,9 +1285,9 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 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) && 
+		if(QUERYLOGGING != 0 && (! $nolog) &&
 		   preg_match('/^(UPDATE|INSERT|DELETE)/', $query) &&
 		   strpos($query, 'UPDATE continuations SET expiretime = ') === FALSE) {
 			$logquery = str_replace("'", "\'", $query);
@@ -1289,10 +1306,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);
@@ -1300,7 +1317,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;
 	}
@@ -1311,14 +1328,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);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1334,7 +1368,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;
 }
@@ -1373,7 +1407,7 @@
 ///                  checked out\n
 /// \b maxinitialtime - maximum time (in minutes) to be shown when requesting
 ///                     a reservation that the image can reserved for\n
-/// \b imagemetaid - NULL or corresponding id from imagemeta table and the 
+/// \b imagemetaid - NULL or corresponding id from imagemeta table and the
 /// following additional information:\n
 /// \b checkuser - whether or not vcld should check for a logged in user\n
 /// \b sysprep - whether or not to use sysprep on creation of the image\n
@@ -1406,7 +1440,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
@@ -1428,9 +1462,10 @@
 	       . "WHERE i.userid = u.id AND ";
 	if(! $includedeleted)
 		$query .=   "i.deleted = 0 AND ";
-	$query .=      "u.affiliationid = a.id";
+	$query .=      "u.affiliationid = a.id "
+	       . "ORDER BY i.imageid, i.revision";
 	$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;
@@ -1485,7 +1520,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;
@@ -1512,7 +1547,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"];
 				}
 			}
@@ -1562,7 +1597,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']);
 	}
@@ -1598,7 +1633,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'];
@@ -1647,7 +1682,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;
@@ -1696,7 +1731,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;
 }
@@ -1723,7 +1758,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' => '');
@@ -1807,7 +1842,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']]);
@@ -1844,7 +1879,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")
@@ -1858,7 +1893,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;
 	}
@@ -1883,7 +1918,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']]);
@@ -1910,7 +1945,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;
 }
@@ -1935,14 +1970,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;
@@ -1990,10 +2025,10 @@
 			return '';
 	$query = "SELECT id, "
 	       .        "imageid "
-	       . "FROM imagerevision  " 
+	       . "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];
 }
@@ -2074,7 +2109,6 @@
 		$bygroup = 1;
 	if(! $userid)
 		$userid = $user["id"];
-	$return = array();
 
 	$nodeprivs = array();
 	$startnodes = array();
@@ -2094,7 +2128,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
@@ -2109,7 +2143,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, "
@@ -2128,7 +2162,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
@@ -2190,7 +2224,7 @@
 
 	$resources = array();
 	foreach(array_keys($resourcegroups) as $type) {
-		$resources[$type] = 
+		$resources[$type] =
 		   getResourcesFromGroups($resourcegroups[$type], $type, $includedeleted);
 	}
 	if(! $bygroup)
@@ -2220,7 +2254,7 @@
 /// \brief adds resource privileges to $nodeprivs for the parents of $nodeid
 ///
 ////////////////////////////////////////////////////////////////////////////////
-function getUserResourcesUp(&$nodeprivs, $nodeid, $userid, 
+function getUserResourcesUp(&$nodeprivs, $nodeid, $userid,
                             $resourceprivs, $privdataset) {
 	# build list of parent nodes
 	# starting at top, get images available at that node and user privs there and
@@ -2257,7 +2291,7 @@
 /// of $nodeid
 ///
 ////////////////////////////////////////////////////////////////////////////////
-function getUserResourcesDown(&$nodeprivs, $nodeid, $userid, 
+function getUserResourcesDown(&$nodeprivs, $nodeid, $userid,
                               $resourceprivs, $privdataset) {
 	# FIXME can we check for cascading and if not there, don't descend?
 	$children = getChildNodes($nodeid);
@@ -2283,11 +2317,11 @@
 ///
 /// \return modifies $nodeprivs, but doesn't return anything
 ///
-/// \brief for $id, gets privileges and cascaded privileges the user and any 
+/// \brief for $id, gets privileges and cascaded privileges the user and any
 /// groups the user is and adds them to $nodeprivs
 ///
 ////////////////////////////////////////////////////////////////////////////////
-function addNodeUserResourcePrivs(&$nodeprivs, $id, $lastid, $userid, 
+function addNodeUserResourcePrivs(&$nodeprivs, $id, $lastid, $userid,
                                   $resourceprivs, $privdataset) {
 	$nodeprivs[$id]["user"] = array("cascade" => 0);
 	foreach($resourceprivs as $priv) {
@@ -2358,9 +2392,9 @@
 			if($noprivs)
 				$nodeprivs[$id][$groupid]["cascade"] = 0;
 		}
-		// if group not blocking at this node, and group had cascade at previous 
+		// if group not blocking at this node, and group had cascade at previous
 		# node
-		if($lastid && ! $nodeprivs[$id][$groupid]["block"] && 
+		if($lastid && ! $nodeprivs[$id][$groupid]["block"] &&
 		   isset($nodeprivs[$lastid][$groupid]) &&
 		   $nodeprivs[$lastid][$groupid]["cascade"]) {
 			# set cascade = 1
@@ -2468,7 +2502,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];
 		}
@@ -2502,7 +2536,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"];
 	}
@@ -2563,7 +2597,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;
@@ -2644,7 +2678,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, "
@@ -2656,7 +2690,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 "
@@ -2725,7 +2759,7 @@
 	$cryptdata = $iv . $cryptdata;
 	return trim(base64_encode($cryptdata));
 }
- 
+
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// \fn decryptData($data, $cryptkey, $algo, $option, $keylength)
@@ -2799,7 +2833,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)
@@ -2828,7 +2862,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
@@ -2836,7 +2870,7 @@
 	}
 	else
 		$padding = constant('OPENSSL_PKCS1_OAEP_PADDING');
-	$savehdlr = set_error_handler(create_function('', ''));
+	$savehdlr = set_error_handler(function() {});
 	if(@openssl_public_encrypt($secret, $encdata, $cryptkey, $padding)) {
 		set_error_handler($savehdlr);
 		$b64data = base64_encode($encdata);
@@ -2866,7 +2900,7 @@
 	$file .= "/.ht-inc/cryptkey/private.pem";
 	$prikey = openssl_pkey_get_private("file://$file", $pemkey);
 	# decrypt secret using private key
-	$savehdlr = set_error_handler(create_function('', ''));
+	$savehdlr = set_error_handler(function() {});
 	if(ASYMOPT == 'OAEP')
 		$padding = constant('OPENSSL_PKCS1_OAEP_PADDING');
 	# OAEP currently only supported padding option
@@ -2896,7 +2930,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
@@ -2935,7 +2969,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);
@@ -2970,6 +3004,7 @@
 function getCryptKeyID() {
 	$reg = "|" . SCRIPT . "$|";
 	$filebase = preg_replace($reg, '', $_SERVER['SCRIPT_FILENAME']);
+	$filebase = preg_replace('|/shibauth|', '', $filebase);
 	$filebase .= "/.ht-inc/cryptkey";
 	$idfile = "$filebase/cryptkeyid";
 
@@ -2988,13 +3023,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) {
@@ -3026,7 +3061,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;
@@ -3073,7 +3108,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', '"
@@ -3116,7 +3151,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, "
@@ -3128,7 +3163,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();
@@ -3185,7 +3220,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', '"
@@ -3349,7 +3384,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)
@@ -3392,13 +3427,13 @@
 		       . "FROM `usergroup` u, "
 		       .      "`usergroupmembers` m "
 		       . "WHERE u.editusergroupid = m.usergroupid AND "
-		       .       "(u.ownerid = $id OR m.userid = $id) AND " 
+		       .       "(u.ownerid = $id OR m.userid = $id) AND "
 		       .       "u.affiliationid = {$user['affiliationid']} "
 		       . "ORDER BY name";
 	}
 	$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;
@@ -3438,7 +3473,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;
 }
@@ -3460,7 +3495,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;
 }
@@ -3505,7 +3540,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
@@ -3549,7 +3584,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;
@@ -3653,7 +3688,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)
@@ -3690,7 +3725,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;
@@ -3714,7 +3749,7 @@
 		return;
 
 	$query = "INSERT INTO usergroupmembers "
-	       .        "(userid, " 
+	       .        "(userid, "
 	       .        "usergroupid) "
 	       . "VALUES "
 	       .        "($userid, "
@@ -3767,8 +3802,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)
@@ -3795,7 +3830,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;
 }
@@ -3814,7 +3849,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;
 }
@@ -3838,8 +3873,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];
 	}
@@ -3858,11 +3893,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;
@@ -3882,8 +3917,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;
@@ -3907,7 +3942,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;
 }
@@ -3935,7 +3970,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;
@@ -3966,7 +4001,7 @@
 	   strncmp("{$_POST[$vartag]}", "0", 1) == 0 &&
 	   $type == ARG_NUMERIC &&
 		strncmp("{$_POST[$vartag]}", "0x0", 3) != 0) ||
-	   (array_key_exists($vartag, $_GET) && 
+	   (array_key_exists($vartag, $_GET) &&
 	   ! is_array($_GET[$vartag]) &&
 	   strncmp("{$_GET[$vartag]}", "0", 1) == 0 &&
 	   $type == ARG_NUMERIC &&
@@ -4165,7 +4200,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;
 	}
@@ -4174,7 +4209,7 @@
 		if(strlen($return) == 0)
 			$return = $defaultvalue;
 		elseif($addslashes)
-			$return = mysql_real_escape_string($return);
+			$return = vcl_mysql_escape_string($return);
 	}
 
 	return $return;
@@ -4232,7 +4267,6 @@
 			return NULL;
 	}
 
-	$user = array();
 	$query = "SELECT u.unityid AS unityid, "
 	       .        "u.affiliationid, "
 	       .        "af.name AS affiliation, "
@@ -4267,7 +4301,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' ||
@@ -4343,7 +4377,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) {
@@ -4362,7 +4396,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"];
 		}
 	}
@@ -4398,7 +4432,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;
 }
@@ -4468,9 +4502,8 @@
 		       . "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'];
 		}
 		else
@@ -4530,9 +4563,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 "
@@ -4547,7 +4580,7 @@
 	       .        "rdpport = $rdpport "
 	       . "WHERE id = $userid";
 	doQuery($query, 270);
-	return mysql_affected_rows($mysql_link_vcl);
+	return mysqli_affected_rows($mysqli_link_vcl);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -4556,7 +4589,7 @@
 ///
 /// \param $userid - an id from the user table
 ///
-/// \return an array of privileges types that the user has somewhere in the 
+/// \return an array of privileges types that the user has somewhere in the
 /// privilege tree
 ///
 /// \brief get the privilege types that the user has somewhere in the
@@ -4578,7 +4611,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';
@@ -4613,7 +4646,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;
 }
@@ -4734,7 +4767,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);
 		}
 
@@ -4744,7 +4777,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);
 		}
 	}
@@ -4761,7 +4794,7 @@
 
 	foreach($requestInfo["images"] as $key => $imageid) {
 		# check for max concurrent usage of image
-		if(! $skipconcurrentcheck && 
+		if(! $skipconcurrentcheck &&
 		   $images[$imageid]['maxconcurrent'] != NULL) {
 			if($userid == 0)
 				$usersgroups = $user['groups'];
@@ -4785,7 +4818,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;
@@ -4807,7 +4840,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);
 			}
@@ -4877,7 +4910,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);
@@ -4893,7 +4926,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);
 			}
@@ -4952,7 +4985,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]) {
@@ -4981,7 +5014,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]);
 		}
 
@@ -5056,9 +5089,11 @@
 			       .          "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;
+			if(empty($computerids) && empty($blockids))
+				return debugIsAvailable(0, 23, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual);
 		}
 
 		# check for use of specified IP address, have to wait until here
@@ -5078,9 +5113,9 @@
 			       .       "(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);
+					return debugIsAvailable(-4, 24, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual);
 				$requestInfo['ipwarning'] = 1;
 			}
 			$query = "SELECT id "
@@ -5090,14 +5125,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();
 			}
@@ -5182,7 +5217,7 @@
 function debugIsAvailable($rc, $loc, $start, $end, $imagerevisionid,
 	                       $compids=array(), $currentids=array(),
 	                       $blockids=array(), $failedids=array(), $virtual='') {
-	global $user, $mode, $requestInfo;
+	global $mode, $requestInfo;
 	$debug = getContinuationVar('debug', 0);
 	if(! $debug ||
 	   $mode != 'AJupdateWaitTime' ||
@@ -5240,9 +5275,6 @@
 		case "13":
 			$msg = "no computers available (after virtual host resource checks/before performing overlapping IP address check)";
 			break;
-		case "18":
-			$msg = "requested IP address in use by another computer";
-			break;
 		case "22":
 			$msg = "at least 2 computers have the requested IP address assigned to them";
 			break;
@@ -5252,6 +5284,12 @@
 		case "12":
 			$msg = "successfully found a computer (id: {$requestInfo['computers'][0]})";
 			break;
+		case "23":
+			$msg = "no computers available after performing VM host check";
+			break;
+		case "24":
+			$msg = "requested IP address in use by another computer";
+			break;
 	}
 	print "console.log('$msg');";
 	return $rc;
@@ -5302,7 +5340,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;
@@ -5322,7 +5360,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'];
 }
@@ -5350,7 +5388,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;
 }
@@ -5386,7 +5424,6 @@
 function allocComputer($blockids, $currentids, $computerids, $start, $end,
                        $nowfuture, $imageid, $imagerevisionid, $holdcomps,
                        $requestid) {
-	global $requestInfo;
 	$ret = array();
 	if(SCHEDULER_ALLOCATE_RANDOM_COMPUTER) {
 		shuffle($blockids);
@@ -5453,7 +5490,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, "
@@ -5467,7 +5504,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) {
@@ -5483,7 +5520,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 "
@@ -5561,7 +5598,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;
 }
@@ -5576,7 +5613,7 @@
 ///
 /// \return an array of resource ids of type $resourcetype2
 ///
-/// \brief gets a list of resources of type $resourcetype2 that $resourcesubid 
+/// \brief gets a list of resources of type $resourcetype2 that $resourcesubid
 /// of type $resourcetype1 maps to based on the resourcemap table
 ///
 ////////////////////////////////////////////////////////////////////////////////
@@ -5592,7 +5629,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
@@ -5601,7 +5638,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]);
 	}
 
@@ -5619,7 +5656,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]);
 	}
 
@@ -5631,7 +5668,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]);
 	}
 
@@ -5646,7 +5683,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;
@@ -5670,7 +5707,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function checkOverlap($start, $end, $max, $requestid=0) {
-	global $user;
 	$requests = getUserRequests("all");
 	$count = 0;
 	if($max > 0)
@@ -5733,7 +5769,7 @@
 	       .       "r.imageid != $imageid) AND "
 	       .       "r.status = 'accepted'";
 	$qh = doQuery($query, 101);
-	return(mysql_num_rows($qh));
+	return(mysqli_num_rows($qh));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -5784,7 +5820,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;
@@ -5806,7 +5842,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();
@@ -5823,7 +5859,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];
@@ -5849,10 +5885,10 @@
 	       .       "'$endstamp', "
 	       .       "NOW(), "
 	       .       "$checkuser)";
-	$qh = doQuery($query, 136);
+	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];
@@ -5894,12 +5930,12 @@
 	       .        "computerid, "
 	       .        "imageid, "
 	       .        "imagerevisionid, "
-	       .        "managementnodeid " 
+	       .        "managementnodeid "
 	       . "FROM semaphore "
 	       . "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";
@@ -6011,7 +6047,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function findManagementNode($compid, $start, $nowfuture) {
-	global $HTMLheader;
 	$allmgmtnodes = array_keys(getManagementNodes($nowfuture));
 	$mapped = getMappedResources($compid, "computer", "managementnode");
 	$usablemgmtnodes = array_intersect($allmgmtnodes, $mapped);
@@ -6036,7 +6071,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");
@@ -6113,11 +6148,11 @@
 	       . "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
-		if(! $printedHTMLheader) 
+		if(! $printedHTMLheader)
 			print $HTMLheader;
 		print "<h1>" . i("OOPS! - Reservation Has Expired") . "</h1>\n";
 		$h = i("The selected reservation is no longer available. Go to <a>Reservations</a> to request a new reservation or select another one that is available.");
@@ -6163,7 +6198,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'];
@@ -6177,7 +6212,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'];
@@ -6191,7 +6226,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
@@ -6204,7 +6239,7 @@
 /// \fn updateRequest($requestid, $nowfuture)
 ///
 /// \param $requestid - the id of the request to be updated
-/// \param $nowfuture (optional) - "now" or "future"; whether the 
+/// \param $nowfuture (optional) - "now" or "future"; whether the
 ///
 /// \brief updates an entry to the request and reservation tables
 ///
@@ -6216,7 +6251,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];
@@ -6256,7 +6291,7 @@
 		                    # could be updated, which would end up setting both
 		                    # rows to the same computer
 		doQuery($query, 147);
-		addChangeLogEntry($logid, NULL, $endstamp, $startstamp, $computerid, NULL, 
+		addChangeLogEntry($logid, NULL, $endstamp, $startstamp, $computerid, NULL,
 		                  1);
 		$query = "UPDATE sublog "
 		       . "SET computerid = $computerid "
@@ -6333,7 +6368,7 @@
 				       . "WHERE id = {$request['id']}";
 			}
 		}
-		$qh = doQuery($query, 150);
+		doQuery($query, 150);
 
 		addChangeLogEntry($request["logid"], NULL, unixToDatetime($now), NULL,
 		                  NULL, "released");
@@ -6343,7 +6378,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']}");
@@ -6376,7 +6411,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function moveReservationsOffComputer($compid=0, $count=0) {
-	global $requestInfo, $user;
+	global $requestInfo;
 	$resInfo = array();
 	$checkstart = unixToDatetime(time() + 180);
 	if($compid == 0) {
@@ -6394,7 +6429,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;
@@ -6418,7 +6453,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))
@@ -6430,7 +6465,7 @@
 	# a reservation is reassigned to meets the same restrictions
 	foreach($resInfo as $res) {
 		// pass forimaging = 1 so that isAvailable only looks at one computer
-		$rc = isAvailable($images, $res["imageid"], $res['imagerevisionid'], 
+		$rc = isAvailable($images, $res["imageid"], $res['imagerevisionid'],
 		      datetimeToUnix($res["start"]), datetimeToUnix($res["end"]), 0,
 		      0, $res["userid"], 0, 1);
 		if($rc < 1) {
@@ -6442,7 +6477,7 @@
 		return 0;
 	foreach($resInfo as $res) {
 		$rc = isAvailable($images, $res["imageid"], $res['imagerevisionid'],
-		      datetimeToUnix($res["start"]), datetimeToUnix($res["end"]), 1, 
+		      datetimeToUnix($res["start"]), datetimeToUnix($res["end"]), 1,
 		      0, $res["userid"], 0, 1);
 		if($rc > 0) {
 			$newcompid = array_shift($requestInfo["computers"]);
@@ -6500,7 +6535,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
@@ -6535,7 +6570,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, "
@@ -6546,7 +6581,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;
@@ -6572,7 +6607,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, "
@@ -6581,7 +6616,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;
@@ -6604,7 +6639,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;
 	}
@@ -6626,7 +6661,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, "
@@ -6641,7 +6676,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;
@@ -6671,7 +6706,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;
 }
@@ -6856,7 +6891,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++;
@@ -6894,7 +6929,7 @@
 			}
 			else {
 				$data[$count]['serverowner'] = 0;
-				if(! empty($row['serveradmingroupid']) && 
+				if(! empty($row['serveradmingroupid']) &&
 				   array_key_exists($row['serveradmingroupid'], $user['groups']))
 					$data[$count]['serveradmin'] = 1;
 				else
@@ -6983,7 +7018,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);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -7157,32 +7192,9 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \fn getDepartmentName($id)
-///
-/// \param $id - id for a department in the department table
-///
-/// \return if found, department name; if not, 0
-///
-/// \brief looks up the name field corresponding to $id in the department table
-/// and returns it
-///
-////////////////////////////////////////////////////////////////////////////////
-function getDepartmentName($id) {
-	$query = "SELECT name FROM department WHERE id = '$id'";
-	$qh = doQuery($query, 101);
-	if($row = mysql_fetch_row($qh)) {
-		return $row[0];
-	}
-	else {
-		return 0;
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-///
 /// \fn getImageId($image)
 ///
-/// \param $image - name of an image (must match name (not prettyname) in the 
+/// \param $image - name of an image (must match name (not prettyname) in the
 /// image table)
 ///
 /// \return the id of matching $image in the image table or 0 if lookup fails
@@ -7192,7 +7204,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;
@@ -7211,7 +7223,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;
@@ -7229,7 +7241,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;
@@ -7247,7 +7259,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;
@@ -7275,7 +7287,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;
 }
@@ -7299,7 +7311,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` "
@@ -7313,7 +7325,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')
@@ -7358,7 +7370,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();
 	}
@@ -7369,7 +7381,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"]));
 	}
@@ -7493,7 +7505,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'] = '';
@@ -7519,7 +7531,7 @@
 			$return[$mn_id]['timeservers'] = $timeservers;
 		}
 	}
-	
+
 	return $return;
 }
 
@@ -7551,14 +7563,12 @@
 	       .       "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) {
-		$mngrpset = getResourceMapping('managementnode', 'computer', '', implode(',', $compgroups));
-		foreach($mngrpset as $mngrpid => $compgrpset)
-			$mngrps[$mngrpid] = 1;
-	}
+	$mngrpset = getResourceMapping('managementnode', 'computer', '', implode(',', $compgroups));
+	foreach($mngrpset as $mngrpid => $compgrpset)
+		$mngrps[$mngrpid] = 1;
 	$mngrpnames = array();
 	foreach(array_keys($mngrps) as $mnid) {
 		$mngrpnames[] = getResourceGroupName($mnid);
@@ -7644,7 +7654,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;
 }
@@ -7660,7 +7670,7 @@
 /// \return array of free/used timeslotes
 ///
 /// \brief generates an array of availability for computers where index is a
-/// computerid with a value that is an array whose indexes are unix timestamps 
+/// computerid with a value that is an array whose indexes are unix timestamps
 /// that increment by 15 minutes with a value that is an array with 2 indexes:
 /// 'scheduleclosed' and 'available' that tell if the computer's schedule is
 /// closed at that moment and if the computer is available at that moment\n
@@ -7716,7 +7726,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];
@@ -7764,7 +7774,7 @@
 	$qh = doQuery($query, 156);
 
 	$id = "";
-	while($row = mysql_fetch_row($qh)) {
+	while($row = mysqli_fetch_row($qh)) {
 		if($row[3] == $requestid) {
 			continue;
 		}
@@ -7855,7 +7865,7 @@
 				continue;
 			}
 			//if between a start and end time
-			if($current >= $times[$id][$count]["start"] && 
+			if($current >= $times[$id][$count]["start"] &&
 			   $current <  $times[$id][$count]["end"]) {
 				if($first) {
 					# set the previous 15 minute block to show as busy to allow for load time
@@ -7874,7 +7884,7 @@
 				continue;
 			}
 			//if after previous end but before this start
-			if($current >= $times[$id][$count - 1]["end"] && 
+			if($current >= $times[$id][$count - 1]["end"] &&
 			   $current <  $times[$id][$count]["start"]) {
 				$reserveInfo[$id][$current]["available"] = 1;
 				continue;
@@ -7928,8 +7938,7 @@
 	              0,
 	              $timeval["mon"],
 	              $timeval["mday"],
-	              $timeval["year"],
-	              -1);
+	              $timeval["year"]);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -8010,11 +8019,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");
@@ -8304,7 +8313,7 @@
 /// \param $ip - (optional, default='') desired IP address
 /// \param $mac - (optional, default='') desired MAC address
 ///
-/// \return an array where each key is a unix timestamp for the start time of 
+/// \return an array where each key is a unix timestamp for the start time of
 /// the available slot and each element is an array with these items:\n
 /// \b start - start of slot in datetime format\n
 /// \b startts - start of slot in unix timestamp format\n
@@ -8399,7 +8408,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;
@@ -8453,7 +8462,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;
@@ -8512,7 +8521,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;
@@ -8537,6 +8546,7 @@
 	       .      "reservation rs, "
 	       .      "image i, "
 	       .      "state s, "
+	       .      "state rqs, "
 	       .      "computer c, "
 	       .      "provisioningOSinstalltype poi, "
 	       .      "OSinstalltype oi, "
@@ -8544,6 +8554,8 @@
 	       . "WHERE rs.requestid = rq.id AND "
 	       .       "(rq.start > '$startdt' OR "
 	       .        "(DATE_ADD(rq.end, INTERVAL 15 MINUTE) > '$startdt' AND rq.start <= '$startdt')) AND "
+	       .       "rq.stateid = rqs.id AND "
+	       .       "rqs.name NOT IN ('failed', 'complete', 'reload') AND "
 	       .       "rs.computerid IN ($incompids) AND "
 	       .       "i.id = $imageid AND "
 	       .       "c.id = rs.computerid AND "
@@ -8568,7 +8580,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) {
@@ -8605,7 +8617,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);
 	}
@@ -8634,7 +8646,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);
 		}
@@ -8648,7 +8660,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']);
@@ -8804,7 +8816,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;
 }
@@ -8957,7 +8969,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'] = '';
@@ -8993,7 +9005,7 @@
 	if(isset($_SESSION['usersessiondata'][$key]))
 		return $_SESSION['usersessiondata'][$key];
 	$computers = getComputers();
-	$resources = getUserResources(array("computerAdmin"), 
+	$resources = getUserResources(array("computerAdmin"),
 	                              array("administer", "manageGroup"), 0, 1);
 	$return = array("platforms" => array(),
 	                "schedules" => array());
@@ -9026,7 +9038,7 @@
 /// they occur\n
 /// \b nextstates - array where each key is a computerloadstate id and its value
 /// is that state's following state; the last state has a NULL value\n
-/// \b totaltime - estimated time (in seconds) it takes for all states to 
+/// \b totaltime - estimated time (in seconds) it takes for all states to
 /// complete\n
 /// \b data - array where each key is is a computerloadstate id and each value
 /// is an array with these elements:\n
@@ -9048,13 +9060,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'];
@@ -9073,7 +9085,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']);
@@ -9083,7 +9095,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;
 		}
@@ -9128,7 +9140,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
@@ -9151,7 +9163,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)
@@ -9191,7 +9203,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
@@ -9217,7 +9229,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;
@@ -9344,7 +9356,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;
 	}
@@ -9375,7 +9387,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;
@@ -9411,7 +9423,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");
@@ -9420,7 +9432,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
-/// \fn getReservationNATports($resid)
+/// \fn getNATports($resid)
 ///
 /// \param $resid - id of a reservation
 ///
@@ -9440,8 +9452,8 @@
 function getNATports($resid) {
 	$ports = array();
 	$query = "SELECT n.publicport, "
-	       .        "n.connectmethodportid, " 
-	       .        "c.port AS privateport, " 
+	       .        "n.connectmethodportid, "
+	       .        "c.port AS privateport, "
 	       .        "c.protocol, "
 	       .        "c.connectmethodid "
 	       . "FROM natport n, "
@@ -9449,7 +9461,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;
 }
@@ -9469,7 +9481,8 @@
 /// \b domaindnsname\n
 /// \b username\n
 /// \b dnsservers\n
-/// \b secretid
+/// \b secretid\n
+/// \b usedbhostnames
 ///
 /// \brief builds an array of AD domains
 ///
@@ -9483,7 +9496,8 @@
 	       .        "ad.domainDNSName AS domaindnsname, "
 	       .        "ad.username, "
 	       .        "ad.dnsServers AS dnsservers, "
-	       .        "ad.secretid "
+	       .        "ad.secretid, "
+	       .        "ad.usedbhostnames "
 	       . "FROM addomain ad, "
 	       .      "affiliation a, "
 	       .      "user u, "
@@ -9499,7 +9513,7 @@
 
 	$qh = doQuery($query);
 	$addomainlist = array();
-	while($row = mysql_fetch_assoc($qh))
+	while($row = mysqli_fetch_assoc($qh))
 		$addomainlist[$row['id']] = $row;
 	return $addomainlist;
 }
@@ -9562,7 +9576,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']);
@@ -9571,7 +9585,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;
@@ -9625,7 +9639,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;
 }
@@ -9648,7 +9662,7 @@
 /// \param $extra - (optional) any extra attributes that need to be set
 ///
 /// \brief prints out a select input part of a form\n
-/// it is assumed that if $selectedid is left off, we assume $dataArr has no 
+/// it is assumed that if $selectedid is left off, we assume $dataArr has no
 /// index '-1'\n
 /// each OPTION's value is the index of that element of the array
 ///
@@ -9707,7 +9721,7 @@
 /// multiple tag set
 ///
 /// \brief generates HTML for select input
-/// it is assumed that if $selectedid is left off, we assume $dataArr has no 
+/// it is assumed that if $selectedid is left off, we assume $dataArr has no
 /// index '-1'\n
 /// each OPTION's value is the index of that element of the array
 ///
@@ -9941,12 +9955,12 @@
 ///
 /// \fn requestIsReady($request)
 ///
-/// \param $request - a request element from the array returned by 
+/// \param $request - a request element from the array returned by
 /// getUserRequests
 ///
 /// \return 1 if request is ready for a user to connect, 0 if not
 ///
-/// \brief checks to see if a request is 
+/// \brief checks to see if a request is
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function requestIsReady($request) {
@@ -9954,7 +9968,7 @@
 		if($res["computerstateid"] != 3 && $res["computerstateid"] != 8)
 			return 0;
 	}
-	if(($request["currstateid"] == 14 &&      // request current state pending 
+	if(($request["currstateid"] == 14 &&      // request current state pending
 	   $request["laststateid"] == 3 &&        //   and last state reserved and
 	   $request["computerstateid"] == 3) ||   //   computer reserved
 	   ($request["currstateid"] == 8 &&       // request current state inuse
@@ -10171,7 +10185,7 @@
 ///
 /// \return 1 if schedule is closed at $timestamp, 0 if it is open
 ///
-/// \brief checks to see if the computer's schedule is open or closed at 
+/// \brief checks to see if the computer's schedule is open or closed at
 /// $timestamp
 ///
 ////////////////////////////////////////////////////////////////////////////////
@@ -10228,7 +10242,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)) ||
@@ -10276,7 +10290,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;
@@ -10292,7 +10306,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];
@@ -10303,7 +10317,7 @@
 /// \fn getUserGroupName($id, $incAffil)
 ///
 /// \param $id - id of a user group
-/// \param $incAffil - 0 or 1 (optional, defaults to 0); include @ and 
+/// \param $incAffil - 0 or 1 (optional, defaults to 0); include @ and
 /// affiliation at the end
 ///
 /// \return name for $id from usergroup table or 0 if name not found
@@ -10325,7 +10339,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;
 }
@@ -10402,7 +10416,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;
@@ -10437,7 +10451,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;
@@ -10454,7 +10468,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function unset_by_val($needle, &$haystack) {
-	while(($gotcha = array_search($needle,$haystack)) > -1) { 
+	while(($gotcha = array_search($needle,$haystack)) > -1) {
 		unset($haystack[$gotcha]);
 	}
 }
@@ -10468,13 +10482,16 @@
 ////////////////////////////////////////////////////////////////////////////////
 function sendRDPfile() {
 	global $user;
-	# for more info on this file, see 
+	# for more info on this file, see
 	# http://dev.remotenetworktechnology.com/ts/rdpfile.htm
 	$requestid = getContinuationVar("requestid");
 	$resid = getContinuationVar("resid");
+
+	$cmid = getContinuationVar('cmid');
+
 	$request = getRequestInfo("$requestid");
 	if($request['stateid'] == 11 || $request['stateid'] == 12 ||
-	   ($request['stateid'] == 14 && 
+	   ($request['stateid'] == 14 &&
 	   ($request['laststateid'] == 11 || $request['laststateid'] == 12))) {
 		$cont = addContinuationsEntry('viewRequests');
 		header("Location: " . BASEURL . SCRIPT . "?continuation=$cont");
@@ -10494,20 +10511,19 @@
 	                                          $res['imagerevisionid']);
 	$natports = getNATports($resid);
 	$port = '';
-	foreach($connectData as $cmid => $method) {
-		if(preg_match('/remote desktop/i', $method['description']) ||
-		   preg_match('/RDP/i', $method['description'])) {
-			# assume index 0 of ports for nat
-			if(! empty($natports) && array_key_exists($method['ports'][0]['key'], $natports[$cmid]))
-				$port = ':' . $natports[$cmid][$method['ports'][0]['key']]['publicport'];
-			else {
-				if($method['ports'][0]['key'] == '#Port-TCP-3389#' &&
-				   $user['rdpport'] != 3389)
-					$port = ':' . $user['rdpport'];
-				else
-					$port = ':' . $method['ports'][0]['port'];
-			}
-			break;
+
+	$method = $connectData[$cmid];
+	if(preg_match('/remote desktop/i', $method['description']) ||
+	   preg_match('/RDP/i', $method['description'])) {
+		# assume index 0 of ports for nat
+		if(! empty($natports) && array_key_exists($method['ports'][0]['key'], $natports[$cmid]))
+			$port = ':' . $natports[$cmid][$method['ports'][0]['key']]['publicport'];
+		else {
+			if($method['ports'][0]['key'] == '#Port-TCP-3389#' &&
+			   $user['rdpport'] != 3389)
+				$port = ':' . $user['rdpport'];
+			else
+				$port = ':' . $method['ports'][0]['port'];
 		}
 	}
 
@@ -10542,15 +10558,15 @@
 	print "desktopwidth:i:$width\r\n";
 	print "desktopheight:i:$height\r\n";
 	print "session bpp:i:$bpp\r\n";
-	
+
 	print "winposstr:s:0,1,0,0,5000,4000\r\n";
-	# 0: 
+	# 0:
 	# 1:    use coordinates for the window position, as opposed to 3 - maximized
 	# 0:    left position in client coordinates
 	# 0:    top position in client coordinates
 	# 5000: width in pixels - set large to avoid scrollbars
 	# 4000: height in pixels - set large to avoid scrollbars
-	
+
 	print "full address:s:$ipaddress$port\r\n";
 	print "compression:i:1\r\n";
 	print "keyboardhook:i:2\r\n";
@@ -10567,6 +10583,8 @@
 		$userid = $user["unityid"];
 	if($request['reservations'][0]['domainDNSName'] != '' && ! strlen($passwd))
 		$userid .= "@" . $request['reservations'][0]['domainDNSName'];
+	elseif($request['reservations'][0]['OStype'] == 'windows')
+		$userid = ".\\$userid";
 	print "username:s:$userid\r\n";
 	print "clear password:s:$passwd\r\n";
 	print "domain:s:\r\n";
@@ -10634,16 +10652,16 @@
 /// available; \b NOTE: pass -1 instead of NULL if you don't want this field
 /// to be updated
 ///
-/// \brief adds an entry to the changelog table and updates information in 
+/// \brief adds an entry to the changelog table and updates information in
 /// the log table
 ///
 ////////////////////////////////////////////////////////////////////////////////
-function addChangeLogEntry($logid, $remoteIP, $end=NULL, $start=NULL, 
+function addChangeLogEntry($logid, $remoteIP, $end=NULL, $start=NULL,
                            $computerid=NULL, $ending=NULL, $wasavailable=-1) {
 	if($logid == 0) {
 		return;
 	}
-	$query = "SELECT computerid, " 
+	$query = "SELECT computerid, "
 	       .        "start, "
 	       .        "initialend, "
 	       .        "remoteIP, "
@@ -10652,13 +10670,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;
@@ -10760,7 +10778,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function addChangeLogEntryOther($logid, $data) {
-	$data = mysql_real_escape_string($data);
+	$data = vcl_mysql_escape_string($data);
 	$query = "INSERT INTO changelog "
 	       .        "(logid, "
 	       .        "timestamp, "
@@ -10796,7 +10814,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 "
@@ -10804,7 +10822,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
@@ -10856,7 +10874,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"];
@@ -10865,7 +10883,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;
@@ -10885,7 +10903,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;
@@ -10934,8 +10952,8 @@
 ///
 /// \param $max - max allowed length in minutes
 ///
-/// \return array of lengths up to $max starting with 30 minutes, 1 hour, 
-/// 2 hours, then increasing by 2 hours up to 47 hours, then 2 days, then 
+/// \return array of lengths up to $max starting with 30 minutes, 1 hour,
+/// 2 hours, then increasing by 2 hours up to 47 hours, then 2 days, then
 /// increasing by 1 day; indexes are the duration in minutes
 ///
 /// \brief generates an array of reservation lengths
@@ -11057,8 +11075,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 "
@@ -11066,7 +11084,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;
@@ -11089,7 +11107,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;
@@ -11107,12 +11125,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;
@@ -11131,7 +11149,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);
@@ -11151,7 +11169,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;
 }
@@ -11170,7 +11188,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;
 }
@@ -11195,7 +11213,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;
 }
@@ -11240,7 +11258,7 @@
 	       .      "user u, "
 	       .      "affiliation ua, "
 	       .      "configtype ct, "
-	       .      "configmaptype cmt, " 
+	       .      "configmaptype cmt, "
 	       .      "affiliation a, "
 	       .      "configstage cs "
 	       . "WHERE cm.configid = c.id AND "
@@ -11261,7 +11279,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'];
@@ -11345,7 +11363,7 @@
 	       .      "user u, "
 	       .      "affiliation ua, "
 	       .      "configtype ct, "
-	       .      "configmaptype cmt, " 
+	       .      "configmaptype cmt, "
 	       .      "affiliation a, "
 	       .      "configstage cs "
 	       . "WHERE cm.configid = c.id AND "
@@ -11372,7 +11390,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'];
@@ -11442,7 +11460,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']);
@@ -11515,7 +11533,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)
@@ -11578,7 +11596,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)) {
@@ -11606,7 +11624,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;
 }
@@ -11639,7 +11657,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;
 }
@@ -11662,7 +11680,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];
@@ -11749,7 +11767,7 @@
 ///
 /// \return -1, 0, 1 if numerical parts of $a <, =, or > $b
 ///
-/// \brief compares $a and $b to determine which one should be ordered first; 
+/// \brief compares $a and $b to determine which one should be ordered first;
 /// has some understand of numerical order in strings
 ///
 ////////////////////////////////////////////////////////////////////////////////
@@ -11809,8 +11827,8 @@
 /// \param $resource2inlist - (optional) comma delimited list of resource groups
 /// to limit query to
 ///
-/// \return an array of $resourcetype1 group to $resourcetype2 group mappings 
-/// where each index is a group id from $resourcetype1 and each value is an 
+/// \return an array of $resourcetype1 group to $resourcetype2 group mappings
+/// where each index is a group id from $resourcetype1 and each value is an
 /// array of $resourcetype2 group ids
 ///
 /// \brief builds an array of $resourcetype2 group ids for each $resourcetype1
@@ -11839,7 +11857,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"]);
@@ -11891,7 +11909,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;
@@ -11929,7 +11947,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;
@@ -11974,8 +11992,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'";
@@ -12024,7 +12042,7 @@
 /// \param $id (optional) - a profile id; if specified, only data about this
 /// profile will be returned
 ///
-/// \return an array of profiles where each key is the profile id and each 
+/// \return an array of profiles where each key is the profile id and each
 /// element is an array with these keys:\n
 /// \b profilename - name of profile\n
 /// \b name - name of profile (so array can be passed to printSelectInput)\n
@@ -12083,7 +12101,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;
 }
@@ -12103,7 +12121,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);
@@ -12117,7 +12135,7 @@
 /// \fn addContinuationsEntry($nextmode, $data, $duration, $deleteFromSelf,
 ///                           $multicall, $repeatProtect)
 ///
-/// \param $nextmode - next mode to go in to 
+/// \param $nextmode - next mode to go in to
 /// \param $data (optional, default=array())- array of data to make available
 /// in $nextmode
 /// \param $duration (optional, default=SECINWEEK)- how long this continuation
@@ -12152,7 +12170,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 "
@@ -12160,7 +12178,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' "
@@ -12183,7 +12201,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'];
 		}
@@ -12267,7 +12285,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
@@ -12373,7 +12391,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);
@@ -12412,7 +12430,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':
@@ -12451,7 +12469,7 @@
 ///
 /// \return array of values from variable table
 ///
-/// \brief gets data from the variable table for $pattern matches 'name' from 
+/// \brief gets data from the variable table for $pattern matches 'name' from
 /// table
 ///
 ////////////////////////////////////////////////////////////////////////////////
@@ -12463,7 +12481,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'];
@@ -12499,7 +12517,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;
@@ -12509,19 +12527,19 @@
 	$_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)
 		$query = "UPDATE variable "
-		       . "SET value = '$qdata', " 
+		       . "SET value = '$qdata', "
 		       .     "serialization = '$serialization', "
 		       .     "setby = 'webcode', "
 		       .     "timestamp = NOW() "
@@ -12622,7 +12640,7 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function xmlrpccall() {
-	global $xmlrpc_handle, $HTTP_RAW_POST_DATA, $user;
+	global $xmlrpc_handle, $user;
 	# create xmlrpc handle
 	$xmlrpc_handle = xmlrpc_server_create();
 	# register functions available via rpc calls
@@ -12676,7 +12694,8 @@
 	xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCfinishBaseImageCapture", "xmlRPChandler");
 	xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCcheckCryptSecrets", "xmlRPChandler");
 
-	print xmlrpc_server_call_method($xmlrpc_handle, $HTTP_RAW_POST_DATA, '');
+	$raw_post_data = file_get_contents("php://input");
+	print xmlrpc_server_call_method($xmlrpc_handle, $raw_post_data, '');
 	xmlrpc_server_destroy($xmlrpc_handle);
 	cleanSemaphore();
 	dbDisconnect();
@@ -12691,13 +12710,14 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function xmlrpcgetaffiliations() {
-	global $xmlrpc_handle, $HTTP_RAW_POST_DATA;
+	global $xmlrpc_handle;
 	# create xmlrpc handle
 	$xmlrpc_handle = xmlrpc_server_create();
 	# register functions available via rpc calls
 	xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaffiliations", "xmlRPChandler");
 
-	print xmlrpc_server_call_method($xmlrpc_handle, $HTTP_RAW_POST_DATA, '');
+	$raw_post_data = file_get_contents("php://input");
+	print xmlrpc_server_call_method($xmlrpc_handle, $raw_post_data, '');
 	xmlrpc_server_destroy($xmlrpc_handle);
 	dbDisconnect();
 	exit;
@@ -12727,15 +12747,15 @@
 		$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, " 
+			       .        "(xmlrpcKeyid, "
 			       .        "timestamp, "
 			       .        "IPaddress, "
 			       .        "method, "
 			       .        "apiversion, "
 			       .        "comments) "
-			       . "VALUES " 
+			       . "VALUES "
 			       .        "($keyid, "
 			       .        "NOW(), "
 			       .        "'$remoteIP', "
@@ -12768,13 +12788,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;
@@ -12783,8 +12803,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";
@@ -12934,7 +12954,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);
 		}
 	}
@@ -13022,7 +13042,7 @@
 			 // Always use "." for floats.
 			 return floatval(str_replace(",", ".", strval($a)));
 		}
- 
+
 		if (is_string($a)) {
 			 static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
 			return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"';
@@ -13082,8 +13102,8 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function sendHeaders() {
-	global $mode, $user, $authed, $oldmode, $actionFunction;
-	global $shibauthed;
+	global $mode, $user, $authed, $actionFunction;
+	global $shibauthed, $authFuncs;
 	if(! $authed && $mode == "auth") {
 		header("Location: " . BASEURL . SCRIPT . "?mode=selectauth");
 		dbDisconnect();
@@ -13091,78 +13111,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;
 	}
@@ -13233,8 +13197,8 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 function printHTMLHeader() {
-	global $mode, $user, $authed, $oldmode, $HTMLheader, $contdata;
-	global $printedHTMLheader, $docreaders, $noHTMLwrappers, $actions;
+	global $mode, $user, $authed, $HTMLheader, $contdata;
+	global $printedHTMLheader, $noHTMLwrappers;
 	if($printedHTMLheader)
 		return;
 	$refresh = 0;
@@ -13810,23 +13774,6 @@
 			                      'dijit.form.ValidationTextBox',
 			                      'dijit.layout.TabContainer');
 			break;
-		# TODO clean up
-		/*case 'serverProfiles':
-			$filename = 'vclServerProfiles.js';
-			$dojoRequires = array('dojo.parser',
-			                      'dijit.Dialog',
-			                      'dijit.form.Button',
-			                      'dijit.form.FilteringSelect',
-			                      'dijit.form.Select',
-			                      'dijit.form.TextBox',
-			                      'dijit.form.ValidationTextBox',
-			                      'dijit.form.CheckBox',
-			                      'dijit.form.Textarea',
-			                      'dijit.layout.ContentPane',
-			                      'dijit.layout.TabContainer',
-			                      'dojox.string.sprintf',
-			                      'dojo.data.ItemFileWriteStore');
-			break;*/
 		/*case 'testDojoREST':
 			$filename = '';
 			$dojoRequires = array('dojo.parser',
@@ -13878,8 +13825,6 @@
 			$rt .= "      testJS();\n";
 			$rt .= "      document.onmousemove = updateMouseXY;\n";
 			$rt .= "      showScriptOnly();\n";
-			/*$cont = addContinuationsEntry('AJserverProfileStoreData', array(), 120, 1, 0);
-			$rt .= "   populateProfileStore('$cont');\n";*/
 			$rt .= "   });\n";
 			if($refresh)
 				$rt .= "   refresh_timer = setTimeout(resRefresh, 12000);\n";
@@ -14363,7 +14308,7 @@
 		setcookie("VCLLOCALE", $_COOKIE['VCLLOCALE'], (time() + (86400 * 31)), "/", COOKIEDOMAIN);
 		$locale = $_COOKIE['VCLLOCALE'];
 	}
-	
+
 	#putenv('LC_ALL=' . $locale);
 	# use UTF8 encoding for any locales other than English (we may just be able
 	#   to always use UTF8)
diff --git a/web/.ht-inc/vm.php b/web/.ht-inc/vm.php
index 5375cdf..df10b43 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']);
@@ -437,9 +437,7 @@
 	$currvms = array_merge($currvms);
 	$noaccess = array_merge($noaccess);
 	$freevms = array_merge($freevms);
-	$cont = addContinuationsEntry('AJchangeVMprofile', array(), 3600, 1, 0);
 	$arr = array('profile' => $data[$vmhostid]['vmprofiledata'],
-	             'continuation' => $cont,
 	             'allvms' => $allvms,
 	             'currvms' => $currvms,
 	             'noaccess' => $noaccess,
@@ -480,7 +478,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))
@@ -516,6 +514,10 @@
 	$fails = array();
 
 	$vmlistids = processInputVar('listids', ARG_STRING);
+	if(! preg_match('/^(\d+)(,\d+)*$/', $vmlistids)) {
+		sendJSON(array('failed' => 'invaliddata'));
+		return;
+	}
 	$vmids = explode(',', $vmlistids);
 
 	# get data about submitted vms to add
@@ -524,7 +526,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 +539,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
@@ -583,6 +585,10 @@
 
 	$fails = array();
 	$vmlistids = processInputVar('listids', ARG_STRING);
+	if(! preg_match('/^(\d+)(,\d+)*$/', $vmlistids)) {
+		sendJSON(array('failed' => 'invaliddata'));
+		return;
+	}
 	$vmids = explode(',', $vmlistids);
 	$rems = array();
 	$checks = array();
@@ -616,7 +622,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'),
@@ -718,6 +724,10 @@
 
 	$fails = array();
 	$requestids = processInputVar('listids', ARG_STRING);
+	if(! preg_match('/^(\d+)(,\d+)*$/', $requestids)) {
+		sendJSON(array('failed' => 'invaliddata'));
+		return;
+	}
 	$now = time();
 	$msg = 'FAIL';
 	foreach(explode(',', $requestids) AS $reqid) {
@@ -840,11 +850,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 +888,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 +905,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);
@@ -944,13 +954,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 function AJnewProfile() {
 	$newprofile = processInputVar('newname', ARG_STRING);
-	if(get_magic_quotes_gpc()) {
+	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 +1003,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..750000e 100644
--- a/web/.ht-inc/xmlrpcWrappers.php
+++ b/web/.ht-inc/xmlrpcWrappers.php
@@ -19,9 +19,9 @@
 /**
  * \file
  * The functions listed here are for making VCL requests from other applications.
- * They are implemented according to the XML RPC spec defined at 
+ * They are implemented according to the XML RPC spec defined at
  * http://www.xmlrpc.com/ \n
- * There is one function called \b XMLRPCtest() that can be used during 
+ * There is one function called \b XMLRPCtest() that can be used during
  * initial development to get started without actually making a request.\n
  * \n
  * The URL you will use to submit RPC calls is the URL for your VCL site
@@ -171,7 +171,7 @@
 	$length = processInputData($length, ARG_NUMERIC);
 	#$foruser = processInputData($foruser, ARG_STRING, 1);
 
-	// make sure user didn't submit a request for an image he 
+	// make sure user didn't submit a request for an image he
 	// doesn't have access to
 	$resources = getUserResources(array("imageAdmin", "imageCheckOut"));
 	$validImageids = array_keys($resources['image']);
@@ -233,7 +233,7 @@
 	$revisionid = getProductionRevisionid($imageid);
 	$rc = isAvailable($images, $imageid, $revisionid, $start, $end, 1);
 	if($rc < 1) {
-		addLogEntry($nowfuture, unixToDatetime($start), 
+		addLogEntry($nowfuture, unixToDatetime($start),
 		            unixToDatetime($end), 0, $imageid);
 		return array('status' => 'notavailable');
 	}
@@ -354,7 +354,7 @@
 	$revisionid = getProductionRevisionid($imageid);
 	$rc = isAvailable($images, $imageid, $revisionid, $start, $end, 1);
 	if($rc < 1) {
-		addLogEntry($nowfuture, unixToDatetime($start), 
+		addLogEntry($nowfuture, unixToDatetime($start),
 		            unixToDatetime($end), 0, $imageid);
 		return array('status' => 'notavailable');
 	}
@@ -387,7 +387,7 @@
 /// \param $foruser - (optional) login to be used when setting up the account
 /// on the reserved machine - CURRENTLY, THIS IS UNSUPPORTED
 /// \param $name - (optional) name for reservation
-/// \param $userdata - (optional) text that will be placed in 
+/// \param $userdata - (optional) text that will be placed in
 /// /root/.vclcontrol/post_reserve_userdata on the reserved node
 ///
 /// \return an array with at least one index named '\b status' which will have
@@ -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)) {
@@ -562,7 +562,7 @@
 	$rc = isAvailable($images, $imageid, $revisionid, $start, $end,
 	                  1, 0, 0, 0, 0, $ipaddr, $macaddr);
 	if($rc < 1) {
-		addLogEntry($nowfuture, unixToDatetime($start), 
+		addLogEntry($nowfuture, unixToDatetime($start),
 		            unixToDatetime($end), 0, $imageid);
 		return array('status' => 'notavailable');
 	}
@@ -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, "
@@ -851,23 +851,23 @@
 		$portdata = array();
 		foreach($connectMethods as $key => $cm) {
 			$connecttext = $cm["connecttext"];
-			$connecttext = preg_replace("/#userid#/", $thisuser, $connecttext); 
-			$connecttext = preg_replace("/#password#/", $passwd, $connecttext); 
-			$connecttext = preg_replace("/#connectIP#/", $serverIP, $connecttext); 
+			$connecttext = preg_replace("/#userid#/", $thisuser, $connecttext);
+			$connecttext = preg_replace("/#password#/", $passwd, $connecttext);
+			$connecttext = preg_replace("/#connectIP#/", $serverIP, $connecttext);
 			foreach($cm['ports'] as $port) {
 				if(! empty($natports) && array_key_exists($port['key'], $natports[$key])) {
-					$connecttext = preg_replace("/{$port['key']}/", $natports[$key][$port['key']]['publicport'], $connecttext); 
+					$connecttext = preg_replace("/{$port['key']}/", $natports[$key][$port['key']]['publicport'], $connecttext);
 					$connectMethods[$key]['connectports'][] = "{$port['protocol']}:{$port['port']}:{$natports[$key][$port['key']]['publicport']}";
 				}
 				else {
 					if((preg_match('/remote desktop/i', $cm['description']) ||
-					   preg_match('/RDP/i', $cm['description'])) && 
+					   preg_match('/RDP/i', $cm['description'])) &&
 					   $port['key'] == '#Port-TCP-3389#') {
-						$connecttext = preg_replace("/{$port['key']}/", $user['rdpport'], $connecttext); 
+						$connecttext = preg_replace("/{$port['key']}/", $user['rdpport'], $connecttext);
 						$connectMethods[$key]['connectports'][] = "{$port['protocol']}:{$port['port']}:{$user['rdpport']}";
 					}
 					else {
-						$connecttext = preg_replace("/{$port['key']}/", $port['port'], $connecttext); 
+						$connecttext = preg_replace("/{$port['key']}/", $port['port'], $connecttext);
 						$connectMethods[$key]['connectports'][] = "{$port['protocol']}:{$port['port']}:{$port['port']}";
 					}
 				}
@@ -880,7 +880,7 @@
 		$cmid = $tmp[0];
 		if(empty($natports))
 			if((preg_match('/remote desktop/i', $connectMethods[$cmid]['description']) ||
-			   preg_match('/RDP/i', $connectMethods[$cmid]['description'])) && 
+			   preg_match('/RDP/i', $connectMethods[$cmid]['description'])) &&
 				$portdata[$cmid][0]['port'] == 3389)
 				$connectport = $user['rdpport'];
 			else
@@ -1005,7 +1005,7 @@
 	if($timeToNext > -1) {
 		$lockedall = 1;
 		if(count($request['reservations']) > 1) {
-			# get semaphore on each existing node in cluster so that nothing 
+			# get semaphore on each existing node in cluster so that nothing
 			# can get moved to the nodes during this process
 			$checkend = unixToDatetime($endts + 900);
 			foreach($request["reservations"] as $res) {
@@ -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');
@@ -1721,7 +1721,7 @@
 			$node['id'] = $id;
 			array_push($nodes, $node);
 			array_push($stack, $node);
-		} 
+		}
 		while(count($stack)) {
 			$item = array_shift($stack);
 			$children = getChildNodes($item['id']);
@@ -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');
@@ -1962,7 +1962,7 @@
 
 	$privileges = array();
 	$nodePrivileges = getNodePrivileges($nodeid, 'usergroups');
-	$cascadedNodePrivileges = getNodeCascadePrivileges($nodeid, 'usergroups'); 
+	$cascadedNodePrivileges = getNodeCascadePrivileges($nodeid, 'usergroups');
 	$cngp = $cascadedNodePrivileges['usergroups'];
 	$ngp = $nodePrivileges['usergroups'];
 	if(array_key_exists($groupid, $cngp)) {
@@ -2180,7 +2180,7 @@
 			             'errormsg' => 'resource group does not exist');
 		}
 		$np = getNodePrivileges($nodeid, 'resources');
-		$cnp = getNodeCascadePrivileges($nodeid, 'resources'); 
+		$cnp = getNodeCascadePrivileges($nodeid, 'resources');
 		$key = "$type/$name/$groupid";
 		if(isset($np['resources'][$key]['block']) || ! isset($cnp['resources'][$key]))
 			$privs = array_keys($np['resources'][$key]);
@@ -2399,9 +2399,9 @@
 	// Filter out any groups to which the user does not have access.
 	$usergroups = array();
 	foreach($groups as $id => $group) {
-		if($group['ownerid'] == $user['id'] || 
+		if($group['ownerid'] == $user['id'] ||
 		   (array_key_exists("editgroupid", $group) &&
-		   array_key_exists($group['editgroupid'], $user["groups"])) || 
+		   array_key_exists($group['editgroupid'], $user["groups"])) ||
 		   (array_key_exists($id, $user["groups"]))) {
 			array_push($usergroups, $group);
 		}
@@ -2470,13 +2470,13 @@
 	       . "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');
 	}
 	// if not owner and not member of managing group, no access
-	if($user['id'] != $row['ownerid'] && 
+	if($user['id'] != $row['ownerid'] &&
 	   ! array_key_exists($row['editgroupid'], $user['groups'])) {
 		return array('status' => 'error',
 		             'errorcode' => 69,
@@ -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,12 +2849,12 @@
 	       . "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');
 	}
-	// if custom and not owner and not member of managing group or 
+	// if custom and not owner and not member of managing group or
 	//    custom/courseroll and no federated user group access, no access to delete group
 	if(($row['custom'] == 1 && $user['id'] != $row['ownerid'] &&
 	   ! array_key_exists($row['editgroupid'], $user['groups'])) ||
@@ -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,13 +2924,13 @@
 	       . "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');
 	}
 	// if not owner and not member of managing group, no access
-	if($user['id'] != $row['ownerid'] && 
+	if($user['id'] != $row['ownerid'] &&
 	   ! array_key_exists($row['editgroupid'], $user['groups'])) {
 		return array('status' => 'error',
 		             'errorcode' => 28,
@@ -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,13 +3006,13 @@
 	       . "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');
 	}
 	// if not owner and not member of managing group, no access
-	if($user['id'] != $row['ownerid'] && 
+	if($user['id'] != $row['ownerid'] &&
 	   ! array_key_exists($row['editgroupid'], $user['groups'])) {
 		return array('status' => 'error',
 		             'errorcode' => 28,
@@ -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');
@@ -3655,7 +3655,7 @@
 	$stagCnt = 0;
 	$stagTime = 60;        # stagger reload reservations by 1 min
 	if($imgLoadTime > 840) // if estimated load time is > 14 min
-		$stagTime = 120;    #    stagger reload reservations by 2 min 
+		$stagTime = 120;    #    stagger reload reservations by 2 min
 	for($i = 0; $i < $reqToAlloc; $i++) {
 		$stagunixstart = $unixstart - $loadtime - ($stagCnt * $stagTime);
 		$stagstart = unixToDatetime($stagunixstart);
@@ -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.");
@@ -4003,8 +4003,8 @@
 	        . "LEFT JOIN OS os ON (i.OSid = os.id) "
 	        . "LEFT JOIN ("
 	        .      "SELECT rs.imageid, "
-	        .             "MAX(rq.id) AS requestid, " 
-	        .             "COUNT(rq.id) AS reqcount " 
+	        .             "MAX(rq.id) AS requestid, "
+	        .             "COUNT(rq.id) AS reqcount "
 	        .      "FROM reservation rs, "
 	        .           "request rq "
 	        .      "WHERE rs.requestid = rq.id AND "
@@ -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']))
@@ -4200,7 +4200,7 @@
 		             'errormsg' => "Specified duration is too long",
 		             'maxduration' => $allowed);
 	}
-	
+
 	$query = "SELECT id "
 	       . "FROM oneclick "
 	       . "WHERE id = $oneclickid AND "
@@ -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.");
@@ -4218,7 +4218,7 @@
 		             'errorcode' => 90,
 		             'errormsg' => "The OneClick with ID $oneclickid does not belong to the user that requested it.");
 	}*/
-	
+
 	$query = "UPDATE oneclick "
 	       . "SET imageid = $imageid, "
 	       .     "name = '$name', "
@@ -4255,14 +4255,14 @@
 function XMLRPCdeleteOneClick($oneclickid) {
 	global $user;
 	$oneclickid = processInputData($oneclickid, ARG_NUMERIC);
-	
+
 	$query = "SELECT id "
 	       . "FROM oneclick "
 	       . "WHERE id = $oneclickid AND "
 	       .       "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..e8a48b8 100644
--- a/web/index.php
+++ b/web/index.php
@@ -16,18 +16,19 @@
   limitations under the License.
 */
 
-# ASF VCL v2.5
-$VCLversion = '2.5';
+# ASF VCL v2.5.1
+$VCLversion = '2.5.1';
 
 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 = '';
+$user = array();
 $mode = '';
 $oldmode = '';
 $submitErr = '';
diff --git a/web/js/code.js b/web/js/code.js
index 0b2c024..3391500 100644
--- a/web/js/code.js
+++ b/web/js/code.js
@@ -226,7 +226,7 @@
 	if(document.styleSheets[0].cssRules)  // Standards Compliant
 		cssobj = document.styleSheets[0].cssRules;
 	else
-		cssobj = document.styleSheets[0].rules;  // IE 
+		cssobj = document.styleSheets[0].rules;  // IE
 	var stop = 0;
 	for(var i = 0; i < cssobj.length; i++) {
 		if(cssobj[i].selectorText) {
diff --git a/web/js/dashboard.js b/web/js/dashboard.js
index 59922f2..0591c5c 100644
--- a/web/js/dashboard.js
+++ b/web/js/dashboard.js
@@ -203,6 +203,7 @@
 	    +  '<th>ReqID</th>'
 	    +  '<th>User</th>'
 	    +  '<th>Computer</th>'
+	    +  '<th>VM Host</th>'
 	    +  '<th>States</th>'
 	    +  '<th>Image</th>'
 	    +  '<th>Install Type</th>'
@@ -222,6 +223,8 @@
 		    + '</td><td style=\"padding: 1px; border-right: 1px solid;\">'
 		    + data[i].computer
 		    + '</td><td style=\"padding: 1px; border-right: 1px solid;\">'
+		    + data[i].vmhost
+		    + '</td><td style=\"padding: 1px; border-right: 1px solid;\">'
 		    + data[i].state
 		    + '</td><td style=\"padding: 1px; border-right: 1px solid;\">'
 		    + data[i].image
diff --git a/web/js/nls/es_CR/messages.js b/web/js/nls/es_CR/messages.js
index 1ea2d26..1fdc787 100644
--- a/web/js/nls/es_CR/messages.js
+++ b/web/js/nls/es_CR/messages.js
@@ -146,5 +146,10 @@
 'Invalid item submitted to save':'Elemento inválido para guardar',
 'Message successfully saved':'Mensaje guardado satisfactoriamente',
 'No changes to submitted message. Nothing saved.':'Sin cambios en el mensaje. Nada guardado.',
-'unset':'sin especificar'
+'unset':'sin especificar',
+'1 hour':'',
+'Default for User':'',
+'Invalid Max Reservation Duration selected':'',
+'minutes':'',
+'Passwords do not match':''
 }
diff --git a/web/js/nls/es_MX/messages.js b/web/js/nls/es_MX/messages.js
index 990c81a..bfe4500 100644
--- a/web/js/nls/es_MX/messages.js
+++ b/web/js/nls/es_MX/messages.js
@@ -146,5 +146,10 @@
 'Invalid item submitted to save':'',
 'Message successfully saved':'',
 'No changes to submitted message. Nothing saved.':'',
-'unset':''
+'unset':'',
+'1 hour':'',
+'Default for User':'',
+'Invalid Max Reservation Duration selected':'',
+'minutes':'',
+'Passwords do not match':''
 }
diff --git a/web/js/nls/fr_CA/messages.js b/web/js/nls/fr_CA/messages.js
index fb82d8b..0e230ac 100644
--- a/web/js/nls/fr_CA/messages.js
+++ b/web/js/nls/fr_CA/messages.js
@@ -146,5 +146,10 @@
 'Invalid item submitted to save':'',
 'Message successfully saved':'',
 'No changes to submitted message. Nothing saved.':'',
-'unset':''
+'unset':'',
+'1 hour':'',
+'Default for User':'',
+'Invalid Max Reservation Duration selected':'',
+'minutes':'',
+'Passwords do not match':''
 }
diff --git a/web/js/nls/messages.js.template b/web/js/nls/messages.js.template
index 2f6abba..60cee37 100644
--- a/web/js/nls/messages.js.template
+++ b/web/js/nls/messages.js.template
@@ -146,5 +146,10 @@
 'Invalid item submitted to save':'',
 'Message successfully saved':'',
 'No changes to submitted message. Nothing saved.':'',
-'unset':''
+'unset':'',
+'1 hour':'',
+'Default for User':'',
+'Invalid Max Reservation Duration selected':'',
+'minutes':'',
+'Passwords do not match':''
 }
diff --git a/web/js/nls/pt_PT/messages.js b/web/js/nls/pt_PT/messages.js
index 6e9beaa..62c3c88 100644
--- a/web/js/nls/pt_PT/messages.js
+++ b/web/js/nls/pt_PT/messages.js
@@ -146,5 +146,10 @@
 'Invalid item submitted to save':'',
 'Message successfully saved':'',
 'No changes to submitted message. Nothing saved.':'',
-'unset':''
+'unset':'',
+'1 hour':'',
+'Default for User':'',
+'Invalid Max Reservation Duration selected':'',
+'minutes':'',
+'Passwords do not match':''
 }
diff --git a/web/js/requests.js b/web/js/requests.js
index 8cfe95f..b8272f9 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)
@@ -876,7 +875,7 @@
 	oldstore = dijit.byId('configvariables').store;
 	dijit.byId('configvariables').setStore(newstore2, '', {query: {id: ''}});
 	delete oldstore;
-	
+
 	// finishconfigs
 	/*if(data.items.configs.length == 0)
 		dijit.byId('newResDlgShowConfigBtn').set('disabled', true);
@@ -1389,7 +1388,7 @@
 		dijit.byId('serverdeletedlg').show();
 		return;
 	}
-	if(dijit.byId('serverdeletedlg') && 
+	if(dijit.byId('serverdeletedlg') &&
 	   dijit.byId('serverdeletedlg').open) {
 		dijit.byId('serverdeletedlg').hide();
 		dijit.byId('serverDeleteDlgBtn').set('disabled', false);
@@ -1553,7 +1552,7 @@
 		data.day = dijit.byId('day').value;
 	if(dijit.byId('editstarttime')) {
 		var t = dijit.byId('editstarttime').value;
-		data.starttime = dojox.string.sprintf('%02d%02d', 
+		data.starttime = dojox.string.sprintf('%02d%02d',
 		                                      t.getHours(),
 		                                      t.getMinutes());
 		var tmp = dijit.byId('day').value.match(/([0-9]{4})([0-9]{2})([0-9]{2})/);
@@ -1584,7 +1583,7 @@
 		data.endmode = 'length';
 	}
 	else if((dojo.byId('dateradio') && dojo.byId('dateradio').checked) ||
-	        (dijit.byId('openenddate') && ! dojo.byId('indefiniteradio')) || 
+	        (dijit.byId('openenddate') && ! dojo.byId('indefiniteradio')) ||
 	        (dijit.byId('openenddate') && dojo.byId('indefiniteradio') && ! dojo.byId('indefiniteradio').checked)) {
 		var d = dijit.byId('openenddate').value;
 		var t = dijit.byId('openendtime').value;
diff --git a/web/js/resources/addomain.js b/web/js/resources/addomain.js
index 4579a24..cffbf94 100644
--- a/web/js/resources/addomain.js
+++ b/web/js/resources/addomain.js
@@ -21,6 +21,16 @@
 }
 ADdomain.prototype = new Resource();
 
+ADdomain.prototype.colformatter = function(value, rowIndex, obj) {
+	if(obj.field == 'usedbhostnames') {
+		if(value == "0")
+			return '<span class="rederrormsg">' + _('false') + '</span>';
+		if(value == "1")
+			return '<span class="ready">' + _('true') + '</span>';
+	}
+	return value;
+}
+
 var resource = new ADdomain();
 
 function addNewResource(title) {
@@ -41,11 +51,10 @@
 		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);
-
+		dijit.byId('usedbhostnames').set('checked', parseInt(data.items.data.usedbhostnames))
 		dijit.byId('password').set('value', '********');
 		dijit.byId('password2').set('value', 'xxxxxxxx');
 
@@ -58,7 +67,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 +98,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);
 }
@@ -125,7 +140,7 @@
 			resourcegrid.store.fetch({
 				query: {id: data.items.data.id},
 				onItem: function(item) {
-					var fields = ['name', 'owner', 'domaindnsname', 'username','dnsservers'];
+					var fields = ['name', 'owner', 'domaindnsname', 'username', 'usedbhostnames', 'dnsservers'];
 					for(var i = 0; i < fields.length; i++) {
 						dijit.byId(fields[i]).reset();
 						resourcegrid.store.setValue(item, fields[i], data.items.data[fields[i]]);
diff --git a/web/js/resources/computer.js b/web/js/resources/computer.js
index 6e511ea..dd08e37 100644
--- a/web/js/resources/computer.js
+++ b/web/js/resources/computer.js
@@ -210,6 +210,32 @@
 	return 0;
 }
 
+Computer.prototype.ipsort = function(a, b) {
+	var aparts = a.split('.');
+	var bparts = b.split('.');
+	for(var i = 0; i < 4; i++) {
+		aparts[i] = parseInt(aparts[i]);
+		bparts[i] = parseInt(bparts[i]);
+	}
+	if(aparts[0] < bparts[0])
+		return -1;
+	if(aparts[0] > bparts[0])
+		return 1;
+	if(aparts[1] < bparts[1])
+		return -1;
+	if(aparts[1] > bparts[1])
+		return 1;
+	if(aparts[2] < bparts[2])
+		return -1;
+	if(aparts[2] > bparts[2])
+		return 1;
+	if(aparts[3] < bparts[3])
+		return -1;
+	if(aparts[3] > bparts[3])
+		return 1;
+	return 0;
+}
+
 Computer.prototype.comparehostnames = function(a, b) {
 	// get hostname
 	var tmp = a.split('.');
@@ -291,6 +317,8 @@
 		resourcestore.comparatorMap['procnumber'] = resource.nocasesort;
 		resourcestore.comparatorMap['procspeed'] = resource.nocasesort;
 		resourcestore.comparatorMap['network'] = resource.nocasesort;
+		resourcestore.comparatorMap['IPaddress'] = resource.ipsort;
+		resourcestore.comparatorMap['privateIPaddress'] = resource.ipsort;
 
 		dojo.connect(resourcegrid, '_onFetchComplete', function() {dojo.byId('computercount').innerHTML = 'Computers in table: ' + resourcegrid.rowCount;});
 	}
@@ -1216,7 +1244,9 @@
 	                               procnumber: resource.nocasesort,
 	                               procspeed: resource.nocasesort,
 	                               network: resource.nocasesort,
-	                               ram: resource.nocasesort};
+	                               ram: resource.nocasesort,
+	                               IPaddress: resource.ipsort,
+	                               privateIPaddress: resource.ipsort};
 	resourcestore.fetch();
 	savescroll = resourcegrid.scrollTop;
 	resourcegrid.setStore(resourcestore, resourcegrid.query);
diff --git a/web/js/resources/image.js b/web/js/resources/image.js
index dad3f47..4ad565d 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
@@ -117,6 +137,12 @@
 	}
 }
 
+function initAddDialog() {
+	if(dijit.byId('addomainid').options.length == 0) {
+		dijit.byId('adauthenable').set('disabled', true);
+	}
+}
+
 function delayedEditResize() {
 	setTimeout(function() {resizeRecenterDijitDialog('addeditdlg');}, 300);
 }
@@ -257,6 +283,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 +372,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);
@@ -755,6 +787,7 @@
 function submitCreateUpdateImage() {
 	if(dojo.byId('newimage').checked) {
 		dijit.byId('addeditdlg').show();
+		initAddDialog();
 		dijit.byId('startimagedlg').hide();
 		return;
 	}
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/js/vm.js b/web/js/vm.js
index 0864f9a..b56313b 100644
--- a/web/js/vm.js
+++ b/web/js/vm.js
@@ -183,6 +183,8 @@
 	if(data.items.failed) {
 		if(data.items.failed == 'nohostaccess')
 			alert('You do not have access to manage this VM host.');
+		if(data.items.failed == 'invaliddata')
+			alert('Invalid list of VMs submitted.');
 		document.body.style.cursor = 'default';
 		return;
 	}
@@ -300,15 +302,18 @@
 		handleAs: "json",
 		error: errorHandler,
 		content: {continuation: cont,
-					 listids: listids.join(','),
-					 hostid: hostid},
+		          listids: listids.join(','),
+		          hostid: hostid},
 		timeout: 15000
 	});
 }
 
 function vmFromHostCB(data, ioArgs) {
 	if(data.items.failed) {
-		alert('You do not have access to manage this VM host.');
+		if(data.items.failed == 'nohostaccess')
+			alert('You do not have access to manage this VM host.');
+		if(data.items.failed == 'invaliddata')
+			alert('Invalid list of VMs submitted.');
 		document.body.style.cursor = 'default';
 		return;
 	}
@@ -412,7 +417,10 @@
 
 function reloadVMhostCB(data, ioArgs) {
 	if(data.items.failed) {
-		alert('You do not have access to manage this VM host.');
+		if(data.items.failed == 'nohostaccess')
+			alert('You do not have access to manage this VM host.');
+		if(data.items.failed == 'invaliddata')
+			alert('Invalid list of VMs submitted.');
 		document.body.style.cursor = 'default';
 		return;
 	}
diff --git a/web/locale/es_CR/LC_MESSAGES/vcl.mo b/web/locale/es_CR/LC_MESSAGES/vcl.mo
index 6e0939d..ad75cab 100644
--- a/web/locale/es_CR/LC_MESSAGES/vcl.mo
+++ b/web/locale/es_CR/LC_MESSAGES/vcl.mo
Binary files differ
diff --git a/web/locale/es_MX/LC_MESSAGES/vcl.mo b/web/locale/es_MX/LC_MESSAGES/vcl.mo
index 6675116..eb80d0c 100644
--- a/web/locale/es_MX/LC_MESSAGES/vcl.mo
+++ b/web/locale/es_MX/LC_MESSAGES/vcl.mo
Binary files differ
diff --git a/web/locale/fr_CA/LC_MESSAGES/vcl.mo b/web/locale/fr_CA/LC_MESSAGES/vcl.mo
index a635d1f..d67a77d 100644
--- a/web/locale/fr_CA/LC_MESSAGES/vcl.mo
+++ b/web/locale/fr_CA/LC_MESSAGES/vcl.mo
Binary files differ
diff --git a/web/locale/ja_JP/LC_MESSAGES/vcl.mo b/web/locale/ja_JP/LC_MESSAGES/vcl.mo
index 2e180d4..0766682 100644
--- a/web/locale/ja_JP/LC_MESSAGES/vcl.mo
+++ b/web/locale/ja_JP/LC_MESSAGES/vcl.mo
Binary files differ
diff --git a/web/locale/po_files/es_CR/vcl.po b/web/locale/po_files/es_CR/vcl.po
index d524480..8e7af8c 100644
--- a/web/locale/po_files/es_CR/vcl.po
+++ b/web/locale/po_files/es_CR/vcl.po
@@ -14,10 +14,10 @@
 # limitations under the License.
 msgid ""
 msgstr ""
-"Project-Id-Version: Apache VCL 2.5\n"
+"Project-Id-Version: VCL 2.5.1\n"
 "Report-Msgid-Bugs-To: dev@vcl.apache.org\n"
 "POT-Creation-Date: 2016-07-14 22:19-0400\n"
-"PO-Revision-Date: 2017-06-07 13:36-0600\n"
+"PO-Revision-Date: 2019-06-13 15:18-0400\n"
 "Last-Translator: Luis Zárate <luis.zarate@solvosoft.com>\n"
 "Language-Team: \n"
 "Language: es_CR\n"
@@ -26,6 +26,93 @@
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: Poedit 1.6.10\n"
 
+#: addomain.php:172
+msgid ""
+"Error encountered while trying to create new AD domain. Please contact an "
+"admin for assistance."
+msgstr ""
+
+#: addomain.php:420 addomain.php:538
+msgid ""
+"Domain DNS Name should be in the format domain.tld and can only contain "
+"letters, numbers, dashes(-), periods(.), and underscores(_) (e.g. "
+"myuniversity.edu)"
+msgstr ""
+
+#: addomain.php:421
+msgid "Domain DNS Name"
+msgstr ""
+
+#. username
+#: addomain.php:424 addomain.php:543
+msgid ""
+"Username cannot contain single (') or double (&quot;) quotes, less than "
+"(&lt;), or greater than (&gt;) and can be from 2 to 64 characters long"
+msgstr ""
+
+#: addomain.php:425
+msgid "Username"
+msgstr ""
+
+#. password
+#: addomain.php:428 addomain.php:550
+msgid "Password must be at least 4 characters long"
+msgstr ""
+
+#. confirm password
+#: addomain.php:431
+msgid "Confirm Password"
+msgstr ""
+
+#. use database hostname checkbox
+#: addomain.php:433
+msgid "Use Database Hostnames"
+msgstr ""
+
+#: addomain.php:439
+msgid "DNS Server(s)"
+msgstr ""
+
+#: addomain.php:458
+msgid ""
+"Each AD Domain should be a member of an AD Domain resource group. The "
+"following dialog will allow you to add the new AD Domain to a group."
+msgstr ""
+
+#: addomain.php:480
+msgid ""
+"domain name registered in DNS for Active Directory Domain (ex: ad.example."
+"com)"
+msgstr ""
+
+#: addomain.php:481
+msgid "These credentials will be used to register reserved computers with AD."
+msgstr ""
+
+#: addomain.php:482
+msgid ""
+"comma delimited list of IP addresses for DNS servers that handle Domain DNS"
+msgstr ""
+
+#: addomain.php:483
+msgid ""
+"Check this option if you like to have the computer object names within AD to "
+"match VM hostname stored within the VCL database"
+msgstr ""
+
+#: addomain.php:529
+msgid "An AD domain already exists with this name."
+msgstr ""
+
+#: addomain.php:533
+msgid "Submitted owner is not valid"
+msgstr ""
+
+#: addomain.php:561
+msgid ""
+"Invalid IP address specified for DNS Server - must be a valid IPV4 address"
+msgstr ""
+
 #: authentication.php:157 utils.php:828
 msgid "Welcome to the Virtual Computing Lab"
 msgstr "Bienvenido al Laboratorio Virtual de Cómputo"
@@ -1273,6 +1360,10 @@
 msgid "Location"
 msgstr "Ubicación"
 
+#: groups.php:286
+msgid "Delete Group"
+msgstr ""
+
 #: help.php:216 help.php:248
 msgid "Authentication Method"
 msgstr "Métodos de autenticación"
@@ -1769,6 +1860,18 @@
 "La siguientes revisiones están en uso y no pueden ser borradas en este "
 "momento"
 
+#: image.php:150 image.php:438
+msgid "Max Reservation Duration"
+msgstr ""
+
+#: image.php:1756
+msgid "Invalid Max Reservation Duration selected"
+msgstr ""
+
+#: image.php:1777
+msgid "Base OU cannot be changed for the selected AD Domain"
+msgstr ""
+
 #: managementnode.php:295
 msgid ""
 "Name can only contain letters, numbers, dashes(-), periods(.), and "
@@ -3417,6 +3520,14 @@
 "%s  está ahora en el proceso de actualización para usar nuevamente "
 "revisiones creadas."
 
+#: requests.php:1069
+msgid "Reservation is in maintenance - Contact admin for help"
+msgstr ""
+
+#: requests.php:1075
+msgid "Reservation is being captured"
+msgstr ""
+
 #: resource.php:172
 msgid "Edit Grouping &amp; Mapping"
 msgstr "Editar agrupación &amp; mapeo"
@@ -3845,7 +3956,7 @@
 "message has a default. Additionally, separate messages can be configured for "
 "each affiliation. Most of the messages will have parts that are in square "
 "brackets. These parts will have data substituted for them before the message "
-"is sent. A list of what can be used in squeare brackets can be found at the "
+"is sent. A list of what can be used in square brackets can be found at the "
 "<a href=\"%s\">Apache VCL web site</a>. Some messages also have a short form "
 "that may be sent such as in the form of a popup within a reservation when "
 "the reservation is about to end."
@@ -3911,6 +4022,192 @@
 msgid "No changes to submitted message. Nothing saved."
 msgstr "No hay cambios en el mensaje enviado. Nada se guardó"
 
+#: siteconfig.php:873
+msgid "Failed to update data for these affiliations:"
+msgstr ""
+
+#: siteconfig.php:979
+msgid "Default value"
+msgstr ""
+
+#: siteconfig.php:1064
+msgid "You do not have access to modify the submitted setting."
+msgstr ""
+
+#: siteconfig.php:1090
+msgid "Failed to add submited value"
+msgstr ""
+
+#: siteconfig.php:1228
+#, php-format
+msgid "Failed to delete address for %s"
+msgstr ""
+
+#: siteconfig.php:1272
+msgid "Help Email Address"
+msgstr ""
+
+#: siteconfig.php:1273
+msgid ""
+"This is the email address used as the from address for emails sent by the "
+"VCL system to users."
+msgstr ""
+
+#: siteconfig.php:1278
+#, php-format
+msgid "Help Email Address added for %s"
+msgstr ""
+
+#: siteconfig.php:1279 siteconfig.php:1378 siteconfig.php:1478
+#: siteconfig.php:1681 siteconfig.php:1813 siteconfig.php:1923
+msgid "Update successful"
+msgstr ""
+
+#: siteconfig.php:1280
+#, php-format
+msgid "Address for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1371
+msgid "Site Web Address"
+msgstr ""
+
+#: siteconfig.php:1372
+msgid "This is the web address in emails sent by the VCL system to users."
+msgstr ""
+
+#: siteconfig.php:1374
+msgid "Invalid web address(es) specified"
+msgstr ""
+
+#: siteconfig.php:1377
+#, php-format
+msgid "Web Address added for %s"
+msgstr ""
+
+#: siteconfig.php:1379
+#, php-format
+msgid "Web Address for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1470
+msgid "KMS Servers"
+msgstr ""
+
+#: siteconfig.php:1471
+msgid ""
+"These are the KMS servers for activating Windows licensing. Multiple servers "
+"are allowed, delimited with a comma (,). Non standard ports can be specified "
+"after the server delimited with a colon (:). (ex: kms.example.com,kms2."
+"example.com:2000)"
+msgstr ""
+
+#: siteconfig.php:1474
+msgid "Invalid IP or hostname specified"
+msgstr ""
+
+#: siteconfig.php:1477
+#, php-format
+msgid "KMS server added for %s"
+msgstr ""
+
+#: siteconfig.php:1479
+#, php-format
+msgid "KMS server for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1675
+msgid "Site Theme"
+msgstr ""
+
+#: siteconfig.php:1676
+msgid "This controls the theme of the site displayed for each affiliation."
+msgstr ""
+
+#: siteconfig.php:1677
+msgid "Invalid theme specified"
+msgstr ""
+
+#: siteconfig.php:1680
+#, php-format
+msgid "Theme setting added for %s"
+msgstr ""
+
+#: siteconfig.php:1682
+#, php-format
+msgid "Theme setting for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1807
+msgid "LDAP Lookup for Shibboleth Authenticated Users"
+msgstr ""
+
+#: siteconfig.php:1808
+msgid ""
+"If an affiliation gets configured for Shibboleth authentication, this "
+"specifies that LDAP authentication has also been configured for that "
+"affiliation so that VCL can perform lookups for new users before they log in "
+"to VCL."
+msgstr ""
+
+#: siteconfig.php:1812
+#, php-format
+msgid "LDAP lookup setting added for %s"
+msgstr ""
+
+#: siteconfig.php:1814
+#, php-format
+msgid "LDAP lookup setting for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1819 siteconfig.php:1928
+msgid "Local"
+msgstr ""
+
+#: siteconfig.php:1917
+msgid "Shibboleth Scope"
+msgstr ""
+
+#: siteconfig.php:1918
+msgid ""
+"This is the Shibboleth scope for an affiliation when Shibboleth "
+"authentication is enabled."
+msgstr ""
+
+#: siteconfig.php:1922
+#, php-format
+msgid "Shibboleth scope added for %s"
+msgstr ""
+
+#: siteconfig.php:1924
+#, php-format
+msgid "Shibboleth scope for %s deleted"
+msgstr ""
+
+#: siteconfig.php:2851
+msgid "Affiliation sucessfully added; reloading page"
+msgstr ""
+
+#: siteconfig.php:2852
+msgid "Affiliation sucessfully deleted; reloading page"
+msgstr ""
+
+#: siteconfig.php:2853
+msgid "Values updated; reloading page"
+msgstr ""
+
+#: siteconfig.php:2855
+msgid "Invalid value - must"
+msgstr ""
+
+#: siteconfig.php:3078
+msgid "Affiliation already exists"
+msgstr ""
+
+#: siteconfig.php:3084
+msgid "Conflicting Affiliation submitted"
+msgstr ""
+
 #: statistics.php:44
 msgid "Statistic Information"
 msgstr "Información Estadística"
diff --git a/web/locale/po_files/es_MX/vcl.po b/web/locale/po_files/es_MX/vcl.po
index 647068d..7664d61 100644
--- a/web/locale/po_files/es_MX/vcl.po
+++ b/web/locale/po_files/es_MX/vcl.po
@@ -14,11 +14,11 @@
 # limitations under the License.
 msgid ""
 msgstr ""
-"Project-Id-Version: Apache VCL 2.5\n"
+"Project-Id-Version: VCL 2.5.1\n"
 "Report-Msgid-Bugs-To: dev@vcl.apache.org\n"
 "POT-Creation-Date: 2016-07-14 22:19-0400\n"
-"PO-Revision-Date: 2015-03-06 17:15-0500\n"
-"Last-Translator:  <jfthomps@apache.org>\n"
+"PO-Revision-Date: 2019-06-13 15:18-0400\n"
+"Last-Translator: Josh Thompson <jfthomps@apache.org>\n"
 "Language-Team: \n"
 "Language: es_MX\n"
 "MIME-Version: 1.0\n"
@@ -26,6 +26,93 @@
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: Poedit 1.5.5\n"
 
+#: addomain.php:172
+msgid ""
+"Error encountered while trying to create new AD domain. Please contact an "
+"admin for assistance."
+msgstr ""
+
+#: addomain.php:420 addomain.php:538
+msgid ""
+"Domain DNS Name should be in the format domain.tld and can only contain "
+"letters, numbers, dashes(-), periods(.), and underscores(_) (e.g. "
+"myuniversity.edu)"
+msgstr ""
+
+#: addomain.php:421
+msgid "Domain DNS Name"
+msgstr ""
+
+#. username
+#: addomain.php:424 addomain.php:543
+msgid ""
+"Username cannot contain single (') or double (&quot;) quotes, less than "
+"(&lt;), or greater than (&gt;) and can be from 2 to 64 characters long"
+msgstr ""
+
+#: addomain.php:425
+msgid "Username"
+msgstr ""
+
+#. password
+#: addomain.php:428 addomain.php:550
+msgid "Password must be at least 4 characters long"
+msgstr ""
+
+#. confirm password
+#: addomain.php:431
+msgid "Confirm Password"
+msgstr ""
+
+#. use database hostname checkbox
+#: addomain.php:433
+msgid "Use Database Hostnames"
+msgstr ""
+
+#: addomain.php:439
+msgid "DNS Server(s)"
+msgstr ""
+
+#: addomain.php:458
+msgid ""
+"Each AD Domain should be a member of an AD Domain resource group. The "
+"following dialog will allow you to add the new AD Domain to a group."
+msgstr ""
+
+#: addomain.php:480
+msgid ""
+"domain name registered in DNS for Active Directory Domain (ex: ad.example."
+"com)"
+msgstr ""
+
+#: addomain.php:481
+msgid "These credentials will be used to register reserved computers with AD."
+msgstr ""
+
+#: addomain.php:482
+msgid ""
+"comma delimited list of IP addresses for DNS servers that handle Domain DNS"
+msgstr ""
+
+#: addomain.php:483
+msgid ""
+"Check this option if you like to have the computer object names within AD to "
+"match VM hostname stored within the VCL database"
+msgstr ""
+
+#: addomain.php:529
+msgid "An AD domain already exists with this name."
+msgstr ""
+
+#: addomain.php:533
+msgid "Submitted owner is not valid"
+msgstr ""
+
+#: addomain.php:561
+msgid ""
+"Invalid IP address specified for DNS Server - must be a valid IPV4 address"
+msgstr ""
+
 #: authentication.php:157 utils.php:828
 msgid "Welcome to the Virtual Computing Lab"
 msgstr "Bienvenido al Laboratorio Virtual de Cómputo"
@@ -1010,6 +1097,10 @@
 msgid "Location"
 msgstr ""
 
+#: groups.php:286
+msgid "Delete Group"
+msgstr ""
+
 #: help.php:216 help.php:248
 msgid "Authentication Method"
 msgstr ""
@@ -1409,6 +1500,18 @@
 msgid "The following revisions are in use and cannot be deleted at this time:"
 msgstr ""
 
+#: image.php:150 image.php:438
+msgid "Max Reservation Duration"
+msgstr ""
+
+#: image.php:1756
+msgid "Invalid Max Reservation Duration selected"
+msgstr ""
+
+#: image.php:1777
+msgid "Base OU cannot be changed for the selected AD Domain"
+msgstr ""
+
 #: managementnode.php:295
 msgid "Name can only contain letters, numbers, dashes(-), periods(.), and underscores(_). It can be from 1 to 50 characters long."
 msgstr ""
@@ -2674,6 +2777,14 @@
 msgid "%s is now in the process of being updated to use the newly created revision."
 msgstr ""
 
+#: requests.php:1069
+msgid "Reservation is in maintenance - Contact admin for help"
+msgstr ""
+
+#: requests.php:1075
+msgid "Reservation is being captured"
+msgstr ""
+
 #: resource.php:172
 msgid "Edit Grouping &amp; Mapping"
 msgstr ""
@@ -2998,7 +3109,7 @@
 
 #: siteconfig.php:1517
 #, php-format
-msgid "This section allows for configuration of messages that are sent to users and administrators about things such as reservations and image management. Every message has a default. Additionally, separate messages can be configured for each affiliation. Most of the messages will have parts that are in square brackets. These parts will have data substituted for them before the message is sent. A list of what can be used in squeare brackets can be found at the <a href=\"%s\">Apache VCL web site</a>. Some messages also have a short form that may be sent such as in the form of a popup within a reservation when the reservation is about to end."
+msgid "This section allows for configuration of messages that are sent to users and administrators about things such as reservations and image management. Every message has a default. Additionally, separate messages can be configured for each affiliation. Most of the messages will have parts that are in square brackets. These parts will have data substituted for them before the message is sent. A list of what can be used in square brackets can be found at the <a href=\"%s\">Apache VCL web site</a>. Some messages also have a short form that may be sent such as in the form of a popup within a reservation when the reservation is about to end."
 msgstr ""
 
 #: siteconfig.php:1582
@@ -3042,6 +3153,192 @@
 msgid "No changes to submitted message. Nothing saved."
 msgstr ""
 
+#: siteconfig.php:873
+msgid "Failed to update data for these affiliations:"
+msgstr ""
+
+#: siteconfig.php:979
+msgid "Default value"
+msgstr ""
+
+#: siteconfig.php:1064
+msgid "You do not have access to modify the submitted setting."
+msgstr ""
+
+#: siteconfig.php:1090
+msgid "Failed to add submited value"
+msgstr ""
+
+#: siteconfig.php:1228
+#, php-format
+msgid "Failed to delete address for %s"
+msgstr ""
+
+#: siteconfig.php:1272
+msgid "Help Email Address"
+msgstr ""
+
+#: siteconfig.php:1273
+msgid ""
+"This is the email address used as the from address for emails sent by the "
+"VCL system to users."
+msgstr ""
+
+#: siteconfig.php:1278
+#, php-format
+msgid "Help Email Address added for %s"
+msgstr ""
+
+#: siteconfig.php:1279 siteconfig.php:1378 siteconfig.php:1478
+#: siteconfig.php:1681 siteconfig.php:1813 siteconfig.php:1923
+msgid "Update successful"
+msgstr ""
+
+#: siteconfig.php:1280
+#, php-format
+msgid "Address for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1371
+msgid "Site Web Address"
+msgstr ""
+
+#: siteconfig.php:1372
+msgid "This is the web address in emails sent by the VCL system to users."
+msgstr ""
+
+#: siteconfig.php:1374
+msgid "Invalid web address(es) specified"
+msgstr ""
+
+#: siteconfig.php:1377
+#, php-format
+msgid "Web Address added for %s"
+msgstr ""
+
+#: siteconfig.php:1379
+#, php-format
+msgid "Web Address for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1470
+msgid "KMS Servers"
+msgstr ""
+
+#: siteconfig.php:1471
+msgid ""
+"These are the KMS servers for activating Windows licensing. Multiple servers "
+"are allowed, delimited with a comma (,). Non standard ports can be specified "
+"after the server delimited with a colon (:). (ex: kms.example.com,kms2."
+"example.com:2000)"
+msgstr ""
+
+#: siteconfig.php:1474
+msgid "Invalid IP or hostname specified"
+msgstr ""
+
+#: siteconfig.php:1477
+#, php-format
+msgid "KMS server added for %s"
+msgstr ""
+
+#: siteconfig.php:1479
+#, php-format
+msgid "KMS server for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1675
+msgid "Site Theme"
+msgstr ""
+
+#: siteconfig.php:1676
+msgid "This controls the theme of the site displayed for each affiliation."
+msgstr ""
+
+#: siteconfig.php:1677
+msgid "Invalid theme specified"
+msgstr ""
+
+#: siteconfig.php:1680
+#, php-format
+msgid "Theme setting added for %s"
+msgstr ""
+
+#: siteconfig.php:1682
+#, php-format
+msgid "Theme setting for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1807
+msgid "LDAP Lookup for Shibboleth Authenticated Users"
+msgstr ""
+
+#: siteconfig.php:1808
+msgid ""
+"If an affiliation gets configured for Shibboleth authentication, this "
+"specifies that LDAP authentication has also been configured for that "
+"affiliation so that VCL can perform lookups for new users before they log in "
+"to VCL."
+msgstr ""
+
+#: siteconfig.php:1812
+#, php-format
+msgid "LDAP lookup setting added for %s"
+msgstr ""
+
+#: siteconfig.php:1814
+#, php-format
+msgid "LDAP lookup setting for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1819 siteconfig.php:1928
+msgid "Local"
+msgstr ""
+
+#: siteconfig.php:1917
+msgid "Shibboleth Scope"
+msgstr ""
+
+#: siteconfig.php:1918
+msgid ""
+"This is the Shibboleth scope for an affiliation when Shibboleth "
+"authentication is enabled."
+msgstr ""
+
+#: siteconfig.php:1922
+#, php-format
+msgid "Shibboleth scope added for %s"
+msgstr ""
+
+#: siteconfig.php:1924
+#, php-format
+msgid "Shibboleth scope for %s deleted"
+msgstr ""
+
+#: siteconfig.php:2851
+msgid "Affiliation sucessfully added; reloading page"
+msgstr ""
+
+#: siteconfig.php:2852
+msgid "Affiliation sucessfully deleted; reloading page"
+msgstr ""
+
+#: siteconfig.php:2853
+msgid "Values updated; reloading page"
+msgstr ""
+
+#: siteconfig.php:2855
+msgid "Invalid value - must"
+msgstr ""
+
+#: siteconfig.php:3078
+msgid "Affiliation already exists"
+msgstr ""
+
+#: siteconfig.php:3084
+msgid "Conflicting Affiliation submitted"
+msgstr ""
+
 #: statistics.php:44
 msgid "Statistic Information"
 msgstr "Información Estadística"
diff --git a/web/locale/po_files/fr_CA/vcl.po b/web/locale/po_files/fr_CA/vcl.po
index 20967d1..c0d7e13 100644
--- a/web/locale/po_files/fr_CA/vcl.po
+++ b/web/locale/po_files/fr_CA/vcl.po
@@ -14,10 +14,10 @@
 # limitations under the License.
 msgid ""
 msgstr ""
-"Project-Id-Version: Apache VCL 2.5\n"
+"Project-Id-Version: VCL 2.5.1\n"
 "Report-Msgid-Bugs-To: dev@vcl.apache.org\n"
 "POT-Creation-Date: 2016-07-14 22:19-0400\n"
-"PO-Revision-Date: 2015-04-16 15:07+0000\n"
+"PO-Revision-Date: 2019-06-13 15:18-0400\n"
 "Last-Translator: Charles Roger SIMEU <crsimeu@yahoo.fr>\n"
 "Language-Team: \n"
 "Language: fr_CA\n"
@@ -25,6 +25,93 @@
 "Content-Type: text/plain; charset=iso-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
 
+#: addomain.php:172
+msgid ""
+"Error encountered while trying to create new AD domain. Please contact an "
+"admin for assistance."
+msgstr ""
+
+#: addomain.php:420 addomain.php:538
+msgid ""
+"Domain DNS Name should be in the format domain.tld and can only contain "
+"letters, numbers, dashes(-), periods(.), and underscores(_) (e.g. "
+"myuniversity.edu)"
+msgstr ""
+
+#: addomain.php:421
+msgid "Domain DNS Name"
+msgstr ""
+
+#. username
+#: addomain.php:424 addomain.php:543
+msgid ""
+"Username cannot contain single (') or double (&quot;) quotes, less than "
+"(&lt;), or greater than (&gt;) and can be from 2 to 64 characters long"
+msgstr ""
+
+#: addomain.php:425
+msgid "Username"
+msgstr ""
+
+#. password
+#: addomain.php:428 addomain.php:550
+msgid "Password must be at least 4 characters long"
+msgstr ""
+
+#. confirm password
+#: addomain.php:431
+msgid "Confirm Password"
+msgstr ""
+
+#. use database hostname checkbox
+#: addomain.php:433
+msgid "Use Database Hostnames"
+msgstr ""
+
+#: addomain.php:439
+msgid "DNS Server(s)"
+msgstr ""
+
+#: addomain.php:458
+msgid ""
+"Each AD Domain should be a member of an AD Domain resource group. The "
+"following dialog will allow you to add the new AD Domain to a group."
+msgstr ""
+
+#: addomain.php:480
+msgid ""
+"domain name registered in DNS for Active Directory Domain (ex: ad.example."
+"com)"
+msgstr ""
+
+#: addomain.php:481
+msgid "These credentials will be used to register reserved computers with AD."
+msgstr ""
+
+#: addomain.php:482
+msgid ""
+"comma delimited list of IP addresses for DNS servers that handle Domain DNS"
+msgstr ""
+
+#: addomain.php:483
+msgid ""
+"Check this option if you like to have the computer object names within AD to "
+"match VM hostname stored within the VCL database"
+msgstr ""
+
+#: addomain.php:529
+msgid "An AD domain already exists with this name."
+msgstr ""
+
+#: addomain.php:533
+msgid "Submitted owner is not valid"
+msgstr ""
+
+#: addomain.php:561
+msgid ""
+"Invalid IP address specified for DNS Server - must be a valid IPV4 address"
+msgstr ""
+
 #: authentication.php:157 utils.php:828
 msgid "Welcome to the Virtual Computing Lab"
 msgstr "Bienvenue au laboratoire Informatique Virtuel (VCL)"
@@ -1009,6 +1096,10 @@
 msgid "Location"
 msgstr ""
 
+#: groups.php:286
+msgid "Delete Group"
+msgstr ""
+
 #: help.php:216 help.php:248
 msgid "Authentication Method"
 msgstr ""
@@ -1408,6 +1499,18 @@
 msgid "The following revisions are in use and cannot be deleted at this time:"
 msgstr "Les révisions suivantes sont en cours d'utilisation et ne peuvent être supprimées pour l'instant"
 
+#: image.php:150 image.php:438
+msgid "Max Reservation Duration"
+msgstr ""
+
+#: image.php:1756
+msgid "Invalid Max Reservation Duration selected"
+msgstr ""
+
+#: image.php:1777
+msgid "Base OU cannot be changed for the selected AD Domain"
+msgstr ""
+
 #: managementnode.php:295
 msgid "Name can only contain letters, numbers, dashes(-), periods(.), and underscores(_). It can be from 1 to 50 characters long."
 msgstr ""
@@ -2673,6 +2776,14 @@
 msgid "%s is now in the process of being updated to use the newly created revision."
 msgstr "%s est maintenant dans le processus de mise à jour pour utiliser la nouvelle révision créée"
 
+#: requests.php:1069
+msgid "Reservation is in maintenance - Contact admin for help"
+msgstr ""
+
+#: requests.php:1075
+msgid "Reservation is being captured"
+msgstr ""
+
 #: resource.php:172
 msgid "Edit Grouping &amp; Mapping"
 msgstr "Éditer les groupages et les mappages"
@@ -2997,7 +3108,7 @@
 
 #: siteconfig.php:1517
 #, php-format
-msgid "This section allows for configuration of messages that are sent to users and administrators about things such as reservations and image management. Every message has a default. Additionally, separate messages can be configured for each affiliation. Most of the messages will have parts that are in square brackets. These parts will have data substituted for them before the message is sent. A list of what can be used in squeare brackets can be found at the <a href=\"%s\">Apache VCL web site</a>. Some messages also have a short form that may be sent such as in the form of a popup within a reservation when the reservation is about to end."
+msgid "This section allows for configuration of messages that are sent to users and administrators about things such as reservations and image management. Every message has a default. Additionally, separate messages can be configured for each affiliation. Most of the messages will have parts that are in square brackets. These parts will have data substituted for them before the message is sent. A list of what can be used in square brackets can be found at the <a href=\"%s\">Apache VCL web site</a>. Some messages also have a short form that may be sent such as in the form of a popup within a reservation when the reservation is about to end."
 msgstr ""
 
 #: siteconfig.php:1582
@@ -3041,6 +3152,192 @@
 msgid "No changes to submitted message. Nothing saved."
 msgstr ""
 
+#: siteconfig.php:873
+msgid "Failed to update data for these affiliations:"
+msgstr ""
+
+#: siteconfig.php:979
+msgid "Default value"
+msgstr ""
+
+#: siteconfig.php:1064
+msgid "You do not have access to modify the submitted setting."
+msgstr ""
+
+#: siteconfig.php:1090
+msgid "Failed to add submited value"
+msgstr ""
+
+#: siteconfig.php:1228
+#, php-format
+msgid "Failed to delete address for %s"
+msgstr ""
+
+#: siteconfig.php:1272
+msgid "Help Email Address"
+msgstr ""
+
+#: siteconfig.php:1273
+msgid ""
+"This is the email address used as the from address for emails sent by the "
+"VCL system to users."
+msgstr ""
+
+#: siteconfig.php:1278
+#, php-format
+msgid "Help Email Address added for %s"
+msgstr ""
+
+#: siteconfig.php:1279 siteconfig.php:1378 siteconfig.php:1478
+#: siteconfig.php:1681 siteconfig.php:1813 siteconfig.php:1923
+msgid "Update successful"
+msgstr ""
+
+#: siteconfig.php:1280
+#, php-format
+msgid "Address for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1371
+msgid "Site Web Address"
+msgstr ""
+
+#: siteconfig.php:1372
+msgid "This is the web address in emails sent by the VCL system to users."
+msgstr ""
+
+#: siteconfig.php:1374
+msgid "Invalid web address(es) specified"
+msgstr ""
+
+#: siteconfig.php:1377
+#, php-format
+msgid "Web Address added for %s"
+msgstr ""
+
+#: siteconfig.php:1379
+#, php-format
+msgid "Web Address for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1470
+msgid "KMS Servers"
+msgstr ""
+
+#: siteconfig.php:1471
+msgid ""
+"These are the KMS servers for activating Windows licensing. Multiple servers "
+"are allowed, delimited with a comma (,). Non standard ports can be specified "
+"after the server delimited with a colon (:). (ex: kms.example.com,kms2."
+"example.com:2000)"
+msgstr ""
+
+#: siteconfig.php:1474
+msgid "Invalid IP or hostname specified"
+msgstr ""
+
+#: siteconfig.php:1477
+#, php-format
+msgid "KMS server added for %s"
+msgstr ""
+
+#: siteconfig.php:1479
+#, php-format
+msgid "KMS server for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1675
+msgid "Site Theme"
+msgstr ""
+
+#: siteconfig.php:1676
+msgid "This controls the theme of the site displayed for each affiliation."
+msgstr ""
+
+#: siteconfig.php:1677
+msgid "Invalid theme specified"
+msgstr ""
+
+#: siteconfig.php:1680
+#, php-format
+msgid "Theme setting added for %s"
+msgstr ""
+
+#: siteconfig.php:1682
+#, php-format
+msgid "Theme setting for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1807
+msgid "LDAP Lookup for Shibboleth Authenticated Users"
+msgstr ""
+
+#: siteconfig.php:1808
+msgid ""
+"If an affiliation gets configured for Shibboleth authentication, this "
+"specifies that LDAP authentication has also been configured for that "
+"affiliation so that VCL can perform lookups for new users before they log in "
+"to VCL."
+msgstr ""
+
+#: siteconfig.php:1812
+#, php-format
+msgid "LDAP lookup setting added for %s"
+msgstr ""
+
+#: siteconfig.php:1814
+#, php-format
+msgid "LDAP lookup setting for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1819 siteconfig.php:1928
+msgid "Local"
+msgstr ""
+
+#: siteconfig.php:1917
+msgid "Shibboleth Scope"
+msgstr ""
+
+#: siteconfig.php:1918
+msgid ""
+"This is the Shibboleth scope for an affiliation when Shibboleth "
+"authentication is enabled."
+msgstr ""
+
+#: siteconfig.php:1922
+#, php-format
+msgid "Shibboleth scope added for %s"
+msgstr ""
+
+#: siteconfig.php:1924
+#, php-format
+msgid "Shibboleth scope for %s deleted"
+msgstr ""
+
+#: siteconfig.php:2851
+msgid "Affiliation sucessfully added; reloading page"
+msgstr ""
+
+#: siteconfig.php:2852
+msgid "Affiliation sucessfully deleted; reloading page"
+msgstr ""
+
+#: siteconfig.php:2853
+msgid "Values updated; reloading page"
+msgstr ""
+
+#: siteconfig.php:2855
+msgid "Invalid value - must"
+msgstr ""
+
+#: siteconfig.php:3078
+msgid "Affiliation already exists"
+msgstr ""
+
+#: siteconfig.php:3084
+msgid "Conflicting Affiliation submitted"
+msgstr ""
+
 #: statistics.php:44
 msgid "Statistic Information"
 msgstr "Informations statistiques"
diff --git a/web/locale/po_files/ja_JP/vcl.po b/web/locale/po_files/ja_JP/vcl.po
index 71ce1de..547b1c5 100644
--- a/web/locale/po_files/ja_JP/vcl.po
+++ b/web/locale/po_files/ja_JP/vcl.po
@@ -15,7 +15,7 @@
 
 msgid ""
 msgstr ""
-"Project-Id-Version: VCL 2.5\n"
+"Project-Id-Version: VCL 2.5.1\n"
 "Report-Msgid-Bugs-To: dev@vcl.apache.org\n"
 "POT-Creation-Date: 2011-02-24 15:16+0900\n"
 "PO-Revision-Date: 2012-04-13 15:40-0500\n"
diff --git a/web/locale/po_files/pt_PT/vcl.po b/web/locale/po_files/pt_PT/vcl.po
index b1375b4..e904bdb 100644
--- a/web/locale/po_files/pt_PT/vcl.po
+++ b/web/locale/po_files/pt_PT/vcl.po
@@ -14,10 +14,10 @@
 # limitations under the License.
 msgid ""
 msgstr ""
-"Project-Id-Version: VCL 2.5\n"
+"Project-Id-Version: VCL 2.5.1\n"
 "Report-Msgid-Bugs-To: dev@vcl.apache.org\n"
 "POT-Creation-Date: 2016-07-14 22:19-0400\n"
-"PO-Revision-Date: 2015-04-22 13:44+0100\n"
+"PO-Revision-Date: 2019-06-13 15:18-0400\n"
 "Last-Translator: António Aragão <aaragao@di.uminho.pt>\n"
 "Language-Team: PT\n"
 "Language: pt\n"
@@ -26,6 +26,93 @@
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: Poedit 1.5.4\n"
 
+#: addomain.php:172
+msgid ""
+"Error encountered while trying to create new AD domain. Please contact an "
+"admin for assistance."
+msgstr ""
+
+#: addomain.php:420 addomain.php:538
+msgid ""
+"Domain DNS Name should be in the format domain.tld and can only contain "
+"letters, numbers, dashes(-), periods(.), and underscores(_) (e.g. "
+"myuniversity.edu)"
+msgstr ""
+
+#: addomain.php:421
+msgid "Domain DNS Name"
+msgstr ""
+
+#. username
+#: addomain.php:424 addomain.php:543
+msgid ""
+"Username cannot contain single (') or double (&quot;) quotes, less than "
+"(&lt;), or greater than (&gt;) and can be from 2 to 64 characters long"
+msgstr ""
+
+#: addomain.php:425
+msgid "Username"
+msgstr ""
+
+#. password
+#: addomain.php:428 addomain.php:550
+msgid "Password must be at least 4 characters long"
+msgstr ""
+
+#. confirm password
+#: addomain.php:431
+msgid "Confirm Password"
+msgstr ""
+
+#. use database hostname checkbox
+#: addomain.php:433
+msgid "Use Database Hostnames"
+msgstr ""
+
+#: addomain.php:439
+msgid "DNS Server(s)"
+msgstr ""
+
+#: addomain.php:458
+msgid ""
+"Each AD Domain should be a member of an AD Domain resource group. The "
+"following dialog will allow you to add the new AD Domain to a group."
+msgstr ""
+
+#: addomain.php:480
+msgid ""
+"domain name registered in DNS for Active Directory Domain (ex: ad.example."
+"com)"
+msgstr ""
+
+#: addomain.php:481
+msgid "These credentials will be used to register reserved computers with AD."
+msgstr ""
+
+#: addomain.php:482
+msgid ""
+"comma delimited list of IP addresses for DNS servers that handle Domain DNS"
+msgstr ""
+
+#: addomain.php:483
+msgid ""
+"Check this option if you like to have the computer object names within AD to "
+"match VM hostname stored within the VCL database"
+msgstr ""
+
+#: addomain.php:529
+msgid "An AD domain already exists with this name."
+msgstr ""
+
+#: addomain.php:533
+msgid "Submitted owner is not valid"
+msgstr ""
+
+#: addomain.php:561
+msgid ""
+"Invalid IP address specified for DNS Server - must be a valid IPV4 address"
+msgstr ""
+
 #: authentication.php:157 utils.php:828
 msgid "Welcome to the Virtual Computing Lab"
 msgstr "Bemvindo ao Laboratório de Computação Virtual"
@@ -695,6 +782,10 @@
 msgid "The end time for the submitted block allocation time has passed. Therefore, it can no longer be modified."
 msgstr "O tempo de finalização submetido para este bloco de alocação já passou. Sendo assim já não pode ser modificado."
 
+#: blockallocations.php:2860
+msgid "The selected Block Allocation no longer exists."
+msgstr "O Bloco de Alocação escolhido já não existe."
+
 #: blockallocations.php:2878
 msgid "Resources"
 msgstr "Recursos"
@@ -1006,6 +1097,10 @@
 msgid "Location"
 msgstr ""
 
+#: groups.php:286
+msgid "Delete Group"
+msgstr ""
+
 #: help.php:216 help.php:248
 msgid "Authentication Method"
 msgstr ""
@@ -1405,6 +1500,18 @@
 msgid "The following revisions are in use and cannot be deleted at this time:"
 msgstr "As seguintes revisões estão em uso e não podem ser excluídas neste momento:"
 
+#: image.php:150 image.php:438
+msgid "Max Reservation Duration"
+msgstr ""
+
+#: image.php:1756
+msgid "Invalid Max Reservation Duration selected"
+msgstr ""
+
+#: image.php:1777
+msgid "Base OU cannot be changed for the selected AD Domain"
+msgstr ""
+
 #: managementnode.php:295
 msgid "Name can only contain letters, numbers, dashes(-), periods(.), and underscores(_). It can be from 1 to 50 characters long."
 msgstr ""
@@ -2075,6 +2182,10 @@
 msgid "Please select the environment you want to use from the list:"
 msgstr "Por favor escolha um ambiente para usar através da seguinte lista:"
 
+#: requests.php:1530
+msgid "Please select a valid environment"
+msgstr "Por favor escolha um ambiente válido"
+
 #: requests.php:1546
 msgid "Reservation Name:"
 msgstr "Nome da Reserva:"
@@ -2288,6 +2399,10 @@
 msgid "Value:"
 msgstr "Valor:"
 
+#: requests.php:2611
+msgid "Value can only contain letters, numbers, spaces, dashes(-), parenthesis, <br>slashes(/), and periods(.) and can be from 3 to 255 characters long"
+msgstr ""
+
 #: requests.php:2621
 msgid "Required:"
 msgstr "Requerido:"
@@ -2662,6 +2777,14 @@
 msgid "%s is now in the process of being updated to use the newly created revision."
 msgstr "%s está agora em vias de ser atualizado para ser usado como nova revisão."
 
+#: requests.php:1069
+msgid "Reservation is in maintenance - Contact admin for help"
+msgstr ""
+
+#: requests.php:1075
+msgid "Reservation is being captured"
+msgstr ""
+
 #: resource.php:172
 msgid "Edit Grouping &amp; Mapping"
 msgstr "Alterando o Agrupamento &amp; Mapeando"
@@ -2986,7 +3109,7 @@
 
 #: siteconfig.php:1517
 #, php-format
-msgid "This section allows for configuration of messages that are sent to users and administrators about things such as reservations and image management. Every message has a default. Additionally, separate messages can be configured for each affiliation. Most of the messages will have parts that are in square brackets. These parts will have data substituted for them before the message is sent. A list of what can be used in squeare brackets can be found at the <a href=\"%s\">Apache VCL web site</a>. Some messages also have a short form that may be sent such as in the form of a popup within a reservation when the reservation is about to end."
+msgid "This section allows for configuration of messages that are sent to users and administrators about things such as reservations and image management. Every message has a default. Additionally, separate messages can be configured for each affiliation. Most of the messages will have parts that are in square brackets. These parts will have data substituted for them before the message is sent. A list of what can be used in square brackets can be found at the <a href=\"%s\">Apache VCL web site</a>. Some messages also have a short form that may be sent such as in the form of a popup within a reservation when the reservation is about to end."
 msgstr ""
 
 #: siteconfig.php:1582
@@ -3030,6 +3153,192 @@
 msgid "No changes to submitted message. Nothing saved."
 msgstr ""
 
+#: siteconfig.php:873
+msgid "Failed to update data for these affiliations:"
+msgstr ""
+
+#: siteconfig.php:979
+msgid "Default value"
+msgstr ""
+
+#: siteconfig.php:1064
+msgid "You do not have access to modify the submitted setting."
+msgstr ""
+
+#: siteconfig.php:1090
+msgid "Failed to add submited value"
+msgstr ""
+
+#: siteconfig.php:1228
+#, php-format
+msgid "Failed to delete address for %s"
+msgstr ""
+
+#: siteconfig.php:1272
+msgid "Help Email Address"
+msgstr ""
+
+#: siteconfig.php:1273
+msgid ""
+"This is the email address used as the from address for emails sent by the "
+"VCL system to users."
+msgstr ""
+
+#: siteconfig.php:1278
+#, php-format
+msgid "Help Email Address added for %s"
+msgstr ""
+
+#: siteconfig.php:1279 siteconfig.php:1378 siteconfig.php:1478
+#: siteconfig.php:1681 siteconfig.php:1813 siteconfig.php:1923
+msgid "Update successful"
+msgstr ""
+
+#: siteconfig.php:1280
+#, php-format
+msgid "Address for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1371
+msgid "Site Web Address"
+msgstr ""
+
+#: siteconfig.php:1372
+msgid "This is the web address in emails sent by the VCL system to users."
+msgstr ""
+
+#: siteconfig.php:1374
+msgid "Invalid web address(es) specified"
+msgstr ""
+
+#: siteconfig.php:1377
+#, php-format
+msgid "Web Address added for %s"
+msgstr ""
+
+#: siteconfig.php:1379
+#, php-format
+msgid "Web Address for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1470
+msgid "KMS Servers"
+msgstr ""
+
+#: siteconfig.php:1471
+msgid ""
+"These are the KMS servers for activating Windows licensing. Multiple servers "
+"are allowed, delimited with a comma (,). Non standard ports can be specified "
+"after the server delimited with a colon (:). (ex: kms.example.com,kms2."
+"example.com:2000)"
+msgstr ""
+
+#: siteconfig.php:1474
+msgid "Invalid IP or hostname specified"
+msgstr ""
+
+#: siteconfig.php:1477
+#, php-format
+msgid "KMS server added for %s"
+msgstr ""
+
+#: siteconfig.php:1479
+#, php-format
+msgid "KMS server for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1675
+msgid "Site Theme"
+msgstr ""
+
+#: siteconfig.php:1676
+msgid "This controls the theme of the site displayed for each affiliation."
+msgstr ""
+
+#: siteconfig.php:1677
+msgid "Invalid theme specified"
+msgstr ""
+
+#: siteconfig.php:1680
+#, php-format
+msgid "Theme setting added for %s"
+msgstr ""
+
+#: siteconfig.php:1682
+#, php-format
+msgid "Theme setting for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1807
+msgid "LDAP Lookup for Shibboleth Authenticated Users"
+msgstr ""
+
+#: siteconfig.php:1808
+msgid ""
+"If an affiliation gets configured for Shibboleth authentication, this "
+"specifies that LDAP authentication has also been configured for that "
+"affiliation so that VCL can perform lookups for new users before they log in "
+"to VCL."
+msgstr ""
+
+#: siteconfig.php:1812
+#, php-format
+msgid "LDAP lookup setting added for %s"
+msgstr ""
+
+#: siteconfig.php:1814
+#, php-format
+msgid "LDAP lookup setting for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1819 siteconfig.php:1928
+msgid "Local"
+msgstr ""
+
+#: siteconfig.php:1917
+msgid "Shibboleth Scope"
+msgstr ""
+
+#: siteconfig.php:1918
+msgid ""
+"This is the Shibboleth scope for an affiliation when Shibboleth "
+"authentication is enabled."
+msgstr ""
+
+#: siteconfig.php:1922
+#, php-format
+msgid "Shibboleth scope added for %s"
+msgstr ""
+
+#: siteconfig.php:1924
+#, php-format
+msgid "Shibboleth scope for %s deleted"
+msgstr ""
+
+#: siteconfig.php:2851
+msgid "Affiliation sucessfully added; reloading page"
+msgstr ""
+
+#: siteconfig.php:2852
+msgid "Affiliation sucessfully deleted; reloading page"
+msgstr ""
+
+#: siteconfig.php:2853
+msgid "Values updated; reloading page"
+msgstr ""
+
+#: siteconfig.php:2855
+msgid "Invalid value - must"
+msgstr ""
+
+#: siteconfig.php:3078
+msgid "Affiliation already exists"
+msgstr ""
+
+#: siteconfig.php:3084
+msgid "Conflicting Affiliation submitted"
+msgstr ""
+
 #: statistics.php:44
 msgid "Statistic Information"
 msgstr "Informação Estatística"
@@ -4056,9 +4365,6 @@
 msgid "monthly"
 msgstr "mensalmente"
 
-msgid "Please select a valid environment"
-msgstr "Por favor escolha um ambiente válido"
-
 msgid "starting install process"
 msgstr "começando o processo de instalação"
 
@@ -4107,9 +4413,6 @@
 msgid "starting virtual machine"
 msgstr ""
 
-msgid "The selected Block Allocation no longer exists."
-msgstr "O Bloco de Alocação escolhido já não existe."
-
 msgid "Log in"
 msgstr ""
 
diff --git a/web/locale/po_files/vcl.po.template b/web/locale/po_files/vcl.po.template
index beb7cf1..470becf 100644
--- a/web/locale/po_files/vcl.po.template
+++ b/web/locale/po_files/vcl.po.template
@@ -16,10 +16,10 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: VCL 2.5\n"
+"Project-Id-Version: VCL 2.5.1\n"
 "Report-Msgid-Bugs-To: dev@vcl.apache.org\n"
 "POT-Creation-Date: 2016-07-14 22:19-0400\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: 2019-06-13 15:18-0400\n"
 "Last-Translator: Josh Thompson <jfthomps@apache.org>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language: \n"
@@ -27,6 +27,92 @@
 "Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: 8bit\n"
 
+#: addomain.php:172
+msgid ""
+"Error encountered while trying to create new AD domain. Please contact an "
+"admin for assistance."
+msgstr ""
+
+#: addomain.php:420 addomain.php:538
+msgid ""
+"Domain DNS Name should be in the format domain.tld and can only contain "
+"letters, numbers, dashes(-), periods(.), and underscores(_) (e.g. "
+"myuniversity.edu)"
+msgstr ""
+
+#: addomain.php:421
+msgid "Domain DNS Name"
+msgstr ""
+
+#. username
+#: addomain.php:424 addomain.php:543
+msgid ""
+"Username cannot contain single (') or double (&quot;) quotes, less than "
+"(&lt;), or greater than (&gt;) and can be from 2 to 64 characters long"
+msgstr ""
+
+#: addomain.php:425
+msgid "Username"
+msgstr ""
+
+#. password
+#: addomain.php:428 addomain.php:550
+msgid "Password must be at least 4 characters long"
+msgstr ""
+
+#. confirm password
+#: addomain.php:431
+msgid "Confirm Password"
+msgstr ""
+
+#. use database hostname checkbox
+#: addomain.php:433
+msgid "Use Database Hostnames"
+msgstr ""
+
+#: addomain.php:439
+msgid "DNS Server(s)"
+msgstr ""
+
+#: addomain.php:458
+msgid ""
+"Each AD Domain should be a member of an AD Domain resource group. The "
+"following dialog will allow you to add the new AD Domain to a group."
+msgstr ""
+
+#: addomain.php:480
+msgid ""
+"domain name registered in DNS for Active Directory Domain (ex: ad.example."
+"com)"
+msgstr ""
+
+#: addomain.php:481
+msgid "These credentials will be used to register reserved computers with AD."
+msgstr ""
+
+#: addomain.php:482
+msgid ""
+"comma delimited list of IP addresses for DNS servers that handle Domain DNS"
+msgstr ""
+
+#: addomain.php:483
+msgid ""
+"Check this option if you like to have the computer object names within AD to "
+"match VM hostname stored within the VCL database"
+msgstr ""
+
+#: addomain.php:529
+msgid "An AD domain already exists with this name."
+msgstr ""
+
+#: addomain.php:533
+msgid "Submitted owner is not valid"
+msgstr ""
+
+#: addomain.php:561
+msgid ""
+"Invalid IP address specified for DNS Server - must be a valid IPV4 address"
+
 #: authentication.php:157 utils.php:828
 msgid "Welcome to the Virtual Computing Lab"
 msgstr ""
@@ -1011,6 +1097,10 @@
 msgid "Location"
 msgstr ""
 
+#: groups.php:286
+msgid "Delete Group"
+msgstr ""
+
 #: help.php:216 help.php:248
 msgid "Authentication Method"
 msgstr ""
@@ -1410,6 +1500,18 @@
 msgid "The following revisions are in use and cannot be deleted at this time:"
 msgstr ""
 
+#: image.php:150 image.php:438
+msgid "Max Reservation Duration"
+msgstr ""
+
+#: image.php:1756
+msgid "Invalid Max Reservation Duration selected"
+msgstr ""
+
+#: image.php:1777
+msgid "Base OU cannot be changed for the selected AD Domain"
+msgstr ""
+
 #: managementnode.php:295
 msgid "Name can only contain letters, numbers, dashes(-), periods(.), and underscores(_). It can be from 1 to 50 characters long."
 msgstr ""
@@ -2675,6 +2777,14 @@
 msgid "%s is now in the process of being updated to use the newly created revision."
 msgstr ""
 
+#: requests.php:1069
+msgid "Reservation is in maintenance - Contact admin for help"
+msgstr ""
+
+#: requests.php:1075
+msgid "Reservation is being captured"
+msgstr ""
+
 #: resource.php:172
 msgid "Edit Grouping &amp; Mapping"
 msgstr ""
@@ -2999,7 +3109,7 @@
 
 #: siteconfig.php:1517
 #, php-format
-msgid "This section allows for configuration of messages that are sent to users and administrators about things such as reservations and image management. Every message has a default. Additionally, separate messages can be configured for each affiliation. Most of the messages will have parts that are in square brackets. These parts will have data substituted for them before the message is sent. A list of what can be used in squeare brackets can be found at the <a href=\"%s\">Apache VCL web site</a>. Some messages also have a short form that may be sent such as in the form of a popup within a reservation when the reservation is about to end."
+msgid "This section allows for configuration of messages that are sent to users and administrators about things such as reservations and image management. Every message has a default. Additionally, separate messages can be configured for each affiliation. Most of the messages will have parts that are in square brackets. These parts will have data substituted for them before the message is sent. A list of what can be used in square brackets can be found at the <a href=\"%s\">Apache VCL web site</a>. Some messages also have a short form that may be sent such as in the form of a popup within a reservation when the reservation is about to end."
 msgstr ""
 
 #: siteconfig.php:1582
@@ -3043,6 +3153,192 @@
 msgid "No changes to submitted message. Nothing saved."
 msgstr ""
 
+#: siteconfig.php:873
+msgid "Failed to update data for these affiliations:"
+msgstr ""
+
+#: siteconfig.php:979
+msgid "Default value"
+msgstr ""
+
+#: siteconfig.php:1064
+msgid "You do not have access to modify the submitted setting."
+msgstr ""
+
+#: siteconfig.php:1090
+msgid "Failed to add submited value"
+msgstr ""
+
+#: siteconfig.php:1228
+#, php-format
+msgid "Failed to delete address for %s"
+msgstr ""
+
+#: siteconfig.php:1272
+msgid "Help Email Address"
+msgstr ""
+
+#: siteconfig.php:1273
+msgid ""
+"This is the email address used as the from address for emails sent by the "
+"VCL system to users."
+msgstr ""
+
+#: siteconfig.php:1278
+#, php-format
+msgid "Help Email Address added for %s"
+msgstr ""
+
+#: siteconfig.php:1279 siteconfig.php:1378 siteconfig.php:1478
+#: siteconfig.php:1681 siteconfig.php:1813 siteconfig.php:1923
+msgid "Update successful"
+msgstr ""
+
+#: siteconfig.php:1280
+#, php-format
+msgid "Address for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1371
+msgid "Site Web Address"
+msgstr ""
+
+#: siteconfig.php:1372
+msgid "This is the web address in emails sent by the VCL system to users."
+msgstr ""
+
+#: siteconfig.php:1374
+msgid "Invalid web address(es) specified"
+msgstr ""
+
+#: siteconfig.php:1377
+#, php-format
+msgid "Web Address added for %s"
+msgstr ""
+
+#: siteconfig.php:1379
+#, php-format
+msgid "Web Address for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1470
+msgid "KMS Servers"
+msgstr ""
+
+#: siteconfig.php:1471
+msgid ""
+"These are the KMS servers for activating Windows licensing. Multiple servers "
+"are allowed, delimited with a comma (,). Non standard ports can be specified "
+"after the server delimited with a colon (:). (ex: kms.example.com,kms2."
+"example.com:2000)"
+msgstr ""
+
+#: siteconfig.php:1474
+msgid "Invalid IP or hostname specified"
+msgstr ""
+
+#: siteconfig.php:1477
+#, php-format
+msgid "KMS server added for %s"
+msgstr ""
+
+#: siteconfig.php:1479
+#, php-format
+msgid "KMS server for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1675
+msgid "Site Theme"
+msgstr ""
+
+#: siteconfig.php:1676
+msgid "This controls the theme of the site displayed for each affiliation."
+msgstr ""
+
+#: siteconfig.php:1677
+msgid "Invalid theme specified"
+msgstr ""
+
+#: siteconfig.php:1680
+#, php-format
+msgid "Theme setting added for %s"
+msgstr ""
+
+#: siteconfig.php:1682
+#, php-format
+msgid "Theme setting for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1807
+msgid "LDAP Lookup for Shibboleth Authenticated Users"
+msgstr ""
+
+#: siteconfig.php:1808
+msgid ""
+"If an affiliation gets configured for Shibboleth authentication, this "
+"specifies that LDAP authentication has also been configured for that "
+"affiliation so that VCL can perform lookups for new users before they log in "
+"to VCL."
+msgstr ""
+
+#: siteconfig.php:1812
+#, php-format
+msgid "LDAP lookup setting added for %s"
+msgstr ""
+
+#: siteconfig.php:1814
+#, php-format
+msgid "LDAP lookup setting for %s deleted"
+msgstr ""
+
+#: siteconfig.php:1819 siteconfig.php:1928
+msgid "Local"
+msgstr ""
+
+#: siteconfig.php:1917
+msgid "Shibboleth Scope"
+msgstr ""
+
+#: siteconfig.php:1918
+msgid ""
+"This is the Shibboleth scope for an affiliation when Shibboleth "
+"authentication is enabled."
+msgstr ""
+
+#: siteconfig.php:1922
+#, php-format
+msgid "Shibboleth scope added for %s"
+msgstr ""
+
+#: siteconfig.php:1924
+#, php-format
+msgid "Shibboleth scope for %s deleted"
+msgstr ""
+
+#: siteconfig.php:2851
+msgid "Affiliation sucessfully added; reloading page"
+msgstr ""
+
+#: siteconfig.php:2852
+msgid "Affiliation sucessfully deleted; reloading page"
+msgstr ""
+
+#: siteconfig.php:2853
+msgid "Values updated; reloading page"
+msgstr ""
+
+#: siteconfig.php:2855
+msgid "Invalid value - must"
+msgstr ""
+
+#: siteconfig.php:3078
+msgid "Affiliation already exists"
+msgstr ""
+
+#: siteconfig.php:3084
+msgid "Conflicting Affiliation submitted"
+msgstr ""
+
 #: statistics.php:44
 msgid "Statistic Information"
 msgstr ""
diff --git a/web/locale/po_files/zh_CN/vcl.po b/web/locale/po_files/zh_CN/vcl.po
index 734ebb1..efc8693 100644
--- a/web/locale/po_files/zh_CN/vcl.po
+++ b/web/locale/po_files/zh_CN/vcl.po
@@ -15,7 +15,7 @@
 
 msgid ""
 msgstr ""
-"Project-Id-Version: VCL 2.5\n"
+"Project-Id-Version: VCL 2.5.1\n"
 "Report-Msgid-Bugs-To: dev@vcl.apache.org\n"
 "POT-Creation-Date: 2011-02-24 15:16+0900\n"
 "PO-Revision-Date: 2012-04-13 15:40-0500\n"
diff --git a/web/locale/pt_PT/LC_MESSAGES/vcl.mo b/web/locale/pt_PT/LC_MESSAGES/vcl.mo
index e3884ef..bc38f41 100644
--- a/web/locale/pt_PT/LC_MESSAGES/vcl.mo
+++ b/web/locale/pt_PT/LC_MESSAGES/vcl.mo
Binary files differ
diff --git a/web/locale/zh_CN/LC_MESSAGES/vcl.mo b/web/locale/zh_CN/LC_MESSAGES/vcl.mo
index 061a86f..c902da4 100644
--- a/web/locale/zh_CN/LC_MESSAGES/vcl.mo
+++ b/web/locale/zh_CN/LC_MESSAGES/vcl.mo
Binary files differ
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