diff options
Diffstat (limited to 'engine/lib/sessions.php')
| -rw-r--r-- | engine/lib/sessions.php | 1055 |
1 files changed, 643 insertions, 412 deletions
diff --git a/engine/lib/sessions.php b/engine/lib/sessions.php index 02a3e06ca..e3d5ce9cd 100644 --- a/engine/lib/sessions.php +++ b/engine/lib/sessions.php @@ -1,425 +1,656 @@ -<?php
-
- /**
- * Elgg session management
- * Functions to manage logins
- *
- * @package Elgg
- * @subpackage Core
- * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
- * @author Curverider Ltd
- * @copyright Curverider Ltd 2008
- * @link http://elgg.org/
- */
-
- /**
- * Returns whether or not the user is currently logged in
- *
- * @uses $_SESSION
- * @return true|false
- */
- function isloggedin() {
-
- if (!is_installed()) return false;
- if ((isset($_SESSION['guid'])) && ($_SESSION['guid'] > 0) && (isset($_SESSION['id'])) && ($_SESSION['id'] > 0) ) -
- return true;
- return false;
-
- }
- - /** - * Returns whether or not the user is currently logged in and that they are an admin user. - * - * @uses $_SESSION - * @uses isloggedin() - * @return true|false - */ - function isadminloggedin() - { - if ((isloggedin()) && (($_SESSION['user']->admin || $_SESSION['user']->siteadmin))) - return true; - - return false; - } -
- /**
- * Perform standard authentication with a given username and password.
- * Returns an ElggUser object for use with login.
- *
- * @see login
- * @param string $username The username, optionally (for standard logins)
- * @param string $password The password, optionally (for standard logins)
- * @return ElggUser|false The authenticated user object, or false on failure.
- */
-
- function authenticate($username, $password) {
- - if (pam_authenticate(array('username' => $username, 'password' => $password))) - return get_user_by_username($username);
-
- return false;
-
- } - - /** - * Hook into the PAM system which accepts a username and password and attempts to authenticate - * it against a known user. - * - * @param array $credentials Associated array of credentials passed to pam_authenticate. This function expects - * 'username' and 'password' (cleartext). - */ - function pam_auth_userpass($credentials = NULL) - { - if (is_array($credentials) && ($credentials['username']) && ($credentials['password'])) - { - //$dbpassword = md5($credentials['password']); - - - if ($user = get_user_by_username($credentials['username'])) { - // Let admins log in without validating their email, but normal users must have validated their email - if ((!$user->admin) && (!$user->validated) && (!$user->admin_created)) - return false; - - if ($user->password == generate_user_password($user, $credentials['password'])) { - return true; - } - } - } - - return false; - }
-
- /**
- * Logs in a specified ElggUser. For standard registration, use in conjunction
- * with authenticate.
- *
- * @see authenticate
- * @param ElggUser $user A valid Elgg user object
- * @param boolean $persistent Should this be a persistent login?
- * @return true|false Whether login was successful
- */
- function login(ElggUser $user, $persistent = false) {
-
- global $CONFIG; -
- $_SESSION['user'] = $user;
- $_SESSION['guid'] = $user->getGUID();
- $_SESSION['id'] = $_SESSION['guid'];
- $_SESSION['username'] = $user->username;
- $_SESSION['name'] = $user->name;
-
- $code = (md5($user->name . $user->username . time() . rand()));
-
- $user->code = md5($code);
-
- $_SESSION['code'] = $code;
-
- if (($persistent))
- setcookie("elggperm", $code, (time()+(86400 * 30)),"/");
-
- if (!$user->save() || !trigger_elgg_event('login','user',$user)) {
- unset($_SESSION['username']);
- unset($_SESSION['name']);
- unset($_SESSION['code']);
- unset($_SESSION['guid']);
- unset($_SESSION['id']);
- unset($_SESSION['user']);
- setcookie("elggperm", "", (time()-(86400 * 30)),"/");
- return false;
- } - - // Users privilege has been elevated, so change the session id (help prevent session hijacking) - session_regenerate_id();
-
- return true;
-
- }
-
- /**
- * Log the current user out
- *
- * @return true|false
- */
- function logout() {
- global $CONFIG;
-
- if (isset($_SESSION['user'])) {
- if (!trigger_elgg_event('logout','user',$_SESSION['user'])) return false;
- $_SESSION['user']->code = "";
- $_SESSION['user']->save();
- } -
- unset($_SESSION['username']);
- unset($_SESSION['name']);
- unset($_SESSION['code']);
- unset($_SESSION['guid']);
- unset($_SESSION['id']);
- unset($_SESSION['user']);
-
- setcookie("elggperm", "", (time()-(86400 * 30)),"/"); - - session_destroy();
-
- return true;
- } - - function get_session_fingerprint() - { - global $CONFIG; - - return md5($_SERVER['HTTP_USER_AGENT'] ); - }
-
- /**
- * Initialises the system session and potentially logs the user in
- *
- * This function looks for:
- *
- * 1. $_SESSION['id'] - if not present, we're logged out, and this is set to 0
- * 2. The cookie 'elggperm' - if present, checks it for an authentication token, validates it, and potentially logs the user in
- *
- * @uses $_SESSION
- * @param unknown_type $event
- * @param unknown_type $object_type
- * @param unknown_type $object
- */
- function session_init($event, $object_type, $object) {
- - global $DB_PREFIX, $CONFIG; -
- if (!is_db_installed()) return false; - - // Use database for sessions - $DB_PREFIX = $CONFIG->dbprefix; // HACK to allow access to prefix after object distruction - session_set_save_handler("__elgg_session_open", "__elgg_session_close", "__elgg_session_read", "__elgg_session_write", "__elgg_session_destroy", "__elgg_session_gc"); -
- session_name('Elgg');
- session_start(); - - // Do some sanity checking by generating a fingerprint (makes some XSS attacks harder) - if (isset($_SESSION['__elgg_fingerprint'])) - { - if ($_SESSION['__elgg_fingerprint'] != get_session_fingerprint()) - { - session_destroy(); - return false; - } - } - else - { - $_SESSION['__elgg_fingerprint'] = get_session_fingerprint(); - } - - // Generate a simple token - if (!isset($_SESSION['__elgg_session'])) $_SESSION['__elgg_session'] = md5(microtime().rand()); -
- if (empty($_SESSION['guid'])) {
- if (isset($_COOKIE['elggperm'])) {
- $code = $_COOKIE['elggperm'];
- $code = md5($code);
- $_SESSION['guid'] = 0;
- $_SESSION['id'] = 0; - // $_SESSION['user'] = new ElggDummy();
- if ($user = get_user_by_code($code)) {
- $_SESSION['user'] = $user;
- $_SESSION['id'] = $user->getGUID();
- $_SESSION['guid'] = $_SESSION['id'];
- $_SESSION['code'] = $_COOKIE['elggperm'];
- }
- } else { - //$_SESSION['user'] = new ElggDummy();
- $_SESSION['id'] = 0;
- $_SESSION['guid'] = 0; - $_SESSION['code'] = "";
- }
- } else {
- if (!empty($_SESSION['code'])) {
- $code = md5($_SESSION['code']);
- if ($user = get_user_by_code($code)) {
- $_SESSION['user'] = $user; - $_SESSION['id'] = $user->getGUID(); - $_SESSION['guid'] = $_SESSION['id'];
- } else {
- unset($_SESSION['user']); - // $_SESSION['user'] = new ElggDummy();
- $_SESSION['guid'] = 0;
- $_SESSION['id'] = 0; - $_SESSION['code'] = "";
- }
- } else { - //$_SESSION['user'] = new ElggDummy();
- $_SESSION['guid'] = 0;
- $_SESSION['id'] = 0; - $_SESSION['code'] = "";
- }
- }
- if ($_SESSION['id'] > 0) {
- set_last_action($_SESSION['id']);
- }
-
- register_action("login",true);
- register_action("logout");
- - // Register a default PAM handler - register_pam_handler('pam_auth_userpass'); -
- return true;
-
- }
-
- /**
- * Used at the top of a page to mark it as logged in users only.
- *
- */
- function gatekeeper() {
- if (!isloggedin()) {
- $_SESSION['last_forward_from'] = current_page_url();
- forward();
- }
- } - - /** - * Used at the top of a page to mark it as logged in admin or siteadmin only. - * - */ - function admin_gatekeeper() - { - gatekeeper(); - if (!$_SESSION['user']->admin && !$_SESSION['user']->siteadmin) {
- $_SESSION['last_forward_from'] = current_page_url();
- forward();
+<?php + +/** + * Elgg session management + * Functions to manage logins + * + * @package Elgg.Core + * @subpackage Session + */ + +/** Elgg magic session */ +global $SESSION; + +/** + * Return the current logged in user, or NULL if no user is logged in. + * + * If no user can be found in the current session, a plugin + * hook - 'session:get' 'user' to give plugin authors another + * way to provide user details to the ACL system without touching the session. + * + * @return ElggUser + */ +function elgg_get_logged_in_user_entity() { + global $SESSION; + + if (isset($SESSION)) { + return $SESSION['user']; + } + + return NULL; +} + +/** + * Return the current logged in user by id. + * + * @see elgg_get_logged_in_user_entity() + * @return int + */ +function elgg_get_logged_in_user_guid() { + $user = elgg_get_logged_in_user_entity(); + if ($user) { + return $user->guid; + } + + return 0; +} + +/** + * Returns whether or not the user is currently logged in + * + * @return bool + */ +function elgg_is_logged_in() { + $user = elgg_get_logged_in_user_entity(); + + if ((isset($user)) && ($user instanceof ElggUser) && ($user->guid > 0)) { + return true; + } + + return false; +} + +/** + * Returns whether or not the user is currently logged in and that they are an admin user. + * + * @return bool + */ +function elgg_is_admin_logged_in() { + $user = elgg_get_logged_in_user_entity(); + + if ((elgg_is_logged_in()) && $user->isAdmin()) { + return TRUE; + } + + return FALSE; +} + +/** + * Check if the given user has full access. + * + * @todo: Will always return full access if the user is an admin. + * + * @param int $user_guid The user to check + * + * @return bool + * @since 1.7.1 + */ +function elgg_is_admin_user($user_guid) { + global $CONFIG; + + $user_guid = (int)$user_guid; + + // cannot use magic metadata here because of recursion + + // must support the old way of getting admin from metadata + // in order to run the upgrade to move it into the users table. + $version = (int) datalist_get('version'); + + if ($version < 2010040201) { + $admin = get_metastring_id('admin'); + $yes = get_metastring_id('yes'); + $one = get_metastring_id('1'); + + $query = "SELECT * FROM {$CONFIG->dbprefix}users_entity as e, + {$CONFIG->dbprefix}metadata as md + WHERE ( + md.name_id = '$admin' + AND md.value_id IN ('$yes', '$one') + AND e.guid = md.entity_guid + AND e.guid = {$user_guid} + AND e.banned = 'no' + )"; + } else { + $query = "SELECT * FROM {$CONFIG->dbprefix}users_entity as e + WHERE ( + e.guid = {$user_guid} + AND e.admin = 'yes' + )"; + } + + // normalizing the results from get_data() + // See #1242 + $info = get_data($query); + if (!((is_array($info) && count($info) < 1) || $info === FALSE)) { + return TRUE; + } + return FALSE; +} + +/** + * Perform user authentication with a given username and password. + * + * @warning This returns an error message on failure. Use the identical operator to check + * for access: if (true === elgg_authenticate()) { ... }. + * + * + * @see login + * + * @param string $username The username + * @param string $password The password + * + * @return true|string True or an error message on failure + * @access private + */ +function elgg_authenticate($username, $password) { + $pam = new ElggPAM('user'); + $credentials = array('username' => $username, 'password' => $password); + $result = $pam->authenticate($credentials); + if (!$result) { + return $pam->getFailureMessage(); + } + return true; +} + +/** + * Hook into the PAM system which accepts a username and password and attempts to authenticate + * it against a known user. + * + * @param array $credentials Associated array of credentials passed to + * Elgg's PAM system. This function expects + * 'username' and 'password' (cleartext). + * + * @return bool + * @throws LoginException + * @access private + */ +function pam_auth_userpass(array $credentials = array()) { + + if (!isset($credentials['username']) || !isset($credentials['password'])) { + return false; + } + + $user = get_user_by_username($credentials['username']); + if (!$user) { + throw new LoginException(elgg_echo('LoginException:UsernameFailure')); + } + + if (check_rate_limit_exceeded($user->guid)) { + throw new LoginException(elgg_echo('LoginException:AccountLocked')); + } + + if ($user->password !== generate_user_password($user, $credentials['password'])) { + log_login_failure($user->guid); + throw new LoginException(elgg_echo('LoginException:PasswordFailure')); + } + + return true; +} + +/** + * Log a failed login for $user_guid + * + * @param int $user_guid User GUID + * + * @return bool + */ +function log_login_failure($user_guid) { + $user_guid = (int)$user_guid; + $user = get_entity($user_guid); + + if (($user_guid) && ($user) && ($user instanceof ElggUser)) { + $fails = (int)$user->getPrivateSetting("login_failures"); + $fails++; + + $user->setPrivateSetting("login_failures", $fails); + $user->setPrivateSetting("login_failure_$fails", time()); + return true; + } + + return false; +} + +/** + * Resets the fail login count for $user_guid + * + * @param int $user_guid User GUID + * + * @return bool true on success (success = user has no logged failed attempts) + */ +function reset_login_failure_count($user_guid) { + $user_guid = (int)$user_guid; + $user = get_entity($user_guid); + + if (($user_guid) && ($user) && ($user instanceof ElggUser)) { + $fails = (int)$user->getPrivateSetting("login_failures"); + + if ($fails) { + for ($n = 1; $n <= $fails; $n++) { + $user->removePrivateSetting("login_failure_$n"); } - }
- - /** - * DB Based session handling code. - */ - function __elgg_session_open($save_path, $session_name) - { - global $sess_save_path; - $sess_save_path = $save_path; - - return true; - } - - /** - * DB Based session handling code. - */ - function __elgg_session_close() - { + + $user->removePrivateSetting("login_failures"); + return true; } - - /** - * DB Based session handling code. - */ - function __elgg_session_read($id) - { - global $DB_PREFIX; - - $id = sanitise_string($id); - - try { - $result = get_data_row("SELECT * from {$DB_PREFIX}users_sessions where session='$id'"); - - if ($result) - return (string)$result->data; - - } catch (DatabaseException $e) { - - // Fall back to file store in this case, since this likely means that the database hasn't been upgraded - global $sess_save_path; - - $sess_file = "$sess_save_path/sess_$id"; - return (string) @file_get_contents($sess_file); - } - - return ''; - } - - /** - * DB Based session handling code. - */ - function __elgg_session_write($id, $sess_data) - { - global $DB_PREFIX; - - $id = sanitise_string($id); + + // nothing to reset + return true; + } + + return false; +} + +/** + * Checks if the rate limit of failed logins has been exceeded for $user_guid. + * + * @param int $user_guid User GUID + * + * @return bool on exceeded limit. + */ +function check_rate_limit_exceeded($user_guid) { + // 5 failures in 5 minutes causes temporary block on logins + $limit = 5; + $user_guid = (int)$user_guid; + $user = get_entity($user_guid); + + if (($user_guid) && ($user) && ($user instanceof ElggUser)) { + $fails = (int)$user->getPrivateSetting("login_failures"); + if ($fails >= $limit) { + $cnt = 0; $time = time(); - - try { - $sess_data_sanitised = sanitise_string($sess_data); + for ($n = $fails; $n > 0; $n--) { + $f = $user->getPrivateSetting("login_failure_$n"); + if ($f > $time - (60 * 5)) { + $cnt++; + } - if (insert_data("REPLACE INTO {$DB_PREFIX}users_sessions (session, ts, data) VALUES ('$id', '$time', '$sess_data_sanitised')")!==false) + if ($cnt == $limit) { + // Limit reached return true; - - } catch (DatabaseException $e) { - // Fall back to file store in this case, since this likely means that the database hasn't been upgraded - global $sess_save_path; - - $sess_file = "$sess_save_path/sess_$id"; - if ($fp = @fopen($sess_file, "w")) { - $return = fwrite($fp, $sess_data); - fclose($fp); - return $return; - } - - else - error_log('marcus FAILED TO WRITe ' . print_r($CONFIG, true)); + } } - - return false; } - - /** - * DB Based session handling code. - */ - function __elgg_session_destroy($id) - { - global $DB_PREFIX; - - $id = sanitise_string($id); - - try { - return (bool)delete_data("DELETE from {$DB_PREFIX}users_sessions where session='$id'"); - } catch (DatabaseException $e) { - // Fall back to file store in this case, since this likely means that the database hasn't been upgraded - global $sess_save_path; - - $sess_file = "$sess_save_path/sess_$id"; - return(@unlink($sess_file)); - } - + } + + return false; +} + +/** + * Logs in a specified ElggUser. For standard registration, use in conjunction + * with elgg_authenticate. + * + * @see elgg_authenticate + * + * @param ElggUser $user A valid Elgg user object + * @param boolean $persistent Should this be a persistent login? + * + * @return true or throws exception + * @throws LoginException + */ +function login(ElggUser $user, $persistent = false) { + // User is banned, return false. + if ($user->isBanned()) { + throw new LoginException(elgg_echo('LoginException:BannedUser')); + } + + $_SESSION['user'] = $user; + $_SESSION['guid'] = $user->getGUID(); + $_SESSION['id'] = $_SESSION['guid']; + $_SESSION['username'] = $user->username; + $_SESSION['name'] = $user->name; + + // if remember me checked, set cookie with token and store token on user + if (($persistent)) { + $code = (md5($user->name . $user->username . time() . rand())); + $_SESSION['code'] = $code; + $user->code = md5($code); + setcookie("elggperm", $code, (time() + (86400 * 30)), "/"); + } + + if (!$user->save() || !elgg_trigger_event('login', 'user', $user)) { + unset($_SESSION['username']); + unset($_SESSION['name']); + unset($_SESSION['code']); + unset($_SESSION['guid']); + unset($_SESSION['id']); + unset($_SESSION['user']); + setcookie("elggperm", "", (time() - (86400 * 30)), "/"); + throw new LoginException(elgg_echo('LoginException:Unknown')); + } + + // Users privilege has been elevated, so change the session id (prevents session fixation) + session_regenerate_id(); + + // Update statistics + set_last_login($_SESSION['guid']); + reset_login_failure_count($user->guid); // Reset any previous failed login attempts + + // if memcache is enabled, invalidate the user in memcache @see https://github.com/Elgg/Elgg/issues/3143 + if (is_memcache_available()) { + // this needs to happen with a shutdown function because of the timing with set_last_login() + register_shutdown_function("_elgg_invalidate_memcache_for_entity", $_SESSION['guid']); + } + + return true; +} + +/** + * Log the current user out + * + * @return bool + */ +function logout() { + if (isset($_SESSION['user'])) { + if (!elgg_trigger_event('logout', 'user', $_SESSION['user'])) { return false; } - - /** - * DB Based session handling code. - */ - function __elgg_session_gc($maxlifetime) - { - global $DB_PREFIX; - - $life = time()-$maxlifetime; - - try { - return (bool)delete_data("DELETE from {$DB_PREFIX}users_sessions where ts<'$life'"); - } catch (DatabaseException $e) { - // Fall back to file store in this case, since this likely means that the database hasn't been upgraded - global $sess_save_path; - - foreach (glob("$sess_save_path/sess_*") as $filename) { - if (filemtime($filename) < $life) { - @unlink($filename); - } - } + $_SESSION['user']->code = ""; + $_SESSION['user']->save(); + } + + unset($_SESSION['username']); + unset($_SESSION['name']); + unset($_SESSION['code']); + unset($_SESSION['guid']); + unset($_SESSION['id']); + unset($_SESSION['user']); + + setcookie("elggperm", "", (time() - (86400 * 30)), "/"); + + // pass along any messages + $old_msg = $_SESSION['msg']; + + session_destroy(); + + // starting a default session to store any post-logout messages. + _elgg_session_boot(NULL, NULL, NULL); + $_SESSION['msg'] = $old_msg; + + return TRUE; +} + +/** + * Initialises the system session and potentially logs the user in + * + * This function looks for: + * + * 1. $_SESSION['id'] - if not present, we're logged out, and this is set to 0 + * 2. The cookie 'elggperm' - if present, checks it for an authentication + * token, validates it, and potentially logs the user in + * + * @uses $_SESSION + * + * @return bool + * @access private + */ +function _elgg_session_boot() { + global $DB_PREFIX, $CONFIG; + + // Use database for sessions + // HACK to allow access to prefix after object destruction + $DB_PREFIX = $CONFIG->dbprefix; + if ((!isset($CONFIG->use_file_sessions))) { + session_set_save_handler("_elgg_session_open", + "_elgg_session_close", + "_elgg_session_read", + "_elgg_session_write", + "_elgg_session_destroy", + "_elgg_session_gc"); + } + + session_name('Elgg'); + session_start(); + + // Generate a simple token (private from potentially public session id) + if (!isset($_SESSION['__elgg_session'])) { + $_SESSION['__elgg_session'] = md5(microtime() . rand()); + } + + // test whether we have a user session + if (empty($_SESSION['guid'])) { + + // clear session variables before checking cookie + unset($_SESSION['user']); + unset($_SESSION['id']); + unset($_SESSION['guid']); + unset($_SESSION['code']); + + // is there a remember me cookie + if (isset($_COOKIE['elggperm'])) { + // we have a cookie, so try to log the user in + $code = $_COOKIE['elggperm']; + $code = md5($code); + if ($user = get_user_by_code($code)) { + // we have a user, log him in + $_SESSION['user'] = $user; + $_SESSION['id'] = $user->getGUID(); + $_SESSION['guid'] = $_SESSION['id']; + $_SESSION['code'] = $_COOKIE['elggperm']; } - + } + } else { + // we have a session and we have already checked the fingerprint + // reload the user object from database in case it has changed during the session + if ($user = get_user($_SESSION['guid'])) { + $_SESSION['user'] = $user; + $_SESSION['id'] = $user->getGUID(); + $_SESSION['guid'] = $_SESSION['id']; + } else { + // user must have been deleted with a session active + unset($_SESSION['user']); + unset($_SESSION['id']); + unset($_SESSION['guid']); + unset($_SESSION['code']); + } + } + + if (isset($_SESSION['guid'])) { + set_last_action($_SESSION['guid']); + } + + elgg_register_action('login', '', 'public'); + elgg_register_action('logout'); + + // Register a default PAM handler + register_pam_handler('pam_auth_userpass'); + + // Initialise the magic session + global $SESSION; + $SESSION = new ElggSession(); + + // Finally we ensure that a user who has been banned with an open session is kicked. + if ((isset($_SESSION['user'])) && ($_SESSION['user']->isBanned())) { + session_destroy(); + return false; + } + + return true; +} + +/** + * Used at the top of a page to mark it as logged in users only. + * + * @return void + */ +function gatekeeper() { + if (!elgg_is_logged_in()) { + $_SESSION['last_forward_from'] = current_page_url(); + register_error(elgg_echo('loggedinrequired')); + forward('', 'login'); + } +} + +/** + * Used at the top of a page to mark it as logged in admin or siteadmin only. + * + * @return void + */ +function admin_gatekeeper() { + gatekeeper(); + + if (!elgg_is_admin_logged_in()) { + $_SESSION['last_forward_from'] = current_page_url(); + register_error(elgg_echo('adminrequired')); + forward('', 'admin'); + } +} + +/** + * Handles opening a session in the DB + * + * @param string $save_path The path to save the sessions + * @param string $session_name The name of the session + * + * @return true + * @todo Document + * @access private + */ +function _elgg_session_open($save_path, $session_name) { + global $sess_save_path; + $sess_save_path = $save_path; + + return true; +} + +/** + * Closes a session + * + * @todo implement + * @todo document + * + * @return true + * @access private + */ +function _elgg_session_close() { + return true; +} + +/** + * Read the session data from DB failing back to file. + * + * @param string $id The session ID + * + * @return string + * @access private + */ +function _elgg_session_read($id) { + global $DB_PREFIX; + + $id = sanitise_string($id); + + try { + $result = get_data_row("SELECT * from {$DB_PREFIX}users_sessions where session='$id'"); + + if ($result) { + return (string)$result->data; + } + + } catch (DatabaseException $e) { + + // Fall back to file store in this case, since this likely means + // that the database hasn't been upgraded + global $sess_save_path; + + $sess_file = "$sess_save_path/sess_$id"; + return (string) @file_get_contents($sess_file); + } + + return ''; +} + +/** + * Write session data to the DB falling back to file. + * + * @param string $id The session ID + * @param mixed $sess_data Session data + * + * @return bool + * @access private + */ +function _elgg_session_write($id, $sess_data) { + global $DB_PREFIX; + + $id = sanitise_string($id); + $time = time(); + + try { + $sess_data_sanitised = sanitise_string($sess_data); + + $q = "REPLACE INTO {$DB_PREFIX}users_sessions + (session, ts, data) VALUES + ('$id', '$time', '$sess_data_sanitised')"; + + if (insert_data($q) !== false) { return true; } -
- register_elgg_event_handler("boot","system","session_init",1);
-
-
-?>
\ No newline at end of file + } catch (DatabaseException $e) { + // Fall back to file store in this case, since this likely means + // that the database hasn't been upgraded + global $sess_save_path; + + $sess_file = "$sess_save_path/sess_$id"; + if ($fp = @fopen($sess_file, "w")) { + $return = fwrite($fp, $sess_data); + fclose($fp); + return $return; + } + } + + return false; +} + +/** + * Destroy a DB session, falling back to file. + * + * @param string $id Session ID + * + * @return bool + * @access private + */ +function _elgg_session_destroy($id) { + global $DB_PREFIX; + + $id = sanitise_string($id); + + try { + return (bool)delete_data("DELETE from {$DB_PREFIX}users_sessions where session='$id'"); + } catch (DatabaseException $e) { + // Fall back to file store in this case, since this likely means that + // the database hasn't been upgraded + global $sess_save_path; + + $sess_file = "$sess_save_path/sess_$id"; + return @unlink($sess_file); + } +} + +/** + * Perform garbage collection on session table / files + * + * @param int $maxlifetime Max age of a session + * + * @return bool + * @access private + */ +function _elgg_session_gc($maxlifetime) { + global $DB_PREFIX; + + $life = time() - $maxlifetime; + + try { + return (bool)delete_data("DELETE from {$DB_PREFIX}users_sessions where ts<'$life'"); + } catch (DatabaseException $e) { + // Fall back to file store in this case, since this likely means that the database + // hasn't been upgraded + global $sess_save_path; + + foreach (glob("$sess_save_path/sess_*") as $filename) { + if (filemtime($filename) < $life) { + @unlink($filename); + } + } + } + + return true; +} |
