Fixed #11430: Performance improvement: use $GLOBALS['EXEC_TIME'] instead of time...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_userauth.php
old mode 100755 (executable)
new mode 100644 (file)
index e5390ef..12a7ae8
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
  *
  *
  *  111: class t3lib_userAuth
- *  187:     function start()
- *  300:     function checkAuthentication()
+ *  195:     function start()
+ *  329:     function checkAuthentication()
  *
  *              SECTION: User Sessions
- *  531:     function createUserSession ($tempuser)
- *  568:     function fetchUserSession()
- *  619:     function logoff()
+ *  569:     function createUserSession ($tempuser)
+ *  606:     function fetchUserSession()
+ *  657:     function logoff()
  *
  *              SECTION: SQL Functions
- *  655:     function user_where_clause()
- *  669:     function ipLockClause()
- *  687:     function ipLockClause_remoteIPNumber($parts)
- *  708:     function hashLockClause()
- *  719:     function hashLockClause_getHashInt()
+ *  713:     function user_where_clause()
+ *  727:     function ipLockClause()
+ *  745:     function ipLockClause_remoteIPNumber($parts)
+ *  766:     function hashLockClause()
+ *  777:     function hashLockClause_getHashInt()
  *
  *              SECTION: Session and Configuration Handling
- *  751:     function writeUC($variable='')
- *  766:     function unpack_uc($theUC='')
- *  782:     function pushModuleData($module,$data,$noSave=0)
- *  795:     function getModuleData($module,$type='')
- *  808:     function getSessionData($key)
- *  821:     function setAndSaveSessionData($key,$data)
+ *  809:     function writeUC($variable='')
+ *  824:     function unpack_uc($theUC='')
+ *  840:     function pushModuleData($module,$data,$noSave=0)
+ *  853:     function getModuleData($module,$type='')
+ *  866:     function getSessionData($key)
+ *  879:     function setAndSaveSessionData($key,$data)
  *
  *              SECTION: Misc
- *  854:     function getLoginFormData()
- *  881:     function processLoginData($loginData, $security_level='')
- *  915:     function getAuthInfoArray()
- *  945:     function compareUident($user, $loginData, $security_level='')
- *  983:     function gc()
- *  997:     function redirect()
- * 1019:     function writelog($type,$action,$error,$details_nr,$details,$data,$tablename,$recuid,$recpid)
- * 1028:     function checkLogFailures()
- * 1041:     function setBeUserByUid($uid)
- * 1053:     function setBeUserByName($name)
- * 1064:     function getRawUserByUid($uid)
- * 1082:     function getRawUserByName($name)
+ *  912:     function getLoginFormData()
+ *  939:     function processLoginData($loginData, $security_level='')
+ *  981:     function getAuthInfoArray()
+ * 1011:     function compareUident($user, $loginData, $security_level='')
+ * 1050:     function gc()
+ * 1064:     function redirect()
+ * 1086:     function writelog($type,$action,$error,$details_nr,$details,$data,$tablename,$recuid,$recpid)
+ * 1095:     function checkLogFailures()
+ * 1108:     function setBeUserByUid($uid)
+ * 1120:     function setBeUserByName($name)
+ * 1131:     function getRawUserByUid($uid)
+ * 1149:     function getRawUserByName($name)
  *
  *              SECTION: Create/update user - EXPERIMENTAL
- * 1121:     function fetchUserRecord($dbUser, $username, $extraWhere='' )
+ * 1188:     function fetchUserRecord($dbUser, $username, $extraWhere='' )
  *
  * TOTAL FUNCTIONS: 29
  * (This index is automatically created/updated by the extension "extdeveval")
@@ -136,9 +136,9 @@ class t3lib_userAuth {
 
        var $auth_include = '';                 // this is the name of the include-file containing the login form. If not set, login CAN be anonymous. If set login IS needed.
 
-       var $auth_timeout_field = 0;            // if > 0 : session-timeout in seconds. if string: The string is fieldname from the usertable where the timeout can be found.
-       var $lifetime = 0;                      // 0 = Session-cookies. If session-cookies, the browser will stop session when the browser is closed. Else it keeps the session for $lifetime seconds.
-       var $gc_time = 24;                      // GarbageCollection. Purge all session data older than $gc_time hours.
+       var $auth_timeout_field = 0;            // Server session lifetime. If > 0: session-timeout in seconds. If false or <0: no timeout. If string: The string is a fieldname from the usertable where the timeout can be found.
+       var $lifetime = 0;                      // Client session lifetime. 0 = Session-cookies. If session-cookies, the browser will stop the session when the browser is closed. Otherwise this specifies the lifetime of a cookie that keeps the session.
+       var $gc_time = 0;                       // GarbageCollection. Purge all server session data older than $gc_time seconds. 0 = default to $this->timeout or use 86400 seconds (1 day) if $this->lifetime is 0
        var $gc_probability = 1;                // Possibility (in percent) for GarbageCollection to be run.
        var $writeStdLog = FALSE;               // Decides if the writelog() function is called at login and logout
        var $writeAttemptLog = FALSE;           // If the writelog() functions is called if a login-attempt has be tried without success
@@ -199,7 +199,13 @@ class t3lib_userAuth {
                $this->loginType = ($this->name=='fe_typo_user') ? 'FE' : 'BE';
 
                        // set level to normal if not already set
-               $this->security_level = $this->security_level ? $this->security_level : 'normal';
+               if (!$this->security_level) {
+                       // Notice: cannot use TYPO3_MODE here because BE user can be logged in and operate inside FE!
+                       $this->security_level = trim($TYPO3_CONF_VARS[$this->loginType]['loginSecurityLevel']);
+                       if (!$this->security_level) {
+                               $this->security_level = 'normal';
+                       }
+               }
 
                        // enable dev logging if set
                if ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['writeDevLog']) $this->writeDevLog = TRUE;
@@ -213,9 +219,12 @@ class t3lib_userAuth {
                $this->newSessionID = FALSE;
                        // $id is set to ses_id if cookie is present. Else set to false, which will start a new session
                $id = isset($_COOKIE[$this->name]) ? stripslashes($_COOKIE[$this->name]) : '';
-               $this->hash_length = t3lib_div::intInRange($this->hash_length,6,32);
                $this->svConfig = $TYPO3_CONF_VARS['SVCONF']['auth'];
 
+                       // if we have a flash client, take the ID from the GP
+               if (!$id && $GLOBALS['CLIENT']['BROWSER'] == 'flash') {
+                       $id = t3lib_div::_GP($this->name);
+               }
 
                        // If fallback to get mode....
                if (!$id && $this->getFallBack && $this->get_name)      {
@@ -225,11 +234,11 @@ class t3lib_userAuth {
                }
                $this->cookieId = $id;
 
-                       // If new session...
-               if (!$id)       {
+                       // If new session or client tries to fix session...
+               if (!$id || !$this->isExistingSessionRecord($id))       {
                                // New random session-$id is made
-               $id = substr(md5(uniqid('').getmypid()),0,$this->hash_length);
-                       // New session
+                       $id = $this->createSessionId();
+                               // New session
                        $this->newSessionID = TRUE;
                }
 
@@ -243,38 +252,68 @@ class t3lib_userAuth {
                        // Make certain that NO user is set initially
                $this->user = '';
 
+                       // Check to see if anyone has submitted login-information and if so register the user with the session. $this->user[uid] may be used to write log...
+               $this->checkAuthentication();
+
+                       // Make certain that NO user is set initially. ->check_authentication may have set a session-record which will provide us with a user record in the next section:
+               unset($this->user);
+
+               // determine whether we need to skip session update.
+               // This is used mainly for checking session timeout without
+               // refreshing the session itself while checking.
+               if (t3lib_div::_GP('skipSessionUpdate')) {
+                       $skipSessionUpdate = true;
+               } else {
+                       $skipSessionUpdate = false;
+               }
+
+                       // re-read user session
+               $this->user = $this->fetchUserSession($skipSessionUpdate);
+
+               if ($this->writeDevLog && is_array($this->user))        t3lib_div::devLog('User session finally read: '.t3lib_div::arrayToLogString($this->user, array($this->userid_column,$this->username_column)), 't3lib_userAuth', -1);
+               if ($this->writeDevLog && !is_array($this->user)) t3lib_div::devLog('No user session found.', 't3lib_userAuth', 2);
+
                        // Setting cookies
+               if ($TYPO3_CONF_VARS['SYS']['cookieDomain'])    {
+                       if ($TYPO3_CONF_VARS['SYS']['cookieDomain']{0} == '/')  {
+                               $matchCnt = @preg_match($TYPO3_CONF_VARS['SYS']['cookieDomain'], t3lib_div::getIndpEnv('TYPO3_HOST_ONLY'), $match);
+                               if ($matchCnt === FALSE)        {
+                                       t3lib_div::sysLog('The regular expression of $TYPO3_CONF_VARS[SYS][cookieDomain] contains errors. The session is not shared across sub-domains.', 'Core', 3);
+                               } elseif ($matchCnt)    {
+                                       $cookieDomain = $match[0];
+                               }
+                       } else {
+                               $cookieDomain = $TYPO3_CONF_VARS['SYS']['cookieDomain'];
+                       }
+               }
+
                        // If new session and the cookie is a sessioncookie, we need to set it only once!
-        if (($this->newSessionID || $this->forceSetCookie) && $this->lifetime==0 ) {
+               if ($this->isSetSessionCookie())        {
                        if (!$this->dontSetCookie)      {
-                               SetCookie($this->name, $id, 0, '/');
-                               if ($this->writeDevLog)         t3lib_div::devLog('Set new Cookie: '.$id, 't3lib_userAuth');
+                               if ($cookieDomain)      {
+                                       SetCookie($this->name, $id, 0, '/', $cookieDomain);
+                               } else {
+                                       SetCookie($this->name, $id, 0, t3lib_div::getIndpEnv('TYPO3_SITE_PATH'));
+                               }
+                               if ($this->writeDevLog)         t3lib_div::devLog('Set new Cookie: '.$id.($cookieDomain ? ', '.$cookieDomain : ''), 't3lib_userAuth');
                        }
                }
 
                        // If it is NOT a session-cookie, we need to refresh it.
-        if ($this->lifetime > 0) {
+               if ($this->isRefreshTimeBasedCookie())  {
                        if (!$this->dontSetCookie)      {
-                               SetCookie($this->name, $id, time()+$this->lifetime, '/');
-                               if ($this->writeDevLog)         t3lib_div::devLog('Update Cookie: '.$id, 't3lib_userAuth');
-               }
+                               if ($cookieDomain)      {
+                                       SetCookie($this->name, $id, $GLOBALS['EXEC_TIME'] + $this->lifetime, '/', $cookieDomain);
+                               } else {
+                                       SetCookie($this->name, $id, $GLOBALS['EXEC_TIME'] + $this->lifetime, t3lib_div::getIndpEnv('TYPO3_SITE_PATH'));
+                               }
+                               if ($this->writeDevLog)         t3lib_div::devLog('Update Cookie: '.$id.($cookieDomain ? ', '.$cookieDomain : ''), 't3lib_userAuth');
+                       }
                }
 
-                       // Check to see if anyone has submitted login-information and if so register the user with the session. $this->user[uid] may be used to write log...
-               $this->checkAuthentication();
-
-                       // Make certain that NO user is set initially. ->check_authentication may have set a session-record which will provide us with a user record in the next section:
-               unset($this->user);
-
-                       // re-read user session
-               $this->user = $this->fetchUserSession();
-
-               if ($this->writeDevLog AND is_array($this->user))       t3lib_div::devLog('User session finally read: '.t3lib_div::arrayToLogString($this->user, array($this->userid_column,$this->username_column)), 't3lib_userAuth', -1);
-               if ($this->writeDevLog AND !is_array($this->user)) t3lib_div::devLog('No user session found.', 't3lib_userAuth', 2);
-
-                       // Hook for alternative ways of filling the $this->user array (is used by TIMTAW extension)
-               if(is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['postUserLookUp']))        {
-                       foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['postUserLookUp'] as $funcName)        {
+                       // Hook for alternative ways of filling the $this->user array (is used by the "timtaw" extension)
+               if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['postUserLookUp']))       {
+                       foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['postUserLookUp'] as $funcName)       {
                                $_params = array(
                                        'pObj' => &$this,
                                );
@@ -293,10 +332,36 @@ class t3lib_userAuth {
                        header('Pragma: no-cache');
                }
 
+                       // Set $this->gc_time if not explicitely specified
+               if ($this->gc_time==0)  {
+                       $this->gc_time = ($this->auth_timeout_field==0 ? 86400 : $this->auth_timeout_field);    // Default to 1 day if $this->auth_timeout_field is 0
+               }
+
                        // If we're lucky we'll get to clean up old sessions....
-               if ((rand()%100) <= $this->gc_probability) {
+               if ((rand()%100) <= $this->gc_probability)      {
                        $this->gc();
                }
+
+       }
+
+       /**
+        * Determine whether a session cookie needs to be set (lifetime=0)
+        *
+        * @return      boolean
+        * @internal
+        */
+       function isSetSessionCookie() {
+               return ($this->newSessionID || $this->forceSetCookie) && $this->lifetime==0;
+       }
+
+       /**
+        * Determine whether a non-session cookie needs to be set (lifetime>0)
+        *
+        * @return      boolean
+        * @internal
+        */
+       function isRefreshTimeBasedCookie() {
+               return $this->lifetime > 0;
        }
 
        /**
@@ -346,7 +411,7 @@ class t3lib_userAuth {
                        if ($this->writeDevLog)         t3lib_div::devLog('Active login (eg. with login form)', 't3lib_userAuth');
 
                                // check referer for submitted login values
-                       if($this->formfield_status && $loginData['uident'] && $loginData['uname'])      {
+                       if ($this->formfield_status && $loginData['uident'] && $loginData['uname'])     {
                                $httpHost = t3lib_div::getIndpEnv('TYPO3_HOST_ONLY');
                                if (!$this->getMethodEnabled && ($httpHost!=$authInfo['refInfo']['host'] && !$GLOBALS['TYPO3_CONF_VARS']['SYS']['doNotCheckReferer']))  {
                                        die('Error: This host address ("'.$httpHost.'") and the referer host ("'.$authInfo['refInfo']['host'].'") mismatches!<br />
@@ -357,23 +422,42 @@ class t3lib_userAuth {
                                        // delete old user session if any
                                $this->logoff();
                        }
+
+                               // Refuse login for _CLI users (used by commandline scripts)
+                       if ((strtoupper(substr($loginData['uname'],0,5))=='_CLI_') && (!defined('TYPO3_cliMode') || !TYPO3_cliMode))    {       // although TYPO3_cliMode should never be set when using active login...
+                               die('Error: You have tried to login using a CLI user. Access prohibited!');
+                       }
                }
 
 
                // the following code makes auto-login possible (if configured). No submitted data needed
 
+               // determine whether we need to skip session update.
+               // This is used mainly for checking session timeout without
+               // refreshing the session itself while checking.
+               if (t3lib_div::_GP('skipSessionUpdate')) {
+                       $skipSessionUpdate = true;
+               } else {
+                       $skipSessionUpdate = false;
+               }
+
                        // re-read user session
-               $authInfo['userSession'] = $this->fetchUserSession();
+               $authInfo['userSession'] = $this->fetchUserSession($skipSessionUpdate);
                $haveSession = is_array($authInfo['userSession']) ? TRUE : FALSE;
 
-               if ($this->writeDevLog AND $haveSession)        t3lib_div::devLog('User session found: '.t3lib_div::arrayToLogString($authInfo['userSession'], array($this->userid_column,$this->username_column)), 't3lib_userAuth', 0);
-               if ($this->writeDevLog)         t3lib_div::devLog('SV setup: '.t3lib_div::arrayToLogString($this->svConfig['setup']), 't3lib_userAuth', 0);
-
+               if ($this->writeDevLog) {
+                       if ($haveSession)       {
+                               t3lib_div::devLog('User session found: '.t3lib_div::arrayToLogString($authInfo['userSession'], array($this->userid_column,$this->username_column)), 't3lib_userAuth', 0);
+                       }
+                       if (is_array($this->svConfig['setup'])) {
+                               t3lib_div::devLog('SV setup: '.t3lib_div::arrayToLogString($this->svConfig['setup']), 't3lib_userAuth', 0);
+                       }
+               }
 
                        // fetch user if ...
-               if ( $activeLogin
-                               OR (!$haveSession AND $this->svConfig['setup'][$this->loginType.'_fetchUserIfNoSession'])
-                               OR $this->svConfig['setup'][$this->loginType.'_alwaysFetchUser']) {
+               if ($activeLogin
+                               || (!$haveSession && $this->svConfig['setup'][$this->loginType.'_fetchUserIfNoSession'])
+                               || $this->svConfig['setup'][$this->loginType.'_alwaysFetchUser']) {
 
                                // use 'auth' service to find the user
                                // first found user will be used
@@ -396,15 +480,15 @@ class t3lib_userAuth {
                        }
                        unset($serviceObj);
 
-                       if ($this->writeDevLog AND $this->svConfig['setup'][$this->loginType.'_alwaysFetchUser'])       t3lib_div::devLog($this->loginType.'_alwaysFetchUser option is enabled', 't3lib_userAuth');
-                       if ($this->writeDevLog AND $serviceChain)       t3lib_div::devLog($subType.' auth services called: '.$serviceChain, 't3lib_userAuth');
-                       if ($this->writeDevLog AND !count($tempuserArr))        t3lib_div::devLog('No user found by services', 't3lib_userAuth');
-                       if ($this->writeDevLog AND count($tempuserArr))         t3lib_div::devLog(count($tempuserArr).' user records found by services', 't3lib_userAuth');
+                       if ($this->writeDevLog && $this->svConfig['setup'][$this->loginType.'_alwaysFetchUser'])        t3lib_div::devLog($this->loginType.'_alwaysFetchUser option is enabled', 't3lib_userAuth');
+                       if ($this->writeDevLog && $serviceChain)        t3lib_div::devLog($subType.' auth services called: '.$serviceChain, 't3lib_userAuth');
+                       if ($this->writeDevLog && !count($tempuserArr))         t3lib_div::devLog('No user found by services', 't3lib_userAuth');
+                       if ($this->writeDevLog && count($tempuserArr))  t3lib_div::devLog(count($tempuserArr).' user records found by services', 't3lib_userAuth');
                }
 
 
                        // If no new user was set we use the already found user session
-               if (!count($tempuserArr) AND $haveSession)      {
+               if (!count($tempuserArr) && $haveSession)       {
                        $tempuserArr[] = $authInfo['userSession'];
                        $tempuser = $authInfo['userSession'];
                                // User is authenticated because we found a user session
@@ -422,9 +506,9 @@ class t3lib_userAuth {
 
 
                        // Authenticate the user if needed
-               if(count($tempuserArr) AND !$authenticated) {
+               if (count($tempuserArr) && !$authenticated)     {
 
-                       foreach($tempuserArr as $tempuser) {
+                       foreach ($tempuserArr as $tempuser)     {
 
                                // use 'auth' service to authenticate the user
                                // if one service returns FALSE then authentication failed
@@ -457,25 +541,23 @@ class t3lib_userAuth {
                                }
                                unset($serviceObj);
 
-                               if ($this->writeDevLog AND $serviceChain)       t3lib_div::devLog($subType.' auth services called: '.$serviceChain, 't3lib_userAuth');
+                               if ($this->writeDevLog && $serviceChain)        t3lib_div::devLog($subType.' auth services called: '.$serviceChain, 't3lib_userAuth');
 
-                               if($authenticated) {
+                               if ($authenticated) {
                                                // leave foreach() because a user is authenticated
                                        break;
                                }
                        }
                }
 
-
                        // If user is authenticated a valid user is in $tempuser
                if ($authenticated)     {
                                // reset failure flag
                        $this->loginFailure = FALSE;
 
-
                                // Insert session record if needed:
-                       if (!($haveSession AND (
-                               $tempuser['ses_id']==$this->id OR       // check if the tempuser has the current session id
+                       if (!($haveSession && (
+                               $tempuser['ses_id']==$this->id ||       // check if the tempuser has the current session id
                                $tempuser['uid']==$authInfo['userSession']['ses_userid']        // check if the tempuser has the uid of the fetched session user
                                ))) {
                                $this->createUserSession($tempuser);
@@ -498,28 +580,43 @@ class t3lib_userAuth {
 
                        if($GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'] == 3 && $this->user_table == 'be_users')        {
                                $requestStr = substr(t3lib_div::getIndpEnv('TYPO3_REQUEST_SCRIPT'), strlen(t3lib_div::getIndpEnv('TYPO3_SITE_URL').TYPO3_mainDir));
-                               if($requestStr == 'alt_main.php' && t3lib_div::getIndpEnv('TYPO3_SSL')) {
+                               $backendScript = t3lib_BEfunc::getBackendScript();
+                               if($requestStr == $backendScript && t3lib_div::getIndpEnv('TYPO3_SSL')) {
                                        list(,$url) = explode('://',t3lib_div::getIndpEnv('TYPO3_SITE_URL'),2);
-                                       header('Location: http://'.$url.TYPO3_mainDir.'alt_main.php');
+                                       list($server,$address) = explode('/',$url,2);
+                                       if (intval($TYPO3_CONF_VARS['BE']['lockSSLPort'])) {
+                                               $sslPortSuffix = ':'.intval($TYPO3_CONF_VARS['BE']['lockSSLPort']);
+                                               $server = str_replace($sslPortSuffix,'',$server);       // strip port from server
+                                       }
+                                       header('Location: http://'.$server.'/'.$address.TYPO3_mainDir.$backendScript);
+                                       exit;
                                }
                        }
 
-               } elseif ($activeLogin OR count($tempuserArr)) {
+               } elseif ($activeLogin || count($tempuserArr)) {
                        $this->loginFailure = TRUE;
 
-                       if ($this->writeDevLog AND !count($tempuserArr) AND $activeLogin)       t3lib_div::devLog('Login failed: '.t3lib_div::arrayToLogString($loginData), 't3lib_userAuth', 2);
-                       if ($this->writeDevLog AND count($tempuserArr))         t3lib_div::devLog('Login failed: '.t3lib_div::arrayToLogString($tempuser, array($this->userid_column,$this->username_column)), 't3lib_userAuth', 2);
+                       if ($this->writeDevLog && !count($tempuserArr) && $activeLogin)         t3lib_div::devLog('Login failed: '.t3lib_div::arrayToLogString($loginData), 't3lib_userAuth', 2);
+                       if ($this->writeDevLog && count($tempuserArr))  t3lib_div::devLog('Login failed: '.t3lib_div::arrayToLogString($tempuser, array($this->userid_column,$this->username_column)), 't3lib_userAuth', 2);
                }
 
 
                        // If there were a login failure, check to see if a warning email should be sent:
-               if ($this->loginFailure AND $activeLogin)       {
+               if ($this->loginFailure && $activeLogin)        {
                        if ($this->writeDevLog)         t3lib_div::devLog('Call checkLogFailures: '.t3lib_div::arrayToLogString(array('warningEmail'=>$this->warningEmail,'warningPeriod'=>$this->warningPeriod,'warningMax'=>$this->warningMax,)), 't3lib_userAuth', -1);
 
                        $this->checkLogFailures($this->warningEmail, $this->warningPeriod, $this->warningMax);
                }
        }
 
+       /**
+        * Creates a new session ID.
+        * 
+        * @return      string          The new session ID
+        */
+       public function createSessionId() {
+               return substr(md5(uniqid('') . getmypid()), 0, $this->hash_length);
+       }
 
 
 
@@ -556,14 +653,7 @@ class t3lib_userAuth {
                                );
 
                        // re-create session entry
-               $insertFields = array(
-                       'ses_id' => $this->id,
-                       'ses_name' => $this->name,
-                       'ses_iplock' => $tempuser['disableIPlock'] ? '[DISABLED]' : $this->ipLockClause_remoteIPNumber($this->lockIP),
-                       'ses_hashlock' => $this->hashLockClause_getHashInt(),
-                       'ses_userid' => $tempuser[$this->userid_column],
-                       'ses_tstamp' => $GLOBALS['EXEC_TIME']
-               );
+               $insertFields = $this->getNewSessionRecord($tempuser);
                $GLOBALS['TYPO3_DB']->exec_INSERTquery($this->session_table, $insertFields);
 
                        // Updating lastLogin_column carrying information about last login.
@@ -577,30 +667,37 @@ class t3lib_userAuth {
        }
 
        /**
+        * Returns a new session record for the current user for insertion into the DB.
+        * This function is mainly there as a wrapper for inheriting classes to override it.
+        *
+        * @return      array           user session record
+        */
+       function getNewSessionRecord($tempuser) {
+               return array(
+                       'ses_id' => $this->id,
+                       'ses_name' => $this->name,
+                       'ses_iplock' => $tempuser['disableIPlock'] ? '[DISABLED]' : $this->ipLockClause_remoteIPNumber($this->lockIP),
+                       'ses_hashlock' => $this->hashLockClause_getHashInt(),
+                       'ses_userid' => $tempuser[$this->userid_column],
+                       'ses_tstamp' => $GLOBALS['EXEC_TIME']
+               );
+       }
+
+       /**
         * Read the user session from db.
         *
         * @return      array           user session data
         */
-       function fetchUserSession() {
+       function fetchUserSession($skipSessionUpdate = false) {
 
                $user = '';
 
                if ($this->writeDevLog)         t3lib_div::devLog('Fetch session ses_id = '.$this->id, 't3lib_userAuth');
 
-                       // The session_id is used to find user in the database. Two tables are joined: The session-table with user_id of the session and the usertable with its primary key
-               $dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
-                                               '*',
-                                               $this->session_table.','.$this->user_table,
-                                               $this->session_table.'.ses_id = '.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->id, $this->session_table).'
-                                                       AND '.$this->session_table.'.ses_name = '.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->name, $this->session_table).'
-                                                       AND '.$this->session_table.'.ses_userid = '.$this->user_table.'.'.$this->userid_column.'
-                                                       '.$this->ipLockClause().'
-                                                       '.$this->hashLockClause().'
-                                                       '.$this->user_where_clause()
-                                       );
-
+                       // fetch the user session from the DB
+               $dbres = $this->fetchUserSessionFromDB();
 
-               if ($user = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($dbres))      {
+               if ($dbres && $user = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($dbres)) {
                                // A user was found
                        if (is_string($this->auth_timeout_field))       {
                                $timeout = intval($user[$this->auth_timeout_field]);            // Get timeout-time from usertable
@@ -610,6 +707,7 @@ class t3lib_userAuth {
                                // If timeout > 0 (true) and currenttime has not exceeded the latest sessions-time plus the timeout in seconds then accept user
                                // Option later on: We could check that last update was at least x seconds ago in order not to update twice in a row if one script redirects to another...
                        if ($timeout>0 && ($GLOBALS['EXEC_TIME'] < ($user['ses_tstamp']+$timeout)))     {
+                               if(!$skipSessionUpdate) {
                                        $GLOBALS['TYPO3_DB']->exec_UPDATEquery(
                                                                                        $this->session_table,
                                                                                        'ses_id='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->id, $this->session_table).'
@@ -617,6 +715,8 @@ class t3lib_userAuth {
                                                                                        array('ses_tstamp' => $GLOBALS['EXEC_TIME'])
                                                                                );
                                        $user['ses_tstamp'] = $GLOBALS['EXEC_TIME'];    // Make sure that the timestamp is also updated in the array
+                               }
+
                        } else {
                                $this->logoff();                // delete any user set...
                        }
@@ -636,10 +736,10 @@ class t3lib_userAuth {
                if ($this->writeDevLog)         t3lib_div::devLog('logoff: ses_id = '.$this->id, 't3lib_userAuth');
 
                        // Hook for pre-processing the logoff() method, requested and implemented by andreas.otto@dkd.de:
-               if ( is_array( $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_feuserauth.php']['logoff_pre_processing'] ) ) {
+               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing']))     {
                        $_params = array();
-                       foreach( $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_feuserauth.php']['logoff_pre_processing'] as $_funcRef ) {
-                               if ($_funcRef) {
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'] as $_funcRef)     {
+                               if ($_funcRef)  {
                                        t3lib_div::callUserFunction($_funcRef,$_params,$this);
                                }
                        }
@@ -654,16 +754,32 @@ class t3lib_userAuth {
                $this->user = '';
 
                        // Hook for post-processing the logoff() method, requested and implemented by andreas.otto@dkd.de:
-               if ( is_array( $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_feuserauth.php']['logoff_post_processing'] ) ) {
+               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_post_processing']))    {
                        $_params = array();
-                       foreach( $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_feuserauth.php']['logoff_post_processing'] as $_funcRef ) {
-                               if ($_funcRef) {
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_post_processing'] as $_funcRef)    {
+                               if ($_funcRef)  {
                                        t3lib_div::callUserFunction($_funcRef,$_params,$this);
                                }
                        }
                }
        }
 
+       /**
+        * Determine whether there's an according session record to a given session_id
+        * in the database. Don't care if session record is still valid or not.
+        *
+        * @param       integer         Claimed Session ID
+        * @return      boolean         Returns true if a corresponding session was found in the database
+        */
+       function isExistingSessionRecord($id) {
+               $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
+                                               'ses_id',
+                                               $this->session_table,
+                                               'ses_id=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($id, $this->session_table)
+                                       );
+               return (($count ? true : false));
+       }
+
 
 
 
@@ -683,6 +799,27 @@ class t3lib_userAuth {
         *************************/
 
        /**
+        * The session_id is used to find user in the database.
+        * Two tables are joined: The session-table with user_id of the session and the usertable with its primary key
+        * @return DB result object or false on error
+        * @access private
+        */
+       protected function fetchUserSessionFromDB() {
+               $dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+                                       '*',
+                                       $this->session_table.','.$this->user_table,
+                                       $this->session_table.'.ses_id = '.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->id, $this->session_table).'
+                                               AND '.$this->session_table.'.ses_name = '.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->name, $this->session_table).'
+                                               AND '.$this->session_table.'.ses_userid = '.$this->user_table.'.'.$this->userid_column.'
+                                               '.$this->ipLockClause().'
+                                               '.$this->hashLockClause().'
+                                               '.$this->user_where_clause()
+               );
+               return $dbres;
+       }
+
+
+       /**
         * This returns the where-clause needed to select the user with respect flags like deleted, hidden, starttime, endtime
         *
         * @return      string
@@ -692,8 +829,8 @@ class t3lib_userAuth {
                return  (($this->enablecolumns['rootLevel']) ? 'AND '.$this->user_table.'.pid=0 ' : '').
                                (($this->enablecolumns['disabled']) ? ' AND '.$this->user_table.'.'.$this->enablecolumns['disabled'].'=0' : '').
                                (($this->enablecolumns['deleted']) ? ' AND '.$this->user_table.'.'.$this->enablecolumns['deleted'].'=0' : '').
-                               (($this->enablecolumns['starttime']) ? ' AND ('.$this->user_table.'.'.$this->enablecolumns['starttime'].'<='.time().')' : '').
-                               (($this->enablecolumns['endtime']) ? ' AND ('.$this->user_table.'.'.$this->enablecolumns['endtime'].'=0 OR '.$this->user_table.'.'.$this->enablecolumns['endtime'].'>'.time().')' : '');
+                               (($this->enablecolumns['starttime']) ? ' AND (' . $this->user_table . '.' . $this->enablecolumns['starttime'] . '<=' . $GLOBALS['EXEC_TIME'] . ')' : '') .
+                               (($this->enablecolumns['endtime']) ? ' AND (' . $this->user_table . '.' . $this->enablecolumns['endtime'] . '=0 OR ' . $this->user_table . '.' . $this->enablecolumns['endtime'] . '>' . $GLOBALS['EXEC_TIME'] . ')' : '');
        }
 
        /**
@@ -1007,12 +1144,12 @@ class t3lib_userAuth {
 
                                if ((string)$loginData['uident'] === (string)md5($user[$this->username_column].':'.$user[$this->userident_column].':'.$loginData['chalvalue'])) {
                                        $OK = TRUE;
-                               };
+                               }
                        break;
                        default:        // normal
                                if ((string)$loginData['uident'] === (string)$user[$this->userident_column])    {
                                        $OK = TRUE;
-                               };
+                               }
                        break;
                }
 
@@ -1028,15 +1165,17 @@ class t3lib_userAuth {
        function gc() {
                $GLOBALS['TYPO3_DB']->exec_DELETEquery(
                                        $this->session_table,
-                                       'ses_tstamp < '.intval(time()-($this->gc_time*60*60)).'
-                                               AND ses_name = '.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->name, $this->session_table)
+                                       'ses_tstamp < ' . intval($GLOBALS['EXEC_TIME'] - ($this->gc_time)) .
+                                               ' AND ses_name = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($this->name, $this->session_table)
                                );
        }
 
        /**
-        * Redirect to somewhere. Obsolete, depreciated etc.
+        * Redirect to somewhere (obsolete).
         *
         * @return      void
+        * @deprecated since TYPO3 3.6
+        * @obsolete
         * @ignore
         */
        function redirect() {
@@ -1168,7 +1307,7 @@ class t3lib_userAuth {
 
                $usernameClause = $username ? ($dbUser['username_column'].'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($username, $dbUser['table'])) : '';
 
-               if ($username OR $extraWhere)   {
+               if ($username || $extraWhere)   {
 
                                // Look up the user by the username and/or extraWhere:
                        $dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
@@ -1194,4 +1333,5 @@ class t3lib_userAuth {
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_userauth.php']) {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_userauth.php']);
 }
-?>
+
+?>
\ No newline at end of file