]> git.mjollnir.org Git - moodle.git/commitdiff
NTLM SSO: MDL-14584 Fix for several outstanding NTLM SSO issues.
authoriarenaza <iarenaza>
Sat, 14 Feb 2009 16:21:14 +0000 (16:21 +0000)
committeriarenaza <iarenaza>
Sat, 14 Feb 2009 16:21:14 +0000 (16:21 +0000)
These include:

MDL-14078: redirect() doubles the specified timeout when we haven't printed
           the page header and uses javascript to execute the redirect. This
           is interacting badly with some versions of IE and FF (at least
           3.0.x Windows version) that fireup javascript timers even if
           we already left the page where we set those up. Just print
           the page header (we are printing other content anyway) to
           make redirect respect our timeouts.

MDL-14071: All the relevant details are in the description of the bug :)

MDL-14297: This is probably the same as MDL-14078

auth/ldap/auth.php
auth/ldap/ntlmsso_attempt.php
auth/ldap/ntlmsso_finish.php

index 3616ee4eed1e913a8533fda8c7bb6926778798cf..7376facd2acfb3925127c711a66337aeea66e0df 100644 (file)
@@ -1769,16 +1769,45 @@ class auth_plugin_ldap extends auth_plugin_base {
      *
      */
     function loginpage_hook() {
-        global $CFG;
+        global $CFG, $SESSION;
+        if (($_SERVER['REQUEST_METHOD'] === 'GET'         // Only on initial GET of loginpage
+                || ($_SERVER['REQUEST_METHOD'] === 'POST'
+                   && (get_referer() != strip_querystring(qualified_me()))))
+                                                           // Or when POSTed from another place
+                                                           // See MDL-14071
+           && !empty($this->config->ntlmsso_enabled)     // SSO enabled
+           && !empty($this->config->ntlmsso_subnet)      // have a subnet to test for
+           && empty($_GET['authldap_skipntlmsso'])       // haven't failed it yet
+           && (isguestuser() || !isloggedin())           // guestuser or not-logged-in users
+            && address_in_subnet($_SERVER['REMOTE_ADDR'], $this->config->ntlmsso_subnet)) {
+
+            // First, let's remember where we were trying to get to before we got here
+            if (empty($SESSION->wantsurl)) {
+                $SESSION->wantsurl = (array_key_exists('HTTP_REFERER', $_SERVER) &&
+                                      $_SERVER['HTTP_REFERER'] != $CFG->wwwroot &&
+                                      $_SERVER['HTTP_REFERER'] != $CFG->wwwroot.'/' &&
+                                      $_SERVER['HTTP_REFERER'] != $CFG->httpswwwroot.'/login/' &&
+                                      $_SERVER['HTTP_REFERER'] != $CFG->httpswwwroot.'/login/index.php')
+                    ? $_SERVER['HTTP_REFERER'] : NULL;
+            }
 
-        if ($_SERVER['REQUEST_METHOD'] === 'GET'    // Only on initial GET 
-                                                    // of loginpage
-            &&!empty($this->config->ntlmsso_enabled)// SSO enabled
-            && !empty($this->config->ntlmsso_subnet)// have a subnet to test for
-            && empty($_GET['authldap_skipntlmsso']) // haven't failed it yet
-            && (isguestuser() || !isloggedin())     // guestuser or not-logged-in users
-            && address_in_subnet($_SERVER['REMOTE_ADDR'],$this->config->ntlmsso_subnet)) {
-            redirect("{$CFG->wwwroot}/auth/ldap/ntlmsso_attempt.php");
+            // Now start the whole NTLM machinery.
+            redirect($CFG->wwwroot.'/auth/ldap/ntlmsso_attempt.php');
+        }
+        // No NTLM SSO, Use the normal login page instead.
+
+        // If $SESSION->wantsurl is empty and we have a 'Referer:' header, the login
+        // page insists on redirecting us to that page after user validation. If
+        // we clicked on the redirect link at the ntlmsso_finish.php page instead
+        // of waiting for the redirection to happen, then we have a 'Referer:' header
+        // we don't want to use at all. As we can't get rid of it, just point
+        // $SESSION->wantsurl to $CFG->wwwroot (after all, we came from there).
+        if (empty($SESSION->wantsurl)
+            && (get_referer() == $CFG->httpswwwroot.'/auth/ldap/ntlmsso_finish.php')) {
+
+            $SESSION->wantsurl = $CFG->wwwroot;
         }
     }
 
@@ -1801,7 +1830,14 @@ class auth_plugin_ldap extends auth_plugin_base {
      */
     function ntlmsso_magic($sesskey) {
         if (isset($_SERVER['REMOTE_USER']) && !empty($_SERVER['REMOTE_USER'])) {
-            $username = $_SERVER['REMOTE_USER'];
+
+            // HTTP __headers__ seem to be sent in ISO-8859-1 encoding
+            // (according to my reading of RFC-1945, RFC-2616 and RFC-2617 and
+            // my local tests), so we need to convert the REMOTE_USER value
+            // (i.e., what we got from the HTTP WWW-Authenticate header) into UTF-8
+            $textlib = textlib_get_instance();
+            $username = $textlib->convert($_SERVER['REMOTE_USER'], 'iso-8859-1', 'utf-8');
+
             $username = substr(strrchr($username, '\\'), 1); //strip domain info
             $username = moodle_strtolower($username); //compatibility hack
             set_cache_flag('auth/ldap/ntlmsess', $sesskey, $username, AUTH_NTLMTIMEOUT);
index 8f2325cf19c208d98ef49eb2de156c4ec7aad403..fac2bce0271fcb892322ba6f1be6a27943933247 100644 (file)
@@ -22,7 +22,15 @@ if (empty($authplugin->config->ntlmsso_enabled)) {
 
 $sesskey = sesskey();
 
-//print_header("$site->fullname: $loginsite", $site->fullname, $loginsite, $focus, '', true);
+// Display the page header. This makes redirect respect the timeout we specify
+// here (and not add 3 more secs) which in turn prevents a bug in both IE 6.x
+// and FF 3.x (Windows version at least) where javascript timers fire up even
+// when we've already left the page that set the timer.
+$loginsite = get_string("loginsite");
+$navlinks = array(array('name' => $loginsite, 'link' => null, 'type' => 'misc'));
+$navigation = build_navigation($navlinks);
+print_header("$site->fullname: $loginsite", $site->fullname, $navigation, '', '', true);
+
 $msg = '<p>'.get_string('ntlmsso_attempting','auth').'</p>'
     . '<img width="1", height="1" '
     . ' src="' . $CFG->wwwroot . '/auth/ldap/ntlmsso_magic.php?sesskey='
index 1fdc5f4322160128aa2df4b632394822e938400c..fe613cc33b748376f500d14ef6c0d6159d232f18 100644 (file)
@@ -24,7 +24,13 @@ if (empty($authplugin->config->ntlmsso_enabled)) {
 // so we only worry about failure.
 if (!$authplugin->ntlmsso_finish()) {
     // Redirect to login, saying "don't try again!"
-    redirect($CFG->wwwroot . '/login/index.php?authldap_skipntlmsso=1', 
+    // Display the page header. This makes redirect respect the timeout we specify
+    // here (and not add 3 more secs).
+    $loginsite = get_string("loginsite");
+    $navlinks = array(array('name' => $loginsite, 'link' => null, 'type' => 'misc'));
+    $navigation = build_navigation($navlinks);
+    print_header("$site->fullname: $loginsite", $site->fullname, $navigation, '', '', true);
+    redirect($CFG->httpswwwroot . '/login/index.php?authldap_skipntlmsso=1', 
              get_string('ntlmsso_failed','auth'), 3);
 }
 ?>