diff --git a/auth/cas/CAS/CAS.php b/auth/cas/CAS/CAS.php
index f74730f..35cba62 100644
--- a/auth/cas/CAS/CAS.php
+++ b/auth/cas/CAS/CAS.php
@@ -6,8 +6,8 @@
 //
 // hack by Vangelis Haniotakis to handle the absence of $_SERVER['REQUEST_URI'] in IIS
 //
-if (!$_SERVER['REQUEST_URI']) {
-     $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING'];
+if (!isset($_SERVER['REQUEST_URI']) || empty($_SERVER['REQUEST_URI'])) {
+    @$_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING'];
 }
 
 //
@@ -431,7 +431,8 @@ class phpCAS
       global $PHPCAS_DEBUG;
 
       if ( $PHPCAS_DEBUG['filename'] ) {
-	for ($i=0;$i<$PHPCAS_DEBUG['indent'];$i++) {
+            @$limit = intval($PHPCAS_DEBUG['indent']);
+            for ($i=0;$i<$limit;$i++) {
 	  $indent_str .= '|    ';
 	}
 	error_log($PHPCAS_DEBUG['unique_id'].' '.$indent_str.$str."\n",3,$PHPCAS_DEBUG['filename']);
@@ -502,7 +503,7 @@ class phpCAS
       }
       $str .= ') ['.basename($dbg[2]['file']).':'.$dbg[2]['line'].']';
       phpCAS::log($str);
-      $PHPCAS_DEBUG['indent'] ++;
+        @$PHPCAS_DEBUG['indent'] ++;
     }
 
   /**
diff --git a/auth/cas/CAS/client.php b/auth/cas/CAS/client.php
index a793e12..be24ce9 100644
--- a/auth/cas/CAS/client.php
+++ b/auth/cas/CAS/client.php
@@ -512,7 +512,7 @@ class CASClient
     //check port
     if ( $server_port == 0 
         || !is_int($server_port) ) {
-      phpCAS::error('bad CAS server port (`'.$server_hostname.'\')');
+      phpCAS::error('bad CAS server port (`'.$server_port.'\')');
     }
     $this->_server['port'] = $server_port;
 
@@ -873,7 +873,7 @@ class CASClient
       // v0.4.14 sebastien.gougeon at univ-rennes1.fr
       // header('Location: '.$cas_url);
       if ( $url != "" ) {
-        $url = '?service=' . $url;
+        $url = '?service=' . $url . '&url=' . $url;
       }
       header('Location: '.$cas_url . $url);
       session_unset();
diff --git a/auth/cas/auth.php b/auth/cas/auth.php
index ff01fa9..03ff74c 100644
--- a/auth/cas/auth.php
+++ b/auth/cas/auth.php
@@ -1,52 +1,53 @@
 <?php
 /**
+ * @author Luke Hudson
  * @author Martin Dougiamas
- * @authro Jerome GUTIERREZ
+ * @author Jerome GUTIERREZ
  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
  * @package moodle multiauth
- *
+
  * Authentication Plugin: CAS Authentication
- *
+
  * Authentication using CAS (Central Authentication Server).
- *
+
+ * 2007-11-30  Rewritten, removing LDAP-specific code, and using aggregation to support other auth methods instead 
+ *              of being hardcoded to LDAP
  * 2006-08-28  File created.
  */
+
 if (!defined('MOODLE_INTERNAL')) {
     die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
 }
+
 require_once($CFG->libdir.'/authlib.php');
 require_once($CFG->dirroot.'/auth/cas/CAS/CAS.php');
+
+
 /**
  * CAS authentication plugin.
  */
 class auth_plugin_cas extends auth_plugin_base {
-    /**
-     * Constructor.
+
+    var $authtype = 'cas';
+
+    var $config;
+
+    var $subauth;  // Aggregated auth plugin -- one of the other active Moodle auth plugin instances.
+    
+
+    /** 
+     * Constructor
      */
     function auth_plugin_cas() {
         $this->authtype = 'cas';
-        $this->config = get_config('auth/cas');
-        if (empty($this->config->ldapencoding)) {
-            $this->config->ldapencoding = 'utf-8';
-        }
-        if (empty($this->config->user_type)) {
-            $this->config->user_type = 'default';
-        }
-        $default = $this->ldap_getdefaults();
-        //use defaults if values not given
-        foreach ($default as $key => $value) {
-            // watch out - 0, false are correct values too
-            if (!isset($this->config->{$key}) or $this->config->{$key} == '') {
-                $this->config->{$key} = $value[$this->config->user_type];
-            }
-        }
-        //hack prefix to objectclass
-        if (empty($this->config->objectclass)) {        // Can't send empty filter
-            $this->config->objectclass='objectClass=*';
-        } else if (strpos($this->config->objectclass, 'objectClass=') !== 0) {
-            $this->config->objectclass = 'objectClass='.$this->config->objectclass;
+        $this->config   = get_config('auth/cas');
+        if (empty($this->config->subauth)) {
+            $this->config->subauth = 'db';
         }
+        $this->subauth = get_auth_plugin($this->config->subauth);
     }
+
+
     /**
      * Authenticates user againt CAS
      * Returns true if the username and password work and false if they are
@@ -57,108 +58,12 @@ class auth_plugin_cas extends auth_plugin_base {
      * @return bool Authentication success or failure.
      */
     function user_login ($username, $password) {
-		$this->connectCAS();	
+        $this->connectCAS();	
+        phpCAS::forceAuthentication();
         return phpCAS::isAuthenticated();
     }
-    /**
-     * Returns true if this authentication plugin is 'internal'.
-     *
-     * @return bool
-     */
-    function is_internal() {
-        return false;
-    }
-    /**
-     * Returns true if this authentication plugin can change the user's
-     * password.
-     *
-     * @return bool
-     */
-    function can_change_password() {
-        return false;
-    }
-    /**
-     * authentication choice (CAS or other)
-     * redirection to the CAS form or to login/index.php
-     * for other authentication
-     */
-    function loginpage_hook() {
-      global $frm;
-      global $CFG;
-	  global $SESSION;
-
-      $site = get_site();
-      $CASform = get_string("CASform","auth");
-      $username = optional_param("username");
-
-      if (!empty($username)) {
-		  if (strstr($SESSION->wantsurl,'ticket') || strstr($SESSION->wantsurl,'NOCAS'))
-			  unset($SESSION->wantsurl);
-          return;		
-        }
-
-
-		
-		// Test si cas activ� et param�tres non remplis
-	  if (empty($this->config->hostname)) {
-		  return;
-		  }
-
-// Connection to CAS server
-	 $this->connectCAS();
 
-	  // Gestion de la connection CAS si acc�s direct d'un ent ou autre	
-	 if (phpCAS::checkAuthentication()) {
-		$frm->username=phpCAS::getUser();
-//		if (phpCAS::getUser()=='esup9992')
-//			$frm->username='erhar0062';
-		$frm->password="passwdCas";		
-		return;
-	 }	 	
-
-	  if ($_GET["loginguest"]== true) {
-			$frm->username="guest";
-			$frm->password="guest";
-			return;
-	  }		
-	 
-     if ($this->config->multiauth) {
-          $authCAS = optional_param("authCAS");
-          if ($authCAS=="NOCAS")
-            return;
-
-// choice authentication form for multi-authentication
-// test pgtIou parameter for proxy mode (https connection
-// in background from CAS server to the php server)
-      if ($authCAS!="CAS" && !isset($_GET["pgtIou"])) {
-            $navlinks = array();
-            $navlinks[] = array('name' => $CASform, 'link' => null, 'type' => 'misc');
-            $navigation = build_navigation($navlinks);
 
-            print_header("$site->fullname: $CASform", $site->fullname, $navigation);
-            include($CFG->dirroot."/auth/cas/cas_form.html");
-            print_footer();
-            exit();
-		 }
-     }
-// CAS authentication
-     if (!phpCAS::isAuthenticated())
-        {phpCAS::forceAuthentication();}
-}
-    /**
-     * logout from the cas
-     *
-     * This function is called from admin/auth.php
-     *
-     */
-    function prelogout_hook() {
-        global $CFG;
-	  if ($this->config->logoutcas ) {
-	        $backurl = $CFG->wwwroot;
-		  $this->connectCAS();
-	        phpCAS::logout($backurl);
-	     }
-    }
     /**
      * Connect to the cas (clientcas connection or proxycas connection
      *
@@ -166,20 +71,24 @@ class auth_plugin_cas extends auth_plugin_base {
      *
      */
     function connectCAS() {
-	
-	global $PHPCAS_CLIENT;
-// mode proxy CAS
-if ( !is_object($PHPCAS_CLIENT) ) {
-	if  ($this->config->proxycas) {
-	    phpCAS::proxy($this->config->casversion, $this-> config->hostname, (int) $this->config->port, $this->config->baseuri);
-	}
-// mode client CAS
-	else {
-	    phpCAS::client($this->config->casversion, $this-> config->hostname, (int) $this->config->port, $this->config->baseuri);
-	}
+        global $PHPCAS_CLIENT;
+        
+
+        phpCAS::setDebug(false);
+        if ( is_object($PHPCAS_CLIENT) ) {
+            return;
+        }
+
+        if  ($this->config->proxycas) { // mode proxy CAS
+            phpCAS::proxy($this->config->casversion, $this->config->hostname,
+                (int) $this->config->port, $this->config->baseuri, false);
+        } else {  // mode client CAS
+            phpCAS::client($this->config->casversion, $this->config->hostname,
+                intval($this->config->port), $this->config->baseuri, false);
+        }
     }
-	
-	}
+
+
     /**
      * Prints a form for configuring this authentication plugin.
      *
@@ -191,927 +100,239 @@ if ( !is_object($PHPCAS_CLIENT) ) {
     function config_form($config, $err, $user_fields) {
         include 'config.html';
     }
-    /**
-     * Returns the URL for changing the user's pw, or empty if the default can
-     * be used.
-     *
-     * @return string
-     */
-    function change_password_url() {
-        return "";
-    }
-    /**
-     * returns predefined usertypes
-     *
-     * @return array of predefined usertypes
-     */
-    function ldap_suppported_usertypes() {
-        $types = array();
-        $types['edir']='Novell Edirectory';
-        $types['rfc2307']='posixAccount (rfc2307)';
-        $types['rfc2307bis']='posixAccount (rfc2307bis)';
-        $types['samba']='sambaSamAccount (v.3.0.7)';
-        $types['ad']='MS ActiveDirectory';
-        $types['default']=get_string('default');
-        return $types;
-    }
+
+
     /**
      * Processes and stores configuration data for this authentication plugin.
      */
     function process_config($config) {
-        // set to defaults if undefined
-        // CAS settings
-        if (!isset ($config->hostname))
-            $config->hostname = '';
-        if (!isset ($config->port))
-            $config->port = '';
-        if (!isset ($config->casversion))
-            $config->casversion = '';
-        if (!isset ($config->baseuri))
-            $config->baseuri = '';
-        if (!isset ($config->language))
-            $config->language = '';
-        if (!isset ($config->proxycas))
-            $config->proxycas = '';
-        if (!isset ($config->logoutcas))
-            $config->logoutcas = '';
-        if (!isset ($config->multiauth))
-            $config->multiauth = '';
-        // LDAP settings
-        if (!isset($config->host_url))
-            { $config->host_url = ''; }
-        if (empty($config->ldapencoding))
-            { $config->ldapencoding = 'utf-8'; }
-        if (!isset($config->contexts))
-            { $config->contexts = ''; }
-        if (!isset($config->user_type))
-            { $config->user_type = 'default'; }
-        if (!isset($config->user_attribute))
-            { $config->user_attribute = ''; }
-        if (!isset($config->search_sub))
-            { $config->search_sub = ''; }
-        if (!isset($config->opt_deref))
-            { $config->opt_deref = ''; }
-        if (!isset($config->bind_dn))
-            {$config->bind_dn = ''; }
-        if (!isset($config->bind_pw))
-            {$config->bind_pw = ''; }
-        if (!isset($config->version))
-            {$config->version = '2'; }
-        if (!isset($config->objectclass))
-            {$config->objectclass = ''; }
-        if (!isset($config->memberattribute))
-            {$config->memberattribute = ''; }
-        if (!isset($config->memberattribute_isdn))
-            {$config->memberattribute_isdn = ''; }
-        if (!isset($config->attrcreators))
-            {$config->attrcreators = ''; }
-        if (!isset($config->groupecreators))
-            {$config->groupecreators = ''; }
-        if (!isset($config->removeuser))
-            {$config->removeuser = 0; }
-        // save CAS settings
-        set_config('hostname',    $config->hostname,    'auth/cas');
-        set_config('port',        $config->port,        'auth/cas');
-        set_config('casversion',     $config->casversion,     'auth/cas');
-        set_config('baseuri',     $config->baseuri,     'auth/cas');
-        set_config('language',    $config->language,    'auth/cas');
-        set_config('proxycas',     $config->proxycas,     'auth/cas');
-        set_config('logoutcas',     $config->logoutcas,     'auth/cas');
-        set_config('multiauth',     $config->multiauth,     'auth/cas');
-        // save LDAP settings
-        set_config('host_url', $config->host_url, 'auth/cas');
-        set_config('ldapencoding', $config->ldapencoding, 'auth/cas');
-        set_config('host_url', $config->host_url, 'auth/cas');
-        set_config('contexts', $config->contexts, 'auth/cas');
-        set_config('user_type', $config->user_type, 'auth/cas');
-        set_config('user_attribute', $config->user_attribute, 'auth/cas');
-        set_config('search_sub', $config->search_sub, 'auth/cas');
-        set_config('opt_deref', $config->opt_deref, 'auth/cas');
-        set_config('bind_dn', $config->bind_dn, 'auth/cas');
-        set_config('bind_pw', $config->bind_pw, 'auth/cas');
-        set_config('version', $config->version, 'auth/cas');
-        set_config('objectclass', $config->objectclass, 'auth/cas');
-        set_config('memberattribute', $config->memberattribute, 'auth/cas');
-        set_config('memberattribute_isdn', $config->memberattribute_isdn, 'auth/cas');
-        set_config('attrcreators', $config->attrcreators, 'auth/cas');
-        set_config('groupecreators', $config->groupecreators, 'auth/cas');
-        set_config('removeuser', $config->removeuser, 'auth/cas');
+        cas_config_set_defaults($config);
+        foreach ($config as $key => $value) {
+            set_config($key, $value, 'auth/cas');
+        }
         return true;
     }
-    /**
-     * Initializes needed ldap variables for cas-module
-     *
-     * Uses names defined in ldap_supported_usertypes.
-     * $default is first defined as:
-     * $default['pseudoname'] = array(
-     *                      'typename1' => 'value',
-     *                      'typename2' => 'value'
-     *                      ....
-     *                      );
-     *
-     * @return array of default values
-     */
-    function ldap_getdefaults() {
-        $default['objectclass'] = array(
-                            'edir' => 'User',
-                            'rfc2307' => 'posixAccount',
-                            'rfc2307bis' => 'posixAccount',
-                            'samba' => 'sambaSamAccount',
-                            'ad' => 'user',
-                            'default' => '*'
-                            );
-        $default['user_attribute'] = array(
-                            'edir' => 'cn',
-                            'rfc2307' => 'uid',
-                            'rfc2307bis' => 'uid',
-                            'samba' => 'uid',
-                            'ad' => 'cn',
-                            'default' => 'cn'
-                            );
-        $default['memberattribute'] = array(
-                            'edir' => 'member',
-                            'rfc2307' => 'member',
-                            'rfc2307bis' => 'member',
-                            'samba' => 'member',
-                            'ad' => 'member',
-                            'default' => 'member'
-                            );
-        $default['memberattribute_isdn'] = array(
-                            'edir' => '1',
-                            'rfc2307' => '0',
-                            'rfc2307bis' => '1',
-                            'samba' => '0', //is this right?
-                            'ad' => '1',
-                            'default' => '0'
-                            );
-        return $default;
-    }
-    /**
-     * reads userinformation from ldap and return it in array()
-     *
-     * Read user information from external database and returns it as array().
-     * Function should return all information available. If you are saving
-     * this information to moodle user-table you should honor syncronization flags
-     *
-     * @param string $username username (with system magic quotes)
-     *
-     * @return mixed array with no magic quotes or false on error
-     */
-    function get_userinfo($username) {
-        $textlib = textlib_get_instance();
-        $extusername = $textlib->convert(stripslashes($username), 'utf-8', $this->config->ldapencoding);
-        $ldapconnection = $this->ldap_connect();
-        $attrmap = $this->ldap_attributes();
-        $result = array();
-        $search_attribs = array();
-        foreach ($attrmap as $key=>$values) {
-            if (!is_array($values)) {
-                $values = array($values);
-            }
-            foreach ($values as $value) {
-                if (!in_array($value, $search_attribs)) {
-                    array_push($search_attribs, $value);
-                }
-            }
-        }
-        $user_dn = $this->ldap_find_userdn($ldapconnection, $extusername);
-        if (!$user_info_result = ldap_read($ldapconnection, $user_dn, $this->config->objectclass, $search_attribs)) {
-            return false; // error!
-        }
-        $user_entry = $this->ldap_get_entries($ldapconnection, $user_info_result);
-        if (empty($user_entry)) {
-            return false; // entry not found
-        }
-        foreach ($attrmap as $key=>$values) {
-            if (!is_array($values)) {
-                $values = array($values);
-            }
-            $ldapval = NULL;
-           foreach ($values as $value) {
-                if ($value == 'dn') {
-                    $result[$key] = $user_dn;
-                }
-                if (!array_key_exists(strtolower($value), $user_entry[0])) {
-                    continue; // wrong data mapping!
-                }
-                if (is_array($user_entry[0][strtolower($value)])) {
-                    $newval = $textlib->convert($user_entry[0][strtolower($value)][0], $this->config->ldapencoding, 'utf-8');
-                } else {
-                    $newval = $textlib->convert($user_entry[0][strtolower($value)], $this->config->ldapencoding, 'utf-8');
-                }
 
-                if (!empty($newval)) { // favour ldap entries that are set
-                    $ldapval = $newval;
-                }
-            }
-            if (!is_null($ldapval)) {
-                $result[$key] = $ldapval;
-            }
-        }
-        @ldap_close($ldapconnection);
-        return $result;
-    }
+
     /**
-     * reads userinformation from ldap and return it in an object
-     *
-     * @param string $username username (with system magic quotes)
-     * @return mixed object or false on error
+     * A chance to validate form data, and last chance to
+     * do stuff before it is inserted in config_plugin
      */
-    function get_userinfo_asobj($username) {
-        $user_array = $this->get_userinfo($username);
-        if ($user_array == false) {
-            return false; //error or not found
-        }
-        $user_array = truncate_userinfo($user_array);
-        $user = new object();
-        foreach ($user_array as $key=>$value) {
-            $user->{$key} = $value;
-        }
-        return $user;
-    }
-    /**
-     * connects to ldap server
-     *
-     * Tries connect to specified ldap servers.
-     * Returns connection result or error.
-     *
-     * @return connection result
-     */
-    function ldap_connect($binddn='',$bindpwd='') {
-        //Select bind password, With empty values use
-        //ldap_bind_* variables or anonymous bind if ldap_bind_* are empty
-        if ($binddn == '' and $bindpwd == '') {
-            if (!empty($this->config->bind_dn)) {
-               $binddn = $this->config->bind_dn;
-            }
-            if (!empty($this->config->bind_pw)) {
-               $bindpwd = $this->config->bind_pw;
-            }
-        }
-        $urls = explode(";",$this->config->host_url);
-        foreach ($urls as $server) {
-            $server = trim($server);
-            if (empty($server)) {
-                continue;
-            }
-            $connresult = ldap_connect($server);
-            //ldap_connect returns ALWAYS true
-            if (!empty($this->config->version)) {
-                ldap_set_option($connresult, LDAP_OPT_PROTOCOL_VERSION, $this->config->version);
-            }
-            if (!empty($binddn)) {
-                //bind with search-user
-                //$debuginfo .= 'Using bind user'.$binddn.'and password:'.$bindpwd;
-                $bindresult=ldap_bind($connresult, $binddn,$bindpwd);
-            }
-            else {
-                //bind anonymously
-                $bindresult=@ldap_bind($connresult);
-            }
-            if (!empty($this->config->opt_deref)) {
-                ldap_set_option($connresult, LDAP_OPT_DEREF, $this->config->opt_deref);
-            }
-            if ($bindresult) {
-                return $connresult;
-            }
-            $debuginfo .= "<br/>Server: '$server' <br/> Connection: '$connresult'<br/> Bind result: '$bindresult'</br>";
+    function validate_form(&$form, &$err) {
+        if (empty($form->port)) {
+            $err['port'] = 'Must not be empty -- try 443 as the port for https';
         }
-        //If any of servers are alive we have already returned connection
-        print_error('auth_ldap_noconnect_all','auth',$this->config->user_type);
-        return false;
-    }
-    /**
-     * retuns user attribute mappings between moodle and ldap
-     *
-     * @return array
-     */
-    function ldap_attributes () {
-        $fields = array("firstname", "lastname", "email", "phone1", "phone2",
-                        "department", "address", "city", "country", "description",
-                        "idnumber", "lang" );
-        $moodleattributes = array();
-        foreach ($fields as $field) {
-            if (!empty($this->config->{"field_map_$field"})) {
-                $moodleattributes[$field] = $this->config->{"field_map_$field"};
-                if (preg_match('/,/',$moodleattributes[$field])) {
-                    $moodleattributes[$field] = explode(',', $moodleattributes[$field]); // split ?
-                }
-            }
+        if (empty($form->casversion) || !is_numeric($form->casversion)) {
+            $err['casversion'] = 'Must be entered, and numeric; try 2.0 as a default';
         }
-        $moodleattributes['username'] = $this->config->user_attribute;
-        return $moodleattributes;
-    }
-    /**
-     * retuns dn of username
-     *
-     * Search specified contexts for username and return user dn
-     * like: cn=username,ou=suborg,o=org
-     *
-     * @param mixed $ldapconnection  $ldapconnection result
-     * @param mixed $username username (external encoding no slashes)
-     *
-     */
-    function ldap_find_userdn ($ldapconnection, $extusername) {
-        //default return value
-        $ldap_user_dn = FALSE;
-        //get all contexts and look for first matching user
-        $ldap_contexts = explode(";",$this->config->contexts);
-        if (!empty($this->config->create_context)) {
-          array_push($ldap_contexts, $this->config->create_context);
-        }
-        foreach ($ldap_contexts as $context) {
-            $context = trim($context);
-            if (empty($context)) {
-                continue;
-            }
-            if ($this->config->search_sub) {
-                //use ldap_search to find first user from subtree
-                $ldap_result = ldap_search($ldapconnection, $context, "(".$this->config->user_attribute."=".$this->filter_addslashes($extusername).")",array($this->config->user_attribute));
-            }
-            else {
-                //search only in this context
-                $ldap_result = ldap_list($ldapconnection, $context, "(".$this->config->user_attribute."=".$this->filter_addslashes($extusername).")",array($this->config->user_attribute));
-            }
-            $entry = ldap_first_entry($ldapconnection,$ldap_result);
-            if ($entry) {
-                $ldap_user_dn = ldap_get_dn($ldapconnection, $entry);
-                break ;
-            }
-        }
-        return $ldap_user_dn;
-    }
-    /**
-     * Quote control characters in quoted "texts" used in ldap
-     *
-     * @param string
-     */
-    function ldap_addslashes($text) {
-        $text = str_replace('\\', '\\\\', $text);
-        $text = str_replace(array('"',   "\0"),
-                            array('\\"', '\\00'), $text);
-        return $text;
     }
+
+
     /**
-     * returns all usernames from external database
+     * Aggregate-handled methods:
      *
-     * get_userlist returns all usernames from external database
+     * The following functions are all handled by the aggregated auth plugin.
      *
-     * @return array
      */
-    function get_userlist() {
-        return $this->ldap_get_userlist("({$this->config->user_attribute}=*)");
+    function can_confirm() { return $this->subauth->can_confirm(); }
+    function can_reset_password() { return $this->subauth->can_reset_password(); }
+    function change_password_url() { return $this->subauth->change_password_url(); }
+    function password_expire($username) { return $this->subauth->password_expire($username); }
+    function get_userinfo($username) { return $this->subauth->get_userinfo($username); }
+    function is_internal() { return $this->subauth->is_internal(); }
+
+    function user_confirm($username, $confirmsecret) { return $this->subauth->user_confirm($user, $confirmsecret); }
+    function user_delete($olduser) { return $this->subauth->user_delete($olduser); }
+    function user_exists($username) { return $this->subauth->user_exists($username); }
+    function user_update($olduser, $newuser) { return $this->subauth->user_update($olduser, $newuser); }
+    function user_update_password($user, $newpassword) { return $this->subauth->user_update_password($user, $newpassword); }
+
+    #function can_signup() { return $this->subauth->can_signup(); }
+    #function user_signup($user, $notify=true) { return $this->subauth->user_signup($user, $notify); }
+
+
+    function sync_roles($user) {
+        return $this->subauth->sync_roles($user);
     }
-    /**
-     * checks if user exists on external db
-     *
-     * @param string $username (with system magic quotes)
-     */
-    function user_exists($username) {
-        $textlib = textlib_get_instance();
-        $extusername = $textlib->convert(stripslashes($username), 'utf-8', $this->config->ldapencoding);
-        //returns true if given username exist on ldap
-        $users = $this->ldap_get_userlist("({$this->config->user_attribute}=".$this->filter_addslashes($extusername).")");
-        return count($users);
+
+
+    function user_authenticated_hook(&$user, $username, $password) { 
+        return $this->subauth->user_authenticated_hook($user, $username, $password); 
     }
+
+    /* End of aggregate-handled methods */
+
+
+
     /**
-     * syncronizes user fron external db to moodle user table
-     *
-     * Sync is now using username attribute.
+     * Called from the Moodle login page, this hooks the login procedure to 
+     * perform the following:
      *
-     * Syncing users removes or suspends users that dont exists anymore in external db.
-     * Creates new users and updates coursecreator status of users.
+     * Authentication choice (CAS or other)
      *
-     * @param int $bulk_insert_records will insert $bulkinsert_records per insert statement
-     *                         valid only with $unsafe. increase to a couple thousand for
-     *                         blinding fast inserts -- but test it: you may hit mysqld's
-     *                         max_allowed_packet limit.
-     * @param bool $do_updates will do pull in data updates from ldap if relevant
+     * Redirection to the CAS form or to login/index.php for other 
+     * authentication
      */
-    function sync_users ($bulk_insert_records = 1000, $do_updates = true) {
+    function loginpage_hook() {
+        global $frm;
         global $CFG;
-        $textlib = textlib_get_instance();
-        $droptablesql = array(); /// sql commands to drop the table (because session scope could be a problem for
-                                 /// some persistent drivers like ODBTP (mssql) or if this function is invoked
-                                 /// from within a PHP application using persistent connections
-        // configure a temp table
-        print "Configuring temp table\n";
-        switch (strtolower($CFG->dbfamily)) {
-            case 'mysql':
-                $temptable = $CFG->prefix . 'extuser';
-                $droptablesql[] = 'DROP TEMPORARY TABLE ' . $temptable; // sql command to drop the table (because session scope could be a problem)
-                execute_sql_arr($droptablesql, true, false); /// Drop temp table to avoid persistence problems later
-                echo "Creating temp table $temptable\n";
-                execute_sql('CREATE TEMPORARY TABLE ' . $temptable . ' (username VARCHAR(64), PRIMARY KEY (username)) TYPE=MyISAM', false);
-                break;
-            case 'postgres':
-                $temptable = $CFG->prefix . 'extuser';
-                $droptablesql[] = 'DROP TABLE ' . $temptable; // sql command to drop the table (because session scope could be a problem)
-                execute_sql_arr($droptablesql, true, false); /// Drop temp table to avoid persistence problems later
-                echo "Creating temp table $temptable\n";
-                $bulk_insert_records = 1; // no support for multiple sets of values
-                execute_sql('CREATE TEMPORARY TABLE '. $temptable . ' (username VARCHAR(64), PRIMARY KEY (username))', false);
-                break;
-            case 'mssql':
-                $temptable = '#'.$CFG->prefix . 'extuser'; /// MSSQL temp tables begin with #
-                $droptablesql[] = 'DROP TABLE ' . $temptable; // sql command to drop the table (because session scope could be a problem)
-                execute_sql_arr($droptablesql, true, false); /// Drop temp table to avoid persistence problems later
-                echo "Creating temp table $temptable\n";
-                $bulk_insert_records = 1; // no support for multiple sets of values
-                execute_sql('CREATE TABLE ' . $temptable . ' (username VARCHAR(64), PRIMARY KEY (username))', false);
-                break;
-            case 'oracle':
-                $temptable = $CFG->prefix . 'extuser';
-                $droptablesql[] = 'TRUNCATE TABLE ' . $temptable; // oracle requires truncate before being able to drop a temp table
-                $droptablesql[] = 'DROP TABLE ' . $temptable; // sql command to drop the table (because session scope could be a problem)
-                execute_sql_arr($droptablesql, true, false); /// Drop temp table to avoid persistence problems later
-                echo "Creating temp table $temptable\n";
-                $bulk_insert_records = 1; // no support for multiple sets of values
-                execute_sql('CREATE GLOBAL TEMPORARY TABLE '.$temptable.' (username VARCHAR(64), PRIMARY KEY (username)) ON COMMIT PRESERVE ROWS', false);
-                break;
-        }
-        print "Connecting to ldap...\n";
-        $ldapconnection = $this->ldap_connect();
-        if (!$ldapconnection) {
-            @ldap_close($ldapconnection);
-            print get_string('auth_ldap_noconnect','auth',$this->config->host_url);
-            exit;
-        }
-        ////
-        //// get user's list from ldap to sql in a scalable fashion
-        ////
-        // prepare some data we'll need
-        $filter = "(&(".$this->config->user_attribute."=*)(".$this->config->objectclass."))";
-        $contexts = explode(";",$this->config->contexts);
-        if (!empty($this->config->create_context)) {
-              array_push($contexts, $this->config->create_context);
-        }
-        $fresult = array();
-        foreach ($contexts as $context) {
-            $context = trim($context);
-            if (empty($context)) {
-                continue;
-            }
-            begin_sql();
-            if ($this->config->search_sub) {
-                //use ldap_search to find first user from subtree
-                $ldap_result = ldap_search($ldapconnection, $context,
-                                           $filter,
-                                           array($this->config->user_attribute));
-            } else {
-                //search only in this context
-                $ldap_result = ldap_list($ldapconnection, $context,
-                                         $filter,
-                                         array($this->config->user_attribute));
-            }
-            if ($entry = ldap_first_entry($ldapconnection, $ldap_result)) {
-                do {
-                    $value = ldap_get_values_len($ldapconnection, $entry, $this->config->user_attribute);
-                    $value = $textlib->convert($value[0], $this->config->ldapencoding, 'utf-8');
-                    array_push($fresult, $value);
-                    if (count($fresult) >= $bulk_insert_records) {
-                        $this->ldap_bulk_insert($fresult, $temptable);
-                        $fresult = array();
-                    }
-                } while ($entry = ldap_next_entry($ldapconnection, $entry));
-            }
-            unset($ldap_result); // free mem
-            // insert any remaining users and release mem
-            if (count($fresult)) {
-                $this->ldap_bulk_insert($fresult, $temptable);
-                $fresult = array();
-            }
-            commit_sql();
-        }
-        /// preserve our user database
-        /// if the temp table is empty, it probably means that something went wrong, exit
-        /// so as to avoid mass deletion of users; which is hard to undo
-        $count = get_record_sql('SELECT COUNT(username) AS count, 1 FROM ' . $temptable);
-        $count = $count->{'count'};
-        if ($count < 1) {
-            print "Did not get any users from LDAP -- error? -- exiting\n";
-            exit;
-        } else {
-            print "Got $count records from LDAP\n\n";
-        }
-/// User removal
-        // find users in DB that aren't in ldap -- to be removed!
-        // this is still not as scalable (but how often do we mass delete?)
-        if (!empty($this->config->removeuser)) {
-            $sql = "SELECT u.id, u.username, u.email
-                    FROM {$CFG->prefix}user u
-                        LEFT JOIN $temptable e ON u.username = e.username
-                    WHERE u.auth='cas'
-                        AND u.deleted=0
-                        AND e.username IS NULL";
-            $remove_users = get_records_sql($sql);
-            if (!empty($remove_users)) {
-                print "User entries to remove: ". count($remove_users) . "\n";
-                foreach ($remove_users as $user) {
-                    if ($this->config->removeuser == 2) {
-                        if (delete_user($user)) {
-                            echo "\t"; print_string('auth_dbdeleteuser', 'auth', array($user->username, $user->id)); echo "\n";
-                        } else {
-                            echo "\t"; print_string('auth_dbdeleteusererror', 'auth', $user->username); echo "\n";
-                        }
-                    } else if ($this->config->removeuser == 1) {
-                        $updateuser = new object();
-                        $updateuser->id = $user->id;
-                        $updateuser->auth = 'nologin';
-                        if (update_record('user', $updateuser)) {
-                            echo "\t"; print_string('auth_dbsuspenduser', 'auth', array($user->username, $user->id)); echo "\n";
-                        } else {
-                            echo "\t"; print_string('auth_dbsuspendusererror', 'auth', $user->username); echo "\n";
-                        }
-                    }
-                }
-            } else {
-                print "No user entries to be removed\n";
-            }
-            unset($remove_users); // free mem!
+        global $SESSION;
+
+        // CAS is enabled, but not properly set up.
+        if (empty($this->config->hostname)) {
+            #error_log("CAS is enabled, but not properly configured (empty hostname)");
+            return;
         }
-/// Revive suspended users
-        if (!empty($this->config->removeuser) and $this->config->removeuser == 1) {
-            $sql = "SELECT u.id, u.username
-                    FROM $temptable e, {$CFG->prefix}user u
-                    WHERE e.username=u.username
-                        AND u.auth='nologin'";
-            $revive_users = get_records_sql($sql);
-            if (!empty($revive_users)) {
-                print "User entries to be revived: ". count($revive_users) . "\n";
-                begin_sql();
-                foreach ($revive_users as $user) {
-                    $updateuser = new object();
-                    $updateuser->id = $user->id;
-                    $updateuser->auth = 'cas';
-                    if (update_record('user', $updateuser)) {
-                        echo "\t"; print_string('auth_dbreviveser', 'auth', array($user->username, $user->id)); echo "\n";
-                    } else {
-                        echo "\t"; print_string('auth_dbreviveusererror', 'auth', $user->username); echo "\n";
-                    }
-                }
-                commit_sql();
-            } else {
-                print "No user entries to be revived\n";
+
+        $site       = get_site();
+        $CASform    = get_string("CASform","auth");
+        $username   = optional_param("username");
+
+        if (!empty($username)) {
+            #error_log("CAS found username GET param ($username), and is unsetting wantsurl ($SESSION->wantsurl) -- is this to prevent infinite redirection?");
+            if (isset($SESSION->wantsurl) && (strstr($SESSION->wantsurl,'ticket') || strstr($SESSION->wantsurl,'NOCAS'))) {
+                unset($SESSION->wantsurl);
             }
-            unset($revive_users);
+            return;		
         }
-/// User Updates - time-consuming (optional)
-        if ($do_updates) {
-            // narrow down what fields we need to update
-            $all_keys = array_keys(get_object_vars($this->config));
-            $updatekeys = array();
-            foreach ($all_keys as $key) {
-                if (preg_match('/^field_updatelocal_(.+)$/',$key, $match)) {
-                    // if we have a field to update it from
-                    // and it must be updated 'onlogin' we
-                    // update it on cron
-                    if ( !empty($this->config->{'field_map_'.$match[1]})
-                         and $this->config->{$match[0]} === 'onlogin') {
-                        array_push($updatekeys, $match[1]); // the actual key name
-                    }
-                }
+
+        $authCAS = optional_param("authCAS");
+        if ($authCAS=="NOCAS")
+            return;
+
+        // Connection to CAS server
+        $this->connectCAS();
+
+        if (phpCAS::checkAuthentication()) {
+            // authenticated okay, now process
+            $frm->username=phpCAS::getUser();
+            $frm->password="passwdCas";		
+
+            if (!$this->subauth->user_exists($frm->username)) {
+                $this->subauth_usernotfound($frm->username);
+                return;
             }
-            // print_r($all_keys); print_r($updatekeys);
-            unset($all_keys); unset($key);
-        } else {
-            print "No updates to be done\n";
+            global $user;
+            $user = get_record('user', 'username', $frm->username);
+            #error_log("CAS Authenticated us as '{$frm->username}'");
+            return;
         }
-        if ( $do_updates and !empty($updatekeys) ) { // run updates only if relevant
-            $users = get_records_sql("SELECT u.username, u.id
-                                      FROM {$CFG->prefix}user u
-                                      WHERE u.deleted=0 AND u.auth='cas'");
-            if (!empty($users)) {
-                print "User entries to update: ". count($users). "\n";
-                $sitecontext = get_context_instance(CONTEXT_SYSTEM);
-                if (!empty($this->config->creators) and !empty($this->config->memberattribute)
-                  and $roles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
-                    $creatorrole = array_shift($roles);      // We can only use one, let's use the first one
-                } else {
-                    $creatorrole = false;
-                }
-                begin_sql();
-                $xcount = 0;
-                $maxxcount = 100;
-                foreach ($users as $user) {
-                    echo "\t"; print_string('auth_dbupdatinguser', 'auth', array($user->username, $user->id));
-                    if (!$this->update_user_record(addslashes($user->username), $updatekeys)) {
-                        echo " - ".get_string('skipped');
-                    }
-                    echo "\n";
-                    $xcount++;
-                    // update course creators if needed
-                    if ($creatorrole !== false) {
-                        if ($this->iscreator($user->username)) {
-                            role_assign($creatorrole->id, $user->id, 0, $sitecontext->id, 0, 0, 0, 'cas');
-                        } else {
-                            role_unassign($creatorrole->id, $user->id, 0, $sitecontext->id, 'cas');
-                        }
-                    }
-                    if ($xcount++ > $maxxcount) {
-                        commit_sql();
-                        begin_sql();
-                        $xcount = 0;
-                    }
-                }
-                commit_sql();
-                unset($users); // free mem
-            }
-        } else { // end do updates
-            print "No updates to be done\n";
+
+        if (isset($_GET["loginguest"]) && ((bool)$_GET['loginguest']) == true) {
+            #error_log("CAS login as guest (GET param)");
+            $frm->username="guest";
+            $frm->password="guest";
+            return;
+        }		
+
+        if ($this->config->multiauth || !empty($authCAS)) {
+            if ($authCAS=="NOCAS")
+                return;
+            $this->loginpage_multiauth($site, $CASform, $authCAS);
         }
-/// User Additions
-        // find users missing in DB that are in LDAP
-        // note that get_records_sql wants at least 2 fields returned,
-        // and gives me a nifty object I don't want.
-        // note: we do not care about deleted accounts anymore, this feature was replaced by suspending to nologin auth plugin
-        $sql = "SELECT e.username, e.username
-                FROM $temptable e LEFT JOIN {$CFG->prefix}user u ON e.username = u.username
-                WHERE u.id IS NULL";
-        $add_users = get_records_sql($sql); // get rid of the fat
-        if (!empty($add_users)) {
-            print "User entries to add: ". count($add_users). "\n";
-            $sitecontext = get_context_instance(CONTEXT_SYSTEM);
-            if (!empty($this->config->creators) and !empty($this->config->memberattribute)
-              and $roles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
-                $creatorrole = array_shift($roles);      // We can only use one, let's use the first one
-            } else {
-                $creatorrole = false;
-            }
-            begin_sql();
-            foreach ($add_users as $user) {
-                $user = $this->get_userinfo_asobj(addslashes($user->username));
-                // prep a few params
-                $user->modified   = time();
-                $user->confirmed  = 1;
-                $user->auth       = 'cas';
-                $user->mnethostid = $CFG->mnet_localhost_id;
-                if (empty($user->lang)) {
-                    $user->lang = $CFG->lang;
-                }
-                $user = addslashes_recursive($user);
-                if ($id = insert_record('user',$user)) {
-                    echo "\t"; print_string('auth_dbinsertuser', 'auth', array(stripslashes($user->username), $id)); echo "\n";
-                    $userobj = $this->update_user_record($user->username);
-                    if (!empty($this->config->forcechangepassword)) {
-                        set_user_preference('auth_forcepasswordchange', 1, $userobj->id);
-                    }
-                } else {
-                    echo "\t"; print_string('auth_dbinsertusererror', 'auth', $user->username); echo "\n";
-                }
-                // add course creators if needed
-                if ($creatorrole !== false and $this->iscreator(stripslashes($user->username))) {
-                    role_assign($creatorrole->id, $user->id, 0, $sitecontext->id, 0, 0, 0, 'cas');
-                }
-            }
-            commit_sql();
-            unset($add_users); // free mem
-        } else {
-            print "No users to be added\n";
+        // CAS authentication
+        if (!phpCAS::isAuthenticated()) {
+            phpCAS::forceAuthentication();
         }
-        return true;
+    } // function loginpage_hook
+
+
+    function subauth_usernotfound($username) {
+        $admin = get_admin();
+        $a = new stdClass();
+        $a->href = 'mailto:' . $admin->email;
+        $a->linktext = 'the site administrator';
+        print_error('auth_cas_subauth_usernotfound', 'auth', '', $a );
+        return;
     }
+
+
     /**
-     * Update a local user record from an external source.
-     * This is a lighter version of the one in moodlelib -- won't do
-     * expensive ops such as enrolment.
-     *
-     * If you don't pass $updatekeys, there is a performance hit and
-     * values removed from LDAP won't be removed from moodle.
-     *
-     * @param string $username username (with system magic quotes)
+     * This small function simply writes the CAS multiauth page
      */
-    function update_user_record($username, $updatekeys = false) {
+    function loginpage_multiauth($site, $CASform, $authCAS) {
         global $CFG;
-        //just in case check text case
-        $username = trim(moodle_strtolower($username));
-        // get the current user record
-        $user = get_record('user', 'username', $username, 'mnethostid', $CFG->mnet_localhost_id);
-        if (empty($user)) { // trouble
-            error_log("Cannot update non-existent user: ".stripslashes($username));
-            print_error('auth_dbusernotexist','auth',$username);
-            die;
-        }
-        // Protect the userid from being overwritten
-        $userid = $user->id;
-        if ($newinfo = $this->get_userinfo($username)) {
-            $newinfo = truncate_userinfo($newinfo);
-            if (empty($updatekeys)) { // all keys? this does not support removing values
-                $updatekeys = array_keys($newinfo);
-            }
-            foreach ($updatekeys as $key) {
-                if (isset($newinfo[$key])) {
-                    $value = $newinfo[$key];
-                } else {
-                    $value = '';
-                }
-                if (!empty($this->config->{'field_updatelocal_' . $key})) {
-                    if ($user->{$key} != $value) { // only update if it's changed
-                        set_field('user', $key, addslashes($value), 'id', $userid);
-                    }
-                }
-            }
-        } else {
-            return false;
-        }
-        return get_record_select('user', "id = $userid AND deleted = 0");
-    }
-    /**
-     * Bulk insert in SQL's temp table
-     * @param array $users is an array of usernames
-     */
-    function ldap_bulk_insert($users, $temptable) {
-        // bulk insert -- superfast with $bulk_insert_records
-        $sql = 'INSERT INTO ' . $temptable . ' (username) VALUES ';
-        // make those values safe
-        $users = addslashes_recursive($users);
-        // join and quote the whole lot
-        $sql = $sql . "('" . implode("'),('", $users) . "')";
-        print "\t+ " . count($users) . " users\n";
-        execute_sql($sql, false);
-    }
-    /**
-     * Returns true if user should be coursecreator.
-     *
-     * @param mixed $username    username (without system magic quotes)
-     * @return boolean result
-     */
-    function iscreator($username) {
-        if ((empty($this->config->attrcreators) && empty($this->config->groupecreators)) or empty($this->config->memberattribute)) {
-            return null;
+        // choice authentication form for multi-authentication
+        // test pgtIou parameter for proxy mode (https connection
+        // in background from CAS server to the php server)
+        #error_log('CAS loginpage_multiauth()');
+        if ($authCAS !="CAS" && !isset($_GET["pgtIou"])) {
+            $navlinks = array();
+            $navlinks[] = array('name' => $CASform, 'link' => null, 'type' => 'misc');
+            $navigation = build_navigation($navlinks);
+
+            print_header("$site->fullname: $CASform", $site->fullname, $navigation);
+            include($CFG->dirroot."/auth/cas/cas_form.html");
+            print_footer();
+            exit();
         }
-        $textlib = textlib_get_instance();
-        $extusername = $textlib->convert($username, 'utf-8', $this->config->ldapencoding);
-//test for groupe creator
-if (!empty($this->config->groupecreators))
-   if ((boolean)$this->ldap_isgroupmember($extusername, $this->config->groupecreators))
-        return true;
-//build filter for attrcreator
-if (!empty($this->config->attrcreators)) {
-    $attrs = explode(";",$this->config->attrcreators);
-    $filter = "(& (".$this->config->user_attribute."=$username)(|";
-    foreach ($attrs as $attr){
-        if(strpos($attr, "="))
-        	$filter .= "($attr)";
-        else
-        	$filter .= "(".$this->config->memberattribute."=$attr)";
     }
-    $filter .= "))";
-    //search
-    $result = $this->ldap_get_userlist($filter);
-    if (count($result)!=0)
-    	return true;
- 	}
 
-    return false;
-    }
-   /**
-     * checks if user belong to specific group(s)
-     *
-     * Returns true if user belongs group in grupdns string.
-     *
-     * @param mixed $username    username
-     * @param mixed $groupdns    string of group dn separated by ;
+
+    /**
+     * logout from the cas
      *
-     */
-    function ldap_isgroupmember($extusername='', $groupdns='') {
-    // Takes username and groupdn(s) , separated by ;
-    // Returns true if user is member of any given groups
-        $ldapconnection = $this->ldap_connect();
-        if (empty($extusername) or empty($groupdns)) {
-            return false;
-            }
-        if ($this->config->memberattribute_isdn) {
-            $memberuser = $this->ldap_find_userdn($ldapconnection, $extusername);
-        } else {
-            $memberuser = $extusername;
-        }
-        if (empty($memberuser)) {
-            return false;
-        }
-        $groups = explode(";",$groupdns);
-        $result = false;
-        foreach ($groups as $group) {
-            $group = trim($group);
-            if (empty($group)) {
-                continue;
-            }
-            //echo "Checking group $group for member $username\n";
-            $search = ldap_read($ldapconnection, $group,  '('.$this->config->memberattribute.'='.$this->filter_addslashes($memberuser).')', array($this->config->memberattribute));
-            if (!empty($search) and ldap_count_entries($ldapconnection, $search)) {
-                $info = $this->ldap_get_entries($ldapconnection, $search);
-                if (count($info) > 0 ) {
-                    // user is member of group
-                    $result = true;
-                    break;
-                }
-          }
-        }
-        return $result;
-    }
-   /**
-     * return all usernames from ldap
+     * This function is called from admin/auth.php
      *
-     * @return array
      */
-    function ldap_get_userlist($filter="*") {
-    /// returns all users from ldap servers
-        $fresult = array();
-        $ldapconnection = $this->ldap_connect();
-        if ($filter=="*") {
-           $filter = "(&(".$this->config->user_attribute."=*)(".$this->config->objectclass."))";
-        }
-        $contexts = explode(";",$this->config->contexts);
-        if (!empty($this->config->create_context)) {
-              array_push($contexts, $this->config->create_context);
-        }
-        foreach ($contexts as $context) {
-            $context = trim($context);
-            if (empty($context)) {
-                continue;
-            }
-            if ($this->config->search_sub) {
-                //use ldap_search to find first user from subtree
-                $ldap_result = ldap_search($ldapconnection, $context,$filter,array($this->config->user_attribute));
-            }
-            else {
-                //search only in this context
-                $ldap_result = ldap_list($ldapconnection, $context,
-                                         $filter,
-                                         array($this->config->user_attribute));
-            }
-            $users = $this->ldap_get_entries($ldapconnection, $ldap_result);
-            //add found users to list
-            for ($i=0;$i<count($users);$i++) {
-                array_push($fresult, ($users[$i][$this->config->user_attribute][0]) );
+    function prelogout_hook() {
+        global $CFG;
+        if ($this->config->logoutcas) {
+            $backurl = $CFG->wwwroot;
+            $this->connectCAS();
+            if (!phpCAS::isAuthenticated()) {
+                return;
             }
+            phpCAS::logout($backurl);
         }
-        return $fresult;
     }
-    /**
-     * return entries from ldap
-     *
-     * Returns values like ldap_get_entries but is
-     * binary compatible and return all attributes as array
-     *
-     * @return array ldap-entries
-     */
-    function ldap_get_entries($conn, $searchresult) {
-    //Returns values like ldap_get_entries but is
-    //binary compatible
-        $i=0;
-        $fresult=array();
-        $entry = ldap_first_entry($conn, $searchresult);
-        do {
-            $attributes = @ldap_get_attributes($conn, $entry);
-            for ($j=0; $j<$attributes['count']; $j++) {
-                $values = ldap_get_values_len($conn, $entry,$attributes[$j]);				
 
-                if (is_array($values)) {
-                $fresult[$i][strtolower($attributes[$j])] = $values;
-                }
-                else {
-                    $fresult[$i][strtolower($attributes[$j])] = array($values);
-                }
-            }
-            $i++;
-        }
-        while ($entry = @ldap_next_entry($conn, $entry));
-        //were done
+} // class auth_plugin_cas
 
-        return ($fresult);
-    }
-    /**
-     * Sync roles for this user
-     *
-     * @param $user object user object (without system magic quotes)
-     */
-    function sync_roles($user) {
-        $iscreator = $this->iscreator($user->username);
-        if ($iscreator === null) {
-            return; //nothing to sync - creators not configured
-        }
-        if ($roles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
-            $creatorrole = array_shift($roles);      // We can only use one, let's use the first one
-            $systemcontext = get_context_instance(CONTEXT_SYSTEM);
-            if ($iscreator) { // Following calls will not create duplicates
-                role_assign($creatorrole->id, $user->id, 0, $systemcontext->id, 0, 0, 0, 'cas');
-            } else {
-                //unassign only if previously assigned by this plugin!
-                role_unassign($creatorrole->id, $user->id, 0, $systemcontext->id, 'cas');
-            }
+
+
+function cas_config_set_defaults(&$config) {
+    // Default CAS configuration, used in case of blank fields from config form
+    static $auth_cas_default_config = array(
+        'baseuri'       => '',
+        'casversion'    => '',
+        'hostname'      => '',
+        'language'      => '',
+        'logoutcas'     => '',
+        'multiauth'     => '',
+        'port'          => '443',
+        'proxycas'      => '',
+        'subauth'       => 'none',
+    );
+
+    // set to defaults if undefined
+    foreach ($auth_cas_default_config as $key => $value) {
+        if (!isset($config->$key)) {
+            $config->$key = $value;
         }
     }
-   /**
-     * Quote control characters in texts used in ldap filters - see rfc2254.txt
-     *
-     * @param string
-     */
-    function filter_addslashes($text) {
-        $text = str_replace('\\', '\\5c', $text);
-        $text = str_replace(array('*',    '(',    ')',    "\0"),
-                            array('\\2a', '\\28', '\\29', '\\00'), $text);
-        return $text;
+}
+
+function cas_get_allowed_subauths() {
+    $allowed = array(
+        'ldap'	=> 1, 'db'	=> 1, 'fc'	=> 1, 'imap'	=> 1, 'mnet'	=> 1,
+        'nntp'	=> 1, 'pam'	=> 1, 'radius'	=> 1, 'shibboleth'	=> 1, 'pop3',
+        'none'  => 1,
+    );
+    $auths = get_list_of_plugins('auth');
+    $displayauths = array();
+    foreach ($auths as $auth) {
+        if (!isset($allowed[$auth])) {
+            continue; 
+        }
+        if (array_key_exists($auth, $displayauths)) {
+            continue; //already in the list
+        }
+        $authplugin = get_auth_plugin($auth);
+        /// Apply titles
+        $displayauths[$auth] = $authplugin->get_title();
     }
+    return $displayauths;
 }
+
 ?>
diff --git a/auth/cas/cas_form.html b/auth/cas/cas_form.html
index 9beb74b..eb74ae5 100644
--- a/auth/cas/cas_form.html
+++ b/auth/cas/cas_form.html
@@ -1,24 +1,6 @@
-
-
-<div class="loginbox clearfix">
-
-<div class="loginpanel">
-
-<div>
-
-<a href="<?php echo $CFG->wwwroot.'/login/index.php?authCAS=CAS';?>"><?php print_string("accesCAS","auth");?></a>
-
-</div>
-
-<br/>
-
-<div>
-
-<a href="<?php echo $CFG->wwwroot.'/login/index.php?authCAS=NOCAS';?>"><?php print_string("accesNOCAS","auth");?></a>
-
-</div>
-
-</div>
-
-</div>
-
+<?php
+    print_box_start('generalbox loginbox loginpanel');
+    print_single_button($CFG->wwwroot . '/login/index.php', array( 'authCAS' => 'CAS' ), get_string('accessCAS', 'auth')); 
+    print_single_button($CFG->wwwroot . '/login/index.php', array( 'authCAS' => 'NOCAS' ), get_string('accessNOCAS', 'auth')); 
+    print_box_end();
+?>
diff --git a/auth/cas/cas_ldap_sync_users.php b/auth/cas/cas_ldap_sync_users.php
deleted file mode 100644
index e4caec4..0000000
--- a/auth/cas/cas_ldap_sync_users.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-/** auth_ldap_sync_users.php
- *  Modified for cas Module
- *
- * This script is meant to be called from a cronjob to sync moodle with the LDAP
- * backend in those setups where the LDAP backend acts as 'master'.
- *
- * Recommended cron entry:
- * # 5 minutes past 4am
- * 5 4 * * * /usr/bin/php -c /etc/php4/cli/php.ini /var/www/moodle/auth/ldap/auth_ldap_sync_users.php
- *
- * Notes:
- *   - If you have a large number of users, you may want to raise the memory limits
- *     by passing -d momory_limit=256M
- *   - For debugging & better logging, you are encouraged to use in the command line:
- *     -d log_errors=1 -d error_reporting=E_ALL -d display_errors=0 -d html_errors=0
- *
- * Performance notes:
- * We have optimized it as best as we could for Postgres and mySQL, with 27K students
- * we have seen this take 10 minutes.
- *
- */
-
-
-if (isset($_SERVER['REMOTE_ADDR'])) {
-    error_log("should not be called from web server!");
-    exit;
-}
-
-$nomoodlecookie = true; // cookie not needed
-
-require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); // global moodle config file.
-
-require_once($CFG->dirroot.'/course/lib.php');
-require_once($CFG->dirroot.'/lib/blocklib.php');
-require_once($CFG->dirroot.'/mod/resource/lib.php');
-require_once($CFG->dirroot.'/mod/forum/lib.php');
-require_once($CFG->dirroot.'/lib/moodlelib.php');
-
-if (!is_enabled_auth('cas')) {
-    echo "Plugin not enabled!";
-    die;
-}
-
-$casauth = get_auth_plugin('cas');
-$casauth->sync_users(1000, true);
-
-?>
\ No newline at end of file
diff --git a/auth/cas/config.html b/auth/cas/config.html
index 22cd7a0..befa736 100644
--- a/auth/cas/config.html
+++ b/auth/cas/config.html
@@ -1,828 +1,128 @@
 <?php
-
-
-
     global $CFG;
 
     require_once 'languages.php';
-
-
-
-    $createoptions[0] = get_string("no");
-
-    $createoptions[1] = get_string("yes");
-
-
-
-    // set to defaults if undefined (CAS)
-
-    if (!isset ($config->hostname)) 
-
-        $config->hostname = '';
-
-    if (!isset ($config->port)) 
-
-        $config->port = '';
-
-    if (!isset ($config->casversion)) 
-
-        $config->casversion = '';
-
-    if (!isset ($config->baseuri)) 
-
-        $config->baseuri = '';
-
-    if (!isset ($config->language)) 
-
-        $config->language = '';
-
-    if (!isset ($config->proxycas)) 
-
-        $config->proxycas = '';
-
-    if (!isset ($config->logoutcas)) 
-
-        $config->logoutcas = '';
-
-    if (!isset ($config->multiauth))
-
-        $config->multiauth = '';
-
-  // set to defaults if undefined (LDAP)
-
-    if (!isset($config->host_url))
-
-        { $config->host_url = ''; }
-
-    if (empty($config->ldapencoding))
-
-        { $config->ldapencoding = 'utf-8'; }
-
-    if (!isset($config->contexts))
-
-        { $config->contexts = ''; }
-
-    if (!isset($config->user_type))
-
-        { $config->user_type = 'default'; }
-
-    if (!isset($config->user_attribute))
-
-        { $config->user_attribute = ''; }
-
-    if (!isset($config->search_sub))
-
-        { $config->search_sub = ''; }
-
-    if (!isset($config->opt_deref))
-
-        { $config->opt_deref = LDAP_DEREF_NEVER; }
-
-    if (!isset($config->bind_dn))
-
-        {$config->bind_dn = ''; }
-
-    if (!isset($config->bind_pw))
-
-        {$config->bind_pw = ''; }
-
-    if (!isset($config->version))
-
-        {$config->version = '2'; }
-
-    if (!isset($config->objectclass))
-
-        {$config->objectclass = ''; }
-
-    if (!isset($config->memberattribute))
-
-        {$config->memberattribute = ''; }
-
-    if (!isset($config->memberattribute_isdn))
-
-        {$config->memberattribute_isdn = ''; }
-
-    if (!isset($config->groupecreators))
-
-        {$config->groupecreators = ''; }
-
-    if (!isset($config->attrcreators))
-
-        {$config->attrcreators = ''; }
-
-     if (!isset($config->removeuser))
-
-        {$config->removeuser = 0; }
-
+    require_once dirname(__FILE__) . '/auth.php';
 
 
     $yesno = array( get_string('no'), get_string('yes') );
+    $createoptions = $yesno;
 
-
-
-if (!function_exists('ldap_connect')) { // Is php4-ldap really there?
-
-    notify(get_string('auth_ldap_noextension','auth'));
-
-}
-
-
-
-
-
+    // set to defaults if undefined (CAS)
+    cas_config_set_defaults($config);
 ?>
-
-
-
 <table cellspacing="0" cellpadding="5" border="0" align="center">
-
-
-
-<tr>
-
-   <td colspan="2">
-
-        <h4><?php print_string('auth_cas_server_settings', 'auth') ?> </h4>
-
-   </td>
-
-</tr>
-
-<tr valign="top" class="required">
-
-    <td align="right"><?php print_string('auth_cas_hostname_key', 'auth') ?>:</td>
-
-    <td>
-
-        <input name="hostname" type="text" size="30" value="<?php echo $config->hostname ?>" />
-
-        <?php
-
-
-
-        if (isset($err['hostname'])) {
-
-            formerr($err['hostname']);
-
-        }
-
-
-
-        ?>
-
+    <tr>
+        <td colspan="2">
+            <h4><?php print_string('auth_cas_server_settings', 'auth') ?> </h4>
+        </td>
+    </tr>
+    <tr valign="top" class="required">
+        <td align="right"><?php print_string('auth_cas_hostname_key', 'auth') ?>:</td>
+        <td>
+            <input name="hostname" type="text" size="30" value="<?php echo $config->hostname ?>" />
+            <?php
+                if (isset($err['hostname'])) {
+                    formerr($err['hostname']);
+                }
+            ?>
     </td>
-
     <td><?php print_string('auth_cas_hostname', 'auth') ?></td>
-
 </tr>
 
-
-
 <tr valign="top"  class="required">
-
     <td align="right"><?php print_string('auth_cas_baseuri_key', 'auth') ?>:</td>
-
     <td>
-
         <input name="baseuri" type="text" size="30" value="<?php echo $config->baseuri ?>" />
-
         <?php
-
-
-
-        if (isset($err['baseuri'])) {
-
-            formerr($err['baseuri']);
-
-        }
-
-
-
+            if (isset($err['baseuri'])) {
+                formerr($err['baseuri']);
+            }
         ?>
-
     </td>
-
     <td><?php print_string('auth_cas_baseuri', 'auth') ?></td>
-
 </tr>
 
-
-
 <tr valign="top" class="required">
-
     <td align="right"><?php print_string('auth_cas_port_key', 'auth') ?>:</td>
-
     <td>
-
         <input name="port" type="text" size="30" value="<?php echo $config->port ?>" />
-
         <?php
-
-
-
-        if (isset($err['port'])) {
-
-            formerr($err['port']);
-
-        }
-
-
-
+            if (isset($err['port'])) {
+                formerr($err['port']);
+            }
         ?>
-
     </td>
-
     <td><?php print_string('auth_cas_port', 'auth') ?></td>
-
 </tr>
 
-
-
 <tr valign="top"  class="required">
-
     <td align="right"><?php print_string('auth_cas_casversion', 'auth') ?>:</td>
-
     <td>
-
         <input name="casversion" type="text" size="30" value="<?php echo $config->casversion ?>" />
-
         <?php
-
-
-
-        if (isset($err['casversion'])) {
-
-            formerr($err['casversion']);
-
-        }
-
-
-
+            if (isset($err['casversion'])) {
+                formerr($err['casversion']);
+            }
         ?>
-
     </td>
-
     <td><?php print_string('auth_cas_version', 'auth') ?></td>
-
 </tr>
 
-
-
 <tr valign="top"  class="required">
-
     <td align="right"><?php print_string('auth_cas_language_key', 'auth') ?>:</td>
-
     <td>
-
         <?php
-
-
-
-        choose_from_menu($CASLANGUAGES, 'language', $config->language, '');
-
-
-
+            choose_from_menu($CASLANGUAGES, 'language', $config->language, '');
         ?>
-
     </td>
-
     <td><?php print_string('auth_cas_language', 'auth') ?></td>
-
 </tr>
 
-
-
 <tr valign="top"  class="required">
-
     <td align="right"><?php print_string('auth_cas_proxycas_key', 'auth') ?>:</td>
-
     <td>
-
         <?php
-
-        unset($options);
-
-        $options[1] = get_string('yes');
-
-        choose_from_menu ($options, 'proxycas', $config->proxycas, get_string('no'), '', '');
-
+            unset($options);
+            $options[1] = get_string('yes');
+            choose_from_menu ($options, 'proxycas', $config->proxycas, get_string('no'), '', '');
         ?>
-
     </td>
-
     <td><?php print_string('auth_cas_proxycas', 'auth') ?></td>
-
 </tr>
 
-
-
 <tr valign="top"  class="required">
-
     <td align="right"><?php print_string('auth_cas_logoutcas_key', 'auth') ?>:</td>
-
     <td>
-
         <?php
-
-        unset($options);
-
-        $options[1] = get_string('yes');
-
-        choose_from_menu ($options, 'logoutcas', $config->logoutcas, get_string('no'), '', '');
-
+            unset($options);
+            $options[1] = get_string('yes');
+            choose_from_menu ($options, 'logoutcas', $config->logoutcas, get_string('no'), '', '');
         ?>
-
     </td>
-
     <td><?php print_string('auth_cas_logoutcas', 'auth') ?></td>
-
 </tr>
 
-
-
 <tr valign="top"  class="required">
-
     <td align="right"><?php print_string('auth_cas_multiauth_key', 'auth') ?>:</td>
-
     <td>
-
         <?php
-
-        unset($options);
-
-        $options[1] = get_string('yes');
-
-        choose_from_menu ($options, 'multiauth', $config->multiauth, get_string('no'), '', '');
-
+            unset($options);
+            $options[1] = get_string('yes');
+            choose_from_menu ($options, 'multiauth', $config->multiauth, get_string('no'), '', '');
         ?>
-
     </td>
-
     <td><?php print_string('auth_cas_multiauth', 'auth') ?></td>
-
 </tr>
-
-
-
-<tr>
-
-   <td colspan="2">
-
-        <h4><?php print_string('auth_ldap_server_settings', 'auth') ?> </h4>
-
-   </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-    <td align="right"><label for="host_url"><?php print_string('auth_ldap_host_url_key','auth') ?></label></td>
-
-    <td>
-
-        <input name="host_url" id="host_url" type="text" size="30" value="<?php echo $config->host_url?>" />
-
-    <?php  if (isset($err['host_url'])) formerr($err['host_url']); ?>
-
-    </td>
-
-    <td>
-
-    <?php print_string('auth_ldap_host_url','auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-    <td align="right"><label for="menuversion"><?php print_string('auth_ldap_version_key','auth') ?></label></td>
-
-    <td>
-
-    <?php
-
-       $versions = array();
-
-       $versions[2] = '2';
-
-       $versions[3] = '3';
-
-       choose_from_menu($versions, 'version', $config->version, '');
-
-       if (isset($err['version'])) formerr($err['version']);
-
-    ?>
-
-    </td>
-
-    <td>
-
-    <?php print_string('auth_ldap_version','auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-    <td align="right"><label for="ldapencoding"><?php print_string("auth_ldap_ldap_encoding_key", "auth") ?></label></td>
-
+<tr valign="top"  class="required">
+    <td align="right"><?php print_string('auth_cas_subauth_key', 'auth') ?>:</td>
     <td>
-
-        <input id="ldapencoding" name="ldapencoding" type="text" value="<?php echo $config->ldapencoding ?>" />
-
         <?php
-
-
-
-        if (isset($err['ldapencoding'])) {
-
-            formerr($err['ldapencoding']);
-
-        }
-
-
-
+            unset($options);
+            $displayauths = cas_get_allowed_subauths();
+            choose_from_menu ($displayauths, 'subauth', $config->subauth, '', '', '');
         ?>
-
-    </td>
-
-    <td><?php print_string('auth_ldap_ldap_encoding', 'auth') ?></td>
-
-</tr>
-
-
-
-<tr>
-
-   <td colspan="2">
-
-        <h4><?php print_string('auth_ldap_bind_settings', 'auth') ?> </h4>
-
-   </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-    <td align="right"><label for="bind_dn"><?php print_string('auth_ldap_bind_dn_key','auth') ?></label></td>
-
-    <td>
-
-    <input name="bind_dn" id="bind_dn" type="text" size="30" value="<?php echo $config->bind_dn?>" />
-
-    <?php  if (isset($err['bind_dn'])) formerr($err['bind_dn']); ?>
-
-    </td><td>
-
-    <?php print_string('auth_ldap_bind_dn','auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-    <td align="right"><label for="bind_pw"><?php print_string('auth_ldap_bind_pw_key','auth') ?></label></td>
-
-    <td>
-
-    <input name="bind_pw" id="bind_pw" type="password" size="30" value="<?php echo $config->bind_pw?>" />
-
-    <?php  if (isset($err['bind_pw'])) formerr($err['bind_pw']); ?>
-
-    </td><td>
-
-    <?php print_string('auth_ldap_bind_pw','auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-<tr>
-
-   <td colspan="2">
-
-        <h4><?php print_string('auth_ldap_user_settings', 'auth') ?> </h4>
-
-   </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-    <td align="right"><label for="menuuser_type"><?php print_string('auth_ldap_user_type_key','auth') ?></label></td>
-
-    <td>
-
-    <?php choose_from_menu($this->ldap_suppported_usertypes(), 'user_type', $config->user_type, ''); ?>
-
-    <?php  if (isset($err['user_type'])) formerr($err['user_type']); ?>
-
-    </td>
-
-    <td>
-
-    <?php print_string('auth_ldap_user_type', 'auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-    <td align="right"><label for="contexts"><?php print_string('auth_ldap_contexts_key','auth') ?></label></td>
-
-    <td>
-
-    <input name="contexts" id="contexts"  type="text" size="30" value="<?php echo $config->contexts?>" />
-
-    <?php  if (isset($err['contexts'])) formerr($err['contexts']); ?>
-
-    </td>
-
-    <td>
-
-    <?php print_string('auth_ldap_contexts', 'auth') ?>
-
     </td>
-
+    <td><?php print_string('auth_cas_subauth', 'auth') ?></td>
 </tr>
-
-
-
-<tr valign="top" class="required">
-
-    <td align="right"><label for="menusearch_sub"><?php print_string('auth_ldap_search_sub_key','auth') ?></label></td>
-
-    <td>
-
-        <?php choose_from_menu($yesno, 'search_sub', $config->search_sub, ''); ?>
-
-    </td>
-
-    <td>
-
-    <?php print_string('auth_ldap_search_sub','auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-    <td align="right"><label for="menuopt_deref"><?php print_string('auth_ldap_opt_deref_key','auth') ?></label></td>
-
-    <td>
-
-    <?php
-
-       $opt_deref = array();
-
-       $opt_deref[LDAP_DEREF_NEVER] = get_string('no');
-
-       $opt_deref[LDAP_DEREF_ALWAYS] = get_string('yes');
-
-       choose_from_menu($opt_deref, 'opt_deref', $config->opt_deref, LDAP_DEREF_NEVER, '');
-
-       if (isset($err['opt_deref'])) formerr($err['opt_deref']);
-
-    ?>
-
-    </td>
-
-    <td>
-
-    <?php print_string('auth_ldap_opt_deref','auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-
-
-
-
-<tr valign="top" class="required">
-
-    <td align="right"><label for="user_attribute"><?php print_string('auth_ldap_user_attribute_key','auth') ?></label></td>
-
-    <td>
-
-    <input name="user_attribute" id="user_attribute" type="text" size="30" value="<?php echo $config->user_attribute?>" />
-
-    <?php  if (isset($err['user_attribute'])) formerr($err['user_attribute']); ?>
-
-    </td>
-
-    <td>
-
-    <?php print_string('auth_ldap_user_attribute','auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-        <td align="right"><label for="memberattribute"><?php print_string('auth_ldap_memberattribute_key','auth') ?></label></td>
-
-        <td>
-
-    <input name="memberattribute" id="memberattribute" type="text" size="30" value="<?php echo $config->memberattribute?>" />
-
-    <?php  if (isset($err['memberattribute'])) formerr($err['memberattribute']); ?>
-
-    </td><td>
-
-    <?php print_string('auth_ldap_memberattribute','auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-        <td align="right"><label for="memberattribute_isdn"><?php print_string('auth_ldap_memberattribute_isdn_key','auth') ?></label></td>
-
-        <td>
-
-    <input name="memberattribute_isdn" id="memberattribute_isdn" type="text" size="30" value="<?php echo $config->memberattribute_isdn?>" />
-
-    <?php  if (isset($err['memberattribute_isdn'])) formerr($err['memberattribute_isdn']); ?>
-
-    </td><td>
-
-    <?php print_string('auth_ldap_memberattribute_isdn','auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-    <td align="right"><label for="objectclass"><?php print_string('auth_ldap_objectclass_key','auth') ?></label></td>
-
-    <td>
-
-    <input name="objectclass" id="objectclass" type="text" size="30" value="<?php echo $config->objectclass?>" />
-
-    <?php  if (isset($err['objectclass'])) formerr($err['objectclass']); ?>
-
-    </td>
-
-    <td>
-
-    <?php print_string('auth_ldap_objectclass','auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-<tr>
-
-   <td colspan="2">
-
-        <h4><?php print_string('coursecreators') ?> </h4>
-
-   </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-        <td align="right"><label for="attrcreators_key"><?php print_string('auth_ldap_attrcreators_key','auth') ?></label></td>
-
-        <td>
-
-    <input name="attrcreators" id="attrcreators" type="text" size="30" value="<?php echo $config->attrcreators?>" />
-
-    <?php  if (isset($err['attrcreators'])) formerr($err['attrcreators']); ?>
-
-    </td><td>
-
-    <?php print_string('auth_ldap_attrcreators','auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-<tr valign="top" class="required">
-
-        <td align="right"><label for="groupecreators_key"><?php print_string('auth_ldap_groupecreators_key','auth') ?></label></td>
-
-        <td>
-
-    <input name="groupecreators" id="groupecreators" type="text" size="30" value="<?php echo $config->groupecreators?>" />
-
-    <?php  if (isset($err['groupecreators'])) formerr($err['groupecreators']); ?>
-
-    </td><td>
-
-    <?php print_string('auth_ldap_groupecreators','auth') ?>
-
-    </td>
-
-</tr>
-
-
-
-<tr>
-
-   <td colspan="2">
-
-        <h4><?php print_string('auth_sync_script', 'auth') ?> </h4>
-
-   </td>
-
-</tr>
-
-
-
-<tr valign="top">
-
-    <td align="right"><label for="menuremoveuser"><?php print_string('auth_remove_user_key','auth') ?></label></td>
-
-    <td>
-
-    <?php
-
-       $deleteopt = array();
-
-       $deleteopt['0'] = get_string('auth_remove_keep','auth');
-
-       $deleteopt['1'] = get_string('auth_remove_suspend','auth');
-
-       $deleteopt['2'] = get_string('auth_remove_delete','auth');
-
-       choose_from_menu($deleteopt, 'removeuser', $config->removeuser, '');
-
-    ?>
-
-    </td>
-
-    <td>
-
-    <?php print_string('auth_remove_user','auth') ?>
-
-    </td>
-
-</tr>
-
-<?php
-
-
-
-$help  = get_string('auth_ldapextrafields','auth');
-
-$help .= get_string('auth_updatelocal_expl','auth');
-
-$help .= get_string('auth_fieldlock_expl','auth');
-
-$help .= get_string('auth_updateremote_expl','auth');
-
-$help .= '<hr />';
-
-$help .= get_string('auth_updateremote_ldap','auth');
-
-
-
-print_auth_lock_options('cas', $user_fields, $help, true, true);
-
-
-
-?>
-</table>
\ No newline at end of file
+</table>
diff --git a/lang/en_utf8/auth.php b/lang/en_utf8/auth.php
index a225309..9e74a55 100644
--- a/lang/en_utf8/auth.php
+++ b/lang/en_utf8/auth.php
@@ -33,22 +33,25 @@ $string['auth_nologindescription'] = 'Auxiliary plugin that prevents user to log
 $string['auth_nologintitle'] = 'No login';
 
 // CAS plugin
-$string['auth_cas_proxycas_key'] = "Proxy mode";
-$string['auth_cas_logoutcas_key'] = "Logout CAS";
-$string['auth_cas_multiauth_key'] = "Multi-authentication";
-$string['auth_cas_proxycas'] = 'Turn this to \'yes\' if you use CASin proxy-mode';
-$string['auth_cas_logoutcas'] = 'Turn this to \'yes\' if tou want to logout from CAS when you deconnect from Moodle';
-$string['auth_cas_multiauth'] = 'Turn this to \'yes\' if you want to have multi-authentication (CAS + other authentication)';
-$string['accesCAS'] = "CAS users";
-$string['accesNOCAS'] = "other users";
-$string['CASform'] = "Authentication choice";
+$string['auth_cas_proxycas_key'] = 'Proxy mode';
+$string['auth_cas_logoutcas_key'] = 'Logout CAS';
+$string['auth_cas_multiauth_key'] = 'Multi-authentication';
+$string['auth_cas_proxycas'] = 'Set this to \'yes\' if you use CAS in proxy-mode';
+$string['auth_cas_logoutcas'] = 'Set this to \'yes\' if you want to logout from CAS when you logout of Moodle';
+$string['auth_cas_multiauth'] = 'Set this to \'yes\' if you want users to be able to choose between CAS and other enabled login methods on the login screen';
+$string['auth_cas_subauth_key'] = 'Sub-authentication module';
+$string['auth_cas_subauth'] = 'CAS is only used for authentication; to retrieve user details, another authentication method must be used.  Here you can choose the backing authentication module which will be used to retrieve user details.  The settings for the sub-authentication plugin can be edited on the Admin->Users->Authentication page.';
+$string['auth_cas_subauth_usernotfound'] = 'CAS has authenticated you, but no details for your account have been retrieved from our identification server.<br />This may mean that the two servers are slightly out of synch.  Please try again in a few minutes.  <br />If you still have problems logging in, please contact <a href=\"$a->href\">$a->linktext</a>.';
+$string['accessCAS'] = 'CAS users login';
+$string['accessNOCAS'] = 'Other users';
+$string['CASform'] = 'Authentication choice';
 $string['auth_cas_logincas'] = 'Secure connection access';
 $string['auth_cas_invalidcaslogin'] = 'Sorry, your login has failed - you could not be authorised';
 $string['auth_cas_server_settings'] = 'CAS server configuration';
 $string['auth_castitle'] = 'CAS server (SSO)';
 $string['auth_cas_hostname'] = 'Hostname of the CAS server <br />eg: host.domain.fr';
-$string['auth_cas_baseuri'] = 'URI of the server (nothing if no baseUri)<br />For example, if the CAS server responds to host.domaine.fr/CAS/ then<br />cas_baseuri = CAS/';
-$string['auth_cas_port'] = 'Port of the CAS server';
+$string['auth_cas_baseuri'] = 'URI of the server (leave empty if not required)<br />For example, if the CAS server responds to host.domaine.fr/CAS/ then<br />enter CAS/';
+$string['auth_cas_port'] = 'Port where the CAS server listens';
 $string['auth_cas_version'] = 'Version of CAS';
 $string['auth_cas_language'] = 'Selected language';
 $string['auth_casdescription'] = 'This method uses a CAS server (Central Authentication Service) to authenticate users in a Single Sign On environment (SSO). You can also use a simple LDAP authentication. If the given username and password are valid according to CAS, Moodle creates a new user entry in its database, taking user attributes from LDAP if required. On following logins only the username and password are checked.';
