From 2170351cbcce58fee367017fe4ade6b99ffd7958 Mon Sep 17 00:00:00 2001 From: Tim Schroeder Date: Wed, 4 Jul 2018 17:56:11 +0200 Subject: [PATCH] MDL-61351 shibboleth: Logout: fix session handler class not being used * use $CFG->session_handler_class to determine which type of session is used * if not set, use $CFG->dbsession instead --- auth/shibboleth/logout.php | 109 +++++++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 41 deletions(-) diff --git a/auth/shibboleth/logout.php b/auth/shibboleth/logout.php index 83f923451fe..ae57977e587 100644 --- a/auth/shibboleth/logout.php +++ b/auth/shibboleth/logout.php @@ -127,64 +127,90 @@ WSDL; * @return SoapFault or void if everything was fine */ function LogoutNotification($spsessionid) { - - global $CFG, $SESSION, $DB; + global $CFG; // Delete session of user using $spsessionid. - if(empty($CFG->dbsessions)) { + // The setting $CFG->session_handler_class may not be set. But if it is, + // it should override $CFG->dbsessions. + if (!empty($CFG->session_handler_class)) { + $sessionclass = $CFG->session_handler_class; + if (preg_match('/database/i', $sessionclass) === 1) { + return logoutdbsession($spsessionid); + } else if (preg_match('/file/i', $sessionclass) === 1) { + return logoutfilesession($spsessionid); + } else { + throw new moodle_exception("Shibboleth logout not implemented for '$sessionclass'"); + } + } else { + // Session handler class is not specified, check dbsessions instead. + if (!empty($CFG->dbsessions)) { + return logoutdbsession($spsessionid); + } + // Assume file sessions if dbsessions isn't used. + return logoutfilesession($spsessionid); + } + // If no SoapFault was thrown, the function will return OK as the SP assumes. +} - // File session - $dir = $CFG->dataroot .'/sessions'; - if (is_dir($dir)) { - if ($dh = opendir($dir)) { - // Read all session files - while (($file = readdir($dh)) !== false) { - // Check if it is a file - if (is_file($dir.'/'.$file)){ - $session_key = preg_replace('/sess_/', '', $file); +// Delete session of user using $spsessionid. +function logoutfilesession($spsessionid) { + global $CFG; - // Read session file data - $data = file($dir.'/'.$file); - if (isset($data[0])){ - $usersession = unserializesession($data[0]); + if (!empty($CFG->session_file_save_path)) { + $dir = $CFG->session_file_save_path; + } else { + $dir = $CFG->dataroot . '/sessions'; + } - // Check if we have found session that shall be deleted - if (isset($usersession['SESSION']) && isset($usersession['SESSION']->shibboleth_session_id)) { + if (is_dir($dir)) { + if ($dh = opendir($dir)) { + // Read all session files. + while (($file = readdir($dh)) !== false) { + // Check if it is a file. + if (is_file($dir.'/'.$file)) { - // If there is a match, delete file - if ($usersession['SESSION']->shibboleth_session_id == $spsessionid) { - // Delete session file - if (!unlink($dir.'/'.$file)){ - return new SoapFault('LogoutError', 'Could not delete Moodle session file.'); - } + // Read session file data. + $data = file($dir.'/'.$file); + if (isset($data[0])) { + $usersession = unserializesession($data[0]); + + // Check if we have found session that shall be deleted. + if (isset($usersession['SESSION']) && isset($usersession['SESSION']->shibboleth_session_id)) { + + // If there is a match, delete file. + if ($usersession['SESSION']->shibboleth_session_id == $spsessionid) { + // Delete session file. + if (!unlink($dir.'/'.$file)) { + return new SoapFault('LogoutError', 'Could not delete Moodle session file.'); } } } } } - closedir($dh); } + closedir($dh); } - } else { - // DB Sessions. - $sessions = $DB->get_records_sql( - 'SELECT userid, sessdata FROM {sessions} WHERE timemodified > ?', - array(time() - $CFG->sessiontimeout) - ); - foreach ($sessions as $session) { - // Get user session from DB. - if (session_decode(base64_decode($session->sessdata))) { - if (isset($_SESSION['SESSION']) && isset($_SESSION['SESSION']->shibboleth_session_id)) { - // If there is a match, kill the session. - if ($_SESSION['SESSION']->shibboleth_session_id == trim($spsessionid)) { - // Delete this user's sessions. - \core\session\manager::kill_user_sessions($session->userid); - } + } +} + +function logoutdbsession($spsessionid) { + global $CFG, $DB; + $sessions = $DB->get_records_sql( + 'SELECT userid, sessdata FROM {sessions} WHERE timemodified > ?', + array(time() - $CFG->sessiontimeout) + ); + foreach ($sessions as $session) { + // Get user session from DB. + if (session_decode(base64_decode($session->sessdata))) { + if (isset($_SESSION['SESSION']) && isset($_SESSION['SESSION']->shibboleth_session_id)) { + // If there is a match, kill the session. + if ($_SESSION['SESSION']->shibboleth_session_id == trim($spsessionid)) { + // Delete this user's sessions. + \core\session\manager::kill_user_sessions($session->userid); } } } } - // If no SoapFault was thrown, the function will return OK as the SP assumes. } /*****************************************************************************/ @@ -199,3 +225,4 @@ function unserializesession($serialized_string) { } return $variables; } +