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;
 }