From: moodler Date: Mon, 20 Sep 2004 09:08:57 +0000 (+0000) Subject: Merged/cleaned changes from MOODLE_15_LDAP to HEAD ... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=d35757eb2571b90c999ae17e5c9a636c1bfec6f6;p=moodle.git Merged/cleaned changes from MOODLE_15_LDAP to HEAD ... please don't use the MOODLE_15_LDAP branch any more. --- diff --git a/admin/auth.php b/admin/auth.php index b44aa21ef7..a74e6f53a4 100644 --- a/admin/auth.php +++ b/admin/auth.php @@ -113,7 +113,10 @@ echo ""; require_once("$CFG->dirroot/auth/$auth/config.html"); - + echo ""; + if ($auth != "email" and $auth != "none" and $auth != "manual") { echo ""; echo " - - + + + + + + - + - + + - - - + + - + + + + + + - - - - + + + + + + + + + + + + + + - - - + + - + - + + + + + + + - - - + + - + - + + - - - + + + + + + + + + - + + + + - - - - + + + + + - - - - - - - + + - - - + + + + + + - - - - - - - - + + + - + + + +
+ + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - - - - + + + + - - - - + + + + - - - - + + + - + + + + + + + + + + + + + diff --git a/auth/ldap/lib.php b/auth/ldap/lib.php index 196aa653c7..57e4a4999f 100644 --- a/auth/ldap/lib.php +++ b/auth/ldap/lib.php @@ -1,5 +1,7 @@ -ldap_objectclass)) { + if (empty($CFG->ldap_objectclass)) { $CFG->ldap_objectclass="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 +/// OPTIONAL PARAMETERS +/// $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; + + if($unsafe_optimizations){ + // 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 + while(count($userids)){ + $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) . '\')'; + execute_sql($sql); + } + + /// 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 + WHERE u.id IS NULL'; + $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"; } + update_user_record($user->username); 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); - + update_user_record($user->username); + $userid = get_field('user', 'id', 'auth', 'ldap', 'idnumber', $user->idnumber); + if (auth_iscreator($user->username)) { if (! record_exists("user_coursecreators", "userid", $userid)) { $cdata['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); + if($unsafe_optimizations){ + $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)) { + $CFG->ldap_objectclass="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"); + @ldap_close($ldap_connection); + return false; + } + + @ldap_close($ldap_connection); + + 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); + + if(!$user_dn){ + 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)); + + if(!$result){ + error_log('LDAP Error in auth_user_update_password(). Error code: ' + . ldap_errno($ldap_connection) . '; Error string : ' + . ldap_err2str(ldap_errno($ldap_connection))); + } + + @ldap_close($ldap_connection); + + return $result; +} + //PRIVATE FUNCTIONS starts //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="*") { auth_ldap_bind($ldap_connection); - if (! isset($CFG->ldap_objectclass)) { + if (empty($CFG->ldap_objectclass)) { $CFG->ldap_objectclass="objectClass=*"; } diff --git a/lang/en/auth.php b/lang/en/auth.php index e26d7720a5..4310a198f7 100644 --- a/lang/en/auth.php +++ b/lang/en/auth.php @@ -14,6 +14,8 @@ $string['auth_dbtable'] = 'Name of the table in the database'; $string['auth_dbtitle'] = 'Use an external database'; $string['auth_dbtype'] = 'The database type (See the ADOdb documentation for details)'; $string['auth_dbuser'] = 'Username with read access to the database'; +$string['auth_editlock'] = 'Lock value'; +$string['auth_editlock_expl'] = '

Lock value: 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.

'; $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_imaphost'] = 'The IMAP server address. Use the IP number, not DNS $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_pop3type'] = 'Server type. If your server uses certificate securit $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'] = '

Update local data: 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.

'; +$string['auth_updateremote'] = 'Update external data'; +$string['auth_updateremote_expl'] = '

Update external data: If enabled, the external auth will be updated when the user record is updated. Fields should be unlocked to allow edits.

'; +$string['auth_updateremote_ldap'] = '

Note: 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.

'; $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'; ?> diff --git a/lang/en/moodle.php b/lang/en/moodle.php index 53ca2638ef..8cacbdce4b 100644 --- a/lang/en/moodle.php +++ b/lang/en/moodle.php @@ -337,6 +337,7 @@ $string['editcoursesettings'] = 'Edit course settings'; $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'; diff --git a/lib/db/mysql.php b/lib/db/mysql.php index 01e51bd3c4..39fb4cdb8b 100644 --- a/lib/db/mysql.php +++ b/lib/db/mysql.php @@ -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; diff --git a/lib/db/mysql.sql b/lib/db/mysql.sql index 5fe5a8e461..832a7fc7b6 100644 --- a/lib/db/mysql.sql +++ b/lib/db/mysql.sql @@ -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`); # -------------------------------------------------------- # diff --git a/lib/db/postgres7.php b/lib/db/postgres7.php index d328c84ece..8065c7c6cb 100644 --- a/lib/db/postgres7.php +++ b/lib/db/postgres7.php @@ -584,11 +584,21 @@ function main_upgrade($oldversion=0) { set_field('user', 'auth', 'manual', 'username', 'guest'); } + /* Just commenteed unused fields out if ($oldversion < 2004090300) { // Add guid-field used in user syncronization table_column('user', '', 'guid', 'varchar', '128', '', '', '', 'auth'); execute_sql("CREATE INDEX {$CFG->prefix}user_auth_guid_idx ON {$CFG->prefix}user (auth, guid)"); } + */ + if ($oldversion < 2004091900) { //Modify idnumber to hold longer keys + set_field('user', 'auth', 'manual', 'username', 'guest'); + table_column('user', 'idnumber', 'idnumber', 'varchar', '64', '', '', '', ''); + execute_sql("CREATE INDEX {$CFG->prefix}user_idnumber_idx ON {$CFG->prefix}user (idnumber)"); + execute_sql("CREATE INDEX {$CFG->prefix}user_auth_idx ON {$CFG->prefix}user (auth)"); + } + + return $result; } diff --git a/lib/db/postgres7.sql b/lib/db/postgres7.sql index 037d3d2639..a7d532553e 100644 --- a/lib/db/postgres7.sql +++ b/lib/db/postgres7.sql @@ -198,12 +198,11 @@ CREATE INDEX prefix_cache_text_md5key_idx ON prefix_cache_text (md5key); CREATE TABLE prefix_user ( id SERIAL PRIMARY KEY, auth varchar(20) NOT NULL default 'manual', - guid varchar(128) default NULL, confirmed integer NOT NULL default '0', deleted integer 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 '', @@ -236,7 +235,8 @@ CREATE TABLE prefix_user ( CONSTRAINT prefix_user_username_uk UNIQUE (username) ); -CREATE INDEX prefix_user_auth_guid_idx ON prefix_user (auth, guid); +CREATE INDEX prefix_user_idnumber_idx ON prefix_user (idnumber); +CREATE INDEX prefix_user_auth_idx ON prefix_user (auth); CREATE TABLE prefix_user_admins ( id SERIAL PRIMARY KEY, diff --git a/lib/db/schemaUser.xml b/lib/db/schemaUser.xml index 6094b6c0f4..c883214253 100755 --- a/lib/db/schemaUser.xml +++ b/lib/db/schemaUser.xml @@ -17,7 +17,7 @@ - + diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 7262b01bf9..a807a15125 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -89,29 +89,34 @@ function reload_user_preferences() { } } -function set_user_preference($name, $value) { +function set_user_preference($name, $value, $user=NULL) { /// Sets a preference for the current user +/// Optionally, can set a preference for a different user object global $USER; + if (empty($user)){ + $user = $USER; + } + if (empty($name)) { return false; } - if ($preference = get_record('user_preferences', 'userid', $USER->id, 'name', $name)) { + if ($preference = get_record('user_preferences', 'userid', $user->id, 'name', $name)) { if (set_field("user_preferences", "value", $value, "id", $preference->id)) { - $USER->preference[$name] = $value; + $user->preference[$name] = $value; return true; } else { return false; } } else { - $preference->userid = $USER->id; + $preference->userid = $user->id; $preference->name = $name; $preference->value = (string)$value; if (insert_record('user_preferences', $preference)) { - $USER->preference[$name] = $value; + $user->preference[$name] = $value; return true; } else { return false; @@ -381,6 +386,20 @@ function require_login($courseid=0, $autologinguest=true) { die; } + // check whether the user should be changing password + reload_user_preferences(); + if ($USER->preference['auth_forcepasswordchange']){ + if (is_internal_auth() || $CFG->{'auth_'.$USER->auth.'_stdchangepassword'}){ + redirect("$CFG->wwwroot/login/change_password.php"); + } elseif($CFG->changepassword) { + redirect($CFG->changepassword); + } else { + error("You cannot proceed without changing your password. + However there is no available page for changing it. + Please contact your Moodle Administrator."); + } + } + // Check that the user account is properly set up if (user_not_fully_set_up($USER)) { redirect("$CFG->wwwroot/user/edit.php?id=$USER->id&course=".SITEID); @@ -762,11 +781,33 @@ function create_user_record($username, $password, $auth='') { $newuser->timemodified = time(); if (insert_record("user", $newuser)) { - return get_user_info_from_db("username", $username); + $user = get_user_info_from_db("username", $newuser->username); + if($CFG->{'auth_'.$newuser->auth.'_forcechangepassword'}){ + set_user_preference('auth_forcepasswordchange', 1, $user); + } + return $user; } return false; } +function update_user_record($username) { +/// will update a local user record from an external source. + global $CFG; + + if (function_exists('auth_get_userinfo')) { + $username = trim(moodle_strtolower($username)); /// just in case check text case + + if ($newinfo = auth_get_userinfo($username)) { + foreach ($newinfo as $key => $value){ + if (!empty($CFG->{'auth_user_' . $key. '_updatelocal'})) { + $value = addslashes(stripslashes($value)); // Just in case + set_field('user', $key, $value, 'username', $username); + } + } + } + } + return get_user_info_from_db("username", $username); +} function guest_user() { global $CFG; @@ -809,6 +850,10 @@ function authenticate_user_login($username, $password) { } else { $auth = $CFG->auth; // Normal users default to site method } + // update user record from external DB + if ($user->auth != 'manual' && $user->auth != 'email') { + $user = update_user_record($username); + } } else { $auth = $user->auth; } @@ -827,6 +872,10 @@ function authenticate_user_login($username, $password) { if ($md5password <> $user->password) { // Update local copy of password for reference set_field('user', 'password', $md5password, 'username', $username); } + // update user record from external DB + if ($user->auth != 'manual' && $user->auth != 'email'){ + $user = update_user_record($username); + } } else { $user = create_user_record($username, $password, $auth); } @@ -3081,4 +3130,4 @@ function getremoteaddr() { } // vim:autoindent:expandtab:shiftwidth=4:tabstop=4:tw=140: -?> \ No newline at end of file +?> diff --git a/login/change_password.php b/login/change_password.php index bb2479f303..71627c5613 100644 --- a/login/change_password.php +++ b/login/change_password.php @@ -1,4 +1,4 @@ -password = $password; - } else { - error("Could not set the new password"); + if(is_internal_auth($user)){ + if (set_field("user", "password", $password, "username", $username)) { + $user->password = $password; + } else { + error("Could not set the new password"); + } + } else { // external users + // the relevant auth libs should be loaded already + // as validate_form() calls authenticate_user_login() + // check that we allow changes through moodle + if(isset($CFG->{'auth_'. $user->auth.'_stdchangepassword'}) && $CFG->{'auth_'. $user->auth.'_stdchangepassword'}){ + if(function_exists('auth_user_update_password')){ + // note that we pass cleartext password + if(auth_user_update_password($user->username, $frm->newpassword1)){ + $user->password = $password; + } else { + error("Could not set the new password"); + } + } else { + + error_log("External Authentication " . $user->auth . + ' is set to use standard change password interface ' . + ' but auth_user_update_password() is missing.'); + error('The authentication module is misconfigured'); + } + } else { + error("You are cannot change you password this way."); + } } - + + // register success changing password + set_user_preference('auth_forcepasswordchange', false); + $USER = $user; $USER->loggedin = true; $USER->site = $CFG->wwwroot; // for added security @@ -103,24 +130,35 @@ *****************************************************************************/ function validate_form($frm, &$err) { - if (empty($frm->username)) + if (empty($frm->username)){ $err->username = get_string("missingusername"); + } else { + if (empty($frm->password)){ + $err->password = get_string("missingpassword"); + } else { + //require non adminusers to give valid password + if (!isadmin() && !authenticate_user_login($frm->username, $frm->password)){ + $err->password = get_string("wrongpassword"); + } + } + } - else if (empty($frm->password)) - $err->password = get_string("missingpassword"); - - else if (!authenticate_user_login($frm->username, $frm->password)) - $err->password = get_string("wrongpassword"); - - if (empty($frm->newpassword1)) + if (empty($frm->newpassword1)){ $err->newpassword1 = get_string("missingnewpassword"); + } - if (empty($frm->newpassword2)) + if (empty($frm->newpassword2)){ $err->newpassword2 = get_string("missingnewpassword"); - - else if ($frm->newpassword1 <> $frm->newpassword2) - $err->newpassword2 = get_string("passwordsdiffer"); - + } else { + if ($frm->newpassword1 <> $frm->newpassword2) { + $err->newpassword2 = get_string("passwordsdiffer"); + } else { + if($frm->password === $frm->newpassword1){ + $err->newpassword1 = get_string("mustchangepassword"); + } + } + } + return; } diff --git a/login/change_password_form.html b/login/change_password_form.html index 226b54020f..d577a51917 100644 --- a/login/change_password_form.html +++ b/login/change_password_form.html @@ -15,18 +15,28 @@ ?>

"; + print_string("auth_common_settings", "auth"); + echo "

"; diff --git a/auth/ldap/config.html b/auth/ldap/config.html index 14d73815b6..ee48eb565e 100644 --- a/auth/ldap/config.html +++ b/auth/ldap/config.html @@ -1,268 +1,643 @@ -ldap_host_url)) { - $config->ldap_host_url = ""; - } - if (!isset($config->ldap_contexts)) { - $config->ldap_contexts = ""; - } - if (!isset($config->ldap_user_attribute)) { - $config->ldap_user_attribute = ""; - } - if (!isset($config->ldap_search_sub)) { - $config->ldap_search_sub = ""; - } - if (!isset($config->ldap_bind_dn)) { - $config->ldap_bind_dn = ""; - } - if (!isset($config->ldap_bind_pw)) { - $config->ldap_bind_pw = ""; - } - if (empty($config->ldap_version)) { - $config->ldap_version = "2"; - } - if (empty($config->ldap_memberattribute)) { - $config->ldap_memberattribute = ""; - } - if (empty($config->ldap_creators)) { - $config->ldap_creators = ""; - } - if (empty($config->ldap_create_context)) { - $config->ldap_create_context = ""; - } - if (empty($config->ldap_objectclass)) { - $config->ldap_objectclass = ""; - } - if (empty($config->auth_user_guid)) { - $config->auth_user_guid = ""; - } +ldap_host_url, ""); + optional_variable($config->ldap_contexts, ""); + optional_variable($config->ldap_user_attribute, ""); + optional_variable($config->ldap_search_sub, ""); + optional_variable($config->ldap_bind_dn, ""); + optional_variable($config->ldap_bind_pw, ""); + optional_variable($config->ldap_version, "2"); + optional_variable($config->ldap_objectclass, ""); + optional_variable($config->ldap_memberattribute, ""); + optional_variable($config->ldap_creators, ""); + optional_variable($config->ldap_create_context, ""); + optional_variable($config->auth_ldap_expirecheck, ""); + optional_variable($config->auth_ldap_expireattr, ""); + optional_variable($config->auth_ldap_expiredaysbefore, ""); + optional_variable($config->auth_ldap_gracecheck, ""); + optional_variable($config->auth_ldap_graceattr, ""); + optional_variable($config->auth_user_create, ""); + optional_variable($config->auth_user_create, ""); + optional_variable($config->auth_ldap_forcepasswordchange, ""); + + optional_variable($config->auth_user_firstname_updatelocal, ""); + optional_variable($config->auth_user_firstname_editlock, ""); + optional_variable($config->auth_user_firstname_updateremote, ""); + optional_variable($config->auth_user_lastname_updatelocal, ""); + optional_variable($config->auth_user_lastname_editlock, ""); + optional_variable($config->auth_user_lastname_updateremote, ""); + optional_variable($config->auth_user_email_updatelocal, ""); + optional_variable($config->auth_user_email_editlock, ""); + optional_variable($config->auth_user_email_updateremote, ""); + optional_variable($config->auth_user_phone1_updatelocal, ""); + optional_variable($config->auth_user_phone1_editlock, ""); + optional_variable($config->auth_user_phone1_updateremote, ""); + optional_variable($config->auth_user_phone2_updatelocal, ""); + optional_variable($config->auth_user_phone2_editlock, ""); + optional_variable($config->auth_user_phone2_updateremote, ""); + optional_variable($config->auth_user_department_updatelocal, ""); + optional_variable($config->auth_user_department_editlock, ""); + optional_variable($config->auth_user_department_updateremote, ""); + optional_variable($config->auth_user_address_updatelocal, ""); + optional_variable($config->auth_user_address_editlock, ""); + optional_variable($config->auth_user_address_updateremote, ""); + optional_variable($config->auth_user_city_updatelocal, ""); + optional_variable($config->auth_user_city_editlock, ""); + optional_variable($config->auth_user_city_updateremote, ""); + optional_variable($config->auth_user_country_updatelocal, ""); + optional_variable($config->auth_user_country_editlock, ""); + optional_variable($config->auth_user_country_updateremote, ""); + optional_variable($config->auth_user_description_updatelocal, ""); + optional_variable($config->auth_user_description_editlock, ""); + optional_variable($config->auth_user_description_updateremote, ""); + optional_variable($config->auth_user_lang_updatelocal, ""); + optional_variable($config->auth_user_lang_editlock, ""); + optional_variable($config->auth_user_lang_updateremote, ""); + optional_variable($config->auth_user_idnumber_updatelocal, ""); + optional_variable($config->auth_user_idnumber_editlock, ""); + optional_variable($config->auth_user_idnumber_updateremote, ""); + optional_variable($config->auth_ldap_stdchangepassword, false); + +if (!function_exists('ldap_connect')){ // Is php4-ldap really there? + print '

Warning: + The PHP LDAP module does not seem to be present. + Please ensure it is installed and enabled.

'; +} + ?> -

ldap_host_url:

- +
+

+

ldap_host_url:

+ - + -

ldap_version:

+

ldap_version:

ldap_version, ""); if (isset($err["ldap_version"])) formerr($err["ldap_version"]); ?> - + -
+

+

ldap_contexts:

- - - - -

ldap_bind_dn:

+ + + + +

ldap_bind_pw:

+ + + + +
+

+

ldap_user_attribute:

- + +

ldap_user_attribute:

+ - + -

ldap_memberattribute:

+ + + + +

ldap_objectclass:

- + +

ldap_objectclass:

+ - + -

ldap_search_sub:

- +

ldap_contexts:

+ + + + +

ldap_search_sub:

+ - + -
+

+

ldap_bind_dn:

- - - - -

ldap_create_context:

+ + + + +

ldap_bind_pw:

- - - - -

ldap_memberattribute:

- - - - -
+

+

ldap_creators:

- +

ldap_creators:

+ - + -
+

+

ldap_create_context:

- - - - -

:

- - +

:

+ +
+ +
+ +
+ +
+
+
-

:

- -

:

+ +
+ +
+ +
+ +
+
+

:

- -

:

+ +
+ +
+ +
+ +
+
+

1:

- -

1:

+ +
+ +
+ +
+ +
+
+

2:

- -

2:

+ +
+ +
+ +
+ +
+
+

:

- -

:

+ +
+ +
+ +
+ +
+
+

:

- -

:

+ +
+ +
+ +
+ +
+
+

:

- -

:

+ +
+ +
+ +
+ +
+
+

:

- -

:

+ +
+ +
+ +
+ +
+
+

:

- -

:

+ +
+ +
+ +
+ +
+
+

:

- -

:

- -

:

+ +
+ +
+ +
+ +
+
+

:

- -

:

+ +
+ +
+ +
+ +
+
+

:

- - +

:

+ + -

:

+ +
+
+

+

:

+
+
+

+

+
+ - - - - - + + + + + + + + '; - echo '' . "\n' . "\n\n"; - if ($adminself || is_internal_auth($user->auth) ){ + if ($adminself || is_internal_auth($user->auth) || (!empty($CFG->{'auth_'.$user->auth.'_stdchangepassword'}))) { echo ""; echo ""; echo "\n"; + if(!$adminself && ($CFG->{'auth_'.$user->auth.'_stdchangepassword'} || $CFG->changepassword)){ + echo ""; + echo ''; + echo ''; + echo ""; + } + echo ""; } } ?> - - - - + @@ -137,20 +162,33 @@ if (isadmin()) { - - + - @@ -160,7 +198,12 @@ if (isadmin()) { if (!$user->lang) { $user->lang = $CFG->lang; } - choose_from_menu ($languages, "lang", $user->lang, "", "", ""); + if($user_external && $CFG->auth_user_lang_editlock){ ?> + + lang); + } else { + choose_from_menu ($languages, "lang", $user->lang, "", "", ""); + } } if (isset($err["lang"])) formerr($err["lang"]); ?> @@ -195,15 +238,23 @@ if (isadmin()) { - + + } ?> + @@ -264,37 +315,67 @@ if (isadmin()) { - - - + + - + - - - diff --git a/user/edit.php b/user/edit.php index 68f71d284c..f55aa79ba1 100644 --- a/user/edit.php +++ b/user/edit.php @@ -44,7 +44,16 @@ error("Sorry, the guest user cannot be edited."); } + // load the relevant auth libraries + if ($user->auth) { + $auth = $user->auth; + if (!file_exists("$CFG->dirroot/auth/$auth/lib.php")) { + $auth = "manual"; // Can't find auth module, default to internal + } + require_once("$CFG->dirroot/auth/$auth/lib.php"); + } + /// If data submitted, then process and store. if ($usernew = data_submitted()) { @@ -68,7 +77,7 @@ require_once($CFG->dirroot.'/lib/uploadlib.php'); $um = new upload_manager('imagefile',false,false,null,false,0,true,true); - if (find_form_errors($user, $usernew, $err,$um)) { + if (find_form_errors($user, $usernew, $err, $um)) { if (empty($err['imagefile']) && $usernew->picture = save_profile_image($user->id, $um,'users')) { set_field('user', 'picture', $usernew->picture, 'id', $user->id); /// Note picture in DB } else { @@ -97,6 +106,21 @@ if (isadmin()) { if (!empty($usernew->newpassword)) { $usernew->password = md5($usernew->newpassword); + // update external passwords + if (!empty($CFG->{'auth_'. $user->auth.'_stdchangepassword'})) { + if(function_exists('auth_user_update_password')){ + if (!auth_user_update_password($user->username, $usernew->newpassword)){ + error('Failed to update password on external auth: ' . $user->auth . + '. See the server logs for more details.'); + } + } else { + error('Your external authentication module is misconfigued!'); + } + } + // store forcepasswordchange in user's preferences + if (isset($usernew->forcepasswordchange)){ + set_user_preference('auth_forcepasswordchange', 1, $user); + } } } else { if (isset($usernew->newpassword)) { @@ -108,7 +132,10 @@ } if (update_record("user", $usernew)) { - add_to_log($course->id, "user", "update", "view.php?id=$user->id&course=$course->id", ""); + if (function_exists("auth_user_update")){ + auth_user_update($user, $usernew); + } + add_to_log($course->id, "user", "update", "view.php?id=$user->id&course=$course->id", ""); if ($user->id == $USER->id) { // Copy data into $USER session variable @@ -183,9 +210,9 @@ print_simple_box_start("center", "", "$THEME->cellheading"); if (!empty($err)) { - echo "
"; - notify(get_string("someerrorswerefound")); - echo "
"; + echo "
"; + notify(get_string("someerrorswerefound")); + echo "
"; } include("edit.html"); print_simple_box_end(); @@ -208,7 +235,7 @@ function find_form_errors(&$user, &$usernew, &$err, &$um) { $err["username"] = get_string("missingusername"); } else if (record_exists("user", "username", $usernew->username) and $user->username == "changeme") { - $err["username"] = get_string("usernameexists"); + $err["username"] = get_string("usernameexists"); } else { if (empty($CFG->extendedusernamechars)) { @@ -263,6 +290,43 @@ function find_form_errors(&$user, &$usernew, &$err, &$um) { $err['imagefile'] = $um->notify; } + if ($CFG->auth_user_firstname_editlock && !($user->firstname === $usernew->firstname)){ + $err["firstname"] = get_string("editlock"); + } + if ($CFG->auth_user_lastname_editlock && !($user->lastname === $usernew->lastname)){ + $err["lastname"] = get_string("editlock"); + } + if ($CFG->auth_user_email_editlock && !($user->email === $usernew->email)){ + $err["email"] = get_string("editlock"); + } + if ($CFG->auth_user_phone1_editlock && !($user->phone1 === $usernew->phone1)){ + $err["phone1"] = get_string("editlock"); + } + if ($CFG->auth_user_phone2_editlock && !($user->phone2 === $usernew->phone2)){ + $err["phone2"] = get_string("editlock"); + } + if ($CFG->auth_user_department_editlock && !($user->department === $usernew->department)){ + $err["department"] = get_string("editlock"); + } + if ($CFG->auth_user_address_editlock && !($user->address === $usernew->address)){ + $err["address"] = get_string("editlock"); + } + if ($CFG->auth_user_city_editlock && !($user->city === $usernew->city)){ + $err["city"] = get_string("editlock"); + } + if ($CFG->auth_user_description_editlock && !($user->description === $usernew->description)){ + $err["description"] = get_string("editlock"); + } + if ($CFG->auth_user_idnumber_editlock && !($user->idnumber === $usernew->idnumber)){ + $err["idnumber"] = get_string("editlock"); + } + if ($CFG->auth_user_lang_editlock && !($user->lang === $usernew->lang)){ + $err["lang"] = get_string("editlock"); + } + if ($CFG->auth_user_guid_editlock && !($user->guid === $usernew->guid)){ + $err["guid"] = get_string("editlock"); + } + $user->email = $usernew->email; return count($err); diff --git a/version.php b/version.php index 9dd319a284..c935c4a229 100644 --- a/version.php +++ b/version.php @@ -5,7 +5,7 @@ // database to determine whether upgrades should // be performed (see lib/db/*.php) -$version = 2004091700; // The current version is a date (YYYYMMDDXX) +$version = 2004091900; // The current version is a date (YYYYMMDDXX) $release = "1.5 unstable development"; // User-friendly version number

:

+ + + + + username)?> + username)) { formerr($err->username); } ?>

:

- password)) { formerr($err->password); } ?> -

:

+ password)) { formerr($err->password); } ?> +

:

diff --git a/login/index.php b/login/index.php index 341e493656..af8ed05085 100644 --- a/login/index.php +++ b/login/index.php @@ -69,6 +69,20 @@ unset($SESSION->lang); $SESSION->justloggedin = true; + // check whether the user should be changing password + reload_user_preferences(); + if ($USER->preference['auth_forcepasswordchange']){ + if (is_internal_auth() || $CFG->{'auth_'.$USER->auth.'_stdchangepassword'}){ + redirect("$CFG->wwwroot/login/change_password.php"); + } elseif($CFG->changepassword) { + redirect($CFG->changepassword); + } else { + error("You cannot proceed without changing your password. + However there is no available page for changing it. + Please contact your Moodle Administrator."); + } + } + if (user_not_fully_set_up($USER)) { redirect("$CFG->wwwroot/user/edit.php?id=$USER->id&course=".SITEID); diff --git a/user/edit.html b/user/edit.html index 0f4af6d61b..a8c51ebbdf 100644 --- a/user/edit.html +++ b/user/edit.html @@ -39,11 +39,11 @@ if (isadmin()) { $auth_options[$module] = get_string("auth_$module"."title", "auth"); } echo '
' . get_string("chooseauthmethod","auth") . ':"; - choose_from_menu ($auth_options, "auth",$user->auth); + echo ''.get_string("chooseauthmethod","auth").'"; + choose_from_menu ($auth_options, "auth", $user->auth); echo "
".get_string("newpassword").": "; echo "

'.get_string('forcepasswordchange').':

'.get_string('forcepasswordchange_help').'

: + + auth_user_firstname_editlock){ ?> + + firstname) ?> + + +
: + + auth_user_lastname_editlock){ ?> + + lastname) ?> + + +
: +

:

+ auth_user_email_editlock){ ?> + + email) ?> + + +
: + : + auth_user_city_editlock){ ?> + + city) ?> + + +
: + country and $CFG->country) { $user->country = $CFG->country; } - choose_from_menu (get_list_of_countries(), "country", $user->country, get_string("selectacountry")."...", "", "") ?> + if($user_external && $CFG->auth_user_country_editlock){ ?> + + country); + } else { + choose_from_menu(get_list_of_countries(), "country", $user->country, get_string("selectacountry")."...", "", ""); + } + ?>
: "; + } ?> + auth_user_description_editlock){ ?> + + description, FORMAT_MOODLE); + } else { if (isset($err["description"])) { formerr($err["description"]); echo "
"; } print_textarea(false, 10, 50, 50, 10, 'description', "$user->description"); helpbutton("text", get_string("helptext")); - ?> -

:
: + + auth_user_idnumber_editlock){ ?> + + idnumber) ?> + + +
: - : +
: - + auth_user_department_editlock){ ?> + + department) ?> + + + +
1: + + auth_user_phone1_editlock){ ?> + + phone1) ?> + + +
2: + + auth_user_phone2_editlock){ ?> + + phone2) ?> + + +
: + + auth_user_address_editlock){ ?> + + address) ?> + + +