[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [websites/wiki-kde-org/develop] extensions/LdapAuthentication: update ldap auth extension
From:       Ingo Malchow <imalchow () kde ! org>
Date:       2013-01-20 14:47:46
Message-ID: 20130120144746.380FBA6091 () git ! kde ! org
[Download RAW message or body]

Git commit 078453378db9166223d03f976ab4084b9dfbb1eb by Ingo Malchow.
Committed on 20/01/2013 at 15:47.
Pushed by imalchow into branch 'develop'.

update ldap auth extension

M  +85   -34   extensions/LdapAuthentication/LdapAuthentication.i18n.php
M  +898  -727  extensions/LdapAuthentication/LdapAuthentication.php
M  +43   -38   extensions/LdapAuthentication/LdapAutoAuthentication.php
A  +13   -0    extensions/LdapAuthentication/ldap.sql

http://commits.kde.org/websites/wiki-kde-org/078453378db9166223d03f976ab4084b9dfbb1eb


diff --git a/extensions/LdapAuthentication/LdapAuthentication.i18n.php \
b/extensions/LdapAuthentication/LdapAuthentication.i18n.php index \
                7969238..2ac3045 100644
--- a/extensions/LdapAuthentication/LdapAuthentication.i18n.php
+++ b/extensions/LdapAuthentication/LdapAuthentication.i18n.php
@@ -43,35 +43,42 @@ $messages['ar'] = array(
 	'ldapauthentication-desc' => 'إضافة تحقيق LDAP بدعم \
لوسائل تحقيق LDAP متعددة',  );
 
-/** Belarusian (Taraškievica orthography) (Беларуская \
(тарашкевіца)) +/** Asturian (asturianu)
+ * @author Xuacu
+ */
+$messages['ast'] = array(
+	'ldapauthentication-desc' => "Complemento p'autenticación LDAP con \
sofitu pa dellos métodos d'autenticación LDAP", +);
+
+/** Belarusian (Taraškievica orthography) (беларуская \
                (тарашкевіца)‎)
  * @author EugeneZelenko
  */
 $messages['be-tarask'] = array(
 	'ldapauthentication-desc' => 'Дапаўненьне \
LDAP-аўтэнтыфікацыі з падтрымкай \
некалькіх мэтадаў аўтэнтыфікацыі LDAP',  );
 
-/** Breton (Brezhoneg)
+/** Breton (brezhoneg)
  * @author Fulup
  */
 $messages['br'] = array(
 	'ldapauthentication-desc' => 'Adveziant gwiriekaat LDAP ennañ meur a \
hentenn wiriekaat LDAP',  );
 
-/** Bosnian (Bosanski)
+/** Bosnian (bosanski)
  * @author CERminator
  */
 $messages['bs'] = array(
 	'ldapauthentication-desc' => 'Proširenje LDAP autentifikacije sa \
podrškom za mnoge metode LDAP autentifikacije',  );
 
-/** Catalan (Catal )
+/** Catalan (catal )
  * @author Paucabot
  */
 $messages['ca'] = array(
 	'ldapauthentication-desc' => "Connector d'autentificació LDAP amb suport \
per a diversos mètodes d'autenticació LDAP",  );
 
-/** Czech (Česky)
+/** Czech (česky)
  * @author Mormegil
  */
 $messages['cs'] = array(
@@ -80,33 +87,41 @@ $messages['cs'] = array(
 
 /** German (Deutsch)
  * @author Imre
+ * @author Kghbln
  */
 $messages['de'] = array(
-	'ldapauthentication-desc' => 'Plug-in für LDAP-Authentifizierung mit \
Unterstützung einiger LDAP-Authentifizierungsmethoden', \
+	'ldapauthentication-desc' => 'Ermöglicht die LDAP-Authentifizierung mit \
Hilfe mehrerer Authentifizierungsmethoden',  );
 
-/** Lower Sorbian (Dolnoserbski)
+/** Lower Sorbian (dolnoserbski)
  * @author Michawiki
  */
 $messages['dsb'] = array(
 	'ldapauthentication-desc' => 'Tykac awtentifikacije LDAP z pódpěru za \
někotare metody LDAP-awtentifikacije',  );
 
-/** Spanish (Español)
+/** Esperanto (Esperanto)
+ * @author Blahma
+ */
+$messages['eo'] = array(
+	'ldapauthentication-desc' => 'LDAP-aŭtentiga kromprogramo kun subteno de \
pluraj LDAP-aŭtentigaj metodoj', +);
+
+/** Spanish (español)
  * @author Translationista
  */
 $messages['es'] = array(
 	'ldapauthentication-desc' => 'Complemento de autentificación LDAP con \
apoyo de múltiples métodos de autentificación LDAP',  );
 
-/** Finnish (Suomi)
+/** Finnish (suomi)
  * @author Centerlink
  */
 $messages['fi'] = array(
 	'ldapauthentication-desc' => 'LDAP-todentamisliitännäinen useiden \
LDAP-todennustapojen tuella',  );
 
-/** French (Français)
+/** French (français)
  * @author IAlex
  * @author Urhixidur
  */
@@ -114,7 +129,7 @@ $messages['fr'] = array(
 	'ldapauthentication-desc' => 'Extension d'authentification LDAP prenant \
en charge de multiples méthodes d'authentification LDAP',  );
 
-/** Galician (Galego)
+/** Galician (galego)
  * @author Toliño
  */
 $messages['gl'] = array(
@@ -135,21 +150,21 @@ $messages['he'] = array(
 	'ldapauthentication-desc' => 'תוסף אימות LDAP עם תמיכה \
במספר שיטות LDAP לאימות',  );
 
-/** Upper Sorbian (Hornjoserbsce)
+/** Upper Sorbian (hornjoserbsce)
  * @author Michawiki
  */
 $messages['hsb'] = array(
 	'ldapauthentication-desc' => 'Tykač awtentifikacije LDAP z podpěru za \
wjacore metody LDAP-awtentifikacije',  );
 
-/** Hungarian (Magyar)
+/** Hungarian (magyar)
  * @author Glanthor Reviol
  */
 $messages['hu'] = array(
 	'ldapauthentication-desc' => 'LDAP hitelesítési bővítmény többféle \
LDAP azonosítási módszer támogatásával',  );
 
-/** Interlingua (Interlingua)
+/** Interlingua (interlingua)
  * @author McDutchie
  */
 $messages['ia'] = array(
@@ -163,7 +178,7 @@ $messages['id'] = array(
 	'ldapauthentication-desc' => 'Pengaya otentikasi LDAP dengan dukungan \
untuk berbagai metode otentikasi LDAP',  );
 
-/** Italian (Italiano)
+/** Italian (italiano)
  * @author HalphaZ
  */
 $messages['it'] = array(
@@ -172,9 +187,17 @@ $messages['it'] = array(
 
 /** Japanese (日本語)
  * @author Aotake
+ * @author Shirayuki
  */
 $messages['ja'] = array(
-	'ldapauthentication-desc' => \
'複数のLDAP認証方式をサポートするLDAP認証プラグイン', \
+	'ldapauthentication-desc' => '複数の LDAP 認証方式対応の LDAP \
認証プラグイン', +);
+
+/** Korean (한국어)
+ * @author 아라
+ */
+$messages['ko'] = array(
+	'ldapauthentication-desc' => '여러 LDAP 인증 방법에 대해 \
지원하는 LDAP 인증 플러그인',  );
 
 /** Colognian (Ripoarisch)
@@ -191,35 +214,42 @@ $messages['lb'] = array(
 	'ldapauthentication-desc' => 'Authentifikatiouns-Plugin fir LDAP mat \
Ënnerstëtzung fir multipel LDAP Authentifikatiouns-Methoden',  );
 
-/** Macedonian (Македонски)
+/** Macedonian (македонски)
  * @author Bjankuloski06
  */
 $messages['mk'] = array(
 	'ldapauthentication-desc' => 'LDAP приклучок за \
потврдување со поддршка за повеќе методи \
на LDAP потврдување',  );
 
-/** Dutch (Nederlands)
- * @author Siebrand
+/** Malay (Bahasa Melayu)
+ * @author Anakmalaysia
  */
-$messages['nl'] = array(
-	'ldapauthentication-desc' => 'LDAP-authenticatieplug-in met ondersteuning \
voor meerdere LDAP-authenticatiemethoden', +$messages['ms'] = array(
+	'ldapauthentication-desc' => 'Pemalam pengesahan LDAP dengan sokongan \
untuk berbilang kaedah pengesahan LDAP',  );
 
-/** Norwegian (bokmål)‬ (‪Norsk (bokmål)‬)
+/** Norwegian Bokmål (norsk (bokmål)‎)
  * @author Nghtwlkr
  */
-$messages['no'] = array(
+$messages['nb'] = array(
 	'ldapauthentication-desc' => 'Programutvidelse for LDAP-autentisering med \
støtte for flere LDAP-autentiseringsmetoder',  );
 
-/** Occitan (Occitan)
+/** Dutch (Nederlands)
+ * @author Siebrand
+ */
+$messages['nl'] = array(
+	'ldapauthentication-desc' => 'LDAP-authenticatieplug-in met ondersteuning \
voor meerdere LDAP-authenticatiemethoden', +);
+
+/** Occitan (occitan)
  * @author Cedric31
  */
 $messages['oc'] = array(
 	'ldapauthentication-desc' => "Plugin d'autentificacion LDAP amb supòrt \
de metòdes d'autentificacion LDAP multiples",  );
 
-/** Polish (Polski)
+/** Polish (polski)
  * @author Sp5uhe
  */
 $messages['pl'] = array(
@@ -234,54 +264,55 @@ $messages['pms'] = array(
 	'ldapauthentication-desc' => "Plugin për l'autenticassion LDAP con \
apògg për v ire manere d'autenticassion LDAP",  );
 
-/** Portuguese (Português)
+/** Portuguese (português)
  * @author Hamilton Abreu
  */
 $messages['pt'] = array(
 	'ldapauthentication-desc' => "''Plugin'' de autenticação LDAP, com \
suporte para vários métodos de autenticação",  );
 
-/** Brazilian Portuguese (Português do Brasil)
+/** Brazilian Portuguese (português do Brasil)
  * @author Giro720
  */
 $messages['pt-br'] = array(
 	'ldapauthentication-desc' => "''Plugin'' de autenticação LDAP, com \
suporte para vários métodos de autenticação",  );
 
-/** Tarandíne (Tarandíne)
+/** tarandíne (tarandíne)
  * @author Joetaras
  */
 $messages['roa-tara'] = array(
 	'ldapauthentication-desc' => "plugin de autendicazione LDAP cu 'u \
supporte pe autendicaziune multeple de metode LDAP",  );
 
-/** Russian ( усский)
+/** Russian (русский)
  * @author Александр Сигачёв
  */
 $messages['ru'] = array(
 	'ldapauthentication-desc' => 'Плагин \
LDAP-аутентификации с поддержкой \
нескольких методов проверки подлинности \
LDAP',  );
 
-/** Slovak (Slovenčina)
+/** Slovak (slovenčina)
  * @author Helix84
  */
 $messages['sk'] = array(
 	'ldapauthentication-desc' => 'Zásuvný modul na autentifikáciu \
prostredníctvom LDAP s podporou viacerých metód LDAP',  );
 
-/** Serbian Cyrillic ekavian (Српски (ћирилица))
+/** Serbian (Cyrillic script) (српски (ћирилица)‎)
  * @author Михајло Анђелковић
  */
 $messages['sr-ec'] = array(
 	'ldapauthentication-desc' => 'Плагин за LDAP \
ауторизацију, са подршком за више метода \
LDAP ауторизације',  );
 
-/** Serbian Latin ekavian (Srpski (latinica)) */
+/** Serbian (Latin script) (srpski (latinica)‎)
+ */
 $messages['sr-el'] = array(
 	'ldapauthentication-desc' => 'Plagin za LDAP autorizaciju, sa podrškom \
za više metoda LDAP autorizacije',  );
 
-/** Swedish (Svenska)
+/** Swedish (svenska)
  * @author Boivie
  */
 $messages['sv'] = array(
@@ -302,10 +333,30 @@ $messages['tr'] = array(
 	'ldapauthentication-desc' => 'Birden çok LDAP kimlik doğrulama \
yöntemini destekleyen LDAP kimlik doğrulama eklentisi',  );
 
-/** Ukrainian (Українська)
+/** Ukrainian (українська)
  * @author Ytsukeng Fyvaprol
  */
 $messages['uk'] = array(
 	'ldapauthentication-desc' => 'Плагін \
LDAP-аутентифікації з підтримкою \
декількох методів перевірки \
автентичності LDAP',  );
 
+/** Vietnamese (Tiếng Việt)
+ * @author Minh Nguyen
+ */
+$messages['vi'] = array(
+	'ldapauthentication-desc' => 'Phần bổ trợ xác thực LDAP hỗ \
trợ nhiều phương pháp xác thực LDAP', +);
+
+/** Simplified Chinese (中文(简体)‎)
+ * @author Yanmiao liu
+ */
+$messages['zh-hans'] = array(
+	'ldapauthentication-desc' => \
'具有多种LDAP认证方法支持的LDAP认证插件', +);
+
+/** Traditional Chinese (中文(繁體)‎)
+ * @author Anakmalaysia
+ */
+$messages['zh-hant'] = array(
+	'ldapauthentication-desc' => \
'具有多種LDAP認證方法支持的LDAP認證外掛程式', +);
diff --git a/extensions/LdapAuthentication/LdapAuthentication.php \
b/extensions/LdapAuthentication/LdapAuthentication.php index \
                2c172bf..3ce51b3 100644
--- a/extensions/LdapAuthentication/LdapAuthentication.php
+++ b/extensions/LdapAuthentication/LdapAuthentication.php
@@ -17,16 +17,7 @@
 # http://www.gnu.org/copyleft/gpl.html
 
 /**
- * LdapAuthentication plugin.
- *
- * Password authentication, and Smartcard Authentication support are \
                currently
- * available. All forms of authentication, current and future, should \
                support
- * group, and attribute based restrictions; preference pulling; and group
- * syncronization. All forms of authentication should have basic support \
                for 
- * adding users, changing passwords, and updating preferences in LDAP.
- *
- * Password authentication has a number of configurations, including \
                straight binds,
- * proxy based authentication, and anonymous-search based authentication.
+ * LdapAuthentication plugin. LDAP Authentication and authorization \
                integration with MediaWiki.
  *
  * @file
  * @ingroup MediaWiki
@@ -36,7 +27,7 @@
 # LdapAuthentication.php
 #
 # Info available at \
                http://www.mediawiki.org/wiki/Extension:LDAP_Authentication
-# Support is available at \
http://www.mediawiki.org/wiki/Extension_talk:LDAP_Authentication  +# \
Support is available at \
http://www.mediawiki.org/wiki/Extension_talk:LDAP_Authentication  #
 
 if ( !defined( 'MEDIAWIKI' ) ) exit;
@@ -61,13 +52,12 @@ $wgLDAPAddLDAPUsers = array();
 $wgLDAPUpdateLDAP = array();
 $wgLDAPPasswordHash = array();
 $wgLDAPMailPassword = array();
-$wgLDAPRetrievePrefs = array();
 $wgLDAPPreferences = array();
 $wgLDAPDisableAutoCreate = array();
 $wgLDAPDebug = 0;
-$wgLDAPGroupDN = ""; //Deprecated
 $wgLDAPGroupUseFullDN = array();
 $wgLDAPLowerCaseUsername = array();
+$wgLDAPLowerCaseUsernameScheme = array();
 $wgLDAPGroupUseRetrievedUsername = array();
 $wgLDAPGroupObjectclass = array();
 $wgLDAPGroupAttribute = array();
@@ -79,16 +69,12 @@ $wgLDAPGroupsPrevail = array();
 $wgLDAPRequiredGroups = array();
 $wgLDAPExcludedGroups = array();
 $wgLDAPGroupSearchNestedGroups = array();
-$wgLDAPSmartcardDomain = ""; //Deprecated
-$wgLDAPSSLUsername = ""; //Deprecated
 $wgLDAPAuthAttribute = array();
 $wgLDAPAutoAuthUsername = "";
 $wgLDAPAutoAuthDomain = "";
-$wgLDAPUniqueAttribute = array(); //Currently unused
-$wgLDAPUniqueBlockLogin = array(); //Currently unused
-$wgLDAPUniqueRenameUser = array(); //Currently unused
+$wgPasswordResetRoutes['domain'] = true;
 
-define( "LDAPAUTHVERSION", "1.2e" );
+define( "LDAPAUTHVERSION", "2.0d" );
 
 /**
  * Add extension information to Special:Version
@@ -99,12 +85,29 @@ $wgExtensionCredits['other'][] = array(
 	'version' => LDAPAUTHVERSION,
 	'author' => 'Ryan Lane',
 	'descriptionmsg' => 'ldapauthentication-desc',
-	'url' => 'http://www.mediawiki.org/wiki/Extension:LDAP_Authentication',
+	'url' => 'https://www.mediawiki.org/wiki/Extension:LDAP_Authentication',
 );
 
 $dir = dirname( __FILE__ ) . '/';
 $wgExtensionMessagesFiles['LdapAuthentication'] = $dir . \
'LdapAuthentication.i18n.php';  
+# Schema changes
+$wgHooks['LoadExtensionSchemaUpdates'][] = \
'efLdapAuthenticationSchemaUpdates'; +
+/**
+ * @param $updater DatabaseUpdater
+ * @return bool
+ */
+function efLdapAuthenticationSchemaUpdates( $updater ) {
+	$base = dirname( __FILE__ );
+	switch ( $updater->getDB()->getType() ) {
+	case 'mysql':
+		$updater->addExtensionTable( 'ldap_domains', "$base/ldap.sql" );
+		break;
+	}
+	return true;
+}
+
 // constants for search base
 define( "GROUPDN", 0 );
 define( "USERDN", 1 );
@@ -142,6 +145,344 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	// the user's entry and all attributes
 	var $userInfo;
 
+	// the user we are currently bound as
+	var $boundAs;
+
+	/**
+	 * Wrapper for ldap_connect
+	 * @param null $hostname
+	 * @param int $port
+	 * @return resource|false
+	 */
+	public static function ldap_connect( $hostname=null, $port=389 ) {
+		wfSuppressWarnings();
+		$ret = ldap_connect( $hostname, $port );
+		wfRestoreWarnings();
+		return $ret;
+	}
+
+	/**
+	 * Wrapper for ldap_bind
+	 * @param $ldapconn
+	 * @param null $dn
+	 * @param null $password
+	 * @return bool
+	 */
+	public static function ldap_bind( $ldapconn, $dn=null, $password=null ) {
+		wfSuppressWarnings();
+		$ret = ldap_bind( $ldapconn, $dn, $password );
+		wfRestoreWarnings();
+		return $ret;
+	}
+
+	/**
+	 * Wrapper for ldap_unbind
+	 * @param $ldapconn
+	 * @return bool
+	 */
+	public static function ldap_unbind( $ldapconn ) {
+		if ( $ldapconn ) {
+			wfSuppressWarnings();
+			$ret = ldap_unbind( $ldapconn );
+			wfRestoreWarnings();
+		} else {
+			$ret = false;
+		}
+		return $ret;
+	}
+
+	/**
+	 * Wrapper for ldap_modify
+	 * @param $ldapconn
+	 * @param $dn
+	 * @param $entry
+	 * @return bool
+	 */
+	public static function ldap_modify( $ldapconn, $dn, $entry ) {
+		wfSuppressWarnings();
+		$ret = ldap_modify( $ldapconn, $dn, $entry );
+		wfRestoreWarnings();
+		return $ret;
+	}
+
+	/**
+	 * Wrapper for ldap_add
+	 * @param $ldapconn
+	 * @param $dn
+	 * @param $entry
+	 * @return bool
+	 */
+	public static function ldap_add( $ldapconn, $dn, $entry ) {
+		wfSuppressWarnings();
+		$ret = ldap_add( $ldapconn, $dn, $entry );
+		wfRestoreWarnings();
+		return $ret;
+	}
+
+	/**
+	 * Wrapper for ldap_delete
+	 * @param $ldapconn
+	 * @param $dn
+	 * @return bool
+	 */
+	public static function ldap_delete( $ldapconn, $dn ) {
+		wfSuppressWarnings();
+		$ret = ldap_delete( $ldapconn, $dn );
+		wfRestoreWarnings();
+		return $ret;
+	}
+
+	/**
+	 * Wrapper for ldap_search
+	 * @param $ldapconn
+	 * @param $basedn
+	 * @param $filter
+	 * @param null $attributes
+	 * @param null $attrsonly
+	 * @param null $sizelimit
+	 * @param null $timelimit
+	 * @param null $deref
+	 * @return resource
+	 */
+	public static function ldap_search( $ldapconn, $basedn, $filter, \
$attributes=array(), $attrsonly=null, $sizelimit=null, $timelimit=null, \
$deref=null ) { +		wfSuppressWarnings();
+		$ret = ldap_search( $ldapconn, $basedn, $filter, $attributes, \
$attrsonly, $sizelimit, $timelimit, $deref ); +		wfRestoreWarnings();
+		return $ret;
+	}
+
+	/**
+	 * Wrapper for ldap_read
+	 * @param $ldapconn
+	 * @param $basedn
+	 * @param $filter
+	 * @param null $attributes
+	 * @param null $attrsonly
+	 * @param null $sizelimit
+	 * @param null $timelimit
+	 * @param null $deref
+	 * @return resource
+	 */
+	public static function ldap_read( $ldapconn, $basedn, $filter, \
$attributes=array(), $attrsonly=null, $sizelimit=null, $timelimit=null, \
$deref=null ) { +		wfSuppressWarnings();
+		$ret = ldap_read( $ldapconn, $basedn, $filter, $attributes, $attrsonly, \
$sizelimit, $timelimit, $deref ); +		wfRestoreWarnings();
+		return $ret;
+	}
+
+	/**
+	 * Wrapper for ldap_list
+	 * @param $ldapconn
+	 * @param $basedn
+	 * @param $filter
+	 * @param null $attributes
+	 * @param null $attrsonly
+	 * @param null $sizelimit
+	 * @param null $timelimit
+	 * @param null $deref
+	 * @return \resource
+	 */
+	public static function ldap_list( $ldapconn, $basedn, $filter, \
$attributes=array(), $attrsonly=null, $sizelimit=null, $timelimit=null, \
$deref=null ) { +		wfSuppressWarnings();
+		$ret = ldap_list( $ldapconn, $basedn, $filter, $attributes, $attrsonly, \
$sizelimit, $timelimit, $deref ); +		wfRestoreWarnings();
+		return $ret;
+	}
+
+	/**
+	 * Wrapper for ldap_get_entries
+	 * @param $ldapconn
+	 * @param $resultid
+	 * @return array
+	 */
+	public static function ldap_get_entries( $ldapconn, $resultid ) {
+		wfSuppressWarnings();
+		$ret = ldap_get_entries( $ldapconn, $resultid );
+		wfRestoreWarnings();
+		return $ret;
+	}
+
+	/**
+	 * Wrapper for ldap_count_entries
+	 * @param $ldapconn
+	 * @param $resultid
+	 * @return int
+	 */
+	public static function ldap_count_entries( $ldapconn, $resultid ) {
+		wfSuppressWarnings();
+		$ret = ldap_count_entries( $ldapconn, $resultid );
+		wfRestoreWarnings();
+		return $ret;
+	}
+
+	/**
+	 * Wrapper for ldap_errno
+	 * @param $ldapconn
+	 * @return int
+	 */
+	public static function ldap_errno( $ldapconn ) {
+		wfSuppressWarnings();
+		$ret = ldap_errno( $ldapconn );
+		wfRestoreWarnings();
+		return $ret;
+	}
+
+	/**
+	 * Get configuration defined by admin, or return default value
+	 *
+	 * @param string $preference
+	 * @return mixed
+	 */
+	public function getConf( $preference, $domain='' ) {
+		if ( !$domain ) {
+			$domain = $this->getDomain();
+		}
+		switch ( $preference ) {
+		case 'ServerNames':
+			global $wgLDAPServerNames;
+			return self::setOrDefault( $wgLDAPServerNames, $domain );
+		case 'UseLocal':
+			global $wgLDAPUseLocal;
+			return $wgLDAPUseLocal;
+		case 'EncryptionType':
+			global $wgLDAPEncryptionType;
+			return self::setOrDefault( $wgLDAPEncryptionType, $domain, 'tls' );
+		case 'Options':
+			global $wgLDAPOptions;
+			return self::setOrDefault( $wgLDAPOptions, $domain, array() );
+		case 'Port':
+			global $wgLDAPPort;
+			if ( isset( $wgLDAPPort[$domain] ) ) {
+				$this->printDebug( "Using non-standard port: " . $wgLDAPPort[$domain], \
SENSITIVE ); +				return (string)$wgLDAPPort[$domain];
+			} elseif ( $this->getConf( 'EncryptionType' ) == 'ssl' ) {
+				return "636";
+			} else {
+				return "389";
+			}
+		case 'SearchString':
+			global $wgLDAPSearchStrings;
+			return self::setOrDefault( $wgLDAPSearchStrings, $domain );
+		case 'ProxyAgent':
+			global $wgLDAPProxyAgent;
+			return self::setOrDefault( $wgLDAPProxyAgent, $domain );
+		case 'ProxyAgentPassword':
+			global $wgLDAPProxyAgentPassword;
+			return self::setOrDefault( $wgLDAPProxyAgentPassword, $domain );
+		case 'SearchAttribute':
+			global $wgLDAPSearchAttributes;
+			return self::setOrDefault( $wgLDAPSearchAttributes, $domain );
+		case 'BaseDN':
+			global $wgLDAPBaseDNs;
+			return self::setOrDefault( $wgLDAPBaseDNs, $domain );
+		case 'GroupBaseDN':
+			global $wgLDAPGroupBaseDNs;
+			return self::setOrDefault( $wgLDAPGroupBaseDNs, $domain );
+		case 'UserBaseDN':
+			global $wgLDAPUserBaseDNs;
+			return self::setOrDefault( $wgLDAPUserBaseDNs, $domain );
+		case 'WriterDN':
+			global $wgLDAPWriterDN;
+			return self::setOrDefault( $wgLDAPWriterDN, $domain );
+		case 'WriterPassword':
+			global $wgLDAPWriterPassword;
+			return self::setOrDefault( $wgLDAPWriterPassword, $domain );
+		case 'WriteLocation':
+			global $wgLDAPWriteLocation;
+			return self::setOrDefault( $wgLDAPWriteLocation, $domain );
+		case 'AddLDAPUsers':
+			global $wgLDAPAddLDAPUsers;
+			return self::setOrDefault( $wgLDAPAddLDAPUsers, $domain, false );
+		case 'UpdateLDAP':
+			global $wgLDAPUpdateLDAP;
+			return self::setOrDefault( $wgLDAPUpdateLDAP, $domain, false );
+		case 'PasswordHash':
+			global $wgLDAPPasswordHash;
+			return self::setOrDefault( $wgLDAPPasswordHash, $domain, 'clear' );
+		case 'MailPassword':
+			global $wgLDAPMailPassword;
+			return self::setOrDefault( $wgLDAPMailPassword, $domain, false );
+		case 'Preferences':
+			global $wgLDAPPreferences;
+			return self::setOrDefault( $wgLDAPPreferences, $domain, array() );
+		case 'DisableAutoCreate':
+			global $wgLDAPDisableAutoCreate;
+			return self::setOrDefault( $wgLDAPDisableAutoCreate, $domain, false );
+		case 'GroupUseFullDN':
+			global $wgLDAPGroupUseFullDN;
+			return self::setOrDefault( $wgLDAPGroupUseFullDN, $domain, false );
+		case 'LowerCaseUsername':
+			global $wgLDAPLowerCaseUsername;
+			if ( isset( $wgLDAPLowerCaseUsername[$domain] ) ) {
+				$this->printDebug( "Configuration set to lowercase username.", \
NONSENSITIVE ); +				return $wgLDAPLowerCaseUsername[$domain];
+			} else {
+				return false;
+			}
+		case 'LowerCaseUsernameScheme':
+			global $wgLDAPLowerCaseUsernameScheme;
+			// Default set to true for backwards compatibility with
+			// versions < 2.0a
+			return self::setOrDefault( $wgLDAPLowerCaseUsernameScheme, $domain, \
true ); +		case 'GroupUseRetrievedUsername':
+			global $wgLDAPGroupUseRetrievedUsername;
+			return self::setOrDefault( $wgLDAPGroupUseRetrievedUsername, $domain, \
false ); +		case 'GroupObjectclass':
+			global $wgLDAPGroupObjectclass;
+			return self::setOrDefault( $wgLDAPGroupObjectclass, $domain );
+		case 'GroupAttribute':
+			global $wgLDAPGroupAttribute;
+			return self::setOrDefault( $wgLDAPGroupAttribute, $domain );
+		case 'GroupNameAttribute':
+			global $wgLDAPGroupNameAttribute;
+			return self::setOrDefault( $wgLDAPGroupNameAttribute, $domain );
+		case 'GroupsUseMemberOf':
+			global $wgLDAPGroupsUseMemberOf;
+			return self::setOrDefault( $wgLDAPGroupsUseMemberOf, $domain, false );
+		case 'UseLDAPGroups':
+			global $wgLDAPUseLDAPGroups;
+			return self::setOrDefault( $wgLDAPUseLDAPGroups, $domain, false );
+		case 'LocallyManagedGroups':
+			global $wgLDAPLocallyManagedGroups;
+			return self::setOrDefault( $wgLDAPLocallyManagedGroups, $domain, \
array() ); +		case 'GroupsPrevail':
+			global $wgLDAPGroupsPrevail;
+			return self::setOrDefault( $wgLDAPGroupsPrevail, $domain, false );
+		case 'RequiredGroups':
+			global $wgLDAPRequiredGroups;
+			return self::setOrDefault( $wgLDAPRequiredGroups, $domain, array() );
+		case 'ExcludedGroups':
+			global $wgLDAPExcludedGroups;
+			return self::setOrDefault( $wgLDAPExcludedGroups, $domain, array() );
+		case 'GroupSearchNestedGroups':
+			global $wgLDAPGroupSearchNestedGroups;
+			return self::setOrDefault( $wgLDAPGroupSearchNestedGroups, $domain, \
false ); +		case 'AuthAttribute':
+			global $wgLDAPAuthAttribute;
+			return self::setOrDefault( $wgLDAPAuthAttribute, $domain );
+		case 'AutoAuthUsername':
+			global $wgLDAPAutoAuthUsername;
+			return $wgLDAPAutoAuthUsername;
+		case 'AutoAuthDomain':
+			global $wgLDAPAutoAuthDomain;
+			return $wgLDAPAutoAuthDomain;
+		}
+		return '';
+	}
+
+	/**
+	 * Returns the item from $array at index $key if it is set,
+	 * else, it returns $default
+	 *
+	 * @param $array array
+	 * @param $key
+	 * @param $default mixed
+	 * @return mixed
+	 */
+	private static function setOrDefault( $array, $key, $default = '' ) {
+		return isset( $array[$key] ) ? $array[$key] : $default;
+	}
+
 	/**
 	 * Check whether there exists a user account with the given name.
 	 * The name will be normalized to MediaWiki's requirements, so
@@ -150,85 +491,62 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 *
 	 * @param string $username
 	 * @return bool
-	 * @access public
 	 */
-	function userExists( $username ) {
-		global $wgLDAPAddLDAPUsers;
-
+	public function userExists( $username ) {
 		$this->printDebug( "Entering userExists", NONSENSITIVE );
 
 		// If we can't add LDAP users, we don't really need to check
 		// if the user exists, the authenticate method will do this for
 		// us. This will decrease hits to the LDAP server.
 		// We do however, need to use this if we are using auto authentication.
-		if ( ( !isset( $wgLDAPAddLDAPUsers[$_SESSION['wsDomain']] ) || \
!$wgLDAPAddLDAPUsers[$_SESSION['wsDomain']] ) && !$this->useAutoAuth() ) { \
+		if ( !$this->getConf( 'AddLDAPUsers' ) && !$this->useAutoAuth() ) {  \
return true;  }
 
-		$this->ldapconn = $this->connect();
-		if ( $this->ldapconn ) {
-			$this->printDebug( "Successfully connected", NONSENSITIVE );
-
-			$searchstring = $this->getSearchString( $this->ldapconn, $username );
+		$ret = false;
+		if ( $this->connect() ) {
+			$searchstring = $this->getSearchString( $username );
 
 			// If we are using auto authentication, and we got
 			// anything back, then the user exists.
 			if ( $this->useAutoAuth() && $searchstring != '' ) {
-				// getSearchString is going to bind, but will not unbind
-				// Let's clean up
-				@ldap_unbind();
-				return true;
-			}
-
-			// Search for the entry.
-			$entry = @ldap_read( $this->ldapconn, $searchstring, "objectclass=*" );
-
-			// getSearchString is going to bind, but will not unbind
-			// Let's clean up
-			@ldap_unbind();
-			if ( !$entry ) {
-				$this->printDebug( "Did not find a matching user in LDAP", \
                NONSENSITIVE );
-				return false;
+				$ret = true;
 			} else {
-				$this->printDebug( "Found a matching user in LDAP", NONSENSITIVE );
-				return true;
+				// Search for the entry.
+				$entry = LdapAuthenticationPlugin::ldap_read( $this->ldapconn, \
$searchstring, "objectclass=*" ); +
+				if ( $entry ) {
+					$this->printDebug( "Found a matching user in LDAP", NONSENSITIVE );
+					$ret = true;
+				} else {
+					$this->printDebug( "Did not find a matching user in LDAP", \
NONSENSITIVE ); +				}
 			}
-		} else {
-			$this->printDebug( "Failed to connect", NONSENSITIVE );
-			return false;
-		}	
+			// getSearchString is going to bind, but will not unbind
+			LdapAuthenticationPlugin::ldap_unbind( $this->ldapconn );
+		}
+		return $ret;
 	}
 
 	/**
 	 * Connect to LDAP
-	 *
-	 * @access private
+	 * @param string $domain
+	 * @return bool
 	 */
-	function connect() {
-		global $wgLDAPServerNames;
-		global $wgLDAPPort;
-		global $wgLDAPEncryptionType;
-		global $wgLDAPOptions;
-
+	public function connect( $domain='' ) {
 		$this->printDebug( "Entering Connect", NONSENSITIVE );
-		
+
 		if ( !function_exists( 'ldap_connect' ) ) {
-			$this->printDebug( "It looks like you are missing LDAP support; please \
ensure you have either compiled LDAP support in, or have enabled the \
module. If the authentication is working for you, the plugin isn't properly \
detecting the LDAP module, and you can safely ignore this message.", \
NONSENSITIVE ); +			$this->printDebug( "It looks like you are missing LDAP \
support; please ensure you have either compiled LDAP " +				. "support in, \
or have enabled the module. If the authentication is working for you, the \
plugin isn't properly " +				. "detecting the LDAP module, and you can \
safely ignore this message.", NONSENSITIVE );  return false;
 		}
 
-		// If the admin didn't set an encryption type, we default to tls
-		if ( isset( $wgLDAPEncryptionType[$_SESSION['wsDomain']] ) ) {
-			$encryptionType = $wgLDAPEncryptionType[$_SESSION['wsDomain']];
-		} else {
-			$encryptionType = "tls";
-		}
-
 		// Set the server string depending on whether we use ssl or not
+		$encryptionType = $this->getConf( 'EncryptionType', $domain );
 		switch( $encryptionType ) {
 			case "ldapi":
-				# this is a really dirty place to put this,
-				# but it is easy and avoids another config option.
 				$this->printDebug( "Using ldapi", SENSITIVE );
 				$serverpre = "ldapi://";
 				break;
@@ -241,18 +559,13 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 				$serverpre = "ldap://";
 		}
 
-		// Make a space separated list of server strings with the ldap:// or \
ldaps:// +		// Make a space separated list of server strings with the \
connection type  // string added.
 		$servers = "";
-		$tmpservers = $wgLDAPServerNames[$_SESSION['wsDomain']];
+		$tmpservers = $this->getConf( 'ServerNames', $domain );
 		$tok = strtok( $tmpservers, " " );
 		while ( $tok ) {
-			if ( isset( $wgLDAPPort[$_SESSION['wsDomain']] ) ) {
-				$this->printDebug( "Using non-standard port: " . \
                $wgLDAPPort[$_SESSION['wsDomain']], SENSITIVE );
-				$servers = $servers . " " . $serverpre . $tok . ":" . \
                $wgLDAPPort[$_SESSION['wsDomain']];
-			} else {
-				$servers = $servers . " " . $serverpre . $tok;
-			}
+			$servers = $servers . " " . $serverpre . $tok . ":" . $this->getConf( \
'Port', $domain );  $tok = strtok( " " );
 		}
 		$servers = rtrim( $servers );
@@ -260,27 +573,31 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 		$this->printDebug( "Using servers: $servers", SENSITIVE );
 
 		// Connect and set options
-		$this->ldapconn = @ldap_connect( $servers );
+		$this->ldapconn = LdapAuthenticationPlugin::ldap_connect( $servers );
+		if ( !$this->ldapconn ) {
+			$this->printDebug( "PHP's LDAP connect method returned null, this \
likely implies a misconfiguration of the plugin.", NONSENSITIVE ); \
+			return false; +		}
 		ldap_set_option( $this->ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3 );
 		ldap_set_option( $this->ldapconn, LDAP_OPT_REFERRALS, 0 );
 
-		if ( isset( $wgLDAPOptions[$_SESSION['wsDomain']] ) ) {
-			$options = $wgLDAPOptions[$_SESSION['wsDomain']];
-			foreach ( $options as $key => $value ) {
-				if ( !ldap_set_option( $this->ldapconn, constant( $key ), $value ) ) {
-					$this->printDebug( "Can't set option to LDAP! Option code and value: \
                " . $key . "=" . $value, 1 );
-				}
+		foreach ( $this->getConf( 'Options' )  as $key => $value ) {
+			if ( !ldap_set_option( $this->ldapconn, constant( $key ), $value ) ) {
+				$this->printDebug( "Can't set option to LDAP! Option code and value: " \
. $key . "=" . $value, 1 );  }
 		}
 
-		// TLS needs to be started after the connection is made
+		// TLS needs to be started after the connection resource is available
 		if ( $encryptionType == "tls" ) {
 			$this->printDebug( "Using TLS", SENSITIVE );
 			if ( !ldap_start_tls( $this->ldapconn ) ) {
 				$this->printDebug( "Failed to start TLS.", SENSITIVE );
-				return;
+				return false;
 			}
 		}
+		$this->printDebug( "PHP's LDAP connect method returned true (note, this \
does not imply it connected to the server).", NONSENSITIVE ); +
+		return true;
 	}
 
 	/**
@@ -293,18 +610,12 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * @param string $username
 	 * @param string $password
 	 * @return bool
-	 * @access public
 	 */
-	function authenticate( $username, $password = '' ) {
-		global $wgLDAPAuthAttribute;
-		global $wgLDAPAutoAuthUsername;
-		global $wgLDAPLowerCaseUsername;
-		global $wgLDAPSearchStrings;
-
-		$this->printDebug( "Entering authenticate", NONSENSITIVE );
+	public function authenticate( $username, $password = '' ) {
+		$this->printDebug( "Entering authenticate for username $username", \
NONSENSITIVE );  
 		// We don't handle local authentication
-		if ( 'local' == $_SESSION['wsDomain'] ) {
+		if ( 'local' == $this->getDomain() ) {
 			$this->printDebug( "User is using a local domain", SENSITIVE );
 			return false;
 		}
@@ -312,31 +623,27 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 		// If the user is using auto authentication, we need to ensure
 		// that he/she isn't trying to fool us by sending a username other
 		// than the one the web server got from the auto-authentication method.
-		if ( $this->useAutoAuth() && $wgLDAPAutoAuthUsername != $username ) {
-			$this->printDebug( "The username provided ($username) doesn't match the \
username provided by the webserver ($wgLDAPAutoAuthUsername). The user is \
probably trying to log in to the auto-authentication domain with password \
authentication via the wiki. Denying access.", SENSITIVE ); +		if ( \
$this->useAutoAuth() && $this->getConf( 'AutoAuthUsername' ) != $username ) \
{ +			$this->printDebug( "The username provided ($username) doesn't match \
the username provided by the webserver (" . $this->getConf( \
'AutoAuthUsername' ) . "). The user is probably trying to log in to the \
auto-authentication domain with password authentication via the wiki. \
Denying access.", SENSITIVE );  return false;
 		}
 
 		// We need to ensure that if we require a password, that it is
 		// not blank. We don't allow blank passwords, so we are being
 		// tricked if someone is supplying one when using password auth.
-		// Smartcard authentication uses a pin, and does not require
-		// a password to be given; a blank password here is wanted.
+		// auto-authentication is handled by the webserver; a blank password
+		// here is wanted.
 		if ( '' == $password && !$this->useAutoAuth() ) {
 			$this->printDebug( "User used a blank password", NONSENSITIVE );
 			return false;
 		}
 
-		$this->connect();
-		if ( $this->ldapconn ) {
-			$this->printDebug( "Connected successfully", NONSENSITIVE );
-
+		if ( $this->connect() ) {
 			// Mediawiki munges the username before authenticate is called,
 			// this can mess with authentication, group pulling/restriction,
 			// preference pulling, etc. Let's allow the admin to use
 			// a lowercased username if needed.
-			if ( isset( $wgLDAPLowerCaseUsername[$_SESSION['wsDomain']] ) && \
                $wgLDAPLowerCaseUsername[$_SESSION['wsDomain']] ) {
-				$this->printDebug( "Lowercasing the username: $username", NONSENSITIVE \
); +			if ( $this->getConf( 'LowerCaseUsername') ) {
 				$username = strtolower( $username );
 			}
 
@@ -347,7 +654,7 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 			// return true, and will let anyone in!
 			if ( '' == $this->userdn ) {
 				$this->printDebug( "User DN is blank", NONSENSITIVE );
-				@ldap_unbind();
+				LdapAuthenticationPlugin::ldap_unbind( $this->ldapconn );
 				$this->markAuthFailed();
 				return false;
 			}
@@ -356,65 +663,62 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 			// user to make sure the password is correct.
 			if ( !$this->useAutoAuth() ) {
 				$this->printDebug( "Binding as the user", NONSENSITIVE );
-
-				// Let's see if the user can authenticate.
 				$bind = $this->bindAs( $this->userdn, $password );
 				if ( !$bind ) {
 					$this->markAuthFailed();
 					return false;
 				}
+				$result = true;
+				wfRunHooks( 'ChainAuth', array( $username, $password, &$result ) );
+				if ( $result == false ) {
+					return false;
+				}
 
 				$this->printDebug( "Bound successfully", NONSENSITIVE );
 
-				if ( isset( $wgLDAPSearchStrings[$_SESSION['wsDomain']] ) ) {
-					$ss = $wgLDAPSearchStrings[$_SESSION['wsDomain']];
+				$ss = $this->getConf( 'SearchString' );
+				if ( $ss ) {
 					if ( strstr( $ss, "@" ) || strstr( $ss, '\\' ) ) {
 						// We are most likely configured using USER-NAME@DOMAIN, or
 						// DOMAIN\\USER-NAME.
 						// Get the user's full DN so we can search for groups and such.
 						$this->userdn = $this->getUserDN( $username );
-						$this->printDebug( "Pulled the user's DN: $this->userdn", \
NONSENSITIVE ); +						$this->printDebug( "Fetched UserDN: $this->userdn", \
NONSENSITIVE ); +					} else {
+						// Now that we are bound, we can pull the user's info.
+						$this->getUserInfo();
 					}
 				}
+			}
 
-				if ( isset( $wgLDAPAuthAttribute[$_SESSION['wsDomain']] ) ) {
-
-					$this->printDebug( "Checking for auth attributes", NONSENSITIVE );
-
-					$filter = "(" . $wgLDAPAuthAttribute[$_SESSION['wsDomain']] . ")";
-					$attributes = array( "dn" );
-
-					$entry = ldap_read( $this->ldapconn, $this->userdn, $filter, \
                $attributes );
-					$info = ldap_get_entries( $this->ldapconn, $entry );
-
-					if ( $info["count"] < 1 ) {
-						$this->printDebug( "Failed auth attribute check", NONSENSITIVE );
-						@ldap_unbind();
-						$this->markAuthFailed();
-						return false;
-					}
+			// Ensure the user's entry has the required auth attribute
+			$aa = $this->getConf( 'AuthAttribute' ); 
+			if ( $aa ) {
+				$this->printDebug( "Checking for auth attributes: $aa", NONSENSITIVE \
); +				$filter = "(" . $aa . ")";
+				$attributes = array( "dn" );
+				$entry = LdapAuthenticationPlugin::ldap_read( $this->ldapconn, \
$this->userdn, $filter, $attributes ); +				$info = \
LdapAuthenticationPlugin::ldap_get_entries( $this->ldapconn, $entry ); \
+				if ( $info["count"] < 1 ) { +					$this->printDebug( "Failed auth \
attribute check", NONSENSITIVE ); \
+					LdapAuthenticationPlugin::ldap_unbind( $this->ldapconn ); \
+					$this->markAuthFailed(); +					return false;
 				}
 			}
 
 			$this->getGroups( $username );
 
 			if ( !$this->checkGroups( $username ) ) {
-				@ldap_unbind();
+				LdapAuthenticationPlugin::ldap_unbind( $this->ldapconn );
 				$this->markAuthFailed();
 				return false;
 			}
 
 			$this->getPreferences();
 
-			if ( !$this->synchUsername( $username ) ) {
-				@ldap_unbind();
-				$this->markAuthFailed();
-				return false;
-			}
-
-			@ldap_unbind();
+			LdapAuthenticationPlugin::ldap_unbind( $this->ldapconn );
 		} else {
-			$this->printDebug( "Failed to connect", NONSENSITIVE );
 			$this->markAuthFailed();
 			return false;
 		}
@@ -432,38 +736,42 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * Modify options in the login template.
 	 *
 	 * @param UserLoginTemplate $template
-	 * @access public
+	 * @param $type
 	 */
-	function modifyUITemplate( &$template ) {
-		global $wgLDAPDomainNames, $wgLDAPUseLocal;
-		global $wgLDAPAddLDAPUsers;
-		global $wgLDAPAutoAuthDomain;
-		global $wgLDAPMailPassword;
-
+	public function modifyUITemplate( &$template, &$type ) {
 		$this->printDebug( "Entering modifyUITemplate", NONSENSITIVE );
-
-		if ( !isset( $wgLDAPAddLDAPUsers[$_SESSION['wsDomain']] ) || \
                !$wgLDAPAddLDAPUsers[$_SESSION['wsDomain']] ) {
-			$template->set( 'create', false );
-		}
-
+		$template->set( 'create', $this->getConf( 'AddLDAPUsers' ) );
 		$template->set( 'usedomain', true );
-		$template->set( 'useemail', isset( \
$wgLDAPMailPassword[$_SESSION['wsDomain']] ) && \
$wgLDAPMailPassword[$_SESSION['wsDomain']] );	 +		$template->set( \
'useemail', $this->getConf( 'MailPassword' ) ); +		$template->set( \
'canreset', $this->getConf( 'MailPassword' ) ); +		$template->set( \
'domainnames', $this->domainList() ); +		wfRunHooks( \
'LDAPModifyUITemplate', array( &$template ) ); +	}
+
+	/**
+	 * @return array
+	 */
+	function domainList() {
+		global $wgLDAPDomainNames;
 
 		$tempDomArr = $wgLDAPDomainNames;
-		if ( $wgLDAPUseLocal ) {
+		if ( $this->getConf( 'UseLocal' ) ) {
 			$this->printDebug( "Allowing the local domain, adding it to the list.", \
NONSENSITIVE );  array_push( $tempDomArr, 'local' );
 		}
 
-		if ( isset( $wgLDAPAutoAuthDomain ) && $wgLDAPAutoAuthDomain != "" ) {
+		if ( $this->getConf( 'AutoAuthDomain' ) ) {
 			$this->printDebug( "Allowing auto-authentication login, removing the \
                domain from the list.", NONSENSITIVE );
-
 			// There is no reason for people to log in directly to the wiki if the \
are using an  // auto-authentication domain. If they try to, they are \
                probably up to something fishy.
-			unset( $tempDomArr[array_search( $wgLDAPAutoAuthDomain, $tempDomArr )] \
); +			unset( $tempDomArr[array_search( $this->getConf( 'AutoAuthDomain' ), \
$tempDomArr )] );  }
 
-		$template->set( 'domainnames', $tempDomArr );
+		$domains = array();
+		foreach ( $tempDomArr as $tempDom ) {
+			$domains["$tempDom"] = $tempDom;
+		}
+		return $domains;
 	}
 
 	/**
@@ -474,12 +782,9 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * This is just a question, and shouldn't perform any actions.
 	 *
 	 * @return bool
-	 * @access public
 	 */
-	function autoCreate() {
-		global $wgLDAPDisableAutoCreate;
-
-		return !( isset( $wgLDAPDisableAutoCreate[$_SESSION['wsDomain']] ) && \
$wgLDAPDisableAutoCreate[$_SESSION['wsDomain']] ); +	public function \
autoCreate() { +		return !$this->getConf( 'DisableAutoCreate' );
 	}
 
 	/**
@@ -489,68 +794,56 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * @param User $user
 	 * @param string $password
 	 * @return bool
-	 * @access public
 	 */
-	function setPassword( $user, &$password ) {
-		global $wgLDAPUpdateLDAP, $wgLDAPWriterDN, $wgLDAPWriterPassword;
-
+	public function setPassword( $user, $password ) {
 		$this->printDebug( "Entering setPassword", NONSENSITIVE );
 
-		if ( $_SESSION['wsDomain'] == 'local' ) {
+		if ( $this->getDomain() == 'local' ) {
 			$this->printDebug( "User is using a local domain", NONSENSITIVE );
 
 			// We don't set local passwords, but we don't want the wiki
-			// to send the user a failure.		
+			// to send the user a failure.
 			return true;
-		} else if ( !isset( $wgLDAPUpdateLDAP[$_SESSION['wsDomain']] ) || \
!$wgLDAPUpdateLDAP[$_SESSION['wsDomain']] ) { +		}
+		if ( !$this->getConf( 'UpdateLDAP' ) ) {
 			$this->printDebug( "Wiki is set to not allow updates", NONSENSITIVE );
 
 			// We aren't allowing the user to change his/her own password
 			return false;
 		}
 
-		if ( !isset( $wgLDAPWriterDN[$_SESSION['wsDomain']] ) ) {
+		$writer = $this->getConf( 'WriterDN' );
+		if ( !$writer ) {
 			$this->printDebug( "Wiki doesn't have wgLDAPWriterDN set", NONSENSITIVE \
);  
 			// We can't change a user's password without an account that is
 			// allowed to do it.
 			return false;
 		}
-
 		$pass = $this->getPasswordHash( $password );
 
-		$this->connect();
-		if ( $this->ldapconn ) {
-			$this->printDebug( "Connected successfully", NONSENSITIVE );
+		if ( $this->connect() ) {
 			$this->userdn = $this->getSearchString( $user->getName() );
-
 			$this->printDebug( "Binding as the writerDN", NONSENSITIVE );
-			$bind = $this->bindAs( $wgLDAPWriterDN[$_SESSION['wsDomain']], \
$wgLDAPWriterPassword[$_SESSION['wsDomain']] ); +			$bind = $this->bindAs( \
$writer, $this->getConf( 'WriterPassword' ) );  if ( !$bind ) {
 				return false;
 			}
-
 			$values["userpassword"] = $pass;
 
 			// Blank out the password in the database. We don't want to save
 			// domain credentials for security reasons.
 			$password = '';
 
-			$success = @ldap_modify( $this->ldapconn, $this->userdn, $values );
-
-			// Let's clean up
-			@ldap_unbind();
+			$success = LdapAuthenticationPlugin::ldap_modify( $this->ldapconn, \
$this->userdn, $values ); +			LdapAuthenticationPlugin::ldap_unbind( \
$this->ldapconn );  if ( $success ) {
 				$this->printDebug( "Successfully modified the user's password", \
NONSENSITIVE );  return true;
-			} else {
-				$this->printDebug( "Failed to modify the user's password", \
                NONSENSITIVE );
-				return false;
 			}
-		} else {
-			$this->printDebug( "Failed to connect", NONSENSITIVE );
-			return false;
+			$this->printDebug( "Failed to modify the user's password", NONSENSITIVE \
);  }
+		return false;
 	}
 
 	/**
@@ -559,26 +852,21 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 *
 	 * @param User $user
 	 * @return bool
-	 * @access public
 	 */
-	function updateExternalDB( $user ) {
-		global $wgLDAPUpdateLDAP;
-		global $wgLDAPWriterDN, $wgLDAPWriterPassword;
+	public function updateExternalDB( $user ) {
+		global $wgMemc;
 
 		$this->printDebug( "Entering updateExternalDB", NONSENSITIVE );
-
-		if ( ( !isset( $wgLDAPUpdateLDAP[$_SESSION['wsDomain']] ) || \
                !$wgLDAPUpdateLDAP[$_SESSION['wsDomain']] ) ||
-			$_SESSION['wsDomain'] == 'local' ) {
+		if ( !$this->getConf( 'UpdateLDAP' ) || $this->getDomain() == 'local' ) \
{  $this->printDebug( "Either the user is using a local domain, or the wiki \
                isn't allowing updates", NONSENSITIVE );
-
 			// We don't handle local preferences, but we don't want the
 			// wiki to return an error.
 			return true;
 		}
 
-		if ( !isset( $wgLDAPWriterDN[$_SESSION['wsDomain']] ) ) {
+		$writer = $this->getConf( 'WriterDN' );
+		if ( !$writer ) {
 			$this->printDebug( "The wiki doesn't have wgLDAPWriterDN set", \
                NONSENSITIVE );
-
 			// We can't modify LDAP preferences if we don't have a user
 			// capable of editing LDAP attributes.
 			return false;
@@ -588,36 +876,32 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 		$this->realname = $user->getRealName();
 		$this->nickname = $user->getOption( 'nickname' );
 		$this->lang = $user->getOption( 'language' );
-
-		$this->connect();
-		if ( $this->ldapconn ) {
-			$this->printDebug( "Connected successfully", NONSENSITIVE );
+		if ( $this->connect() ) {
 			$this->userdn = $this->getSearchString( $user->getName() );
-
 			$this->printDebug( "Binding as the writerDN", NONSENSITIVE );
-			$bind = $this->bindAs( $wgLDAPWriterDN[$_SESSION['wsDomain']], \
$wgLDAPWriterPassword[$_SESSION['wsDomain']] ); +			$bind = $this->bindAs( \
$writer, $this->getConf( 'WriterPassword' ) );  if ( !$bind ) {
 				return false;
 			}
 
-			if ( '' != $this->email ) { $values["mail"] = $this->email; }
-			if ( '' != $this->nickname ) { $values["displayname"] = \
                $this->nickname; }
-			if ( '' != $this->realname ) { $values["cn"] = $this->realname; }
-			if ( '' != $this->lang ) { $values["preferredlanguage"] = $this->lang; \
} +			$values = array();
+			if ( is_string( $this->email ) ) { $values["mail"] = $this->email; }
+			if ( is_string( $this->nickname ) ) { $values["displayname"] = \
$this->nickname; } +			if ( is_string( $this->realname ) ) { $values["cn"] \
= $this->realname; } +			if ( is_string( $this->lang ) ) { \
$values["preferredlanguage"] = $this->lang; }  
-			if ( 0 != sizeof( $values ) && @ldap_modify( $this->ldapconn, \
$this->userdn, $values ) ) { +			if ( count( $values ) && \
LdapAuthenticationPlugin::ldap_modify( $this->ldapconn, $this->userdn, \
$values ) ) { +				// We changed the user, we need to invalidate the \
memcache key +				$key = wfMemcKey( 'ldapauthentication', 'userinfo', \
$this->userdn ); +				$wgMemc->delete( $key );
 				$this->printDebug( "Successfully modified the user's attributes", \
                NONSENSITIVE );
-				@ldap_unbind();
+				LdapAuthenticationPlugin::ldap_unbind( $this->ldapconn );
 				return true;
-			} else {
-				$this->printDebug( "Failed to modify the user's attributes", \
                NONSENSITIVE );
-				@ldap_unbind();
-				return false;
 			}
-		} else {
-			$this->printDebug( "Failed to Connect", NONSENSITIVE );
-			return false;
+			$this->printDebug( "Failed to modify the user's attributes", \
NONSENSITIVE ); +			LdapAuthenticationPlugin::ldap_unbind( $this->ldapconn \
);  }
+		return false;
 	}
 
 	/**
@@ -625,12 +909,9 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * Return true if yes.
 	 *
 	 * @return bool
-	 * @access public
 	 */
-	function canCreateAccounts() {
-		global $wgLDAPAddLDAPUsers;
-
-		return ( isset( $wgLDAPAddLDAPUsers[$_SESSION['wsDomain']] ) && \
$wgLDAPAddLDAPUsers[$_SESSION['wsDomain']] ); +	public function \
canCreateAccounts() { +		return $this->getConf( 'AddLDAPUsers' );
 	}
 
 	/**
@@ -639,30 +920,33 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * Return true if yes.
 	 *
 	 * @return bool
-	 * @access public
 	 */
-	function allowPasswordChange() {
-		global $wgLDAPUpdateLDAP, $wgLDAPMailPassword;
-		global $wgLDAPUseLocal;
-
+	public function allowPasswordChange() {
 		$this->printDebug( "Entering allowPasswordChange", NONSENSITIVE );
 
-		$retval = false;
-
 		// Local domains need to be able to change passwords
-		if ( ( isset( $wgLDAPUseLocal ) && $wgLDAPUseLocal ) && 'local' == \
                $_SESSION['wsDomain'] ) {
-			$retval = true;
+		if ( $this->getConf( 'UseLocal' ) && 'local' == $this->getDomain() ) {
+			return true;
 		}
-
-		if ( isset( $wgLDAPUpdateLDAP[$_SESSION['wsDomain']] ) && \
                $wgLDAPUpdateLDAP[$_SESSION['wsDomain']] ) {
-			$retval = true;
+		if ( $this->getConf( 'UpdateLDAP' ) || $this->getConf( 'MailPassword' ) \
) { +			return true;
 		}
+		return false;
+	}
 
-		if ( isset( $wgLDAPMailPassword[$_SESSION['wsDomain']] ) && \
                $wgLDAPMailPassword[$_SESSION['wsDomain']] ) {
-			$retval = true;
-		}
+	/**
+	 * Disallow MediaWiki from setting local passwords in the database,
+	 * unless $wgLDAPUseLocal is true. Warning: if you set $wgLDAPUseLocal,
+	 * it will cause MediaWiki to leak LDAP passwords into the local \
database. +	 */
+	public function allowSetLocalPassword() {
+		global $wgLDAPUseLocal;
 
-		return $retval;
+		if ( $wgLDAPUseLocal ) {
+			return true;
+		} else {
+			return false;
+		}
 	}
 
 	/**
@@ -671,27 +955,20 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 *
 	 * @param User $user
 	 * @param string $password
+	 * @param string $email
+	 * @param string $realname
 	 * @return bool
-	 * @access public
 	 */
-	function addUser( $user, $password ) {
-		global $wgLDAPAddLDAPUsers, $wgLDAPWriterDN, $wgLDAPWriterPassword;
-		global $wgLDAPSearchAttributes;
-		global $wgLDAPWriteLocation;
-		global $wgLDAPRequiredGroups, $wgLDAPGroupDN;
-		global $wgLDAPAuthAttribute;
-
+	public function addUser( $user, $password, $email = '', $realname = '' ) \
{  $this->printDebug( "Entering addUser", NONSENSITIVE );
 
-		if ( ( !isset( $wgLDAPAddLDAPUsers[$_SESSION['wsDomain']] ) || \
                !$wgLDAPAddLDAPUsers[$_SESSION['wsDomain']] ) ||
-			'local' == $_SESSION['wsDomain'] ) {
+		if ( !$this->getConf( 'AddLDAPUsers' ) || 'local' == $this->getDomain() \
) {  $this->printDebug( "Either the user is using a local domain, or the \
wiki isn't allowing users to be added to LDAP", NONSENSITIVE );  
 			// Tell the wiki not to return an error.
 			return true;
 		}
-
-		if ( $wgLDAPRequiredGroups || $wgLDAPGroupDN ) {
+		if ( $this->getConf( 'RequiredGroups' ) ) {
 			$this->printDebug( "The wiki is requiring users to be in specific \
groups, and cannot add users as this would be a security hole.", \
NONSENSITIVE );  // It is possible that later we can add users into
 			// groups, but since we don't support it, we don't want
@@ -699,7 +976,8 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 			return false;
 		}
 
-		if ( !isset( $wgLDAPWriterDN[$_SESSION['wsDomain']] ) ) {
+		$writer = $this->getConf( 'WriterDN' );
+		if ( !$writer ) {
 			$this->printDebug( "The wiki doesn't have wgLDAPWriterDN set", \
NONSENSITIVE );  
 			// We can't add users without an LDAP account capable of doing so.
@@ -709,196 +987,210 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 		$this->email = $user->getEmail();
 		$this->realname = $user->getRealName();
 		$username = $user->getName();
-
+		if ( $this->getConf( 'LowerCaseUsernameScheme' ) ) {
+			$username = strtolower( $username );
+		}
 		$pass = $this->getPasswordHash( $password );
-
-		$this->connect();
-		if ( $this->ldapconn ) {
-			$this->printDebug( "Successfully connected", NONSENSITIVE );
-
+		if ( $this->connect() ) {
+			$writeloc = $this->getConf( 'WriteLocation' );
 			$this->userdn = $this->getSearchString( $username );
 			if ( '' == $this->userdn ) {
-				$this->printDebug( "$this->userdn is blank, attempting to use \
                wgLDAPWriteLocation", NONSENSITIVE );
-				if ( isset( $wgLDAPWriteLocation[$_SESSION['wsDomain']] ) ) {
+				$this->printDebug( "userdn is blank, attempting to use \
wgLDAPWriteLocation", NONSENSITIVE ); +				if ( $writeloc ) {
 					$this->printDebug( "wgLDAPWriteLocation is set, using that", \
                NONSENSITIVE );
-					$this->userdn = $wgLDAPSearchAttributes[$_SESSION['wsDomain']] . "=" \
                .
-						$username . "," . $wgLDAPWriteLocation[$_SESSION['wsDomain']];
+					$this->userdn = $this->getConf( 'SearchAttribute' ) . "=" .
+						$username . "," . $writeloc;
 				} else {
 					$this->printDebug( "wgLDAPWriteLocation is not set, failing", \
NONSENSITIVE );  // getSearchString will bind, but will not unbind
-					@ldap_unbind();
+					LdapAuthenticationPlugin::ldap_unbind( $this->ldapconn );
 					return false;
 				}
 			}
 
 			$this->printDebug( "Binding as the writerDN", NONSENSITIVE );
-
-			$bind = $this->bindAs( $wgLDAPWriterDN[$_SESSION['wsDomain']], \
$wgLDAPWriterPassword[$_SESSION['wsDomain']] ); +			$bind = $this->bindAs( \
$writer, $this->getConf( 'WriterPassword' ) );  if ( !$bind ) {
 				$this->printDebug( "Failed to bind as the writerDN; add failed", \
NONSENSITIVE );  return false;
 			}
 
-			// Set up LDAP attributes
+			// Set up LDAP objectclasses and attributes
+			// TODO: make objectclasses and attributes configurable
 			$values["uid"] = $username;
 			// sn is required for objectclass inetorgperson
 			$values["sn"] = $username;
-			if ( '' != $this->email ) { $values["mail"] = $this->email; }
-			if ( '' != $this->realname ) { $values["cn"] = $this->realname; }
+			if ( is_string( $this->email ) ) { $values["mail"] = $this->email; }
+			if ( is_string( $this->realname ) ) { $values["cn"] = $this->realname; \
}  else { $values["cn"] = $username; }
 			$values["userpassword"] = $pass;
-			$values["objectclass"] = "inetorgperson";
-
-			if ( isset ( $wgLDAPAuthAttribute[$_SESSION['wsDomain']] ) ) {
-				$values[$wgLDAPAuthAttribute[$_SESSION['wsDomain']]] = "true";
+			$values["objectclass"] = array( "inetorgperson" );
+
+			$result = true;
+			# Let other extensions modify the user object before creation
+			wfRunHooks( 'LDAPSetCreationValues', array( $this, $username, &$values, \
$writeloc, &$this->userdn, &$result ) ); +			if ( !$result ) {
+				$this->printDebug( "Failed to add user because LDAPSetCreationValues \
returned false", NONSENSITIVE ); \
+				LdapAuthenticationPlugin::ldap_unbind( $this->ldapconn ); +				return \
false;  }
 
 			$this->printDebug( "Adding user", NONSENSITIVE );
-			if ( @ldap_add( $this->ldapconn, $this->userdn, $values ) ) {
+			if ( LdapAuthenticationPlugin::ldap_add( $this->ldapconn, \
$this->userdn, $values ) ) {  $this->printDebug( "Successfully added user", \
                NONSENSITIVE );
-				@ldap_unbind();
+				LdapAuthenticationPlugin::ldap_unbind( $this->ldapconn );
 				return true;
-			} else {
-				$this->printDebug( "Failed to add user", NONSENSITIVE );
-				@ldap_unbind();
-				return false;
 			}
-		} else {
-			$this->printDebug( "Failed to connect; add failed", NONSENSITIVE );
-			return false;
+			$errno = LdapAuthenticationPlugin::ldap_errno( $this->ldapconn );
+			# Constraint violation, let's allow other plugins a chance to retry
+			if ( $errno === 19 ) {
+				$result = false;
+				wfRunHooks( 'LDAPRetrySetCreationValues', array( $this, $username, \
&$values, $writeloc, &$this->userdn, &$result ) ); +				if ( $result && \
LdapAuthenticationPlugin::ldap_add( $this->ldapconn, $this->userdn, $values \
) ) { +					$this->printDebug( "Successfully added user", NONSENSITIVE );
+					LdapAuthenticationPlugin::ldap_unbind( $this->ldapconn );
+					return true;
+				}
+			}
+			$this->printDebug( "Failed to add user", NONSENSITIVE );
+			LdapAuthenticationPlugin::ldap_unbind( $this->ldapconn );
 		}
+		return false;
 	}
 
 	/**
 	 * Set the domain this plugin is supposed to use when authenticating.
 	 *
 	 * @param string $domain
-	 * @access public	
 	 */
-	function setDomain( $domain ) {
+	public function setDomain( $domain ) {
 		$this->printDebug( "Setting domain as: $domain", NONSENSITIVE );
 		$_SESSION['wsDomain'] = $domain;
 	}
 
 	/**
+	 * Get the user's domain
+	 *
+	 * @return string
+	 */
+	public function getDomain() {
+		global $wgUser;
+
+		$this->printDebug( "Entering getDomain", NONSENSITIVE );
+
+		# First check if we already have a valid domain set
+		if ( isset( $_SESSION['wsDomain'] ) && $_SESSION['wsDomain'] != \
'invaliddomain' ) { +			$this->printDebug( "Pulling domain from session.", \
NONSENSITIVE ); +			return $_SESSION['wsDomain'];
+		}
+		# If the session domain isn't set, the user may have been logged
+		# in with a token, check the user options.
+		if ( $wgUser->isLoggedIn() && $wgUser->getToken( false ) ) {
+			$this->printDebug( "Pulling domain from user options.", NONSENSITIVE );
+			$domain = self::loadDomain( $wgUser );
+			if ( $domain ) {
+				return $domain;
+			}
+		}
+		# The user must be using an invalid domain
+		$this->printDebug( "No domain found, returning invaliddomain", \
NONSENSITIVE ); +		return 'invaliddomain';
+	}
+
+	/**
 	 * Check to see if the specific domain is a valid domain.
 	 * Return true if the domain is valid.
 	 *
 	 * @param string $domain
 	 * @return bool
-	 * @access public
 	 */
-	function validDomain( $domain ) {
-		global $wgLDAPDomainNames, $wgLDAPUseLocal;
+	public function validDomain( $domain ) {
+		global $wgLDAPDomainNames;
 
 		$this->printDebug( "Entering validDomain", NONSENSITIVE );
-
-		if ( in_array( $domain, $wgLDAPDomainNames ) || ( $wgLDAPUseLocal && \
                'local' == $domain ) ) {
-			$this->printDebug( "User is using a valid domain.", NONSENSITIVE );
+		if ( in_array( $domain, $wgLDAPDomainNames ) || ( $this->getConf( \
'UseLocal' ) && 'local' == $domain ) ) { +			$this->printDebug( "User is \
using a valid domain ($domain).", NONSENSITIVE );  return true;
-		} else {
-			$this->printDebug( "User is not using a valid domain.", NONSENSITIVE );
-			return false;
 		}
+		$this->printDebug( "User is not using a valid domain ($domain).", \
NONSENSITIVE ); +		return false;
 	}
 
 	/**
 	 * When a user logs in, update user with information from LDAP.
 	 *
-	 * @param User $user
-	 * @access public
+	 * @param $user User
 	 * TODO: fix the setExternalID stuff
 	 */
-	function updateUser( &$user ) {
-		global $wgLDAPRetrievePrefs, $wgLDAPPreferences;
-		global $wgLDAPUseLDAPGroups;
-		global $wgLDAPUniqueBlockLogin, $wgLDAPUniqueRenameUser;
-
+	public function updateUser( &$user ) {
 		$this->printDebug( "Entering updateUser", NONSENSITIVE );
-
 		if ( $this->authFailed ) {
 			$this->printDebug( "User didn't successfully authenticate, exiting.", \
NONSENSITIVE );  return;
 		}
 
-		$saveSettings = false;
-
-		// If we aren't pulling preferences, we don't want to accidentally
-		// overwrite anything.
-		if ( ( isset( $wgLDAPRetrievePrefs[$_SESSION['wsDomain']] ) && \
                $wgLDAPRetrievePrefs[$_SESSION['wsDomain']] )
-			|| isset( $wgLDAPPreferences[$_SESSION['wsDomain']] ) ) {
+		if ( $this->getConf( 'Preferences' ) ) {
 			$this->printDebug( "Setting user preferences.", NONSENSITIVE );
-
-			if ( '' != $this->lang ) {
+			if ( is_string( $this->lang ) ) {
 				$this->printDebug( "Setting language.", NONSENSITIVE );
 				$user->setOption( 'language', $this->lang );
 			}
-			if ( '' != $this->nickname ) {
+			if ( is_string( $this->nickname ) ) {
 				$this->printDebug( "Setting nickname.", NONSENSITIVE );
 				$user->setOption( 'nickname', $this->nickname );
 			}
-			if ( '' != $this->realname ) {
+			if ( is_string( $this->realname ) ) {
 				$this->printDebug( "Setting realname.", NONSENSITIVE );
 				$user->setRealName( $this->realname );
 			}
-			if ( '' != $this->email ) {
+			if ( is_string( $this->email ) ) {
 				$this->printDebug( "Setting email.", NONSENSITIVE );
 				$user->setEmail( $this->email );
 				$user->confirmEmail();
 			}
-			if ( ( isset( $wgLDAPUniqueBlockLogin[$_SESSION['wsDomain']] ) && \
                $wgLDAPUniqueBlockLogin[$_SESSION['wsDomain']] )
-				|| ( isset( $wgLDAPUniqueRenameUser[$_SESSION['wsDomain']] ) && \
                $wgLDAPUniqueRenameUser[$_SESSION['wsDomain']] ) ) {
-
-				if ( '' != $this->externalid ) {
-					$user->setExternalID( $this->externalid );
-				}
-			}
-
-			$saveSettings = true;
 		}
 
-		if ( isset( $wgLDAPUseLDAPGroups[$_SESSION['wsDomain']] ) && \
$wgLDAPUseLDAPGroups[$_SESSION['wsDomain']] ) { +		if ( $this->getConf( \
'UseLDAPGroups' ) ) {  $this->printDebug( "Setting user groups.", \
NONSENSITIVE );  $this->setGroups( $user );
-
-			$saveSettings = true;
 		}
 
-		if ( $saveSettings ) {
-			$this->printDebug( "Saving user settings.", NONSENSITIVE );
-			$user->saveSettings();
+		# We must set a user option if we want token based logins to work
+		if ( $user->getToken( false ) ) {
+			$this->printDebug( "User has a token, setting domain in user options.", \
NONSENSITIVE ); +			self::saveDomain( $user, $_SESSION['wsDomain'] );
 		}
+
+		# Let other extensions update the user
+		wfRunHooks( 'LDAPUpdateUser', array( &$user ) );
+
+		$this->printDebug( "Saving user settings.", NONSENSITIVE );
+		$user->saveSettings();
 	}
 
 	/**
 	 * When creating a user account, initialize user with information from \
LDAP. +	 * TODO: fix setExternalID stuff
 	 *
 	 * @param User $user
-	 * @access public
-	 * TODO: fix setExternalID stuff
+	 * @param bool $autocreate
 	 */
-	function initUser( &$user ) {
+	public function initUser( &$user, $autocreate = false ) {
 		$this->printDebug( "Entering initUser", NONSENSITIVE );
 
 		if ( $this->authFailed ) {
 			$this->printDebug( "User didn't successfully authenticate, exiting.", \
                NONSENSITIVE );
-			return;
+			return null;
 		}
-
-		if ( 'local' == $_SESSION['wsDomain'] ) {
+		if ( 'local' == $this->getDomain() ) {
 			$this->printDebug( "User is using a local domain", NONSENSITIVE );
-			return;
+			return null;
 		}
 
-		// We are creating an LDAP user, it is very important that we do
-		// NOT set a local password because it could compromise the
-		// security of our domain.
-		$user->mPassword = '';
-
 		// The update user function does everything else we need done.
 		$this->updateUser( $user );
 
-		// updateUser() won't definately save the user's settings
+		// updateUser() won't necessarily save the user's settings
 		$user->saveSettings();
 	}
 
@@ -909,70 +1201,82 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * This is just a question, and shouldn't perform any actions.
 	 *
 	 * @return bool
-	 * @access public
 	 */
-	function strict() {
-		global $wgLDAPUseLocal, $wgLDAPMailPassword;
-
+	public function strict() {
 		$this->printDebug( "Entering strict.", NONSENSITIVE );
 
-		if ( $wgLDAPUseLocal || ( isset( \
$wgLDAPMailPassword[$_SESSION['wsDomain']] ) && \
$wgLDAPMailPassword[$_SESSION['wsDomain']] ) ) { +		if ( $this->getConf( \
'UseLocal' ) || $this->getConf( 'MailPassword' ) ) {  $this->printDebug( \
"Returning false in strict().", NONSENSITIVE );  return false;
-		} else {
-			$this->printDebug( "Returning true in strict().", NONSENSITIVE );
-			return true;
 		}
+		$this->printDebug( "Returning true in strict().", NONSENSITIVE );
+		return true;
 	}
 
 	/**
-	 * Munge the username to always have a form of uppercase for the first \
                letter,
-	 * and lowercase for the rest of the letters.
+	 * Munge the username based on a scheme (lowercase, by default)
 	 *
 	 * @param string $username
 	 * @return string
-	 * @access public
 	 */
-	function getCanonicalName( $username ) {
-		$this->printDebug( "Entering getCanonicalName", NONSENSITIVE );
+	public function getCanonicalName( $username ) {
+		global $wgMemc;
 
+		$this->printDebug( "Entering getCanonicalName", NONSENSITIVE );
+		$key = wfMemcKey( 'ldapauthentication', 'canonicalname', $username );
+		$canonicalname = $username;
 		if ( $username != '' ) {
-			$this->printDebug( "Username isn't empty.", NONSENSITIVE );
-
-			// We want to use the username returned by LDAP
-			// if it exists
-			if ( $this->LDAPUsername != '' ) {
-				$this->printDebug( "Using LDAPUsername.", NONSENSITIVE );
-				$username = $this->LDAPUsername;
-			}
+			$this->printDebug( "Username is: $username", NONSENSITIVE );
+			if ( $this->getConf( 'LowerCaseUsernameScheme' ) ) {
+				$canonicalname = strtolower( $canonicalname );
+			} else {
+				# Fetch username, so that we can possibly use it.
+				$userInfo = $wgMemc->get( $key );
+				if ( is_array( $userInfo ) ) {
+					$this->printDebug( "Fetched userInfo from memcache.", NONSENSITIVE );
+					if ( $userInfo["username"] == $username ) {
+						$this->printDebug( "Username matched a key in memcache, using the \
fetched name: " . $userInfo["canonicalname"], NONSENSITIVE ); +						return \
$userInfo["canonicalname"]; +					}
+				} else {
+					if ( $this->validDomain( $this->getDomain() ) && $this->connect() ) {
+						// Try to pull the username from LDAP. In the case of straight \
binds, +						// try to fetch the username by search before bind.
+						$this->userdn = $this->getUserDN( $username, true );
+						$hookSetUsername = $this->LDAPUsername;
+						wfRunHooks( 'SetUsernameAttributeFromLDAP', array( \
&$hookSetUsername, $this->userInfo ) ); +						if ( is_string( \
$hookSetUsername ) ) { +							$this->printDebug( "Username munged by hook: \
$hookSetUsername", NONSENSITIVE ); +							$this->LDAPUsername = \
$hookSetUsername; +						} else {
+							$this->printDebug( "Fetched username is not a string (check your \
hook code...). This message can be safely ignored if you do not have the \
SetUsernameAttributeFromLDAP hook defined.", NONSENSITIVE ); +						}
+					}
+				}
 
-			if ( isset( $_SESSION['wsDomain'] ) && 'local' != $_SESSION['wsDomain'] \
                ) {
-				// Change username to lowercase so that multiple user accounts
-				// won't be created for the same user.
-				// But don't do it for the local domain!
-				$username = strtolower( $username );
+				// We want to use the username returned by LDAP
+				// if it exists
+				if ( $this->LDAPUsername != '' ) {
+					$canonicalname = $this->LDAPUsername;
+					$this->printDebug( "Using LDAPUsername: $canonicalname", NONSENSITIVE \
); +				}
 			}
 
 			// The wiki considers an all lowercase name to be invalid; need to
 			// uppercase the first letter
-			$username[0] = strtoupper( $username[0] );
+			$canonicalname[0] = strtoupper( $canonicalname[0] );
 		}
-
-		$this->printDebug( "Munged username: $username", NONSENSITIVE );
-
-		return $username;
+		$this->printDebug( "Munged username: $canonicalname", NONSENSITIVE );
+		$wgMemc->set( $key, array( "username" => $username, "canonicalname" => \
$canonicalname ), 3600 * 24 ); +		return $canonicalname;
 	}
 
 	/**
 	 * Configures the authentication plugin for use with auto-authentication
 	 * plugins.
-	 *
-	 * @access public
 	 */
-	function autoAuthSetup() {
-		global $wgLDAPAutoAuthDomain;
-
-		$this->setDomain( $wgLDAPAutoAuthDomain );
+	public function autoAuthSetup() {
+		$this->setDomain( $this->getConf( 'AutoAuthDomain' ) );
 	}
 
 	/**
@@ -984,35 +1288,14 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * @access private
 	 */
 	function getSearchString( $username ) {
-		global $wgLDAPSearchStrings;
-		global $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword;
-
 		$this->printDebug( "Entering getSearchString", NONSENSITIVE );
-
-		if ( isset( $wgLDAPSearchStrings[$_SESSION['wsDomain']] ) ) {
+		$ss = $this->getConf( 'SearchString' );
+		if ( $ss ) {
 			// This is a straight bind
 			$this->printDebug( "Doing a straight bind", NONSENSITIVE );
-
-			$tmpuserdn = $wgLDAPSearchStrings[$_SESSION['wsDomain']];
-			$userdn = str_replace( "USER-NAME", $username, $tmpuserdn );
+			$userdn = str_replace( "USER-NAME", $username, $ss );
 		} else {
-			// This is a proxy bind, or an anonymous bind with a search
-			if ( isset( $wgLDAPProxyAgent[$_SESSION['wsDomain']] ) ) {
-				// This is a proxy bind
-				$this->printDebug( "Doing a proxy bind", NONSENSITIVE );
-				$bind = $this->bindAs( $wgLDAPProxyAgent[$_SESSION['wsDomain']], \
                $wgLDAPProxyAgentPassword[$_SESSION['wsDomain']] );
-			} else {
-				// This is an anonymous bind
-				$this->printDebug( "Doing an anonymous bind", NONSENSITIVE );
-				$bind = $this->bindAs();
-			}
-	
-			if ( !$bind ) {
-				$this->printDebug( "Failed to bind", NONSENSITIVE );
-				return '';
-			}
-
-			$userdn = $this->getUserDN( $username );
+			$userdn = $this->getUserDN( $username, true );
 		}
 		$this->printDebug( "userdn is: $userdn", SENSITIVE );
 		return $userdn;
@@ -1021,227 +1304,140 @@ class LdapAuthenticationPlugin extends AuthPlugin \
{  /**
 	 * Gets the DN of a user based upon settings for the domain.
 	 * This function will set $this->LDAPUsername
-	 * You must bind to the server before calling this.
 	 *
 	 * @param string $username
 	 * @return string
 	 * @access private
 	 */
-	function getUserDN( $username ) {
-		global $wgLDAPSearchAttributes;
-		global $wgLDAPAuthAttribute;
-
+	function getUserDN( $username, $bind=false, $searchattr='' ) {
 		$this->printDebug( "Entering getUserDN", NONSENSITIVE );
+		if ( $bind ) {
+			// This is a proxy bind, or an anonymous bind with a search
+			$proxyagent = $this->getConf( 'ProxyAgent');
+			if ( $proxyagent ) {
+				// This is a proxy bind
+				$this->printDebug( "Doing a proxy bind", NONSENSITIVE );
+				$bind = $this->bindAs( $proxyagent, $this->getConf( \
'ProxyAgentPassword' ) ); +			} else {
+				// This is an anonymous bind
+				$this->printDebug( "Doing an anonymous bind", NONSENSITIVE );
+				$bind = $this->bindAs();
+			}
+			if ( !$bind ) {
+				$this->printDebug( "Failed to bind", NONSENSITIVE );
+				return '';
+			}
+		}
 
-		// we need to do a subbase search for the entry
-
-		// Auto auth needs to check LDAP for required attributes.
-		if ( ( isset( $wgLDAPAuthAttribute[$_SESSION['wsDomain']] ) )
-			&& $this->useAutoAuth() ) {
-			$auth_filter = "(" . $wgLDAPAuthAttribute[$_SESSION['wsDomain']] . ")";
-			$srch_filter = "(" . $wgLDAPSearchAttributes[$_SESSION['wsDomain']] . \
                "=" . $this->getLdapEscapedString( $username ) . ")";
-			$filter = "(&" . $srch_filter . $auth_filter . ")";
-			$this->printDebug( "Created an auth attribute filter: $filter", \
                SENSITIVE );
-		} else {
-			$filter = "(" . $wgLDAPSearchAttributes[$_SESSION['wsDomain']] . "=" . \
                $this->getLdapEscapedString( $username ) . ")";
-			$this->printDebug( "Created a regular filter: $filter", SENSITIVE );
+		if ( ! $searchattr ) {
+			$searchattr = $this->getConf( 'SearchAttribute' );
 		}
+		// we need to do a subbase search for the entry
+		$filter = "(" . $searchattr . "=" . $this->getLdapEscapedString( \
$username ) . ")"; +		$this->printDebug( "Created a regular filter: \
$filter", SENSITIVE );  
-		$attributes = array( "*" );
+		// We explicitly put memberof here because it's an operational attribute \
in some servers. +		$attributes = array( "*", "memberof" );
 		$base = $this->getBaseDN( USERDN );
-
 		$this->printDebug( "Using base: $base", SENSITIVE );
-
-		$entry = @ldap_search( $this->ldapconn, $base, $filter, $attributes );
-		if ( !$entry ) {
+		$entry = LdapAuthenticationPlugin::ldap_search( $this->ldapconn, $base, \
$filter, $attributes ); +		if ( \
LdapAuthenticationPlugin::ldap_count_entries( $this->ldapconn, $entry ) == \
0 ) {  $this->printDebug( "Couldn't find an entry", NONSENSITIVE );
 			$this->fetchedUserInfo = false;
 			return '';
 		}
-
-		$this->userInfo = @ldap_get_entries( $this->ldapconn, $entry );
+		$this->userInfo = LdapAuthenticationPlugin::ldap_get_entries( \
$this->ldapconn, $entry );  $this->fetchedUserInfo = true;
-
-		// This is a pretty useful thing to have for auto authentication,
-		// group checking, and pulling preferences.
-		wfRunHooks( 'SetUsernameAttributeFromLDAP', array( &$this->LDAPUsername, \
                $this->userInfo ) );
-		if ( !is_string( $this->LDAPUsername ) ) {
-			$this->printDebug( "Fetched username is not a string (check your hook \
code...). This message can be safely ignored if you do not have the \
                SetUsernameAttributeFromLDAP hook defined.", NONSENSITIVE \
                );
-			$this->LDAPUsername = '';
+		if ( isset( $this->userInfo[0][$searchattr] ) ) {
+			$username = $this->userInfo[0][$searchattr][0];
+			$this->printDebug( "Setting the LDAPUsername based on fetched \
wgLDAPSearchAttributes: $username", NONSENSITIVE ); +			$this->LDAPUsername \
= $username;  }
-
 		$userdn = $this->userInfo[0]["dn"];
 		return $userdn;
 	}
 
+	/**
+	 * Load the current user's entry
+	 *
+	 * @return bool
+	 */
 	function getUserInfo() {
 		// Don't fetch the same data more than once
 		if ( $this->fetchedUserInfo ) {
-			return $this->userInfo;
+			return true;
 		}
-
-		$entry = @ldap_read( $this->ldapconn, $this->userdn, "objectclass=*" );
-		$userInfo = @ldap_get_entries( $this->ldapconn, $entry );
-		if ( $userInfo["count"] < 1 ) {
+		$userInfo = $this->getUserInfoStateless( $this->userdn );
+		if ( is_null( $userInfo ) ) {
 			$this->fetchedUserInfo = false;
-			return;
 		} else {
 			$this->fetchedUserInfo = true;
-			return $userInfo;
+			$this->userInfo = $userInfo;
 		}
+		return $this->fetchedUserInfo;
 	}
 
 	/**
-	 * Retrieve user preferences from LDAP
-	 *
-	 * @param string $userDN
-	 * @access private
+	 * @param $userdn string
+	 * @return array|null
 	 */
-	function getPreferences() {
-		global $wgLDAPPreferences;
-		global $wgLDAPRetrievePrefs;
-
-		$this->printDebug( "Entering getPreferences", NONSENSITIVE );
-
-		$this->userInfo = $this->getUserInfo();
-		if ( is_null( $this->userInfo ) ) {
-			$this->printDebug( "Failed to get preferences", NONSENSITIVE );
-		}
-
-		// Retrieve preferences
-		if ( isset( $wgLDAPPreferences[$_SESSION['wsDomain']] ) ) {
-			$this->printDebug( "Retrieving preferences", NONSENSITIVE );
-			$prefs = $wgLDAPPreferences[$_SESSION['wsDomain']];
-			foreach ( array_keys( $prefs ) as $key ) {
-				switch ( $key ) {
-					case "email":
-						if ( isset( $this->userInfo[0]["$prefs[$key]"] ) ) {
-							$this->email = $this->userInfo[0]["$prefs[$key]"][0];
-							$this->printDebug( "Retrieved email ($this->email) using attribute \
                ($prefs[$key])", NONSENSITIVE );
-						}
-						break;
-					case "language":
-						if ( isset( $this->userInfo[0]["$prefs[$key]"] ) ) {
-							$this->lang = $this->userInfo[0][$prefs[$key]][0];
-							$this->printDebug( "Retrieved language ($this->lang) using \
                attribute ($prefs[$key])", NONSENSITIVE );
-						}
-						break;
-					case "nickname":
-						if ( isset( $this->userInfo[0]["$prefs[$key]"] ) ) {
-							$this->nickname = $this->userInfo[0]["$prefs[$key]"][0];
-							$this->printDebug( "Retrieved nickname ($this->nickname) using \
                attribute ($prefs[$key])", NONSENSITIVE );
-						}
-						break;
-					case "realname":
-						if ( isset( $this->userInfo[0]["$prefs[$key]"] ) ) {
-							$this->realname = $this->userInfo[0]["$prefs[$key]"][0];
-							$this->printDebug( "Retrieved realname ($this->realname) using \
                attribute ($prefs[$key])", NONSENSITIVE );
-						}
-						break;
-				}
+	function getUserInfoStateless( $userdn ) {
+		global $wgMemc;
+
+		$key = wfMemcKey( 'ldapauthentication', 'userinfo', $userdn );
+		$userInfo = $wgMemc->get( $key );
+		if ( !is_array( $userInfo ) ) {
+			$entry = LdapAuthenticationPlugin::ldap_read( $this->ldapconn, $userdn, \
"objectclass=*", array( '*', 'memberof' ) ); +			$userInfo = \
LdapAuthenticationPlugin::ldap_get_entries( $this->ldapconn, $entry ); \
+			if ( $userInfo["count"] < 1 ) { +				return null;
 			}
-		} else if ( isset( $wgLDAPRetrievePrefs[$_SESSION['wsDomain']] ) && \
                $wgLDAPRetrievePrefs[$_SESSION['wsDomain']] ) {
-			// DEPRECATED. Kept for backwards compatibility.
-			$this->printDebug( "Retrieving preferences", NONSENSITIVE );
-			$this->printDebug( '$wgLDAPRetrievePrefs is a DEPRECATED option, please \
                use $wgLDAPPreferences.', NONSENSITIVE );
-
-			if ( isset( $this->userInfo[0]["mail"] ) ) {
-				$this->email = $this->userInfo[0]["mail"][0];
-			}
-			if ( isset( $this->userInfo[0]["preferredlanguage"] ) ) {
-				$this->lang = $this->userInfo[0]["preferredlanguage"][0];
-			}
-			if ( isset( $this->userInfo[0]["displayname"] ) ) {
-				$this->nickname = $this->userInfo[0]["displayname"][0];
-			}
-			if ( isset( $this->userInfo[0]["cn"] ) ) {
-				$this->realname = $this->userInfo[0]["cn"][0];
-			}
-
-			$this->printDebug( "Retrieved: $this->email, $this->lang, \
$this->nickname, $this->realname", SENSITIVE ); +			$wgMemc->set( $key, \
$userInfo, 3600 * 24 );  }
+		return $userInfo;
 	}
 
-	function synchUsername( $username ) {
-		global $wgLDAPUniqueBlockLogin, $wgLDAPUniqueRenameUser;
-		global $wgLDAPUniqueAttribute;
-
-		$this->printDebug( "Entering synchUsername", NONSENSITIVE );
-
-		$this->userInfo = $this->getUserInfo();
-		if ( is_null( $this->userInfo ) ) {
-			$this->printDebug( "Failed to get preferences", NONSENSITIVE );
-		}
-
-		// Are we blocking login/renaming users on unique external ID \
                mismatches?
-		//     *** WARNING ***
-		//     This needs to be fixed before use! This probably does not work \
                correctly
-		//     with all options. It is probably a good idea to refactor the \
                username stuff
-		//     in general (as it is currently somewhat of a kludge). Also, \
                MediaWiki does
-		//     not currently have support for this.
-		//     *** WARNING ***
-		if ( ( isset( $wgLDAPUniqueBlockLogin[$_SESSION['wsDomain']] ) && \
                $wgLDAPUniqueBlockLogin[$_SESSION['wsDomain']] )
-			|| ( isset( $wgLDAPUniqueRenameUser[$_SESSION['wsDomain']] ) && \
                $wgLDAPUniqueRenameUser[$_SESSION['wsDomain']] ) ) {
-
-			$this->printDebug( "Checking for username change in LDAP.", SENSITIVE \
); +	/**
+	 * Retrieve user preferences from LDAP
+	 */
+	private function getPreferences() {
+		$this->printDebug( "Entering getPreferences", NONSENSITIVE );
 
-			// Get the user's unique attribute from LDAP
-			if ( isset( $wgLDAPUniqueAttribute[$_SESSION['wsDomain']] ) ) {
-				$ldapuniqueattr = $wgLDAPUniqueAttribute[$_SESSION['wsDomain']];
-				$this->externalid = $this->info[0][$ldapuniqueattr][0];
-			} else {
-				return false;
+		// Retrieve preferences
+		$prefs = $this->getConf( 'Preferences' );
+		if ( !$prefs ) {
+			return null;
+		}
+		if ( !$this->getUserInfo() ) {
+			$this->printDebug( "Failed to get preferences, the user's entry wasn't \
found.", NONSENSITIVE ); +			return null;
+		}
+		$this->printDebug( "Retrieving preferences", NONSENSITIVE );
+		foreach ( array_keys( $prefs ) as $key ) {
+			$attr = strtolower( $prefs[$key] );
+			if ( !isset( $this->userInfo[0][$attr] ) ) {
+				continue;
 			}
-
-			$this->printDebug( "Retrieved external id: $this->externalid", \
                SENSITIVE );
-
-			$retrievedusername = User::whoIsExternalID( "$this->externalid" );
-
-			$this->printDebug( "Username (in MediaWiki database) of fetched \
                external id: $retrievedusername", SENSITIVE );
-
-			// See if the username returned from the database matches the username \
                given
-			if ( $retrievedusername != '' && ( $username != $retrievedusername ) ) \
                {
-				if ( isset( $wgLDAPUniqueBlockLogin[$_SESSION['wsDomain']] )
-					&& $wgLDAPUniqueBlockLogin[$_SESSION['wsDomain']] ) {
-
-					$this->printDebug( "Usernames do not match, blocking login.", \
                SENSITIVE );
-					return false;
-				} else if ( isset( $wgLDAPUniqueRenameUser[$_SESSION['wsDomain']] )
-					&& $wgLDAPUniqueRenameUser[$_SESSION['wsDomain']] ) {
-
-					$this->printDebug( "Usernames do not match, renaming user in \
                database.", SENSITIVE );
-
-					global $wgVersion;
-					if ( version_compare( $wgVersion, '1.7.0', '<' ) ) {
-						$this->printDebug( "Renaming users is only supported in MediaWiki \
                1.7+, please upgrade.", SENSITIVE );
-						$this->markAuthFailed();
-						return false;
-					}
-
-					$olduser = User::newFromName( $retrievedusername );
-					$uid = $olduser->idForName();
-
-					// Ensure we don't require the same class twice
-					if ( !class_exists( 'RenameuserSQL' ) ) {
-						require( 'Renameuser/SpecialRenameuser_body.php' );
-					}
-
-					// Make a new rename user object with: from, to, uid of from	
-					$rename = new RenameuserSQL( $retrievedusername, $username, $uid );
-					$rename->rename();
-
-					// For the time being we can't just allow the user to log in
-					// as MediaWiki will try to create the user account after we
-					// do a rename. If we don't return false, the user will get
-					// a database error
-					return false;
-				}
+			$value = $this->userInfo[0][$attr][0];
+			switch ( $key ) {
+				case "email":
+					$this->email = $value;
+					$this->printDebug( "Retrieved email ($this->email) using attribute \
($prefs[$key])", NONSENSITIVE ); +					break;
+				case "language":
+					$this->lang = $value;
+					$this->printDebug( "Retrieved language ($this->lang) using attribute \
($prefs[$key])", NONSENSITIVE ); +					break;
+				case "nickname":
+					$this->nickname = $value;
+					$this->printDebug( "Retrieved nickname ($this->nickname) using \
attribute ($prefs[$key])", NONSENSITIVE ); +					break;
+				case "realname":
+					$this->realname = $value;
+					$this->printDebug( "Retrieved realname ($this->realname) using \
attribute ($prefs[$key])", NONSENSITIVE ); +					break;
 			}
-
-			$this->printDebug( "Usernames matched or the user doesn't exist in the \
database yet.", SENSITIVE );  }
-
-		return true;
 	}
 
 	/**
@@ -1252,25 +1448,11 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * @access private
 	 */
 	function checkGroups( $username ) {
-		global $wgLDAPGroupDN;
-		global $wgLDAPRequiredGroups, $wgLDAPExcludedGroups;
-
 		$this->printDebug( "Entering checkGroups", NONSENSITIVE );
 
-		// Old style groups, non-nestable and fairly limited on group type (full \
                DN
-		// versus username). DEPRECATED
-		if ( $wgLDAPGroupDN ) {
-			$this->printDebug( "Checking for (old style) group membership", \
                NONSENSITIVE );
-			// we need to do a subbase search for the entry
-			$filter = "(member=" . $this->getLdapEscapedString( $this->userdn ) . \
                ")";
-			$info = @ldap_get_entries( $this->ldapconn, @ldap_search( \
                $this->ldapconn, $wgLDAPGroupDN, $filter ) );
-
-			return ( $info["count"] >= 1 );
-		}
-
-		if ( isset( $wgLDAPExcludedGroups[$_SESSION['wsDomain']] ) ) {
+		$excgroups = $this->getConf( 'ExcludedGroups' );
+		if ( $excgroups ) {
 			$this->printDebug( "Checking for excluded group membership", \
                NONSENSITIVE );
-			$excgroups = $wgLDAPExcludedGroups[$_SESSION['wsDomain']];
 			for ( $i = 0; $i < count( $excgroups ); $i++ ) {
 				$excgroups[$i] = strtolower( $excgroups[$i] );
 			}
@@ -1286,10 +1468,9 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 			}
 		}
 
-		// New style group checking
-		if ( isset( $wgLDAPRequiredGroups[$_SESSION['wsDomain']] ) ) {
+		$reqgroups = $this->getConf( 'RequiredGroups' );
+		if ( $reqgroups ) {
 			$this->printDebug( "Checking for (new style) group membership", \
                NONSENSITIVE );
-			$reqgroups = $wgLDAPRequiredGroups[$_SESSION['wsDomain']];
 			for ( $i = 0; $i < count( $reqgroups ); $i++ ) {
 				$reqgroups[$i] = strtolower( $reqgroups[$i] );
 			}
@@ -1314,28 +1495,23 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 
 	/**
 	 * Function to get the user's groups.
-	 *
-	 * @access private
+	 * @param string $username
 	 */
-	function getGroups( $username ) {
-		global $wgLDAPRequiredGroups, $wgLDAPUseLDAPGroups;
-		global $wgLDAPGroupUseFullDN, $wgLDAPGroupUseRetrievedUsername;
-		global $wgLDAPGroupSearchNestedGroups;
-		global $wgLDAPGroupsPrevail;
-		global $wgLDAPGroupsUseMemberOf;
-
+	protected function getGroups( $username ) {
 		$this->printDebug( "Entering getGroups", NONSENSITIVE );
 
+		// Ensure userLDAPGroups is set, no matter what
+		$this->userLDAPGroups = array( "dn"=> array(), "short"=>array() );
+
 		// Find groups
-		if ( isset( $wgLDAPRequiredGroups[$_SESSION['wsDomain']] ) || ( isset( \
$wgLDAPUseLDAPGroups[$_SESSION['wsDomain']] ) && \
$wgLDAPUseLDAPGroups[$_SESSION['wsDomain']] ) ) { +		if ( $this->getConf( \
'RequiredGroups' ) || $this->getConf( 'UseLDAPGroups' ) ) {  \
$this->printDebug( "Retrieving LDAP group membership", NONSENSITIVE );  
 			// Let's figure out what we should be searching for
-			if ( isset( $wgLDAPGroupUseFullDN[$_SESSION['wsDomain']] ) && \
$wgLDAPGroupUseFullDN[$_SESSION['wsDomain']] ) { +			if ( $this->getConf( \
'GroupUseFullDN' ) ) {  $usertopass = $this->userdn;
 			} else {
-				if ( ( isset( $wgLDAPGroupUseRetrievedUsername[$_SESSION['wsDomain']] \
                ) && \
                $wgLDAPGroupUseRetrievedUsername[$_SESSION['wsDomain']] )
-					&& $this->LDAPUsername != '' ) {
+				if ( $this->getConf( 'GroupUseRetrievedUsername' ) && \
$this->LDAPUsername != '' ) {  
 					$usertopass = $this->LDAPUsername;
 				} else {
@@ -1343,13 +1519,11 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 				}
 			}
 
-			if ( isset( $wgLDAPGroupsUseMemberOf[$_SESSION['wsDomain']] ) && \
$wgLDAPGroupsUseMemberOf[$_SESSION['wsDomain']] ) { +			if ( \
$this->getConf( 'GroupsUseMemberOf' ) ) {  $this->printDebug( "Using \
                memberOf", NONSENSITIVE );
-				$this->userInfo = $this->getUserInfo();
-				if ( is_null( $this->userInfo ) ) {
-					$this->printDebug( "Failed to get memberOf attribute", NONSENSITIVE \
                );
-				}
-				if ( isset( $this->userInfo[0]["memberof"] ) ) {
+				if ( !$this->getUserInfo() ) {
+					$this->printDebug( "Couldn't get the user's entry.", NONSENSITIVE );
+				} else if ( isset( $this->userInfo[0]["memberof"] ) ) {
 					# The first entry is always a count
 					$memberOfMembers = $this->userInfo[0]["memberof"];
 					array_shift( $memberOfMembers );
@@ -1367,23 +1541,23 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 							}
 						}
 					}
+					$this->printDebug( "Got the following groups:", SENSITIVE, \
$groups["dn"] );  
 					$this->userLDAPGroups = $groups;
+				} else {
+					$this->printDebug( "memberOf attribute isn't set", NONSENSITIVE );
 				}
 			} else {
 				$this->printDebug( "Searching for the groups", NONSENSITIVE );
 				$this->userLDAPGroups = $this->searchGroups( $usertopass );
-
-				if ( isset( $wgLDAPGroupSearchNestedGroups[$_SESSION['wsDomain']] ) && \
$wgLDAPGroupSearchNestedGroups[$_SESSION['wsDomain']] ) { +				if ( \
                $this->getConf( 'GroupSearchNestedGroups' ) ) {
 					$this->userLDAPGroups = $this->searchNestedGroups( \
                $this->userLDAPGroups );
 					$this->printDebug( "Got the following nested groups:", SENSITIVE, \
$this->userLDAPGroups["dn"] );  }
 			}
-
 			// Only find all groups if the user has any groups; otherwise, we are
 			// just wasting a search.
-			if ( ( isset( $wgLDAPGroupsPrevail[$_SESSION['wsDomain']] )
-				&& $wgLDAPGroupsPrevail[$_SESSION['wsDomain']] ) && count( \
$this->userLDAPGroups ) != 0 ) { +			if ( $this->getConf( 'GroupsPrevail' ) \
&& count( $this->userLDAPGroups ) != 0 ) {  $this->allLDAPGroups = \
$this->searchGroups( '*' );  }
 		}
@@ -1394,12 +1568,12 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * $searchedgroups is used for tail recursion and shouldn't be provided
 	 * when called externally.
 	 *
-	 * @param string $userDN
+	 * @param $groups
 	 * @param array $searchedgroups
 	 * @return bool
 	 * @access private
 	 */
-	function searchNestedGroups( $groups, $searchedgroups = array( "dn" => \
Array(), "short" => Array() ) ) { +	function searchNestedGroups( $groups, \
$searchedgroups = array( "dn" => array(), "short" => array() ) ) {  \
$this->printDebug( "Entering searchNestedGroups", NONSENSITIVE );  
 		// base case, no more groups left to check
@@ -1409,7 +1583,6 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 		}
 
 		$this->printDebug( "Searching groups:", SENSITIVE, $groups["dn"] );
-
 		$groupstosearch = array( "short" => array(), "dn" => array() );
 		foreach ( $groups["dn"] as $group ) {
 			$returnedgroups = $this->searchGroups( $group );
@@ -1435,10 +1608,8 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 				}
 			}
 		}
-
 		$searchedgroups = array_merge_recursive( $groups, $searchedgroups );
 
-		// Mmmmmm. Tail recursion. Tasty.
 		return $this->searchNestedGroups( $groupstosearch, $searchedgroups );
 	}
 
@@ -1447,46 +1618,44 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 *
 	 * @param string $dn
 	 * @return array
-	 * @access private
 	 */
-	function searchGroups( $dn ) {
-		global $wgLDAPGroupObjectclass, $wgLDAPGroupAttribute, \
                $wgLDAPGroupNameAttribute;
-		global $wgLDAPProxyAgent, $wgLDAPProxyAgentPassword;
-		
+	private function searchGroups( $dn ) {
 		$this->printDebug( "Entering searchGroups", NONSENSITIVE );
 
 		$base = $this->getBaseDN( GROUPDN );
-
-		$objectclass = $wgLDAPGroupObjectclass[$_SESSION['wsDomain']];
-		$attribute = $wgLDAPGroupAttribute[$_SESSION['wsDomain']];
-		$nameattribute = $wgLDAPGroupNameAttribute[$_SESSION['wsDomain']];
+		$objectclass = $this->getConf( 'GroupObjectclass' );
+		$attribute = $this->getConf( 'GroupAttribute' );
+		$nameattribute = $this->getConf( 'GroupNameAttribute' );
 
 		// We actually want to search for * not \2a, ensure we don't escape *
 		$value = $dn;
-		if ( $value != "*" )
+		if ( $value != "*" ) {
 			$value = $this->getLdapEscapedString( $value );
+		}
 
-		if ( isset( $wgLDAPProxyAgent[$_SESSION['wsDomain']] ) ) {
+		$proxyagent = $this->getConf( 'ProxyAgent' );
+		if ( $proxyagent ) {
 			// We'll try to bind as the proxyagent as the proxyagent should \
normally have more  // rights than the user. If the proxyagent fails to \
bind, we will still be able  // to search as the normal user (which is why \
we don't return on fail).  $this->printDebug( "Binding as the proxyagent", \
                NONSENSITIVE );
-			$this->bindAs( $wgLDAPProxyAgent[$_SESSION['wsDomain']], \
$wgLDAPProxyAgentPassword[$_SESSION['wsDomain']] ); +			$this->bindAs( \
$proxyagent, $this->getConf( 'ProxyAgentPassword' ) );  }
 
 		$groups = array( "short" => array(), "dn" => array() );
-		
+
 		// AD does not include the primary group in the list of groups, we have \
to find it ourselves.  // TODO: find a way to only do this search for AD \
domains.  if ( $dn != "*" ) {
 			$PGfilter = "(&(distinguishedName=$value)(objectclass=user))";
 			$this->printDebug( "User Filter: $PGfilter", SENSITIVE );
-			$PGinfo = @ldap_search( $this->ldapconn, $base, $PGfilter );
-			$PGentries = @ldap_get_entries( $this->ldapconn, $PGinfo );
+			$PGinfo = LdapAuthenticationPlugin::ldap_search( $this->ldapconn, \
$base, $PGfilter ); +			$PGentries = \
LdapAuthenticationPlugin::ldap_get_entries( $this->ldapconn, $PGinfo );  if \
( $PGentries ) {  $Usid = $PGentries[0]['objectsid'][0];
 				$PGrid = $PGentries[0]['primarygroupid'][0];
 				$PGsid = bin2hex( $Usid );
+				$PGSID = array();
 				for ( $i=0; $i < 56; $i += 2 ) {
 					$PGSID[] = substr( $PGsid, $i, 2 );
 				}
@@ -1499,13 +1668,14 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 				for ( $i = 24; $i < 28; $i++ ) {
 					$PGSID[$i] = array_pop( $PGRID );
 				}
+				$PGsid_string = '';
 				foreach ( $PGSID as $PGsid_bit ) {
 					$PGsid_string .= "\\" . $PGsid_bit;
 				}
 				$PGfilter = "(&(objectSid=$PGsid_string)(objectclass=$objectclass))";
 				$this->printDebug( "Primary Group Filter: $PGfilter", SENSITIVE );
-				$info = @ldap_search( $this->ldapconn, $base, $PGfilter );
-				$PGentries = @ldap_get_entries( $this->ldapconn, $info );
+				$info = LdapAuthenticationPlugin::ldap_search( $this->ldapconn, $base, \
$PGfilter ); +				$PGentries = LdapAuthenticationPlugin::ldap_get_entries( \
$this->ldapconn, $info );  array_shift( $PGentries );
 				$dnMember = strtolower( $PGentries[0]['dn'] );
 				$groups["dn"][] = $dnMember;
@@ -1517,29 +1687,24 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 						$groups["short"][] = strtolower( $memAttrs[1] );
 					}
 				}
-				
+
 			}
 		}
 
 		$filter = "(&($attribute=$value)(objectclass=$objectclass))";
-
 		$this->printDebug( "Search string: $filter", SENSITIVE );
-
-		$info = @ldap_search( $this->ldapconn, $base, $filter );
+		$info = LdapAuthenticationPlugin::ldap_search( $this->ldapconn, $base, \
$filter );  if ( !$info ) {
 			$this->printDebug( "No entries returned from search.", SENSITIVE );
-
 			// Return an array so that other functions
 			// don't error out.
 			return array( "short" => array(), "dn" => array() );
 		}
 
-		$entries = @ldap_get_entries( $this->ldapconn, $info );
-
+		$entries = LdapAuthenticationPlugin::ldap_get_entries( $this->ldapconn, \
$info );  if ( $entries ){
 			// We need to shift because the first entry will be a count
 			array_shift( $entries );
-
 			// Let's get a list of both full dn groups and shortname groups
 			foreach ( $entries as $entry ) {
 				$shortMember = strtolower( $entry[$nameattribute][0] );
@@ -1550,7 +1715,6 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 		}
 
 		$this->printDebug( "Returned groups:", SENSITIVE, $groups["dn"] );
-
 		return $groups;
 	}
 
@@ -1564,7 +1728,6 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 */
 	function hasLDAPGroup( $group ) {
 		$this->printDebug( "Entering hasLDAPGroup", NONSENSITIVE );
-
 		return in_array( strtolower( $group ), $this->userLDAPGroups["short"] );
 	}
 
@@ -1577,7 +1740,6 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 */
 	function isLDAPGroup( $group ) {
 		$this->printDebug( "Entering isLDAPGroup", NONSENSITIVE );
-
 		return in_array( strtolower( $group ), $this->allLDAPGroups["short"] );
 	}
 
@@ -1589,16 +1751,15 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * @access private
 	 */
 	function setGroups( &$user ) {
-		global $wgLDAPGroupsPrevail, $wgGroupPermissions, \
$wgLDAPLocallyManagedGroups; +		global $wgGroupPermissions;
 
 		// TODO: this is *really* ugly code. clean it up!
-
 		$this->printDebug( "Entering setGroups.", NONSENSITIVE );
 
 		# Add ldap groups as local groups
-		if ( isset( $wgLDAPGroupsPrevail[$_SESSION['wsDomain']] ) && \
$wgLDAPGroupsPrevail[$_SESSION['wsDomain']] ) { +		if ( $this->getConf( \
'GroupsPrevail' ) ) {  $this->printDebug( "Adding all groups to \
                wgGroupPermissions: ", SENSITIVE, $this->allLDAPGroups );
-			
+
 			foreach ( $this->allLDAPGroups["short"] as $ldapgroup ) {
 				if ( !array_key_exists( $ldapgroup, $wgGroupPermissions ) )
 						$wgGroupPermissions[$ldapgroup] = array();
@@ -1608,21 +1769,18 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 		# add groups permissions
 		$localAvailGrps = $user->getAllGroups();
 		$localUserGrps = $user->getEffectiveGroups();
-		
 		$defaultLocallyManagedGrps = array( 'bot', 'sysop', 'bureaucrat' );
-
-		if ( isset( $wgLDAPLocallyManagedGroups[$_SESSION['wsDomain']] ) ) {
-			$locallyManagedGrps = \
$wgLDAPLocallyManagedGroups[$_SESSION['wsDomain']]; +		$locallyManagedGrps \
= $this->getConf( 'LocallyManagedGroups' ); +		if ( $locallyManagedGrps ) {
 			$locallyManagedGrps = array_unique( array_merge( \
$defaultLocallyManagedGrps, $locallyManagedGrps ) );  $this->printDebug( \
"Locally managed groups: ", SENSITIVE, $locallyManagedGrps );  } else {
 			$locallyManagedGrps = $defaultLocallyManagedGrps;
 			$this->printDebug( "Locally managed groups is unset, using defaults: ", \
SENSITIVE, $locallyManagedGrps );  }
-			
+
 		$this->printDebug( "Available groups are: ", NONSENSITIVE, \
$localAvailGrps );  $this->printDebug( "Effective groups are: ", \
                NONSENSITIVE, $localUserGrps );
-
 		# note: $localUserGrps does not need to be updated with $cGroup added,
 		#       as $localAvailGrps contains $cGroup only once.
 		foreach ( $localAvailGrps as $cGroup ) {
@@ -1653,19 +1811,15 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * @access private
 	 */
 	function getPasswordHash( $password ) {
-		global $wgLDAPPasswordHash;
-
 		$this->printDebug( "Entering getPasswordHash", NONSENSITIVE );
 
-		if ( isset( $wgLDAPPasswordHash[$_SESSION['wsDomain']] ) ) {
-			$hashtouse = $wgLDAPPasswordHash[$_SESSION['wsDomain']];
-		} else {
-			$hashtouse = '';
-		}
-
 		// Set the password hashing based upon admin preference
-		switch ( $hashtouse ) {
+		switch ( $this->getConf( 'PasswordHash' ) ) {
 			case 'crypt':
+				// https://bugs.php.net/bug.php?id=55439
+				if ( crypt( 'password', '$1$U7AjYB.O$' ) == '$1$U7AjYB.O' ) {
+					die( 'The version of PHP in use has a broken crypt function. Please \
upgrade your installation of PHP, or use another encryption function for \
LDAP.' ); +				}
 				$pass = '{CRYPT}' . crypt( $password );
 				break;
 			case 'clear':
@@ -1677,7 +1831,6 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 				break;
 		}
 
-		$this->printDebug( "Password is $pass", HIGHLYSENSITIVE );
 		return $pass;
 	}
 
@@ -1717,15 +1870,15 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	function bindAs( $userdn = null, $password = null ) {
 		// Let's see if the user can authenticate.
 		if ( $userdn == null || $password == null ) {
-			$bind = @ldap_bind( $this->ldapconn );
+			$bind = LdapAuthenticationPlugin::ldap_bind( $this->ldapconn );
 		} else {
-			$bind = @ldap_bind( $this->ldapconn, $userdn, $password );
+			$bind = LdapAuthenticationPlugin::ldap_bind( $this->ldapconn, $userdn, \
$password );  }
 		if ( !$bind ) {
 			$this->printDebug( "Failed to bind as $userdn", NONSENSITIVE );
-			$this->printDebug( "with password: $password", HIGHLYSENSITIVE );
 			return false;
 		}
+		$this->boundAs = $userdn;
 		return true;
 	}
 
@@ -1737,64 +1890,53 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 	 * @access private
 	 */
 	function useAutoAuth() {
-		global $wgLDAPAutoAuthDomain;
-
-		$this->printDebug( "", NONSENSITIVE );
-		return isset( $wgLDAPAutoAuthDomain ) && $_SESSION['wsDomain'] == \
$wgLDAPAutoAuthDomain; +		return $this->getDomain() == $this->getConf( \
'AutoAuthDomain' );  }
 
 	/**
 	 * Returns a string which has the chars *, (, ), \ & NUL escaped to LDAP \
                compliant
 	 * syntax as per RFC 2254
 	 * Thanks and credit to Iain Colledge for the research and function.
-	 * 
+	 *
 	 * @param string $string
 	 * @return string
 	 * @access private
 	 */
-	function getLdapEscapedString ( $string ) {
+	function getLdapEscapedString( $string ) {
 		// Make the string LDAP compliant by escaping *, (, ) , \ & NUL
 		return str_replace(
-			array( "*", "(", ")", "\\", "\x00" ), // replace this
-			array( "\\2a", "\\28", "\\29", "\\5c", "\\00" ), // with this
-			$string // in this
+			array( "\\", "(", ")", "*", "\x00" ),
+			array( "\\5c", "\\28", "\\29", "\\2a", "\\00" ),
+			$string
 			);
 	}
 
 	/**
 	 * Returns a basedn by the type of entry we are searching for.
-	 * 
+	 *
 	 * @param int $type
 	 * @return string
 	 * @access private
 	 */
-	function getBaseDN ( $type ) {
-		global $wgLDAPBaseDNs, $wgLDAPGroupBaseDNs, $wgLDAPUserBaseDNs;
-
+	function getBaseDN( $type ) {
 		$this->printDebug( "Entering getBaseDN", NONSENSITIVE );
 
 		$ret = '';
 		switch( $type ) {
 			case USERDN:
-				if ( isset( $wgLDAPUserBaseDNs[$_SESSION['wsDomain']] ) ) {
-					$ret = $wgLDAPUserBaseDNs[$_SESSION['wsDomain']];
-				}
+				$ret = $this->getConf( 'UserBaseDN' );
 				break;
 			case GROUPDN:
-				if ( isset( $wgLDAPGroupBaseDNs[$_SESSION['wsDomain']] ) ) {
-					$ret =  $wgLDAPGroupBaseDNs[$_SESSION['wsDomain']];
-				}
+				$ret = $this->getConf( 'GroupBaseDN' );
 				break;
 			case DEFAULTDN:
-				if ( isset( $wgLDAPBaseDNs[$_SESSION['wsDomain']] ) ) {
-					$ret = $wgLDAPBaseDNs[$_SESSION['wsDomain']];
-					$this->printDebug( "basedn is $ret", NONSENSITIVE );
+				$ret = $this->getConf( 'BaseDN' );
+				if ( $ret ) {
 					return $ret;
 				} else {
 					$this->printDebug( "basedn is not set.", NONSENSITIVE );
 					return '';
 				}
-				break;
 		}
 
 		if ( $ret == '' ) {
@@ -1807,50 +1949,79 @@ class LdapAuthenticationPlugin extends AuthPlugin {
 			return $ret;
 		}
 	}
+
+	/**
+	 * @param User $user
+	 * @return string
+	 */
+	static function loadDomain( $user ) {
+		$user_id = $user->getId();
+		if ( $user_id != 0 ) {
+			$dbr = wfGetDB( DB_SLAVE );
+			$row = $dbr->selectRow(
+				'ldap_domains',
+				array( 'domain' ),
+				array( 'user_id' => $user_id ),
+				__METHOD__ );
+
+			if ( $row ) {
+				return $row->domain;
+			}
+		}
+
+		return null;
+	}
+
+	/**
+	 * @param User $user
+	 * @param string $domain
+	 * @return bool
+	 */
+	static function saveDomain( $user, $domain ) {
+		$user_id = $user->getId();
+		if ( $user_id != 0 ) {
+			$dbw = wfGetDB( DB_MASTER );
+			$olddomain = self::loadDomain( $user );
+			if ( $olddomain ) {
+				return $dbw->update(
+					'ldap_domains',
+					array( 'domain' => $domain ),
+					array( 'user_id' => $user_id ),
+					__METHOD__ );
+			} else {
+				return $dbw->insert(
+					'ldap_domains',
+					array(  'domain' => $domain,
+						'user_id' => $user_id ),
+					__METHOD__ );
+			}
+		} else {
+			return false;
+		}
+	}
+
 }
 
-// The following was derived from the SSL Authentication plugin
+// The auto-auth code was originally derived from the SSL Authentication \
plugin  // http://www.mediawiki.org/wiki/SSL_authentication
 
 /**
- * Sets up the SSL authentication piece of the LDAP plugin.
+ * Sets up the auto-authentication piece of the LDAP plugin.
  *
  * @access public
  */
 function AutoAuthSetup() {
-	global $wgLDAPAutoAuthUsername;
-	global $wgLDAPSSLUsername;
-	global $wgLDAPAutoAuthDomain;
-	global $wgLDAPSmartcardDomain;
 	global $wgHooks;
 	global $wgAuth;
-	global $wgVersion;
-
 	$wgAuth = new LdapAuthenticationPlugin();
 
 	$wgAuth->printDebug( "Entering AutoAuthSetup.", NONSENSITIVE );
 
-	// Set configuration options for backwards compatibility
-	if ( isset( $wgLDAPSSLUsername ) && $wgLDAPSSLUsername != "" ) {
-		$wgAuth->printDebug( 'Setting $wgLDAPAutoAuthUsername to \
$wgLDAPSSLUsername; please change your configuration to fix this deprecated \
                configuration variable.', NONSENSITIVE );
-		$wgLDAPAutoAuthUsername = $wgLDAPSSLUsername;
-	}
-	if ( isset( $wgLDAPSmartcardDomain ) && $wgLDAPSmartcardDomain != "" ) {
-		$wgAuth->printDebug( 'Setting $wgLDAPAutoAuthDomain to \
$wgLDAPSmartcardDomain; please change your configuration to fix this \
                deprecated configuration variable.', NONSENSITIVE );
-		$wgLDAPAutoAuthDomain = $wgLDAPSmartcardDomain;
-	}
+	# We need both authentication username and domain (bug 34787)
+	if ( $wgAuth->getConf("AutoAuthUsername") !== "" && \
$wgAuth->getConf("AutoAuthDomain") !== "" ) { +		$wgAuth->printDebug( \
"wgLDAPAutoAuthUsername and wgLDAPAutoAuthDomain is not null, adding \
hooks.", NONSENSITIVE ); +		$wgHooks['UserLoadAfterLoadFromSession'][] = \
'LdapAutoAuthentication::Authenticate';  
-	if ( $wgLDAPAutoAuthUsername !== "" ) {
-		$wgAuth->printDebug( "wgLDAPAutoAuthUsername is not null, adding \
                hooks.", NONSENSITIVE );
-		if ( version_compare( $wgVersion, '1.14.0', '<' ) ) {
-			if ( version_compare( $wgVersion, '1.13.0', '<' ) ) {
-				$wgHooks['AutoAuthenticate'][] = \
                'LdapAutoAuthentication::Authenticate';
-			} else {
-				$wgHooks['UserLoadFromSession'][] = \
                'LdapAutoAuthentication::Authenticate';
-			}
-		} else {
-			$wgHooks['UserLoadAfterLoadFromSession'][] = \
                'LdapAutoAuthentication::Authenticate';
-		}
 		$wgHooks['PersonalUrls'][] = 'LdapAutoAuthentication::NoLogout'; /* \
Disallow logout link */  }
 }
diff --git a/extensions/LdapAuthentication/LdapAutoAuthentication.php \
b/extensions/LdapAuthentication/LdapAutoAuthentication.php index \
                73141b6..2dd2421 100644
--- a/extensions/LdapAuthentication/LdapAutoAuthentication.php
+++ b/extensions/LdapAuthentication/LdapAutoAuthentication.php
@@ -5,33 +5,21 @@ class LdapAutoAuthentication {
 	/**
 	 * Does the web server authentication piece of the LDAP plugin.
 	 *
-	 * @access public
+	 * @param $user User
+	 * @param $result bool
+	 * @return bool
 	 */
-	static function Authenticate( $user, &$result = null ) {
-		global $wgAuth, $wgLDAPAutoAuthUsername, $wgVersion;
+	public static function Authenticate( $user, &$result = null ) {
+		/**
+		 * @var $wgAuth LdapAuthenticationPlugin
+		 */
+		global $wgAuth;
 
 		$wgAuth->printDebug( "Entering AutoAuthentication.", NONSENSITIVE );
 
-		if ( version_compare( $wgVersion, '1.14.0', '<' ) ) {
-			// The following section is a hack to determine whether or not
-			// the user is logged in. We need a core fix to make this simpler.
-			if ( isset( $_SESSION['wsUserID'] ) ) {
-				$user->setID( $_SESSION['wsUserID'] );
-				if ( $user->loadFromId() ) {
-					if ( $_SESSION['wsToken'] == $user->mToken  && \
                $_SESSION['wsUserName'] == $user->mName ) {
-						$wgAuth->printDebug( "User is already logged in.", NONSENSITIVE );
-						$result = true;
-						return true;
-					} else {
-						$user->loadDefaults();
-					}
-				}
-			}
-		} else {
-			if ( $user->isLoggedIn() ) {
-				$wgAuth->printDebug( "User is already logged in.", NONSENSITIVE );
-				return true;
-			}
+		if ( $user->isLoggedIn() ) {
+			$wgAuth->printDebug( "User is already logged in.", NONSENSITIVE );
+			return true;
 		}
 
 		$wgAuth->printDebug( "User isn't logged in, calling setup.", \
NONSENSITIVE ); @@ -40,9 +28,11 @@ class LdapAutoAuthentication {
 		// authentication chaining
 		$wgAuth->autoAuthSetup();
 
-		$wgAuth->printDebug( "Calling authenticate with username \
($wgLDAPAutoAuthUsername).", NONSENSITIVE ); +		$autoauthname = \
$wgAuth->getConf( 'AutoAuthUsername' ); +		$wgAuth->printDebug( "Calling \
authenticate with username ($autoauthname).", NONSENSITIVE ); +
 		// The user hasn't already been authenticated, let's check them
-		$authenticated = $wgAuth->authenticate( $wgLDAPAutoAuthUsername );
+		$authenticated = $wgAuth->authenticate( $autoauthname, '' );
 		if ( !$authenticated ) {
 			// If the user doesn't exist in LDAP, there isn't much reason to
 			// go any further.
@@ -50,12 +40,11 @@ class LdapAutoAuthentication {
 			return false;
 		}
 
-		// We need the username that MediaWiki will always use, *not* the one we
+		// We need the username that MediaWiki will always use, not necessarily \
the one we  // get from LDAP.
-		$mungedUsername = $wgAuth->getCanonicalName( $wgLDAPAutoAuthUsername );
+		$mungedUsername = $wgAuth->getCanonicalName( $autoauthname );
 
 		$wgAuth->printDebug( "User exists in LDAP; finding the user by name \
                ($mungedUsername) in MediaWiki.", NONSENSITIVE );
-
 		$localId = User::idFromName( $mungedUsername );
 		$wgAuth->printDebug( "Got id ($localId).", NONSENSITIVE );
 
@@ -79,7 +68,15 @@ class LdapAutoAuthentication {
 		return true;
 	}
 
-	static function attemptAddUser( $user, $mungedUsername ) {
+	/**
+	 * @param $user User
+	 * @param $mungedUsername String
+	 * @return bool
+	 */
+	public static function attemptAddUser( $user, $mungedUsername ) {
+		/**
+		 * @var $wgAuth LdapAuthenticationPlugin
+		 */
 		global $wgAuth;
 
 		if ( !$wgAuth->autoCreate() ) {
@@ -88,32 +85,40 @@ class LdapAutoAuthentication {
 		}
 
 		$wgAuth->printDebug( "User does not exist in local database; creating.", \
                NONSENSITIVE );
-
 		// Checks passed, create the user
 		$user->loadDefaults( $mungedUsername );
-		$user->addToDatabase();
-
+		$status = $user->addToDatabase();
+		if ( $status !== null && !$status->isOK() ) {
+			$wgAuth->printDebug( "Creation failed: " . $status->getWikiText(), \
NONSENSITIVE ); +			return false;
+		}
 		$wgAuth->initUser( $user, true );
 		$user->setCookies();
 		wfSetupSession();
-
 		# Update user count
 		$ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
 		$ssUpdate->doUpdate();
-
 		# Notify hooks (e.g. Newuserlog)
 		wfRunHooks( 'AuthPluginAutoCreate', array( $user ) );
 
 		return true;
 	}
 
-	/* No logout link in MW */
-	static function NoLogout( &$personal_urls, $title ) {
+	/**
+	 * No logout link in MW
+	 * @param $personal_urls array
+	 * @param $title Title
+	 * @return bool
+	 */
+	public static function NoLogout( &$personal_urls, $title ) {
+		/**
+		 * @var $wgAuth LdapAuthenticationPlugin
+		 */
 		global $wgAuth;
-		$wgAuth->printDebug( "Entering NoLogout.", NONSENSITIVE );
 
+		$wgAuth->printDebug( "Entering NoLogout.", NONSENSITIVE );
 		unset( $personal_urls['logout'] );
-
 		return true;
 	}
+
 }
diff --git a/extensions/LdapAuthentication/ldap.sql \
b/extensions/LdapAuthentication/ldap.sql new file mode 100644
index 0000000..fa96916
--- /dev/null
+++ b/extensions/LdapAuthentication/ldap.sql
@@ -0,0 +1,13 @@
+CREATE TABLE /*_*/ldap_domains (
+	-- IF for domain
+	domain_id int not null primary key auto_increment,
+
+	-- domain itself
+	domain varchar(255) binary not null,
+
+	-- User to which this domain belongs
+	user_id int not null
+
+) /*$wgDBTableOptions*/;
+
+CREATE INDEX /*i*/user_id on /*_*/ldap_domains (user_id);


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic