Add return parameter and relay state support to logout processing in lieu of templates.
[shibboleth/sp.git] / shibsp / ServiceProvider.cpp
index e0d257b..529d834 100644 (file)
@@ -402,19 +402,10 @@ pair<bool,long> ServiceProvider::doExport(SPRequest& request, bool requireSessio
         }
 
         // Export the attributes.
-        bool remoteUserSet = false;
         const multimap<string,const Attribute*>& attributes = session->getIndexedAttributes();
         for (multimap<string,const Attribute*>::const_iterator a = attributes.begin(); a!=attributes.end(); ++a) {
-            const vector<string>& vals = a->second->getSerializedValues();
-
-            // See if this needs to be set as the REMOTE_USER value.
-            if (!remoteUserSet && !vals.empty() && app->getRemoteUserAttributeIds().count(a->first)) {
-                request.setRemoteUser(vals.front().c_str());
-                remoteUserSet = true;
-            }
-
-            // Handle the normal export case.
             string header(request.getSecureHeader(a->first.c_str()));
+            const vector<string>& vals = a->second->getSerializedValues();
             for (vector<string>::const_iterator v = vals.begin(); v!=vals.end(); ++v) {
                 if (!header.empty())
                     header += ";";
@@ -434,6 +425,22 @@ pair<bool,long> ServiceProvider::doExport(SPRequest& request, bool requireSessio
             request.setHeader(a->first.c_str(), header.c_str());
         }
 
+        // Check for REMOTE_USER.
+        bool remoteUserSet = false;
+        const vector<string>& rmids = app->getRemoteUserAttributeIds();
+        for (vector<string>::const_iterator rmid = rmids.begin(); !remoteUserSet && rmid != rmids.end(); ++rmid) {
+            pair<multimap<string,const Attribute*>::const_iterator,multimap<string,const Attribute*>::const_iterator> matches =
+                attributes.equal_range(*rmid);
+            while (matches.first != matches.second) {
+                const vector<string>& vals = matches.first->second->getSerializedValues();
+                if (!vals.empty()) {
+                    request.setRemoteUser(vals.front().c_str());
+                    remoteUserSet = true;
+                    break;
+                }
+            }
+        }
+
         return make_pair(false,0L);
     }
     catch (exception& e) {
@@ -518,6 +525,7 @@ pair<bool,long> ServiceProvider::doHandler(SPRequest& request) const
     catch (exception& e) {
         TemplateParameters tp(&e);
         tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+        tp.m_request = &request;
         return make_pair(true,sendError(log, request, app, "session", tp));
     }
 }