/** * get the number of values * * @return the number of values */ public final function count() { $arr = []; if ($this->get_node()->get_changed()) { $this->get_node()->refresh_entry(); } $data = @ldap_get_values_len($this->get_ldapconn()->get_conn(), $this->get_node()->get_entry(), $this->get_name()); return $data['count']; }
function getObjectSid($adConn, $dn, $distname) { //Select which attributes wa want $attrs = array("objectsid"); //Filter creation $filter = "distinguishedname=" . addslashes($distname); //Do the seacrh! $search = ldap_search($adConn, $dn, $filter, $attrs) or die("**** happens, no connection!"); $entry = ldap_first_entry($adConn, $search); $vals = ldap_get_values_len($adConn, $entry, "objectsid"); return bin2hex($vals[0]); }
/** * read binary attribute from one entry from the ldap directory * * @todo still needed??? * * @param string $_dn the dn to read * @param string $_filter search filter * @param array $_attribute which field to return * @return blob binary data of given field * @throws Exception with ldap error */ public function fetchBinaryAttribute($_dn, $_filter, $_attribute) { $searchResult = @ldap_search($this->getResource(), $_dn, $_filter, $_attributes, $this->_attrsOnly, $this->_sizeLimit, $this->_timeLimit); if ($searchResult === FALSE) { throw new Exception(ldap_error($this->getResource())); } $searchCount = ldap_count_entries($this->getResource(), $searchResult); if ($searchCount === 0) { throw new Exception('Nothing found for filter: ' . $_filter); } elseif ($searchCount > 1) { throw new Exception('More than one entry found for filter: ' . $_filter); } $entry = ldap_first_entry($this->getResource(), $searchResult); return ldap_get_values_len($this->getResource(), $entry, $attribute); }
/** * Read an LDAP entry. * * @param resource $ds * LDAP connection resource. * @param resource $entryId * LDAP entry resource. * @param string[] $binaryFields * Names of binary attributes. * * @return array * Attributes for an LDAP entry. */ public static function readEntry($ds, $entryId, $binaryFields = array()) { $data = array(); for ($attribute = ldap_first_attribute($ds, $entryId, $attributeId); $attribute !== false; $attribute = ldap_next_attribute($ds, $entryId, $attributeId)) { $fieldValues = ldap_get_values($ds, $entryId, $attribute); if (in_array($attribute, $binaryFields)) { $fieldValues = ldap_get_values_len($ds, $entryId, $attribute); } if ($fieldValues['count'] == 1) { $data[$attribute] = $fieldValues[0]; } else { for ($i = 0; $i < $fieldValues['count']; $i++) { $data[$attribute][$i] = $fieldValues[$i]; } } } return $data; }
protected function getUserLdapPhoto($contactID) { $ldap_context = $_SESSION['phpgw_info']['expressomail']['ldap_server']['dn']; $justthese = array("dn", 'jpegPhoto', 'givenName', 'sn'); $this->getLdapCatalog()->ldapConnect(true); $ds = $this->getLdapCatalog()->ds; if ($ds) { $resource = @ldap_read($ds, $contactID, "phpgwaccounttype=u"); $n_entries = @ldap_count_entries($ds, $resource); if ($n_entries == 1) { $first_entry = ldap_first_entry($ds, $resource); $obj = ldap_get_attributes($ds, $first_entry); if ($obj['jpegPhoto']) { return ldap_get_values_len($ds, $first_entry, "jpegPhoto"); } } } return false; }
/** * I cannot imagine a lib being more crap than PHP LDAP one. * Structure information is melt with data, all functions need a * connection handler, there are 367 ways of doing the things but only one * works (at least with binary results) without failures nor error * messages. Result keys change with automatic pagination without notice * and so does values when they have accentuated characters. * It has been a pain to write and a hell to debug, thanks to the * obsolutely non informative documentation. * * hydrateFromResult * * Create an entity instance from a LDAP result. * * @param Resource $ldap_entry * @return Entity */ protected function hydrateFromResult($ldap_entry) { if ($ldap_entry === false) { return false; } $values = array(); foreach ($this->getAttributes($ldap_entry) as $ldap_attribute) { $attribute = strpos($ldap_attribute, ';') === false ? $ldap_attribute : substr($ldap_attribute, 0, strpos($ldap_attribute, ';')); if ($this->map->getAttributeModifiers($attribute) & EntityMap::FIELD_BINARY) { $value = @ldap_get_values_len($this->handler, $ldap_entry, sprintf("%s", $ldap_attribute)); } else { $value = @ldap_get_values($this->handler, $ldap_entry, $ldap_attribute); } if (is_array($value)) { if ($this->map->getAttributeModifiers($attribute) & EntityMap::FIELD_MULTIVALUED) { unset($value['count']); if (!$this->map->getAttributeModifiers($attribute) & EntityMap::FIELD_BINARY) { $values[$attribute] = array_map(function ($val) { if ($val === base64_encode(base64_decode($val, true))) { return base64_decode($val); } return $val; }, $value); } else { $values[$attribute] = $value; } } else { if ($value[0] === base64_encode(base64_decode($value[0], true))) { $values[$attribute] = $value[0]; } else { $values[$attribute] = $value[0]; } } } } $values['dn'] = ldap_get_dn($this->handler, $ldap_entry); return $this->map->createObject($values); }
/** * @param array $attrs An array of names of desired attributes * @return array An array of the attributes representing the account * @throws Zend_Ldap_Exception */ private function _getAccount($acctname, $attrs = null) { $baseDn = $this->_getBaseDn(); if (!$baseDn) { /** * @see Zend_Ldap_Exception */ require_once 'Zend/Ldap/Exception.php'; throw new Zend_Ldap_Exception(null, 'Base DN not set'); } $accountFilter = $this->_getAccountFilter($acctname); if (!$accountFilter) { /** * @see Zend_Ldap_Exception */ require_once 'Zend/Ldap/Exception.php'; throw new Zend_Ldap_Exception(null, 'Invalid account filter'); } if (!is_resource($this->_resource)) $this->bind(); $resource = $this->_resource; $str = $accountFilter; $code = 0; /** * @todo break out search operation into simple function (private for now) */ if (!extension_loaded('ldap')) { /** * @see Zend_Ldap_Exception */ require_once 'Zend/Ldap/Exception.php'; throw new Zend_Ldap_Exception(null, 'LDAP extension not loaded'); } $result = @ldap_search($resource, $baseDn, $accountFilter, $attrs); if (is_resource($result) === true) { $count = @ldap_count_entries($resource, $result); if ($count == 1) { $entry = @ldap_first_entry($resource, $result); if ($entry) { $acct = array('dn' => @ldap_get_dn($resource, $entry)); $name = @ldap_first_attribute($resource, $entry, $berptr); while ($name) { $data = @ldap_get_values_len($resource, $entry, $name); $acct[$name] = $data; $name = @ldap_next_attribute($resource, $entry, $berptr); } @ldap_free_result($result); return $acct; } } else if ($count == 0) { /** * @see Zend_Ldap_Exception */ require_once 'Zend/Ldap/Exception.php'; $code = Zend_Ldap_Exception::LDAP_NO_SUCH_OBJECT; } else { /** * @todo limit search to 1 record and remove some of this logic? */ $resource = null; $str = "$accountFilter: Unexpected result count: $count"; /** * @see Zend_Ldap_Exception */ require_once 'Zend/Ldap/Exception.php'; $code = Zend_Ldap_Exception::LDAP_OPERATIONS_ERROR; } @ldap_free_result($result); } /** * @see Zend_Ldap_Exception */ require_once 'Zend/Ldap/Exception.php'; throw new Zend_Ldap_Exception($resource, $str, $code); }
/** * fill a database table with usernames from al LDAP directory * searching parameters are defined in configuration * DOES NOT SUPPORT PAGED RESULTS if more than a 1000 (AD) * @param string tablename * @param string columnname * @param string $extrafilter if present returns only users having some values in some LDAP attribute * @return integer (nb of records added) or false in case of error */ private function ldap_get_users_scalable($tablename, $columnname = 'username', $extrafilter = '') { global $CFG; execute_sql('TRUNCATE TABLE ' . $tablename); $ldapconnection = $this->ldap_connect(); if (!$ldapconnection) { return false; } $filter = "(" . $this->config['user_attribute'] . "=*)"; if (!empty($this->config['objectclass'])) { $filter .= "&(" . $this->config['objectclass'] . "))"; } if ($extrafilter) { $filter = "(&{$filter}({$extrafilter}))"; } // get all contexts and look for first matching user $ldap_contexts = explode(";", $this->config['contexts']); $ldapuserfields = $this->get_ldap_user_fields(); $fieldstoimport = array_values($ldapuserfields); $fieldstoimport[] = $this->config['user_attribute']; // Lowercase all the fields to avoid case mismatch issues $ldapuserfields = array_map('strtolower', $ldapuserfields); log_info('retrieving these fields: ' . implode(',', $fieldstoimport) . "\n"); $nbadded = 0; foreach ($ldap_contexts as $context) { $context = trim($context); if (empty($context)) { continue; } if ($this->config['search_sub'] == 'yes') { // use ldap_search to find first user from subtree $ldap_result = ldap_search($ldapconnection, $context, $filter, $fieldstoimport); } else { // search only in this context $ldap_result = ldap_list($ldapconnection, $context, $filter, $fieldstoimport); } if ($entry = ldap_first_entry($ldapconnection, $ldap_result)) { do { $value = ldap_get_values_len($ldapconnection, $entry, $this->config['user_attribute']); $value = $value[0]; // let's convert all keys to lowercase, to avoid case sensitivity issues $ldaprec = array_change_key_case(ldap_get_attributes($ldapconnection, $entry)); $todb = new stdClass(); $todb->{$columnname} = $value; foreach ($ldapuserfields as $dbfield => $ldapfield) { if (array_key_exists($ldapfield, $ldaprec)) { $todb->{$dbfield} = $ldaprec[$ldapfield][0]; } else { log_warn("Ldap record contained no {$ldapfield} field to map to DB {$dbfield}"); } } insert_record($tablename, $todb, false, false); $nbadded++; if ($nbadded % 100 == 0) { echo '.'; } } while ($entry = ldap_next_entry($ldapconnection, $entry)); echo "\n"; } ldap_free_result($ldap_result); // free mem } $this->ldap_close($ldapconnection); return $nbadded; }
/** * Get all binary values from the specified result entry. * * @param $entry * @param $attribute * * @return array */ public function getValuesLen($entry, $attribute) { if ($this->suppressErrors) { return @ldap_get_values_len($this->getConnection(), $entry, $attribute); } return ldap_get_values_len($this->getConnection(), $entry, $attribute); }
/** * Wrapper for ldap_get_entries * * @access private * */ private function getEntries() { return $this->entries = @ldap_get_entries($this->ldap_handle, $this->result); // this way ldap_get_entries is binary safe $i = 0; $tmp_entries = array(); $entry = ldap_first_entry($this->ldap_handle, $this->result); do { $attributes = @ldap_get_attributes($this->ldap_handle, $entry); for ($j = 0; $j < $attributes['count']; $j++) { $values = ldap_get_values_len($this->ldap_handle, $entry, $attributes[$j]); $tmp_entries[$i][strtolower($attributes[$j])] = $values; } $i++; } while ($entry = @ldap_next_entry($this->ldap_handle, $entry)); if ($i) { $tmp_entries['count'] = $i; } $this->entries = $tmp_entries; return $this->entries; }
/** * Recupere le SID de l'utilisateur * Required by Active Directory * * @param string $ldapUser Login de l'utilisateur * @return string Sid */ function getObjectSid($ldapUser) { $criteria = '(' . $this->getUserIdentifier() . '=' . $ldapUser . ')'; $justthese = array("objectsid"); // if the directory is AD, then bind first with the search user first if ($this->serverType == "activedirectory") { $this->bindauth($this->searchUser, $this->searchPassword); } $i = 0; $searchDN = $this->people; while ($i <= 2) { $ldapSearchResult = @ldap_search($this->connection, $searchDN, $criteria, $justthese); if (!$ldapSearchResult) { $this->error = ldap_errno($this->connection) . " " . ldap_error($this->connection); return -1; } $entry = ldap_first_entry($this->connection, $ldapSearchResult); if (!$entry) { // Si pas de resultat on cherche dans le domaine $searchDN = $this->domain; $i++; } else { $i++; $i++; } } if ($entry) { $ldapBinary = ldap_get_values_len($this->connection, $entry, "objectsid"); $SIDText = $this->binSIDtoText($ldapBinary[0]); return $SIDText; } else { $this->error = ldap_errno($this->connection) . " " . ldap_error($this->connection); return '?'; } }
/** * 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][strtolower($attributes[$j])] = $values; } else { $fresult[$i][strtolower($attributes[$j])] = array($values); } } $i++; } while ($entry = @ldap_next_entry($conn, $entry)); //were done return $fresult; }
/** * {@inheritdoc} */ public function getValuesLen($entry, $attribute) { return ldap_get_values_len($this->getConnection(), $entry, $attribute); }
public function __construct($ldap, $entry, array $fieldMap) { $ldapEntry = ldap_get_attributes($ldap, $entry); $this->dn = ldap_get_dn($ldap, $entry); $this->fieldMap = $fieldMap; $this->attributes = array(); for ($i = 0; $i < $ldapEntry['count']; $i++) { $attribute = $ldapEntry[$i]; $attrib = strtolower($attribute); $count = $ldapEntry[$attribute]['count']; if ($attrib == $this->fieldMap['photodata']) { if ($data = @ldap_get_values_len($ldap, $entry, $attribute)) { $this->attributes[$attrib] = $data; // Get binary photo data } } else { $this->attributes[$attrib] = array(); for ($j = 0; $j < $count; $j++) { if (!in_array($ldapEntry[$attribute][$j], $this->attributes[$attrib])) { $this->attributes[$attrib][] = str_replace('$', "\n", $ldapEntry[$attribute][$j]); } } } } }
function QueryArray($str = '(ObjectClass=*)', $fields = false) { global $APPLICATION; if (strlen($this->arFields['BASE_DN']) <= 0) { return false; } $arBaseDNs = explode(";", $this->arFields['BASE_DN']); $info = false; $i = 0; if ($this->arFields["CONVERT_UTF8"] == "Y") { $str = $APPLICATION->ConvertCharset($str, SITE_CHARSET, "utf-8"); } foreach ($arBaseDNs as $BaseDN) { global $APPLICATION; $BaseDN = trim($BaseDN); if ($BaseDN == "") { continue; } if ($this->arFields["CONVERT_UTF8"] == "Y") { $BaseDN = $APPLICATION->ConvertCharset($BaseDN, SITE_CHARSET, "utf-8"); } $defaultMaxPageSizeAD = 1000; $pageSize = isset($this->arFields['MAX_PAGE_SIZE']) && intval($this->arFields['MAX_PAGE_SIZE'] > 0) ? intval($this->arFields['MAX_PAGE_SIZE']) : $defaultMaxPageSizeAD; $cookie = ''; do { if (CLdapUtil::isLdapPaginationAviable()) { ldap_control_paged_result($this->conn, $pageSize, false, $cookie); } if ($fields === false) { $sr = @ldap_search($this->conn, $BaseDN, $str); } else { $sr = @ldap_search($this->conn, $BaseDN, $str, $fields); } if ($sr) { $entry = ldap_first_entry($this->conn, $sr); if ($entry) { if (!is_array($info)) { $info = array(); $i = 0; } do { $attributes = ldap_get_attributes($this->conn, $entry); for ($j = 0; $j < $attributes['count']; $j++) { $values = @ldap_get_values_len($this->conn, $entry, $attributes[$j]); if ($values === false) { continue; } $bPhotoAttr = in_array($attributes[$j], self::$PHOTO_ATTRIBS); $info[$i][strtolower($attributes[$j])] = $bPhotoAttr ? $values : $this->WorkAttr($values); } if (!is_set($info[$i], 'dn')) { if ($this->arFields["CONVERT_UTF8"] == "Y") { $info[$i]['dn'] = $APPLICATION->ConvertCharset(ldap_get_dn($this->conn, $entry), "utf-8", SITE_CHARSET); } else { $info[$i]['dn'] = ldap_get_dn($this->conn, $entry); } } $i++; } while ($entry = ldap_next_entry($this->conn, $entry)); } } elseif ($sr === false) { $APPLICATION->ThrowException("LDAP_SEARCH_ERROR"); } if (CLdapUtil::isLdapPaginationAviable()) { ldap_control_paged_result_response($this->conn, $sr, $cookie); } } while ($cookie !== null && $cookie != ''); } return $info; }
/** * Return entries from ldap * * Returns values like ldap_get_entries but is binary compatible and return * all attributes as array * * @return array ldap-entries */ private function ldap_get_entries($conn, $searchresult) { $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)); // We're done return $fresult; }
$sr = @ldap_search($ds, $ldap_basedn, '(uid=*)'); $info = ldap_get_entries($ds, $sr); for ($key = 0; $key < $info["count"]; $key++) { echo "<pre>"; print_r($info[$key]); echo "</pre>"; $lastname = api_utf8_decode($info[$key]["sn"][0]); $firstname = api_utf8_decode($info[$key]["givenname"][0]); $email = $info[$key]["mail"][0]; // Get uid from dn $dn_array = ldap_explode_dn($info[$key]["dn"], 1); $username = $dn_array[0]; // uid is first key $outab[] = $info[$key]["edupersonprimaryaffiliation"][0]; // Ici "student" $val = ldap_get_values_len($ds, $sr, "userPassword"); $password = $val[0]; // Pour faciliter la gestion on ajoute le code "etape-annee" $official_code = $etape . "-" . $annee; $auth_source = "ldap"; // Pas de date d'expiration d'etudiant (a recuperer par rapport au shadow expire LDAP) $expiration_date = '0000-00-00 00:00:00'; $active = 1; // Ajout de l'utilisateur if (UserManager::is_username_available($username)) { $user_id = UserManager::create_user($firstname, $lastname, $status, $email, $username, $password, $official_code, api_get_setting('language.platform_language'), $phone, $picture_uri, $auth_source, $expiration_date, $active); $UserAdd[] = $user_id; } else { $user = api_get_user_info_from_username($username); $user_id = $user['user_id']; UserManager::update_user($user_id, $firstname, $lastname, $username, null, null, $email, $status, $official_code, $phone, $picture_uri, $expiration_date, $active);
/** * Syncronizes user fron external LDAP server to moodle user table * * Sync is now using username attribute. * * Syncing users removes or suspends users that dont exists anymore in external LDAP. * Creates new users and updates coursecreator status of users. * * @param bool $do_updates will do pull in data updates from LDAP if relevant */ function sync_users($do_updates = true) { global $CFG, $DB; print_string('connectingldap', 'auth_ldap'); $ldapconnection = $this->ldap_connect(); $dbman = $DB->get_manager(); /// Define table user to be created $table = new xmldb_table('tmp_extuser'); $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('username', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null); $table->add_field('mnethostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); $table->add_index('username', XMLDB_INDEX_UNIQUE, array('mnethostid', 'username')); print_string('creatingtemptable', 'auth_ldap', 'tmp_extuser'); $dbman->create_temp_table($table); //// //// get user's list from ldap to sql in a scalable fashion //// // prepare some data we'll need $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); } $ldap_pagedresults = ldap_paged_results_supported($this->config->ldap_version); $ldap_cookie = ''; foreach ($contexts as $context) { $context = trim($context); if (empty($context)) { continue; } do { if ($ldap_pagedresults) { ldap_control_paged_result($ldapconnection, $this->config->pagesize, true, $ldap_cookie); } 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 (!$ldap_result) { continue; } if ($ldap_pagedresults) { ldap_control_paged_result_response($ldapconnection, $ldap_result, $ldap_cookie); } if ($entry = @ldap_first_entry($ldapconnection, $ldap_result)) { do { $value = ldap_get_values_len($ldapconnection, $entry, $this->config->user_attribute); $value = core_text::convert($value[0], $this->config->ldapencoding, 'utf-8'); $value = trim($value); $this->ldap_bulk_insert($value); } while ($entry = ldap_next_entry($ldapconnection, $entry)); } unset($ldap_result); // Free mem. } while ($ldap_pagedresults && $ldap_cookie !== null && $ldap_cookie != ''); } // If LDAP paged results were used, the current connection must be completely // closed and a new one created, to work without paged results from here on. if ($ldap_pagedresults) { $this->ldap_close(true); $ldapconnection = $this->ldap_connect(); } /// 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 = $DB->count_records_sql('SELECT COUNT(username) AS count, 1 FROM {tmp_extuser}'); if ($count < 1) { print_string('didntgetusersfromldap', 'auth_ldap'); exit; } else { print_string('gotcountrecordsfromldap', 'auth_ldap', $count); } /// User removal // Find users in DB that aren't in ldap -- to be removed! // this is still not as scalable (but how often do we mass delete?) if ($this->config->removeuser == AUTH_REMOVEUSER_FULLDELETE) { $sql = "SELECT u.*\n FROM {user} u\n LEFT JOIN {tmp_extuser} e ON (u.username = e.username AND u.mnethostid = e.mnethostid)\n WHERE u.auth = :auth\n AND u.deleted = 0\n AND e.username IS NULL"; $remove_users = $DB->get_records_sql($sql, array('auth' => $this->authtype)); if (!empty($remove_users)) { print_string('userentriestoremove', 'auth_ldap', count($remove_users)); foreach ($remove_users as $user) { if (delete_user($user)) { echo "\t"; print_string('auth_dbdeleteuser', 'auth_db', array('name' => $user->username, 'id' => $user->id)); echo "\n"; } else { echo "\t"; print_string('auth_dbdeleteusererror', 'auth_db', $user->username); echo "\n"; } } } else { print_string('nouserentriestoremove', 'auth_ldap'); } unset($remove_users); // Free mem! } else { if ($this->config->removeuser == AUTH_REMOVEUSER_SUSPEND) { $sql = "SELECT u.*\n FROM {user} u\n LEFT JOIN {tmp_extuser} e ON (u.username = e.username AND u.mnethostid = e.mnethostid)\n WHERE u.auth = :auth\n AND u.deleted = 0\n AND u.suspended = 0\n AND e.username IS NULL"; $remove_users = $DB->get_records_sql($sql, array('auth' => $this->authtype)); if (!empty($remove_users)) { print_string('userentriestoremove', 'auth_ldap', count($remove_users)); foreach ($remove_users as $user) { $updateuser = new stdClass(); $updateuser->id = $user->id; $updateuser->suspended = 1; user_update_user($updateuser, false); echo "\t"; print_string('auth_dbsuspenduser', 'auth_db', array('name' => $user->username, 'id' => $user->id)); echo "\n"; \core\session\manager::kill_user_sessions($user->id); } } else { print_string('nouserentriestoremove', 'auth_ldap'); } unset($remove_users); // Free mem! } } /// Revive suspended users if (!empty($this->config->removeuser) and $this->config->removeuser == AUTH_REMOVEUSER_SUSPEND) { $sql = "SELECT u.id, u.username\n FROM {user} u\n JOIN {tmp_extuser} e ON (u.username = e.username AND u.mnethostid = e.mnethostid)\n WHERE (u.auth = 'nologin' OR (u.auth = ? AND u.suspended = 1)) AND u.deleted = 0"; // Note: 'nologin' is there for backwards compatibility. $revive_users = $DB->get_records_sql($sql, array($this->authtype)); if (!empty($revive_users)) { print_string('userentriestorevive', 'auth_ldap', count($revive_users)); foreach ($revive_users as $user) { $updateuser = new stdClass(); $updateuser->id = $user->id; $updateuser->auth = $this->authtype; $updateuser->suspended = 0; user_update_user($updateuser, false); echo "\t"; print_string('auth_dbreviveduser', 'auth_db', array('name' => $user->username, 'id' => $user->id)); echo "\n"; } } else { print_string('nouserentriestorevive', 'auth_ldap'); } unset($revive_users); } /// 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 } } } unset($all_keys); unset($key); } else { print_string('noupdatestobedone', 'auth_ldap'); } if ($do_updates and !empty($updatekeys)) { // run updates only if relevant $users = $DB->get_records_sql('SELECT u.username, u.id FROM {user} u WHERE u.deleted = 0 AND u.auth = ? AND u.mnethostid = ?', array($this->authtype, $CFG->mnet_localhost_id)); if (!empty($users)) { print_string('userentriestoupdate', 'auth_ldap', count($users)); $sitecontext = context_system::instance(); if (!empty($this->config->creators) and !empty($this->config->memberattribute) and $roles = get_archetype_roles('coursecreator')) { $creatorrole = array_shift($roles); // We can only use one, let's use the first one } else { $creatorrole = false; } $transaction = $DB->start_delegated_transaction(); $xcount = 0; $maxxcount = 100; foreach ($users as $user) { echo "\t"; print_string('auth_dbupdatinguser', 'auth_db', array('name' => $user->username, 'id' => $user->id)); if (!$this->update_user_record($user->username, $updatekeys, true)) { echo ' - ' . get_string('skipped'); } echo "\n"; $xcount++; // Update course creators if needed if ($creatorrole !== false) { if ($this->iscreator($user->username)) { role_assign($creatorrole->id, $user->id, $sitecontext->id, $this->roleauth); } else { role_unassign($creatorrole->id, $user->id, $sitecontext->id, $this->roleauth); } } } $transaction->allow_commit(); unset($users); // free mem } } else { // end do updates print_string('noupdatestobedone', 'auth_ldap'); } /// User Additions // Find users missing in DB that are in LDAP // and gives me a nifty object I don't want. // note: we do not care about deleted accounts anymore, this feature was replaced by suspending to nologin auth plugin $sql = 'SELECT e.id, e.username FROM {tmp_extuser} e LEFT JOIN {user} u ON (e.username = u.username AND e.mnethostid = u.mnethostid) WHERE u.id IS NULL'; $add_users = $DB->get_records_sql($sql); if (!empty($add_users)) { print_string('userentriestoadd', 'auth_ldap', count($add_users)); $sitecontext = context_system::instance(); if (!empty($this->config->creators) and !empty($this->config->memberattribute) and $roles = get_archetype_roles('coursecreator')) { $creatorrole = array_shift($roles); // We can only use one, let's use the first one } else { $creatorrole = false; } $transaction = $DB->start_delegated_transaction(); foreach ($add_users as $user) { $user = $this->get_userinfo_asobj($user->username); // Prep a few params $user->modified = time(); $user->confirmed = 1; $user->auth = $this->authtype; $user->mnethostid = $CFG->mnet_localhost_id; // get_userinfo_asobj() might have replaced $user->username with the value // from the LDAP server (which can be mixed-case). Make sure it's lowercase $user->username = trim(core_text::strtolower($user->username)); if (empty($user->lang)) { $user->lang = $CFG->lang; } if (empty($user->calendartype)) { $user->calendartype = $CFG->calendartype; } $id = user_create_user($user, false); echo "\t"; print_string('auth_dbinsertuser', 'auth_db', array('name' => $user->username, 'id' => $id)); echo "\n"; $euser = $DB->get_record('user', array('id' => $id)); if (!empty($this->config->forcechangepassword)) { set_user_preference('auth_forcepasswordchange', 1, $id); } // Add course creators if needed if ($creatorrole !== false and $this->iscreator($user->username)) { role_assign($creatorrole->id, $id, $sitecontext->id, $this->roleauth); } } $transaction->allow_commit(); unset($add_users); // free mem } else { print_string('nouserstobeadded', 'auth_ldap'); } $dbman->drop_table($table); $this->ldap_close(); return true; }
/** * Converts a username (samAccountName) to a GUID * * @param string $username The username to query * @return string */ public function username2guid($username) { if (!$this->_bind) { return false; } if ($username === null) { return "Missing compulsory field [username]"; } $filter = "samaccountname=" . $username; $fields = array("objectGUID"); $sr = @ldap_search($this->_conn, $this->_base_dn, $filter, $fields); if (ldap_count_entries($this->_conn, $sr) > 0) { $entry = @ldap_first_entry($this->_conn, $sr); $guid = @ldap_get_values_len($this->_conn, $entry, 'objectGUID'); $strGUID = $this->binary2text($guid[0]); return $strGUID; } else { return false; } }
/** * Get all the binary values from the entry * * Used to read all the values of the attribute in the entry * * I renamed the get_values_len to getValuesBin as it seemed more logical * * Returns an array of values for the attribute on success and FALSE on error. * * @link http://www.php.net/ldap_get_values_len * @param string $attr The attribute you want to read * @return array */ function getValuesBin($attr) { if ($arr = @ldap_get_values_len($this->connection, $this->entry, $attr)) { return $arr; } $this->setErrVars(); return false; }
/** * fill a database table with usernames from al LDAP directory * searching parameters are defined in configuration * DOES NOT SUPPORT PAGED RESULTS if more than a 1000 (AD) * @param string tablename * @param string columnname * @param string $extrafilter if present returns only users having some values in some LDAP attribute * @return integer (nb of records added) or false in case of error */ public function ldap_get_users_scalable($tablename, $columname = 'username', $extrafilter = '') { global $CFG; execute_sql('TRUNCATE TABLE ' . $tablename); $ldapconnection = $this->ldap_connect(); if ($CFG->debug_ldap_groupes) { moodle_print_object("connexion ldap: ", $ldapconnection); } if (!$ldapconnection) { return false; } $filter = "(" . $this->config['user_attribute'] . "=*)"; if (!empty($this->config['objectclass'])) { $filter .= "&(" . $this->config['objectclass'] . "))"; } if ($extrafilter) { $filter = "(&{$filter}({$extrafilter}))"; } if ($CFG->debug_ldap_groupes) { moodle_print_object("filter users ldap: ", $filter); } // get all contexts and look for first matching user $ldap_contexts = explode(";", $this->config['contexts']); $nbadded = 0; foreach ($ldap_contexts as $context) { $context = trim($context); if (empty($context)) { continue; } if ($this->config['search_sub'] == 'yes') { // 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, $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]; //array_push($ret, $value); insert_record($tablename, array($columname => addslashes($value)), false, false); $nbadded++; } while ($entry = ldap_next_entry($ldapconnection, $entry)); } unset($ldap_result); // free mem } @ldap_close($ldapconnection); return $nbadded; }
/** * Returns values like ldap_get_entries but is binary compatible and * returns all attributes as array. * * @param mixed $ldapconnection A valid LDAP connection * @param mixed $searchresult A search result from ldap_search, ldap_list, etc. * @return array ldap-entries with lower-cased attributes as indexes */ function ldap_get_entries_moodle($ldapconnection, $searchresult) { if (empty($ldapconnection) || empty($searchresult)) { return array(); } $i = 0; $result = array(); $entry = ldap_first_entry($ldapconnection, $searchresult); if (!$entry) { return array(); } do { $attributes = array_change_key_case(ldap_get_attributes($ldapconnection, $entry), CASE_LOWER); for ($j = 0; $j < $attributes['count']; $j++) { $values = ldap_get_values_len($ldapconnection, $entry, $attributes[$j]); if (is_array($values)) { $result[$i][$attributes[$j]] = $values; } else { $result[$i][$attributes[$j]] = array($values); } } $i++; } while ($entry = ldap_next_entry($ldapconnection, $entry)); return $result; }
/** * Recursively process the groups the given member distinguished name * belongs to, adding them to the already processed groups array. * * @param string $memberdn distinguished name to search * @param array reference &$membergroups array with already found * groups, where we'll put the newly found * groups. */ protected function ldap_find_user_groups_recursively($memberdn, &$membergroups) { $result = @ldap_read($this->ldapconnection, $memberdn, '(objectClass=*)', array($this->get_config('group_memberofattribute'))); if (!$result) { return; } if ($entry = ldap_first_entry($this->ldapconnection, $result)) { do { $attributes = ldap_get_attributes($this->ldapconnection, $entry); for ($j = 0; $j < $attributes['count']; $j++) { $groups = ldap_get_values_len($this->ldapconnection, $entry, $attributes[$j]); foreach ($groups as $key => $group) { if ($key === 'count') { // Skip the entries count continue; } if (!in_array($group, $membergroups)) { // Only push and recurse if we haven't 'seen' this group before // to prevent loops (MS Active Directory allows them!!). array_push($membergroups, $group); $this->ldap_find_user_groups_recursively($group, $membergroups); } } } } while ($entry = ldap_next_entry($this->ldapconnection, $entry)); } }
/** * Return the current result item * Implements Iterator * * @return array|null * @throws Zend_Ldap_Exception */ public function current() { if (!is_resource($this->_current)) { $this->rewind(); } if (!is_resource($this->_current)) { return null; } $entry = array('dn' => $this->key()); $ber_identifier = null; $name = @ldap_first_attribute($this->_ldap->getResource(), $this->_current, $ber_identifier); while ($name) { $data = @ldap_get_values_len($this->_ldap->getResource(), $this->_current, $name); unset($data['count']); switch ($this->_attributeNameTreatment) { case self::ATTRIBUTE_TO_LOWER: $attrName = strtolower($name); break; case self::ATTRIBUTE_TO_UPPER: $attrName = strtoupper($name); break; case self::ATTRIBUTE_NATIVE: $attrName = $name; break; default: $attrName = call_user_func($this->_attributeNameTreatment, $name); break; } $entry[$attrName] = $data; $name = @ldap_next_attribute($this->_ldap->getResource(), $this->_current, $ber_identifier); } ksort($entry, SORT_LOCALE_STRING); return $entry; }
/** * Converts a username (samAccountName) to a GUID * * @param string $username The username to query * @return string */ public function usernameToGuid($username) { if (!$this->adldap->getLdapBind()) { return false; } if ($username === null) { return "Missing compulsory field [username]"; } $filter = "samaccountname=" . $username; $fields = array("objectGUID"); $sr = @ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); if (ldap_count_entries($this->adldap->getLdapConnection(), $sr) > 0) { $entry = @ldap_first_entry($this->adldap->getLdapConnection(), $sr); $guid = @ldap_get_values_len($this->adldap->getLdapConnection(), $entry, 'objectGUID'); $strGUID = $this->adldap->utilities()->binaryToText($guid[0]); return $strGUID; } return false; }
/** * Return the current result item * Implements Iterator * * @return array|null * @throws \Zend\Ldap\Exception\LdapException */ public function current() { if (!is_resource($this->current)) { $this->rewind(); } if (!is_resource($this->current)) { return; } $entry = ['dn' => $this->key()]; $resource = $this->ldap->getResource(); ErrorHandler::start(); $name = ldap_first_attribute($resource, $this->current); ErrorHandler::stop(); while ($name) { ErrorHandler::start(); $data = ldap_get_values_len($resource, $this->current, $name); ErrorHandler::stop(); if (!$data) { $data = []; } if (isset($data['count'])) { unset($data['count']); } switch ($this->attributeNameTreatment) { case self::ATTRIBUTE_TO_LOWER: $attrName = strtolower($name); break; case self::ATTRIBUTE_TO_UPPER: $attrName = strtoupper($name); break; case self::ATTRIBUTE_NATIVE: $attrName = $name; break; default: $attrName = call_user_func($this->attributeNameTreatment, $name); break; } $entry[$attrName] = $data; ErrorHandler::start(); $name = ldap_next_attribute($resource, $this->current); ErrorHandler::stop(); } ksort($entry, SORT_LOCALE_STRING); return $entry; }
<?php require "connect.inc"; $link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version); insert_dummy_data($link); $result = ldap_search($link, "dc=my-domain,dc=com", "(objectclass=organization)"); $entry = ldap_first_entry($link, $result); var_dump(ldap_get_values_len($link, $entry, "o")); ?> ===DONE=== <?php include "connect.inc"; $link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version); remove_dummy_data($link);
function ldap_get_values_raw() { // will use ldap_get_values_len() instead and build the array // note: it's similar with the array returned by // ldap_get_entries() except it has no "count" elements $i = 0; $entry = ldap_first_entry($this->conn, $this->srchRslt); do { $attributes = ldap_get_attributes($this->conn, $entry); for ($j = 0; $j < $attributes['count']; $j++) { $values = ldap_get_values_len($this->conn, $entry, $attributes[$j]); $this->rawData[$i][$attributes[$j]] = $values; } $i++; } while ($entry = ldap_next_entry($this->conn, $entry)); //we're done return $this->rawData; }
public function searchnamesforgroup($value, $groupdn, $allowgeneric = false) { require FRAMEWORK . DS . 'conf' . DS . 'mycafetaria.php'; $value = $this->adescape($value); $groupdn = $this->adescape($groupdn, true); $agemenegebruikersdn = $this->adescape($agemenegebruikersdn, true); if (!$allowgeneric) { $filter = "(&(objectCategory=user)(objectClass=user)(|(displayname={$value})(samaccountname={$value}))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(memberof={$agemenegebruikersdn}))(memberof:1.2.840.113556.1.4.1941:={$groupdn}))"; } else { $filter = "(&(objectCategory=user)(objectClass=user)(|(displayname={$value})(samaccountname={$value}))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(memberof:1.2.840.113556.1.4.1941:={$groupdn}))"; } $filter2 = "(&(objectCategory=user)(objectClass=user)(|(displayname={$value})(samaccountname={$value}))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(memberof:1.2.840.113556.1.4.1941:={$groupdn}))"; $result = ldap_search($this->con, $this->dn, $filter, $this->attributes); if (ldap_errno($this->con)) { throw new searchException('Unable to conduct search: ' . ldap_error($this->con)); } $result2 = ldap_search($this->con2, $this->dn2, $filter2, $this->attributes); if (ldap_errno($this->con2)) { throw new searchException('Unable to conduct search: ' . ldap_error($this->con2)); } $output = array(); if (ldap_count_entries($this->con, $result)) { ldap_sort($this->con, $result, 'samaccountname'); $i = 0; $entry = ldap_first_entry($this->con, $result); do { $attributes = ldap_get_attributes($this->con, $entry); for ($j = 0; $j < $attributes['count']; $j++) { $values = ldap_get_values_len($this->con, $entry, $attributes[$j]); $rows[$i][strtolower($attributes[$j])] = $values; if (strtolower($attributes[$j]) == 'objectguid') { $rows[$i][strtolower($attributes[$j])][0] = bin2hex($values[0]); } if (count($rows[$i][strtolower($attributes[$j])]) == 2) { $rows[$i][strtolower($attributes[$j])] = $rows[$i][strtolower($attributes[$j])][0]; } else { unset($rows[$i][strtolower($attributes[$j])]['count']); } } $i++; } while ($entry = ldap_next_entry($this->con, $entry)); $rows['count'] = ldap_count_entries($this->con, $result); for ($index = 0; $index < $rows['count']; $index++) { $object = $this->fillObject($rows[$index], false); $output[] = $object; } } if (ldap_count_entries($this->con2, $result2)) { ldap_sort($this->con2, $result2, 'samaccountname'); $i = 0; $entry = ldap_first_entry($this->con2, $result2); do { $attributes = ldap_get_attributes($this->con2, $entry); for ($j = 0; $j < $attributes['count']; $j++) { $values = ldap_get_values_len($this->con2, $entry, $attributes[$j]); $rows[$i][strtolower($attributes[$j])] = $values; if (strtolower($attributes[$j]) == 'objectguid') { $rows[$i][strtolower($attributes[$j])][0] = bin2hex($values[0]); } if (count($rows[$i][strtolower($attributes[$j])]) == 2) { $rows[$i][strtolower($attributes[$j])] = $rows[$i][strtolower($attributes[$j])][0]; } else { unset($rows[$i][strtolower($attributes[$j])]['count']); } } $i++; } while ($entry = ldap_next_entry($this->con2, $entry)); $rows['count'] = ldap_count_entries($this->con2, $result2); for ($index = 0; $index < $rows['count']; $index++) { $object = $this->fillObject($rows[$index], false); $output[] = $object; } } return $output; }
/** * binary safe function to get all search result data. * It will use ldap_get_values_len() instead and build the array * note: it's similar with the array returned by ldap_get_entries() * except it has no "count" elements * * @author: Original code by Ovidiu Geaboc <*****@*****.**> */ function ldap_get_binentries($conn, $srchRslt) { if (!@ldap_count_entries($conn, $srchRslt)) { return null; } $entry = ldap_first_entry($conn, $srchRslt); $i = 0; do { $dn = ldap_get_dn($conn, $entry); $attrs = ldap_get_attributes($conn, $entry); for ($j = 0; $j < $attrs['count']; $j++) { $vals = ldap_get_values_len($conn, $entry, $attrs[$j]); for ($k = 0; $k < $vals['count']; $k++) { $data[$i][$attrs[$j]][$k] = $vals[$k]; } } $data[$i]['dn'] = $dn; $i++; } while ($entry = ldap_next_entry($conn, $entry)); return $data; }