2 namespace TYPO3\CMS\Core\Authentication;
359 if (empty($this->loginType)) {
360 throw new \TYPO3\CMS\Core\Exception(
'No loginType defined, should be set explicitly by subclass');
363 if (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_userauth.php'][
'writeDevLog']) {
364 $this->writeDevLog =
true;
366 if (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_userauth.php'][
'writeDevLog' . $this->loginType]) {
367 $this->writeDevLog =
true;
370 $this->writeDevLog =
true;
372 if ($this->writeDevLog) {
373 GeneralUtility::devLog(
'## Beginning of auth logging.', \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
377 $this->newSessionID =
false;
380 $this->svConfig =
$GLOBALS[
'TYPO3_CONF_VARS'][
'SVCONF'][
'auth'];
383 if (!
$id && $this->getFallBack && $this->get_name) {
385 if (strlen(
$id) != $this->hash_length) {
396 $this->newSessionID =
true;
401 if ($mode ==
'get' && $this->getFallBack && $this->get_name) {
402 $this->get_URL_ID =
'&' . $this->get_name .
'=' .
$id;
409 if ($this->sendNoCacheHeaders && !(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI)) {
410 header(
'Expires: 0');
411 header(
'Last-Modified: ' . gmdate(
'D, d M Y H:i:s') .
' GMT');
412 $cacheControlHeader =
'no-cache, must-revalidate';
413 $pragmaHeader =
'no-cache';
420 $cacheControlHeader =
'must-revalidate';
422 $pragmaHeader =
'private';
424 header(
'Cache-Control: ' . $cacheControlHeader);
425 header(
'Pragma: ' . $pragmaHeader);
431 if (!$this->dontSetCookie) {
435 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_userauth.php'][
'postUserLookUp'])) {
436 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_userauth.php'][
'postUserLookUp'] as $funcName) {
444 if ($this->gc_time == 0) {
449 if (rand() % 100 <= $this->gc_probability) {
464 if ($isSetSessionCookie || $isRefreshTimeBasedCookie) {
465 $settings =
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'];
471 $cookieExpire = $isRefreshTimeBasedCookie ?
$GLOBALS[
'EXEC_TIME'] + $this->lifetime : 0;
475 $cookieHttpOnly = (bool)$settings[
'cookieHttpOnly'];
478 setcookie($this->name, $this->
id, $cookieExpire, $cookiePath, $cookieDomain, $cookieSecure, $cookieHttpOnly);
479 $this->cookieWasSetOnCurrentRequest =
true;
481 throw new \TYPO3\CMS\Core\Exception(
'Cookie was not set since HTTPS was forced in $TYPO3_CONF_VARS[SYS][cookieSecure].', 1254325546);
483 if ($this->writeDevLog) {
484 $devLogMessage = ($isRefreshTimeBasedCookie ?
'Updated Cookie: ' :
'Set Cookie: ') . $this->
id;
485 GeneralUtility::devLog($devLogMessage . ($cookieDomain ?
', ' . $cookieDomain :
''), \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
499 $cookieDomain =
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'cookieDomain'];
502 if (!empty(
$GLOBALS[
'TYPO3_CONF_VARS'][$this->loginType][
'cookieDomain'])) {
506 if ($cookieDomain[0] ==
'/') {
509 if ($matchCnt ===
false) {
510 GeneralUtility::sysLog(
'The regular expression for the cookie domain (' . $cookieDomain .
') contains errors. The session is not shared across sub-domains.',
'core',
GeneralUtility::SYSLOG_SEVERITY_ERROR);
515 $result = $cookieDomain;
529 return isset($_COOKIE[$cookieName]) ? stripslashes($_COOKIE[$cookieName]) :
'';
540 return ($this->newSessionID || $this->forceSetCookie) && $this->lifetime == 0;
551 return $this->lifetime > 0;
564 $tempuserArr = array();
567 $authenticated =
false;
569 $activeLogin =
false;
571 $this->loginFailure =
false;
572 if ($this->writeDevLog) {
573 GeneralUtility::devLog(
'Login type: ' . $this->loginType, \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
579 if ($this->writeDevLog) {
583 if ($loginData[
'status'] ==
'logout') {
584 if ($this->writeStdLog) {
586 $this->
writelog(255, 2, 0, 2,
'User %s logged out', array($this->user[
'username']),
'', 0, 0);
589 if ($this->writeDevLog) {
590 GeneralUtility::devLog(
'User logged out. Id: ' . $this->
id, \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class, -1);
595 if ($loginData[
'status'] ==
'login') {
597 if ($this->writeDevLog) {
598 GeneralUtility::devLog(
'Active login (eg. with login form)', \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
601 if ($this->formfield_status && $loginData[
'uident'] && $loginData[
'uname']) {
603 if (!$this->getMethodEnabled && ($httpHost != $authInfo[
'refInfo'][
'host'] && !
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'doNotCheckReferer'])) {
604 throw new \RuntimeException(
'TYPO3 Fatal Error: Error: This host address ("' . $httpHost .
'") and the referer host ("' . $authInfo[
'refInfo'][
'host'] .
'") mismatches! ' .
605 'It is possible that the environment variable HTTP_REFERER is not passed to the script because of a proxy. ' .
606 'The site administrator can disable this check in the "All Configuration" section of the Install Tool (flag: TYPO3_CONF_VARS[SYS][doNotCheckReferer]).', 1270853930);
613 if (strtoupper(substr($loginData[
'uname'], 0, 5)) ==
'_CLI_' && !(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI)) {
614 throw new \RuntimeException(
'TYPO3 Fatal Error: You have tried to login using a CLI user. Access prohibited!', 1270853931);
622 $haveSession =
false;
623 if (!$this->newSessionID) {
626 $haveSession = is_array($authInfo[
'userSession']);
628 if ($this->writeDevLog) {
632 GeneralUtility::devLog(
'No user session found.', \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class, 2);
634 if (is_array($this->svConfig[
'setup'])) {
640 $activeLogin || $this->svConfig[
'setup'][$this->loginType .
'_alwaysFetchUser']
641 || !$haveSession && $this->svConfig[
'setup'][$this->loginType .
'_fetchUserIfNoSession']
648 $serviceChain .=
',' . $serviceObj->getServiceKey();
649 $serviceObj->initAuth($subType, $loginData, $authInfo, $this);
650 if ($row = $serviceObj->getUser()) {
651 $tempuserArr[] = $row;
652 if ($this->writeDevLog) {
656 if (!$this->svConfig[
'setup'][($this->loginType .
'_fetchAllUsers')]) {
663 if ($this->writeDevLog && $this->svConfig[
'setup'][$this->loginType .
'_alwaysFetchUser']) {
664 GeneralUtility::devLog($this->loginType .
'_alwaysFetchUser option is enabled', \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
666 if ($this->writeDevLog && $serviceChain) {
667 GeneralUtility::devLog($subType .
' auth services called: ' . $serviceChain, \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
669 if ($this->writeDevLog && empty($tempuserArr)) {
670 GeneralUtility::devLog(
'No user found by services', \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
672 if ($this->writeDevLog && !empty($tempuserArr)) {
673 GeneralUtility::devLog(count($tempuserArr) .
' user records found by services', \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
677 if (empty($tempuserArr) && $haveSession) {
678 $tempuserArr[] = $authInfo[
'userSession'];
679 $tempuser = $authInfo[
'userSession'];
681 $authenticated =
true;
682 if ($this->writeDevLog) {
687 if ($this->svConfig[
'setup'][$this->loginType .
'_alwaysAuthUser']) {
688 $authenticated =
false;
689 if ($this->writeDevLog) {
690 GeneralUtility::devLog(
'alwaysAuthUser option is enabled', \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
694 if (!empty($tempuserArr) && !$authenticated) {
695 foreach ($tempuserArr as $tempuser) {
699 if ($this->writeDevLog) {
705 $serviceChain .=
',' . $serviceObj->getServiceKey();
706 $serviceObj->initAuth($subType, $loginData, $authInfo, $this);
707 if (($ret = $serviceObj->authUser($tempuser)) > 0) {
709 if ((
int)$ret >= 200) {
710 $authenticated =
true;
712 }
elseif ((
int)$ret >= 100) {
714 $authenticated =
true;
717 $authenticated =
false;
723 if ($this->writeDevLog && $serviceChain) {
724 GeneralUtility::devLog($subType .
' auth services called: ' . $serviceChain, \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
726 if ($authenticated) {
733 if ($authenticated) {
735 $this->loginFailure =
false;
737 if (!($haveSession && ($tempuser[
'ses_id'] == $this->
id || $tempuser[
'uid'] == $authInfo[
'userSession'][
'ses_userid']))) {
740 $this->user = array_merge(
746 $this->loginSessionStarted =
true;
747 if ($this->writeDevLog && is_array($this->user)) {
751 $this->user = $authInfo[
'userSession'];
753 if ($activeLogin && !$this->newSessionID) {
757 if ($this->writeStdLog && $activeLogin) {
758 $this->
writelog(255, 1, 0, 1,
'User %s logged in from %s (%s)', array($tempuser[$this->username_column],
GeneralUtility::getIndpEnv(
'REMOTE_ADDR'),
GeneralUtility::getIndpEnv(
'REMOTE_HOST')),
'',
'',
'', -1,
'', $tempuser[
'uid']);
760 if ($this->writeDevLog && $activeLogin) {
763 if ($this->writeDevLog && !$activeLogin) {
766 }
elseif ($activeLogin || !empty($tempuserArr)) {
767 $this->loginFailure =
true;
768 if ($this->writeDevLog && empty($tempuserArr) && $activeLogin) {
771 if ($this->writeDevLog && !empty($tempuserArr)) {
776 if ($this->loginFailure && $activeLogin) {
777 if ($this->writeDevLog) {
778 GeneralUtility::devLog(
'Call checkLogFailures: ' .
GeneralUtility::arrayToLogString(array(
'warningEmail' => $this->warningEmail,
'warningPeriod' => $this->warningPeriod,
'warningMax' => $this->warningMax)), \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class, -1);
783 !empty(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_userauth.php'][
'postLoginFailureProcessing'])
784 && is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_userauth.php'][
'postLoginFailureProcessing'])
787 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_userauth.php'][
'postLoginFailureProcessing'] as $_funcRef) {
795 $this->
checkLogFailures($this->warningEmail, $this->warningPeriod, $this->warningMax);
819 $this->db->exec_UPDATEquery(
820 $this->session_table,
821 'ses_id = ' . $this->db->fullQuoteStr($oldSessionId, $this->session_table)
822 .
' AND ses_name = ' . $this->db->fullQuoteStr($this->name, $this->session_table),
823 array(
'ses_id' => $this->
id)
825 $this->newSessionID =
true;
842 if ($this->writeDevLog) {
843 GeneralUtility::devLog(
'Create session ses_id = ' . $this->
id, \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
846 $this->db->exec_DELETEquery(
847 $this->session_table,
848 'ses_id = ' . $this->db->fullQuoteStr($this->id, $this->session_table)
849 .
' AND ses_name = ' . $this->db->fullQuoteStr($this->name, $this->session_table)
853 $inserted = (bool)$this->db->exec_INSERTquery($this->session_table, $insertFields);
855 $message =
'Session data could not be written to DB. Error: ' . $this->db->sql_error();
857 if ($this->writeDevLog) {
862 if ($this->lastLogin_column && $inserted) {
863 $this->db->exec_UPDATEquery(
865 $this->userid_column .
'=' . $this->db->fullQuoteStr($tempuser[$this->userid_column], $this->user_table),
866 array($this->lastLogin_column =>
$GLOBALS[
'EXEC_TIME'])
870 return $inserted ? $insertFields : array();
883 'ses_id' => $this->
id,
884 'ses_name' => $this->name,
887 'ses_userid' => $tempuser[$this->userid_column],
888 'ses_tstamp' =>
$GLOBALS[
'EXEC_TIME'],
902 if ($this->writeDevLog) {
903 GeneralUtility::devLog(
'Fetch session ses_id = ' . $this->
id, \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
910 $statement->execute();
911 $user = $statement->fetch();
916 if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->auth_timeout_field)) {
918 $timeout = (int)$this->auth_timeout_field;
921 $timeout = (int)
$user[$this->auth_timeout_field];
925 if ($timeout > 0 &&
$GLOBALS[
'EXEC_TIME'] <
$user[
'ses_tstamp'] + $timeout) {
926 $sessionUpdateGracePeriod = 61;
927 if (!$skipSessionUpdate &&
$GLOBALS[
'EXEC_TIME'] > (
$user[
'ses_tstamp'] + $sessionUpdateGracePeriod)) {
928 $this->db->exec_UPDATEquery($this->session_table,
'ses_id=' . $this->db->fullQuoteStr($this->id, $this->session_table)
929 .
' AND ses_name=' . $this->db->fullQuoteStr($this->name, $this->session_table), array(
'ses_tstamp' =>
$GLOBALS[
'EXEC_TIME']));
951 if ($this->writeDevLog) {
952 GeneralUtility::devLog(
'logoff: ses_id = ' . $this->
id, \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
955 \TYPO3\CMS\Backend\Utility\BackendUtility::lockRecords();
957 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_userauth.php'][
'logoff_pre_processing'])) {
959 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_userauth.php'][
'logoff_pre_processing'] as $_funcRef) {
965 $this->db->exec_DELETEquery($this->session_table,
'ses_id = ' . $this->db->fullQuoteStr($this->id, $this->session_table) .
'
966 AND ses_name = ' . $this->db->fullQuoteStr($this->name, $this->session_table));
969 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_userauth.php'][
'logoff_post_processing'])) {
971 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
't3lib/class.t3lib_userauth.php'][
'logoff_post_processing'] as $_funcRef) {
990 setcookie($cookieName, null, -1, $cookiePath, $cookieDomain);
1002 $statement = $this->db->prepare_SELECTquery(
'COUNT(*)', $this->session_table,
'ses_id = :ses_id');
1003 $statement->execute(array(
':ses_id' =>
$id));
1004 $row = $statement->fetch(\TYPO3\CMS\Core\Database\PreparedStatement::FETCH_NUM);
1006 return (
bool)$row[0];
1017 return $this->cookieWasSetOnCurrentRequest || $this->
getCookie($this->name);
1039 $statement = $this->db->prepare_SELECTquery(
'*', $this->session_table .
',' . $this->user_table, $this->session_table .
'.ses_id = :ses_id
1040 AND ' . $this->session_table .
'.ses_name = :ses_name
1041 AND ' . $this->session_table .
'.ses_userid = ' . $this->user_table .
'.' . $this->userid_column .
'
1042 ' . $ipLockClause[
'where'] .
'
1045 $statement->bindValues(array(
1046 ':ses_id' => $this->
id,
1047 ':ses_name' => $this->name
1049 $statement->bindValues($ipLockClause[
'parameters']);
1063 if ($this->enablecolumns[
'rootLevel']) {
1064 $whereClause .=
'AND ' . $this->user_table .
'.pid=0 ';
1066 if ($this->enablecolumns[
'disabled']) {
1067 $whereClause .=
' AND ' . $this->user_table .
'.' . $this->enablecolumns[
'disabled'] .
'=0';
1069 if ($this->enablecolumns[
'deleted']) {
1070 $whereClause .=
' AND ' . $this->user_table .
'.' . $this->enablecolumns[
'deleted'] .
'=0';
1072 if ($this->enablecolumns[
'starttime']) {
1073 $whereClause .=
' AND (' . $this->user_table .
'.' . $this->enablecolumns[
'starttime'] .
'<=' .
$GLOBALS[
'EXEC_TIME'] .
')';
1075 if ($this->enablecolumns[
'endtime']) {
1076 $whereClause .=
' AND (' . $this->user_table .
'.' . $this->enablecolumns[
'endtime'] .
'=0 OR '
1077 . $this->user_table .
'.' . $this->enablecolumns[
'endtime'] .
'>' .
$GLOBALS[
'EXEC_TIME'] .
')';
1079 return $whereClause;
1090 $statementClause = array(
1092 'parameters' => array()
1094 if ($this->lockIP) {
1095 $statementClause[
'where'] =
'AND (
1096 ' . $this->session_table .
'.ses_iplock = :ses_iplock
1097 OR ' . $this->session_table .
'.ses_iplock=\'[DISABLED]\'
1099 $statementClause[
'parameters'] = array(
1103 return $statementClause;
1120 $parts = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($parts, 1, 3);
1121 $IPparts = explode(
'.', $IP);
1122 for ($a = 4; $a > $parts; $a--) {
1123 unset($IPparts[$a - 1]);
1125 return implode(
'.', $IPparts);
1138 return substr(md5($this->
id .
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'encryptionKey']), 0, 10);
1182 if (is_array($this->user) && $this->user[$this->userid_column]) {
1183 if (!is_array($variable)) {
1186 if ($this->writeDevLog) {
1187 GeneralUtility::devLog(
'writeUC: ' . $this->userid_column .
'=' . (
int)$this->user[$this->userid_column], \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
1189 $this->db->exec_UPDATEquery($this->user_table, $this->userid_column .
'=' . (
int)$this->user[$this->userid_column], array(
'uc' => serialize($variable)));
1202 if (!$theUC && isset($this->user[
'uc'])) {
1203 $theUC = unserialize($this->user[
'uc']);
1205 if (is_array($theUC)) {
1222 $this->uc[
'moduleData'][$module] = $data;
1223 $this->uc[
'moduleSessionID'][$module] =
$this->id;
1238 if ($type !=
'ses' || (isset($this->uc[
'moduleSessionID'][$module]) && $this->uc[
'moduleSessionID'][$module] == $this->
id)) {
1239 return $this->uc[
'moduleData'][$module];
1253 $sesDat = unserialize($this->user[
'ses_data']);
1254 return $sesDat[$key];
1267 $sesDat = unserialize($this->user[
'ses_data']);
1268 $sesDat[$key] = $data;
1269 $this->user[
'ses_data'] = serialize($sesDat);
1270 if ($this->writeDevLog) {
1271 GeneralUtility::devLog(
'setAndSaveSessionData: ses_id = ' . $this->user[
'ses_id'], \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication::class);
1273 $this->db->exec_UPDATEquery($this->session_table,
'ses_id=' . $this->db->fullQuoteStr($this->user[
'ses_id'], $this->session_table), array(
'ses_data' => $this->user[
'ses_data']));
1289 $loginData = array();
1291 if ($this->getMethodEnabled) {
1299 if ($loginData[
'status'] ===
'login') {
1302 $loginData = array_map(
'trim', $loginData);
1317 $loginSecurityLevel = trim(
$GLOBALS[
'TYPO3_CONF_VARS'][$this->loginType][
'loginSecurityLevel']) ?:
'normal';
1318 $passwordTransmissionStrategy = $passwordTransmissionStrategy ?: $loginSecurityLevel;
1319 if ($this->writeDevLog) {
1325 $isLoginDataProcessed =
false;
1326 $processedLoginData = $loginData;
1328 $serviceChain .=
',' . $serviceObject->getServiceKey();
1329 $serviceObject->initAuth($subType, $loginData, $authInfo, $this);
1330 $serviceResult = $serviceObject->processLoginData($processedLoginData, $passwordTransmissionStrategy);
1331 if (!empty($serviceResult)) {
1332 $isLoginDataProcessed =
true;
1334 if ((
int)$serviceResult >= 200) {
1335 unset($serviceObject);
1339 unset($serviceObject);
1341 if ($isLoginDataProcessed) {
1342 $loginData = $processedLoginData;
1343 if ($this->writeDevLog) {
1358 $authInfo = array();
1372 if ($this->checkPid && $this->checkPid_value !== null) {
1374 $authInfo[
'db_user'][
'check_pid_clause'] =
' AND pid IN (' .
1375 $this->db->cleanIntList($this->checkPid_value) .
')';
1377 $authInfo[
'db_user'][
'checkPidList'] =
'';
1378 $authInfo[
'db_user'][
'check_pid_clause'] =
'';
1394 return (
string)$loginData[
'uident_text'] === (string)
$user[$this->userident_column];
1405 $this->db->exec_DELETEquery($this->session_table,
'ses_tstamp < ' . (
int)(
$GLOBALS[
'EXEC_TIME'] - $this->gc_time) .
' AND ses_name = ' . $this->db->fullQuoteStr($this->name, $this->session_table));
1422 public function writelog($type, $action, $error, $details_nr, $details, $data, $tablename, $recuid, $recpid)
1480 $dbres = $this->db->exec_SELECTquery(
'*', $this->user_table,
'uid=' . (
int)$uid .
' ' . $this->
user_where_clause());
1482 $user = $this->db->sql_fetch_assoc($dbres);
1483 $this->db->sql_free_result($dbres);
1499 $dbres = $this->db->exec_SELECTquery(
'*', $this->user_table,
'username=' . $this->db->fullQuoteStr(
$name, $this->user_table) .
' ' . $this->
user_where_clause());
1501 $user = $this->db->sql_fetch_assoc($dbres);
1502 $this->db->sql_free_result($dbres);
1524 $usernameClause = $username ? $dbUser[
'username_column'] .
'=' . $this->db->fullQuoteStr($username, $dbUser[
'table']) :
'1=1';
1525 if ($username || $extraWhere) {
1527 $dbres = $this->db->exec_SELECTquery(
'*', $dbUser[
'table'], $usernameClause . $dbUser[
'check_pid_clause'] . $dbUser[
'enable_clause'] . $extraWhere);
1529 $user = $this->db->sql_fetch_assoc($dbres);
1530 $this->db->sql_free_result($dbres);