/** * Write session data * * @param string session id * @param string session data */ static function _writeData($a_session_id, $a_data) { global $ilDB, $ilClientIniFile; if ($GLOBALS['WEB_ACCESS_WITHOUT_SESSION']) { // Prevent session data written for web access checker // when no cookie was sent (e.g. for pdf files linking others). // This would result in new session records for each request. return false; } $now = time(); // prepare session data $fields = array("user_id" => array("integer", (int) $_SESSION["AccountId"]), "expires" => array("integer", self::getExpireValue()), "data" => array("clob", $a_data), "ctime" => array("integer", $now), "type" => array("integer", (int) $_SESSION["SessionType"])); if ($ilClientIniFile->readVariable("session", "save_ip")) { $fields["remote_addr"] = array("text", $_SERVER["REMOTE_ADDR"]); } if (ilSession::_exists($a_session_id)) { $ilDB->update("usr_session", $fields, array("session_id" => array("text", $a_session_id))); } else { $fields["session_id"] = array("text", $a_session_id); $fields["createtime"] = array("integer", $now); $ilDB->insert("usr_session", $fields); // check type against session control $type = $fields["type"][1]; if (in_array($type, ilSessionControl::$session_types_controlled)) { ilSessionStatistics::createRawEntry($fields["session_id"][1], $type, $fields["createtime"][1], $fields["user_id"][1]); } } // finally delete deprecated sessions if (rand(0, 50) == 2) { // get time _before_ destroying expired sessions self::_destroyExpiredSessions(); ilSessionStatistics::aggretateRaw($now); } return true; }
/** * checks wether the current session exhaust the limit of sessions * when limit is reached it deletes "firstRequestAbidencer" and checks again * when limit is still reached it deletes "oneMinIdleSession" and checks again * when limit is still reached the current session will be logged out * * @global ilSetting $ilSetting * @global ilAppEventHandler $ilAppEventHandler * @param Auth $a_auth */ private static function checkCurrentSessionIsAllowed(Auth $a_auth, $a_user_id) { global $ilSetting; $max_sessions = (int) $ilSetting->get('session_max_count', DEFAULT_MAX_COUNT); if ($max_sessions > 0) { // get total number of sessions $num_sessions = self::getExistingSessionCount(self::$session_types_controlled); self::debug(__METHOD__ . "--> total existing sessions (" . $num_sessions . ")"); if ($num_sessions + 1 > $max_sessions) { self::debug(__METHOD__ . ' --> limit for session pool reached, but try kicking some first request abidencer'); self::kickFirstRequestAbidencer(self::$session_types_controlled); // get total number of sessions again $num_sessions = self::getExistingSessionCount(self::$session_types_controlled); if ($num_sessions + 1 > $max_sessions) { self::debug(__METHOD__ . ' --> limit for session pool still reached so try kick one min idle session'); self::kickOneMinIdleSession(self::$session_types_controlled); // get total number of sessions again $num_sessions = self::getExistingSessionCount(self::$session_types_controlled); if ($num_sessions + 1 > $max_sessions) { self::debug(__METHOD__ . ' --> limit for session pool still reached so logout session (' . session_id() . ') and trigger event'); ilSession::setClosingContext(ilSession::SESSION_CLOSE_LIMIT); // as the session is opened and closed in one request, there // is no proper session yet and we have to do this ourselves ilSessionStatistics::createRawEntry(session_id(), $_SESSION['SessionType'], time(), $a_user_id); $a_auth->logout(); // Trigger reachedSessionPoolLimit Event global $ilAppEventHandler; $ilAppEventHandler->raise('Services/Authentication', 'reachedSessionPoolLimit', array()); // auth won't do this, we need to close session properly session_destroy(); ilUtil::redirect('login.php?reached_session_limit=true'); } else { self::debug(__METHOD__ . ' --> limit of session pool not reached anymore after kicking one min idle session'); } } else { self::debug(__METHOD__ . ' --> limit of session pool not reached anymore after kicking some first request abidencer'); } } else { self::debug(__METHOD__ . ' --> limit for session pool not reached yet'); } } else { self::debug(__METHOD__ . ' --> limit for session pool not set so check is bypassed'); } }