Index: trunk/lib/App.inc.php
===================================================================
--- trunk/lib/App.inc.php	(revision 102)
+++ trunk/lib/App.inc.php	(revision 103)
@@ -222,5 +222,5 @@
          */
 
-        if ($this->getParam('enable_db')) {
+        if (true === $this->getParam('enable_db')) {
 
             // DB connection parameters taken from environment variables in the httpd.conf file, readable only by root.
@@ -337,7 +337,9 @@
     {
         session_write_close();
-        $this->db->close();
         restore_include_path();
         $this->running = false;
+        if (true === $this->getParam('enable_db')) {
+            $this->db->close();
+        }
     }
 
@@ -364,4 +366,5 @@
 
         if (!$this->running || '' == $message) {
+            $this->logMsg(sprintf('Canceled method call %s, application not running or message is an empty string.', __FUNCTION__), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
@@ -397,4 +400,5 @@
 
         if (!$this->running) {
+            $this->logMsg(sprintf('Canceled method call %s, application not running.', __FUNCTION__), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
@@ -421,4 +425,5 @@
 
         if (!$this->running) {
+            $this->logMsg(sprintf('Canceled method call %s, application not running.', __FUNCTION__), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
@@ -441,4 +446,5 @@
 
         if (!$this->running) {
+            $this->logMsg(sprintf('Canceled method call %s, application not running.', __FUNCTION__), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
@@ -650,4 +656,5 @@
 
         if (!$this->running) {
+            $this->logMsg(sprintf('Canceled method call %s, application not running.', __FUNCTION__), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
@@ -769,4 +776,5 @@
 
         if (!$this->running) {
+            $this->logMsg(sprintf('Canceled method call %s, application not running.', __FUNCTION__), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
@@ -831,4 +839,5 @@
 
         if (!$this->running) {
+            $this->logMsg(sprintf('Canceled method call %s, application not running.', __FUNCTION__), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
@@ -879,4 +888,5 @@
 
         if (!$this->running) {
+            $this->logMsg(sprintf('Canceled method call %s, application not running.', __FUNCTION__), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
@@ -925,4 +935,5 @@
 
         if (!$this->running) {
+            $this->logMsg(sprintf('Canceled method call %s, application not running.', __FUNCTION__), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
@@ -966,4 +977,5 @@
 
         if (!$this->running) {
+            $this->logMsg(sprintf('Canceled method call %s, application not running.', __FUNCTION__), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
@@ -994,4 +1006,5 @@
 
         if (!$this->running) {
+            $this->logMsg(sprintf('Canceled method call %s, application not running.', __FUNCTION__), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
@@ -1007,8 +1020,8 @@
 
     /**
-     * Check if a valid boomerang URL value has been set.
-     * if it is not the current url, and has not been accessed within n seconds.
-     *
-     * @return bool  True if it is set and not the current URL.
+     * Check if a valid boomerang URL value has been set. A boomerang URL is considered
+     * valid if: 1) it is not empty, 2) it is not the current URL, and 3) has not been accessed within n seconds.
+     *
+     * @return bool  True if it is set and valid, false otherwise.
      */
     function validBoomerangURL($id=null, $use_nonspecificboomerang=false)
@@ -1019,8 +1032,10 @@
 
         if (!$this->running) {
+            $this->logMsg(sprintf('Canceled method call %s, application not running.', __FUNCTION__), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
 
         if (!isset($_SESSION[$this->app]['boomerang']['url'])) {
+            $this->logMsg(sprintf('validBoomerangURL(%s) no boomerang URL set.', $id, $url), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
Index: trunk/lib/Auth_File.inc.php
===================================================================
--- trunk/lib/Auth_File.inc.php	(revision 102)
+++ trunk/lib/Auth_File.inc.php	(revision 103)
@@ -5,6 +5,15 @@
  *
  * @author  Quinn Comendant <quinn@strangecode.com>
- * @version 1.1
+ * @version 1.2
  */
+ 
+// Usage example:
+// $auth = new Auth_File();
+// $auth->setParam(array(
+//     'htpasswd_file' => COMMON_BASE . '/global/site_users.htpasswd',
+//     'login_timeout' => 21600,
+//     'idle_timeout' => 3600,
+//     'login_url' => '/login.php'
+// ));
 
 // Available encryption types for class Auth_SQL.
@@ -16,11 +25,31 @@
 class Auth_File {
 
-    var $_params = array(
+    var $_auth = '';
+    var $_sess = '_auth_';
+    var $_params = array();
+    var $_default_params = array(
+        
+        // Full path to htpasswd file.
+        'htpasswd_file' => null,
+
+        // The type of encryption to use for passwords stored in the db_table. Use one of the AUTH_ENCRYPT_* types specified above.
         'encryption_type' => AUTH_ENCRYPT_CRYPT,
-        'htpasswd_file' => null,
-        'login_timeout' => 21600, // 6 hours.
-        'idle_timeout' => 3600, // 1 hour.
-        'login_url' => '/login.php',
+
+        // The URL to the login script.
+        'login_url' => '/',
+
+        // The maximum amount of time a user is allowed to be logged in. They will be forced to login again if they expire.
+        // This applies to admins and users. In seconds. 21600 seconds = 6 hours.
+        'login_timeout' => 21600,
+
+        // The maximum amount of time a user is allowed to be idle before their session expires. They will be forced to login again if they expire.
+        // This applies to admins and users. In seconds. 3600 seconds = 1 hour.
+        'idle_timeout' => 3600,
+
+        // An array of IP blocks that are bypass the remote_ip comparison check. Useful for dynamic IPs or those behind proxy servers.
+        'trusted_networks' => array(),
     );
+
+    // Associative array of usernames to hashed passwords.
     var $_users = array();
 
@@ -32,19 +61,13 @@
      * @param optional array $params  A hash containing parameters.
      */
-    function Auth_File($params = array())
-    {
-        $this->_params = array_merge($this->_params, $params);
-
-        if (!empty($this->_params['htpasswd_file'])) {
-            if (false === ($users = file($this->_params['htpasswd_file']))) {
-                App::logMsg(sprintf(_("Could not read htpasswd file: %s"), $this->_params['htpasswd_file']), LOG_ERR, __FILE__, __LINE__);
-            }
-            if (is_array($users)) {
-                foreach ($users as $line) {
-                    list($user, $pass) = explode(':', $line, 2);
-                    $this->_users[trim($user)] = trim($pass);
-                }
-            }
-        }
+    function Auth_File($auth_name=null)
+    {
+        if (isset($auth_name)) {
+            $this->_auth = $auth_name;
+            $this->_sess .= $auth_name;
+        }
+
+        // Initialize default parameters.
+        $this->setParam($this->_default_params);
     }
 
@@ -87,7 +110,41 @@
     function clearAuth()
     {
-        $_SESSION['_auth_file'] = array('authenticated' => false);
-    }
-
+        $_SESSION[$this->_sess] = array('authenticated' => false);
+    }
+
+
+    /**
+     * Sets a variable into a registered auth session.
+     *
+     * @access public
+     * @param mixed $key      Which value to set.
+     * @param mixed $val      Value to set variable to.
+     */
+    function setVal($key, $val)
+    {
+        if (!isset($_SESSION[$this->_sess]['user_data'])) {
+            $_SESSION[$this->_sess]['user_data'] = array();
+        }
+        $_SESSION[$this->_sess]['user_data'][$key] = $val;
+    }
+
+    /**
+     * Returns a specified value from a registered auth session.
+     *
+     * @access public
+     * @param mixed $key      Which value to return.
+     * @param mixed $default  Value to return if key not found in user_data.
+     * @return mixed          Value stored in session.
+     */
+    function getVal($key, $default='')
+    {
+        if (isset($_SESSION[$this->_sess][$key])) {
+            return $_SESSION[$this->_sess][$key];
+        } else if (isset($_SESSION[$this->_sess]['user_data'][$key])) {
+            return $_SESSION[$this->_sess]['user_data'][$key];
+        } else {
+            return $default;
+        }
+    }
     /**
      * Find out if a set of login credentials are valid. Only supports
@@ -104,7 +161,10 @@
     {
         if ('' == trim($password)) {
-            App::logMsg(_("No password provided for htpasswd authentication."), LOG_INFO, __FILE__, __LINE__);
-            return false;
-        }
+            App::logMsg(_("No password provided for authentication."), LOG_INFO, __FILE__, __LINE__);
+            return false;
+        }
+        
+        // Load users file.
+        $this->_loadHTPasswdFile();
 
         if (!isset($this->_users[$username])) {
@@ -113,10 +173,11 @@
         }
 
-        if ($this->_encrypt($password, $this->_users[$username]) == $this->_users[$username]) {
-            return true;
-        } else {
+        if ($this->_encrypt($password, $this->_users[$username]) != $this->_users[$username]) {
             App::logMsg(sprintf('Authentication failed for user %s', $username), LOG_INFO, __FILE__, __LINE__);
             return false;
         }
+        
+        // Authentication successful!
+        return true;
     }
 
@@ -137,15 +198,19 @@
         $this->clearAuth();
 
-        if ($this->authenticate($username, $password)) {
-            $_SESSION['_auth_file'] = array(
-                'authenticated' => true,
-                'username' => $username,
-                'login_datetime' => date('Y-m-d H:i:s'),
-                'last_access_datetime' => date('Y-m-d H:i:s'),
-                'remote_addr' => getRemoteAddr()
-            );
-            return true;
-        }
-        return false;
+        if (!$this->authenticate($username, $password)) {
+            // No login: failed authentication!
+            return false;
+        }
+        
+        $_SESSION[$this->_sess] = array(
+            'authenticated' => true,
+            'username' => $username,
+            'login_datetime' => date('Y-m-d H:i:s'),
+            'last_access_datetime' => date('Y-m-d H:i:s'),
+            'remote_ip' => getRemoteAddr()
+        );
+
+        // We're logged-in!
+        return true;
     }
 
@@ -162,19 +227,49 @@
     function isLoggedIn()
     {
-        if (isset($_SESSION['_auth_file'])) {
-            if (true === $_SESSION['_auth_file']['authenticated']
-            && !empty($_SESSION['_auth_file']['username'])
-            && strtotime($_SESSION['_auth_file']['login_datetime']) > time() - $this->_params['login_timeout']
-            && strtotime($_SESSION['_auth_file']['last_access_datetime']) > time() - $this->_params['idle_timeout']
-            && $_SESSION['_auth_file']['remote_addr'] == getRemoteAddr()
-            ) {
-                $_SESSION['_auth_file']['last_access_datetime'] = date('Y-m-d H:i:s');
-                return true;
-            } else if (true === $_SESSION['_auth_file']['authenticated']) {
+        // Some users will access from networks with a changing IP number (i.e. behind a proxy server). These users must be allowed entry by adding their IP to the list of trusted_networks.
+        if ($trusted_net = ipInRange(getRemoteAddr(), $this->_params['trusted_networks'])) {
+            $user_in_trusted_network = true;
+            App::logMsg(sprintf('User %s accessing from trusted network %s', $_SESSION[$this->_sess]['username'], $trusted_net), LOG_DEBUG, __FILE__, __LINE__);
+        } else if (preg_match('/proxy.aol.com$/i', getRemoteAddr(true))) {
+            $user_in_trusted_network = true;
+            App::logMsg(sprintf('User %s accessing from trusted network proxy.aol.com', $_SESSION[$this->_sess]['username']), LOG_DEBUG, __FILE__, __LINE__);
+        } else {
+            $user_in_trusted_network = false;
+        }
+
+        // Test login with information stored in session. Skip IP matching for users from trusted networks.
+        if (isset($_SESSION[$this->_sess])
+            && true === $_SESSION[$this->_sess]['authenticated']
+            && !empty($_SESSION[$this->_sess]['username'])
+            && strtotime($_SESSION[$this->_sess]['login_datetime']) > time() - $this->_params['login_timeout']
+            && strtotime($_SESSION[$this->_sess]['last_access_datetime']) > time() - $this->_params['idle_timeout']
+            && ($_SESSION[$this->_sess]['remote_ip'] == getRemoteAddr() || $user_in_trusted_network)
+        ) {
+            // User is authenticated!
+            $_SESSION[$this->_sess]['last_access_datetime'] = date('Y-m-d H:i:s');
+            return true;
+        } else if (isset($_SESSION[$this->_sess]) && true === $_SESSION[$this->_sess]['authenticated']) {
+            if (strtotime($_SESSION[$this->_sess]['last_access_datetime']) > time() - 43200) {
+                // Only raise message if last session is less than 12 hours old.
                 App::raiseMsg(_("Your session has closed. You need to log-in again."), MSG_NOTICE, __FILE__, __LINE__);
-                $this->clearAuth();
-                return false;
-            }
-        }
+            }
+
+            // Log the reason for login expiration.
+            $expire_reasons = array();
+            if (empty($_SESSION[$this->_sess]['username'])) {
+                $expire_reasons[] = 'username not found';
+            }
+            if (strtotime($_SESSION[$this->_sess]['login_datetime']) <= time() - $this->_params['login_timeout']) {
+                $expire_reasons[] = 'login_timeout expired';
+            }
+            if (strtotime($_SESSION[$this->_sess]['last_access_datetime']) <= time() - $this->_params['idle_timeout']) {
+                $expire_reasons[] = 'idle_timeout expired';
+            }
+            if ($_SESSION[$this->_sess]['remote_ip'] != getRemoteAddr() && !$user_in_trusted_network) {
+                $expire_reasons[] = sprintf('remote_ip not matched (%s != %s)', $_SESSION[$this->_sess]['remote_ip'], getRemoteAddr());
+            }
+            App::logMsg(sprintf('User %s session expired: %s', $_SESSION[$this->_sess]['username'], join(', ', $expire_reasons)), LOG_INFO, __FILE__, __LINE__);
+        }
+
         return false;
     }
@@ -193,5 +288,5 @@
     {
         if (!$this->isLoggedIn()) {
-            // Display message for requiring login.
+            // Display message for requiring login. (RaiseMsg will ignore empty strings.)
             App::raiseMsg($message, $type, $file, $line);
 
@@ -200,4 +295,39 @@
             App::dieURL($this->_params['login_url']);
         }
+    }
+    
+    /*
+    * Reads the configured htpasswd file into the _users array.
+    *
+    * @access   public
+    * @return   false on error, true on success.
+    * @author   Quinn Comendant <quinn@strangecode.com>
+    * @version  1.0
+    * @since    18 Apr 2006 18:17:48
+    */
+    function _loadHTPasswdFile()
+    {
+        static $users = null;
+        
+        if (!file_exists($this->_params['htpasswd_file'])) {
+            App::logMsg(sprintf('htpasswd file missing or not specified: %s', $this->_params['htpasswd_file']), LOG_ERR, __FILE__, __LINE__);
+            return false;
+        }
+        
+        if (!isset($users)) {
+            if (false === ($users = file($this->_params['htpasswd_file']))) {
+                App::logMsg(sprintf(_("Could not read htpasswd file: %s"), $this->_params['htpasswd_file']), LOG_ERR, __FILE__, __LINE__);
+                return false;
+            }
+        }
+
+        if (is_array($users)) {
+            foreach ($users as $u) {
+                list($user, $pass) = explode(':', $u, 2);
+                $this->_users[trim($user)] = trim($pass);
+            }
+            return true;
+        }
+        return false;
     }
 
Index: trunk/lib/Auth_SQL.inc.php
===================================================================
--- trunk/lib/Auth_SQL.inc.php	(revision 102)
+++ trunk/lib/Auth_SQL.inc.php	(revision 103)
@@ -25,7 +25,4 @@
     var $_default_params = array(
 
-        // Message displayed by requireLogin().
-        'login_required_message' => 'Please login',
-
         // Automatically create table and verify columns. Better set to false after site launch.
         'create_table' => true,
@@ -77,5 +74,5 @@
         'login_abuse_exempt_usernames' => array(),
 
-        // An array of IP blocks that are bypass the remote_addr comparison check. Useful for dynamic IPs or those behind proxy servers.
+        // An array of IP blocks that are bypass the remote_ip comparison check. Useful for dynamic IPs or those behind proxy servers.
         'trusted_networks' => array(),
 
@@ -209,4 +206,53 @@
 
     /**
+     * Set the params of an auth object.
+     *
+     * @param  array $params   Array of parameter keys and value to set.
+     * @return bool true on success, false on failure
+     */
+    function setParam($params)
+    {
+        if (isset($params) && is_array($params)) {
+            // Merge new parameters with old overriding only those passed.
+            $this->_params = array_merge($this->_params, $params);
+        }
+    }
+
+    /**
+     * Return the value of a parameter, if it exists.
+     *
+     * @access public
+     * @param string $param        Which parameter to return.
+     * @return mixed               Configured parameter value.
+     */
+    function getParam($param)
+    {
+        if (isset($this->_params[$param])) {
+            return $this->_params[$param];
+        } else {
+            App::logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
+            return null;
+        }
+    }
+
+    /**
+     * Clear any authentication tokens in the current session. A.K.A. logout.
+     *
+     * @access public
+     */
+    function clearAuth()
+    {
+        $this->initDB();
+
+        DB::query("
+            UPDATE " . $this->_params['db_table'] . " SET
+            seconds_online = seconds_online + (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(last_access_datetime)),
+            last_login_datetime = '0000-00-00 00:00:00'
+            WHERE " . $this->_params['db_primary_key'] . " = '" . $this->getVal('user_id') . "'
+        ");
+        $_SESSION['_auth_file'] = array('authenticated' => false);
+    }
+
+    /**
      * Sets a variable into a registered auth session.
      *
@@ -240,54 +286,4 @@
             return $default;
         }
-    }
-
-    /**
-     * Set the params of an auth object.
-     *
-     * @param  array $params   Array of parameter keys and value to set.
-     * @return bool true on success, false on failure
-     */
-    function setParam($params)
-    {
-        if (isset($params) && is_array($params)) {
-            // Merge new parameters with old overriding only those passed.
-            $this->_params = array_merge($this->_params, $params);
-        }
-    }
-
-    /**
-     * Return the value of a parameter, if it exists.
-     *
-     * @access public
-     * @param string $param        Which parameter to return.
-     * @return mixed               Configured parameter value.
-     */
-    function getParam($param)
-    {
-        if (isset($this->_params[$param])) {
-            return $this->_params[$param];
-        } else {
-            App::logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
-            return null;
-        }
-    }
-
-    /**
-     * Clear any authentication tokens in the current session. A.K.A. logout.
-     *
-     * @access public
-     */
-    function clearAuth()
-    {
-        $this->initDB();
-
-        DB::query("
-            UPDATE " . $this->_params['db_table'] . " SET
-            seconds_online = seconds_online + (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(last_access_datetime)),
-            last_login_datetime = '0000-00-00 00:00:00'
-            WHERE " . $this->_params['db_primary_key'] . " = '" . $this->getVal('user_id') . "'
-        ");
-        $_SESSION[$this->_sess] = array();
-        $_SESSION[$this->_sess]['authenticated'] = false;
     }
 
@@ -532,5 +528,5 @@
                 $expire_reasons[] = 'idle_timeout expired';
             }
-            if ($_SESSION[$this->_sess]['remote_ip'] != getRemoteAddr()) {
+            if ($_SESSION['_auth_file']['remote_ip'] != getRemoteAddr() && !$user_in_trusted_network) {
                 $expire_reasons[] = sprintf('remote_ip not matched (%s != %s)', $_SESSION[$this->_sess]['remote_ip'], getRemoteAddr());
             }
@@ -556,5 +552,5 @@
     {
         if (!$this->isLoggedIn()) {
-            // Display message for requiring login.
+            // Display message for requiring login. (RaiseMsg will ignore empty strings.)
             App::raiseMsg($message, $type, $file, $line);
 
Index: trunk/lib/Utilities.inc.php
===================================================================
--- trunk/lib/Utilities.inc.php	(revision 102)
+++ trunk/lib/Utilities.inc.php	(revision 103)
@@ -104,5 +104,6 @@
 
 /**
- * Returns text with stylistic modifications.
+ * Returns text with stylistic modifications. Warning: this will break some HTML attibutes!
+ * FIXME: Allow a string such as this to be passted: <a href="javascript:openPopup('/foo/bar.php')">Click here</a>
  *
  * @param  string   $txt  Text to clean.
@@ -111,26 +112,28 @@
 function fancyTxt($txt)
 {
-    return $txt; /// FIXME.
-    
-//     $search = array();
-//     $replace = array();
-// 
-//     // "double quoted text"  becomes  &ldquo;double quoted text&rdquo;
-//     $search['double_quotes']    = '/(^|[^\w=])(?:"|&quot;|&#34;|&#x22;|&ldquo;)([^"]+?)(?:"|&quot;|&#34;|&#x22;|&rdquo;)([^\w]|$)/'; // " is the same as &quot; and &#34; and &#x22;
-//     $replace['double_quotes']   = '\\1&ldquo;\\2&rdquo;\\3';
-// 
-//     // text's apostrophes  become  text&rsquo;s apostrophes
-//     $search['apostrophe']       = '/(\w)(?:\'|&#39;|&#039;)(\w)/';
-//     $replace['apostrophe']      = '\\1&rsquo;\\2';
-// 
-//     // 'single quoted text'  becomes  &lsquo;single quoted text&rsquo;
-//     $search['single_quotes']    = '/(^|[^\w=])(?:\'|&#39;|&lsquo;)([^\']+?)(?:\'|&#39;|&rsquo;)([^\w]|$)/';
-//     $replace['single_quotes']   = '\\1&lsquo;\\2&rsquo;\\3';
-// 
-//     // em--dashes  become em&mdash;dashes
-//     $search['em_dash']          = '/(\s*[^!<-])--([^>-]\s*)/';
-//     $replace['em_dash']         = '\\1&mdash;\\2';
-// 
-//     return preg_replace($search, $replace, $txt);
+    $search = array();
+    $replace = array();
+
+    // "double quoted text"  becomes  &ldquo;double quoted text&rdquo;
+    $search['double_quotes']    = '/(^|[^\w=])(?:"|&quot;|&#34;|&#x22;|&ldquo;)([^"]+?)(?:"|&quot;|&#34;|&#x22;|&rdquo;)([^\w]|$)/ms'; // " is the same as &quot; and &#34; and &#x22;
+    $replace['double_quotes']   = '$1&ldquo;$2&rdquo;$3';
+
+    // text's apostrophes  become  text&rsquo;s apostrophes
+    $search['apostrophe']       = '/(\w)(?:\'|&#39;|&#039;)(\w)/ms';
+    $replace['apostrophe']      = '$1&rsquo;$2';
+
+    // 'single quoted text'  becomes  &lsquo;single quoted text&rsquo;
+    $search['single_quotes']    = '/(^|[^\w=])(?:\'|&#39;|&lsquo;)([^\']+?)(?:\'|&#39;|&rsquo;)([^\w]|$)/ms';
+    $replace['single_quotes']   = '$1&lsquo;$2&rsquo;$3';
+
+    // plural posessives' apostrophes become posessives&rsquo;
+    $search['apostrophes']      = '/(s)(?:\'|&#39;|&#039;)(\s)/ms';
+    $replace['apostrophes']     = '$1&rsquo;$2';
+
+    // em--dashes  become em&mdash;dashes
+    $search['em_dash']          = '/(\s*[^!<-])--([^>-]\s*)/';
+    $replace['em_dash']         = '$1&mdash;$2';
+
+    return preg_replace($search, $replace, $txt);
 }
 
Index: trunk/services/login.php
===================================================================
--- trunk/services/login.php	(revision 102)
+++ trunk/services/login.php	(revision 103)
@@ -16,5 +16,5 @@
 
 if (getFormdata('username', false)) {
-    /* form has been submitted, check if the user login information is correct */
+    // Form has been submitted, check if the user login information is correct.
 
     if ($auth->login($frm['username'], $frm['password'])) {
Index: trunk/services/logout.php
===================================================================
--- trunk/services/logout.php	(revision 102)
+++ trunk/services/logout.php	(revision 103)
@@ -5,11 +5,10 @@
  */
 
-require_once 'codebase/lib/RecordLock.inc.php';
-
-// Delete this admin's record locks.
-if (!isset($lock) || !is_a($lock, 'RecordLock')) {
+if (is_a($auth_object, 'Auth_SQL')) {
+    // Delete the current user's record locks.
+    require_once 'codebase/lib/RecordLock.inc.php';
     $lock =& RecordLock::getInstance($auth);
+    $lock->removeAll($auth->getVal('user_id'));
 }
-$lock->removeAll($auth->getVal('user_id'));
 
 // Logout.
