sHostName = $sHostName; $this->sUserDnFormat = $sUserDnFormat; $this->sPasswordField = $sPasswordField; $this->sPasswordEncType = $sPasswordEncType; return $this; } /** * @param string $sAllowedEmails * * @return \ChangePasswordLdapDriver */ public function SetAllowedEmails($sAllowedEmails) { $this->sAllowedEmails = $sAllowedEmails; return $this; } /** * @param \MailSo\Log\Logger $oLogger * * @return \ChangePasswordLdapDriver */ public function SetLogger($oLogger) { if ($oLogger instanceof \MailSo\Log\Logger) { $this->oLogger = $oLogger; } return $this; } /** * @param \RainLoop\Account $oAccount * * @return bool */ public function PasswordChangePossibility($oAccount) { return $oAccount && $oAccount->Email() && \RainLoop\Plugins\Helper::ValidateWildcardValues($oAccount->Email(), $this->sAllowedEmails); } /** * @param \RainLoop\Model\Account $oAccount * @param string $sPrevPassword * @param string $sNewPassword * * @return bool */ public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword) { $bResult = false; try { $sDomain = \MailSo\Base\Utils::GetDomainFromEmail($oAccount->Email()); $sUserDn = \strtr($this->sUserDnFormat, array( '{domain}' => $sDomain, '{domain:dc}' => 'dc='.\strtr($sDomain, array('.' => ',dc=')), '{email}' => $oAccount->Email(), '{email:user}' => \MailSo\Base\Utils::GetAccountNameFromEmail($oAccount->Email()), '{email:domain}' => $sDomain, '{login}' => $oAccount->Login(), '{imap:login}' => $oAccount->Login(), '{imap:host}' => $oAccount->DomainIncHost(), '{imap:port}' => $oAccount->DomainIncPort() )); $oCon = @\ldap_connect($this->sHostName); if ($oCon) { @\ldap_set_option($oCon, LDAP_OPT_PROTOCOL_VERSION, 3); if (!@\ldap_bind($oCon, $sUserDn, $sPrevPassword)) { if ($this->oLogger) { $sError = $oCon ? @\ldap_error($oCon) : ''; $iErrno = $oCon ? @\ldap_errno($oCon) : 0; $this->oLogger->Write('ldap_bind error: '.$sError.' ('.$iErrno.')', \MailSo\Log\Enumerations\Type::WARNING, 'LDAP'); } return false; } } $sEncodedNewPassword = $sNewPassword; switch (\strtolower($this->sPasswordEncType)) { case 'sha': switch (true) { default: case \function_exists('sha1'): $sEncodedNewPassword = '{SHA}'.\base64_encode(\pack('H*', \sha1($sNewPassword))); break; case \function_exists('hash'): $sEncodedNewPassword = '{SHA}'.\base64_encode(\hash('sha1', $sNewPassword, true)); break; case \function_exists('mhash') && defined('MHASH_SHA1'): $sEncodedNewPassword = '{SHA}'.\base64_encode(\mhash(MHASH_SHA1, $sNewPassword)); break; } break; case 'md5': $sEncodedNewPassword = '{MD5}'.\base64_encode(\pack('H*', \md5($sNewPassword))); break; case 'crypt': $sEncodedNewPassword = '{CRYPT}'.\crypt($sNewPassword, $this->getSalt(2)); break; } $aEntry = array(); $aEntry[$this->sPasswordField] = (string) $sEncodedNewPassword; if (!!@\ldap_modify($oCon, $sUserDn, $aEntry)) { $bResult = true; } else { if ($this->oLogger) { $sError = $oCon ? @\ldap_error($oCon) : ''; $iErrno = $oCon ? @\ldap_errno($oCon) : 0; $this->oLogger->Write('ldap_modify error: '.$sError.' ('.$iErrno.')', \MailSo\Log\Enumerations\Type::WARNING, 'LDAP'); } } } catch (\Exception $oException) { if ($this->oLogger) { $this->oLogger->WriteException($oException, \MailSo\Log\Enumerations\Type::WARNING, 'LDAP'); } $bResult = false; } return $bResult; } /** * @param int $iLength * * @return string */ private function getSalt($iLength) { $sChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $iCharsLength = \strlen($sChars); $sResult = ''; while (\strlen($sResult) < $iLength) { $sResult .= \substr($sChars, \rand() % $iCharsLength, 1); } return $sResult; } }