public function test_ldap_addslashes() { // See http://tools.ietf.org/html/rfc4514#section-5.2 if you want // to add additional tests. $tests = array(array('test' => 'Simplest', 'expected' => 'Simplest'), array('test' => 'Simple case', 'expected' => 'Simple\\20case'), array('test' => 'Medium ‒ case', 'expected' => 'Medium\\20‒\\20case'), array('test' => '#Harder+case#', 'expected' => '\\23Harder\\2bcase\\23'), array('test' => ' Harder (and); harder case ', 'expected' => '\\20Harder\\20(and)\\3b\\20harder\\20case\\20'), array('test' => 'Really \\0 (hard) case!\\', 'expected' => 'Really\\20\\5c0\\20(hard)\\20case!\\5c'), array('test' => 'James "Jim" = Smith, III', 'expected' => 'James\\20\\22Jim\\22\\20\\3d\\20Smith\\2c\\20III'), array('test' => ' <*****@*****.**> ', 'expected' => '\\20\\20\\3cjsmith@example.com\\3e\\20')); foreach ($tests as $test) { $this->assertSame($test['expected'], ldap_addslashes($test['test'])); } }
/** * Creates a new user on LDAP. * By using information in userobject * Use user_exists to prevent duplicate usernames * * @param mixed $userobject Moodle userobject * @param mixed $plainpass Plaintext password */ function user_create($userobject, $plainpass) { $extusername = core_text::convert($userobject->username, 'utf-8', $this->config->ldapencoding); $extpassword = core_text::convert($plainpass, 'utf-8', $this->config->ldapencoding); switch ($this->config->passtype) { case 'md5': $extpassword = '******' . base64_encode(pack('H*', md5($extpassword))); break; case 'sha1': $extpassword = '******' . base64_encode(pack('H*', sha1($extpassword))); break; case 'plaintext': default: break; // plaintext } $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})) { $newuser[$value] = core_text::convert($userobject->{$key}, 'utf-8', $this->config->ldapencoding); } } } //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'] = $extusername; $newuser['logindisabled'] = 'TRUE'; $newuser['userpassword'] = $extpassword; $uadd = ldap_add($ldapconnection, $this->config->user_attribute . '=' . ldap_addslashes($extusername) . ',' . $this->config->create_context, $newuser); break; case 'rfc2307': case 'rfc2307bis': // posixAccount object class forces us to specify a uidNumber // and a gidNumber. That is quite complicated to generate from // Moodle without colliding with existing numbers and without // race conditions. As this user is supposed to be only used // with Moodle (otherwise the user would exist beforehand) and // doesn't need to login into a operating system, we assign the // user the uid of user 'nobody' and gid of group 'nogroup'. In // addition to that, we need to specify a home directory. We // use the root directory ('/') as the home directory, as this // is the only one can always be sure exists. Finally, even if // it's not mandatory, we specify '/bin/false' as the login // shell, to prevent the user from login in at the operating // system level (Moodle ignores this). $newuser['objectClass'] = array('posixAccount', 'inetOrgPerson', 'organizationalPerson', 'person', 'top'); $newuser['cn'] = $extusername; $newuser['uid'] = $extusername; $newuser['uidNumber'] = AUTH_UID_NOBODY; $newuser['gidNumber'] = AUTH_GID_NOGROUP; $newuser['homeDirectory'] = '/'; $newuser['loginShell'] = '/bin/false'; // IMPORTANT: // We have to create the account locked, but posixAccount has // no attribute to achive this reliably. So we are going to // modify the password in a reversable way that we can later // revert in user_activate(). // // Beware that this can be defeated by the user if we are not // using MD5 or SHA-1 passwords. After all, the source code of // Moodle is available, and the user can see the kind of // modification we are doing and 'undo' it by hand (but only // if we are using plain text passwords). // // Also bear in mind that you need to use a binding user that // can create accounts and has read/write privileges on the // 'userPassword' attribute for this to work. $newuser['userPassword'] = '******' . $extpassword; $uadd = ldap_add($ldapconnection, $this->config->user_attribute . '=' . ldap_addslashes($extusername) . ',' . $this->config->create_context, $newuser); break; case 'ad': // User account creation is a two step process with AD. First you // create the user object, then you set the password. If you try // to set the password while creating the user, the operation // fails. // Passwords in Active Directory must be encoded as Unicode // strings (UCS-2 Little Endian format) and surrounded with // double quotes. See http://support.microsoft.com/?kbid=269190 if (!function_exists('mb_convert_encoding')) { print_error('auth_ldap_no_mbstring', 'auth_ldap'); } // Check for invalid sAMAccountName characters. if (preg_match('#[/\\[\\]:;|=,+*?<>@"]#', $extusername)) { print_error('auth_ldap_ad_invalidchars', 'auth_ldap'); } // First create the user account, and mark it as disabled. $newuser['objectClass'] = array('top', 'person', 'user', 'organizationalPerson'); $newuser['sAMAccountName'] = $extusername; $newuser['userAccountControl'] = AUTH_AD_NORMAL_ACCOUNT | AUTH_AD_ACCOUNTDISABLE; $userdn = 'cn=' . ldap_addslashes($extusername) . ',' . $this->config->create_context; if (!ldap_add($ldapconnection, $userdn, $newuser)) { print_error('auth_ldap_ad_create_req', 'auth_ldap'); } // Now set the password unset($newuser); $newuser['unicodePwd'] = mb_convert_encoding('"' . $extpassword . '"', 'UCS-2LE', 'UTF-8'); if (!ldap_modify($ldapconnection, $userdn, $newuser)) { // Something went wrong: delete the user account and error out ldap_delete($ldapconnection, $userdn); print_error('auth_ldap_ad_create_req', 'auth_ldap'); } $uadd = true; break; default: print_error('auth_ldap_unsupportedusertype', 'auth_ldap', '', $this->config->user_type_name); } $this->ldap_close(); return $uadd; }
function get_users_having_attribute_value($attributevalue) { global $CFG, $DB; //build a filter $filter = '(&(' . $this->config->user_attribute . '=*)' . $this->config->objectclass . ')'; $filter = '(&' . $filter . '(' . $this->config->cohort_synching_ldap_attribute_attribute . '=' . ldap_addslashes($attributevalue) . '))'; if ($CFG->debug_ldap_groupes) { pp_print_object('looking for ', $filter); } // call Moodle ldap_get_userlist that return it as an array with Moodle user attributes names $matchings = $this->ldap_get_userlist($filter); // return the FIRST entry found if (empty($matchings)) { if ($CFG->debug_ldap_groupes) { pp_print_object('not found', ''); } return array(); } if ($CFG->debug_ldap_groupes) { pp_print_object('found ', count($matchings) . ' matching users in LDAP'); } $ret = array(); //remove all matching LDAP users unkown to Moodle foreach ($matchings as $member) { $params = array('username' => $member); if ($user = $DB->get_record('user', $params, 'id,username')) { $ret[$user->id] = $user->username; } } if ($CFG->debug_ldap_groupes) { pp_print_object('found ', count($ret) . ' matching users known to Moodle'); } return $ret; }