private function getUser($attribute, $username) { $conn = $this->getConnection(); $query = ldap_sprintf('%Q=%S', $attribute, $username); $result = ldap_search($conn, $this->getBaseDN(), $query); if (!$result) { throw new Exception('Search failed. Please check your LDAP and HTTP ' . 'logs for more information.'); } $entries = ldap_get_entries($conn, $result); if ($entries === false) { throw new Exception('Could not get entries'); } if ($entries['count'] > 1) { throw new Exception('Found more then one user with this ' . $attribute); } if ($entries['count'] == 0) { throw new PhabricatorLDAPUnknownUserException('Could not find user'); } return $entries[0]; }
private function loadLDAPUserData() { $conn = $this->establishConnection(); $login_user = $this->loginUsername; $login_pass = $this->loginPassword; if ($this->shouldBindWithoutIdentity()) { $distinguished_name = null; $search_query = null; foreach ($this->searchAttributes as $attribute) { $search_query = $this->formatLDAPAttributeSearch($attribute, $login_user); $record = $this->searchLDAPForRecord($search_query); if ($record) { $distinguished_name = $this->readLDAPData($record, 'dn'); break; } } if ($distinguished_name === null) { throw new PhutilAuthCredentialException(); } } else { $search_query = $this->formatLDAPAttributeSearch(head($this->searchAttributes), $login_user); if ($this->activeDirectoryDomain) { $distinguished_name = ldap_sprintf('%s@%Q', $login_user, $this->activeDirectoryDomain); } else { $distinguished_name = ldap_sprintf('%Q,%Q', $search_query, $this->baseDistinguishedName); } } $this->bindLDAP($conn, $distinguished_name, $login_pass); $result = $this->searchLDAPForRecord($search_query); if (!$result) { // This is unusual (since the bind succeeded) but we've seen it at least // once in the wild, where the anonymous user is allowed to search but // the credentialed user is not. // If we don't have anonymous credentials, raise an explicit exception // here since we'll fail a typehint if we don't return an array anyway // and this is a more useful error. // If we do have anonymous credentials, we'll rebind and try the search // again below. Doing this automatically means things work correctly more // often without requiring additional configuration. if (!$this->shouldBindWithoutIdentity()) { // No anonymous credentials, so we just fail here. throw new Exception(pht('LDAP: Failed to retrieve record for user "%s" when searching. ' . 'Credentialed users may not be able to search your LDAP server. ' . 'Try configuring anonymous credentials or fully anonymous binds.', $login_user)); } else { // Rebind as anonymous and try the search again. $user = $this->anonymousUsername; $pass = $this->anonymousPassword; $this->bindLDAP($conn, $user, $pass); $result = $this->searchLDAPForRecord($search_query); if (!$result) { throw new Exception(pht('LDAP: Failed to retrieve record for user "%s" when searching ' . 'with both user and anonymous credentials.', $login_user)); } } } return $result; }