Пример #1
1
 /**
  * Update the entry on the directory server
  *
  * This will evaluate all changes made so far and send them
  * to the directory server.
  * Please note, that if you make changes to objectclasses wich
  * have mandatory attributes set, update() will currently fail.
  * Remove the entry from the server and readd it as new in such cases.
  * This also will deal with problems with setting structural object classes.
  *
  * @param Net_LDAP2 $ldap If passed, a call to setLDAP() is issued prior update, thus switching the LDAP-server. This is for perl-ldap interface compliance
  *
  * @access public
  * @return true|Net_LDAP2_Error
  * @todo Entry rename with a DN containing special characters needs testing!
  */
 public function update($ldap = null)
 {
     if ($ldap) {
         $msg = $this->setLDAP($ldap);
         if (Net_LDAP2::isError($msg)) {
             return PEAR::raiseError('You passed an invalid $ldap variable to update()');
         }
     }
     // ensure we have a valid LDAP object
     $ldap =& $this->getLDAP();
     if (!$ldap instanceof Net_LDAP2) {
         return PEAR::raiseError("The entries LDAP object is not valid");
     }
     // Get and check link
     $link = $ldap->getLink();
     if (!is_resource($link)) {
         return PEAR::raiseError("Could not update entry: internal LDAP link is invalid");
     }
     /*
      * Delete the entry
      */
     if (true === $this->_delete) {
         return $ldap->delete($this);
     }
     /*
      * New entry
      */
     if (true === $this->_new) {
         $msg = $ldap->add($this);
         if (Net_LDAP2::isError($msg)) {
             return $msg;
         }
         $this->_new = false;
         $this->_changes['add'] = array();
         $this->_changes['delete'] = array();
         $this->_changes['replace'] = array();
         $this->_original = $this->_attributes;
         $return = true;
         return $return;
     }
     /*
      * Rename/move entry
      */
     if (false == is_null($this->_newdn)) {
         if ($ldap->getLDAPVersion() !== 3) {
             return PEAR::raiseError("Renaming/Moving an entry is only supported in LDAPv3");
         }
         // make dn relative to parent (needed for ldap rename)
         $parent = Net_LDAP2_Util::ldap_explode_dn($this->_newdn, array('casefolding' => 'none', 'reverse' => false, 'onlyvalues' => false));
         if (Net_LDAP2::isError($parent)) {
             return $parent;
         }
         $child = array_shift($parent);
         // maybe the dn consist of a multivalued RDN, we must build the dn in this case
         // because the $child-RDN is an array!
         if (is_array($child)) {
             $child = Net_LDAP2_Util::canonical_dn($child);
         }
         $parent = Net_LDAP2_Util::canonical_dn($parent);
         // rename/move
         if (false == @ldap_rename($link, $this->_dn, $child, $parent, true)) {
             return PEAR::raiseError("Entry not renamed: " . @ldap_error($link), @ldap_errno($link));
         }
         // reflect changes to local copy
         $this->_dn = $this->_newdn;
         $this->_newdn = null;
     }
     /*
      * Carry out modifications to the entry
      */
     // ADD
     foreach ($this->_changes["add"] as $attr => $value) {
         // if attribute exists, add new values
         if ($this->exists($attr)) {
             if (false === @ldap_mod_add($link, $this->dn(), array($attr => $value))) {
                 return PEAR::raiseError("Could not add new values to attribute {$attr}: " . @ldap_error($link), @ldap_errno($link));
             }
         } else {
             // new attribute
             if (false === @ldap_modify($link, $this->dn(), array($attr => $value))) {
                 return PEAR::raiseError("Could not add new attribute {$attr}: " . @ldap_error($link), @ldap_errno($link));
             }
         }
         // all went well here, I guess
         unset($this->_changes["add"][$attr]);
     }
     // DELETE
     foreach ($this->_changes["delete"] as $attr => $value) {
         // In LDAPv3 you need to specify the old values for deleting
         if (is_null($value) && $ldap->getLDAPVersion() === 3) {
             $value = $this->_original[$attr];
         }
         if (false === @ldap_mod_del($link, $this->dn(), array($attr => $value))) {
             return PEAR::raiseError("Could not delete attribute {$attr}: " . @ldap_error($link), @ldap_errno($link));
         }
         unset($this->_changes["delete"][$attr]);
     }
     // REPLACE
     foreach ($this->_changes["replace"] as $attr => $value) {
         if (false === @ldap_modify($link, $this->dn(), array($attr => $value))) {
             return PEAR::raiseError("Could not replace attribute {$attr} values: " . @ldap_error($link), @ldap_errno($link));
         }
         unset($this->_changes["replace"][$attr]);
     }
     // all went well, so _original (server) becomes _attributes (local copy)
     $this->_original = $this->_attributes;
     $return = true;
     return $return;
 }
Пример #2
0
 /**
  * Writes a DN to the filehandle
  *
  * @param string $dn DN to write
  *
  * @access protected
  * @return void
  */
 protected function writeDN($dn)
 {
     // prepare DN
     if ($this->_options['encode'] == 'base64') {
         $dn = $this->convertDN($dn) . PHP_EOL;
     } elseif ($this->_options['encode'] == 'canonical') {
         $dn = Net_LDAP2_Util::canonical_dn($dn, array('casefold' => 'none')) . PHP_EOL;
     } else {
         $dn = $dn . PHP_EOL;
     }
     $this->writeLine($dn, 'Net_LDAP2_LDIF error: unable to write DN of entry ' . $this->_entrynum);
 }
Пример #3
0
 /**
  * Tells if a DN does exist in the directory
  *
  * @param string|Net_LDAP2_Entry $dn The DN of the object to test
  *
  * @return boolean|Net_LDAP2_Error
  */
 public function dnExists($dn)
 {
     if (PEAR::isError($dn)) {
         return $dn;
     }
     if ($dn instanceof Net_LDAP2_Entry) {
         $dn = $dn->dn();
     }
     if (false === is_string($dn)) {
         return PEAR::raiseError('Parameter $dn is not a string nor an entry object!');
     }
     // make dn relative to parent
     $base = Net_LDAP2_Util::ldap_explode_dn($dn, array('casefold' => 'none', 'reverse' => false, 'onlyvalues' => false));
     if (self::isError($base)) {
         return $base;
     }
     $entry_rdn = array_shift($base);
     if (is_array($entry_rdn)) {
         // maybe the dn consist of a multivalued RDN, we must build the dn in this case
         // because the $entry_rdn is an array!
         $filter_dn = Net_LDAP2_Util::canonical_dn($entry_rdn);
     }
     $base = Net_LDAP2_Util::canonical_dn($base);
     $result = @ldap_list($this->_link, $base, $entry_rdn, array(), 1, 1);
     if (@ldap_count_entries($this->_link, $result)) {
         return true;
     }
     if (ldap_errno($this->_link) == 32) {
         return false;
     }
     if (ldap_errno($this->_link) != 0) {
         return PEAR::raiseError(ldap_error($this->_link), ldap_errno($this->_link));
     }
     return false;
 }
Пример #4
0
 /**
  * Retrieve this leaf-filters attribute, match and value component.
  *
  * For leaf filters, this returns array(attr, match, value).
  * Match is be the logical operator, not the text representation,
  * eg "=" instead of "equals". Note that some operators are really
  * a combination of operator+value with wildcard, like
  * "begins": That will return "=" with the value "value*"!
  *
  * For non-leaf filters this will drop an error.
  *
  * @todo $this->_match is not always available and thus not usable here; it would be great if it would set in the factory methods and constructor.
  * @return array|Net_LDAP2_Error
  */
 function getComponents()
 {
     if ($this->isLeaf()) {
         $raw_filter = preg_replace('/^\\(|\\)$/', '', $this->_filter);
         $parts = Net_LDAP2_Util::split_attribute_string($raw_filter, true, true);
         if (count($parts) != 3) {
             return PEAR::raiseError("Net_LDAP2_Filter getComponents() error: invalid filter syntax - unknown matching rule used");
         } else {
             return $parts;
         }
     } else {
         return PEAR::raiseError('Net_LDAP2_Filter getComponents() call is invalid for non-leaf filters!');
     }
 }
Пример #5
0
 /**
  * This can be used to escape a string to provide a valid LDAP-Filter.
  *
  * LDAP will only recognise certain characters as the
  * character istself if they are properly escaped. This is
  * what this method does.
  * The method can be called statically, so you can use it outside
  * for your own purposes (eg for escaping only parts of strings)
  *
  * In fact, this is just a shorthand to {@link Net_LDAP2_Util::escape_filter_value()}.
  * For upward compatibiliy reasons you are strongly encouraged to use the escape
  * methods provided by the Net_LDAP2_Util class.
  *
  * @param string $value Any string who should be escaped
  *
  * @static
  * @return string         The string $string, but escaped
  * @deprecated  Do not use this method anymore, instead use Net_LDAP2_Util::escape_filter_value() directly
  */
 public static function escape($value)
 {
     $return = Net_LDAP2_Util::escape_filter_value(array($value));
     return $return[0];
 }
Пример #6
0
 /**
  * Update the entry on the directory server
  *
  * This will evaluate all changes made so far and send them
  * to the directory server.
  * Please note, that if you make changes to objectclasses wich
  * have mandatory attributes set, update() will currently fail.
  * Remove the entry from the server and readd it as new in such cases.
  * This also will deal with problems with setting structural object classes.
  *
  * @param Net_LDAP2 $ldap If passed, a call to setLDAP() is issued prior update, thus switching the LDAP-server. This is for perl-ldap interface compliance
  *
  * @access public
  * @return true|Net_LDAP2_Error
  * @todo Entry rename with a DN containing special characters needs testing!
  */
 public function update($ldap = null)
 {
     if ($ldap) {
         $msg = $this->setLDAP($ldap);
         if (Net_LDAP2::isError($msg)) {
             return PEAR::raiseError('You passed an invalid $ldap variable to update()');
         }
     }
     // ensure we have a valid LDAP object
     $ldap = $this->getLDAP();
     if (!$ldap instanceof Net_LDAP2) {
         return PEAR::raiseError("The entries LDAP object is not valid");
     }
     // Get and check link
     $link = $ldap->getLink();
     if (!is_resource($link)) {
         return PEAR::raiseError("Could not update entry: internal LDAP link is invalid");
     }
     /*
      * Delete the entry
      */
     if (true === $this->_delete) {
         return $ldap->delete($this);
     }
     /*
      * New entry
      */
     if (true === $this->_new) {
         $msg = $ldap->add($this);
         if (Net_LDAP2::isError($msg)) {
             return $msg;
         }
         $this->_new = false;
         $this->_changes['add'] = array();
         $this->_changes['delete'] = array();
         $this->_changes['replace'] = array();
         $this->_original = $this->_attributes;
         // In case the "new" entry was moved after creation, we must
         // adjust the internal DNs as the entry was already created
         // with the most current DN.
         if (false == is_null($this->_newdn)) {
             $this->_dn = $this->_newdn;
             $this->_newdn = null;
         }
         $return = true;
         return $return;
     }
     /*
      * Rename/move entry
      */
     if (false == is_null($this->_newdn)) {
         if ($ldap->getLDAPVersion() !== 3) {
             return PEAR::raiseError("Renaming/Moving an entry is only supported in LDAPv3");
         }
         // make dn relative to parent (needed for ldap rename)
         $parent = Net_LDAP2_Util::ldap_explode_dn($this->_newdn, array('casefolding' => 'none', 'reverse' => false, 'onlyvalues' => false));
         if (Net_LDAP2::isError($parent)) {
             return $parent;
         }
         $child = array_shift($parent);
         // maybe the dn consist of a multivalued RDN, we must build the dn in this case
         // because the $child-RDN is an array!
         if (is_array($child)) {
             $child = Net_LDAP2_Util::canonical_dn($child);
         }
         $parent = Net_LDAP2_Util::canonical_dn($parent);
         // rename/move
         if (false == @ldap_rename($link, $this->_dn, $child, $parent, false)) {
             return PEAR::raiseError("Entry not renamed: " . @ldap_error($link), @ldap_errno($link));
         }
         // reflect changes to local copy
         $this->_dn = $this->_newdn;
         $this->_newdn = null;
     }
     /*
      * Retrieve a entry that has all attributes we need so that the list of changes to build is created accurately
      */
     $fullEntry = $ldap->getEntry($this->dn());
     if (Net_LDAP2::isError($fullEntry)) {
         return PEAR::raiseError("Could not retrieve a full set of attributes to reconcile changes with");
     }
     $modifications = array();
     // ADD
     foreach ($this->_changes["add"] as $attr => $value) {
         // if attribute exists, we need to combine old and new values
         if ($fullEntry->exists($attr)) {
             $currentValue = $fullEntry->getValue($attr, "all");
             $value = array_merge($currentValue, $value);
         }
         $modifications[$attr] = $value;
     }
     // DELETE
     foreach ($this->_changes["delete"] as $attr => $value) {
         // In LDAPv3 you need to specify the old values for deleting
         if (is_null($value) && $ldap->getLDAPVersion() === 3) {
             $value = $fullEntry->getValue($attr);
         }
         if (!is_array($value)) {
             $value = array($value);
         }
         // Find out what is missing from $value and exclude it
         $currentValue = isset($modifications[$attr]) ? $modifications[$attr] : $fullEntry->getValue($attr, "all");
         $modifications[$attr] = array_values(array_diff($currentValue, $value));
     }
     // REPLACE
     foreach ($this->_changes["replace"] as $attr => $value) {
         $modifications[$attr] = $value;
     }
     // COMMIT
     if (false === @ldap_modify($link, $this->dn(), $modifications)) {
         return PEAR::raiseError("Could not modify the entry: " . @ldap_error($link), @ldap_errno($link));
     }
     // all went well, so _original (server) becomes _attributes (local copy), reset _changes too...
     $this->_changes['add'] = array();
     $this->_changes['delete'] = array();
     $this->_changes['replace'] = array();
     $this->_original = $this->_attributes;
     $return = true;
     return $return;
 }
Пример #7
0
 /**
  * Tell if a DN does exist in the directory
  *
  * @param string $dn The DN of the object to test
  *
  * @return boolean|Net_LDAP2_Error
  */
 public function dnExists($dn)
 {
     if (!is_string($dn)) {
         return PEAR::raiseError('$dn is expected to be a string but is ' . gettype($dn) . ' ' . get_class($dn));
     }
     // make dn relative to parent
     $base = Net_LDAP2_Util::ldap_explode_dn($dn, array('casefold' => 'none', 'reverse' => false, 'onlyvalues' => false));
     if (self::isError($base)) {
         return $base;
     }
     $entry_rdn = array_shift($base);
     if (is_array($entry_rdn)) {
         // maybe the dn consist of a multivalued RDN, we must build the dn in this case
         // because the $entry_rdn is an array!
         $filter_dn = Net_LDAP2_Util::canonical_dn($entry_rdn);
     }
     $base = Net_LDAP2_Util::canonical_dn($base);
     $result = @ldap_list($this->_link, $base, $entry_rdn, array(), 1, 1);
     if (@ldap_count_entries($this->_link, $result)) {
         return true;
     }
     if (ldap_errno($this->_link) == 32) {
         return false;
     }
     if (ldap_errno($this->_link) != 0) {
         return PEAR::raiseError(ldap_error($this->_link), ldap_errno($this->_link));
     }
     return false;
 }
Пример #8
0
 /**
  * Test if split_attribute_string() works
  */
 public function testSplitAttributeString()
 {
     // test default behavour
     $this->assertEquals(array('fooAttr', 'barValue'), Net_LDAP2_Util::split_attribute_string("fooAttr=barValue"));
     $this->assertEquals(array('fooAttr', '=barValue'), Net_LDAP2_Util::split_attribute_string("fooAttr==barValue"));
     $this->assertEquals(array('fooAttr', 'bar=Value'), Net_LDAP2_Util::split_attribute_string("fooAttr=bar=Value"));
     $this->assertEquals(array('foo\\=Attr', 'barValue'), Net_LDAP2_Util::split_attribute_string("foo\\=Attr=barValue"));
     $this->assertEquals(array('fooAttr', 'bar\\=Value'), Net_LDAP2_Util::split_attribute_string("fooAttr=bar\\=Value"));
     // test default behaviour with delim
     $this->assertEquals(array('fooAttr', '=', 'barValue'), Net_LDAP2_Util::split_attribute_string("fooAttr=barValue", false, true));
     $this->assertEquals(array('fooAttr', '=', '=barValue'), Net_LDAP2_Util::split_attribute_string("fooAttr==barValue", false, true));
     $this->assertEquals(array('fooAttr', '=', 'bar=Value'), Net_LDAP2_Util::split_attribute_string("fooAttr=bar=Value", false, true));
     $this->assertEquals(array('foo\\=Attr', '=', 'barValue'), Net_LDAP2_Util::split_attribute_string("foo\\=Attr=barValue", false, true));
     // test basic extended splitting and delimter return
     $test_delimeters = array('=', '~=', '>', '>=', '<', '<=');
     foreach ($test_delimeters as $td) {
         // default behavior with simple parameters
         $this->assertEquals(array('fooAttr', 'barValue'), Net_LDAP2_Util::split_attribute_string("fooAttr{$td}barValue", true), "AttrString='fooAttr{$td}barValue'; sep='{$td}'");
         $this->assertEquals(array('fooAttr', 'barValue'), Net_LDAP2_Util::split_attribute_string("fooAttr{$td}barValue", true, false));
         // test proper escaping
         $tde = addcslashes($td, '=~><');
         $this->assertEquals(array("foo{$tde}Attr", 'barValue'), Net_LDAP2_Util::split_attribute_string("foo{$tde}Attr{$td}barValue", true));
     }
     // negative test case: perform no split
     $this->assertEquals(array('fooAttr barValue'), Net_LDAP2_Util::split_attribute_string('fooAttr barValue'));
     $this->assertEquals(array('fooAttr barValue'), Net_LDAP2_Util::split_attribute_string('fooAttr barValue', true, true));
     $this->assertEquals(array('fooAttr>barValue'), Net_LDAP2_Util::split_attribute_string('fooAttr>barValue'));
     // extended splitting used, but not activated
     // negative testcase: wrong escaping used
     $this->assertEquals(array('fooAttr\\>', 'barValue'), Net_LDAP2_Util::split_attribute_string('fooAttr\\>=barValue', false, false));
     $this->assertEquals(array('fooAttr\\>', '=', 'barValue'), Net_LDAP2_Util::split_attribute_string('fooAttr\\>=barValue', true, true));
     $this->assertEquals(array('fooAttr', '>', '\\=barValue'), Net_LDAP2_Util::split_attribute_string('fooAttr>\\=barValue', true, true));
     $this->assertEquals(array('fooAttr\\>\\=barValue'), Net_LDAP2_Util::split_attribute_string('fooAttr\\>\\=barValue', true, true));
 }
Пример #9
0
 /**
  * Execute a LDAP query stement and fetch all results.
  *
  * @param mixed  $query      The SQL query as a string or an array.
  * @param string $configPath The config path; used for exception messages.
  *
  * @return array An array of records.
  * @throws XML_Query2XML_LDAP2Exception If Net_LDAP2::search() returns an error.
  * @see XML_Query2XML_Driver::getAllRecords()
  */
 public function getAllRecords($query, $configPath)
 {
     $base = null;
     $filter = null;
     $options = array();
     if (isset($query['base'])) {
         $base = $query['base'];
     }
     if (isset($query['filter'])) {
         $filter = $query['filter'];
     }
     if (isset($query['options'])) {
         $options = $query['options'];
     }
     if (isset($options['query2xml_placeholder'])) {
         $placeholder = $options['query2xml_placeholder'];
     } else {
         $placeholder = '?';
     }
     unset($options['query2xml_placeholder']);
     if (isset($query['data']) && is_array($query['data'])) {
         $data = Net_LDAP2_Util::escape_filter_value($query['data']);
         $base = self::_replacePlaceholders($base, $data, $placeholder);
         if (is_string($filter)) {
             $filter = self::_replacePlaceholders($filter, $data, $placeholder);
         }
     }
     $search = $this->_ldap->search($base, $filter, $options);
     if (PEAR::isError($search)) {
         /*
          * unit test: getXML/throwLDAPException_queryError.phpt
          */
         throw new XML_Query2XML_LDAP2Exception($configPath . ': Could not run LDAP search query: ' . $search->toString());
     }
     $records = array();
     $entries = $search->entries();
     foreach ($entries as $key => $entry) {
         $records[] = $entry->getValues();
     }
     $search->done();
     $records = self::_processMultiValueAttributes($records);
     // set missing attriubtes to null
     if (isset($options['attributes']) && is_array($options['attributes'])) {
         foreach ($options['attributes'] as $attribute) {
             for ($i = 0; $i < count($records); $i++) {
                 if (!array_key_exists($attribute, $records[$i])) {
                     $records[$i][$attribute] = null;
                 }
             }
         }
     }
     return $records;
 }
Пример #10
0
 /**
  * Main Authentication method
  * Required for plugin interface 
  * @param unknown $login  User's username
  * @param unknown $password User's password
  * @return boolean
  */
 function authenticate($login, $password)
 {
     if ($login && $password) {
         if (!function_exists('ldap_connect')) {
             trigger_error('auth_ldap requires PHP\'s PECL LDAP package installed.');
             return FALSE;
         }
         if (!(require_once 'Net/LDAP2.php')) {
             trigger_error('auth_ldap requires the PEAR package Net::LDAP2');
             return FALSE;
         }
         /**
               Loading configuration 
               **/
         $this->_debugMode = defined('LDAP_AUTH_DEBUG') ? LDAP_AUTH_DEBUG : FALSE;
         $this->_anonBeforeBind = defined('LDAP_AUTH_ANONYMOUSBEFOREBIND') ? LDAP_AUTH_ANONYMOUSBEFOREBIND : FALSE;
         $this->_serviceBindDN = defined('LDAP_AUTH_BINDDN') ? LDAP_AUTH_BINDDN : null;
         $this->_serviceBindPass = defined('LDAP_AUTH_BINDPW') ? LDAP_AUTH_BINDPW : null;
         $this->_baseDN = defined('LDAP_AUTH_BASEDN') ? LDAP_AUTH_BASEDN : null;
         if (!defined('LDAP_AUTH_BASEDN')) {
             $this->_log('LDAP_AUTH_BASEDN is required and not defined.', E_USER_ERROR);
             return FALSE;
         } else {
             $this->_baseDN = LDAP_AUTH_BASEDN;
         }
         $parsedURI = parse_url(LDAP_AUTH_SERVER_URI);
         if ($parsedURI === FALSE) {
             $this->_log('Could not parse LDAP_AUTH_SERVER_URI in config.php', E_USER_ERROR);
             return FALSE;
         }
         $this->_host = $parsedURI['host'];
         $this->_scheme = $parsedURI['scheme'];
         if (is_int($parsedURI['port'])) {
             $this->_port = $parsedURI['port'];
         } else {
             $this->_port = $this->_scheme === 'ldaps' ? 636 : 389;
         }
         $this->_useTLS = defined('LDAP_AUTH_USETLS') ? LDAP_AUTH_USETLS : FALSE;
         $this->_allowUntrustedCerts = defined('LDAP_AUTH_ALLOW_UNTRUSTED_CERT') ? LDAP_AUTH_ALLOW_UNTRUSTED_CERT : FALSE;
         $this->_schemaCacheEnable = defined('LDAP_AUTH_SCHEMA_CACHE_ENABLE') ? LDAP_AUTH_SCHEMA_CACHE_ENABLE : TRUE;
         $this->_schemaCacheTimeout = defined('LDAP_AUTH_SCHEMA_CACHE_TIMEOUT') ? LDAP_AUTH_SCHEMA_CACHE_TIMEOUT : 86400;
         $this->_logAttempts = defined('LDAP_AUTH_LOG_ATTEMPTS') ? LDAP_AUTH_LOG_ATTEMPTS : FALSE;
         $this->_ldapLoginAttrib = defined('LDAP_AUTH_LOGIN_ATTRIB') ? LDAP_AUTH_LOGIN_ATTRIB : null;
         /**
               Building LDAP connection
               **/
         $ldapConnParams = array('host' => $this->_scheme . '://' . $this->_host, 'options' => array('LDAP_OPT_REFERRALS' => 0), 'basedn' => $this->_baseDN, 'port' => $this->_port, 'starttls' => $this->_useTLS);
         if (!$this->_anonBeforeBind) {
             $ldapConnParams['binddn'] = $this->_serviceBindDN;
             $ldapConnParams['bindpw'] = $this->_serviceBindPass;
         }
         if ($this->_allowUntrustedCerts) {
             putenv('LDAPTLS_REQCERT=never');
         }
         if ($this->_debugMode) {
             $this->_log(print_r($ldapConnParams, TRUE), E_USER_NOTICE);
         }
         $ldapConn = Net_LDAP2::connect($ldapConnParams);
         if (get_class($ldapConn) !== 'Net_LDAP2') {
             $this->_log('Could not connect to LDAP Server: ' . $ldapConn->getMessage() . ' with ' . $this->_getBindDNWord(), E_USER_ERROR);
             return FALSE;
         } else {
             $this->ldapObj = $ldapConn;
             $this->_log('Connected to LDAP Server: ' . LDAP_AUTH_SERVER_URI . ' with ' . $this->_getBindDNWord());
         }
         // Bind with service account if orignal connexion was anonymous
         if ($this->_anonBeforeBind && strlen($this->_bindDN > 0)) {
             $binding = $this->ldapObj->bind($this->_serviceBindDN, $this->_serviceBindPass);
             if (get_class($binding) !== 'Net_LDAP2') {
                 $this->_log('Cound not bind service account: ' . $binding->getMessage(), E_USER_ERROR);
                 return FALSE;
             } else {
                 $this->_log('Bind with ' . $this->_serviceBindDN . ' successful.', E_USER_NOTICE);
             }
         }
         //Cache LDAP Schema
         if ($ldapSchemaCacheEnable) {
             $this->_getSchemaCache();
         }
         //Validate BaseDN
         $baseDNObj = $this->ldapObj->getEntry($this->_baseDN);
         if (get_class($baseDNObj) !== 'Net_LDAP2_Entry') {
             $this->_log('Cound not get LDAP_AUTH_BASEDN.  Please check config.php', E_USER_ERROR);
             //return FALSE;
         }
         //Searching for user
         $escapedUserName = Net_LDAP2_Util::escape_filter_value(array($login));
         $completedSearchFilter = str_replace('???', $escapedUserName[0], LDAP_AUTH_SEARCHFILTER);
         $filterObj = Net_LDAP2_Filter::parse($completedSearchFilter);
         if (get_class($filterObj) !== 'Net_LDAP2_Filter') {
             $this->_log('Could not parse LDAP Search filter', E_USER_ERROR);
             return FALSE;
         }
         if ($this->_debugMode) {
             $this->_log("Seaching for user {$login} with this query " . $filterObj->asString() . ' within ' . $this->_baseDN);
         }
         $searchResults = $this->ldapObj->search($this->_baseDN, $filterObj);
         if (get_class($searchResults) !== 'Net_LDAP2_Search') {
             $this->_log('LDAP Search Failed: ' . $searchResults->getMessage(), E_USER_ERROR);
             return FALSE;
         } elseif ($searchResults->count() === 0) {
             $this->_log((string) $login, 'Unknown User', E_USER_NOTICE);
             return FALSE;
         } elseif ($searchResults->count() > 1) {
             $this->_log('Multiple DNs found for username ' . (string) $login, E_USER_WARNING);
             return FALSE;
         }
         //Getting user's DN from search
         $userEntry = $searchResults->shiftEntry();
         $userDN = $userEntry->dn();
         //Binding with user's DN.
         if ($this->_debugMode) {
             $this->_log('Try to bind with user\'s DN: ' . $userDN);
         }
         $loginAttempt = $this->ldapObj->bind($userDN, $password);
         if ($loginAttempt === TRUE) {
             $this->_log('User: '******' authentication successful');
             if (strlen($this->_ldapLoginAttrib) > 0) {
                 if ($this->_debugMode) {
                     $this->_log('Looking up TT-RSS username attribute in ' . $this->_ldapLoginAttrib);
                 }
                 $ttrssUsername = $userEntry->getValue($this->_ldapLoginAttrib, 'single');
                 $this->ldapObj->disconnect();
                 if (!is_string($ttrssUsername)) {
                     $this->_log('Could not find user name attribute ' . $this->_ldapLoginAttrib . ' in LDAP entry', E_USER_WARNING);
                     return FALSE;
                 }
                 return $this->base->auto_create_user($ttrssUsername);
             } else {
                 $this->ldapObj->disconnect();
                 return $this->base->auto_create_user($login);
             }
         } elseif ($loginAttempt->getCode() == 49) {
             $this->ldapObj->disconnect();
             $this->_log('User: '******' authentication failed');
             return FALSE;
         } else {
             $this->ldapObj->disconnect();
             $this->_log('Unknown Error: Code: ' . $loginAttempt->getCode() . ' Message: ' . $loginAttempt->getMessage() . ' user(' . (string) $login . ')', E_USER_WARNING);
             return FALSE;
         }
     }
     return false;
 }