Skip to content
Browse files

Merged/cleaned changes from MOODLE_15_LDAP to HEAD ...

please don't use the MOODLE_15_LDAP branch any more.
  • Loading branch information...
moodler committed Sep 20, 2004
1 parent 9f2e099 commit d35757eb2571b90c999ae17e5c9a636c1bfec6f6
@@ -113,7 +113,10 @@
echo "<table border=\"0\" width=\"100%\" cellpadding=\"4\">";
echo "<tr><td colspan=\"2\"><h2>";
print_string("auth_common_settings", "auth");
echo "</h2><td/></tr>";
if ($auth != "email" and $auth != "none" and $auth != "manual") {
echo "<tr valign=\"top\">";
echo "<td align=\"right\" nowrap=\"nowrap\"><p>";

Large diffs are not rendered by default.

@@ -1,5 +1,7 @@
<?php // $Id$
<?PHP // $Id$
//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
@@ -29,6 +31,8 @@
so all default values are for it.
!!!! Following comlete outdated as guid-field is not used anymorein moodeles user-table
!!!! I'll update this documentation as soon ldap-code get more stabile.
This is first version of usersync so backup your database, if you like to test this feature!
@@ -135,7 +139,6 @@ function auth_get_userinfo($username){
@@ -195,7 +198,7 @@ function auth_get_users($filter='*') {
if (! isset($CFG->ldap_objectclass)) {
if (empty($CFG->ldap_objectclass)) {
@@ -256,33 +259,92 @@ function auth_get_users($filter='*') {
return $fresult;
function auth_sync_users () {
function auth_sync_users ($unsafe_optimizations = false, $bulk_insert_records = 1) {
//Syncronizes userdb with ldap
//This will add, rename
/// $unsafe_optimizations = true // will skip over moodle standard DB interfaces and use very optimized
/// and non-portable SQL -- useful only for mysql or postgres7
/// $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.
global $CFG ;
$users = auth_get_users();
$usedguids = Array();
$ldapusers = auth_get_users();
$usedidnumbers = Array();
// these are only populated if we managed to find added/removed users
$add_users = false;
$remove_users = false;
// create a temp table
if(strtolower($CFG->dbtype) === 'mysql'){
// help old mysql versions cope with large temp tables
execute_sql('SET SQL_BIG_TABLES=1');
execute_sql('CREATE TEMPORARY TABLE ' . $CFG->prefix .'extuser (idnumber VARCHAR(12), PRIMARY KEY (idnumber)) TYPE=MyISAM');
} elseif (strtolower($CFG->dbtype) === 'postgres7'){
execute_sql('CREATE TEMPORARY TABLE '.$CFG->prefix.'extuser (idnumber VARCHAR(12), PRIMARY KEY (idnumber))');
$userids = array_keys($ldapusers);
// bulk insert -- superfast with $bulk_insert_records
$sql = 'INSERT INTO '.$CFG->prefix.'extuser (idnumber) VALUES ';
$values = array_splice($userids, -($bulk_insert_records) );
// make those values safe
array_map('addslashes', $values);
// join and quote the whole lot
$sql = $sql . '(\'' . join('\'),(\'', $values) . '\')';
/// REMOVE execute_sql('delete from mdl_user where idnumber like \'%s\'');
// find users in DB that aren't in ldap -- to be removed!
$sql = 'SELECT u.*
FROM ' . $CFG->prefix .'user u LEFT JOIN ' . $CFG->prefix .'extuser e
ON u.idnumber = e.idnumber
WHERE u.auth=\'ldap\' AND u.deleted=\'0\' AND e.idnumber IS NULL';
$remove_users = get_records_sql($sql);
print "User entries to remove: ". count($remove_users) . "\n";
// 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
$add_users = array_keys(get_records_sql($sql)) || array(); // get rid of the fat
print "User entries to add: ". count($add_users). "\n";
foreach ($ldapusers as $user) {
foreach ($users as $user) {
$usedguids[] = $user->guid; //we will need all used guids later
$usedidnumbers[] = $user->idnumber; //we will need all used idnumbers later
//update modified time
$user->modified = time();
//All users are confirmed
$user->confirmed = 1;
// if user does not exist create it
if (!record_exists('user','auth', 'ldap', 'guid', $user->guid)) {
if ( ($unsafe_optimizations && is_array($add_users) && in_array($user->idnumber, $add_users) )
|| (!$unsafe_optimizations &&!record_exists('user','auth', 'ldap', 'idnumber', $user->idnumber)) ) {
if (insert_record ('user',$user)) {
echo "inserted user $user->username with guid $user->guid \n";
echo "inserted user $user->username with idnumber $user->idnumber \n";
} else {
echo "error inserting user $user->username with guid $user->guid \n";
echo "error inserting user $user->username with idnumber $user->idnumber \n";
continue ;
} else {
//update username
set_field('user', 'username', $user->username , 'auth', 'ldap', 'guid', $user->guid);
set_field('user', 'username', $user->username , 'auth', 'ldap', 'idnumber', $user->idnumber);
//no id-information in ldap so get now
$userid = get_field('user', 'id', 'auth', 'ldap', 'guid', $user->guid);
$userid = get_field('user', 'id', 'auth', 'ldap', 'idnumber', $user->idnumber);
if (auth_iscreator($user->username)) {
if (! record_exists("user_coursecreators", "userid", $userid)) {
@@ -302,9 +364,13 @@ function auth_sync_users () {
//find nonexisting users from moodles userdb
$sql = "SELECT * FROM ".$CFG->prefix."user WHERE deleted = '0' AND auth = 'ldap' AND guid NOT IN ('".implode('\' , \'',$usedguids)."');" ;
$result = get_records_sql($sql);
$result=(is_array($remove_users) ? $remove_users : array());
} else{
//find nonexisting users from moodles userdb
$sql = "SELECT * FROM ".$CFG->prefix."user WHERE deleted = '0' AND auth = 'ldap' AND idnumber NOT IN ('".implode('\' , \'',$usedidnumbers)."');" ;
$result = get_records_sql($sql);
if (!empty($result)){
foreach ($result as $user) {
@@ -375,6 +441,98 @@ function auth_iscreator($username=0) {
function auth_user_update($olduser, $newuser) {
/// called when the user record is updated. push fields to
/// the LDAP database if configured to do so...
global $USER , $CFG;
$ldap_connection = auth_ldap_connect();
$ldapbind = auth_ldap_bind($ldap_connection);
$result = array();
$search_attribs = array();
$attrmap = auth_ldap_attributes();
foreach ($attrmap as $key=>$value) {
if (!in_array($value, $search_attribs)) {
array_push($search_attribs, $value);
$user_dn = auth_ldap_find_userdn($ldap_connection, $olduser->username);
if (empty($CFG->ldap_objectclass)) {
$user_info_result = ldap_read($ldap_connection,$user_dn,$CFG->ldap_objectclass, $search_attribs);
if ($user_info_result){
$user_entry = ldap_get_entries($ldap_connection, $user_info_result);
//error_log(var_export($user_entry) . 'fpp' );
foreach ($attrmap as $key=>$ldapkey){
if (isset($CFG->{'auth_user_'. $key.'_updateremote'}) && $CFG->{'auth_user_'. $key.'_updateremote'}){
// skip update if the values already match
if( !($newuser->$key === $user_entry[0][strtolower($ldapkey)][0]) ){
ldap_modify($ldap_connection, $user_dn, array($ldapkey => utf8_encode($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 " . $user_entry[0][strtolower($ldapkey)][0]);
} else {
error_log("ERROR:No user found in LDAP");
return false;
return true;
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;
$result = false;
$ldap_connection = auth_ldap_connect();
$ldapbind = auth_ldap_bind($ldap_connection);
$user_dn = auth_ldap_find_userdn($ldap_connection, $username);
error_log('LDAP Error in auth_user_update_password(). No DN for: ' . $username);
return false;
// send ldap the password in cleartext, it will md5 it itself
$result = ldap_modify($ldap_connection, $user_dn, array('userPassword' => $newpassword));
error_log('LDAP Error in auth_user_update_password(). Error code: '
. ldap_errno($ldap_connection) . '; Error string : '
. ldap_err2str(ldap_errno($ldap_connection)));
return $result;
//private functions are named as auth_ldap*
@@ -502,11 +660,11 @@ function auth_ldap_attributes (){
$config = (array)$CFG;
$fields = array("firstname", "lastname", "email", "phone1", "phone2",
"department", "address", "city", "country", "description",
"idnumber", "lang", "guid");
"idnumber", "lang" );
$moodleattributes = array();
foreach ($fields as $field) {
if ($config["auth_user_$field"]) {
if (!empty($config["auth_user_$field"])) {
$moodleattributes[$field] = $config["auth_user_$field"];
@@ -523,7 +681,7 @@ function auth_ldap_get_userlist($filter="*") {
if (! isset($CFG->ldap_objectclass)) {
if (empty($CFG->ldap_objectclass)) {
@@ -14,6 +14,8 @@
$string['auth_dbtitle'] = 'Use an external database';
$string['auth_dbtype'] = 'The database type (See the <a href=\"../lib/adodb/readme.htm#drivers\">ADOdb documentation</a> for details)';
$string['auth_dbuser'] = 'Username with read access to the database';
$string['auth_editlock'] = 'Lock value';
$string['auth_editlock_expl'] = '<p><b>Lock value:</b> If enabled, will prevent Moodle users and admins from editing the field directly. Use this option if you are maintaining this data in the external auth system. </p>';
$string['auth_emaildescription'] = 'Email confirmation is the default authentication method. When the user signs up, choosing their own new username and password, a confirmation email is sent to the user\'s email address. This email contains a secure link to a page where the user can confirm their account. Future logins just check the username and password against the stored values in the Moodle database.';
$string['auth_emailtitle'] = 'Email-based authentication';
$string['auth_fctitle'] = 'Use a FirstClass server';
@@ -28,6 +30,12 @@
$string['auth_imapport'] = 'IMAP server port number. Usually this is 143 or 993.';
$string['auth_imaptitle'] = 'Use an IMAP server';
$string['auth_imaptype'] = 'The IMAP server type. IMAP servers can have different types of authentication and negotiation.';
$string['auth_ldap_server_settings'] = 'LDAP server settings';
$string['auth_ldap_bind_settings'] = 'Bind settings';
$string['auth_ldap_user_settings'] = 'User lookup settings';
$string['auth_ldap_login_settings'] = 'Login settings';
$string['auth_common_settings'] = 'Common settings';
$string['auth_data_mapping'] = 'Data mapping';
$string['auth_ldap_bind_dn'] = 'If you want to use bind-user to search users, specify it here. Someting like \'cn=ldapuser,ou=public,o=org\'';
$string['auth_ldap_bind_pw'] = 'Password for bind-user.';
$string['auth_ldap_contexts'] = 'List of contexts where users are located. Separate different contexts with \';\'. For example: \'ou=users,o=org; ou=others,o=org\'';
@@ -69,15 +77,24 @@
$string['auth_user_create'] = 'Enable user creation';
$string['auth_user_creation'] = 'New (anonymous) users can create user accounts on the external authentication source and confirmed via email. If you enable this , remember to also configure module-specific options for user creation.';
$string['auth_usernameexists'] = 'Selected username already exists. Please choose a new one.';
$string['auth_updatelocal'] = 'Update local data';
$string['auth_updatelocal_expl'] = '<p><b>Update local data:</b> If enabled, the field will be updated (from external auth) every time the user logs in or there is a user synchronization. Fields set to update locally should be locked.</p>';
$string['auth_updateremote'] = 'Update external data';
$string['auth_updateremote_expl'] = '<p><b>Update external data:</b> If enabled, the external auth will be updated when the user record is updated. Fields should be unlocked to allow edits.</p>';
$string['auth_updateremote_ldap'] = '<p><b>Note:</b> Updating external LDAP data requires that you set binddn and bindpw to a bind-user with editing privileges to all the user records. It currently does not preserve multi-valued attributes, and will remove extra values on update. </p>';
$string['authenticationoptions'] = 'Authentication options';
$string['authinstructions'] = 'Here you can provide instructions for your users, so they know which username and password they should be using. The text you enter here will appear on the login page. If you leave this blank then no instructions will be printed.';
$string['changepassword'] = 'Change password URL';
$string['changepasswordhelp'] = 'Here you can specify a location at which your users can recover or change their username/password if they\'ve forgotten it. This will be provided to users as a button on the login page and their user page. if you leave this blank the button will not be printed.';
$string['chooseauthmethod'] = 'Choose an authentication method: ';
$string['guestloginbutton'] = 'Guest login button';
$string['instructions'] = 'Instructions';
$string['md5'] = 'MD5 encryption';
$string['plaintext'] = 'Plain text';
$string['showguestlogin'] = 'You can hide or show the guest login button on the login page.';
$string['stdchangepassword'] = 'Use standard Change Password Page';
$string['stdchangepassword_expl'] = 'If the external authentication system allows password changes through Moodle, switch this to Yes. This setting overrides \'Change Password URL\'.';
$string['stdchangepassword_explldap'] = 'NOTE: It is recommended that you use LDAP over an SSL encrypted tunnel (ldaps://) if the LDAP server is remote.';
$string['forcechangepassword'] = 'Force change password';
$string['forcechangepassword_help'] = 'Force users to change password on their first login to Moodle.';$string['guestloginbutton'] = 'Guest login button';
@@ -337,6 +337,7 @@
$string['editfiles'] = 'Edit files';
$string['editgroupprofile'] = 'Edit group profile';
$string['editinga'] = 'Editing $a';
$string['editlock'] = 'This value cannot be edited!';
$string['editmyprofile'] = 'Edit profile';
$string['editorbgcolor'] = 'Background-color';
$string['editorcleanonpaste'] = 'Clean Word HTML on paste';
@@ -850,10 +850,18 @@ function main_upgrade($oldversion=0) {
set_field('user', 'auth', 'manual', 'username', 'guest');
/* Commented out unused guid-field code
if ($oldversion < 2004090300) { // Add guid-field used in user syncronization
table_column('user', '', 'guid', 'varchar', '128', '', '', '', 'auth');
execute_sql("ALTER TABLE {$CFG->prefix}user ADD INDEX authguid (auth, guid)");
if ($oldversion < 2004091900) { // modify idnumber to hold longer values
table_column('user', 'idnumber', 'idnumber', 'varchar', '64', '', '', '', 'auth');
execute_sql("ALTER TABLE {$CFG->prefix}user ADD INDEX idnumber (idnumber)");
execute_sql("ALTER TABLE {$CFG->prefix}user ADD INDEX auth (auth)");
return $result;
@@ -308,12 +308,11 @@ CREATE TABLE `prefix_scale` (
CREATE TABLE `prefix_user` (
`id` int(10) unsigned NOT NULL auto_increment,
`auth` varchar(20) NOT NULL default 'manual',
`guid` varchar(128) default NULL,
`confirmed` tinyint(1) NOT NULL default '0',
`deleted` tinyint(1) NOT NULL default '0',
`username` varchar(100) NOT NULL default '',
`password` varchar(32) NOT NULL default '',
`idnumber` varchar(12) default NULL,
`idnumber` varchar(64) default NULL,
`firstname` varchar(20) NOT NULL default '',
`lastname` varchar(20) NOT NULL default '',
`email` varchar(100) NOT NULL default '',
@@ -348,7 +347,8 @@ CREATE TABLE `prefix_user` (
UNIQUE KEY `username` (`username`)
) TYPE=MyISAM COMMENT='One record for each person';

ALTER TABLE `prefix_user` ADD INDEX `authguid` (`auth`, `guid`);
ALTER TABLE `prefix_user` ADD INDEX `auth` (`auth`);
ALTER TABLE `prefix_user` ADD INDEX `idnumber` (`idnumber`);
# --------------------------------------------------------


0 comments on commit d35757e

Please sign in to comment.
You can’t perform that action at this time.