multiauth: migrated all files to the new OO API, written new API documentation
authormartinlanghoff <martinlanghoff>
Thu, 4 Jan 2007 04:52:42 +0000 (04:52 +0000)
committermartinlanghoff <martinlanghoff>
Thu, 4 Jan 2007 04:52:42 +0000 (04:52 +0000)
Author: Martin Langhoff <martin@catalyst.net.nz>

52 files changed:
auth/README
auth/README2 [new file with mode: 0644]
auth/authlib.php [new file with mode: 0644]
auth/cas/auth.php [new file with mode: 0644]
auth/cas/auth_ldap_sync_users.php
auth/cas/config.html
auth/cas/index_form.html
auth/cas/lib.php [deleted file]
auth/cas/login.php
auth/cas/logout.php
auth/db/auth.php [new file with mode: 0644]
auth/db/auth_db_sync_users.php
auth/db/config.html
auth/db/lib.php [deleted file]
auth/email/auth.php [new file with mode: 0644]
auth/email/config.html
auth/email/lib.php [deleted file]
auth/fc/auth.php [new file with mode: 0644]
auth/fc/config.html
auth/fc/fcFPP.php
auth/fc/lib.php [deleted file]
auth/imap/auth.php [new file with mode: 0644]
auth/imap/config.html
auth/imap/lib.php [deleted file]
auth/ldap/auth.php [new file with mode: 0644]
auth/ldap/auth_ldap_sync_users.php
auth/ldap/config.html
auth/ldap/lib.php [deleted file]
auth/manual/auth.php [new file with mode: 0644]
auth/manual/config.html
auth/manual/lib.php [deleted file]
auth/nntp/auth.php [new file with mode: 0644]
auth/nntp/config.html
auth/nntp/lib.php [deleted file]
auth/none/auth.php [new file with mode: 0644]
auth/none/config.html
auth/none/lib.php [deleted file]
auth/pam/auth.php [new file with mode: 0644]
auth/pam/config.html
auth/pam/lib.php [deleted file]
auth/pop3/auth.php [new file with mode: 0644]
auth/pop3/config.html
auth/pop3/lib.php [deleted file]
auth/radius/auth.php [new file with mode: 0644]
auth/radius/config.html
auth/radius/lib.php [deleted file]
auth/shibboleth/README.txt
auth/shibboleth/auth.php [new file with mode: 0644]
auth/shibboleth/config.html
auth/shibboleth/index.php
auth/shibboleth/lib.php [deleted file]
lang/en_utf8/auth.php

index 251d28d..3caa42f 100644 (file)
@@ -6,12 +6,17 @@ check that a user has provided a correct
    - username, and 
    - password.
 
-Even when external forms of authentication are being
-used, Moodle still maintains the internal "user" table 
-with all the associated information about that user such
-as name, email address and so on.
+Even when external forms of authentication are being used, Moodle still
+maintains the internal "user" table with all the associated information about
+that user such as name, email address and so on.
 
-The active method is set by the admin on the Configuration page.
+Multiauthentication in Moodle 1.8
+-------------------------------------
+
+The active methods are set by the admin on the Configuration page. Multiple
+authentication plugins can now be used and ordered in a fail-through sequence.
+One plugin can be selected for interactive login as well (which will need to be
+part of the enabled plugin sequence).
 
 
 email - authentication by email  (DEFAULT METHOD)
@@ -84,27 +89,127 @@ db  - Uses an external database to check username/password
       a new Moodle account is created
 
 
-------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
 
 Authentication API
+------------------
+
+Each authentication plugin is now contained in a subfolder as a class definition
+in the auth.php file. For instance, the LDAP authentication plugin is the class
+called auth_plugin_ldap defined in:
+
+   /auth/ldap/auth.php
+
+To instantiate the class, there is a function in lib/moodlelib called
+get_auth_plugin() that does the work for you:
+
+   $ldapauth = get_auth_plugin('ldap');
+
+If an auth is not specified, get_auth_plugin() will return you the auth plugin
+defined in the $CFG->auth variable.
+
+Auth plugin classes are pretty basic. They contain the same functions that were
+previously in each plugin's lib.php file, but refactored to become class
+methods, and tweaked to reference the plugin's instantiated config to get at the
+settings, rather than the global $CFG variable.
+
+Configuration
+-----------------
+
+All auth plugins must have a config property that contains the name value pairs
+from the config_plugins table. This is populated using the get_config() function
+in the constructor. The settings keys have also had the "auth_" prefix, as well
+as the auth plugin name, trimmed. For instance, what used to be
+
+   echo $CFG->auth_ldapversion;
+
+is now accessed as
+
+   echo $ldapauth->config->version;
+
+Authentication settings have been moved to the config_plugins database table,
+with the plugin field set to "auth/foo" (for instance, "auth/ldap").
+
+Upgrading from Moodle 1.7
+-----------------------------
+
+Moodle will upgrade the old auth settings (in $CFG->auth_foobar where foo is the
+auth plugin and bar is the setting) to the new style in the config_plugin
+database table.
+
+Method Names
+-----------------
+
+When the functions from lib.php were ported to methods in auth.php, the "auth_"
+prefix was dropped. For instance, calls to
+
+   auth_user_login($user, $pass);
+
+now become
+
+   $ldapauth->user_login($user, $pass);
+
+this also avoids having to worry about which auth/lib file to include since
+Moodle takes care of it for you when you create an instance with
+get_auth_plugin().
+
+Code Usage
+-----------------
+
+Code calling auth plugins can use method_exists() to determine plugin
+functionality, much in the same way that function_exists() was used until now.
+In addition, auth plugins provide some methods by default that can be called:
+
+user_login($username, $password)
+   This is the primary method that is used by the authenticate_user_login()
+   function in moodlelib.php. This method should return a boolean indicating
+   whether or not the username and password authenticate successfully.
+
+is_internal()
+   Returns true if this authentication plugin is "internal" (which means that
+   Moodle stores the users' passwords and other details in the local Moodle
+   database).
+
+can_change_password()
+   Returns true if the plugin can change the users' passwords.
+
+change_password_url()
+   Returns the URL for changing the users' passwords, or false if the default
+   URL can be used.
+
+user_update_password($username, $newpassword)
+   Updates the user's password.
 
-This file describes Moodle interface functions to authentication modules.
+config_form()
+   Displays the configuration form for the auth plugin, for use in the admin
+   pages.
 
-Most of functions are from ldap-authentication module and are not implemented (yet?)
-on other modules. Please feel free to extend other modules to support same features
-or roll your own module.
+process_config()
+   Saves the auth plugin's configuration to the database.
 
-Some of new function are still tested and are not documented here yet.
+Other Methods
+------------------
 
+Most of functions are from ldap-authentication module and are not implemented
+(yet?) on other modules. Please feel free to extend other modules to support
+same features or roll your own module.
 
+Some of the new functions are still to be tested and are not documented here
+yet.
 
 AUTHENTICATION
-Basic fuctions to authenticate users with external db
+
+Basic fuctions to authenticate users with external db.
 
 Mandatory: 
-    
-    auth_user_login ($username, $password) 
-    
+
+    auth_plugin_foo()
+
+    Constructor. At the least, it populates config member variable with settings
+    from the Moodle database. It makes sense to put other startup code here.
+
+    user_login($username, $password) 
+
     Authenticate username, password with userdatabase.
 
     Returns:
@@ -112,17 +217,18 @@ Mandatory:
     and false if they don't
 
 Optional:
-    
-    auth_get_userinfo($username)
-    
+
+    get_userinfo($username)
+
     Query other userinformation from database.
 
     Returns:
     Userinformation in array ( name => value, .... 
     or false in case of error
 
-    auth_validate_form(&$form, &$err)
-    
+
+    validate_form(&$form, &$err)
+
     Validate form data.
 
     Returns:
@@ -131,7 +237,7 @@ Optional:
 
 COURSE CREATING
 
-    auth_iscreator($username)
+    iscreator($username)
 
     should user have rights to create courses
 
@@ -145,15 +251,16 @@ Functions that enable usercreation, activation and deactivation
 from moodle to external database
   
   
-    auth_user_exists ($username) 
-   
+    user_exists ($username) 
+
     Checks if given username exist on external db
 
     Returns:
     true if given usernname exist or false
-    auth_user_create ($userobject,$plainpass) 
+
+
+    user_create ($userobject,$plainpass) 
+
     Creates new user to external db. User should be created
     in inactive stage until confirmed by email.
 
@@ -161,18 +268,18 @@ from moodle to external database
     True on success otherwise false
 
 
-    auth_user_activate ($username) 
-    
+    user_activate ($username) 
+
     activate new user after email-address is confirmed
 
     Returns:
     True on success otherwise false
 
 
-    auth_user_disable ($username) {
-    
+    user_disable ($username) {
+
     deactivate  user in external db.
-    
+
     Returns:
     True on success otherwise false
 
@@ -180,16 +287,16 @@ from moodle to external database
 
 USER INFORMATION AND SYNCRONIZATION
 
-    auth_get_userlist () 
+    get_userlist ()
 
     Get list of usernames in external db.
 
     Returns:
     All usernames in array or false on error.
-    
 
-    auth_get_users($filter='*') 
-    
+
+    get_users($filter='*') 
+
     Get ALL USEROBJECTS FROM EXTERNAL DB.
 
     Returns:
diff --git a/auth/README2 b/auth/README2
new file mode 100644 (file)
index 0000000..40ba274
--- /dev/null
@@ -0,0 +1,92 @@
+AUTHENTICATION PLUGINS
+----------------------
+Each authentication plugin is now contained in a subfolder as a class definition
+in the auth.php file. For instance, the LDAP authentication plugin is the class
+called auth_plugin_ldap defined in:
+
+   /auth/ldap/auth.php
+
+To instantiate the class, there is a function in lib/moodlelib called
+get_auth_plugin() that does the work for you:
+
+   $ldapauth = get_auth_plugin('ldap');
+
+If an auth is not specified, get_auth_plugin() will return you the auth plugin
+defined in the $CFG->auth variable.
+
+Auth plugin classes are pretty basic. They contain the same functions that were
+previously in each plugin's lib.php file, but refactored to become class
+methods, and tweaked to reference the plugin's instantiated config to get at the
+settings, rather than the global $CFG variable.
+
+Configuration
+-----------------
+
+All auth plugins must have a config property that contains the name value pairs
+from the config_plugins table. This is populated using the get_config() function
+in the constructor. The settings keys have also had the "auth_" prefix, as well
+as the auth plugin name, trimmed. For instance, what used to be
+
+   echo $CFG->auth_ldapversion;
+
+is now accessed as
+
+   echo $ldapauth->config->version;
+
+Authentication settings have been moved to the config_plugins database table,
+with the plugin field set to "auth/foo" (for instance, "auth/ldap").
+
+Method Names
+-----------------
+
+When the functions from lib.php were ported to methods in auth.php, the "auth_"
+prefix was dropped. For instance, calls to
+
+   auth_user_login($user, $pass);
+
+now become
+
+   $ldapauth->user_login($user, $pass);
+
+this also avoids having to worry about which auth/lib file to include since
+Moodle takes care of it for you when you create an instance with
+get_auth_plugin().
+
+Code Use
+-----------------
+
+Code calling auth plugins can use method_exists() to determine plugin
+functionality, much in the same way that function_exists() was used until now.
+In addition, auth plugins provide some methods by default that can be called:
+
+user_login($username, $password)
+   This is the primary method that is used by the authenticate_user_login()
+   function in moodlelib.php. This method should return a boolean indicating
+   whether or not the username and password authenticate successfully.
+
+is_internal()
+   Returns true if this authentication plugin is "internal" (which means that
+   Moodle stores the users' passwords and other details in the local Moodle
+   database).
+
+can_change_password()
+   Returns true if the plugin can change the users' passwords.
+
+change_password_url()
+   Returns the URL for changing the users' passwords, or false if the default
+   URL can be used.
+
+Other Methods
+-----------------
+
+get_userinfo()
+   This method should return an array of fields from the authentication source
+   for the given username.
+
+Upgrading from Moodle 1.7
+-----------------------------
+
+Moodle will upgrade the old auth settings (in $CFG->auth_foobar where foo is the
+auth plugin and bar is the setting) to the new style in the config_plugin
+database table.
+
diff --git a/auth/authlib.php b/auth/authlib.php
new file mode 100644 (file)
index 0000000..9aa2e75
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+/**
+ * @author Martin Dougiamas
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodle multiauth
+ *
+ * Multiple plugin authentication
+ * Support library
+ *
+ * 2006-08-28  File created, AUTH return values defined.
+ */
+
+/**
+ * Returned when the login was successful.
+ */
+define('AUTH_OK',     0);
+
+/**
+ * Returned when the login was unsuccessful.
+ */
+define('AUTH_FAIL',   1);
+
+/**
+ * Returned when the login was denied (a reason for AUTH_FAIL).
+ */
+define('AUTH_DENIED', 2);
+
+/**
+ * Returned when some error occurred (a reason for AUTH_FAIL).
+ */
+define('AUTH_ERROR',  4);
+
+?>
diff --git a/auth/cas/auth.php b/auth/cas/auth.php
new file mode 100644 (file)
index 0000000..cc716cd
--- /dev/null
@@ -0,0 +1,298 @@
+<?php
+/**
+ * @author Martin Dougiamas
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodle multiauth
+ *
+ * Authentication Plugin: CAS Authentication
+ *
+ * Authentication using CAS (Central Authentication Server).
+ *
+ * 2006-08-28  File created.
+ */
+
+// This page cannot be called directly
+if (!isset($CFG)) exit;
+
+/**
+ * CAS authentication plugin.
+ */
+class auth_plugin_cas {
+
+    /**
+     * The configuration details for the plugin.
+     */
+    var $config;
+
+    /**
+     * Constructor.
+     */
+    function auth_plugin_cas() {
+        $this->config = get_config('auth/cas');
+    }
+
+    /**
+     * Authenticates user againt CAS with LDAP.
+     * Returns true if the username and password work and false if they are
+     * wrong or don't exist.
+     *
+     * @param string $username The username
+     * @param string $password The password
+     * @returns bool Authentication success or failure.
+     */
+    function user_login ($username, $password) {
+
+        // TODO: find how to get at LDAP funcs
+        
+        global $CFG;
+
+        // don't allow blank usernames or passwords
+        if (!$username or !$password) {
+            return false;
+        }
+     
+        // CAS specific
+        if ($CFG->auth == "cas" and !empty($this->config->enabled)) {
+            if ($this->config->create_user == '0') {
+                if (record_exists('user', 'username', $username)) {
+                    return true;
+                }
+                else {
+                    return false;
+                }
+            }
+            else {
+                return true;
+            }
+        }
+
+        $ldap_connection = ldap_connect();
+
+        if ($ldap_connection) {
+            $ldap_user_dn = auth_ldap_find_userdn($ldap_connection, $username);
+          
+            // if ldap_user_dn is empty, user does not exist
+            if (!$ldap_user_dn) {
+                ldap_close($ldap_connection);
+                return false;
+            }
+
+            // Try to bind with current username and password
+            $ldap_login = ldap_bind($ldap_connection, $ldap_user_dn, $password);
+            ldap_close($ldap_connection);
+            if ($ldap_login) {
+               if ($this->config->create_user=='0') {  //cas specific
+                  if (record_exists('user', 'username', $username)) {
+                    return true;
+                  }else{
+                    return false;
+                  }
+               }else{
+                  return true;
+               }
+            }
+        } else {
+            ldap_close($ldap_connection);
+            error("LDAP part of CAS-module cannot connect to server: $CFG->ldap_host_url");
+        }
+        return false;
+    }
+
+    /**
+     * Authenticates user against CAS from screen login
+     * the user doesn't have a CAS Ticket yet.
+     *
+     * Returns an object user if the username and password work
+     * and nothing if they don't
+     *
+     * @param string  $username
+     * @param string  $password
+     *
+    */
+    function authenticate_user_login ($username, $password) {
+
+        // TODO: fix SOMEOTHER::
+
+        global $CFG;
+        // FIX ME: $cas_validate is not global
+        $cas_validate = true;
+        phpCAS::client($this->config->casversion, $this->config->hostname, (int) $this->config->port, $this->config->baseuri);
+        phpCAS::setLang($this->config->language);
+        phpCAS::forceAuthentication();
+        if ($this->config->create_user == '0') {
+            if (record_exists('user', 'username', phpCAS::getUser())) {
+                // TODO::SOMEOTHER::
+                $user = authenticate_user_login(phpCAS::getUser(), 'cas');
+            }
+            else {
+                // login as guest if CAS but not Moodle and not automatic creation
+                if ($CFG->guestloginbutton) {
+                    // TODO::SOMEOTHER::
+                    $user = authenticate_user_login('guest', 'guest');
+                }
+                else {
+                    // TODO::SOMEOTHER::
+                    $user = authenticate_user_login(phpCAS::getUser(), 'cas');
+                }
+            }
+        }
+        else {
+            // TODO::SOMEOTHER::
+            $user = authenticate_user_login(phpCAS::getUser(), 'cas');
+        }
+        return $user;
+    }
+
+    /**
+     * Authenticates user against CAS when first call of Moodle
+     * if already in CAS (cookie with the CAS ticket), don't have to log again (SSO)
+     *
+     * Returns an object user if the username and password work
+     * and nothing if they don't
+     *
+     * @param object $user
+     *
+    */
+    function automatic_authenticate ($user='') {
+
+        // TODO: fix SOMEOTHER::
+
+        global $CFG;
+        // FIX ME: $cas_validate is not global, but it works anyway ;-)
+        if (!$cas_validate) {
+            $cas_validate = true;
+            phpCAS::client($this->config->casversion, $this->config->hostname, (int) $this->config->port, $this->config->baseuri);
+            phpCAS::setLang($this->config->language);
+            $cas_user_exist = phpCAS::checkAuthentication();
+            if (!$cas_user_exist and !$CFG->guestloginbutton) {
+                $cas_user_exist=phpCAS::forceAuthentication();
+            }
+            if ($cas_user_exist) {
+                if ($this->config->create_user == '0') {
+                    if (record_exists('user', 'username', phpCAS::getUser())) {
+                        // TODO::SOMEOTHER::
+                        $user = authenticate_user_login(phpCAS::getUser(), 'cas');
+                    }
+                    else {
+                        // login as guest if CAS but not Moodle and not automatic creation
+                        if ($CFG->guestloginbutton) {
+                            // TODO::SOMEOTHER::
+                            $user = authenticate_user_login('guest', 'guest');
+                        }
+                        else {
+                            // TODO::SOMEOTHER::
+                            $user = authenticate_user_login(phpCAS::getUser(), 'cas');
+                        }
+                    }
+                }
+                else {
+                    // TODO::SOMEOTHER::
+                    $user = authenticate_user_login(phpCAS::getUser(), 'cas');
+                }
+                return $user;
+            }
+            else {
+                return;
+            }
+        }
+        else {
+            return $user;
+        }
+    }
+
+    /**
+     * Returns true if this authentication plugin is 'internal'.
+     *
+     * @returns bool
+     */
+    function is_internal() {
+        return false;
+    }
+
+    /**
+     * Returns true if this authentication plugin can change the user's
+     * password.
+     *
+     * @returns bool
+     */
+    function can_change_password() {
+        return false;
+    }
+
+    /**
+     * Prints a form for configuring this authentication plugin.
+     *
+     * This function is called from admin/auth.php, and outputs a full page with
+     * a form for configuring this plugin.
+     *
+     * @param array $page An object containing all the data for this page.
+     */
+    function config_form($config, $err) {
+        include 'config.html';
+    }
+
+    /**
+     * Returns the URL for changing the user's pw, or false if the default can
+     * be used.
+     *
+     * @returns bool
+     */
+    function change_password_url() {
+        return $this->config->changepasswordurl;
+    }
+
+    /**
+     * Processes and stores configuration data for this authentication plugin.
+     */
+    function process_config($config) {
+        // set to defaults if undefined
+        if (!isset ($config->hostname)) {
+            $config->hostname = '';
+        }
+        if (!isset ($config->port)) {
+            $config->port = '';
+        }
+        if (!isset ($config->casversion)) {
+            $config->casversion = '';
+        }
+        if (!isset ($config->baseuri)) {
+            $config->baseuri = '';
+        }
+        if (!isset ($config->language)) {
+            $config->language = '';
+        }
+        if (!isset ($config->use_cas)) {
+            $config->use_cas = '';
+        }
+        if (!isset ($config->auth_user_create)) {
+            $config->auth_user_create = '';
+        }
+        if (!isset ($config->create_user)) {
+            $config->create_user = '0';
+        }
+        if (!isset($config->changepasswordurl)) {
+            $config->changepasswordurl = '';
+        }
+
+        // save CAS settings
+        set_config('hostname',    $config->hostname,    'auth/cas');
+        set_config('port',        $config->port,        'auth/cas');
+        set_config('casversion',     $config->casversion,     'auth/cas');
+        set_config('baseuri',     $config->baseuri,     'auth/cas');
+        set_config('language',    $config->language,    'auth/cas');
+        set_config('use_cas',     $config->use_cas,     'auth/cas');
+        set_config('auth_user_create', $config->auth_user_create, 'auth/cas');
+        set_config('create_user', $config->create_user, 'auth/cas');
+        set_config('changepasswordurl', $config->changepasswordurl, 'auth/cas');
+
+        // save LDAP settings
+        // TODO: Do we want the CAS LDAP settings to be separate from the LDAP settings?
+        $ldapauth = get_auth_plugin('ldap');
+        $ldapauth->process_config($config);
+
+        return true;
+    }
+
+}
+
+?>
index 29e74d4..2e73161 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 
-if(!empty($_SERVER['GATEWAY_INTERFACE'])){
+if (!empty($_SERVER['GATEWAY_INTERFACE'])) {
     error_log("should not be called from apache!");
     exit;
 }
@@ -32,9 +32,10 @@ require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); // global moodl
 require_once($CFG->dirroot.'/course/lib.php');
 require_once($CFG->dirroot.'/lib/blocklib.php');
 require_once($CFG->dirroot.'/mod/resource/lib.php');
-require_once($CFG->dirroot.'/auth/cas/lib.php');  //cas specific
 require_once($CFG->dirroot.'/mod/forum/lib.php');
+require_once($CFG->dirroot.'/lib/moodlelib.php');
 $CFG->debug=10;
-auth_sync_users(1000, true  );
+$casauth = get_auth_plugin('cas');
+$casauth->sync_users(1000, true);
 
 ?>
\ No newline at end of file
index d6e1f91..9d2084e 100644 (file)
 <?php
-    require_once('languages.php');
-    // Initialize vars
-    if (!isset ($config->cas_hostname)) {
-        $config->cas_hostname = "";
+
+    global $CFG;
+    require_once 'languages.php';
+
+    $createoptions[0] = get_string("no");
+    $createoptions[1] = get_string("yes");
+
+    // set to defaults if undefined
+    if (!isset ($config->hostname)) {
+        $config->hostname = '';
     }
-    if (!isset ($config->cas_port)) {
-        $config->cas_port = "";
+    if (!isset ($config->port)) {
+        $config->port = '';
     }
-    if (!isset ($config->cas_version)) {
-        $config->cas_version = "";
+    if (!isset ($config->casversion)) {
+        $config->casversion = '';
     }
-    if (!isset ($config->cas_baseuri)) {
-        $config->cas_baseuri = "";
+    if (!isset ($config->baseuri)) {
+        $config->baseuri = '';
     }
-    if (!isset ($config->cas_language)) {
-        $config->cas_language = "";
+    if (!isset ($config->language)) {
+        $config->language = '';
     }
-    if (!isset ($config->cas_use_cas)) {
-        $config->cas_use_cas = "";
+    if (!isset ($config->use_cas)) {
+        $config->use_cas = '';
     }
-    if (!isset ($config->cas_create_user)) {
-        $config->cas_create_user = "0";
+    if (!isset ($config->auth_user_create)) {
+        $config->auth_user_create = '0';
+    }
+    if (!isset ($config->create_user)) {
+        $config->create_user = '0';
+    }
+    if (!isset($config->changepasswordurl)) {
+        $config->changepasswordurl = '';
     }
-?>
 
+?>
+<table cellspacing="0" cellpadding="5" border="0" align="center">
 
 <tr>
    <td colspan="2">
-        <h4><?php print_string("auth_cas_server_settings", "auth") ?> </h4>
+        <h4><?php print_string('auth_cas_server_settings', 'auth') ?> </h4>
    </td>
 </tr>
+
 <tr valign="top"  class="required">
-    <td align="right">cas_enabled:</td>
+    <td align="right">use_cas:</td>
     <td>
-    <?php
-       unset($options);
-       $options[1] = get_string("yes");
+        <?php
 
-       choose_from_menu ($options, "cas_enabled", $config->cas_enabled, get_string("no"),"","");?>
-    </td><td>
-    <?php  print_string("auth_cas_enabled","auth") ?>
+        unset($options);
+        $options[1] = get_string('yes');
+        choose_from_menu ($options, 'use_cas', $config->use_cas, get_string('no'), '', '');
+       
+        ?>
     </td>
+    <td><?php print_string('auth_cas_enabled', 'auth') ?></td>
 </tr>
-<tr valign="top"  class="required">
-    <td align="right">cas_hostname:</td>
-    <td>
-        <input name="cas_hostname" type="text" size="30" value="<?php echo $config->cas_hostname?>" />
-    <?php  if (isset($err["cas_hostname"])) formerr($err["cas_hostname"]); ?>
-    </td>
+
+<tr valign="top" class="required">
+    <td align="right">hostname:</td>
     <td>
-    <?php  print_string("auth_cas_hostname","auth") ?>
+        <input name="hostname" type="text" size="30" value="<?php echo $config->hostname ?>" />
+        <?php
+        
+        if (isset($err['hostname'])) {
+            formerr($err['hostname']);
+        }    
+        
+        ?>
     </td>
+    <td><?php print_string('auth_cas_hostname', 'auth') ?></td>
 </tr>
 
 <tr valign="top"  class="required">
-    <td align="right">cas_baseuri:</td>
+    <td align="right">baseuri:</td>
     <td>
-        <input name="cas_baseuri" type="text" size="30" value="<?php echo $config->cas_baseuri?>" />
-    <?php  if (isset($err["cas_baseuri"])) formerr($err["cas_baseuri"]); ?>
+        <input name="baseuri" type="text" size="30" value="<?php echo $config->baseuri ?>" />
+        <?php
+        
+        if (isset($err['baseuri'])) {
+            formerr($err['baseuri']);
+        }
+        
+        ?>
     </td>
+    <td><?php print_string('auth_cas_baseuri', 'auth') ?></td>
+</tr>
+
+<tr valign="top" class="required">
+    <td align="right">port:</td>
     <td>
-    <?php  print_string("auth_cas_baseuri","auth") ?>
+        <input name="port" type="text" size="30" value="<?php echo $config->port ?>" />
+        <?php
+        
+        if (isset($err['port'])) {
+            formerr($err['port']);
+        }
+        
+        ?>
     </td>
+    <td><?php print_string('auth_cas_port', 'auth') ?></td>
 </tr>
+
 <tr valign="top"  class="required">
-    <td align="right">cas_port:</td>
+    <td align="right">casversion:</td>
     <td>
-        <input name="cas_port" type="text" size="30" value="<?php echo $config->cas_port?>" />
-    <?php  if (isset($err["cas_port"])) formerr($err["cas_port"]); ?>
-    </td>
-    <td>
-    <?php  print_string("auth_cas_port","auth") ?>
+        <input name="casversion" type="text" size="30" value="<?php echo $config->casversion ?>" />
+        <?php
+
+        if (isset($err['casversion'])) {
+            formerr($err['casversion']);
+        }
+
+        ?>
     </td>
+    <td><?php print_string('auth_cas_version', 'auth') ?></td>
 </tr>
 
 <tr valign="top"  class="required">
-    <td align="right">cas_version:</td>
+    <td align="right">language:</td>
     <td>
-        <input name="cas_version" type="text" size="30" value="<?php echo $config->cas_version?>" />
-    <?php  if (isset($err["cas_version"])) formerr($err["cas_version"]); ?>
-    </td>
-    <td>
-    <?php  print_string("auth_cas_version","auth") ?>
+        <?php
+
+        choose_from_menu($CASLANGUAGES, 'language', $config->language, '');
+
+        ?>
     </td>
+    <td><?php print_string('auth_cas_language', 'auth') ?></td>
 </tr>
 
-<tr valign="top"  class="required">
-    <td align="right">cas_language:</td>
+<tr valign="top">
+    <td align="right">auth_user_create: </td>
     <td>
-        <?php choose_from_menu ($CASLANGUAGES, "cas_language", $config->cas_language, "");?>
+      <?php
+
+        choose_from_menu($createoptions, 'auth_user_create', $config->auth_user_create, '');
+        if (isset($err['auth_user_create'])) {
+            formerr($err['auth_user_create']);
+        }
+
+      ?>
     </td>
     <td>
-    <?php  print_string("auth_cas_language","auth") ?>
+        <?php print_string("auth_user_creation","auth"); ?>
     </td>
 </tr>
 
 <tr valign="top"  class="required">
-    <td align="right">cas_create_user:</td>
+    <td align="right">create_user:</td>
     <td>
-    <?php
-       unset($options);
-       $options[0] = get_string("no");
-       $options[1] = get_string("yes");
-
-       choose_from_menu ($options, "cas_create_user", $config->cas_create_user, "");?>
-    </td><td>
-    <?php  print_string("auth_cas_create_user","auth") ?>
+        <?php
+
+        unset($options);
+        $options[0] = get_string('no');
+        $options[1] = get_string('yes');
+        choose_from_menu($options, 'create_user', $config->create_user, '');
+
+        ?>
     </td>
+    <td><?php print_string('auth_cas_create_user', 'auth') ?></td>
 </tr>
 
-<?php
-    include($CFG->dirroot.'/auth/ldap/config.html');
-?>
+<tr valign="top">
+    <td align="right"> changepasswordurl: </td>
+    <td>
+        <input name="changepasswordurl" type="text" value="<?php echo $config->changepasswordurl ?>" />
+        <?php
 
+        if (isset($err['changepasswordurl'])) {
+            formerr($err['changepasswordurl']);
+        }
 
+        ?>
+    </td>
+    <td><?php print_string('changepasswordhelp', 'auth') ?></td>
+</tr>
 
+</table>
 
+<?php
+
+    $ldapplugin = get_auth_plugin('ldap');
+    $ldapplugin->config_form(get_config('auth/ldap'), $err);
+
+?>
index 7455483..0cc529d 100644 (file)
                  print_string("loginstepsnone");
                  break;
                default:
+                 $authplugin = get_auth_plugin($CFG->auth);
                  echo format_text($CFG->auth_instructions);
-                 if (!function_exists('auth_user_login')) {
-                    require_once("../auth/$CFG->auth/lib.php");
-                 }
-                 if (!empty($CFG->auth_user_create) and function_exists('auth_user_create') ){
+                 if (!empty($authplugin->config->user_create) and method_exists($authplugin, 'user_create')) {
 ?>
 
                  <div align="center">
diff --git a/auth/cas/lib.php b/auth/cas/lib.php
deleted file mode 100644 (file)
index 29d0aee..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-<?PHP
-// $Id$
-// author: romuald Lorthioir
-//CHANGELOG:
-//16/03/2005 Use of LDAP Module
-//05.02.2005 Added CAS module
-
-/* README!
-CAS Module
-This Module can be turn ON/OFF on admin screen.
-The /login/index.php module is intercepted and replace with the login.php.
-This Module is using the /auth/cas/index_form.html.
-This module is using the LDAP Module so you need the /auth/ldap directory.
-You can see /auth/ldap/lib.php for the other functions.
-*/
-defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
-
-define('AUTH_LDAP_NAME', 'cas'); // for ldap module
-require_once($CFG->dirroot.'/config.php');
-require_once($CFG->dirroot.'/auth/ldap/lib.php');
-require_once($CFG->dirroot.'/lib/cas/CAS.php');
-$cas_validate=false;
-
-/**
- * replace the ldap auth_user_login function
- * authenticates user againt CAS with ldap
- * Returns true if the username and password work
- * and false if they don't
- *
- * @param string  $username
- * @param string  $password
- *
-*/
-function cas_ldap_auth_user_login ($username, $password) {
-/// Returns true if the username and password work
-/// and false if they don't
-
-    global $CFG;
-    if (!$username or !$password) {    // Don't allow blank usernames or passwords
-        return false;
-    }
-    if ($CFG->auth == "cas" && !empty($CFG->cas_enabled)){ //cas specific
-       if ($CFG->cas_create_user=="0"){
-          if (record_exists('user', 'username', $username)){
-             return true;
-          }else{
-             return false;
-          }
-       }else{
-          return true;
-       }
-    }
-
-    $ldap_connection = auth_ldap_connect();
-
-    if ($ldap_connection) {
-        $ldap_user_dn = auth_ldap_find_userdn($ldap_connection, $username);
-      
-        //if ldap_user_dn is empty, user does not exist
-        if(!$ldap_user_dn){
-            ldap_close($ldap_connection);
-            return false;
-        }
-
-        // Try to bind with current username and password
-        $ldap_login = ldap_bind($ldap_connection, $ldap_user_dn, $password);
-        ldap_close($ldap_connection);
-        if ($ldap_login) {
-           if ($CFG->cas_create_user=="0"){  //cas specific
-              if (record_exists('user', 'username', $username)){
-                return true;
-              }else{
-                return false;
-              }
-           }else{
-              return true;
-           }
-        }
-    } else {
-        ldap_close($ldap_connection);
-        error("LDAP part of CAS-module cannot connect to server: $CFG->ldap_host_url");
-    }
-    return false;
-}
-
-/**
- * authenticates user against CAS from screen login
- * the user doesn't have a CAS Ticket yet.
- *
- * Returns an object user if the username and password work
- * and nothing if they don't
- *
- * @param string  $username
- * @param string  $password
- *
-*/
-function cas_authenticate_user_login ($username, $password) {
-
-   global $CFG;
-   // FIX ME: $cas_validate is not global
-   $cas_validate=true;
-   phpCAS::client($CFG->cas_version,$CFG->cas_hostname,(int)$CFG->cas_port,$CFG->cas_baseuri);
-   phpCAS::setLang($CFG->cas_language);
-   phpCAS::forceAuthentication();
-   if ($CFG->cas_create_user=="0"){
-      if (record_exists('user', 'username', phpCAS::getUser())) {
-         $user = authenticate_user_login(phpCAS::getUser(), 'cas');
-      }else{
-         //login as guest if CAS but not Moodle and not automatic creation
-         if ($CFG->guestloginbutton){
-             $user = authenticate_user_login('guest', 'guest');
-         }else{
-             $user = authenticate_user_login(phpCAS::getUser(), 'cas');
-         }
-      }
-   }else{
-      $user = authenticate_user_login(phpCAS::getUser(), 'cas');
-   }
-   return $user;
-}
-
-/**
- * authenticates user against CAS when first call of Moodle
- * if already in CAS (cookie with the CAS ticket), don't have to log again (SSO)
- *
- * Returns an object user if the username and password work
- * and nothing if they don't
- *
- * @param object $user
- *
-*/
-function cas_automatic_authenticate ($user="") {
-   global $CFG;
-   // FIX ME: $cas_validate is not global, but it works anyway ;-)
-   if (!$cas_validate){
-        $cas_validate=true;
-        phpCAS::client($CFG->cas_version,$CFG->cas_hostname,(int)$CFG->cas_port,$CFG->cas_baseuri);
-        phpCAS::setLang($CFG->cas_language);
-        $cas_user_exist=phpCAS::checkAuthentication();
-        if (!$cas_user_exist && !$CFG->guestloginbutton){
-           $cas_user_exist=phpCAS::forceAuthentication();
-        }
-        if ($cas_user_exist){
-           if ($CFG->cas_create_user=="0"){
-              if (record_exists('user', 'username', phpCAS::getUser())) {
-                 $user = authenticate_user_login(phpCAS::getUser(), 'cas');
-              }else{
-                 //login as guest if CAS but not Moodle and not automatic creation
-                 if ($CFG->guestloginbutton){
-                     $user = authenticate_user_login('guest', 'guest');
-                 }else{
-                     $user = authenticate_user_login(phpCAS::getUser(), 'cas');
-                 }
-              }
-           }else{
-
-              $user = authenticate_user_login(phpCAS::getUser(), 'cas');
-           }
-           return $user;
-        }else{
-           return;
-        }
-
-   }else{
-      return $user;
-   }
-}
-
-
-?>
\ No newline at end of file
index d7d09a4..504f68d 100644 (file)
@@ -24,6 +24,8 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
     }
 
     $loginsite = get_string("loginsite");
+    $casauth = get_auth_plugin('cas');
+    $ldapauth = get_auth_plugin('ldap');
 
 
     $frm = false;
@@ -59,9 +61,8 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
             $user = false;    /// Can't log in as guest if guest button is disabled
             $frm = false;
         } else if (!$user) {
-            if ($CFG->auth == "cas" && $frm->username != 'guest'){ /// Cas SSO case
-               require_once($CFG->dirroot.'/auth/cas/lib.php');
-               $user = cas_authenticate_user_login($frm->username, $frm->password);
+            if ($CFG->auth == "cas" && $frm->username != 'guest') { /// Cas SSO case
+               $user = $casauth->authenticate_user_login($frm->username, $frm->password);
             }else{
                $user = authenticate_user_login($frm->username, $frm->password);
             }
@@ -101,18 +102,19 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
             $SESSION->justloggedin = true;
 
             // Restore the calendar filters, if saved
-            if(intval(get_user_preferences('calendar_persistflt', 0))) {
+            if (intval(get_user_preferences('calendar_persistflt', 0))) {
                 include_once($CFG->dirroot.'/calendar/lib.php');
                 calendar_set_filters_status(get_user_preferences('calendar_savedflt', 0xff));
             }
 
             //Select password change url
-            if (is_internal_auth() || $CFG->{'auth_'.$USER->auth.'_stdchangepassword'}){
+            $userauth = get_auth_plugin($USER->auth);
+            if (method_exists($userauth, 'can_change_password') and $userauth->can_change_password()) {
                 $passwordchangeurl=$CFG->wwwroot.'/login/change_password.php';
             } 
 
             // check whether the user should be changing password
-            if (get_user_preferences('auth_forcepasswordchange', false)){
+            if (get_user_preferences('auth_forcepasswordchange', false)) {
                 if (isset($passwordchangeurl)) {
                     redirect($passwordchangeurl);
                 } else {
@@ -140,9 +142,8 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
 
             // check if user password has expired
             // Currently supported only for ldap-authentication module
-            if (isset($CFG->ldap_expiration) && $CFG->ldap_expiration == 1 ) {
-                if (function_exists('auth_password_expire')){
-                    $days2expire = auth_password_expire($USER->username);
+            if ($ldapauth->config->expiration == 1) {
+                    $days2expire = $ldapauth->password_expire($USER->username);
                     if (intval($days2expire) > 0 && intval($days2expire) < intval($CFG->{$USER->auth.'_expiration_warning'})) {
                         print_header("$site->fullname: $loginsite", "$site->fullname", $loginsite, $focus, "", true, "<div align=\"right\">$langmenu</div>"); 
                         notice_yesno(get_string('auth_passwordwillexpire', 'auth', $days2expire), $passwordchangeurl, $urltogo); 
@@ -153,8 +154,7 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
                         notice_yesno(get_string('auth_passwordisexpired', 'auth'), $passwordchangeurl, $urltogo);
                         print_footer();
                         exit;
-                    }    
-                }
+                    }
             }
 
             reset_login_count();
@@ -166,8 +166,7 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
             exit;
     
         } else {
-          if ($CFG->auth == "cas" ){ /// CAS error login
-            require_once($CFG->dirroot.'/auth/cas/lib.php');
+          if ($CFG->auth == "cas" ) { /// CAS error login
             $errormsg = get_string("invalidcaslogin");
             phpCAS::logout("$CFG->wwwroot/auth/cas/forbidden.php");
           }else{
@@ -175,8 +174,7 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
           }
         }
     }
-    require_once($CFG->dirroot.'/auth/cas/lib.php');
-    $user=cas_automatic_authenticate($user);
+    $user = $casauth->automatic_authenticate($user);
     if ($user) {
         if (! $user->confirmed ) {       // they never confirmed via email 
             print_header(get_string("mustconfirm"), get_string("mustconfirm") ); 
@@ -210,18 +208,19 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
         $SESSION->justloggedin = true;
 
         // Restore the calendar filters, if saved
-        if(intval(get_user_preferences('calendar_persistflt', 0))) {
+        if (intval(get_user_preferences('calendar_persistflt', 0))) {
             include_once($CFG->dirroot.'/calendar/lib.php');
             calendar_set_filters_status(get_user_preferences('calendar_savedflt', 0xff));
         }
 
         //Select password change url
-        if (is_internal_auth() || $CFG->{'auth_'.$USER->auth.'_stdchangepassword'}){
+        $userauth = get_auth_plugin($USER->auth);
+        if (method_exists($userauth, 'can_change_password') and $userauth->can_change_password()) {
             $passwordchangeurl=$CFG->wwwroot.'/login/change_password.php';
         }
 
         // check whether the user should be changing password
-        if (get_user_preferences('auth_forcepasswordchange', false)){
+        if (get_user_preferences('auth_forcepasswordchange', false)) {
             if (isset($passwordchangeurl)) {
                 redirect($passwordchangeurl);
             } else {
@@ -249,9 +248,8 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
 
         // check if user password has expired
         // Currently supported only for ldap-authentication module
-        if (isset($CFG->ldap_expiration) && $CFG->ldap_expiration == 1 ) {
-            if (function_exists('auth_password_expire')){
-                $days2expire = auth_password_expire($USER->username);
+        if ($ldapauth->config->expiration == 1) {
+                $days2expire = $ldapauth->password_expire($USER->username);
                 if (intval($days2expire) > 0 && intval($days2expire) < intval($CFG->{$USER->auth.'_expiration_warning'})) {
                     print_header("$site->fullname: $loginsite", "$site->fullname", $loginsite, $focus, "", true, "<div align=\"right\">$langmenu</div>"); 
                     notice_yesno(get_string('auth_passwordwillexpire', 'auth', $days2expire), $passwordchangeurl, $urltogo); 
@@ -262,8 +260,7 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
                     notice_yesno(get_string('auth_passwordisexpired', 'auth'), $passwordchangeurl, $urltogo);
                     print_footer();
                     exit;
-                }    
-            }
+                }
         }
 
         reset_login_count();
@@ -274,7 +271,7 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
 
         exit;
     } else {
-       if(!$CFG->guestloginbutton){
+       if (!$CFG->guestloginbutton) {
            $errormsg = get_string("invalidcaslogin");
            phpCAS::logout("$CFG->wwwroot/auth/cas/forbidden.php");
        }
index 9cb57a8..5f0a5cc 100644 (file)
@@ -4,7 +4,7 @@
 defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
 
        global $CFG;
-       if ($CFG->cas_logout){
+       if ($CFG->cas_logout) {
          require_once($CFG->dirroot.'/config.php');
          include_once($CFG->dirroot.'/lib/cas/CAS.php');
          phpCAS::client($CFG->cas_version,$CFG->cas_hostname,(int)$CFG->cas_port,$CFG->cas_baseuri);
diff --git a/auth/db/auth.php b/auth/db/auth.php
new file mode 100644 (file)
index 0000000..f1f126e
--- /dev/null
@@ -0,0 +1,560 @@
+<?php
+
+/**
+ * @author Martin Dougiamas
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodle multiauth
+ *
+ * Authentication Plugin: External Database Authentication
+ *
+ * Checks against an external database.
+ *
+ * 2006-08-28  File created.
+ */
+
+// This page cannot be called directly
+if (!isset($CFG)) exit;
+
+/**
+ * External database authentication plugin.
+ */
+class auth_plugin_db {
+
+    /**
+     * The configuration details for the plugin.
+     */
+    var $config;
+
+    /**
+     * Constructor.
+     */
+    function auth_plugin_db() {
+        $this->config = get_config('auth/db');
+    }
+
+    /**
+     * Returns true if the username and password work and false if they are
+     * wrong or don't exist.
+     *
+     * @param string $username The username
+     * @param string $password The password
+     * @returns bool Authentication success or failure.
+     */
+    function user_login ($username, $password) {
+
+        global $CFG;
+
+        // This is a hack to workaround what seems to be a bug in ADOdb with accessing 
+        // two databases of the same kind ... it seems to get confused when trying to access
+        // the first database again, after having accessed the second.
+        // The following hack will make the database explicit which keeps it happy
+        // This seems to broke postgesql so ..
+
+        $prefix = $CFG->prefix.'';    // Remember it.  The '' is to prevent PHP5 reference.. see bug 3223
+
+        if ($CFG->dbtype != 'postgres7') {
+            $CFG->prefix = $CFG->dbname.$CFG->prefix;
+        }
+
+        // Connect to the external database
+        $authdb = &ADONewConnection($this->config->type); 
+        $authdb->PConnect($this->config->host, $this->config->user, $this->config->pass, $this->config->name); 
+        $authdb->SetFetchMode(ADODB_FETCH_ASSOC);
+
+        if ($this->config->passtype === 'internal') { 
+            // lookup username externally, but resolve
+            // password locally -- to support backend that
+            // don't track passwords
+            $rs = $authdb->Execute("SELECT * FROM {$this->config->table} 
+                                     WHERE {$this->config->fielduser} = '$username' ");
+            $authdb->Close();
+
+            if (!$rs) {
+                notify("Could not connect to the specified authentication database...");
+
+                return false;
+            }
+        
+            if ( $rs->RecordCount() ) {
+                // user exists exterally
+                // check username/password internally
+                if ($user = get_record('user', 'username', $username)) {
+                    return validate_internal_user_password($user, $password);
+                }
+            } else {
+                // user does not exist externally
+                return false;
+            }  
+
+        } else { 
+            // normal case: use external db for passwords
+
+            if ($this->config->passtype === 'md5') {   // Re-format password accordingly
+                $password = md5($password);
+            }
+
+            $rs = $authdb->Execute("SELECT * FROM {$this->config->table} 
+                                WHERE {$this->config->fielduser} = '$username' 
+                                  AND {$this->config->fieldpass} = '$password' ");
+            $authdb->Close();
+            
+            $CFG->prefix = $prefix;
+            
+            if (!$rs) {
+                notify("Could not connect to the specified authentication database...");
+                return false;
+            }
+        
+            if ( $rs->RecordCount() ) {
+                return true;
+            } else {
+                return false;
+            }        
+            
+        }
+    }
+
+
+    /**
+     * Reads any other information for a user from external database,
+     * then returns it in an array
+     */
+    function get_userinfo($username) {
+
+        global $CFG;
+
+        ADOLoadCode($this->config->type);          
+        $authdb = &ADONewConnection();         
+        $authdb->PConnect($this->config->host, $this->config->user, $this->config->pass, $this->config->name); 
+        $authdb->SetFetchMode(ADODB_FETCH_ASSOC);
+
+        $fields = array("firstname", "lastname", "email", "phone1", "phone2", 
+                        "department", "address", "city", "country", "description", 
+                        "idnumber", "lang");
+
+        $result = array();
+
+        foreach ($fields as $field) {
+            if ($this->config->{'field_map_' . $field}) {
+                if ($rs = $authdb->Execute("SELECT " . $this->config->{'field_map_' . $field} . " FROM {$this->config->table}
+                                            WHERE {$this->config->fielduser} = '$username'")) {
+                    if ( $rs->RecordCount() == 1 ) {
+                        if (!empty($CFG->unicodedb)) {
+                            $result["$field"] = addslashes(stripslashes($rs->fields[0]));
+                        } else {
+                            $result["$field"] = addslashes(stripslashes(utf8_decode($rs->fields[0])));
+                        }
+                    }
+                }
+            }
+        }
+        $authdb->Close();
+
+        return $result;
+    }
+
+
+    function user_update_password($username, $newpassword) {
+
+        if ($this->config->passtype === 'internal') {
+            return set_field('user', 'password', md5($newpassword), 'username', $username);
+        } else {
+            // we should have never been called!
+            return false;
+        }
+    }
+
+    /**
+     * syncronizes user fron external db to moodle user table
+     *
+     * Sync shouid be done by using idnumber attribute, not username.
+     * You need to pass firstsync parameter to function to fill in
+     * idnumbers if they dont exists in moodle user table.
+     * 
+     * Syncing users removes (disables) users that dont exists anymore in external db.
+     * Creates new users and updates coursecreator status of users. 
+     * 
+     * @param bool $do_updates  Optional: set to true to force an update of existing accounts
+     *
+     * This implementation is simpler but less scalable than the one found in the LDAP module.
+     *
+     */
+    function sync_users ($do_updates=0) {
+        
+        global $CFG;
+        $pcfg = get_config('auth/db');
+
+        ///
+        /// list external users
+        ///
+        $userlist = $this->get_userlist();
+        $quoteduserlist = implode("', '", $userlist);
+        $quoteduserlist = "'$quoteduserlist'";
+
+        ///
+        /// delete obsolete internal users
+        ///
+           
+        // find obsolete users
+        if (count($userlist)) {
+            $sql = 'SELECT u.id, u.username 
+                    FROM ' . $CFG->prefix .'user u 
+                    WHERE u.auth=\'db\' AND u.deleted=\'0\' AND u.username NOT IN (' . $quoteduserlist . ')';
+        } else {
+            $sql = 'SELECT u.id, u.username 
+                    FROM ' . $CFG->prefix .'user u 
+                    WHERE u.auth=\'db\' AND u.deleted=\'0\' ';
+        }
+        $remove_users = get_records_sql($sql); 
+
+        if (!empty($remove_users)) {
+            print "User entries to remove: ". count($remove_users) . "\n";
+
+            begin_sql();
+            foreach ($remove_users as $user) {
+                //following is copy pasted from admin/user.php
+                //maybe this should moved to function in lib/datalib.php
+                unset($updateuser);
+                $updateuser->id = $user->id;
+                $updateuser->deleted = "1";
+                $updateuser->timemodified = time();
+                if (update_record("user", $updateuser)) {
+                    // unenrol_student($user->id);  // From all courses
+                    // remove_teacher($user->id);   // From all courses
+                    // remove_admin($user->id);
+                    delete_records('role_assignments', 'userid', $user->id); // unassign all roles
+                    notify(get_string("deletedactivity", "", fullname($user, true)) );
+                } else {
+                    notify(get_string("deletednot", "", fullname($user, true)));
+                }
+                //copy pasted part ends
+            }     
+            commit_sql();
+        } 
+        unset($remove_users); // free mem!   
+
+        if (!count($userlist)) {
+            // exit right here
+            // nothing else to do
+            return true;
+        }
+
+        ///
+        /// update existing accounts
+        ///
+        if ($do_updates) {
+            // narrow down what fields we need to update
+            $all_keys = array_keys(get_object_vars($this->config));
+            $updatekeys = array();
+            foreach ($all_keys as $key) {
+                if (preg_match('/^field_updatelocal_(.+)$/',$key, $match)) {
+                    if ($this->config->{$key} === 'onlogin') {
+                        array_push($updatekeys, $match[1]); // the actual key name
+                    }
+                }
+            }
+            // print_r($all_keys); print_r($updatekeys);
+            unset($all_keys); unset($key);
+
+            // only go ahead if we actually
+            // have fields to update locally
+            if (!empty($updatekeys)) {
+                $sql = 'SELECT u.id, u.username 
+                        FROM ' . $CFG->prefix .'user u 
+                        WHERE u.auth=\'db\' AND u.deleted=\'0\' AND u.username IN (' . $quoteduserlist . ')';
+                $update_users = get_records_sql($sql);
+            
+                foreach ($update_users as $user) {
+                    $this->db_update_user_record($user->username, $updatekeys);
+                }
+                unset($update_users); // free memory
+            }
+        }
+
+
+        ///
+        /// create missing accounts
+        ///
+        // NOTE: this is very memory intensive
+        // and generally inefficient
+        $sql = 'SELECT u.id, u.username 
+                FROM ' . $CFG->prefix .'user u 
+                WHERE u.auth=\'db\' AND u.deleted=\'0\'';
+
+        $users = get_records_sql($sql);
+        
+        // simplify down to usernames
+        $usernames = array();
+        foreach ($users as $user) {
+            array_push($usernames, $user->username);
+        }
+        unset($users);
+
+        $add_users = array_diff($userlist, $usernames);
+        unset($usernames);
+
+        if (!empty($add_users)) {
+            print "User entries to add: ". count($add_users). "\n";
+            begin_sql();
+            foreach($add_users as $user) {
+                $username = $user;
+                $user = $this->get_userinfo_asobj($user);
+                
+                // prep a few params
+                $user->username  = $username;
+                $user->modified  = time();
+                $user->confirmed = 1;
+                $user->auth      = 'db';
+                
+                // insert it
+                $old_debug=$CFG->debug; 
+                $CFG->debug=10;
+                
+                // maybe the user has been deleted before
+                if ($old_user = get_record('user', 'username', $user->username, 'deleted', 1)) {
+                    $user->id = $old_user->id;
+                    set_field('user', 'deleted', 0, 'username', $user->username);
+                    echo "Revived user $user->username id $user->id\n";
+                } elseif ($id=insert_record ('user',$user)) { // it is truly a new user
+                    echo "inserted user $user->username id $id\n";
+                    $user->id = $id;
+                    // if relevant, tag for password generation
+                    if ($this->config->passtype === 'internal') {
+                        set_user_preference('auth_forcepasswordchange', 1, $id);
+                        set_user_preference('create_password',          1, $id);
+                    }
+                } else {
+                    echo "error inserting user $user->username \n";
+                }
+                $CFG->debug=$old_debug;                        
+            }
+            commit_sql();
+            unset($add_users); // free mem
+        }
+        return true;
+    }
+
+    function user_exists ($username) {
+        $authdb = &ADONewConnection($this->config->type); 
+        $authdb->PConnect($this->config->host, $this->config->user, $this->config->pass, $this->config->name); 
+        $authdb->SetFetchMode(ADODB_FETCH_ASSOC);
+
+        $rs = $authdb->Execute("SELECT * FROM {$this->config->table} 
+                                     WHERE {$this->config->fielduser} = '$username' ");
+        $authdb->Close();
+
+        if (!$rs) {
+            notify("Could not connect to the specified authentication database...");
+            return false;
+        }
+        
+        if ( $rs->RecordCount() ) {
+            // user exists exterally
+            // check username/password internally
+            // ?? there is no $password variable, so why??
+            /*if ($user = get_record('user', 'username', $username)) {
+                return ($user->password == md5($password));
+            }*/
+            return $rs->RecordCount();
+        } else {
+            // user does not exist externally
+            return false;
+        }  
+    }
+
+
+    function get_userlist() {
+        // Connect to the external database
+        $authdb = &ADONewConnection($this->config->type); 
+        $authdb->PConnect($this->config->host,$this->config->user,$this->config->pass,$this->config->name); 
+        $authdb->SetFetchMode(ADODB_FETCH_ASSOC);
+
+        // fetch userlist
+        $rs = $authdb->Execute("SELECT {$this->config->fielduser} AS username
+                                FROM   {$this->config->table} ");
+        $authdb->Close();
+
+        if (!$rs) {
+            notify("Could not connect to the specified authentication database...");
+            return false;
+        }
+        
+        if ( $rs->RecordCount() ) {
+            $userlist = array();
+            while ($rec = $rs->FetchRow()) {
+                array_push($userlist, $rec['username']);
+            }
+            return $userlist;
+        } else {
+            return array();
+        }        
+    }
+
+    /**
+     * reads userinformation from DB and return it in an object
+     *
+     * @param string $username username
+     * @return array
+     */
+    function get_userinfo_asobj($username) {
+        $user_array = truncate_userinfo($this->get_userinfo($username));
+        $user = new object;
+        foreach($user_array as $key=>$value) {
+            $user->{$key} = $value;
+        }
+        return $user;
+    }
+
+    /*
+     * will update a local user record from an external source. 
+     * is a lighter version of the one in moodlelib -- won't do 
+     * expensive ops such as enrolment
+     *
+     * If you don't pass $updatekeys, there is a performance hit and 
+     * values removed from DB won't be removed from moodle.
+     */
+     function db_update_user_record($username, $updatekeys=false) {
+
+        $pcfg = get_config('auth/db');
+
+        //just in case check text case
+        $username = trim(moodle_strtolower($username));
+        
+        // get the current user record
+        $user = get_record('user', 'username', $username);
+        if (empty($user)) { // trouble
+            error_log("Cannot update non-existent user: $username");
+            die;
+        }
+
+        // TODO: this had a function_exists() - now we have a $this 
+        if ($newinfo = $this->get_userinfo($username)) {
+            $newinfo = truncate_userinfo($newinfo);
+            
+            if (empty($updatekeys)) { // all keys? this does not support removing values
+                $updatekeys = array_keys($newinfo);
+            }
+            
+            foreach ($updatekeys as $key) {
+                unset($value);
+                if (isset($newinfo[$key])) {
+                    $value = $newinfo[$key];
+                    $value = addslashes(stripslashes($value)); // Just in case
+                } else {
+                    $value = '';
+                }
+                if (!empty($this->config->{'field_updatelocal_' . $key})) { 
+                        if ($user->{$key} != $value) { // only update if it's changed
+                            set_field('user', $key, $value, 'username', $username);
+                        }
+                }
+            }
+        }
+        return get_record_select("user", "username = '$username' AND deleted <> '1'");
+    }
+
+    // A chance to validate form data, and last chance to 
+    // do stuff before it is inserted in config_plugin
+    function validate_form(&$form, &$err) {
+        if ($form['passtype'] === 'internal') {
+            $this->config->changepasswordurl = '';
+            set_config('changepasswordurl', '', 'auth/db');
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if this authentication plugin is 'internal'.
+     *
+     * @returns bool
+     */
+    function is_internal() {
+        return false;
+    }
+
+    /**
+     * Returns true if this authentication plugin can change the user's
+     * password.
+     *
+     * @returns bool
+     */
+    function can_change_password() {
+        return ($this->config->passtype === 'internal');
+    }
+
+    /**
+     * Returns the URL for changing the user's pw, or false if the default can
+     * be used.
+     *
+     * @returns bool
+     */
+    function change_password_url() {
+        return $this->config->changepasswordurl;
+    }
+
+    /**
+     * Prints a form for configuring this authentication plugin.
+     *
+     * This function is called from admin/auth.php, and outputs a full page with
+     * a form for configuring this plugin.
+     *
+     * @param array $page An object containing all the data for this page.
+     */
+    function config_form($config, $err) {
+        include "config.html";
+    }
+
+    /**
+     * Processes and stores configuration data for this authentication plugin.
+     */
+    function process_config($config) {
+        // set to defaults if undefined
+        if (!isset($config->host)) {
+            $config->host = "localhost";
+        }
+        if (!isset($config->type)) {
+            $config->type = "mysql";
+        }
+        if (!isset($config->name)) {
+            $config->name = "";
+        }
+        if (!isset($config->user)) {
+            $config->user = "";
+        }
+        if (!isset($config->pass)) {
+            $config->pass = "";
+        }
+        if (!isset($config->table)) {
+            $config->table = "";
+        }
+        if (!isset($config->fielduser)) {
+            $config->fielduser = "";
+        }
+        if (!isset($config->fieldpass)) {
+            $config->fieldpass = "";
+        }
+        if (!isset($config->passtype)) {
+            $config->passtype = "plaintext";
+        }
+        if (!isset($config->changepasswordurl)) {
+            $config->changepasswordurl = '';
+        }
+
+        // save settings
+        set_config('host',      $config->host,      'auth/db');
+        set_config('type',      $config->type,      'auth/db');
+        set_config('name',      $config->name,      'auth/db');
+        set_config('user',      $config->user,      'auth/db');
+        set_config('pass',      $config->pass,      'auth/db');
+        set_config('table',     $config->table,     'auth/db');
+        set_config('fielduser', $config->fielduser, 'auth/db');
+        set_config('fieldpass', $config->fieldpass, 'auth/db');
+        set_config('passtype',  $config->passtype,  'auth/db');
+        set_config('changepasswordurl', $config->changepasswordurl, 'auth/db');
+        
+        return true;
+    }
+
+}
+
+?>
index 3e05508..c9bcac9 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 
-if(!empty($_SERVER['GATEWAY_INTERFACE'])){
+if (!empty($_SERVER['GATEWAY_INTERFACE'])) {
     error_log("should not be called from apache!");
     exit;
 }
@@ -31,9 +31,10 @@ require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); // global moodl
 require_once($CFG->dirroot.'/course/lib.php');
 require_once($CFG->dirroot.'/lib/blocklib.php');
 require_once($CFG->dirroot.'/mod/resource/lib.php');
-require_once($CFG->dirroot.'/auth/db/lib.php');
+require_once($CFG->dirroot.'/lib/moodlelib.php');
 require_once($CFG->dirroot.'/mod/forum/lib.php');
 $CFG->debug=10;
-auth_sync_users(true  );
+$dbauth = get_auth_plugin('db');
+$dbauth->sync_users(true);
 
 ?>
\ No newline at end of file
index a455c3f..e2058e6 100644 (file)
@@ -1,54 +1,65 @@
 <?php
-    if (!isset($config->auth_dbhost)) {
-        $config->auth_dbhost = "localhost";
+
+    // set to defaults if undefined
+    if (!isset($config->host)) {
+        $config->host = "localhost";
+    }
+    if (!isset($config->type)) {
+        $config->type = "mysql";
     }
-    if (!isset($config->auth_dbtype)) {
-        $config->auth_dbtype = "mysql";
+    if (!isset($config->name)) {
+        $config->name = "";
     }
-    if (!isset($config->auth_dbname)) {
-        $config->auth_dbname = "";
+    if (!isset($config->user)) {
+        $config->user = "";
     }
-    if (!isset($config->auth_dbuser)) {
-        $config->auth_dbuser = "";
+    if (!isset($config->pass)) {
+        $config->pass = "";
     }
-    if (!isset($config->auth_dbpass)) {
-        $config->auth_dbpass = "";
+    if (!isset($config->table)) {
+        $config->table = "";
     }
-    if (!isset($config->auth_dbtable)) {
-        $config->auth_dbtable = "";
+    if (!isset($config->fielduser)) {
+        $config->fielduser = "";
     }
-    if (!isset($config->auth_dbfielduser)) {
-        $config->auth_dbfielduser = "";
+    if (!isset($config->fieldpass)) {
+        $config->fieldpass = "";
     }
-    if (!isset($config->auth_dbfieldpass)) {
-        $config->auth_dbfieldpass = "";
+    if (!isset($config->passtype)) {
+        $config->passtype = "plaintext";
     }
-    if (!isset($config->auth_dbpasstype)) {
-        $config->auth_dbpasstype = "plaintext";
+    if (!isset($config->changepasswordurl)) {
+        $config->changepasswordurl = '';
     }
 
     $pluginconfig = get_config('auth/db');
+
 ?>
+<table cellspacing="0" cellpadding="5" border="0" align="center">
 
 <tr valign="top" class="required">
-    <td align="right">auth_dbhost:</td>
+    <td align="right"> host: </td>
     <td>
-        <input name="auth_dbhost" type="text" size="30" value="<?php echo $config->auth_dbhost?>" />
-    <?php  if (isset($err["auth_dbhost"])) formerr($err["auth_dbhost"]); ?>
-    </td>
-    <td>
-    <?php  print_string("auth_dbhost","auth") ?>
+        <input name="host" type="text" size="30" value="<?php echo $config->host?>" />
+        <?php
+
+        if (isset($err["host"])) {
+            formerr($err["host"]);
+        }
+        
+        ?>
     </td>
+    <td><?php print_string("auth_dbhost", "auth") ?></td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_dbtype:</td>
+    <td align="right"> type: </td>
     <td>
     <?php  $dbtypes = array("access","ado_access", "ado", "ado_mssql", "borland_ibase", "csv", "db2", "fbsql", "firebird", "ibase", "informix72", "informix", "mssql", "mssql_n", "mysql", "mysqlt", "oci805", "oci8", "oci8po", "odbc", "odbc_mssql", "odbc_oracle", "oracle", "postgres64", "postgres7", "postgres", "proxy", "sqlanywhere", "sybase", "vfp");
        foreach ($dbtypes as $dbtype) {
            $dboptions[$dbtype] = $dbtype;
        }
-       choose_from_menu($dboptions, "auth_dbtype", $config->auth_dbtype, "");
+       choose_from_menu($dboptions, "type", $config->type, "");
     ?>
       
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_dbname:</td>
+    <td align="right"> name: </td>
     <td>
-    <input name="auth_dbname" type="text" size="30" value="<?php echo $config->auth_dbname?>" />
-    <?php  if (isset($err["auth_dbname"]))formerr($err["auth_dbname"]); ?>
-    </td>
-    <td>
-    <?php  print_string("auth_dbname","auth") ?>
+        <input name="name" type="text" size="30" value="<?php echo $config->name?>" />
+        <?php
+
+        if (isset($err["name"])) {
+            formerr($err["name"]);
+        }
+        
+        ?>
     </td>
+    <td><?php print_string("auth_dbname", "auth") ?></td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_dbuser:</td>
-    <td>
-    <input name="auth_dbuser" type="text" size="30" value="<?php echo $config->auth_dbuser?>" />
-    <?php  if (isset($err["auth_dbuser"])) formerr($err["auth_dbuser"]); ?>
-    </td>
+    <td align="right"> user: </td>
     <td>
-    <?php  print_string("auth_dbuser","auth") ?>
+        <input name="user" type="text" size="30" value="<?php echo $config->user?>" />
+        <?php
+
+        if (isset($err["user"])) {
+            formerr($err["user"]);
+        }
+
+        ?>
     </td>
+    <td><?php print_string("auth_dbuser", "auth") ?></td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_dbpass:</td>
+    <td align="right"> pass: </td>
     <td>
-    <input name="auth_dbpass" type="text" size="30" value="<?php echo $config->auth_dbpass?>" />
-    <?php  if (isset($err["auth_dbpass"])) formerr($err["auth_dbpass"]); ?>
+        <input name="pass" type="text" size="30" value="<?php echo $config->pass?>" />
+        <?php
+
+        if (isset($err["pass"])) {
+            formerr($err["pass"]);
+        }
+
+        ?>
     </td>
     <td>
-    <?php  print_string("auth_dbpass","auth") ?>
+    <?php print_string("auth_dbpass", "auth") ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_dbtable:</td>
-    <td>
-    <input name="auth_dbtable" type="text" size="30" value="<?php echo $config->auth_dbtable?>" />
-    <?php  if (isset($err["auth_dbtable"])) formerr($err["auth_dbtable"]); ?>
-    </td>
+    <td align="right"> table: </td>
     <td>
-    <?php  print_string("auth_dbtable","auth") ?>
+        <input name="table" type="text" size="30" value="<?php echo $config->table?>" />
+        <?php
+
+        if (isset($err["table"])) {
+            formerr($err["table"]);
+        }
+
+        ?>
     </td>
+    <td><?php print_string("auth_dbtable", "auth") ?></td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_dbfielduser:</td>
-    <td>
-    <input name="auth_dbfielduser" type="text" size="30" value="<?php echo $config->auth_dbfielduser?>" />
-    <?php  if (isset($err["auth_dbfielduser"])) formerr($err["auth_dbfielduser"]); ?>
-    </td>
+    <td align="right"> fielduser: </td>
     <td>
-    <?php  print_string("auth_dbfielduser","auth") ?>
+        <input name="fielduser" type="text" size="30" value="<?php echo $config->fielduser?>" />
+        <?php
+
+        if (isset($err["fielduser"])) {
+            formerr($err["fielduser"]);
+        }
+
+        ?>
     </td>
+    <td><?php print_string("auth_dbfielduser", "auth") ?></td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_dbfieldpass:</td>
+    <td align="right"> fieldpass: </td>
     <td>
-    <input name="auth_dbfieldpass" type="text" size="30" value="<?php echo $config->auth_dbfieldpass?>" />
-    <?php  if (isset($err["auth_dbfieldpass"])) formerr($err["auth_dbfieldpass"]); ?>
-    </td>
-    <td>
-    <?php  print_string("auth_dbfieldpass","auth") ?>
+        <input name="fieldpass" type="text" size="30" value="<?php echo $config->fieldpass?>" />
+        <?php
+
+        if (isset($err["fieldpass"])) {
+            formerr($err["fieldpass"]);
+        }
+
+        ?>
     </td>
+    <td><?php print_string("auth_dbfieldpass", "auth") ?></td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_dbpasstype:</td>
-    <td>
-    <?php  
-       $passtype["plaintext"] = get_string("plaintext", "auth");
-       $passtype["md5"]       = get_string("md5", "auth");
-       $passtype["internal"]  = get_string("internal", "auth");
-       
-       choose_from_menu($passtype, "auth_dbpasstype", $config->auth_dbpasstype, "");
-    ?>
-      
-    </td>
+    <td align="right"> passtype: </td>
     <td>
-    <?php  print_string("auth_dbpasstype","auth") ?>
+        <?php  
+
+        $passtype["plaintext"] = get_string("plaintext", "auth");
+        $passtype["md5"]       = get_string("md5", "auth");
+        $passtype["internal"]  = get_string("internal", "auth");
+        choose_from_menu($passtype, "passtype", $config->passtype, "");
+
+        ?>
     </td>
+    <td><?php print_string("auth_dbpasstype", "auth") ?></td>
 </tr>
 
-<?php print_auth_lock_options($auth, $user_fields, get_string("auth_dbextrafields","auth"), true, false);  ?>
-
 <tr valign="top">
-    <td align="right"><?php  print_string("instructions", "auth") ?>:</td>
-    <td>
-    <textarea name="auth_instructions" cols="30" rows="10" wrap="virtual"><?php  p($config->auth_instructions) ?></textarea> 
-    </td>
+    <td align="right"> changepasswordurl: </td>
     <td>
-    <?php  print_string("authinstructions","auth") ?>
-    <?php  helpbutton("text", get_string("helptext")) ?>
+        <input name="changepasswordurl" type="text" value="<?php echo $config->changepasswordurl ?>" />
+        <?php
+
+        if (isset($err['changepasswordurl'])) {
+            formerr($err['changepasswordurl']);
+        }
+
+        ?>
     </td>
+    <td><?php print_string('changepasswordhelp', 'auth') ?></td>
 </tr>
+<?php 
+
+global $user_fields;
+print_auth_lock_options('db', $user_fields, get_string('auth_dbextrafields', 'auth'), true, false);
+
+?>
+</table>
diff --git a/auth/db/lib.php b/auth/db/lib.php
deleted file mode 100644 (file)
index e0db9bc..0000000
+++ /dev/null
@@ -1,463 +0,0 @@
-<?php  // $Id$
-       // Authentication by looking up an external database table
-
-
-function auth_user_login ($username, $password) {
-// Returns true if the username and password work
-// and false if they are wrong or don't exist.
-
-    global $CFG;
-
-    // This is a hack to workaround what seems to be a bug in ADOdb with accessing 
-    // two databases of the same kind ... it seems to get confused when trying to access
-    // the first database again, after having accessed the second.
-    // The following hack will make the database explicit which keeps it happy
-    // This seems to broke postgesql so ..
-
-    $prefix = $CFG->prefix.'';    // Remember it.  The '' is to prevent PHP5 reference.. see bug 3223
-
-    if ($CFG->dbtype != 'postgres7') {
-        $CFG->prefix = $CFG->dbname.$CFG->prefix;
-    }
-
-    // Connect to the external database
-    $authdb = &ADONewConnection($CFG->auth_dbtype); 
-    $authdb->PConnect($CFG->auth_dbhost,$CFG->auth_dbuser,$CFG->auth_dbpass,$CFG->auth_dbname);
-    $authdb->SetFetchMode(ADODB_FETCH_ASSOC); ///Set Assoc mode always after DB connection
-
-    if ($CFG->auth_dbpasstype === 'internal') { 
-        // lookup username externally, but resolve
-        // password locally -- to support backend that
-        // don't track passwords
-        $rs = $authdb->Execute("SELECT * FROM $CFG->auth_dbtable 
-                                 WHERE $CFG->auth_dbfielduser = '$username' ");
-        $authdb->Close();
-
-        if (!$rs) {
-            notify("Could not connect to the specified authentication database...");
-
-            return false;
-        }
-    
-        if ( $rs->RecordCount() ) {
-            // user exists exterally
-            // check username/password internally
-            if ($user = get_record('user', 'username', $username)) {
-                return validate_internal_user_password($user, $password);
-            }
-        } else {
-            // user does not exist externally
-            return false;
-        }  
-
-    } else { 
-        // normal case: use external db for passwords
-
-        if ($CFG->auth_dbpasstype === 'md5') {   // Re-format password accordingly
-            $password = md5($password);
-        }
-
-        $rs = $authdb->Execute("SELECT * FROM $CFG->auth_dbtable 
-                            WHERE $CFG->auth_dbfielduser = '$username' 
-                              AND $CFG->auth_dbfieldpass = '$password' ");
-        $authdb->Close();
-        
-        $CFG->prefix = $prefix;
-        
-        if (!$rs) {
-            notify("Could not connect to the specified authentication database...");
-            return false;
-        }
-    
-        if ( $rs->RecordCount() ) {
-            return true;
-        } else {
-            return false;
-        }        
-        
-    }
-}
-
-
-function auth_get_userinfo($username){
-// Reads any other information for a user from external database,
-// then returns it in an array
-
-    global $CFG;
-
-    $config = (array) $CFG;
-
-    $pcfg = get_config('auth/db');
-    $pcfg = (array) $pcfg;
-
-    ADOLoadCode($CFG->auth_dbtype);          
-    $authdb = &ADONewConnection();         
-    $authdb->PConnect($CFG->auth_dbhost,$CFG->auth_dbuser,$CFG->auth_dbpass,$CFG->auth_dbname); 
-    $authdb->SetFetchMode(ADODB_FETCH_ASSOC); ///Set Assoc mode always after DB connection
-
-    $fields = array("firstname", "lastname", "email", "phone1", "phone2", 
-                    "department", "address", "city", "country", "description", 
-                    "idnumber", "lang");
-
-    $result = array();
-
-    foreach ($fields as $field) {
-        if ($pcfg["field_map_$field"]) {
-            if ($rs = $authdb->Execute("SELECT ".$pcfg["field_map_$field"]." FROM $CFG->auth_dbtable
-                                        WHERE $CFG->auth_dbfielduser = '$username'")) {
-                if ( $rs->RecordCount() == 1 ) {
-                    // TODO: fix encoding conversion
-                    $result["$field"] = addslashes(stripslashes($rs->fields[0]));
-                }
-            }
-        }
-    }
-
-    return $result;
-}
-
-
-function auth_user_update_password($username, $newpassword) {
-    global $CFG;
-    if ($CFG->auth_dbpasstype === 'internal') {
-        return set_field('user', 'password', md5($newpassword), 'username', $username);
-    } else {
-        // we should have never been called!
-        return false;
-    }
-}
-
-/**
- * syncronizes user fron external db to moodle user table
- *
- * Sync shouid be done by using idnumber attribute, not username.
- * You need to pass firstsync parameter to function to fill in
- * idnumbers if they dont exists in moodle user table.
- * 
- * Syncing users removes (disables) users that dont exists anymore in external db.
- * Creates new users and updates coursecreator status of users. 
- * 
- * @param bool $do_updates  Optional: set to true to force an update of existing accounts
- *
- * This implementation is simpler but less scalable than the one found in the LDAP module.
- *
- */
-function auth_sync_users ($do_updates=0) {
-    
-    global $CFG;
-    $pcfg = get_config('auth/db');
-
-    ///
-    /// list external users
-    ///
-    $userlist = auth_get_userlist();
-    $quoteduserlist = implode("', '", $userlist);
-    $quoteduserlist = "'$quoteduserlist'";
-
-    ///
-    /// delete obsolete internal users
-    ///
-       
-    // find obsolete users
-    if (count($userlist)) {
-        $sql = 'SELECT u.id, u.username 
-                FROM ' . $CFG->prefix .'user u 
-                WHERE u.auth=\'db\' AND u.deleted=\'0\' AND u.username NOT IN (' . $quoteduserlist . ')';
-    } else {
-        $sql = 'SELECT u.id, u.username 
-                FROM ' . $CFG->prefix .'user u 
-                WHERE u.auth=\'db\' AND u.deleted=\'0\' ';
-    }
-    $remove_users = get_records_sql($sql); 
-
-    if (!empty($remove_users)){
-        print "User entries to remove: ". count($remove_users) . "\n";
-
-        begin_sql();
-        foreach ($remove_users as $user) {
-            //following is copy pasted from admin/user.php
-            //maybe this should moved to function in lib/datalib.php
-            unset($updateuser);
-            $updateuser->id = $user->id;
-            $updateuser->deleted = "1";
-            $updateuser->timemodified = time();
-            if (update_record("user", $updateuser)) {
-                // unenrol_student($user->id);  // From all courses
-                // remove_teacher($user->id);   // From all courses
-                // remove_admin($user->id);
-                delete_records('role_assignments', 'userid', $user->id); // unassign all roles
-                notify(get_string("deletedactivity", "", fullname($user, true)) );
-            } else {
-                notify(get_string("deletednot", "", fullname($user, true)));
-            }
-            //copy pasted part ends
-        }     
-        commit_sql();
-    } 
-    unset($remove_users); // free mem!   
-
-    if (!count($userlist)) {
-        // exit right here
-        // nothing else to do
-        return true;
-    }
-
-    ///
-    /// update existing accounts
-    ///
-    if ($do_updates) {
-        // narrow down what fields we need to update
-        $all_keys = array_keys(get_object_vars($pcfg));
-        $updatekeys = array();
-        foreach ($all_keys as $key) {
-            if (preg_match('/^field_updatelocal_(.+)$/',$key, $match)) {
-                if ($pcfg->{$key} === 'onlogin') {
-                    array_push($updatekeys, $match[1]); // the actual key name
-                }
-            }
-        }
-        // print_r($all_keys); print_r($updatekeys);
-        unset($all_keys); unset($key);
-
-        // only go ahead if we actually
-        // have fields to update locally
-        if (!empty($updatekeys)) {
-            $sql = 'SELECT u.id, u.username 
-                    FROM ' . $CFG->prefix .'user u 
-                    WHERE u.auth=\'db\' AND u.deleted=\'0\' AND u.username IN (' . $quoteduserlist . ')';
-            $update_users = get_records_sql($sql);
-        
-            foreach ($update_users as $user) {
-                auth_db_update_user_record($user->username, $updatekeys);
-            }
-            unset($update_users); // free memory
-        }
-    }
-
-
-    ///
-    /// create missing accounts
-    ///
-    // NOTE: this is very memory intensive
-    // and generally inefficient
-    $sql = 'SELECT u.id, u.username 
-            FROM ' . $CFG->prefix .'user u 
-            WHERE u.auth=\'db\' AND u.deleted=\'0\'';
-
-    $users = get_records_sql($sql);
-    
-    // simplify down to usernames
-    $usernames = array();
-    foreach ($users as $user) {
-        array_push($usernames, $user->username);
-    }
-    unset($users);
-
-    $add_users = array_diff($userlist, $usernames);
-    unset($usernames);
-
-    if(!empty($add_users)){
-        print "User entries to add: ". count($add_users). "\n";
-        begin_sql();
-        foreach($add_users as $user){
-            $username = $user;
-            $user = auth_get_userinfo_asobj($user);
-            
-            // prep a few params
-            $user->username  = $username;
-            $user->modified  = time();
-            $user->confirmed = 1;
-            $user->auth      = 'db';
-            
-            // insert it
-            $old_debug=$CFG->debug; 
-            $CFG->debug=10;
-            
-            // maybe the user has been deleted before
-            if ($old_user = get_record('user', 'username', $user->username, 'deleted', 1)) {
-                $user->id = $old_user->id;
-                set_field('user', 'deleted', 0, 'username', $user->username);
-                echo "Revived user $user->username id $user->id\n";
-            } elseif ($id=insert_record ('user',$user)) { // it is truly a new user
-                echo "inserted user $user->username id $id\n";
-                $user->id = $id;
-                // if relevant, tag for password generation
-                if ($CFG->auth_dbpasstype === 'internal') {
-                    set_user_preference('auth_forcepasswordchange', 1, $id);
-                    set_user_preference('create_password',          1, $id);
-                }
-            } else {
-                echo "error inserting user $user->username \n";
-            }
-            $CFG->debug=$old_debug;                        
-        }
-        commit_sql();
-        unset($add_users); // free mem
-    }
-    return true;
-}
-
-function auth_user_exists ($username) {
-    global $CFG;
-    $authdb = &ADONewConnection($CFG->auth_dbtype); 
-    $authdb->PConnect($CFG->auth_dbhost,$CFG->auth_dbuser,$CFG->auth_dbpass,$CFG->auth_dbname); 
-    $authdb->SetFetchMode(ADODB_FETCH_ASSOC); ///Set Assoc mode always after DB connection
-
-    $rs = $authdb->Execute("SELECT * FROM $CFG->auth_dbtable 
-                                 WHERE $CFG->auth_dbfielduser = '$username' ");
-    $authdb->Close();
-
-    if (!$rs) {
-        notify("Could not connect to the specified authentication database...");
-        return false;
-    }
-    
-    if ( $rs->RecordCount() ) {
-        // user exists exterally
-        // check username/password internally
-        // ?? there is no $password variable, so why??
-        /*if ($user = get_record('user', 'username', $username)) {
-            return ($user->password == md5($password));
-        }*/
-        return $rs->RecordCount();
-    } else {
-        // user does not exist externally
-        return false;
-    }  
-}
-
-
-function auth_get_userlist() {
-
-    global $CFG;
-
-    // Connect to the external database
-    $authdb = &ADONewConnection($CFG->auth_dbtype); 
-    $authdb->PConnect($CFG->auth_dbhost,$CFG->auth_dbuser,$CFG->auth_dbpass,$CFG->auth_dbname); 
-    $authdb->SetFetchMode(ADODB_FETCH_ASSOC); ///Set Assoc mode always after DB connection
-
-    // fetch userlist
-    $rs = $authdb->Execute("SELECT $CFG->auth_dbfielduser AS username
-                            FROM   $CFG->auth_dbtable ");
-    $authdb->Close();
-
-    if (!$rs) {
-        notify("Could not connect to the specified authentication database...");
-        return false;
-    }
-    
-    if ( $rs->RecordCount() ) {
-        $userlist = array();
-        while ($rec = $rs->FetchRow()) {
-            array_push($userlist, $rec['username']);
-        }
-        return $userlist;
-    } else {
-        return array();
-    }        
-}
-
-/**
- * reads userinformation from DB and return it in an object
- *
- * @param string $username username
- * @return array
- */
-function auth_get_userinfo_asobj($username){
-    $user_array = truncate_userinfo(auth_get_userinfo($username));
-    $user = new object;
-    foreach($user_array as $key=>$value){
-        $user->{$key} = $value;
-    }
-    return $user;
-}
-
-function auth_db_update_user_record($username, $updatekeys=false) {
-/// will update a local user record from an external source. 
-/// is a lighter version of the one in moodlelib -- won't do 
-/// expensive ops such as enrolment
-///
-/// If you don't pass $updatekeys, there is a performance hit and 
-/// values removed from DB won't be removed from moodle. 
-
-    global $CFG;
-
-    $pcfg = get_config('auth/db');
-
-    //just in case check text case
-    $username = trim(moodle_strtolower($username));
-    
-    // get the current user record
-    $user = get_record('user', 'username', $username);
-    if (empty($user)) { // trouble
-        error_log("Cannot update non-existent user: $username");
-        die;
-    }
-
-    if (function_exists('auth_get_userinfo')) {
-        if ($newinfo = auth_get_userinfo($username)) {
-            $newinfo = truncate_userinfo($newinfo);
-            
-            if (empty($updatekeys)) { // all keys? this does not support removing values
-                $updatekeys = array_keys($newinfo);
-            }
-            
-            foreach ($updatekeys as $key){
-                unset($value);
-                if (isset($newinfo[$key])) {
-                    $value = $newinfo[$key];
-                    $value = addslashes(stripslashes($value)); // Just in case
-                } else {
-                    $value = '';
-                }
-                if (!empty($pcfg->{'field_updatelocal_' . $key})) { 
-                       if ($user->{$key} != $value) { // only update if it's changed
-                           set_field('user', $key, $value, 'username', $username);
-                       }
-                }
-            }
-        }
-    }
-    return get_record_select("user", "username = '$username' AND deleted <> '1'");
-}
-
-// A chance to validate form data, and last chance to 
-// do stuff before it is inserted in config_plugin
-function auth_validate_form(&$form, &$err) {
-    
-    // compat until we rework auth a bit
-    if ($form['auth_dbpasstype'] === 'internal') {
-        $CFG->auth_db_stdchangepassword = true;
-        if ($conf = get_record('config', 'name', 'auth_db_stdchangepassword')) {
-            $conf->value = 1;
-            if (! update_record('config', $conf)) {
-                notify("Could not update $name to $value");
-            }
-        } else {
-            $conf = new StdClass;
-            $conf->name = 'auth_db_stdchangepassword';
-            $conf->value = 1;
-            if (! insert_record('config', $conf)) {
-                notify("Error: could not add new variable $name !");
-            }
-        }
-    } else {
-        $CFG->auth_db_stdchangepassword = false;
-        if ($conf = get_record('config', 'name', 'auth_db_stdchangepassword')) {
-            $conf->value = 0;
-            if (! update_record('config', $conf)) {
-                notify("Could not update $name to $value");
-            }
-        } else {
-            $conf = new StdClass;
-            $conf->name = 'auth_db_stdchangepassword';
-            $conf->value = 0;
-            if (! insert_record('config', $conf)) {
-                notify("Error: could not add new variable $name !");
-            }
-        }
-    }
-    return true;
-}
-
-?>
diff --git a/auth/email/auth.php b/auth/email/auth.php
new file mode 100644 (file)
index 0000000..cec823d
--- /dev/null
@@ -0,0 +1,166 @@
+<?php
+
+/**
+ * @author Martin Dougiamas
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodle multiauth
+ *
+ * Authentication Plugin: Email Authentication
+ *
+ * Standard authentication function.
+ *
+ * 2006-08-28  File created.
+ */
+
+// This page cannot be called directly
+if (!isset($CFG)) exit;
+
+/**
+ * Error codes for user confirm
+ */
+define('AUTH_CONFIRM_FAIL', 0);
+define('AUTH_CONFIRM_OK', 1);
+define('AUTH_CONFIRM_ALREADY', 2);
+define('AUTH_CONFIRM_ERROR', 3);
+// TODO: instead of integers these could be the language keys?
+
+
+/**
+ * Email authentication plugin.
+ */
+class auth_plugin_email {
+
+    /**
+     * The configuration details for the plugin.
+     */
+    var $config;
+
+    /**
+     * Constructor.
+     */
+    function auth_plugin_email() {
+        $this->config = get_config('auth/email');
+    }
+
+    /**
+     * Returns true if the username and password work and false if they are
+     * wrong or don't exist.
+     *
+     * @param string $username The username
+     * @param string $password The password
+     * @returns bool Authentication success or failure.
+     */
+    function user_login ($username, $password) {
+        if ($user = get_record('user', 'username', $username)) {
+            return validate_internal_user_password($user, $password);
+        }
+        return false;
+    }
+
+    /*
+     * Updates the user's password.
+     *
+     * called when the user password is updated.
+     *
+     * @param mixed $username    Username
+     * @param mixed $newpassword Plaintext password
+     * @return boolean result
+     *
+     */
+    function user_update_password($username, $newpassword) {
+        $user = get_complete_user_data('username', $username);
+        return update_internal_user_password($user, $newpassword);
+    }
+
+    /*
+     * Sign up a new user ready for confirmation.
+     */
+    function user_signup($user, $notify = true) {
+        if (! ($user->id = insert_record('user', $user)) ) {
+            error('Could not add your record to the database!');
+        }
+        if (! send_confirmation_email($user)) {
+            error('Tried to send you an email but failed!');
+        }
+
+        if ($notify) {
+            global $CFG;
+            $emailconfirm = get_string('emailconfirm');
+            print_header($emailconfirm, $emailconfirm, $emailconfirm);
+            notice(get_string('emailconfirmsent', '', $user->email), "$CFG->wwwroot/index.php");
+        }        
+    }
+
+    /*
+     * Confirm the new user as registered.
+     */
+    function user_confirm($username, $confirmsecret) {
+        $user = get_complete_user_data('username', $username);
+
+        if (!empty($user)) {
+            if ($user->confirmed) {
+                return AUTH_CONFIRM_ALREADY;
+            }
+            if ($user->secret == $confirmsecret) {   // They have provided the secret key to get in
+                if (!set_field("user", "confirmed", 1, "id", $user->id)) {
+                    return AUTH_CONFIRM_FAIL;
+                }
+                if (!set_field("user", "firstaccess", time(), "id", $user->id)) {
+                    return AUTH_CONFIRM_FAIL;
+                }
+                return AUTH_CONFIRM_OK;
+            }
+        }
+    }
+
+    /**
+     * Returns true if this authentication plugin is 'internal'.
+     *
+     * @returns bool
+     */
+    function is_internal() {
+        return true;
+    }
+    
+    /**
+     * Returns true if this authentication plugin can change the user's
+     * password.
+     *
+     * @returns bool
+     */
+    function can_change_password() {
+        return true;
+    }
+    
+    /**
+     * Returns the URL for changing the user's pw, or false if the default can
+     * be used.
+     *
+     * @returns bool
+     */
+    function change_password_url() {
+        return false;
+    }
+    
+    /**
+     * Prints a form for configuring this authentication plugin.
+     *
+     * This function is called from admin/auth.php, and outputs a full page with
+     * a form for configuring this plugin.
+     *
+     * @param array $page An object containing all the data for this page.
+     */
+    function config_form($config, $err) {
+        include "config.html";
+    }
+
+    /**
+     * Processes and stores configuration data for this authentication plugin.
+     */
+    function process_config($config) {
+        return true;
+    }
+        
+}
+
+?>
index f686f3a..b150158 100644 (file)
@@ -1,4 +1,11 @@
 <!-- No config needed -->
 <div align="center"><?php print_string('none'); ?></div>
 
-<?php print_auth_lock_options($auth, $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false); ?>
\ No newline at end of file
+<table cellspacing="0" cellpadding="5" border="0" align="center">
+<?php 
+
+global $user_fields;
+print_auth_lock_options('email', $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false);
+
+?>
+</table>
diff --git a/auth/email/lib.php b/auth/email/lib.php
deleted file mode 100644 (file)
index d16b8e2..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php  // $Id$
-       // Standard authentication function
-
-function auth_user_login ($username, $password) {
-// Returns true if the username and password work
-// and false if they don't
-
-    global $CFG;
-
-    if ($user = get_record('user', 'username', $username)) {
-        return validate_internal_user_password($user, $password);
-    }
-
-    return false;
-}
-
-
-
-?>
diff --git a/auth/fc/auth.php b/auth/fc/auth.php
new file mode 100644 (file)
index 0000000..0308bb2
--- /dev/null
@@ -0,0 +1,219 @@
+<?php
+/**
+ * @author Martin Dougiamas
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodle multiauth
+ *
+ * Authentication Plugin: FirstClass Authentication
+ *
+ * Authentication using a FirstClass server.
+ *
+ * 2006-08-28  File created.
+ */
+
+// This page cannot be called directly
+if (!isset($CFG)) exit;
+
+require_once 'fcFPP.php';\r
+
+/**
+ * FirstClass authentication plugin.
+ */
+class auth_plugin_fc {
+
+    /**
+     * The configuration details for the plugin.
+     */
+    var $config;
+
+    /**
+     * Constructor.
+     */
+    function auth_plugin_fc() {
+        $this->config = get_config('auth/fc');
+    }
+
+    /**
+     * Returns true if the username and password work and false if they are
+     * wrong or don't exist.
+     *
+     * @param string $username The username
+     * @param string $password The password
+     * @returns bool Authentication success or failure.
+     */
+    function user_login ($username, $password) {
+        global $CFG;
+        $retval = false;
+
+        // Don't allow blank usernames or passwords
+        if (!$username or !$password) {
+            return $retval;
+        }
+
+        $fpp = new fcFPP($this->config->host, $this->config->fppport);
+        if ($fpp->open()) {
+            if ($fpp->login($username, $password)) {
+                $retval = true;
+            }
+        }
+        $fpp->close();
+    
+        return $retval;
+    }
+
+    /**
+     * Get user information from FirstCLass server and return it in an array.
+     * Localize this routine to fit your needs.
+     */
+    function get_userinfo($username) {
+        /*
+        Moodle                FirstCLass fieldID in UserInfo form
+        ------                -----------------------------------
+        firstname             1202
+        lastname              1204
+        email                 1252
+        icq                   -
+        phone1                1206
+        phone2                1207 (Fax)
+        institution           -
+        department            -
+        address               1205
+        city                  -
+        country               -
+        lang                  -
+        timezone              8030 (Not used yet. Need to figure out how FC codes timezones)
+        
+        description           Get data from users resume. Pictures will be removed.
+        
+        */
+
+        $userinfo = array();
+    
+        $fpp = new fcFPP($this->config->host, $this->config->port);
+        if ($fpp->open()) {
+            if ($fpp->login($this->config->userid, $this->config->passwd)) {
+                $userinfo['firstname']   = $fpp->getUserInfo($username,"1202");
+                $userinfo['lastname']    = $fpp->getUserInfo($username,"1204");
+                $userinfo['email']       = strtok($fpp->getUserInfo($username,"1252"),',');
+                $userinfo['phone1']      = $fpp->getUserInfo($username,"1206");
+                $userinfo['phone2']      = $fpp->getUserInfo($username,"1207");
+                $userinfo['description'] = $fpp->getResume($username);
+            }
+        }
+        $fpp->close();
+    
+        foreach($userinfo as $key => $value) {
+            if (!$value) {
+                unset($userinfo[$key]);
+            }
+        }
+
+        return $userinfo;
+    }
+    
+    /**
+     * Get users group membership from the FirstClass server user and check if
+     * user is member of one of the groups of creators.
+     */
+    function iscreator($username = 0) {
+        global $USER;
+    
+        if (! $this->config->creators) {
+            return false;
+        }
+        if (! $username) {
+            $username = $USER->username;
+        }
+    
+        $fcgroups = array();
+    
+        $fpp = new fcFPP($this->config->host, $this->config->port);
+        if ($fpp->open()) {
+            if ($fpp->login($this->config->userid, $this->config->passwd)) {
+                $fcgroups = $fpp->getGroups($username);
+            }
+        }
+        $fpp->close();
+    
+        if ((! $fcgroups)) {
+            return false;
+        }
+    
+        $creators = explode(";", $this->config->creators);
+    
+        foreach($creators as $creator) {
+            If (in_array($creator, $fcgroups)) return true;
+        }
+        
+        return false;
+    }
+
+    /**
+     * Returns true if this authentication plugin is 'internal'.
+     *
+     * @returns bool
+     */
+    function is_internal() {
+        return false;
+    }
+
+    /**
+     * Returns true if this authentication plugin can change the user's
+     * password.
+     *
+     * @returns bool
+     */
+    function can_change_password() {
+        return false;
+    }
+
+    /**
+     * Prints a form for configuring this authentication plugin.
+     *
+     * This function is called from admin/auth.php, and outputs a full page with
+     * a form for configuring this plugin.
+     *
+     * @param array $page An object containing all the data for this page.
+     */
+    function config_form($config, $err) {
+        include "config.html";
+    }
+
+    /**
+     * Processes and stores configuration data for this authentication plugin.
+     */
+    function process_config($config) {
+        // set to defaults if undefined
+        if (!isset($config->host)) {
+            $config->host = "127.0.0.1";
+        }
+        if (!isset($config->fppport)) {
+            $config->fppport = "3333";
+        }
+        if (!isset($config->userid)) {
+            $config->userid = "fcMoodle";
+        }
+        if (!isset($config->passwd)) {
+            $config->passwd = "";
+        }
+        if (!isset($config->creators)) {
+            $config->creators = "";
+        }
+        if (!isset($config->changepasswordurl)) {
+            $config->changepasswordurl = '';
+        }
+
+        // save settings
+        set_config('host',      $config->user,     'auth/fc');
+        set_config('fppport',   $config->fppport,  'auth/fc');
+        set_config('userid',    $config->userid,   'auth/fc');
+        set_config('passwd',    $config->passwd,   'auth/fc');
+        set_config('creators',  $config->creators, 'auth/fc');
+        set_config('changepasswordurl', $config->changepasswordurl, 'auth/fc');
+
+        return true;
+    }
+
+}
+
+?>
index 9f15f8e..f1d87ee 100644 (file)
 <?php
-    if (!isset($config->auth_fchost)) {
-        $config->auth_fchost = "127.0.0.1";
+
+    // set to defaults if undefined
+    if (!isset($config->host)) {
+        $config->host = "127.0.0.1";
+    }
+    if (!isset($config->fppport)) {
+        $config->fppport = "3333";
     }
-    if (!isset($config->auth_fcfppport)) {
-        $config->auth_fcfppport = "3333";
+    if (!isset($config->userid)) {
+        $config->userid = "fcMoodle";
     }
-    if (!isset($config->auth_fcuserid)) {
-        $config->auth_fcuserid = "fcMoodle";
+    if (!isset($config->passwd)) {
+        $config->passwd = "";
     }
-    if (!isset($config->auth_fcpasswd)) {
-        $config->auth_fcpasswd = "";
+    if (!isset($config->creators)) {
+        $config->creators = "";
     }    
-    if (!isset($config->auth_fccreators)) {
-        $config->auth_fccreators = "";
+    if (!isset($config->changepasswordurl)) {
+        $config->changepasswordurl = '';
     }   
+    if (!isset($config->changepasswordurl)) {
+        $config->changepasswordurl = '';
+    }
+
 ?>
+<table cellspacing="0" cellpadding="5" border="0" align="center">
 
 <tr valign="top" class="required">
-    <td align="right">auth_fchost:</td>
+       <td align="right">host:</td>
     <td>
-        <input name="auth_fchost" type="text" size="30" value="<?php echo $config->auth_fchost?>" />
-    <?php  if (isset($err["auth_fchost"])) formerr($err["auth_fchost"]); ?>
+        <input name="host" type="text" size="30" value="<?php echo $config->host?>" />
+       <?php  if (isset($err["host"])) formerr($err["host"]); ?>
     </td>
     <td>
-    <?php  print_string("auth_fchost","auth") ?>
+    <?php  print_string("auth_fchost", "auth") ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_fcfppport:</td>
+       <td align="right">fppport:</td>
     <td>
-        <input name="auth_fcfppport" type="text" size="30" value="<?php echo $config->auth_fcfppport?>" />
-    <?php  if (isset($err["auth_fcfppport"])) formerr($err["auth_fchost"]); ?>
+        <input name="fppport" type="text" size="30" value="<?php echo $config->fppport?>" />
+       <?php  if (isset($err["fppport"])) formerr($err["host"]); ?>
     </td>
     <td>
-    <?php  print_string("auth_fcfppport","auth") ?>
+    <?php  print_string("auth_fcfppport", "auth") ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_fcuserid:</td>
+       <td align="right">userid:</td>
     <td>
-        <input name="auth_fcuserid" type="text" size="30" maxlength="15" value="<?php echo $config->auth_fcuserid?>" />
-    <?php  if (isset($err["auth_fcuserid"])) formerr($err["auth_fcuserid"]); ?>
+        <input name="userid" type="text" size="30" maxlength="15" value="<?php echo $config->userid?>" />
+       <?php  if (isset($err["userid"])) formerr($err["userid"]); ?>
     </td>
     <td>
-    <?php  print_string("auth_fcuserid","auth") ?>
+    <?php  print_string("auth_fcuserid", "auth") ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_fcpasswd:</td>
+       <td align="right">passwd:</td>
     <td>
-        <input name="auth_fcpasswd" type="password" size="30" maxlength="12" value="<?php echo $config->auth_fcpasswd?>" />
-    <?php  if (isset($err["auth_fcpasswd"])) formerr($err["auth_fcpasswd"]); ?>
+        <input name="passwd" type="password" size="30" maxlength="12" value="<?php echo $config->passwd?>" />
+       <?php  if (isset($err["passwd"])) formerr($err["passwd"]); ?>
     </td>
     <td>
-    <?php  print_string("auth_fcpasswd","auth") ?>
+    <?php  print_string("auth_fcpasswd", "auth") ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_fccreators:</td>
+       <td align="right">creators:</td>
     <td>
-        <input name="auth_fccreators" type="text" size="30" value="<?php echo $config->auth_fccreators?>" />
-    <?php  if (isset($err["auth_fccreators"])) formerr($err["auth_fccreators"]); ?>
+        <input name="creators" type="text" size="30" value="<?php echo $config->creators?>" />
+       <?php  if (isset($err["creators"])) formerr($err["creators"]); ?>
     </td>
     <td>
-    <?php  print_string("auth_fccreators","auth") ?>
+    <?php  print_string("auth_fccreators", "auth") ?>
     </td>
 </tr>
 
-
 <tr valign="top">
-    <td align="right"><?php  print_string("instructions", "auth") ?>:</td>
-    <td>
-    <textarea name="auth_instructions" cols="30" rows="10" wrap="virtual"><?php  p($config->auth_instructions) ?></textarea> 
-    </td>
+    <td align="right"> changepasswordurl: </td>
     <td>
-    <?php  print_string("authinstructions","auth") ?>
-    <?php  helpbutton("text", get_string("helptext")) ?>
+        <input name="changepasswordurl" type="text" value="<?php echo $config->changepasswordurl ?>" />
+        <?php
+
+        if (isset($err['changepasswordurl'])) {
+            formerr($err['changepasswordurl']);
+        }
+
+        ?>
     </td>
+    <td><?php print_string('changepasswordhelp', 'auth') ?></td>
 </tr>
-<?php print_auth_lock_options($auth, $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false); ?>
+
+<?php 
+
+global $user_fields;
+print_auth_lock_options('fc', $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false);
+
+?>
+</table>
index b9f25a7..5ddd2c5 100644 (file)
@@ -40,22 +40,22 @@ class fcFPP
     // open a connection to the FirstClass server
     function open()
     {
-    if($this->_debug) echo "Connecting to host ";
+    if ($this->_debug) echo "Connecting to host ";
     $host = $this->_hostname;
     $port = $this->_port;
 
-    if($this->_debug) echo "[$host:$port]..";
+    if ($this->_debug) echo "[$host:$port]..";
 
     // open the connection to the FirstClass server
     $conn = fsockopen($host, $port, $errno, $errstr, 5);
-    if(!$conn)
+    if (!$conn)
     {
         echo "connection failed!".$errno. $errstr;
         return false;
     }
     
     // We are connected
-    if($this->_debug) echo "connected!";
+    if ($this->_debug) echo "connected!";
     
     // Read connection message.
     $line = fgets ($conn);        //+0
@@ -74,7 +74,7 @@ class fcFPP
     $conn = &$this->_conn;
 
     // close it if it's open
-        if($conn)
+        if ($conn)
     {
         fclose($conn);
 
@@ -90,7 +90,7 @@ class fcFPP
     function login($userid, $passwd)
     {
     // we did have a connection right?!
-        if($this->_conn)
+        if ($this->_conn)
     {
         # Send username
         fputs($this->_conn,"$userid\r\n");
@@ -105,13 +105,13 @@ class fcFPP
         $line = fgets ($this->_conn);        //+0
         $line = fgets ($this->_conn);        //+0 or message
         
-        if($this->_debug) echo $line;
+        if ($this->_debug) echo $line;
         
         if (preg_match ("/^\+0/", $line)) {      //+0, user with subadmin privileges
             $this->_user = $userid;
             $this->_pwd  = $passwd; 
             return TRUE;        
-        } elseif (strpos($line, 'You are not allowed')){ // Denied access but a valid user and password
+        } elseif (strpos($line, 'You are not allowed')) { // Denied access but a valid user and password
                                                          // "Sorry. You are not allowed to login with the FPP interface"
             return TRUE;
         } else {                    //Invalid user or password
@@ -124,12 +124,12 @@ class fcFPP
     }
 
     // Get the list of groups the user is a member of 
-    function getGroups($userid){
+    function getGroups($userid) {
     
     $groups = array();
     
     // we must be logged in as a user with subadmin privileges 
-    if($this->_conn AND $this->_user) {
+    if ($this->_conn AND $this->_user) {
         # Send BA-command to get groups
         fputs($this->_conn,"GET USER '" . $userid . "' 4 -1\r");
         $line = "";
@@ -141,7 +141,7 @@ class fcFPP
         list( , , $groups[$n++]) = explode(" ",$line,3);
         $line = trim(fgets ($this->_conn));
         }
-            if($this->_debug) echo "getGroups:" . implode(",",$groups);
+            if ($this->_debug) echo "getGroups:" . implode(",",$groups);
     }
     
     return $groups;
@@ -149,24 +149,24 @@ class fcFPP
 
     // Check if the user is member of any of the groups.
     // Return the list of groups the user is member of.
-    function isMemberOf($userid, $groups){
+    function isMemberOf($userid, $groups) {
     
     $usergroups = array_map("strtolower",$this->getGroups($userid));
     $groups = array_map("strtolower",$groups);
     
     $result = array_intersect($groups,$usergroups);
     
-        if($this->_debug) echo "isMemberOf:" . implode(",",$result);
+        if ($this->_debug) echo "isMemberOf:" . implode(",",$result);
     
     return $result;
 
     }
     
-    function getUserInfo($userid, $field){
+    function getUserInfo($userid, $field) {
     
     $userinfo = "";
     
-    if($this->_conn AND $this->_user) {
+    if ($this->_conn AND $this->_user) {
         # Send BA-command to get data
         fputs($this->_conn,"GET USER '" . $userid . "' " . $field . "\r");
         $line = "";
@@ -178,20 +178,20 @@ class fcFPP
         list( , , $userinfo) = explode(" ",$line,3);
         $line = trim(fgets ($this->_conn));
         }
-        if($this->_debug) echo "getUserInfo:" . $userinfo;
+        if ($this->_debug) echo "getUserInfo:" . $userinfo;
     }
       
     return str_replace('\r',' ',trim($userinfo,'"'));
 
     }
 
-    function getResume($userid){
+    function getResume($userid) {
     
     $resume = "";
 
     $pattern = "/\[.+:.+\..+\]/";         // Remove references to pictures in resumes
     
-    if($this->_conn AND $this->_user) {
+    if ($this->_conn AND $this->_user) {
         # Send BA-command to get data
         fputs($this->_conn,"GET RESUME '" . $userid . "' 6\r");
         $line = "";
@@ -205,7 +205,7 @@ class fcFPP
         //print $line;
         
         }
-        if($this->_debug) echo "getResume:" . $resume;
+        if ($this->_debug) echo "getResume:" . $resume;
     }
       
     return $resume;
diff --git a/auth/fc/lib.php b/auth/fc/lib.php
deleted file mode 100644 (file)
index 70bedab..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-<?php  // $Id$
-       
-// FirstClass authentication using FirstClass Flexible Provisining Protocol
-
-/* Author: Torsten Anderson, torsten.anderson@skeria.skelleftea.se
-
-CHANGELOG
-
-README
-  Module will authenticate user against FirstClass server and check if user belongs to any of
-  the defined creator groups.
-  User authenticates using their existing FirstClass username and password.
-  Where possible userdata is copied from the FirstClass directory to Moodle. You may
-  want to modify this.
-  Module requires the fcFPP class to do it's jobb.
- */
-       
-
-require('fcFPP.php');
-   
-
-function auth_user_login ($username, $password) {
-/// Returns true if the username and password work
-/// and false if they don't
-
-    global $CFG;
-
-    $hostname = $CFG->auth_fchost;
-    $port     = $CFG->auth_fcfppport;
-
-    $retval = FALSE;
-
-    if (!$username or !$password) {    // Don't allow blank usernames or passwords
-        return $retval;
-    }
-
-
-    $fpp = new fcFPP($hostname,$port);
-    if ($fpp->open()) {
-       if ($fpp->login($username,$password)){
-          $retval = TRUE;
-       }
-    }
-    $fpp->close();
-
-    return $retval;
-
-}
-
-function auth_get_userinfo($username){
-// Get user information from FirstCLass server and return it in an array.
-// Localize this routine to fit your needs. 
-
-/*
-Moodle                FirstCLass fieldID in UserInfo form
-------                -----------------------------------
-firstname             1202
-lastname              1204
-email                 1252
-icq                   -
-phone1                1206
-phone2                1207 (Fax)
-institution           -  
-department            - 
-address               1205
-city                  - 
-country               -
-lang                  -
-timezone              8030 (Not used yet. Need to figure out how FC codes timezones)
-
-description           Get data from users resume. Pictures will be removed.
-
-*/
-
-    global $CFG;
-    
-    $hostname = $CFG->auth_fchost;
-    $port     = $CFG->auth_fcfppport;
-    $userid   = $CFG->auth_fcuserid;
-    $passwd   = $CFG->auth_fcpasswd; 
-
-    $userinfo = array();
-
-    $fpp = new fcFPP($hostname,$port);
-    if ($fpp->open()) {
-       if ($fpp->login($userid,$passwd)){
-
-          $userinfo['firstname']   = $fpp->getUserInfo($username,"1202");
-          $userinfo['lastname']    = $fpp->getUserInfo($username,"1204");
-          $userinfo['email']       = strtok($fpp->getUserInfo($username,"1252"),',');
-          $userinfo['phone1']      = $fpp->getUserInfo($username,"1206");
-          $userinfo['phone2']      = $fpp->getUserInfo($username,"1207");
-          $userinfo['description'] = $fpp->getResume($username);
-
-       }
-    }
-
-    $fpp->close();
-
-    foreach($userinfo as $key => $value) {
-       if (!$value) {
-          unset($userinfo[$key]);
-       }
-    }
-    
-    return $userinfo;
-
-}
-
-
-function auth_iscreator($username=0) {
-//Get users group membership from the FirstClass server user and check if
-// user is member of one of the groups of creators.
-
-    global $CFG, $USER;
-
-    if (! $CFG->auth_fccreators) {
-       return false;
-    }
-
-    if (! $username) {
-       $username=$USER->username;
-    }
-
-    $fcgroups = array();
-
-    $hostname = $CFG->auth_fchost;
-    $port     = $CFG->auth_fcfppport;
-    $userid   = $CFG->auth_fcuserid;
-    $passwd   = $CFG->auth_fcpasswd; 
-
-    $fpp = new fcFPP($hostname,$port);
-    if ($fpp->open()) {
-       if ($fpp->login($userid,$passwd)){
-          $fcgroups = $fpp->getGroups($username);
-       }
-    }
-    $fpp->close();
-
-   
-    if ((! $fcgroups)) {
-      return false;
-    }
-
-    $creators = explode(";",$CFG->auth_fccreators);
-   
-    foreach($creators as $creator) {
-        If (in_array($creator, $fcgroups)) return true;
-    }
-    
-    return false;
-}
-  
diff --git a/auth/imap/auth.php b/auth/imap/auth.php
new file mode 100644 (file)
index 0000000..ad8e581
--- /dev/null
@@ -0,0 +1,155 @@
+<?php
+
+/**
+ * @author Martin Dougiamas
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodle multiauth
+ *
+ * Authentication Plugin: IMAP Authentication
+ *
+ * Authenticates against an IMAP server.
+ *
+ * 2006-08-31  File created.
+ */
+
+// This page cannot be called directly
+if (!isset($CFG)) exit;
+
+/**
+ * IMAP authentication plugin.
+ */
+class auth_plugin_imap {
+
+    /**
+     * The configuration details for the plugin.
+     */
+    var $config;
+
+    /**
+     * Constructor.
+     */
+    function auth_plugin_imap() {
+        $this->config = get_config('auth/imap');
+    }
+
+    /**
+     * Returns true if the username and password work and false if they are
+     * wrong or don't exist.
+     *
+     * @param string $username The username
+     * @param string $password The password
+     * @returns bool Authentication success or failure.
+     */
+    function user_login ($username, $password) {
+        if (! function_exists('imap_open')) {
+            error("Cannot use IMAP authentication. The PHP IMAP module is not installed.");
+        }
+        
+        global $CFG;
+        $hosts = split(';', $this->config->host);   // Could be multiple hosts
+
+        foreach ($hosts as $host) {                 // Try each host in turn
+            $host = trim($host);
+
+            switch ($this->config->type) {
+                case 'imapssl':
+                    $host = '{'.$host.":{$this->config->port}/imap/ssl}";
+                break;
+        
+                case 'imapcert':
+                    $host = '{'.$host.":{$this->config->port}/imap/ssl/novalidate-cert}";
+                break;
+        
+                case 'imaptls':
+                    $host = '{'.$host.":{$this->config->port}/imap/tls}";
+                break;
+        
+                default:
+                    $host = '{'.$host.":{$this->config->port}/imap}";
+            }
+
+            error_reporting(0);
+            $connection = imap_open($host, $username, $password, OP_HALFOPEN);
+            error_reporting($CFG->debug);   
+
+            if ($connection) {
+                imap_close($connection);
+                return true;
+            }
+        }
+
+        return false;  // No match
+    }
+
+    /**
+     * Returns true if this authentication plugin is 'internal'.
+     *
+     * @returns bool
+     */
+    function is_internal() {
+        return false;
+    }
+
+    /**
+     * Returns true if this authentication plugin can change the user's
+     * password.
+     *
+     * @returns bool
+     */
+    function can_change_password() {
+        return false;
+    }
+    
+    /**
+     * Returns the URL for changing the user's pw, or false if the default can
+     * be used.
+     *
+     * @returns bool
+     */
+    function change_password_url() {
+        return $CFG->changepasswordurl; // TODO: will this be global?
+        //return $this->config->changepasswordurl;
+    }
+    
+    /**
+     * Prints a form for configuring this authentication plugin.
+     *
+     * This function is called from admin/auth.php, and outputs a full page with
+     * a form for configuring this plugin.
+     *
+     * @param array $page An object containing all the data for this page.
+     */
+    function config_form($config, $err) {
+        include "config.html";
+    }
+
+    /**
+     * Processes and stores configuration data for this authentication plugin.
+     */
+    function process_config($config) {
+        // set to defaults if undefined
+        if (!isset ($config->host)) {
+            $config->host = '127.0.0.1';
+        }
+        if (!isset ($config->type)) {
+            $config->type = 'imap';
+        }
+        if (!isset ($config->port)) {
+            $config->port = '143';
+        }
+        if (!isset($config->changepasswordurl)) {
+            $config->changepasswordurl = '';
+        }
+
+        // save settings
+        set_config('host', $config->host, 'auth/imap');
+        set_config('type', $config->type, 'auth/imap');
+        set_config('port', $config->port, 'auth/imap');
+        set_config('changepasswordurl', $config->changepasswordurl, 'auth/imap');
+
+        return true;
+    }
+
+}
+
+?>
index 40619cb..6ce0de0 100644 (file)
@@ -1,60 +1,94 @@
 <?php
-    if (!isset($config->auth_imaphost)) {
-        $config->auth_imaphost = "127.0.0.1";
-    }
-    if (!isset($config->auth_imaptype)) {
-        $config->auth_imaptype = "imap";
-    }
-    if (!isset($config->auth_imapport)) {
-        $config->auth_imapport = "143";
-    }
+
+// set to defaults if undefined
+if (!isset($config->host)) {
+    $config->host = '127.0.0.1';
+}
+if (!isset($config->type)) {
+    $config->type = 'imap';
+}
+if (!isset($config->port)) {
+    $config->port = '143';
+}
+if (!isset($config->changepasswordurl)) {
+    $config->changepasswordurl = '';
+}
+
 ?>
+<table cellspacing="0" cellpadding="5" border="0" align="center">
+
 <tr valign="top" class="required">
-    <td align="right">auth_imaphost:</td>
+    <td align="right"> host: </td>
     <td>
-        <input name="auth_imaphost" type="text" size="30" value="<?php echo $config->auth_imaphost?>" />
-    <?php  if (isset($err["auth_imaphost"])) formerr($err["auth_imaphost"]); ?>
+        <input name="host" type="text" size="30" value="<?php echo $config->host ?>" />
+        <?php
+
+        if (isset($err['host'])) {
+            formerr($err['host']);
+        }
+
+        ?>
     </td>
     <td>
-    <?php  print_string("auth_imaphost","auth") ?> 
-    <?php  print_string("auth_multiplehosts","auth") ?>
+        <?php
+
+        print_string('auth_imaphost', 'auth');
+        print_string('auth_multiplehosts', 'auth');
+
+        ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_imaptype:</td>
-    <td>
-    <?php  $imaptypes = array("imap","imapssl", "imapcert", "imaptls");
-       foreach($imaptypes as $imaptype) {
-           $imapoptions[$imaptype] = $imaptype;
-       }
-       choose_from_menu($imapoptions, "auth_imaptype", $config->auth_imaptype, "");
-    ?>
-    </td>
+    <td align="right"> type: </td>
     <td>
-    <?php  print_string("auth_imaptype","auth") ?>
+        <?php
+
+        $imaptypes = array('imap', 'imapssl', 'imapcert', 'imaptls');
+        foreach ($imaptypes as $imaptype) {
+            $imapoptions[$imaptype] = $imaptype;
+        }
+        choose_from_menu($imapoptions, 'type', $config->type, '');
+
+        ?>
     </td>
+    <td><?php print_string('auth_imaptype', 'auth') ?></td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_imapport:</td>
+    <td align="right"> port: </td>
     <td>
-    <input name="auth_imapport" type="text" size="6" value="<?php echo $config->auth_imapport?>" />
-    <?php  if (isset($err["auth_imapport"])) formerr($err["auth_imapport"]); ?>
-    </td>
-    <td>
-    <?php  print_string("auth_imapport","auth") ?>
+        <input name="port" type="text" size="6" value="<?php echo $config->port ?>" />
+        <?php
+
+        if (isset($err['port'])) {
+            formerr($err['port']);
+        }
+
+        ?>
     </td>
+    <td><?php print_string('auth_imapport', 'auth') ?></td>
 </tr>
 
 <tr valign="top">
-    <td align="right"><?php  print_string("instructions", "auth") ?>:</td>
+    <td align="right"> changepasswordurl: </td>
     <td>
-    <textarea name="auth_instructions" cols="30" rows="10" wrap="virtual"><?php  p($config->auth_instructions) ?></textarea> 
-    </td>
-    <td>
-    <?php  print_string("authinstructions","auth") ?>
-    <?php  helpbutton("text", get_string("helptext")) ?>
+        <input name="changepasswordurl" type="text" value="<?php echo $config->changepasswordurl ?>" />
+        <?php
+
+        if (isset($err['changepasswordurl'])) {
+            formerr($err['changepasswordurl']);
+        }
+
+        ?>
     </td>
+    <td><?php print_string('changepasswordhelp', 'auth') ?></td>
 </tr>
-<?php print_auth_lock_options($auth, $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false); ?>
\ No newline at end of file
+
+<?php 
+
+global $user_fields;
+print_auth_lock_options('imap', $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false);
+
+?>
+</table>
diff --git a/auth/imap/lib.php b/auth/imap/lib.php
deleted file mode 100644 (file)
index a2c0927..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php  // $Id$
-       // Authentication by looking up an IMAP server
-
-function auth_user_login ($username, $password) {
-// Returns true if the username and password work
-// and false if they are wrong or don't exist.
-
-    global $CFG;
-
-    $hosts = split(';', $CFG->auth_imaphost);   // Could be multiple hosts
-
-    foreach ($hosts as $host) {                 // Try each host in turn
-
-        $host = trim($host);
-
-        switch ($CFG->auth_imaptype) {
-            case "imapssl":
-                $host = '{'.$host.":$CFG->auth_imapport/imap/ssl}";
-            break;
-    
-            case "imapcert":
-                $host = '{'.$host.":$CFG->auth_imapport/imap/ssl/novalidate-cert}";
-            break;
-    
-            case "imaptls":
-                $host = '{'.$host.":$CFG->auth_imapport/imap/notls}";
-            break;
-    
-            default:
-                $host = '{'.$host.":$CFG->auth_imapport}";
-        }
-
-        error_reporting(0);
-        $connection = imap_open($host, $username, $password, OP_HALFOPEN);
-        error_reporting($CFG->debug);   
-
-        if ($connection) {
-            imap_close($connection);
-            return true;
-        }
-    }
-
-    return false;  // No match
-}
-
-
-?>
diff --git a/auth/ldap/auth.php b/auth/ldap/auth.php
new file mode 100644 (file)
index 0000000..465143f
--- /dev/null
@@ -0,0 +1,1651 @@
+<?php
+
+/**
+ * @author Martin Dougiamas
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodle multiauth
+ *
+ * Authentication Plugin: LDAP Authentication
+ *
+ * Authentication using LDAP (Lightweight Directory Access Protocol).
+ *
+ * 2006-08-28  File created.
+ */
+
+// This page cannot be called directly
+if (!isset($CFG)) exit;
+
+// LDAP functions are reused by other auth libs
+if (!defined('AUTH_LDAP_NAME')) {
+    define('AUTH_LDAP_NAME', 'ldap');
+}
+
+/**
+ * LDAP authentication plugin.
+ */
+class auth_plugin_ldap {
+
+    /**
+     * The configuration details for the plugin.
+     */
+    var $config;
+
+    /**
+     * Constructor.
+     */
+    function auth_plugin_ldap() {
+        $this->config = get_config('auth/ldap');
+    }
+
+    /**
+     * Returns true if the username and password work and false if they are
+     * wrong or don't exist.
+     *
+     * @param string $username The username
+     * @param string $password The password
+     * @returns bool Authentication success or failure.
+     */
+    function user_login($username, $password) {
+
+        global $CFG;
+
+        if (!$username or !$password) {    // Don't allow blank usernames or passwords
+            return false;
+        }
+     
+        // CAS-supplied auth tokens override LDAP auth
+        if ($CFG->auth == "cas" and !empty($CFG->cas_enabled)) {
+            return cas_ldap_auth_user_login($username, $password);
+        }
+
+        $ldapconnection = $this->ldap_connect();
+
+        if ($ldapconnection) {
+            $ldap_user_dn = $this->ldap_find_userdn($ldapconnection, $username);
+          
+            //if ldap_user_dn is empty, user does not exist
+            if (!$ldap_user_dn) {
+                ldap_close($ldapconnection);
+                return false;
+            }
+
+            // Try to bind with current username and password
+            $ldap_login = @ldap_bind($ldapconnection, $ldap_user_dn, stripslashes($password));
+            ldap_close($ldapconnection);
+            if ($ldap_login) {
+                return true;
+            }
+        }
+        else {
+            @ldap_close($ldapconnection);
+            error("LDAP-module cannot connect to server: $this->config->host_url");
+        }
+        return false;
+    }
+
+    /**
+     * reads userinformation from ldap and return it in array()
+     *
+     * Read user information from external database and returns it as array().
+     * Function should return all information available. If you are saving
+     * this information to moodle user-table you should honor syncronization flags
+     *
+     * @param string $username username
+     * @return array
+     */
+    function get_userinfo($username) {
+        global $CFG;
+        $ldapconnection = $this->ldap_connect();
+        $config = (array)$CFG;
+        $attrmap = $this->ldap_attributes();
+       
+        $result = array();
+        $search_attribs = array();
+      
+        foreach ($attrmap as $key=>$values) {
+            if (!is_array($values)) {
+                $values = array($values);
+            }
+            foreach ($values as $value) {
+                if (!in_array($value, $search_attribs)) {
+                    array_push($search_attribs, $value);
+                }    
+            }
+        }
+
+        $user_dn = $this->ldap_find_userdn($ldapconnection, $username);
+
+        if (empty($this->config->objectclass)) {        // Can't send empty filter
+            $this->config->objectclass="objectClass=*";
+        }
+      
+        $user_info_result = ldap_read($ldapconnection, $user_dn, $this->config->objectclass, $search_attribs);
+
+        if ($user_info_result) {
+            $user_entry = $this->ldap_get_entries($ldapconnection, $user_info_result);
+            foreach ($attrmap as $key=>$values) {
+                if (!is_array($values)) {
+                    $values = array($values);
+                }
+                $ldapval = NULL;
+                foreach ($values as $value) {
+                    if (is_array($user_entry[0][strtolower($value)])) {
+                        if (!empty($CFG->unicodedb)) {
+                            $newval = addslashes(stripslashes($user_entry[0][strtolower($value)][0]));
+                        }
+                        else {
+                            $newval = addslashes(stripslashes(utf8_decode($user_entry[0][strtolower($value)][0])));
+                        }
+                    }
+                    else {
+                        if (!empty($CFG->unicodedb)) {
+                            $newval = addslashes(stripslashes($user_entry[0][strtolower($value)]));
+                        }
+                        else {
+                            $newval = addslashes(stripslashes(utf8_decode($user_entry[0][strtolower($value)])));
+                        }
+                    }
+                    if (!empty($newval)) { // favour ldap entries that are set
+                        $ldapval = $newval;
+                    } 
+                }
+                if (!is_null($ldapval)) {
+                    $result[$key] = $ldapval;
+                }
+            }
+        }
+
+        @ldap_close($ldapconnection);
+        
+        return $result;
+    }
+
+    /**
+     * reads userinformation from ldap and return it in an object
+     *
+     * @param string $username username
+     * @return array
+     */
+    function get_userinfo_asobj($username) {
+        $user_array = truncate_userinfo($this->get_userinfo($username));
+        $user = new object;
+        foreach ($user_array as $key=>$value) {
+            $user->{$key} = $value;
+        }
+        return $user;
+    }
+
+    /**
+     * returns all usernames from external database
+     *
+     * get_userlist returns all usernames from external database
+     *
+     * @return array 
+     */
+    function get_userlist() {
+        global $CFG;
+        $this->ldap_init();
+        return $this->ldap_get_userlist("({$this->config->user_attribute}=*)");
+    }
+
+    /**
+     * checks if user exists on external db
+     */
+    function user_exists($username) {
+       global $CFG; 
+       $this->ldap_init();
+       //returns true if given usernname exist on ldap
+       $users = $this->ldap_get_userlist("({$this->config->user_attribute}=$username)");
+       return count($users); 
+    }
+
+    /**
+     * creates new user on external database
+     *
+     * user_create() creates new user on external database
+     * By using information in userobject
+     * Use user_exists to prevent dublicate usernames
+     *
+     * @param mixed $userobject  Moodle userobject
+     * @param mixed $plainpass   Plaintext password
+     */
+    function user_create($userobject, $plainpass) {
+        global $CFG;
+        $ldapconnection = $this->ldap_connect();
+        $attrmap = $this->ldap_attributes();
+        
+        $newuser = array();
+         
+        foreach ($attrmap as $key => $values) {
+            if (!is_array($values)) {
+                $values = array($values);
+            }
+            foreach ($values as $value) {
+                if (!empty($userobject->$key) ) {
+                    if (!empty($CFG->unicodedb)) {
+                        $newuser[$value] = $userobject->$key;
+                    }
+                    else {
+                        $newuser[$value] = utf8_encode($userobject->$key);
+                    }
+                }
+            }
+        }
+        
+        //Following sets all mandatory and other forced attribute values
+        //User should be creted as login disabled untill email confirmation is processed
+        //Feel free to add your user type and send patches to paca@sci.fi to add them 
+        //Moodle distribution
+
+        switch ($this->config->user_type)  {
+            case 'edir':
+                $newuser['objectClass']= array("inetOrgPerson","organizationalPerson","person","top");
+                $newuser['uniqueId']= $userobject->username;
+                $newuser['logindisabled']="TRUE";
+                $newuser['userpassword']=$plainpass;
+                break;
+            default:
+               error('auth: ldap user_create() does not support selected usertype:"'.$this->config->user_type.'" (..yet)');
+        }
+        $uadd = $this->ldap_add($ldapconnection, "{$this->config->user_attribute}={$userobject->username},{$this->config->create_context}", $newuser);
+        ldap_close($ldapconnection);
+        return $uadd;
+        
+    }
+
+    /**
+     * 
+     * get_users() returns userobjects from external database
+     *
+     * Function returns users from external databe as Moodle userobjects
+     * If filter is not present it should return ALL users in external database
+     * 
+     * @param mixed $filter substring of username
+     * @returns array of userobjects 
+     */
+    function get_users($filter = '*', $dontlistcreated = false) {
+        global $CFG;
+
+        $ldapconnection = $this->ldap_connect();
+        $fresult = array();
+
+        if ($filter=="*") {
+           $filter = "(&(".$this->config->user_attribute."=*)(".$this->config->objectclass."))";
+        }
+
+        $contexts = explode(";",$this->config->contexts);
+     
+        if (!empty($this->config->create_context) and empty($dontlistcreated)) {
+              array_push($contexts, $this->config->create_context);
+        }
+
+        $attrmap = $this->ldap_attributes();
+       
+        $search_attribs = array();
+      
+        foreach ($attrmap as $key=>$values) {
+            if (!is_array($values)) {
+                $values = array($values);
+            }
+            foreach ($values as $value) {
+                if (!in_array($value, $search_attribs)) {
+                    array_push($search_attribs, $value);
+                }   
+            } 
+        }
+
+
+        foreach ($contexts as $context) {
+            
+            $context = trim($context);
+            if (empty($context)) {
+                continue;
+            }
+
+            if ($this->config->search_sub) {
+                //use ldap_search to find first user from subtree
+                $ldap_result = ldap_search($ldapconnection, $context,
+                                           $filter,
+                                           $search_attribs);
+            }
+            else {
+                //search only in this context
+                $ldap_result = ldap_list($ldapconnection, $context,
+                                         $filter,
+                                         $search_attribs);
+            }
+
+            $users = $this->ldap_get_entries($ldapconnection, $ldap_result);
+
+            //add found users to list
+            foreach ($users as $ldapuser=>$attribs) {
+                $user = new object();
+                foreach ($attrmap as $key=>$value) {
+                    if (isset($users[$ldapuser][$value][0])) {
+                        $user->$key=$users[$ldapuser][$value][0];
+                    }
+                }    
+                //quick way to get around binarystrings
+                $user->guid=bin2hex($user->guid);
+                //add authentication source stamp 
+                $user->auth = AUTH_LDAP_NAME;
+                $fresult[$user->username]=$user;
+
+            }
+        }
+       
+        return $fresult;
+    }
+
+    /**
+     * return number of days to user password expires
+     *
+     * If userpassword does not expire it should return 0. If password is already expired
+     * it should return negative value.
+     *
+     * @param mixed $username username
+     * @return integer
+     */
+    function password_expire($username) {
+        global $CFG ;
+        $result = false;
+        
+        $ldapconnection = $this->ldap_connect();
+        $user_dn = $this->ldap_find_userdn($ldapconnection, $username);
+        $search_attribs = array($this->config->expireattr);
+        $sr = ldap_read($ldapconnection, $user_dn, 'objectclass=*', $search_attribs);
+        if ($sr)  {
+            $info=$this->ldap_get_entries($ldapconnection, $sr);
+            if ( empty($info[0][strtolower($this->config->expireattr)][0])) {
+                //error_log("ldap: no expiration value".$info[0][$this->config->expireattr]);
+                // no expiration attribute, password does not expire
+                $result = 0;
+            }
+            else {
+                $now = time();
+                $expiretime = $this->ldap_expirationtime2unix($info[0][strtolower($this->config->expireattr)][0]);
+                if ($expiretime > $now) {
+                    $result = ceil(($expiretime - $now) / DAYSECS);
+                }
+                else {
+                    $result = floor(($expiretime - $now) / DAYSECS);
+                }    
+            }
+        }
+        else {    
+            error_log("ldap: password_expire did't find expiration time.");
+        }
+
+        //error_log("ldap: password_expire user $user_dn expires in $result days!");
+        return $result;
+    }
+
+    /**
+     * syncronizes user fron external db to moodle user table
+     *
+     * Sync shouid be done by using idnumber attribute, not username.
+     * You need to pass firstsync parameter to function to fill in
+     * idnumbers if they dont exists in moodle user table.
+     * 
+     * Syncing users removes (disables) users that dont exists anymore in external db.
+     * Creates new users and updates coursecreator status of users. 
+     * 
+     * @param mixed $firstsync  Optional: set to true to fill idnumber fields if not filled yet
+     */
+    function sync_users ($bulk_insert_records = 1000, $do_updates = 1) {
+    //Syncronizes userdb with ldap
+    //This will add, rename 
+    /// OPTIONAL PARAMETERS
+    /// $bulk_insert_records = 1 // will insert $bulkinsert_records per insert statement
+    ///                         valid only with $unsafe. increase to a couple thousand for
+    ///                         blinding fast inserts -- but test it: you may hit mysqld's 
+    ///                         max_allowed_packet limit.
+    /// $do_updates = 1 // will do pull in data updates from ldap if relevant
+
+
+        global $CFG ;
+
+        // configure a temp table 
+        print "Configuring temp table\n";    
+        if (strtolower($CFG->dbtype) === 'mysql') {
+            // help old mysql versions cope with large temp tables
+            execute_sql('SET SQL_BIG_TABLES=1', false); 
+            execute_sql('CREATE TEMPORARY TABLE ' . $CFG->prefix .'extuser (idnumber VARCHAR(64), PRIMARY KEY (idnumber)) TYPE=MyISAM',false); 
+        }
+        elseif (strtolower($CFG->dbtype) === 'postgres7') {
+            $bulk_insert_records = 1; // no support for multiple sets of values
+            execute_sql('CREATE TEMPORARY TABLE '.$CFG->prefix.'extuser (idnumber VARCHAR(64), PRIMARY KEY (idnumber))',false); 
+        }
+
+        print "connecting to ldap\n";
+        $ldapconnection = $this->ldap_connect();
+
+        if (!$ldapconnection) {
+            @ldap_close($ldapconnection);
+            notify("LDAP-module cannot connect to server: $CFG->ldap_host_url");
+            return false;
+        }
+
+        ////
+        //// get user's list from ldap to sql in a scalable fashion
+        ////
+        // prepare some data we'll need
+        if (! empty($this->config->objectclass)) {
+            $this->config->objectclass="objectClass=*";
+        }
+
+        $filter = "(&(".$this->config->user_attribute."=*)(".$this->config->objectclass."))";
+
+        $contexts = explode(";",$this->config->contexts);
+     
+        if (!empty($this->config->create_context)) {
+              array_push($contexts, $this->config->create_context);
+        }
+
+        $fresult = array();
+        $count = 0;
+        foreach ($contexts as $context) {
+            $context = trim($context);
+            if (empty($context)) {
+                continue;
+            }
+            begin_sql();
+            if ($this->config->search_sub) {
+                //use ldap_search to find first user from subtree
+                $ldap_result = ldap_search($ldapconnection, $context,
+                                           $filter,
+                                           array($this->config->user_attribute));
+            }
+            else {
+                //search only in this context
+                $ldap_result = ldap_list($ldapconnection, $context,
+                                         $filter,
+                                         array($this->config->user_attribute));
+            }
+
+            if ($entry = ldap_first_entry($ldapconnection, $ldap_result)) {
+                do {
+                    $value = ldap_get_values_len($ldapconnection, $entry,$this->config->user_attribute);
+                    $value = $value[0];
+                    $count++;
+                    array_push($fresult, $value);
+                    if (count($fresult) >= $bulk_insert_records) {
+                        $this->ldap_bulk_insert($fresult);
+                        //print var_dump($fresult);
+                        $fresult=array();
+                    }         
+                }
+                while ($entry = ldap_next_entry($ldapconnection, $entry));
+            }
+
+            // insert any remaining users and release mem
+            if (count($fresult)) {
+                $this->ldap_bulk_insert($fresult);
+                $fresult=array();
+            }
+            commit_sql();
+        }
+        // free mem
+        $ldap_results = 0;
+
+        /// preserve our user database
+        /// if the temp table is empty, it probably means that something went wrong, exit
+        /// so as to avoid mass deletion of users; which is hard to undo
+        $count = get_record_sql('SELECT COUNT(idnumber) AS count, 1 FROM ' . $CFG->prefix .'extuser');
+        $count = $count->{'count'};
+        if ($count < 1) {
+            print "Did not get any users from LDAP -- error? -- exiting\n";
+            exit;
+        }
+
+        ////
+        //// User removal
+        ////
+        // find users in DB that aren't in ldap -- to be removed!
+        // this is still not as scalable
+        $sql = 'SELECT u.id, u.username 
+                FROM ' . $CFG->prefix .'user u LEFT JOIN ' . $CFG->prefix .'extuser e 
+                        ON u.idnumber = e.idnumber 
+                WHERE u.auth=\'' . AUTH_LDAP_NAME . '\' AND u.deleted=\'0\' AND e.idnumber IS NULL';
+        //print($sql);            
+        $remove_users = get_records_sql($sql); 
+
+        if (!empty($remove_users)) {
+            print "User entries to remove: ". count($remove_users) . "\n";
+
+            begin_sql();
+            foreach ($remove_users as $user) {
+                //following is copy pasted from admin/user.php
+                //maybe this should moved to function in lib/datalib.php
+                unset($updateuser);
+                $updateuser->id = $user->id;
+                $updateuser->deleted = '1';
+                //$updateuser->username = "$user->username".time();  // Remember it just in case
+                //$updateuser->email = '';               // Clear this field to free it up
+                $updateuser->timemodified = time();
+                if (update_record("user", $updateuser)) {
+                    // unenrol_student($user->id);  // From all courses
+                    // remove_teacher($user->id);   // From all courses
+                    // remove_admin($user->id);
+                    delete_records('role_assignments', 'userid', $user->id); // unassign all roles
+                    notify(get_string('deletedactivity', '', fullname($user, true)) );
+                }
+                else {
+                    notify(get_string('deletednot', '', fullname($user, true)));
+                }
+                //copy pasted part ends
+            }     
+            commit_sql();
+        } 
+        $remove_users = 0; // free mem!   
+
+        ////
+        //// User Updates
+        //// (time-consuming, optional)
+        ////
+        if ($do_updates) {
+            // narrow down what fields we need to update
+            $all_keys = array_keys(get_object_vars($this->config));
+            $updatekeys = array();
+            foreach ($all_keys as $key) {
+                if (preg_match('/^field_updatelocal_(.+)$/',$key, $match)) {
+                    // if we have a field to update it from
+                    // and it must be updated 'onlogin' we 
+                    // update it on cron
+                    if ( !empty($this->config->{'field_map_'.$match[1]})
+                         and $this->config->{$match[0]} === 'onlogin') { 
+                        array_push($updatekeys, $match[1]); // the actual key name
+                    }
+                }
+            }
+            // print_r($all_keys); print_r($updatekeys);
+            unset($all_keys); unset($key);
+            
+        }
+        if ( $do_updates and !(empty($updatekeys)) ) { // run updates only if relevant
+            $users = get_records_sql('SELECT u.username, u.id FROM ' . $CFG->prefix . 'user u WHERE u.deleted=0 and u.auth=\'' . AUTH_LDAP_NAME . '\'' );
+            if (!empty($users)) {
+                print "User entries to update: ". count($users). "\n";
+                $sitecontext = get_context_instance(CONTEXT_SYSTEM);
+
+                if ($creatorroles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
+                    $creatorrole = array_shift($creatorroles);      // We can only use one, let's use the first one
+
+                    begin_sql();
+                    $xcount = 0;
+                    $maxxcount = 100;
+
+                    foreach ($users as $user) { 
+                        echo "updating user $user->username \n";
+                        $this->update_user_record($user->username, $updatekeys);
+
+                        // update course creators
+                        if (!empty($this->config->creators) and !empty($this->config->memberattribute) ) {
+                            if ($this->iscreator($user->username)) {   // Following calls will not create duplicates
+                                role_assign($creatorrole->id, $user->id, 0, $sitecontext->id, 0, 0, 0, 'ldap');
+                                $xcount++;
+                            } else {
+                                role_unassign($creatorrole->id, $user->id, 0, $sitecontext->id);
+                                $xcount++;
+                            }
+                        }
+
+                        if ($xcount++ > $maxxcount) {
+                            commit_sql();
+                            begin_sql(); 
+                            $xcount = 0;
+                        }
+                    }  
+                    commit_sql();
+                    unset($users); // free mem
+                }
+            }
+        } // end do updates
+        
+        ////
+        //// User Additions
+        ////
+        // find users missing in DB that are in LDAP
+        // note that get_records_sql wants at least 2 fields returned,
+        // and gives me a nifty object I don't want.
+        $sql = 'SELECT e.idnumber,1 
+                FROM ' . $CFG->prefix .'extuser e  LEFT JOIN ' . $CFG->prefix .'user u
+                        ON e.idnumber = u.idnumber 
+                WHERE  u.id IS NULL OR (u.id IS NOT NULL AND u.deleted=1)';
+        $add_users = get_records_sql($sql); // get rid of the fat        
+        
+        if (!empty($add_users)) {
+            print "User entries to add: ". count($add_users). "\n";
+
+            if ($creatorroles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
+                $creatorrole = array_shift($roles);      // We can only use one, let's use the first one
+            }
+
+            begin_sql();
+            foreach ($add_users as $user) {
+                $user = $this->get_userinfo_asobj($user->idnumber);
+                //print $user->username . "\n";
+                
+                // prep a few params
+                $user->modified  = time();
+                $user->confirmed = 1;
+                $user->auth      = AUTH_LDAP_NAME;
+                
+                // insert it
+                $old_debug=$CFG->debug; 
+                $CFG->debug=10;
+                
+                // maybe the user has been deleted before
+                if ($old_user = get_record('user', 'idnumber', $user->idnumber, 'deleted', 1)) {
+                    $user->id = $old_user->id;
+                    set_field('user', 'deleted', 0, 'idnumber', $user->idnumber);
+                    echo "Revived user $user->username with idnumber $user->idnumber id $user->id\n";
+                }
+                elseif ($id = insert_record('user',$user)) { // it is truly a new user
+                    echo "inserted user $user->username with idnumber $user->idnumber id $id\n";
+                    $user->id = $id;
+                }
+                else {
+                    echo "error inserting user $user->username with idnumber $user->idnumber \n";
+                }
+                $CFG->debug = $old_debug;
+                $userobj = $this->update_user_record($user->username);
+                if (isset($this->config->forcechangepassword) and $this->config->forcechangepassword) {
+                    set_user_preference('auth_forcepasswordchange', 1, $userobj->id);
+                }
+                
+                // update course creators
+                if (isset($creatorrole->id) and !empty($this->config->creators) and !empty($this->config->memberattribute)) {
+                    if ($this->iscreator($user->username)) {
+                        if (user_has_role_assignment($user->id, $creatorrole->id, $sitecontext->id)) {
+                            role_unassign($creatorrole->id, $user->id, 0, $sitecontext->id);
+                        } else {
+                            role_assign($creatorrole->id, $user->id, 0, $sitecontext->id, 0, 0, 0, 'ldap');
+                        }
+                    }
+                }
+            }
+            commit_sql();
+            unset($add_users); // free mem
+        }
+        return true;
+    }
+
+    /** 
+     * Update a local user record from an external source. 
+     * This is a lighter version of the one in moodlelib -- won't do 
+     * expensive ops such as enrolment.
+     *
+     * If you don't pass $updatekeys, there is a performance hit and 
+     * values removed from LDAP won't be removed from moodle. 
+     */
+    function update_user_record($username, $updatekeys = false) {
+
+        global $CFG;
+
+        //just in case check text case
+        $username = trim(moodle_strtolower($username));
+        
+        // get the current user record
+        $user = get_record('user', 'username', $username);
+        if (empty($user)) { // trouble
+            error_log("Cannot update non-existent user: $username");
+            die;
+        }
+
+        if (function_exists('auth_get_userinfo')) {
+            if ($newinfo = auth_get_userinfo($username)) {
+                $newinfo = truncate_userinfo($newinfo);
+                
+                if (empty($updatekeys)) { // all keys? this does not support removing values
+                    $updatekeys = array_keys($newinfo);
+                }
+                
+                foreach ($updatekeys as $key) {
+                    unset($value);
+                    if (isset($newinfo[$key])) {
+                        $value = $newinfo[$key];
+                        $value = addslashes(stripslashes($value)); // Just in case
+                    }
+                    else {
+                        $value = '';
+                    }
+                    if (!empty($this->config->{'field_updatelocal_' . $key})) { 
+                           if ($user->{$key} != $value) { // only update if it's changed
+                               set_field('user', $key, $value, 'username', $username);
+                           }
+                    }
+                }
+            }
+        }
+        return get_record_select("user", "username = '$username' AND deleted <> '1'");
+    }
+
+    function ldap_bulk_insert($users) {
+    // bulk insert in SQL's temp table
+    // $users is an array of usernames
+        global $CFG;
+        
+        // bulk insert -- superfast with $bulk_insert_records
+        $sql = 'INSERT INTO '.$CFG->prefix.'extuser (idnumber) VALUES ';
+        // make those values safe
+        array_map('addslashes', $users);
+        // join and quote the whole lot
+        $sql = $sql . '(\'' . join('\'),(\'', $users) . '\')';
+        print "+ " . count($users) . " users\n";
+        execute_sql($sql, false); 
+
+    }
+
+
+    /*
+     * user_activate activates user in external db.
+     *
+     * Activates (enables) user in external db so user can login to external db
+     *
+     * @param mixed $username    username
+     * @return boolen result
+     */
+    function user_activate($username) {
+        
+        global $CFG;
+        
+        $ldapconnection = $this->ldap_connect();
+
+        $userdn = $this->ldap_find_userdn($ldapconnection, $username);
+        switch ($this->config->user_type)  {
+            case 'edir':
+                $newinfo['loginDisabled']="FALSE";
+                break;
+            default:
+                error ('auth: ldap user_activate() does not support selected usertype:"'.$this->config->user_type.'" (..yet)');    
+        } 
+        $result = ldap_modify($ldapconnection, $userdn, $newinfo);
+        ldap_close($ldapconnection);
+        return $result;
+    }
+
+    /*
+     * user_disables disables user in external db.
+     *
+     * Disables user in external db so user can't login to external db
+     *
+     * @param mixed $username    username
+     * @return boolean result
+     */
+    function user_disable($username) {
+        global $CFG;
+
+        $ldapconnection = $this->ldap_connect();
+
+        $userdn = $this->ldap_find_userdn($ldapconnection, $username);
+        switch ($this->config->user_type)  {
+            case 'edir':
+                $newinfo['loginDisabled']="TRUE";
+                break;
+            default:
+                error ('auth: ldap user_disable() does not support selected usertype (..yet)');    
+        }    
+        $result = ldap_modify($ldapconnection, $userdn, $newinfo);
+        ldap_close($ldapconnection);
+        return $result;
+    }
+
+    /*
+     * Returns true if user should be coursecreator.
+     *
+     * @param mixed $username    username
+     * @return boolean result
+     */
+    function iscreator($username = false) {
+        ///if user is member of creator group return true
+        global $USER, $CFG;
+        $this->ldap_init();
+        if (! $username) {
+            $username = $USER->username;
+        }
+        if ((! $this->config->creators) or (! $this->config->memberattribute)) {
+            return null;
+        }
+        return $this->ldap_isgroupmember($username, $this->config->creators);
+    }
+
+    /* 
+     * user_update saves userinformation from moodle to external db
+     *
+     * Called when the user record is updated.
+     * Modifies user in external database. It takes olduser (before changes) and newuser (after changes) 
+     * conpares information saved modified information to external db.
+     *
+     * @param mixed $olduser     Userobject before modifications
+     * @param mixed $newuser     Userobject new modified userobject
+     * @return boolean result
+     *
+     */
+    function user_update($olduser, $newuser) {
+
+        global $USER, $CFG;
+
+        $ldapconnection = $this->ldap_connect();
+        
+        $result = array();
+        $search_attribs = array();
+
+        $attrmap = $this->ldap_attributes();  
+        foreach ($attrmap as $key => $values) {
+            if (!is_array($values)) {
+                $values = array($values);
+            }
+            foreach ($values as $value) {
+                if (!in_array($value, $search_attribs)) {
+                    array_push($search_attribs, $value);
+                }
+            }    
+        }
+
+        $user_dn = $this->ldap_find_userdn($ldapconnection, $olduser->username);
+
+        $user_info_result = ldap_read($ldapconnection, $user_dn,
+                                $this->config->objectclass, $search_attribs);
+
+        if ($user_info_result) {
+
+            $user_entry = $this->ldap_get_entries($ldapconnection, $user_info_result);
+            if (count($user_entry) > 1) {
+                trigger_error("ldap: Strange! More than one user record found in ldap. Only using the first one.");
+            }
+            $user_entry = $user_entry[0];
+
+            //error_log(var_export($user_entry) . 'fpp' );
+            
+            foreach ($attrmap as $key => $ldapkeys) {
+
+                // only process if the moodle field ($key) has changed and we
+                // are set to update LDAP with it
+                if ($olduser->$key !== $newuser->$key and
+                    !empty($this->config->{'field_updateremote_'. $key})) {
+
+                    // for ldap values that could be in more than one 
+                    // ldap key, we will do our best to match 
+                    // where they came from
+                    $ambiguous = true;
+                    $changed   = false;
+                    if (!is_array($ldapkeys)) {
+                        $ldapkeys = array($ldapkeys);
+                    }
+                    if (count($ldapkeys) < 2) {
+                        $ambiguous = false;
+                    }
+                     
+                    foreach ($ldapkeys as $ldapkey) {
+                        $ldapkey   = strtolower($ldapkey);
+                        $ldapvalue = $user_entry[$ldapkey][0];
+                        if (!$ambiguous) {
+                            // skip update if the values already match
+                            if ( !($newuser->$key === $ldapvalue) ) {
+                                ldap_modify($ldapconnection, $user_dn, array($ldapkey => $newuser->$key));
+                            }
+                            else { 
+                                error_log("Skip updating field $key for entry $user_dn: it seems to be already same on LDAP.
+                                      old moodle value: '{$olduser->$key}'
+                                      new value: '{$newuser->$key}'
+                                      current value in ldap entry: '{$ldapvalue}'");
+                            }
+                        }
+                        else {
+                            // ambiguous
+                            // value empty before in Moodle (and LDAP) - use 1st ldap candidate field
+                            // no need to guess
+                            if (empty($olduser->$key)) { // value empty before - use 1st ldap candidate
+                                if (ldap_modify($ldapconnection, $user_dn, array($ldapkey => $newuser->$key))) {
+                                    $changed = true;
+                                    last;
+                                }
+                                else {
+                                    error ('Error updating LDAP record. Error code: ' 
+                                        . ldap_errno($ldapconnection) . '; Error string : '
+                                        . ldap_err2str(ldap_errno($ldapconnection)));                                
+                                }
+                            }
+
+                            // we found which ldap key to update!                            
+                            if (!empty($ldapvalue) and $olduser->$key === $ldapvalue ) {
+                                // error_log("Matched: ". $olduser->$key . " === " . $ldapvalue);
+                                if (ldap_modify($ldapconnection, $user_dn, array($ldapkey => $newuser->$key))) {
+                                    $changed = true;
+                                    last;
+                                }
+                                else {
+                                    error ('Error updating LDAP record. Error code: ' 
+                                      . ldap_errno($ldapconnection) . '; Error string : '
+                                      . ldap_err2str(ldap_errno($ldapconnection))); 
+                                }
+                            }
+                        }
+                    }
+                    
+                    if ($ambiguous and !$changed) {
+                        error_log("Failed to update LDAP with ambiguous field $key". 
+                                  "  old moodle value: '" . $olduser->$key . 
+                                  "' new value '" . $newuser->$key );
+                    }
+                }
+            }
+            
+
+        }
+        else {
+            error_log("ERROR:No user found in LDAP");
+            @ldap_close($ldapconnection);
+            return false;
+        }
+
+        @ldap_close($ldapconnection);
+        
+        return true;
+
+    }
+
+    /*
+     * changes userpassword in external db
+     *
+     * called when the user password is updated.
+     * changes userpassword in external db
+     *
+     * @param mixed $username    Username
+     * @param mixed $newpassword Plaintext password
+     * @param mixed $oldpassword Plaintext old password to bind ldap with
+     * @return boolean result
+     *
+     */
+    // function user_update_password($username, $newpassword) {
+    function user_update_password($user, $newpassword) {
+    /// called when the user password is updated -- it assumes it is called by an admin
+    /// or that you've otherwise checked the user's credentials
+    /// IMPORTANT: $newpassword must be cleartext, not crypted/md5'ed
+
+        global $CFG, $USER;
+        $result = false;
+        $username = $user->username;
+                 
+        $ldapconnection = $this->ldap_connect();
+
+        $user_dn = $this->ldap_find_userdn($ldapconnection, $username);
+        
+        if (!$user_dn) {
+            error_log('LDAP Error in user_update_password(). No DN for: ' . $username); 
+            return false;
+        }
+
+        switch ($this->config->user_type) {
+            case 'edir':
+                //Change password
+                $result = ldap_modify($ldapconnection, $user_dn, array('userPassword' => $newpassword));
+                if (!$result) {
+                    error_log('LDAP Error in user_update_password(). Error code: '
+                              . ldap_errno($ldapconnection) . '; Error string : '
+                              . ldap_err2str(ldap_errno($ldapconnection)));
+                }
+                //Update password expiration time, grace logins count
+                $search_attribs = array($this->config->expireattr, 'passwordExpirationInterval','loginGraceLimit' );
+                $sr = ldap_read($ldapconnection, $user_dn, 'objectclass=*', $search_attribs);
+                if ($sr)  {
+                    $info=$this->ldap_get_entries($ldapconnection, $sr);
+                    $newattrs = array();
+                    if (!empty($info[0][$this->config->expireattr][0])) {
+                        //Set expiration time only if passwordExpirationInterval is defined
+                        if (!empty($info[0]['passwordExpirationInterval'][0])) {
+                           $expirationtime = time() + $info[0]['passwordExpirationInterval'][0]; 
+                           $ldapexpirationtime = $this->ldap_unix2expirationtime($expirationtime);
+                           $newattrs['passwordExpirationTime'] = $ldapexpirationtime;
+                        }    
+
+                        //set gracelogin count
+                        if (!empty($info[0]['loginGraceLimit'][0])) {
+                           $newattrs['loginGraceRemaining']= $info[0]['loginGraceLimit'][0]; 
+                        }
+        
+                        //Store attribute changes to ldap
+                        $result = ldap_modify($ldapconnection, $user_dn, $newattrs);
+                        if (!$result) {
+                           error_log('LDAP Error in user_update_password() when modifying expirationtime and/or gracelogins. Error code: '
+                                     . ldap_errno($ldapconnection) . '; Error string : '
+                                     . ldap_err2str(ldap_errno($ldapconnection)));
+                        }
+                    }
+                }
+                else {
+                    error_log('LDAP Error in user_update_password() when reading password expiration time. Error code: '
+                              . ldap_errno($ldapconnection) . '; Error string : '
+                              . ldap_err2str(ldap_errno($ldapconnection)));
+                }    
+                break;
+                
+            default:
+                $usedconnection = &$ldapconnection;
+                // send ldap the password in cleartext, it will md5 it itself
+                $result = ldap_modify($ldapconnection, $user_dn, array('userPassword' => $newpassword));
+                if (!$result) {
+                    error_log('LDAP Error in user_update_password(). Error code: ' 
+                        . ldap_errno($ldapconnection) . '; Error string : '
+                        . ldap_err2str(ldap_errno($ldapconnection)));
+                }
+        
+        }
+
+        @ldap_close($ldapconnection);
+        return $result;
+    }
+
+    //PRIVATE FUNCTIONS starts
+    //private functions are named as ldap_*
+
+    /**
+     * returns predefined usertypes
+     *
+     * @return array of predefined usertypes
+     */
+
+    function ldap_suppported_usertypes() {
+    // returns array of supported usertypes (schemas)
+    // If you like to add our own please name and describe it here
+    // And then add case clauses in relevant places in functions
+    // iauth_ldap_init, auth_user_create, auth_check_expire, auth_check_grace
+        $types['edir']='Novell Edirectory';
+        $types['rfc2307']='posixAccount (rfc2307)';
+        $types['rfc2307bis']='posixAccount (rfc2307bis)';
+        $types['samba']='sambaSamAccount (v.3.0.7)';
+        $types['ad']='MS ActiveDirectory'; 
+        return $types;
+    }    
+
+       
+    /**
+     * initializes needed variables for ldap-module
+     *
+     * Uses names defined in ldap_supported_usertypes.
+     * $default is first defined as:
+     * $default['pseudoname'] = array(
+     *                      'typename1' => 'value',
+     *                      'typename2' => 'value'
+     *                      ....
+     *                      );
+     *
+     * @return array of default values
+     */
+    function ldap_getdefaults() {
+        $default['objectclass'] = array(
+                            'edir' => 'User',
+                            'rfc2703' => 'posixAccount',
+                            'rfc2703bis' => 'posixAccount',
+                            'samba' => 'sambaSamAccount',
+                            'ad' => 'user',
+                            'default' => '*'
+                            );
+        $default['user_attribute'] = array(
+                            'edir' => 'cn',
+                            'rfc2307' => 'uid',
+                            'rfc2307bis' => 'uid',
+                            'samba' => 'uid',
+                            'ad' => 'cn',
+                            'default' => 'cn'
+                            );
+        $default['memberattribute'] = array(
+                            'edir' => 'member',
+                            'rfc2307' => 'member',
+                            'rfc2307bis' => 'member',
+                            'samba' => 'member',
+                            'ad' => 'member', 
+                            'default' => 'member'
+                            );
+        $default['memberattribute_isdn'] = array(
+                            'edir' => '1',
+                            'rfc2307' => '0',
+                            'rfc2307bis' => '1',
+                            'samba' => '0', //is this right?
+                            'ad' => '1',
+                            'default' => '0'
+                            );
+        $default['expireattr'] = array (
+                            'edir' => 'passwordExpirationTime',
+                            'rfc2307' => 'shadowExpire',
+                            'rfc2307bis' => 'shadowExpire',
+                            'samba' => '', //No support yet
+                            'ad' => '', //No support yet
+                            'default' => ''
+                            );
+        return $default; 
+    }
+
+    /**
+     * return binaryfields of selected usertype
+     *
+     *
+     * @return array
+     */
+    function ldap_getbinaryfields () {
+        global $CFG;
+        $binaryfields = array (
+                            'edir' => array('guid'),
+                            'rfc2703' => array(),
+                            'rfc2703bis' => array(),
+                            'samba' => array(),
+                            'ad' => array(),
+                            'default' => '*'
+                            );
+        if (!empty($this->config->user_type)) {
+            return $binaryfields[$this->config->user_type];   
+        }
+        else {
+            return $binaryfields['default'];
+        }    
+    }
+
+    function ldap_isbinary ($field) {
+        if (!isset($field)) {
+            return null ;
+        }    
+        return array_search($field, $this->ldap_getbinaryfields());
+    }    
+
+    /**
+     * set $CFG-values for ldap_module
+     * 
+     * Get default configuration values with ldap_getdefaults() 
+     * and by using this information $CFG-> values are set
+     * If $CFG->value is alredy set current value is honored.
+     *
+     * 
+     */
+    function ldap_init () {
+        global $CFG;
+     
+        $default = $this->ldap_getdefaults();
+
+        // TODO: do we need set_config calls here?
+
+        foreach ($default as $key => $value) {
+            //set defaults if overriding fields not set
+            if (empty($this->config->{$key})) {
+                if (!empty($this->config->user_type) and !empty($default[$key][$this->config->user_type])) {
+                    $this->config->{$key} = $default[$key][$this->config->user_type];
+                }
+                else {
+                    //use default value if user_type not set
+                    if (!empty($default[$key]['default'])) {
+                        $this->config->{$key} = $default[$key]['default'];
+                    }
+                    else {
+                        unset($this->config->{$key});
+                    }    
+                }
+            }
+        }   
+        //hack prefix to objectclass
+        if ('objectClass=' != substr($this->config->objectclass, 0, 12)) {
+           $this->config->objectclass = 'objectClass='.$this->config->objectclass;
+        }
+       
+        //all chages go in $CFG , no need to return value
+    }
+
+    /**
+     * take expirationtime and return it as unixseconds
+     * 
+     * takes expriration timestamp as readed from ldap
+     * returns it as unix seconds
+     * depends on $config->user_type variable
+     *
+     * @param mixed time   Time stamp readed from ldap as it is.
+     * @return timestamp
+     */
+    function ldap_expirationtime2unix ($time) {
+
+        global $CFG;
+        $result = false;
+        switch ($this->config->user_type) {
+            case 'edir':
+                $yr=substr($time,0,4);
+                $mo=substr($time,4,2);
+                $dt=substr($time,6,2);
+                $hr=substr($time,8,2);
+                $min=substr($time,10,2);
+                $sec=substr($time,12,2);
+                $result = mktime($hr,$min,$sec,$mo,$dt,$yr); 
+                break;
+            case 'posix':
+                $result = $time * DAYSECS; //The shadowExpire contains the number of DAYS between 01/01/1970 and the actual expiration date
+                break;
+            default:  
+                error('config.user_type not defined or function ldap_expirationtime2unix does not support selected type!');
+        }
+        return $result;
+    }
+
+    /**
+     * takes unixtime and return it formated for storing in ldap
+     *
+     * @param integer unix time stamp
+     */
+    function ldap_unix2expirationtime($time) {
+        global $CFG;
+        $result = false;
+        switch ($this->config->user_type) {
+            case 'edir':
+                $result=date('YmdHis', $time).'Z';  
+                break;
+            case 'posix':
+                $result = $time ; //Already in correct format
+                break;
+            default:  
+                error('config.user_type not defined or function ldap_unixi2expirationtime does not support selected type!');
+        }        
+        return $result;
+
+    }
+
+    /*
+     * checks if user belong to specific group(s)
+     *
+     * Returns true if user belongs group in grupdns string.
+     *
+     * @param mixed $username    username
+     * @param mixed $groupdns    string of group dn separated by ;
+     *
+     */
+    function ldap_isgroupmember($username='', $groupdns='') {
+    // Takes username and groupdn(s) , separated by ;
+    // Returns true if user is member of any given groups
+
+        global $CFG ;
+        $result = false;
+        $ldapconnection = $this->ldap_connect();
+        
+        if (empty($username) or empty($groupdns)) {
+            return $result;
+            }
+
+        if ($this->config->memberattribute_isdn) {
+            $username=$this->ldap_find_userdn($ldapconnection, $username);
+        }
+        if (! $username ) {
+            return $result;
+        }
+
+        $groups = explode(";",$groupdns);
+        
+        foreach ($groups as $group) {
+            $group = trim($group);
+            if (empty($group)) {
+                continue;
+            }
+            //echo "Checking group $group for member $username\n";
+            $search = @ldap_read($ldapconnection, $group,  '('.$this->config->memberattribute.'='.$username.')', array($this->config->memberattribute));
+
+            if (!empty($search) and ldap_count_entries($ldapconnection, $search)) {$info = $this->ldap_get_entries($ldapconnection, $search);
+            
+                if (count($info) > 0 ) {
+                    // user is member of group
+                    $result = true;
+                    break;
+                }
+        }
+    }
+
+        return $result;
+
+    }
+
+    /**
+     * connects to ldap server
+     *
+     * Tries connect to specified ldap servers.
+     * Returns connection result or error.
+     *
+     * @return connection result
+     */
+    function ldap_connect($binddn='',$bindpwd='') {
+    /// connects  and binds to ldap-server
+    /// Returns connection result
+
+        global $CFG;
+        $this->ldap_init();
+
+        //Select bind password, With empty values use
+        //ldap_bind_* variables or anonymous bind if ldap_bind_* are empty
+        if ($binddn == '' and $bindpwd == '') {
+            if (!empty($this->config->bind_dn)) {
+               $binddn = $this->config->bind_dn;
+            }
+            if (!empty($this->config->bind_pw)) {
+               $bindpwd = $this->config->bind_pw;
+            }
+        }
+        
+        $urls = explode(";",$this->config->host_url);
+            
+        foreach ($urls as $server) {
+            $server = trim($server);
+            if (empty($server)) {
+                continue;
+            }
+
+            $connresult = ldap_connect($server);
+            //ldap_connect returns ALWAYS true
+     
+            if (!empty($this->config->version)) {
+                ldap_set_option($connresult, LDAP_OPT_PROTOCOL_VERSION, $this->config->version);
+            }
+
+            if (!empty($binddn)) {
+                //bind with search-user
+                //$debuginfo .= 'Using bind user'.$binddn.'and password:'.$bindpwd; 
+                $bindresult=ldap_bind($connresult, $binddn,$bindpwd);
+            }
+            else {
+                //bind anonymously 
+                $bindresult=@ldap_bind($connresult);
+            }  
+           
+            if (!empty($this->config->opt_deref)) {
+                ldap_set_option($connresult, LDAP_OPT_DEREF, $this->config->opt_deref);
+            }
+
+            if ($bindresult) {
+                return $connresult;
+            }
+            
+            $debuginfo .= "<br/>Server: '$server' <br/> Connection: '$connresult'<br/> Bind result: '$bindresult'</br>";
+        }
+
+        //If any of servers are alive we have already returned connection
+        error("LDAP-module cannot connect any LDAP servers : $debuginfo");
+        return false;
+    }
+
+    /**
+     * retuns dn of username
+     *
+     * Search specified contexts for username and return user dn
+     * like: cn=username,ou=suborg,o=org
+     *
+     * @param mixed $ldapconnection  $ldapconnection result
+     * @param mixed $username username
+     *
+     */
+
+    function ldap_find_userdn ($ldapconnection, $username) {
+
+        global $CFG;
+
+        //default return value
+        $ldap_user_dn = FALSE;
+
+        //get all contexts and look for first matching user
+        $ldap_contexts = explode(";",$this->config->contexts);
+        
+        if (!empty($this->config->create_context)) {
+          array_push($ldap_contexts, $this->config->create_context);
+        }
+      
+        foreach ($ldap_contexts as $context) {
+
+            $context = trim($context);
+            if (empty($context)) {
+                continue;
+            }
+
+            if ($this->config->search_sub) {
+                //use ldap_search to find first user from subtree
+                $ldap_result = ldap_search($ldapconnection, $context, "(".$this->config->user_attribute."=".$username.")",array($this->config->user_attribute));
+
+            }
+            else {
+                //search only in this context
+                $ldap_result = ldap_list($ldapconnection, $context, "(".$this->config->user_attribute."=".$username.")",array($this->config->user_attribute));
+            }
+     
+            $entry = ldap_first_entry($ldapconnection,$ldap_result);
+
+            if ($entry) {
+                $ldap_user_dn = ldap_get_dn($ldapconnection, $entry);
+                break ;
+            }
+        }
+
+        return $ldap_user_dn;
+    }
+
+    /**
+     * retuns user attribute mappings between moodle and ldap
+     *
+     * @return array
+     */
+
+    function ldap_attributes () {
+        $fields = array("firstname", "lastname", "email", "phone1", "phone2", 
+                        "department", "address", "city", "country", "description", 
+                        "idnumber", "lang" );
+        $moodleattributes = array();
+        foreach ($fields as $field) {
+            if (!empty($this->config->{"field_map_$field"})) {
+                $moodleattributes[$field] = $this->config->{"field_map_$field"};
+                if (preg_match('/,/',$moodleattributes[$field])) {
+                    $moodleattributes[$field] = explode(',', $moodleattributes[$field]); // split ?
+                }
+            }
+        }
+        $moodleattributes['username'] = $this->config->user_attribute;
+        return $moodleattributes;
+    }
+
+    /**
+     * return all usernames from ldap
+     *
+     * @return array
+     */
+
+    function ldap_get_userlist($filter="*") {
+    /// returns all users from ldap servers
+        global $CFG;
+
+        $fresult = array();
+
+        $ldapconnection = $this->ldap_connect();
+
+        if ($filter=="*") {
+           $filter = "(&(".$this->config->user_attribute."=*)(".$this->config->objectclass."))";
+        }
+
+        $contexts = explode(";",$this->config->contexts);
+     
+        if (!empty($this->config->create_context)) {
+              array_push($contexts, $this->config->create_context);
+        }
+
+        foreach ($contexts as $context) {
+
+            $context = trim($context);
+            if (empty($context)) {
+                continue;
+            }
+
+            if ($this->config->search_sub) {
+                //use ldap_search to find first user from subtree
+                $ldap_result = ldap_search($ldapconnection, $context,$filter,array($this->config->user_attribute));
+            }
+            else {
+                //search only in this context
+                $ldap_result = ldap_list($ldapconnection, $context,
+                                         $filter,
+                                         array($this->config->user_attribute));
+            }
+            
+            $users = $this->ldap_get_entries($ldapconnection, $ldap_result);
+
+            //add found users to list
+            for ($i=0;$i<count($users);$i++) {
+                array_push($fresult, ($users[$i][$this->config->user_attribute][0]) );
+            }
+        }
+       
+        return $fresult;
+    }
+
+    /**
+     * return entries from ldap
+     *
+     * Returns values like ldap_get_entries but is
+     * binary compatible and return all attributes as array
+     *
+     * @return array ldap-entries
+     */
+       
+    function ldap_get_entries($conn, $searchresult) {
+    //Returns values like ldap_get_entries but is
+    //binary compatible
+        $i=0;
+        $fresult=array();
+        $entry = ldap_first_entry($conn, $searchresult);
+        do {
+            $attributes = @ldap_get_attributes($conn, $entry);
+            for ($j=0; $j<$attributes['count']; $j++) {
+                $values = ldap_get_values_len($conn, $entry,$attributes[$j]);
+                if (is_array($values)) {
+                $fresult[$i][$attributes[$j]] = $values;
+                }
+                else {
+                    $fresult[$i][$attributes[$j]] = array($values);
+                }
+            }         
+            $i++;               
+        }
+        while ($entry = @ldap_next_entry($conn, $entry));
+        //were done
+        return ($fresult);
+    }
+
+    /**
+     * Returns true if this authentication plugin is 'internal'.
+     *
+     * @returns bool
+     */
+    function is_internal() {
+        return false;
+    }
+
+    /**
+     * Returns true if this authentication plugin can change the user's
+     * password.
+     *
+     * @returns bool
+     */
+    function can_change_password() {
+        return true;
+    }
+    
+    /**
+     * Returns the URL for changing the user's pw, or false if the default can
+     * be used.
+     *
+     * @returns bool
+     */
+    function change_password_url() {
+        return $CFG->changepasswordurl; // TODO: will this be global?
+    }
+    
+    /**
+     * Prints a form for configuring this authentication plugin.
+     *
+     * This function is called from admin/auth.php, and outputs a full page with
+     * a form for configuring this plugin.
+     *
+     * @param array $page An object containing all the data for this page.
+     */
+    function config_form($config, $err) {
+        include "config.html";
+    }
+
+    /**
+     * Processes and stores configuration data for this authentication plugin.
+     */
+    function process_config($config) {
+        // set to defaults if undefined
+        if (!isset($config->host_url)) 
+            { $config->host_url = ''; }
+        if (!isset($config->contexts)) 
+            { $config->contexts = ''; }
+        if (!isset($config->user_type)) 
+            { $config->user_type = ''; }
+        if (!isset($config->user_attribute)) 
+            { $config->user_attribute = ''; }
+        if (!isset($config->search_sub)) 
+            { $config->search_sub = ''; }
+        if (!isset($config->opt_deref)) 
+            { $config->opt_deref = ''; }
+        if (!isset($config->preventpassindb)) 
+            { $config->preventpassindb = 0; } 
+        if (!isset($config->bind_dn)) 
+            {$config->bind_dn = ''; }
+        if (!isset($config->bind_pw)) 
+            {$config->bind_pw = ''; }
+        if (!isset($config->version)) 
+            {$config->version = '2'; }
+        if (!isset($config->objectclass)) 
+            {$config->objectclass = ''; }
+        if (!isset($config->memberattribute)) 
+            {$config->memberattribute = ''; }
+        if (!isset($config->creators)) 
+            {$config->creators = ''; }
+        if (!isset($config->create_context)) 
+            {$config->create_context = ''; }
+        if (!isset($config->expiration)) 
+            {$config->expiration = ''; }
+        if (!isset($config->expiration_warning)) 
+            {$config->expiration_warning = '10'; }
+        if (!isset($config->expireattr)) 
+            {$config->expireattr = ''; }
+        if (!isset($config->gracelogins)) 
+            {$config->gracelogins = ''; }
+        if (!isset($config->graceattr)) 
+            {$config->graceattr = ''; }
+        if (!isset($config->auth_user_create)) 
+            {$config->auth_user_create = ''; }
+        if (!isset($config->forcechangepassword)) 
+            {$config->forcechangepassword = false; }
+        if (!isset($config->stdchangepassword))
+            {$config->stdchangepassword = false; }
+        if (!isset($config->changepasswordurl))
+            {$config->changepasswordurl = ''; }
+
+        // save settings
+        set_config('host_url', $config->host_url, 'auth/ldap');
+        set_config('contexts', $config->contexts, 'auth/ldap');
+        set_config('user_type', $config->user_type, 'auth/ldap');
+        set_config('user_attribute', $config->user_attribute, 'auth/ldap');
+        set_config('search_sub', $config->search_sub, 'auth/ldap');
+        set_config('opt_deref', $config->opt_deref, 'auth/ldap');
+        set_config('preventpassindb', $config->preventpassindb, 'auth/ldap');
+        set_config('bind_dn', $config->bind_dn, 'auth/ldap');
+        set_config('bind_pw', $config->bind_pw, 'auth/ldap');
+        set_config('version', $config->version, 'auth/ldap');
+        set_config('objectclass', $config->objectclass, 'auth/ldap');
+        set_config('memberattribute', $config->memberattribute, 'auth/ldap');
+        set_config('creators', $config->creators, 'auth/ldap');
+        set_config('create_context', $config->create_context, 'auth/ldap');
+        set_config('expiration', $config->expiration, 'auth/ldap');
+        set_config('expiration_warning', $config->expiration_warning, 'auth/ldap');
+        set_config('expireattr', $config->expireattr, 'auth/ldap');
+        set_config('gracelogins', $config->gracelogins, 'auth/ldap');
+        set_config('graceattr', $config->graceattr, 'auth/ldap');
+        set_config('auth_user_create', $config->auth_user_create, 'auth/ldap');
+        set_config('forcechangepassword', $config->forcechangepassword, 'auth/ldap');
+        set_config('stdchangepassword', $config->stdchangepassword, 'auth/ldap');
+        set_config('changepasswordurl', $config->changepasswordurl, 'auth/ldap');
+
+        return true;
+    }
+
+}
+
+?>
index 1696b12..c5d5d16 100755 (executable)
@@ -21,7 +21,7 @@
  */
 
 
-if(!empty($_SERVER['GATEWAY_INTERFACE'])){
+if (!empty($_SERVER['GATEWAY_INTERFACE'])) {
     error_log("should not be called from apache!");
     exit;
 }
@@ -31,9 +31,11 @@ require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); // global moodl
 require_once($CFG->dirroot.'/course/lib.php');
 require_once($CFG->dirroot.'/lib/blocklib.php');
 require_once($CFG->dirroot.'/mod/resource/lib.php');
-require_once($CFG->dirroot.'/auth/ldap/lib.php');
 require_once($CFG->dirroot.'/mod/forum/lib.php');
 $CFG->debug=10;
-auth_sync_users(1000, true  );
 
-?>
\ No newline at end of file
+require_once($CFG->dirroot.'/lib/moodlelib.php');
+$ldapauth = get_auth_plugin('ldap');
+$ldapauth->sync_users(1000, true);
+
+?>
index 0c50e34..9f22fb1 100644 (file)
 <?php
-    // Initialize vars
-    if (!isset($config->ldap_host_url)) 
-        { $config->ldap_host_url = ''; }
-    if (!isset($config->ldap_contexts)) 
-        { $config->ldap_contexts = ''; }
-    if (!isset($config->ldap_user_type)) 
-        { $config->ldap_user_type = ''; }
-    if (!isset($config->ldap_user_attribute)) 
-        { $config->ldap_user_attribute = ''; }
-    if (!isset($config->ldap_search_sub)) 
-        { $config->ldap_search_sub = ''; }
-    if (!isset($config->ldap_opt_deref)) 
-        { $config->ldap_opt_deref = ''; }
-    if (!isset($config->ldap_preventpassindb)) 
-        { $config->ldap_preventpassindb = 0; } 
-    if (!isset($config->ldap_bind_dn)) 
-        {$config->ldap_bind_dn = ''; }
-    if (!isset($config->ldap_bind_pw)) 
-        {$config->ldap_bind_pw = ''; }
-    if (!isset($config->ldap_version)) 
-        {$config->ldap_version = '2'; }
-    if (!isset($config->ldap_objectclass)) 
-        {$config->ldap_objectclass = ''; }
-    if (!isset($config->ldap_memberattribute)) 
-        {$config->ldap_memberattribute = ''; }
-    if (!isset($config->ldap_creators)) 
-        {$config->ldap_creators = ''; }
-    if (!isset($config->ldap_create_context)) 
-        {$config->ldap_create_context = ''; }
-    if (!isset($config->ldap_expiration)) 
-        {$config->ldap_expiration = ''; }
-    if (!isset($config->ldap_expiration_warning)) 
-        {$config->ldap_expiration_warning = '10'; }
-    if (!isset($config->ldap_expireattr)) 
-        {$config->ldap_expireattr = ''; }
-    if (!isset($config->ldap_gracelogins)) 
-        {$config->ldap_gracelogins = ''; }
-    if (!isset($config->ldap_graceattr)) 
-        {$config->ldap_graceattr = ''; }
+
+    $createoptions[0] = get_string("no");
+    $createoptions[1] = get_string("yes");
+
+    // set to defaults if undefined
+    if (!isset($config->host_url)) 
+        { $config->host_url = ''; }
+    if (!isset($config->contexts)) 
+        { $config->contexts = ''; }
+    if (!isset($config->user_type)) 
+        { $config->user_type = ''; }
+    if (!isset($config->user_attribute)) 
+        { $config->user_attribute = ''; }
+    if (!isset($config->search_sub)) 
+        { $config->search_sub = ''; }
+    if (!isset($config->opt_deref)) 
+        { $config->opt_deref = ''; }
+    if (!isset($config->preventpassindb)) 
+        { $config->preventpassindb = 0; } 
+    if (!isset($config->bind_dn)) 
+        {$config->bind_dn = ''; }
+    if (!isset($config->bind_pw)) 
+        {$config->bind_pw = ''; }
+    if (!isset($config->version)) 
+        {$config->version = '2'; }
+    if (!isset($config->objectclass)) 
+        {$config->objectclass = ''; }
+    if (!isset($config->memberattribute)) 
+        {$config->memberattribute = ''; }
+    if (!isset($config->creators)) 
+        {$config->creators = ''; }
+    if (!isset($config->create_context)) 
+        {$config->create_context = ''; }
+    if (!isset($config->expiration)) 
+        {$config->expiration = ''; }
+    if (!isset($config->expiration_warning)) 
+        {$config->expiration_warning = '10'; }
+    if (!isset($config->expireattr)) 
+        {$config->expireattr = ''; }
+    if (!isset($config->gracelogins)) 
+        {$config->gracelogins = ''; }
+    if (!isset($config->graceattr)) 
+        {$config->graceattr = ''; }
     if (!isset($config->auth_user_create)) 
         {$config->auth_user_create = ''; }
-    if (!isset($config->auth_ldap_forcechangepassword)) 
-        {$config->auth_ldap_forcechangepassword = false; }
-    if (!isset($config->auth_ldap_stdchangepassword))
-        {$config->auth_ldap_stdchangepassword = false; }
+    if (!isset($config->forcechangepassword)) 
+        {$config->forcechangepassword = false; }
+    if (!isset($config->stdchangepassword))
+        {$config->stdchangepassword = false; }
+    if (!isset($config->changepasswordurl))
+        {$config->changepasswordurl = ''; }
 
     $yesno = array( get_string('no'), get_string('yes') );
     
-if (!function_exists('ldap_connect')){ // Is php4-ldap really there?
+if (!function_exists('ldap_connect')) { // Is php4-ldap really there?
     print '<tr><td><p align="center"><font color="red"><strong>Warning:
            The PHP LDAP module does not seem to be present. 
            Please ensure it is installed and enabled.</strong></font></p></td></tr>';
 }
     
 ?>
+<table cellspacing="0" cellpadding="5" border="0" align="center">
+
 <tr>
    <td colspan="2">
-        <h4><?php print_string("auth_ldap_server_settings", "auth") ?> </h4>
+        <h4><?php print_string('auth_ldap_server_settings', 'auth') ?> </h4>
    </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_host_url:</td>
+    <td align="right">host_url:</td>
     <td>
-        <input name="ldap_host_url" type="text" size="30" value="<?php echo $config->ldap_host_url?>" />
-    <?php  if (isset($err["ldap_host_url"])) formerr($err["ldap_host_url"]); ?>
+        <input name="host_url" type="text" size="30" value="<?php echo $config->host_url?>" />
+    <?php  if (isset($err['host_url'])) formerr($err['host_url']); ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_host_url","auth") ?>
+    <?php  print_string('auth_ldap_host_url','auth') ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_version:</td>
+    <td align="right">version:</td>
     <td>
     <?php
-       $versions[2] = "2";
-       $versions[3] = "3";
-       choose_from_menu($versions, "ldap_version", $config->ldap_version, "");
-       if (isset($err["ldap_version"])) formerr($err["ldap_version"]); 
+       $versions[2] = '2';
+       $versions[3] = '3';
+       choose_from_menu($versions, 'version', $config->version, '');
+       if (isset($err['version'])) formerr($err['version']); 
     ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_version","auth") ?>
+    <?php  print_string('auth_ldap_version','auth') ?>
     </td>
 </tr>
 
 <tr>
    <td colspan="2">
-        <h4><?php print_string("auth_ldap_bind_settings", "auth") ?> </h4>
+        <h4><?php print_string('auth_ldap_bind_settings', 'auth') ?> </h4>
    </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_preventpassindb:</td>
+    <td align="right">preventpassindb:</td>
     <td>
     <?php
         $choices = array();
-        $choices["0"] = get_string("no");
-        $choices["1"] = get_string("yes");
-        choose_from_menu ($choices, "ldap_preventpassindb", $config->ldap_preventpassindb, "");
+        $choices['0'] = get_string('no');
+        $choices['1'] = get_string('yes');
+        choose_from_menu ($choices, 'preventpassindb', $config->preventpassindb, '');
     ?>
     </td><td>
-    <?php  print_string("auth_ldap_preventpassindb","auth") ?>
+    <?php  print_string('auth_ldap_preventpassindb','auth') ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_bind_dn:</td>
+    <td align="right">bind_dn:</td>
     <td>
-    <input name="ldap_bind_dn" type="text" size="30" value="<?php echo $config->ldap_bind_dn?>" />
-    <?php  if (isset($err["ldap_bind_dn"])) formerr($err["ldap_bind_dn"]); ?>
+    <input name="bind_dn" type="text" size="30" value="<?php echo $config->bind_dn?>" />
+    <?php  if (isset($err['bind_dn'])) formerr($err['bind_dn']); ?>
     </td><td>
-    <?php  print_string("auth_ldap_bind_dn","auth") ?>
+    <?php  print_string('auth_ldap_bind_dn','auth') ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_bind_pw:</td>
+    <td align="right">bind_pw:</td>
     <td>
-    <input name="ldap_bind_pw" type="password" size="30" value="<?php echo $config->ldap_bind_pw?>" />
-    <?php  if (isset($err["ldap_bind_pw"])) formerr($err["ldap_bind_pw"]); ?>
+    <input name="bind_pw" type="password" size="30" value="<?php echo $config->bind_pw?>" />
+    <?php  if (isset($err['bind_pw'])) formerr($err['bind_pw']); ?>
     </td><td>
-    <?php  print_string("auth_ldap_bind_pw","auth") ?>
+    <?php  print_string('auth_ldap_bind_pw','auth') ?>
     </td>
 </tr>
 
 <tr>
    <td colspan="2">
-        <h4><?php print_string("auth_ldap_user_settings", "auth") ?> </h4>
+        <h4><?php print_string('auth_ldap_user_settings', 'auth') ?> </h4>
    </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_user_type:</td>
+    <td align="right">user_type:</td>
     <td>
-    <?php choose_from_menu(auth_ldap_suppported_usertypes(), "ldap_user_type", $config->ldap_user_type, ""); ?>
-    <?php  if (isset($err["ldap_user_type"])) formerr($err["ldap_user_type"]); ?>
+    <?php choose_from_menu($this->ldap_suppported_usertypes(), 'user_type', $config->user_type, ''); ?>
+    <?php  if (isset($err['user_type'])) formerr($err['user_type']); ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_user_type","auth") ?>
+    <?php  print_string('auth_ldap_user_type', 'auth') ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_contexts:</td>
+    <td align="right">contexts:</td>
     <td>
-    <input name="ldap_contexts" type="text" size="30" value="<?php echo $config->ldap_contexts?>" />
-    <?php  if (isset($err["ldap_contexts"])) formerr($err["ldap_contexts"]); ?>
+    <input name="contexts" type="text" size="30" value="<?php echo $config->contexts?>" />
+    <?php  if (isset($err['contexts'])) formerr($err['contexts']); ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_contexts","auth") ?>
+    <?php  print_string('auth_ldap_contexts', 'auth') ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_search_sub:</td>
+    <td align="right">search_sub:</td>
     <td>
 <?php
     $choices = array();
-    $choices["0"] = get_string("no");
-    $choices["1"] = get_string("yes");
-    choose_from_menu ($choices, "ldap_search_sub", $config->ldap_search_sub, "");
+    $choices['0'] = get_string('no');
+    $choices['1'] = get_string('yes');
+    choose_from_menu ($choices, 'search_sub', $config->search_sub, '');
 ?>
-    <?php  if (isset($err["ldap_search_sub"])) formerr($err["ldap_search_sub"]); ?>
+    <?php  if (isset($err['search_sub'])) formerr($err['search_sub']); ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_search_sub","auth") ?>
+    <?php  print_string('auth_ldap_search_sub','auth') ?>
     </td>
 </tr>
 <tr valign="top" class="required">
-    <td align="right">ldap_opt_deref:</td>
+    <td align="right">opt_deref:</td>
     <td>
     <?php
-       $opt_deref[LDAP_DEREF_NEVER] = get_string("no");
-       $opt_deref[LDAP_DEREF_ALWAYS] = get_string("yes");
-       choose_from_menu($opt_deref, "ldap_opt_deref", $config->ldap_opt_deref, LDAP_DEREF_NEVER);
-       if (isset($err["ldap_opt_deref"])) formerr($err["ldap_opt_deref"]); 
+       $opt_deref[LDAP_DEREF_NEVER] = get_string('no');
+       $opt_deref[LDAP_DEREF_ALWAYS] = get_string('yes');
+       choose_from_menu($opt_deref, 'opt_deref', $config->opt_deref, LDAP_DEREF_NEVER);
+       if (isset($err['opt_deref'])) formerr($err['opt_deref']); 
     ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_opt_deref","auth") ?>
+    <?php  print_string('auth_ldap_opt_deref','auth') ?>
     </td>
 </tr>
 
 
 
 <tr valign="top" class="required">
-    <td align="right">ldap_user_attribute:</td>
+    <td align="right">user_attribute:</td>
     <td>
-    <input name="ldap_user_attribute" type="text" size="30" value="<?php echo $config->ldap_user_attribute?>" />
-    <?php  if (isset($err["ldap_user_attribute"])) formerr($err["ldap_user_attribute"]); ?>
+    <input name="user_attribute" type="text" size="30" value="<?php echo $config->user_attribute?>" />
+    <?php  if (isset($err['user_attribute'])) formerr($err['user_attribute']); ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_user_attribute","auth") ?>
+    <?php  print_string('auth_ldap_user_attribute','auth') ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-        <td align="right">ldap_memberattribute:</td>
+        <td align="right">memberattribute:</td>
         <td>
-    <input name="ldap_memberattribute" type="text" size="30" value="<?php echo $config->ldap_memberattribute?>" />
-    <?php  if (isset($err["ldap_memberattribute"])) formerr($err["ldap_memberattribute"]); ?>
+    <input name="memberattribute" type="text" size="30" value="<?php echo $config->memberattribute?>" />
+    <?php  if (isset($err['memberattribute'])) formerr($err['memberattribute']); ?>
     </td><td>
-    <?php  print_string("auth_ldap_memberattribute","auth") ?>
+    <?php  print_string('auth_ldap_memberattribute','auth') ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_objectclass:</td>
+    <td align="right">objectclass:</td>
     <td>
-    <input name="ldap_objectclass" type="text" size="30" value="<?php echo $config->ldap_objectclass?>" />
-    <?php  if (isset($err["ldap_objectclass"])) formerr($err["ldap_objectclass"]); ?>
+    <input name="objectclass" type="text" size="30" value="<?php echo $config->objectclass?>" />
+    <?php  if (isset($err['objectclass'])) formerr($err['objectclass']); ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_objectclass","auth") ?>
+    <?php  print_string('auth_ldap_objectclass','auth') ?>
     </td>
 </tr>
 
 <tr>
    <td colspan="2">
-        <h4><?php print_string("forcechangepassword", "auth") ?> </h4>
+        <h4><?php print_string('forcechangepassword', 'auth') ?> </h4>
    </td>
 </tr>
 
@@ -228,11 +236,11 @@ if (!function_exists('ldap_connect')){ // Is php4-ldap really there?
     <td align="right" valign="top"><?php  print_string('forcechangepassword', 'auth') ?>:</td>
     <td>
  
-    <select name="auth_ldap_forcechangepassword">
-        <option value="0" <?php echo ($config->auth_ldap_forcechangepassword ? '' : 'selected="yes"') ?> >
-            <?php  print_string("no")  ?></option>
-        <option value="1" <?php echo ($config->auth_ldap_forcechangepassword ? 'selected="yes"' : '') ?> >
-            <?php  print_string("yes") ?></option>
+    <select name="forcechangepassword">
+        <option value="0" <?php echo ($config->forcechangepassword ? '' : 'selected="yes"') ?> >
+            <?php  print_string('no')  ?></option>
+        <option value="1" <?php echo ($config->forcechangepassword ? 'selected="yes"' : '') ?> >
+            <?php  print_string('yes') ?></option>
     </select><br />
  
     </td>
@@ -245,11 +253,11 @@ if (!function_exists('ldap_connect')){ // Is php4-ldap really there?
     <td align="right" valign="top"><?php  print_string('stdchangepassword', 'auth') ?>:</td>
     <td>
  
-    <select name="auth_ldap_stdchangepassword">
-        <option value="0" <?php echo ($config->auth_ldap_stdchangepassword ? '' : 'selected="yes"') ?> >
-            <?php  print_string("no")  ?></option>
-        <option value="1" <?php echo ($config->auth_ldap_stdchangepassword ? 'selected="yes"' : '') ?> >
-            <?php  print_string("yes") ?></option>
+    <select name="stdchangepassword">
+        <option value='0' <?php echo ($config->stdchangepassword ? '' : 'selected="yes"') ?> >
+            <?php  print_string('no')  ?></option>
+        <option value='1' <?php echo ($config->stdchangepassword ? 'selected="yes"' : '') ?> >
+            <?php  print_string('yes') ?></option>
     </select><br />
 
     </td>
@@ -259,76 +267,91 @@ if (!function_exists('ldap_connect')){ // Is php4-ldap really there?
     </td>
 </tr>
 
+<tr valign="top">
+    <td align="right"> changepasswordurl: </td>
+    <td>
+        <input name="changepasswordurl" type="text" value="<?php echo $config->changepasswordurl ?>" />
+        <?php
+
+        if (isset($err['changepasswordurl'])) {
+            formerr($err['changepasswordurl']);
+        }
+
+        ?>
+    </td>
+    <td><?php print_string('changepasswordhelp', 'auth') ?></td>
+</tr>
+
 <tr>
    <td colspan="2">
-        <h4><?php print_string("auth_ldap_passwdexpire_settings", "auth") ?> </h4>
+        <h4><?php print_string('auth_ldap_passwdexpire_settings', 'auth') ?> </h4>
    </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_expiration:</td>
+    <td align="right">expiration:</td>
     <td>
     <?php
-       $expiration['0'] = "No";
-       $expiration['1'] = "LDAP";
-       choose_from_menu($expiration, "ldap_expiration", $config->ldap_expiration, "");
-       if (isset($err["ldap_expiration"])) formerr($err["ldap_expiration"]); 
+       $expiration['0'] = 'no';
+       $expiration['1'] = 'LDAP';
+       choose_from_menu($expiration, 'expiration', $config->expiration, '');
+       if (isset($err['expiration'])) formerr($err['expiration']); 
     ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_expiration_desc","auth") ?>
+    <?php  print_string('auth_ldap_expiration_desc','auth') ?>
     </td>
 </tr>
 
 
 <tr valign="top" class="required">
-    <td align="right">ldap_expiration_warning:</td>
+    <td align="right">expiration_warning:</td>
     <td>
-    <input name="ldap_expiration_warning" type="text" size="2" value="<?php echo $config->ldap_expiration_warning?>" />
-    <?php   if (isset($err["ldap_expiration_warning"])) formerr($err["ldap_expiration_warning"]); 
+    <input name="expiration_warning" type="text" size="2" value="<?php echo $config->expiration_warning?>" />
+    <?php   if (isset($err['expiration_warning'])) formerr($err['expiration_warning']); 
     ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_expiration_warning_desc","auth") ?>
+    <?php  print_string('auth_ldap_expiration_warning_desc','auth') ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_exprireattr:</td>
+    <td align="right">exprireattr:</td>
     <td>
-    <input name="ldap_expireattr" type="text" size="30" value="<?php echo $config->ldap_expireattr?>" />
-    <?php  if (isset($err["ldap_expireattr"])) formerr($err["ldap_expireattr"]); 
+    <input name="expireattr" type="text" size="30" value="<?php echo $config->expireattr?>" />
+    <?php  if (isset($err['expireattr'])) formerr($err['expireattr']); 
     ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_expireattr_desc","auth") ?>
+    <?php  print_string('auth_ldap_expireattr_desc','auth') ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_gracelogins:</td>
+    <td align="right">gracelogins:</td>
     <td>
     <?php
-       $grace['0'] = get_string("no");
-       $grace['1'] = get_string("yes");
-       choose_from_menu($grace, "ldap_gracelogins", $config->ldap_gracelogins, "");
-       if (isset($err["ldap_expiration"])) formerr($err["ldap_expiration"]); 
+       $grace['0'] = get_string('no');
+       $grace['1'] = get_string('yes');
+       choose_from_menu($grace, 'gracelogins', $config->gracelogins, '');
+       if (isset($err['expiration'])) formerr($err['expiration']); 
     ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_gracelogins_desc","auth") ?>
+    <?php  print_string('auth_ldap_gracelogins_desc','auth') ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">ldap_graceattr:</td>
+    <td align="right">graceattr:</td>
     <td>
-    <input name="ldap_graceattr" type="text" size="30" value="<?php echo $config->ldap_graceattr?>" />
-    <?php   if (isset($err["ldap_graceattr"])) formerr($err["ldap_graceattr"]); 
+    <input name="graceattr" type="text" size="30" value="<?php echo $config->graceattr?>" />
+    <?php   if (isset($err['graceattr'])) formerr($err['graceattr']); 
     ?>
     </td>
     <td>
-    <?php  print_string("auth_ldap_graceattr_desc","auth") ?>
+    <?php  print_string('auth_ldap_graceattr_desc','auth') ?>
     </td>
 </tr>
 
@@ -336,60 +359,67 @@ if (!function_exists('ldap_connect')){ // Is php4-ldap really there?
 
 <tr>
    <td colspan="2">
-        <h4><?php print_string("auth_user_create", "auth") ?> </h4>
+        <h4><?php print_string('auth_user_create', 'auth') ?> </h4>
    </td>
 </tr>
 
+<tr valign="top">
+    <td align="right">auth_user_create: </td>
+    <td>
+      <?php
+
+        choose_from_menu($createoptions, 'auth_user_create', $config->auth_user_create, '');
+        if (isset($err['auth_user_create'])) {
+            formerr($err['auth_user_create']);
+        }
+
+      ?>
+    </td>
+    <td>
+        <?php print_string("auth_user_creation","auth"); ?>
+    </td>
+</tr>
+
 </tr>
 <tr valign="top" class="required">
-    <td align="right">ldap_create_context:</td>
+    <td align="right">create_context:</td>
     <td>
-    <input name="ldap_create_context" type="text" size="30" value="<?php echo $config->ldap_create_context?>" />
-    <?php  if (isset($err["ldap_create_context"])) formerr($err["ldap_create_context"]); ?>
+    <input name="create_context" type="text" size="30" value="<?php echo $config->create_context?>" />
+    <?php  if (isset($err['create_context'])) formerr($err['create_context']); ?>
     </td><td>
-    <?php  print_string("auth_ldap_create_context","auth") ?>
+    <?php  print_string('auth_ldap_create_context','auth') ?>
     </td>
 </tr>
 
 
 <tr>
    <td colspan="2">
-        <h4><?php print_string("coursecreators") ?> </h4>
+        <h4><?php print_string('coursecreators') ?> </h4>
    </td>
 </tr>
 
 <tr valign="top" class="required">
-        <td align="right">ldap_creators:</td>
+        <td align="right">creators:</td>
         <td>
-    <input name="ldap_creators" type="text" size="30" value="<?php echo $config->ldap_creators?>" />
-    <?php  if (isset($err["ldap_creators"])) formerr($err["ldap_creators"]); ?>
+    <input name="creators" type="text" size="30" value="<?php echo $config->creators?>" />
+    <?php  if (isset($err['creators'])) formerr($err['creators']); ?>
     </td><td>
-    <?php  print_string("auth_ldap_creators","auth") ?>
+    <?php  print_string('auth_ldap_creators','auth') ?>
     </td>
 </tr>
 
 <?php 
 
-$help  = get_string("auth_ldapextrafields","auth");
-$help .= get_string("auth_updatelocal_expl","auth");
-$help .= get_string("auth_fieldlock_expl","auth");
-$help .= get_string("auth_updateremote_expl","auth");
+$help  = get_string('auth_ldapextrafields','auth');
+$help .= get_string('auth_updatelocal_expl','auth');
+$help .= get_string('auth_fieldlock_expl','auth');
+$help .= get_string('auth_updateremote_expl','auth');
 $help .= '<hr />';
-$help .= get_string("auth_updateremote_ldap","auth");
+$help .= get_string('auth_updateremote_ldap','auth');
 
-print_auth_lock_options($auth, $user_fields, $help, true, true); 
-?>
-
-<tr valign="top" class="required">
-    <td align="right"><?php  print_string("instructions", "auth") ?>:</td>
-    <td>
-    <textarea name="auth_instructions" cols="30" rows="10" wrap="virtual"><?php  p($config->auth_instructions) ?></textarea> 
-    </td>
-    <td>
-
-    <?php  print_string("authinstructions","auth") ?>
-    <?php  helpbutton("text", get_string("helptext")) ?>
-    </td>
-</tr>
+global $user_fields;
+print_auth_lock_options('ldap', $user_fields, $help, true, true); 
 
+?>
 
+</table>
diff --git a/auth/ldap/lib.php b/auth/ldap/lib.php
deleted file mode 100644 (file)
index 3d1e72e..0000000
+++ /dev/null
@@ -1,1505 +0,0 @@
-<?PHP  
-/**
- *
- * @author Petri Asikainen
- * @version $Id$
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package moodleauth
- * LDAPA-authentication functions
- *
- * 30.09.2004 Removed outdated documentation
- * 24.09.2004 Lot of changes:
- *           -Added usertype configuration, this removes need for separate obejcclass and attributename configuration
- *            Overriding values is still supported
- *          
- * 21.09.2004 Added support for multiple ldap-servers.
- *          Theres no nedd to use auth_ldap_bind,
- *          Anymore auth_ldap_connect does this for you
- * 19.09.2004 Lot of changes are coming from Martin Langhoff
- *          Current code is working but can change a lot. Be warned...
- * 15.08.2004 Added support for user syncronization
- * 24.02.2003 Added support for coursecreators
- * 20.02.2003 Added support for user creation
- * 12.10.2002 Reformatted source for consistency
- * 03.10.2002 First version to CVS
- * 29.09.2002 Clean up and splitted code to functions v. 0.02
- * 29.09.2002 LDAP authentication functions v. 0.01
- */
-
-/**
- * authenticates user againt external userdatabase
- *
- * Returns true if the username and password work
- * and false if they don't
- *
- * @param string  $username
- * @param string  $password
- *
-*/
-
-// LDAP functions are reused by other auth libs
-if (!defined('AUTH_LDAP_NAME')) {
-    define('AUTH_LDAP_NAME', 'ldap');
-}
-
-function auth_user_login ($username, $password) {
-
-    global $CFG;
-
-    if (!$username or !$password) {    // Don't allow blank usernames or passwords
-        return false;
-    }
-    // CAS-supplied auth tokens override LDAP auth
-    if ($CFG->auth == "cas" && !empty($CFG->cas_enabled)) {
-        return cas_ldap_auth_user_login($username, $password);
-    }
-
-    $ldapconnection = auth_ldap_connect();
-
-    if ($ldapconnection) {
-        $ldap_user_dn = auth_ldap_find_userdn($ldapconnection, $username);
-      
-        //if ldap_user_dn is empty, user does not exist
-        if(!$ldap_user_dn){
-            ldap_close($ldapconnection);
-            return false;
-        }
-
-        // Try to bind with current username and password
-        $ldap_login = @ldap_bind($ldapconnection, $ldap_user_dn, stripslashes($password));
-        ldap_close($ldapconnection);
-        if ($ldap_login) {
-            return true;
-        }
-    } else {
-        @ldap_close($ldapconnection);
-        error("LDAP-module cannot connect to server: $CFG->ldap_host_url");
-    }
-    return false;
-}
-
-/**
- * reads userinformation from ldap and return it in array()
- *
- * Read user information from external database and returns it as array().
- * Function should return all information available. If you are saving
- * this information to moodle user-table you should honor syncronization flags
- *
- * @param string $username username
- * @return array
- */
-function auth_get_userinfo($username){
-    global $CFG;
-    $ldapconnection=auth_ldap_connect();
-    $config = (array)$CFG;
-    $attrmap = auth_ldap_attributes();
-   
-    $result = array();
-    $search_attribs = array();
-  
-    foreach ($attrmap as $key=>$values) {
-        if (!is_array($values)) {
-            $values = array($values);
-        }
-        foreach ($values as $value) {
-            if (!in_array($value, $search_attribs)) {
-                array_push($search_attribs, $value);
-            }    
-        }
-    }
-
-    $user_dn = auth_ldap_find_userdn($ldapconnection, $username);
-
-    if (empty($CFG->ldap_objectclass)) {        // Can't send empty filter
-        $CFG->ldap_objectclass="objectClass=*";
-    }
-  
-    $user_info_result = ldap_read($ldapconnection,$user_dn,$CFG->ldap_objectclass, $search_attribs);
-
-    if ($user_info_result) {
-        $user_entry = ldap_get_entries($ldapconnection, $user_info_result);
-        foreach ($attrmap as $key=>$values){
-            if (!is_array($values)) {
-                $values = array($values);
-            }
-            $ldapval = NULL;
-            foreach ($values as $value) {
-                if(is_array($user_entry[0][strtolower($value)])) {
-                    // TODO: fix encoding conversion
-                    $newval = addslashes(stripslashes($user_entry[0][strtolower($value)][0]));
-                }
-                else {
-                    // TODO: fix encoding conversion
-                    $newval = addslashes(stripslashes($user_entry[0][strtolower($value)]));
-                }
-                if (!empty($newval)) { // favour ldap entries that are set
-                    $ldapval = $newval;
-                } 
-            }
-            if (!is_null($ldapval)) {
-                $result[$key] = $ldapval;
-            }
-        }
-    }
-
-    @ldap_close($ldapconnection);
-    
-    return $result;
-}
-
-/**
- * reads userinformation from ldap and return it in an object
- *
- * @param string $username username
- * @return array
- */
-function auth_get_userinfo_asobj($username){
-    $user_array = truncate_userinfo(auth_get_userinfo($username));
-    $user = new object;
-    foreach($user_array as $key=>$value){
-        $user->{$key} = $value;
-    }
-    return $user;
-}
-
-/**
- * returns all usernames from external database
- *
- * auth_get_userlist returns all usernames from external database
- *
- * @return array 
- */
-function auth_get_userlist () {
-    global $CFG;
-    auth_ldap_init();
-    return auth_ldap_get_userlist("($CFG->ldap_user_attribute=*)");
-}
-/**
- * checks if user exists on external db
- */
-function auth_user_exists ($username) {
-   global $CFG; 
-   auth_ldap_init();
-   //returns true if given usernname exist on ldap
-   $users = auth_ldap_get_userlist("($CFG->ldap_user_attribute=$username)");
-   return count($users); 
-}
-
-/**
- * creates new user on external database
- *
- * auth_user_create() creates new user on external database
- * By using information in userobject
- * Use auth_user_exists to prevent dublicate usernames
- *
- * @param mixed $userobject  Moodle userobject
- * @param mixed $plainpass   Plaintext password
- */
-function auth_user_create ($userobject,$plainpass) {
-    global $CFG;
-    $ldapconnection = auth_ldap_connect();
-    $attrmap = auth_ldap_attributes();
-    
-    $newuser = array();
-     
-    foreach ($attrmap as $key=>$values){
-        if (!is_array($values)) {
-            $values = array($values);
-        }
-        foreach ($values as $value) {
-            if(!empty($userobject->$key) ){
-                $newuser[$value]= $userobject->$key;
-            }
-        }
-    }
-    
-    //Following sets all mandatory and other forced attribute values
-    //User should be creted as login disabled untill email confirmation is processed
-    //Feel free to add your user type and send patches to paca@sci.fi to add them 
-    //Moodle distribution
-
-    switch ($CFG->ldap_user_type)  {
-        case 'edir':
-            $newuser['objectClass']= array("inetOrgPerson","organizationalPerson","person","top");
-            $newuser['uniqueId']= $userobject->username;
-            $newuser['logindisabled']="TRUE";
-            $newuser['userpassword']=$plainpass;
-            break;
-        default:
-           error('auth: ldap auth_user_create() does not support selected usertype:"'.$CFG->ldap_user_type.'" (..yet)');
-    }
-    $uadd = ldap_add($ldapconnection, $CFG->ldap_user_attribute."=$userobject->username,".$CFG->ldap_create_context, $newuser);
-
-    ldap_close($ldapconnection);
-    return $uadd;
-    
-}
-
-/*/
- * 
- * auth_get_users() returns userobjects from external database
- *
- * Function returns users from external databe as Moodle userobjects
- * If filter is not present it should return ALL users in external database
- * 
- * @param mixed $filter substring of username
- * @returns array of userobjects 
- */
-function auth_get_users($filter='*', $dontlistcreated=false) {
-    global $CFG;
-
-    $ldapconnection = auth_ldap_connect();
-    $fresult = array();
-
-    if ($filter=="*") {
-       $filter = "(&(".$CFG->ldap_user_attribute."=*)(".$CFG->ldap_objectclass."))";
-    }
-
-    $contexts = explode(";",$CFG->ldap_contexts);
-    if (!empty($CFG->ldap_create_context) and empty($dontlistcreated)){
-          array_push($contexts, $CFG->ldap_create_context);
-    }
-
-    $attrmap = auth_ldap_attributes();
-   
-    $search_attribs = array();
-  
-    foreach ($attrmap as $key=>$values) {
-        if (!is_array($values)) {
-            $values = array($values);
-        }
-        foreach ($values as $value) {
-            if (!in_array($value, $search_attribs)) {
-                array_push($search_attribs, $value);
-            }   
-        } 
-    }
-
-
-    foreach ($contexts as $context) {
-        
-        $context = trim($context);
-        if (empty($context)) {
-            continue;
-        }
-
-        if ($CFG->ldap_search_sub) {
-            //use ldap_search to find first user from subtree
-            $ldap_result = ldap_search($ldapconnection, $context,
-                                       $filter,
-                                       $search_attribs);
-        } else {
-            //search only in this context
-            $ldap_result = ldap_list($ldapconnection, $context,
-                                     $filter,
-                                     $search_attribs);
-        }
-
-        $users = auth_ldap_get_entries($ldapconnection, $ldap_result);
-
-        //add found users to list
-        foreach ($users as $ldapuser=>$attribs) {
-            $user = new object();
-            foreach ($attrmap as $key=>$value){
-                if(isset($users[$ldapuser][$value][0])){
-                    $user->$key=$users[$ldapuser][$value][0];
-                }
-            }    
-            //quick way to get around binarystrings
-            $user->guid=bin2hex($user->guid);
-            //add authentication source stamp 
-            $user->auth = AUTH_LDAP_NAME;
-            $fresult[$user->username]=$user;
-
-        }
-    }
-   
-    return $fresult;
-}
-
-/**
- * return number of days to user password expires
- *
- * If userpassword does not expire it should return 0. If password is already expired
- * it should return negative value.
- *
- * @param mixed $username username
- * @return integer
- */
-function auth_password_expire($username) {
-    global $CFG ;
-    $result = false;
-    
-    $ldapconnection = auth_ldap_connect();
-    $user_dn = auth_ldap_find_userdn($ldapconnection, $username);
-    $search_attribs = array($CFG->ldap_expireattr);
-    $sr = ldap_read($ldapconnection, $user_dn, 'objectclass=*', $search_attribs);
-    if ($sr)  {
-        $info=auth_ldap_get_entries($ldapconnection, $sr);
-        if ( empty($info[0][strtolower($CFG->ldap_expireattr)][0])) {
-            //error_log("ldap: no expiration value".$info[0][$CFG->ldap_expireattr]);
-            // no expiration attribute, password does not expire
-            $result = 0;
-        } else {
-            $now = time();
-            $expiretime = auth_ldap_expirationtime2unix($info[0][strtolower($CFG->ldap_expireattr)][0]);
-            if ($expiretime > $now) {
-                $result = ceil(($expiretime - $now) / DAYSECS);
-            } else {
-                $result = floor(($expiretime - $now) / DAYSECS);
-            }    
-        }
-    } else {    
-        error_log("ldap: auth_password_expire did't find expiration time!.");
-    }    
-
-    //error_log("ldap: auth_password_expire user $user_dn expires in $result days!");
-    return $result;
-}
-
-/**
- * syncronizes user fron external db to moodle user table
- *
- * Sync shouid be done by using idnumber attribute, not username.
- * You need to pass firstsync parameter to function to fill in
- * idnumbers if they dont exists in moodle user table.
- * 
- * Syncing users removes (disables) users that dont exists anymore in external db.
- * Creates new users and updates coursecreator status of users. 
- * 
- * @param mixed $firstsync  Optional: set to true to fill idnumber fields if not filled yet
- */
-function auth_sync_users ($bulk_insert_records = 1000, $do_updates=1) {
-//Syncronizes userdb with ldap
-//This will add, rename 
-/// OPTIONAL PARAMETERS
-/// $bulk_insert_records = 1 // will insert $bulkinsert_records per insert statement
-///                         valid only with $unsafe. increase to a couple thousand for
-///                         blinding fast inserts -- but test it: you may hit mysqld's 
-///                         max_allowed_packet limit.
-/// $do_updates = 1 // will do pull in data updates from ldap if relevant
-
-
-    global $CFG ;
-    $pcfg = get_config('auth/ldap');
-
-    // configure a temp table 
-    print "Configuring temp table\n";    
-    if(strtolower($CFG->dbtype) === 'mysql'){
-        // help old mysql versions cope with large temp tables
-        execute_sql('SET SQL_BIG_TABLES=1', false); 
-        execute_sql('CREATE TEMPORARY TABLE ' . $CFG->prefix .'extuser (idnumber VARCHAR(64), PRIMARY KEY (idnumber)) TYPE=MyISAM',false); 
-    } elseif (strtolower($CFG->dbtype) === 'postgres7'){
-        $bulk_insert_records = 1; // no support for multiple sets of values
-        execute_sql('CREATE TEMPORARY TABLE '.$CFG->prefix.'extuser (idnumber VARCHAR(64), PRIMARY KEY (idnumber))',false); 
-    }
-
-        
-    print "connecting to ldap\n";
-    $ldapconnection = auth_ldap_connect();
-    if (!$ldapconnection) {
-        @ldap_close($ldapconnection);
-        notify("LDAP-module cannot connect to server: $CFG->ldap_host_url");
-        return false;
-    }
-
-    ////
-    //// get user's list from ldap to sql in a scalable fashion
-    ////
-    // prepare some data we'll need
-    if (! empty($CFG->ldap_objectclass)) {
-        $CFG->ldap_objectclass="objectClass=*";
-    }
-
-    $filter = "(&(".$CFG->ldap_user_attribute."=*)(".$CFG->ldap_objectclass."))";
-
-    $contexts = explode(";",$CFG->ldap_contexts);
-    if (!empty($CFG->ldap_create_context)){
-          array_push($contexts, $CFG->ldap_create_context);
-    }
-
-    $fresult = array();
-    $count = 0;
-    foreach ($contexts as $context) {
-        $context = trim($context);
-        if (empty($context)) {
-            continue;
-        }
-        begin_sql();
-        if ($CFG->ldap_search_sub) {
-            //use ldap_search to find first user from subtree
-            $ldap_result = ldap_search($ldapconnection, $context,
-                                       $filter,
-                                       array($CFG->ldap_user_attribute));
-        } else {
-            //search only in this context
-            $ldap_result = ldap_list($ldapconnection, $context,
-                                     $filter,
-                                     array($CFG->ldap_user_attribute));
-        }
-
-        if ($entry = ldap_first_entry($ldapconnection, $ldap_result)) {
-            do {
-                $value = ldap_get_values_len($ldapconnection, $entry,$CFG->ldap_user_attribute);
-                $value = $value[0];
-                $count++;
-                array_push($fresult, $value);
-                if(count($fresult) >= $bulk_insert_records){
-                    auth_ldap_bulk_insert($fresult);
-                    //print var_dump($fresult);
-                    $fresult=array();
-                }         
-            }
-            while ($entry = ldap_next_entry($ldapconnection, $entry));
-        }
-        
-        // insert any remaining users and release mem
-        if(count($fresult)){
-            auth_ldap_bulk_insert($fresult);
-            $fresult=array();
-        }
-        commit_sql();
-    }
-    // free mem
-    $ldap_results = 0;
-
-    /// preserve our user database
-    /// if the temp table is empty, it probably means that something went wrong, exit
-    /// so as to avoid mass deletion of users; which is hard to undo
-    $count = get_record_sql('SELECT COUNT(idnumber) AS count, 1 FROM ' . $CFG->prefix .'extuser');
-    $count = $count->{'count'};
-    if($count < 1){
-        print "Did not get any users from LDAP -- error? -- exiting\n";
-        exit;
-    }
-
-    ////
-    //// User removal
-    ////
-    // find users in DB that aren't in ldap -- to be removed!
-    // this is still not as scalable
-    $sql = 'SELECT u.id, u.username 
-            FROM ' . $CFG->prefix .'user u LEFT JOIN ' . $CFG->prefix .'extuser e 
-                    ON u.idnumber = e.idnumber 
-            WHERE u.auth=\'' . AUTH_LDAP_NAME . '\' AND u.deleted=\'0\' AND e.idnumber IS NULL';
-    //print($sql);            
-    $remove_users = get_records_sql($sql); 
-
-    if (!empty($remove_users)){
-        print "User entries to remove: ". count($remove_users) . "\n";
-
-        begin_sql();
-        foreach ($remove_users as $user) {
-            //following is copy pasted from admin/user.php
-            //maybe this should moved to function in lib/datalib.php
-            unset($updateuser);
-            $updateuser->id = $user->id;
-            $updateuser->deleted = "1";
-            //$updateuser->username = "$user->username".time();  // Remember it just in case
-            //$updateuser->email = "";               // Clear this field to free it up
-            $updateuser->timemodified = time();
-            if (update_record("user", $updateuser)) {
-                // unenrol_student($user->id);  // From all courses
-                // remove_teacher($user->id);   // From all courses
-                // remove_admin($user->id);
-                delete_records('role_assignments', 'userid', $user->id); // unassign all roles
-                notify(get_string("deletedactivity", "", fullname($user, true)) );
-            } else {
-                notify(get_string("deletednot", "", fullname($user, true)));
-            }
-            //copy pasted part ends
-        }     
-        commit_sql();
-    } 
-    $remove_users = 0; // free mem!   
-
-    ////
-    //// User Updates
-    //// (time-consuming, optional)
-    ////
-    if ($do_updates) {
-        // narrow down what fields we need to update
-        $all_keys = array_keys(get_object_vars($pcfg));
-        $updatekeys = array();
-        foreach ($all_keys as $key) {
-            if (preg_match('/^field_updatelocal_(.+)$/',$key, $match)) {
-                // if we have a field to update it from
-                // and it must be updated 'onlogin' we 
-                // update it on cron
-                if ( !empty($pcfg->{'field_map_'.$match[1]})
-                     && $pcfg->{$match[0]} === 'onlogin') { 
-                    array_push($updatekeys, $match[1]); // the actual key name
-                }
-            }
-        }
-        // print_r($all_keys); print_r($updatekeys);
-        unset($all_keys); unset($key);
-        
-    }
-    if ( $do_updates && !(empty($updatekeys)) ) { // run updates only if relevant
-        $users = get_records_sql('SELECT u.username, u.id FROM ' . $CFG->prefix . 'user  u WHERE u.deleted=0 and u.auth=\'' . AUTH_LDAP_NAME . '\'' );
-        if (!empty($users)) {
-            print "User entries to update: ". count($users). "\n";
-            
-            $sitecontext = get_context_instance(CONTEXT_SYSTEM);
-
-            if ($creatorroles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
-
-                $creatorrole = array_shift($creatorroles);      // We can only use one, let's use the first one
-
-                begin_sql();
-                $xcount=0; $maxxcount=100;
-                foreach ($users as $user) { 
-                    echo "updating user $user->username \n";
-                    auth_ldap_update_user_record($user->username, $updatekeys);
-
-                    // update course creators
-                    if (!empty($CFG->ldap_creators) && !empty($CFG->ldap_memberattribute) ) {
-                        if (auth_iscreator($user->username)) {   // Following calls will not create duplicates
-                            role_assign($creatorrole->id, $user->id, 0, $sitecontext->id, 0, 0, 0, 'ldap');
-                            $xcount++;
-                        } else {
-                            role_unassign($creatorrole->id, $user->id, 0, $sitecontext->id);
-                            $xcount++;
-                        }
-                    }
-
-                    if ($xcount++ > $maxxcount) {
-                        commit_sql();
-                        begin_sql(); 
-                        $xcount=0;
-                    }
-                }
-                commit_sql();
-                unset($users); // free mem
-            }
-        }
-    } // end do updates
-    
-    ////
-    //// User Additions
-    ////
-    // find users missing in DB that are in LDAP
-    // note that get_records_sql wants at least 2 fields returned,
-    // and gives me a nifty object I don't want.
-    $sql = 'SELECT e.idnumber,1 
-            FROM ' . $CFG->prefix .'extuser e  LEFT JOIN ' . $CFG->prefix .'user u
-                    ON e.idnumber = u.idnumber 
-            WHERE  u.id IS NULL OR (u.id IS NOT NULL AND u.deleted=1)';
-    $add_users = get_records_sql($sql); // get rid of the fat        
-    
-    if(!empty($add_users)){
-        print "User entries to add: ". count($add_users). "\n";
-
-        if ($creatorroles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
-            $creatorrole = array_shift($roles);      // We can only use one, let's use the first one
-        }
-
-        begin_sql();
-        foreach($add_users as $user){
-            $user = auth_get_userinfo_asobj($user->idnumber);
-            //print $user->username . "\n";
-            
-            // prep a few params
-            $user->modified  = time();
-            $user->confirmed = 1;
-            $user->auth      = AUTH_LDAP_NAME;
-            
-            // insert it
-            $old_debug=$CFG->debug; 
-            $CFG->debug=10;
-            
-            // maybe the user has been deleted before
-            if ($old_user = get_record('user', 'idnumber', $user->idnumber, 'deleted', 1)) {
-                $user->id = $old_user->id;
-                set_field('user', 'deleted', 0, 'idnumber', $user->idnumber);
-                echo "Revived user $user->username with idnumber $user->idnumber id $user->id\n";
-            } elseif ($id=insert_record ('user',$user)) { // it is truly a new user
-                echo "inserted user $user->username with idnumber $user->idnumber id $id\n";
-                $user->id = $id;
-            } else {
-                echo "error inserting user $user->username with idnumber $user->idnumber \n";
-            }
-            $CFG->debug=$old_debug;
-            $userobj = auth_ldap_update_user_record($user->username);
-            if(isset($CFG->{'auth_ldap_forcechangepassword'}) && $CFG->{'auth_ldap_forcechangepassword'}){
-                set_user_preference('auth_forcepasswordchange', 1, $userobj->id);
-            }
-            
-            if (isset($creatorrole->id) &&  !empty($CFG->ldap_creators) && !empty($CFG->ldap_memberattribute) ) {
-                if (auth_iscreator($user->username)) {
-                    if (user_has_role_assignment($user->id, $creatorrole->id, $sitecontext->id)) {
-                        role_unassign($creatorrole->id, $user->id, 0, $sitecontext->id);
-                    } else {
-                        role_assign($creatorrole->id, $user->id, 0, $sitecontext->id, 0, 0, 0, 'ldap');
-                    }
-                }
-            }
-        }
-        commit_sql();
-        unset($add_users); // free mem
-    }
-    return true;
-}
-
-function auth_ldap_update_user_record($username, $updatekeys=false) {
-/// will update a local user record from an external source. 
-/// is a lighter version of the one in moodlelib -- won't do 
-/// expensive ops such as enrolment
-///
-/// If you don't pass $updatekeys, there is a performance hit and 
-/// values removed from LDAP won't be removed from moodle. 
-
-    global $CFG;
-
-    $pcfg = get_config('auth/ldap');
-
-    //just in case check text case
-    $username = trim(moodle_strtolower($username));
-    
-    // get the current user record
-    $user = get_record('user', 'username', $username);
-    if (empty($user)) { // trouble
-        error_log("Cannot update non-existent user: $username");
-        die;
-    }
-
-    if (function_exists('auth_get_userinfo')) {
-        if ($newinfo = auth_get_userinfo($username)) {
-            $newinfo = truncate_userinfo($newinfo);
-            
-            if (empty($updatekeys)) { // all keys? this does not support removing values
-                $updatekeys = array_keys($newinfo);
-            }
-            
-            foreach ($updatekeys as $key){
-                unset($value);
-                if (isset($newinfo[$key])) {
-                    $value = $newinfo[$key];
-                    $value = addslashes(stripslashes($value)); // Just in case
-                } else {
-                    $value = '';
-                }
-                if (!empty($pcfg->{'field_updatelocal_' . $key})) { 
-                       if ($user->{$key} != $value) { // only update if it's changed
-                           set_field('user', $key, $value, 'username', $username);
-                       }
-                }
-            }
-        }
-    }
-    return get_record_select("user", "username = '$username' AND deleted <> '1'");
-}
-
-function auth_ldap_bulk_insert($users){
-// bulk insert in SQL's temp table
-// $users is an array of usernames
-    global $CFG;
-    
-    // bulk insert -- superfast with $bulk_insert_records
-    $sql = 'INSERT INTO '.$CFG->prefix.'extuser (idnumber) VALUES ';
-    // make those values safe
-    $users = array_map('addslashes', $users);
-    // join and quote the whole lot
-    $sql = $sql . '(\'' . join('\'),(\'', $users) . '\')';
-    print "+ " . count($users) . " users\n";
-    execute_sql($sql, false); 
-
-}
-
-
-/*
- * auth_user_activate activates user in external db.
- *
- * Activates (enables) user in external db so user can login to external db
- *
- * @param mixed $username    username
- * @return boolen result
- */
-function auth_user_activate ($username) {
-    
-    global $CFG;
-    
-    $ldapconnection = auth_ldap_connect();
-
-    $userdn = auth_ldap_find_userdn($ldapconnection, $username);
-    switch ($CFG->ldap_user_type)  {
-        case 'edir':
-            $newinfo['loginDisabled']="FALSE";
-            break;
-        default:
-            error ('auth: ldap auth_user_activate() does not support selected usertype:"'.$CFG->ldap_user_type.'" (..yet)');    
-    } 
-    $result = ldap_modify($ldapconnection, $userdn, $newinfo);
-    ldap_close($ldapconnection);
-    return $result;
-}
-
-/*
- * auth_user_disables disables user in external db.
- *
- * Disables user in external db so user can't login to external db
- *
- * @param mixed $username    username
- * @return boolean result
- */
-function auth_user_disable ($username) {
-    global $CFG;
-
-    $ldapconnection = auth_ldap_connect();
-
-    $userdn = auth_ldap_find_userdn($ldapconnection, $username);
-    switch ($CFG->ldap_user_type)  {
-        case 'edir':
-            $newinfo['loginDisabled']="TRUE";
-            break;
-        default:
-            error ('auth: ldap auth_user_disable() does not support selected usertype (..yet)');    
-    }    
-    $result = ldap_modify($ldapconnection, $userdn, $newinfo);
-    ldap_close($ldapconnection);
-    return $result;
-}
-
-/*
- * auth_iscreator returns true if user should be coursecreator
- *
- * auth_iscreator returns true if user should be coursecreator
- *
- * @param mixed $username    username
- * @return boolean result
- */
-function auth_iscreator($username=0) {
-///if user is member of creator group return true
-    global $USER , $CFG; 
-    auth_ldap_init();
-
-    if (! $username) {
-        $username=$USER->username;
-    }
-   
-    if ((! $CFG->ldap_creators) OR (! $CFG->ldap_memberattribute)) {
-        return null;
-    } 
-
-    return auth_ldap_isgroupmember($username, $CFG->ldap_creators);
-}
-
-/* 
- * auth_user_update saves userinformation from moodle to external db
- *
- * Called when the user record is updated.
- * Modifies user in external database. It takes olduser (before changes) and newuser (after changes) 
- * conpares information saved modified information to external db.
- *
- * @param mixed $olduser     Userobject before modifications
- * @param mixed $newuser     Userobject new modified userobject
- * @return boolean result
- *
- */
-function auth_user_update($olduser, $newuser) {
-
-    global $USER , $CFG;
-
-    $pcfg = get_config('auth/ldap');
-    
-    $ldapconnection = auth_ldap_connect();
-    
-    $result = array();
-    $search_attribs = array();
-
-    $attrmap = auth_ldap_attributes();  
-    foreach ($attrmap as $key=>$values) {
-        if (!is_array($values)) {
-            $values = array($values);
-        }
-        foreach ($values as $value) {
-            if (!in_array($value, $search_attribs)) {
-                array_push($search_attribs, $value);
-            }
-        }    
-    }
-
-    $user_dn = auth_ldap_find_userdn($ldapconnection, $olduser->username);
-
-    $user_info_result = ldap_read($ldapconnection,$user_dn,$CFG->ldap_objectclass, $search_attribs);
-
-    if ($user_info_result){
-
-        $user_entry = auth_ldap_get_entries($ldapconnection, $user_info_result);
-        if (count($user_entry) > 1) {
-            trigger_error("ldap: Strange! More than one user record found in ldap. Only using the first one.");
-        }
-        $user_entry = $user_entry[0];
-
-        //error_log(var_export($user_entry) . 'fpp' );
-        
-        foreach ($attrmap as $key=>$ldapkeys){
-
-            // only process if the moodle field ($key) has changed and we
-            // are set to update LDAP with it
-            if ($olduser->$key !== $newuser->$key &&
-                !empty($pcfg->{'field_updateremote_'. $key})) {
-
-                // for ldap values that could be in more than one 
-                // ldap key, we will do our best to match 
-                // where they came from
-                $ambiguous = true;
-                $changed   = false;
-                if (!is_array($ldapkeys)) {
-                    $ldapkeys = array($ldapkeys);
-                }
-                if (count($ldapkeys) < 2) {
-                    $ambiguous = false;
-                }
-                 
-                foreach ($ldapkeys as $ldapkey) {
-                    $ldapkey   = strtolower($ldapkey);
-                    $ldapvalue = $user_entry[$ldapkey][0];
-                    if (!$ambiguous) {
-                        // skip update if the values already match
-                        if( !($newuser->$key === $ldapvalue) ){
-                            ldap_modify($ldapconnection, $user_dn, array($ldapkey => $newuser->$key));
-                        } else { 
-                    error_log("Skip updating field $key for entry $user_dn: it seems to be already same on LDAP. " . 
-                                      "  old moodle value: '" . $olduser->$key . 
-                                      "' new value '" . $newuser->$key . 
-                                      "' current value in ldap entry " . $ldapvalue);
-                        }
-                    } else { // ambiguous
-                        // value empty before in Moodle (and LDAP) - use 1st ldap candidate field
-                        // no need to guess
-                        if (empty($olduser->$key)) { // value empty before - use 1st ldap candidate
-                            if(ldap_modify($ldapconnection, $user_dn, array($ldapkey => $newuser->$key))){
-                                $changed=true;
-                                last;
-                            } else {
-                                error ('Error updating LDAP record. Error code: ' 
-                                  . ldap_errno($ldapconnection) . '; Error string : '
-                                  . ldap_err2str(ldap_errno($ldapconnection)));                                
-                            }
-                        }
-
-                        // we found which ldap key to update!                            
-                        if ( !empty($ldapvalue) && $olduser->$key === $ldapvalue ) {
-                            // error_log("Matched: ". $olduser->$key . " === " . $ldapvalue);
-                            if(ldap_modify($ldapconnection, $user_dn, array($ldapkey => $newuser->$key))){
-                                $changed=true;
-                                last;
-                            } else {
-                                error ('Error updating LDAP record. Error code: ' 
-                                  . ldap_errno($ldapconnection) . '; Error string : '
-                                  . ldap_err2str(ldap_errno($ldapconnection))); 
-                            }
-                        }
-                    }
-                }
-                
-                if ($ambiguous AND !$changed) {
-                    error_log("Failed to update LDAP with ambiguous field $key". 
-                              "  old moodle value: '" . $olduser->$key . 
-                              "' new value '" . $newuser->$key );
-                }
-            }
-        }
-        
-
-    } else {
-        error_log("ERROR:No user found in LDAP");
-        @ldap_close($ldapconnection);
-        return false;
-    }
-
-    @ldap_close($ldapconnection);
-    
-    return true;
-
-}
-
-/*
- * changes userpassword in external db
- *
- * called when the user password is updated.
- * changes userpassword in external db
- *
- * @param mixed $username    Username
- * @param mixed $newpassword Plaintext password
- * @param mixed $oldpassword Plaintext old password to bind ldap with
- * @return boolean result
- *
- */
-function auth_user_update_password($username, $newpassword) {
-/// called when the user password is updated -- it assumes it is called by an admin
-/// or that you've otherwise checked the user's credentials
-/// IMPORTANT: $newpassword must be cleartext, not crypted/md5'ed
-
-    global $CFG, $USER;
-    $result = false;
-     
-    $ldapconnection = auth_ldap_connect();
-
-    $user_dn = auth_ldap_find_userdn($ldapconnection, $username);
-    
-    if(!$user_dn){
-        error_log('LDAP Error in auth_user_update_password(). No DN for: ' . $username); 
-        return false;
-    }
-
-    switch ($CFG->ldap_user_type) {
-        case 'edir':
-            //Change password
-            $result = ldap_modify($ldapconnection, $user_dn, array('userPassword' => $newpassword));
-            if(!$result){
-                error_log('LDAP Error in auth_user_update_password(). Error code: '
-                          . ldap_errno($ldapconnection) . '; Error string : '
-                          . ldap_err2str(ldap_errno($ldapconnection)));
-            }
-            //Update password expiration time, grace logins count
-            $search_attribs = array($CFG->ldap_expireattr, 'passwordExpirationInterval','loginGraceLimit' );
-            $sr = ldap_read($ldapconnection, $user_dn, 'objectclass=*', $search_attribs);
-            if ($sr)  {
-                $info=auth_ldap_get_entries($ldapconnection, $sr);
-                $newattrs = array();
-                if (!empty($info[0][$CFG->ldap_expireattr][0])) {
-                    //Set expiration time only if passwordExpirationInterval is defined
-                    if (!empty($info[0]['passwordExpirationInterval'][0])) {
-                       $expirationtime = time() + $info[0]['passwordExpirationInterval'][0]; 
-                       $ldapexpirationtime = auth_ldap_unix2expirationtime($expirationtime);
-                       $newattrs['passwordExpirationTime'] = $ldapexpirationtime;
-                    }    
-
-                    //set gracelogin count
-                    if (!empty($info[0]['loginGraceLimit'][0])) {
-                       $newattrs['loginGraceRemaining']= $info[0]['loginGraceLimit'][0]; 
-                    }
-    
-                    //Store attribute changes to ldap
-                    $result = ldap_modify($ldapconnection, $user_dn, $newattrs);
-                    if(!$result){
-                       error_log('LDAP Error in auth_user_update_password() when modifying expirationtime and/or gracelogins. Error code: '
-                                 . ldap_errno($ldapconnection) . '; Error string : '
-                                 . ldap_err2str(ldap_errno($ldapconnection)));
-                    }
-                }
-            } else {
-                error_log('LDAP Error in auth_user_update_password() when reading password expiration time. Error code: '
-                          . ldap_errno($ldapconnection) . '; Error string : '
-                          . ldap_err2str(ldap_errno($ldapconnection)));
-            }    
-            break;
-        default:
-            $usedconnection = &$ldapconnection;
-            // send ldap the password in cleartext, it will md5 it itself
-            $result = ldap_modify($ldapconnection, $user_dn, array('userPassword' => $newpassword));
-    if(!$result){
-        error_log('LDAP Error in auth_user_update_password(). Error code: ' 
-                  . ldap_errno($ldapconnection) . '; Error string : '
-                  . ldap_err2str(ldap_errno($ldapconnection)));
-    }
-    
-    }
-
-        
-    @ldap_close($ldapconnection);
-
-    return $result;
-}
-
-//PRIVATE FUNCTIONS starts
-//private functions are named as auth_ldap*
-
-/**
- * returns predefined usertypes
- *
- * @return array of predefined usertypes
- */
-
-function auth_ldap_suppported_usertypes (){
-// returns array of supported usertypes (schemas)
-// If you like to add our own please name and describe it here
-// And then add case clauses in relevant places in functions
-// iauth_ldap_init, auth_user_create, auth_check_expire, auth_check_grace
-    $types['edir']='Novell Edirectory';
-    $types['rfc2307']='posixAccount (rfc2307)';
-    $types['rfc2307bis']='posixAccount (rfc2307bis)';
-    $types['samba']='sambaSamAccount (v.3.0.7)';
-    $types['ad']='MS ActiveDirectory'; 
-    return $types;
-}    
-
-   
-/**
- * initializes needed variables for ldap-module
- *
- * Uses names defined in auth_ldap_supported_usertypes.
- * $default is first defined as:
- * $default['pseudoname'] = array(
- *                      'typename1' => 'value',
- *                      'typename2' => 'value'
- *                      ....
- *                      );
- *
- * @return array of default values
- */
-
-function auth_ldap_getdefaults(){
-    $default['ldap_objectclass'] = array(
-                        'edir' => 'User',
-                        'rfc2703' => 'posixAccount',
-                        'rfc2703bis' => 'posixAccount',
-                        'samba' => 'sambaSamAccount',
-                        'ad' => 'user',
-                        'default' => '*'
-                        );
-    $default['ldap_user_attribute'] = array(
-                        'edir' => 'cn',
-                        'rfc2307' => 'uid',
-                        'rfc2307bis' => 'uid',
-                        'samba' => 'uid',
-                        'ad' => 'cn',
-                        'default' => 'cn'
-                        );
-    $default['ldap_memberattribute'] = array(
-                        'edir' => 'member',
-                        'rfc2307' => 'member',
-                        'rfc2307bis' => 'member',
-                        'samba' => 'member',
-                        'ad' => 'member', 
-                        'default' => 'member'
-                        );
-    $default['ldap_memberattribute_isdn'] = array(
-                        'edir' => '1',
-                        'rfc2307' => '0',
-                        'rfc2307bis' => '1',
-                        'samba' => '0', //is this right?
-                        'ad' => '1',
-                        'default' => '0'
-                        );
-    $default['ldap_expireattr'] = array (
-                        'edir' => 'passwordExpirationTime',
-                        'rfc2307' => 'shadowExpire',
-                        'rfc2307bis' => 'shadowExpire',
-                        'samba' => '', //No support yet
-                        'ad' => '', //No support yet
-                        'default' => ''
-                        );
-    return $default; 
-}
-
-/**
- * return binaryfields of selected usertype
- *
- *
- * @return array
- */
-
-function auth_ldap_getbinaryfields () {
-    global $CFG;
-    $binaryfields = array (
-                        'edir' => array('guid'),
-                        'rfc2703' => array(),
-                        'rfc2703bis' => array(),
-                        'samba' => array(),
-                        'ad' => array(),
-                        'default' => '*'
-                        );
-    if (!empty($CFG->ldap_user_type)) {
-        return $binaryfields[$CFG->ldap_user_type];   
-    } else {
-        return $binaryfields['default'];
-    }    
-    }
-    
-function auth_ldap_isbinary ($field) {
-    if (!isset($field)) {
-        return null ;
-    }    
-    return array_search($field, auth_ldap_getbinaryfields());
-}    
-
-/**
- * set $CFG-values for ldap_module
- * 
- * Get default configuration values with auth_ldap_getdefaults() 
- * and by using this information $CFG-> values are set
- * If $CFG->value is alredy set current value is honored.
- *
- * 
- */
-function auth_ldap_init () {
-    global $CFG;
-    $default = auth_ldap_getdefaults();
-
-    foreach ($default as $key => $value) {
-        //set defaults if overriding fields not set
-        if(empty($CFG->{$key})) {
-            if (!empty($CFG->ldap_user_type) && !empty($default[$key][$CFG->ldap_user_type])) {
-                $CFG->{$key} = $default[$key][$CFG->ldap_user_type];
-            }else {
-                //use default value if user_type not set
-                if(!empty($default[$key]['default'])){
-                    $CFG->$key = $default[$key]['default'];
-                }else {
-                    unset($CFG->$key);
-                }    
-            }
-        }
-    }   
-    //hack prefix to objectclass
-    if ('objectClass=' != substr($CFG->ldap_objectclass, 0, 12)) {
-       $CFG->ldap_objectclass = 'objectClass='.$CFG->ldap_objectclass;
-    }
-   
-    //all chages go in $CFG , no need to return value
-}
-
-/**
- * take expirationtime and return it as unixseconds
- * 
- * takes expriration timestamp as readed from ldap
- * returns it as unix seconds
- * depends on $CFG->usertype variable
- *
- * @param mixed time   Time stamp readed from ldap as it is.
- * @return timestamp
- */
-
-function auth_ldap_expirationtime2unix ($time) {
-
-    global $CFG;
-    $result = false;
-    switch ($CFG->ldap_user_type) {
-        case 'edir':
-            $yr=substr($time,0,4);
-            $mo=substr($time,4,2);
-            $dt=substr($time,6,2);
-            $hr=substr($time,8,2);
-            $min=substr($time,10,2);
-            $sec=substr($time,12,2);
-            $result = mktime($hr,$min,$sec,$mo,$dt,$yr); 
-            break;
-        case 'posix':
-            $result = $time * DAYSECS ; //The shadowExpire contains the number of DAYS between 01/01/1970 and the actual expiration date
-            break;
-        default:  
-            error('CFG->ldap_user_type not defined or function auth_ldap_expirationtime2unix does not support selected type!');
-}
-    return $result;
-}
-
-/**
- * takes unixtime and return it formated for storing in ldap
- *
- * @param integer unix time stamp
- */
-function auth_ldap_unix2expirationtime ($time) {
-    global $CFG;
-    $result = false;
-    switch ($CFG->ldap_user_type) {
-        case 'edir':
-            $result=date('YmdHis', $time).'Z';  
-            break;
-        case 'posix':
-            $result = $time ; //Already in correct format
-            break;
-        default:  
-            error('CFG->ldap_user_type not defined or function auth_ldap_unixi2expirationtime does not support selected type!');
-    }        
-    return $result;
-
-}
-
-/*
- * checks if user belong to specific group(s)
- *
- * Returns true if user belongs group in grupdns string.
- *
- * @param mixed $username    username
- * @param mixed $groupdns    string of group dn separated by ;
- *
- */
-function auth_ldap_isgroupmember ($username='', $groupdns='') {
-// Takes username and groupdn(s) , separated by ;
-// Returns true if user is member of any given groups
-
-    global $CFG ;
-    $result = false;
-    $ldapconnection = auth_ldap_connect();
-    
-    if (empty($username) OR empty($groupdns)) {
-        return $result;
-        }
-
-    if ($CFG->ldap_memberattribute_isdn) {
-        $username=auth_ldap_find_userdn($ldapconnection, $username);
-    }
-    if (! $username ) {
-        return $result;
-    }
-
-    $groups = explode(";",$groupdns);
-    
-    foreach ($groups as $group){
-        $group = trim($group);
-        if (empty($group)) {
-            continue;
-        }
-        //echo "Checking group $group for member $username\n";
-        $search = @ldap_read($ldapconnection, $group,  '('.$CFG->ldap_memberattribute.'='.$username.')', array($CFG->ldap_memberattribute));
-
-        if (!empty($search) AND ldap_count_entries($ldapconnection, $search)) {$info = auth_ldap_get_entries($ldapconnection, $search);
-        
-            if (count($info) > 0 ) {
-                // user is member of group
-                $result = true;
-                break;
-            }
-    }
-}
-
-    return $result;
-
-}
-
-/**
- * connects to ldap server
- *
- * Tries connect to specified ldap servers.
- * Returns connection result or error.
- *
- * @return connection result
- */
-function auth_ldap_connect($binddn='',$bindpwd=''){
-/// connects  and binds to ldap-server
-/// Returns connection result
-
-    global $CFG;
-    auth_ldap_init();
-
-    //Select bind password, With empty values use
-    //ldap_bind_* variables or anonymous bind if ldap_bind_* are empty
-    if ($binddn == '' AND $bindpwd == '') {
-        if (!empty($CFG->ldap_bind_dn)){
-           $binddn = $CFG->ldap_bind_dn;
-        }
-        if (!empty($CFG->ldap_bind_pw)){
-           $bindpwd = $CFG->ldap_bind_pw;
-        }
-    }
-    
-    $urls = explode(";",$CFG->ldap_host_url);
-        
-    foreach ($urls as $server){
-        $server = trim($server);
-        if (empty($server)) {
-            continue;
-        }
-
-        $connresult = ldap_connect($server);
-        //ldap_connect returns ALWAYS true
-        if (!empty($CFG->ldap_version)) {
-            ldap_set_option($connresult, LDAP_OPT_PROTOCOL_VERSION, $CFG->ldap_version);
-        }
-
-        if (!empty($binddn)){
-            //bind with search-user
-            //$debuginfo .= 'Using bind user'.$binddn.'and password:'.$bindpwd; 
-            $bindresult=ldap_bind($connresult, $binddn,$bindpwd);
-        } else {
-            //bind anonymously 
-            $bindresult=@ldap_bind($connresult);
-        }  
-       
-        if (!empty($CFG->ldap_opt_deref)) {
-            ldap_set_option($connresult, LDAP_OPT_DEREF, $CFG->ldap_opt_deref);
-        }
-
-        if ($bindresult) {
-            return $connresult;
-        }
-        
-        $debuginfo .= "<br/>Server: '$server' <br/> Connection: '$connresult'<br/> Bind result: '$bindresult'</br>";
-    }
-
-    //If any of servers are alive we have already returned connection
-    error("LDAP-module cannot connect any LDAP servers : $debuginfo");
-    return false;
-}
-
-/**
- * retuns dn of username
- *
- * Search specified contexts for username and return user dn
- * like: cn=username,ou=suborg,o=org
- *
- * @param mixed $ldapconnection  $ldapconnection result
- * @param mixed $username username
- *
- */
-
-function auth_ldap_find_userdn ($ldapconnection, $username){
-
-    global $CFG;
-
-    //default return value
-    $ldap_user_dn = FALSE;
-
-    //get all contexts and look for first matching user
-    $ldap_contexts = explode(";",$CFG->ldap_contexts);
-    
-    if (!empty($CFG->ldap_create_context)){
-      array_push($ldap_contexts, $CFG->ldap_create_context);
-    }
-  
-    foreach ($ldap_contexts as $context) {
-
-        $context = trim($context);
-        if (empty($context)) {
-            continue;
-        }
-
-        if ($CFG->ldap_search_sub){
-            //use ldap_search to find first user from subtree
-            $ldap_result = ldap_search($ldapconnection, $context, "(".$CFG->ldap_user_attribute."=".$username.")",array($CFG->ldap_user_attribute));
-
-        } else {
-            //search only in this context
-            $ldap_result = ldap_list($ldapconnection, $context, "(".$CFG->ldap_user_attribute."=".$username.")",array($CFG->ldap_user_attribute));
-        }
-        $entry = ldap_first_entry($ldapconnection,$ldap_result);
-
-        if ($entry){
-            $ldap_user_dn = ldap_get_dn($ldapconnection, $entry);
-            break ;
-        }
-    }
-
-    return $ldap_user_dn;
-}
-
-/**
- * retuns user attribute mappings between moodle and ldap
- *
- * @return array
- */
-
-function auth_ldap_attributes (){
-
-    global $CFG;
-
-    $config = (array)$CFG;
-    $fields = array("firstname", "lastname", "email", "phone1", "phone2", 
-                    "department", "address", "city", "country", "description", 
-                    "idnumber", "lang" );
-
-    $pcfg = get_config('auth/ldap');
-
-    $moodleattributes = array();
-    foreach ($fields as $field) {
-        if (!empty($pcfg->{"field_map_$field"})) {
-            $moodleattributes[$field] = $pcfg->{"field_map_$field"};
-            if (preg_match('/,/',$moodleattributes[$field])) {
-                $moodleattributes[$field] = explode(',', $moodleattributes[$field]); // split ?
-            }
-        }
-    }
-    $moodleattributes['username']=$config["ldap_user_attribute"];
-    return $moodleattributes;
-}
-
-/**
- * return all usernames from ldap
- *
- * @return array
- */
-
-function auth_ldap_get_userlist($filter="*") {
-/// returns all users from ldap servers
-    global $CFG;
-
-    $fresult = array();
-
-    $ldapconnection = auth_ldap_connect();
-
-    if ($filter=="*") {
-       $filter = "(&(".$CFG->ldap_user_attribute."=*)(".$CFG->ldap_objectclass."))";
-    }
-
-    $contexts = explode(";",$CFG->ldap_contexts);
-    if (!empty($CFG->ldap_create_context)){
-          array_push($contexts, $CFG->ldap_create_context);
-    }
-
-    foreach ($contexts as $context) {
-
-        $context = trim($context);
-        if (empty($context)) {
-            continue;
-        }
-
-        if ($CFG->ldap_search_sub) {
-            //use ldap_search to find first user from subtree
-            $ldap_result = ldap_search($ldapconnection, $context,$filter,array($CFG->ldap_user_attribute));
-        } else {
-            //search only in this context
-            $ldap_result = ldap_list($ldapconnection, $context,
-                                     $filter,
-                                     array($CFG->ldap_user_attribute));
-        }
-        
-        $users = auth_ldap_get_entries($ldapconnection, $ldap_result);
-
-        //add found users to list
-        for ($i=0;$i<count($users);$i++) {
-            array_push($fresult, ($users[$i][$CFG->ldap_user_attribute][0]) );
-        }
-    }
-   
-    return $fresult;
-}
-
-/**
- * return entries from ldap
- *
- * Returns values like ldap_get_entries but is
- * binary compatible and return all attributes as array
- *
- * @return array ldap-entries
- */
-   
-function auth_ldap_get_entries($conn, $searchresult){
-//Returns values like ldap_get_entries but is
-//binary compatible
-    $i=0;
-    $fresult=array();
-    $entry = ldap_first_entry($conn, $searchresult);
-    do {
-        $attributes = @ldap_get_attributes($conn, $entry);
-        for($j=0; $j<$attributes['count']; $j++) {
-            $values = ldap_get_values_len($conn, $entry,$attributes[$j]);
-            if (is_array($values)) {
-            $fresult[$i][$attributes[$j]] = $values;
-            } else {
-                $fresult[$i][$attributes[$j]] = array($values);
-            }
-        }         
-        $i++;               
-    }
-    while ($entry = @ldap_next_entry($conn, $entry));
-    //were done
-    return ($fresult);
-}
-
-
-
-
-?>
diff --git a/auth/manual/auth.php b/auth/manual/auth.php
new file mode 100644 (file)
index 0000000..e6311c7
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+/**
+ * @author Martin Dougiamas
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodle multiauth
+ *
+ * Authentication Plugin: Manual Authentication
+ *
+ * Just does a simple check against the moodle database.
+ *
+ * 2006-08-28  File created.
+ */
+
+// This page cannot be called directly
+if (!isset($CFG)) exit;
+
+/**
+ * Manual authentication plugin.
+ */
+class auth_plugin_manual
+{
+    /**
+     * The configuration details for the plugin.
+     */
+    var $config;
+
+    var $canchangepassword = true;
+    var $isinternal = true;
+
+    /**
+     * Constructor.
+     */
+    function auth_plugin_manual() {
+        $this->config = get_config('auth/manual');
+    }
+
+    /**
+     * Returns true if the username and password work and false if they are
+     * wrong or don't exist.
+     *
+     * @param string $username The username
+     * @param string $password The password
+     * @returns bool Authentication success or failure.
+     */
+    function user_login ($username, $password) {
+        if ($user = get_record('user', 'username', $username)) {
+            if (validate_internal_user_password($user, $password)) {
+                return true;
+                // return AUTH_OK;
+            }
+        }
+        return false;
+        // return AUTH_FAIL;
+    }
+
+    /*
+     * Updates the user's password.
+     *
+     * called when the user password is updated.
+     *
+     * @param mixed $username    Username
+     * @param mixed $newpassword Plaintext password
+     * @return boolean result
+     *
+     */
+    function user_update_password($username, $newpassword) {
+        $user = get_complete_user_data('username', $username);
+        return update_internal_user_password($user, $newpassword);
+    }
+
+    /**
+     * Returns true if this authentication plugin is 'internal'.
+     *
+     * @returns bool
+     */
+    function is_internal() {
+        return true;
+    }
+    
+    /**
+     * Returns true if this authentication plugin can change the user's
+     * password.
+     *
+     * @returns bool
+     */
+    function can_change_password() {
+        return true;
+    }
+    
+    /**
+     * Returns the URL for changing the user's pw, or false if the default can
+     * be used.
+     *
+     * @returns bool
+     */
+    function change_password_url() {
+        return false;
+    }
+    
+    /**
+     * Prints a form for configuring this authentication plugin.
+     *
+     * This function is called from admin/auth.php, and outputs a full page with
+     * a form for configuring this plugin.
+     *
+     * @param array $page An object containing all the data for this page.
+     */
+    function config_form($config, $err) {
+        include "config.html";
+    }
+
+    /**
+     * Processes and stores configuration data for this authentication plugin.
+     */
+    function process_config($config) {
+        return true;
+    }
+        
+}
+
+?>
index 7288eb4..59e4bf9 100644 (file)
@@ -1,11 +1,11 @@
-<tr valign="top">
-    <td align="right"><?php  print_string("instructions", "auth") ?>:</td>
-    <td>
-    <textarea name="auth_instructions" cols="30" rows="10" wrap="virtual"><?php  p($config->auth_instructions) ?></textarea> 
-    </td>
-    <td>
-    <?php  print_string("authinstructions","auth") ?>
-    <?php  helpbutton("text", get_string("helptext")) ?>
-    </td>
-</tr>
-<?php print_auth_lock_options($auth, $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false); ?>
+<!-- No config needed -->
+<div align="center"><?php print_string('none'); ?></div>
+
+<table cellspacing="0" cellpadding="5" border="0" align="center">
+<?php 
+
+global $user_fields;
+print_auth_lock_options('manual', $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false);
+
+?>
+</table>
diff --git a/auth/manual/lib.php b/auth/manual/lib.php
deleted file mode 100644 (file)
index a398cb4..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php  // $Id$
-       // manual method - Just does a simple check against the database
-
-function auth_user_login ($username, $password) {
-// Returns false if the username doesn't exist yet
-// Returns true if the username and password work
-
-    if ($user = get_record('user', 'username', $username)) {
-        return validate_internal_user_password($user, $password);
-    }
-
-    return false;
-}
-
-
-?>
diff --git a/auth/nntp/auth.php b/auth/nntp/auth.php
new file mode 100644 (file)
index 0000000..a86d1cd
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+
+/**
+ * @author Martin Dougiamas
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodle multiauth
+ *
+ * Authentication Plugin: NNTP Authentication
+ *
+ * Authenticates against an NNTP server.
+ *
+ * 2006-08-31  File created.
+ */
+
+// This page cannot be called directly
+if (!isset($CFG)) exit;
+
+/**
+ * NNTP authentication plugin.
+ */
+class auth_plugin_nntp {
+
+    /**
+     * The configuration details for the plugin.
+     */
+    var $config;
+
+    /**
+     * Constructor.
+     */
+    function auth_plugin_nntp() {
+        $this->config = get_config('auth/nntp');
+    }
+
+    /**
+     * Returns true if the username and password work and false if they are
+     * wrong or don't exist.
+     *
+     * @param string $username The username
+     * @param string $password The password
+     * @returns bool Authentication success or failure.
+     */
+    function user_login ($username, $password) {
+        if (! function_exists('imap_open')) {
+            error("Cannot use NNTP authentication. The PHP IMAP module is not installed.");
+        }
+        
+        global $CFG;
+        
+        // try each multiple host
+        $hosts = split(';', $this->config->host);
+        foreach ($hosts as $host) {
+            $host = '{' . trim($host) . ':' . $this->config->port . '/nntp}';
+
+            error_reporting(0);
+            $connection = imap_open($host, $username, $password, OP_HALFOPEN);
+            error_reporting($CFG->debug);   
+
+            if ($connection) {
+                imap_close($connection);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if this authentication plugin is 'internal'.
+     *
+     * @returns bool
+     */
+    function is_internal() {
+        return false;
+    }
+
+    /**
+     * Returns true if this authentication plugin can change the user's
+     * password.
+     *
+     * @returns bool
+     */
+    function can_change_password() {
+        return false;
+    }
+    
+    /**
+     * Prints a form for configuring this authentication plugin.
+     *
+     * This function is called from admin/auth.php, and outputs a full page with
+     * a form for configuring this plugin.
+     *
+     * @param array $page An object containing all the data for this page.
+     */
+    function config_form($config, $err) {
+        include "config.html";
+    }
+
+    /**
+     * Processes and stores configuration data for this authentication plugin.
+     */
+    function process_config($config) {
+        // set to defaults if undefined
+        if (!isset ($config->host)) {
+            $config->host = '127.0.0.1';
+        }
+        if (!isset ($config->port)) {
+            $config->port = '119';
+        }
+        if (!isset($config->changepasswordurl)) {
+            $config->changepasswordurl = '';
+        }
+
+        // save settings
+        set_config('host', $config->host, 'auth/nntp');
+        set_config('port', $config->port, 'auth/nntp');
+        set_config('changepasswordurl', $config->changepasswordurl, 'auth/nntp');
+
+        return true;
+    }
+
+}
+
+?>
index f8216d0..abcd86b 100644 (file)
@@ -1,43 +1,75 @@
 <?php
-    if (!isset($config->auth_nntphost)) {
-        $config->auth_nntphost = "127.0.0.1";
-    }
-    if (!isset($config->auth_nntpport)) {
-        $config->auth_nntpport = "119";
-    }
+
+// set to defaults if undefined
+if (!isset($config->host)) {
+    $config->host = "127.0.0.1";
+}
+if (!isset($config->port)) {
+    $config->port = "119";
+}
+if (!isset($config->changepasswordurl)) {
+    $config->changepasswordurl = '';
+}
+
 ?>
+<table cellspacing="0" cellpadding="5" border="0" align="center">
 
 <tr valign="top" class="required">
-    <td align="right">auth_nntphost:</td>
+    <td align="right"> host: </td>
     <td>
-        <input name="auth_nntphost" type="text" size="30" value="<?php echo $config->auth_nntphost?>" />
-    <?php  if (isset($err["auth_nntphost"]))  formerr($err["auth_nntphost"]); ?>
+        <input name="host" type="text" size="30" value="<?php echo $config->host ?>" />
+        <?php
+        
+        if (isset($err["host"])) {
+            formerr($err["host"]);
+        }
+        
+        ?>
     </td>
     <td>
-    <?php  print_string("auth_nntphost","auth") ?>
-    <?php  print_string("auth_multiplehosts","auth") ?>
+        <?php
+       
+        print_string("auth_nntphost", "auth");
+        print_string("auth_multiplehosts", "auth");
+            
+        ?>
     </td>
 </tr>
 
 <tr valign="top" class="required">
-    <td align="right">auth_nntpport:</td>
-    <td>
-    <input name="auth_nntpport" type="text" size="6" value="<?php echo $config->auth_nntpport?>" />
-    <?php  if (isset($err["auth_nntpport"])) formerr($err["auth_nntpport"]); ?>
-    </td>
+    <td align="right"> port: </td>
     <td>
-    <?php  print_string("auth_nntpport","auth") ?>
+        <input name="port" type="text" size="6" value="<?php echo $config->port ?>" />
+        <?php
+
+        if (isset($err["port"])) {
+            formerr($err["port"]);
+        }
+        
+        ?>
     </td>
+    <td><?php print_string("auth_nntpport", "auth") ?></td>
 </tr>
 
 <tr valign="top">
-    <td align="right"><?php  print_string("instructions", "auth") ?>:</td>
-    <td>
-    <textarea name="auth_instructions" cols="30" rows="10" wrap="virtual"><?php  p($config->auth_instructions) ?></textarea> 
-    </td>
+    <td align="right"> changepasswordurl: </td>
     <td>
-    <?php  print_string("authinstructions","auth") ?>
-    <?php  helpbutton("text", get_string("helptext")) ?>
+        <input name="changepasswordurl" type="text" value="<?php echo $config->changepasswordurl ?>" />
+        <?php
+
+        if (isset($err['changepasswordurl'])) {
+            formerr($err['changepasswordurl']);
+        }
+
+        ?>
     </td>
+    <td><?php print_string('changepasswordhelp', 'auth') ?></td>
 </tr>
-<?php print_auth_lock_options($auth, $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false); ?>
\ No newline at end of file
+
+<?php 
+
+global $user_fields;
+print_auth_lock_options('nntp', $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false);
+
+?>
+</table>
diff --git a/auth/nntp/lib.php b/auth/nntp/lib.php
deleted file mode 100644 (file)
index 502d051..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php  // $Id$
-       // Authentication by looking up an NNTP server
-
-
-function auth_user_login ($username, $password) {
-// Returns true if the username and password work
-// and false if they are wrong or don't exist.
-
-    global $CFG;
-
-    $hosts = split(';', $CFG->auth_nntphost);   // Could be multiple hosts
-
-    foreach ($hosts as $host) {                 // Try each host in turn
-        $host = '{'.trim($host).":$CFG->auth_nntpport/nntp}";
-
-        error_reporting(0);
-        $connection = imap_open($host, $username, $password, OP_HALFOPEN);
-        error_reporting($CFG->debug);   
-
-        if ($connection) {
-            imap_close($connection);
-            return true;
-        }
-    }
-
-    return false;    // No match
-}
-
-
-?>
diff --git a/auth/none/auth.php b/auth/none/auth.php
new file mode 100644 (file)
index 0000000..520c832
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * @author Martin Dougiamas
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodle multiauth
+ *
+ * Authentication Plugin: No Authentication
+ *
+ * No authentication at all. This method approves everything!
+ *
+ * 2006-08-31  File created.
+ */
+
+// This page cannot be called directly
+if (!isset($CFG)) exit;
+
+/**
+ * Plugin for no authentication.
+ */
+class auth_plugin_none {
+
+    /**
+     * The configuration details for the plugin.
+     */
+    var $config;
+
+    var $canchangepassword = true;
+    var $isinternal = true;
+
+    /**
+     * Constructor.
+     */
+    function auth_plugin_none() {
+        $this->config = get_config('auth/none');
+    }
+
+    /**
+     * Returns true if the username and password work or don't exist and false
+     * if the user exists and the password is wrong.
+     *
+     * @param string $username The username
+     * @param string $password The password
+     * @returns bool Authentication success or failure.
+     */
+    function user_login ($username, $password) {
+        if ($user = get_record('user', 'username', $username)) {
+            return validate_internal_user_password($user, $password);
+        }
+        return true;
+    }
+
+    /*
+     * Updates the user's password.
+     *
+     * called when the user password is updated.
+     *
+     * @param mixed $username    Username
+     * @param mixed $newpassword Plaintext password
+     * @return boolean result
+     *
+     */
+    function user_update_password($username, $newpassword) {
+        $user = get_complete_user_data('username', $username);
+        return update_internal_user_password($user, $newpassword);
+    }
+
+    /**
+     * Returns true if this authentication plugin is 'internal'.
+     *
+     * @returns bool
+     */
+    function is_internal() {
+        return true;
+    }
+
+    /**
+     * Returns true if this authentication plugin can change the user's
+     * password.
+     *
+     * @returns bool
+     */
+    function can_change_password() {
+        return true;
+    }
+    
+    /**
+     * Returns the URL for changing the user's pw, or false if the default can
+     * be used.
+     *
+     * @returns bool
+     */
+    function change_password_url() {
+        return false;
+    }
+    
+    /**
+     * Prints a form for configuring this authentication plugin.
+     *
+     * This function is called from admin/auth.php, and outputs a full page with
+     * a form for configuring this plugin.
+     *
+     * @param array $page An object containing all the data for this page.
+     */
+    function config_form($config, $err) {
+        include "config.html";
+    }
+
+    /**
+     * Processes and stores configuration data for this authentication plugin.
+     */
+    function process_config($config) {
+        return true;
+    }
+
+}
+
+?>
index e3056db..f8e7d03 100644 (file)
@@ -1,3 +1,11 @@
 <!-- No config needed -->
 <div align="center"><?php print_string('none'); ?></div>
-<?php print_auth_lock_options($auth, $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false); ?>
\ No newline at end of file
+
+<table cellspacing="0" cellpadding="5" border="0" align="center">
+<?php 
+
+global $user_fields;
+print_auth_lock_options('none', $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false);
+
+?>
+</table>
diff --git a/auth/none/lib.php b/auth/none/lib.php
deleted file mode 100644 (file)
index f3734dc..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php  // $Id$
-       // No authentication at all.  This method approves everything!
-
-function auth_user_login ($username, $password) {
-// Returns true if the username doesn't exist yet
-// Returns true if the username and password work
-
-    if ($user = get_record('user', 'username', $username)) {
-        return validate_internal_user_password($user, $password);
-    }
-
-    return true;
-}
-
-
-
-?>
diff --git a/auth/pam/auth.php b/auth/pam/auth.php
new file mode 100644 (file)
index 0000000..037ebd6
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * @author Martin Dougiamas
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package moodle multiauth
+ *
+ * Authentication Plugin: PAM Authentication
+ *
+ * PAM (Pluggable Authentication Modules) for Moodle 
+ * 
+ * Description:
+ * Authentication by using the PHP4 PAM module:
+ * http://www.math.ohio-state.edu/~ccunning/pam_auth/
+ * 
+ * Version 0.3  2006/09/07 by Jonathan Harker (plugin class)
+ * Version 0.2: 2004/09/01 by Martin V�geli (stable version)
+ * Version 0.1: 2004/08/30 by Martin V�geli (first draft)
+ * 
+ * Contact: martinvoegeli@gmx.ch
+ * Website 1: http://elearning.zhwin.ch/
+ * Website 2: http://birdy1976.com/
+ *
+ * License:  GPL License v2
+ *
+ * 2006-08-31  File created.
+ */
+
+// This page cannot be called directly
+if (!isset($CFG)) exit;
+
+/**
+ * PAM authentication plugin.
+ */
+class auth_plugin_pam {
+
+    /**
+     * The configuration details for the plugin.
+     */
+    var $config;
+    
+    /**
+     * Store error messages from pam authentication attempts.
+     */
+    var $lasterror;
+
+    /**
+     * Constructor.
+     */
+    function auth_plugin_pam() {
+        $this->config = get_config('auth/pam');
+        $this->errormessage = '';
+    }
+
+    /**
+     * Returns true if the username and password work and false if they are
+     * wrong or don't exist.
+     *
+     * @param string $username The username
+     * @param string $password The password
+     * @returns bool Authentication success or failure.
+     */
+    function user_login ($username, $password) {
+        // variable to store possible errors during authentication
+        $errormessage = str_repeat(' ', 2048);
+        
+        // just for testing and debugging
+        // error_reporting(E_ALL);
+        if (pam_auth($username, $password, &$errormessage)) {
+            return true;
+        }
+        else {
+            $this->lasterror =&