Follow-up to bug #12499: re-added the removed function call and moved the deprecation...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_userauth.php
old mode 100755 (executable)
new mode 100644 (file)
index b8cb0a0..166ad92
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2006 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
@@ -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,55 +252,31 @@ class t3lib_userAuth {
                        // Make certain that NO user is set initially
                $this->user = '';
 
-                       // 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->dontSetCookie)      {
-                               if ($cookieDomain)      {
-                                       SetCookie($this->name, $id, 0, '/', $cookieDomain);
-                               } else {
-                                       SetCookie($this->name, $id, 0, '/');
-                               }
-                               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->dontSetCookie)      {
-                               if ($cookieDomain)      {
-                                       SetCookie($this->name, $id, time()+$this->lifetime, '/', $cookieDomain);
-                               } else {
-                                       SetCookie($this->name, $id, time()+$this->lifetime, '/');
-                               }
-                               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);
 
+               // 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();
+               $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);
 
-               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);
+                       // Setting cookies
+               if (!$this->dontSetCookie)      {
+                       $this->setSessionCookie();
+               }
 
                        // 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']))       {
@@ -314,10 +299,110 @@ 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();
                }
+
+       }
+
+       /**
+        * Sets the session cookie for the current disposal.
+        *
+        * @return      void
+        */
+       protected function setSessionCookie() {
+               $isSetSessionCookie = $this->isSetSessionCookie();
+               $isRefreshTimeBasedCookie = $this->isRefreshTimeBasedCookie();
+
+               if ($isSetSessionCookie || $isRefreshTimeBasedCookie) {
+                       $settings = $GLOBALS['TYPO3_CONF_VARS']['SYS'];
+
+                       // Get the domain to be used for the cookie (if any):
+                       $cookieDomain = $this->getCookieDomain();
+                       // If no cookie domain is set, use the base path:
+                       $cookiePath = ($cookieDomain ? '/' : t3lib_div::getIndpEnv('TYPO3_SITE_PATH'));
+                       // If the cookie lifetime is set, use it:
+                       $cookieExpire = ($isRefreshTimeBasedCookie ? $GLOBALS['EXEC_TIME'] + $this->lifetime : 0);
+                       // Use the secure option when the current request is served by a secure connection:
+                       $cookieSecure = (bool)$settings['cookieSecure'] && t3lib_div::getIndpEnv('TYPO3_SSL');
+                       // Deliver cookies only via HTTP and prevent possible XSS by JavaScript:
+                       $cookieHttpOnly = (bool)$settings['cookieHttpOnly'];
+
+                       // Do not set cookie if cookieSecure is set to "1" (force HTTPS) and no secure channel is used:
+                       if ((int)$settings['cookieSecure'] !== 1 || t3lib_div::getIndpEnv('TYPO3_SSL')) {
+                               setcookie(
+                                       $this->name,
+                                       $this->id,
+                                       $cookieExpire,
+                                       $cookiePath,
+                                       $cookieDomain,
+                                       $cookieSecure,
+                                       $cookieHttpOnly
+                               );
+                       } else {
+                               throw new t3lib_exception(
+                                       'Cookie was not set since HTTPS was forced in $TYPO3_CONF_VARS[SYS][cookieSecure].',
+                                       1254325546
+                               );
+                       }
+
+                       if ($this->writeDevLog) {
+                               $devLogMessage = ($isRefreshTimeBasedCookie ? 'Updated Cookie: ' : 'Set Cookie: ') . $this->id;
+                               t3lib_div::devLog($devLogMessage . ($cookieDomain ? ', '.$cookieDomain : ''), 't3lib_userAuth');
+                       }
+               }
+       }
+
+       /**
+        * Gets the domain to be used on setting cookies.
+        * The information is taken from the value in $TYPO3_CONF_VARS[SYS][cookieDomain].
+        *
+        * @return      string          The domain to be used on setting cookies
+        */
+       protected function getCookieDomain() {
+               $result = '';
+               $cookieDomain = $GLOBALS['TYPO3_CONF_VARS']['SYS']['cookieDomain'];
+
+               if ($cookieDomain) {
+                       if ($cookieDomain{0} == '/') {
+                               $matchCnt = @preg_match($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) {
+                                       $result = $match[0];
+                               }
+                       } else {
+                               $result = $cookieDomain;
+                       }
+               }
+
+               return $result;
+       }
+
+       /**
+        * 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;
        }
 
        /**
@@ -367,7 +452,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 />
@@ -378,23 +463,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
@@ -417,15 +521,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
@@ -443,9 +547,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
@@ -478,25 +582,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);
@@ -519,29 +621,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);
+       }
 
 
 
@@ -578,14 +694,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.
@@ -599,30 +708,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
@@ -632,6 +748,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).'
@@ -639,6 +756,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...
                        }
@@ -686,6 +805,22 @@ class t3lib_userAuth {
                }
        }
 
+       /**
+        * 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));
+       }
+
 
 
 
@@ -705,6 +840,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
@@ -714,8 +870,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'] . ')' : '');
        }
 
        /**
@@ -1029,12 +1185,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;
                }
 
@@ -1050,19 +1206,22 @@ 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, deprecated etc.
+        * Redirect to somewhere (obsolete).
         *
         * @return      void
+        * @deprecated since TYPO3 3.6, this function will be removed in TYPO3 4.5.
+        * @obsolete
         * @ignore
         */
        function redirect() {
                if (!$this->userid && $this->auth_url)  {        // if no userid AND an include-document for login is given
+                       t3lib_div::deprecationLog('Redirection after login via PHP include is deprecated.');
                        include ($this->auth_include);
                        exit;
                }
@@ -1190,7 +1349,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(
@@ -1216,4 +1375,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