diff --git a/modules/saml/lib/SP/LogoutStore.php b/modules/saml/lib/SP/LogoutStore.php index 5576dba7ff4ca442449287cc51815ae87dc9a680..ee47c2df3552a23f9180ca4bdaed2d9044b48ef5 100644 --- a/modules/saml/lib/SP/LogoutStore.php +++ b/modules/saml/lib/SP/LogoutStore.php @@ -194,7 +194,7 @@ class sspmod_saml_SP_LogoutStore { * @param string $authId The authsource ID. * @param array $nameId The NameID of the user. * @param array $sessionIndexes The SessionIndexes we should log out of. Logs out of all if this is empty. - * @returns bool TRUE if OK, FALSE if not supported. + * @returns int|FALSE Number of sessions logged out, or FALSE if not supported. */ public static function logoutSessions($authId, array $nameId, array $sessionIndexes) { assert('is_string($authId)'); @@ -235,6 +235,7 @@ class sspmod_saml_SP_LogoutStore { $sessionHandler = SimpleSAML_SessionHandler::getSessionHandler(); + $numLoggedOut = 0; foreach ($sessionIndexes as $sessionIndex) { if (!isset($sessions[$sessionIndex])) { SimpleSAML_Logger::info('saml.LogoutStore: Logout requested for unknown SessionIndex.'); @@ -256,9 +257,10 @@ class sspmod_saml_SP_LogoutStore { SimpleSAML_Logger::info('saml.LogoutStore: Logging out of session with trackId [' . $session->getTrackId() . '].'); $session->doLogout($authId); + $numLoggedOut += 1; } - return TRUE; + return $numLoggedOut; } } diff --git a/modules/saml/www/sp/saml2-logout.php b/modules/saml/www/sp/saml2-logout.php index 0df055c1845e4ea2cbce734af72c4f7e29235fd8..2d7d69c103b59734e754fe9588fb64b9497a0aa5 100644 --- a/modules/saml/www/sp/saml2-logout.php +++ b/modules/saml/www/sp/saml2-logout.php @@ -85,9 +85,11 @@ if ($message instanceof SAML2_LogoutResponse) { $nameId = $message->getNameId(); $sessionIndexes = $message->getSessionIndexes(); - if (!sspmod_saml_SP_LogoutStore::logoutSessions($sourceId, $nameId, $sessionIndexes)) { + $numLoggedOut = sspmod_saml_SP_LogoutStore::logoutSessions($sourceId, $nameId, $sessionIndexes); + if ($numLoggedOut === FALSE) { /* This type of logout was unsupported. Use the old method. */ $source->handleLogout($idpEntityId); + $numLoggedOut = count($sessionIndexes); } /* Create an send response. */ @@ -95,6 +97,15 @@ if ($message instanceof SAML2_LogoutResponse) { $lr->setRelayState($message->getRelayState()); $lr->setInResponseTo($message->getId()); + /* We should return a partial logout if we were unable to log out of all the given session(s). */ + if ($numLoggedOut < count($sessionIndexes)) { + $lr->setStatus(array( + 'Code' => SAML2_Const::STATUS_SUCCESS, + 'SubCode' => SAML2_Const::STATUS_PARTIAL_LOGOUT, + 'Message' => 'Logged out of ' . $numLoggedOut . ' of ' . count($sessionIndexes) . ' sessions.' + )); + } + $binding->send($lr); } else { throw new SimpleSAML_Error_BadRequest('Unknown message received on logout endpoint: ' . get_class($message));