/** * Sets the users password. * * @param string $new New password. * @param string $old Current password. * @param string $authenticate Authenticate the old password before setting new. * * @return boolean True on success. * * @since 2.0 */ public function setPassword($new, $old = null, $authenticate = false) { if (is_null($this->_dn)) { $this->getId($authenticate); } elseif ($this->_dn instanceof Exception) { // Do not retry. Ldap configuration or user has problems. throw $this->_dn; } $hash = strtolower($this->client->passwordHash); $key = $this->getPassword(true); // Check if we need to authenticate and if so then do it if ($authenticate) { if (empty($old)) { throw new InvalidArgumentException(JText::_('LIB_SHUSERADAPTERSLDAP_ERR_10917', 10917)); } if (!$this->client->bind($this->_dn, $old)) { // Incorrect old password throw new InvalidArgumentException(JText::_('LIB_SHUSERADAPTERSLDAP_ERR_10918', 10918)); } } $password = $this->_genPassword($new); // Commit the Ldap password operation $this->client->replaceAttributes($this->_dn, array($key => $password)); // Update the password inside this adapter $this->updateCredential($new); return true; }
/** * @covers SHLdap::__get */ public function testMagicGetMethod() { $user = TestsHelper::getUserCreds('shaun.maunder'); $ldap = new SHLdap(TestsHelper::getLdapConfig(214)); $ldap->connect(); // Test Bind Status $this->assertEquals(SHLdap::AUTH_NONE, $ldap->bindStatus); $ldap->proxyBind(); $this->assertEquals(SHLdap::AUTH_PROXY, $ldap->bindStatus); $ldap->bind('asdasdas', 'asdasdas'); $this->assertEquals(SHLdap::AUTH_NONE, $ldap->bindStatus); $ldap->bind($user['dn'], $user['password']); $this->assertEquals(SHLdap::AUTH_USER, $ldap->bindStatus); // Rinse and Go $ldap = new SHLdap(TestsHelper::getLdapConfig(214)); $ldap->connect(); // Test Last User DN $this->assertNull($ldap->lastUserDn); $ldap->getUserDn($user['username'], $user['password']); $this->assertEquals($user['dn'], $ldap->lastUserDn); // Test All user Filter $this->assertEquals('(objectclass=user)', $ldap->allUserFilter); // Rinse and Go $ldap = new SHLdap(TestsHelper::getLdapConfig(216)); $ldap->connect(); // Test Key for Name Attribute $this->assertEquals('cn', $ldap->keyName); $this->assertEquals('mail', $ldap->keyEmail); $this->assertEquals('uid', $ldap->keyUid); $this->assertEquals('uid', $ldap->ldap_uid); // Test Information $this->assertEquals('ldap1.shmanic.net:389', $ldap->info); // Test something that doesn't exist $this->assertNull($ldap->doesntexist); }
/** * Get a users Ldap distinguished name with optional bind authentication. * * @param boolean $authenticate Attempt to authenticate the user (i.e. * bind the user with the password supplied) * * @return string User DN. * * @since 2.1 * @throws InvalidArgumentException Invalid argument in config related error * @throws SHLdapException Ldap specific error. * @throws SHExceptionInvaliduser User invalid error. */ private function _getDn($authenticate = false) { $replaced = str_replace(SHLdap::USERNAME_REPLACE, $this->username, $this->_userParams['user_query']); /* * A basic detection check for LDAP filter. * (i.e. distinguished names do not start and end with brackets). */ $useSearch = preg_match('/(?<!\\S)[\\(]([\\S]+)[\\)](?!\\S)/', $this->_userParams['user_query']) ? true : false; SHLog::add("Attempt to retrieve user distinguished name using '{$replaced}' " . ($useSearch ? ' with search.' : ' with direct bind.'), 102, JLog::DEBUG, 'ldap'); // Get a array of distinguished names from either the search or direct bind methods. $DNs = $useSearch ? $this->_getDnBySearch() : $this->_getDnDirect(); if (empty($DNs)) { /* * Cannot find the specified username. We are going to throw * a special user not found error to try to split between * configuration errors and invalid errors. However, this might * still be a configuration error. */ throw new SHExceptionInvaliduser(JText::_('LIB_SHLDAP_ERR_10302'), 10302, $this->username); } // Check if we have to authenticate the distinguished name with a password if ($authenticate) { // Attempt to bind each distinguished name with the specified password then return it foreach ($DNs as $dn) { if ($this->client->bind($dn, $this->password)) { // Successfully binded with this distinguished name SHLog::add("Successfully authenticated {$this->username} with distinguished name {$dn}.", 102, JLog::DEBUG, 'ldap'); return $dn; } } if ($useSearch) { // User found, but was unable to bind with the supplied password throw new SHExceptionInvaliduser(JText::_('LIB_SHLDAP_ERR_10303'), 10303, $this->username); } else { // Unable to bind directly to the given distinguished name parameters throw new SHExceptionInvaliduser(JText::_('LIB_SHLDAP_ERR_10304'), 10304, $this->username); } } else { $result = false; if ($useSearch) { /* We can be sure the distinguished name(s) exists in the Ldap * directory. However, we cannot be sure if the correct * distinguished name is returned for the specified user without * authenticating. Therefore, we have to assume the first (and * hopefully only) distinguished name is correct. * If the correct configuration has been given and the Ldap * directory is well organised, this will always be correct. */ $result = $DNs[0]; } else { /* Unlike searching, binding directly means we cannot be sure * if the distinguished name(s) exists in the Ldap directory. * Therefore, lets attempt to bind with a proxy user, then Ldap * read each distinguished name's entity to check if it exists. * If binding with the proxy user fails, then we have no option * but to assume the first distinguished name exists. */ if ($this->client->proxyBind()) { foreach ($DNs as $dn) { try { $read = $this->client->read($dn, null, array('dn')); } catch (Exception $e) { // We don't need to worry about the exception too much SHLog::add("Failed to read direct bind without auth DN {$dn}.", 102, JLog::DEBUG, 'ldap'); continue; } // Check if the distinguished name entity exists if ($read->countEntries() > 0) { // It exists so we assume this is the correct distinguished name. $result = $dn; break; } } if ($result === false) { // Failed to find any of the distinguished name(s) in the Ldap directory. throw new SHExceptionInvaliduser(JText::_('LIB_SHLDAP_ERR_10305'), 10305, $this->username); } } else { // Unable to check Ldap directory, so have to assume the first is correct $result = $DNs[0]; } } SHLog::add("Using distinguished name {$result} for user {$this->username}.", 102, JLog::DEBUG, 'ldap'); return $result; } }