/** * _authenticateValidateResult() - This method attempts to validate that the record in the * result set is indeed a record that matched the identity provided to this adapter. * * @param array $resultIdentity * @return Zend_Auth_Result */ protected function _authenticateValidateResult($resultIdentity) { $passwordHash = substr($resultIdentity[$this->_credentialColumn], 0, 1) === '{' ? $resultIdentity[$this->_credentialColumn] : '{PLAIN-MD5}' . $resultIdentity[$this->_credentialColumn]; if (Hash_Password::validate($passwordHash, $this->_credential) !== true) { $this->_authenticateResultInfo['code'] = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID; $this->_authenticateResultInfo['messages'][] = 'Supplied credential is invalid.'; return $this->_authenticateCreateAuthResult(); } unset($resultIdentity['zend_auth_credential_match']); $this->_resultRow = $resultIdentity; $this->_authenticateResultInfo['code'] = Zend_Auth_Result::SUCCESS; $this->_authenticateResultInfo['messages'][] = 'Authentication successful.'; return $this->_authenticateCreateAuthResult(); }
/** * set the password for given account * * @param string $_userId * @param string $_password * @param bool $_encrypt encrypt password * @param bool $_mustChange * @return void * @throws Tinebase_Exception_InvalidArgument */ public function setPassword($_userId, $_password, $_encrypt = TRUE, $_mustChange = null) { if ($this->_isReadOnlyBackend) { return; } $user = $_userId instanceof Tinebase_Model_FullUser ? $_userId : $this->getFullUserById($_userId); $this->checkPasswordPolicy($_password, $user); $metaData = $this->_getMetaData($user); $encryptionType = isset($this->_options['pwEncType']) ? $this->_options['pwEncType'] : Tinebase_User_Abstract::ENCRYPT_SSHA; $userpassword = $_encrypt && $encryptionType !== Tinebase_User_Abstract::ENCRYPT_PLAIN ? Hash_Password::generate($encryptionType, $_password) : $_password; $ldapData = array('userpassword' => $userpassword, 'shadowlastchange' => floor(Tinebase_DateTime::now()->getTimestamp() / 86400)); foreach ($this->_ldapPlugins as $plugin) { $plugin->inspectSetPassword($user, $_password, $_encrypt, $_mustChange, $ldapData); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' $dn: ' . $metaData['dn']); } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' $ldapData: ' . print_r($ldapData, true)); } $this->_ldap->update($metaData['dn'], $ldapData); // update last modify timestamp in sql backend too $values = array('last_password_change' => Tinebase_DateTime::now()->get(Tinebase_Record_Abstract::ISO8601LONG)); $where = array($this->_db->quoteInto($this->_db->quoteIdentifier('id') . ' = ?', $user->getId())); $this->_db->update(SQL_TABLE_PREFIX . 'accounts', $values, $where); $this->_setPluginsPassword($user->getId(), $_password, $_encrypt); }
/** * returns array of raw Dbmail data * * @param Tinebase_Model_EmailUser $_user * @param Tinebase_Model_EmailUser $_newUserProperties * @return array */ protected function _recordToRawData(Tinebase_Model_FullUser $_user, Tinebase_Model_FullUser $_newUserProperties) { $rawData = array(); foreach ($_newUserProperties->imapUser as $key => $value) { $property = isset($this->_propertyMapping[$key]) || array_key_exists($key, $this->_propertyMapping) ? $this->_propertyMapping[$key] : false; if ($property && !in_array($key, $this->_readOnlyFields)) { switch ($key) { case 'emailPassword': $rawData[$property] = Hash_Password::generate($this->_config['emailScheme'], $value, false); $rawData[$this->_propertyMapping['emailScheme']] = $this->_config['emailScheme']; break; case 'emailUserId': case 'emailGID': case 'emailUsername': // do nothing break; case 'emailMailQuota': case 'emailMailSize': case 'emailSieveQuota': case 'emailSieveSize': // convert to bytes $rawData[$property] = Tinebase_Helper::convertToBytes($value . 'M'); break; default: $rawData[$property] = $value; } } } $rawData[$this->_propertyMapping['emailUserId']] = $this->_hasTine20Userid === true ? $_user->getId() : $this->_convertToInt($_user->getId()); if ($this->_hasTine20Userid === true) { $rawData[$this->_propertyMapping['emailGID']] = $this->_config['emailGID']; $rawData['client_idnr'] = $this->_convertToInt($this->_config['emailGID']); } else { $rawData[$this->_propertyMapping['emailGID']] = $this->_convertToInt($this->_config['emailGID']); } $rawData[$this->_propertyMapping['emailUsername']] = $this->_appendDomain($_user->accountLoginName); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($rawData, TRUE)); } return $rawData; }
/** * returns array of raw Dovecot data * * @param Tinebase_Model_FullUser $_user * @param Tinebase_Model_FullUser $_newUserProperties * @return array */ protected function _recordToRawData(Tinebase_Model_FullUser $_user, Tinebase_Model_FullUser $_newUserProperties) { $rawData = array(); if (isset($_newUserProperties->imapUser)) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($_newUserProperties->imapUser->toArray(), true)); } foreach ($_newUserProperties->imapUser as $key => $value) { $property = isset($this->_propertyMapping[$key]) || array_key_exists($key, $this->_propertyMapping) ? $this->_propertyMapping[$key] : false; if ($property && !in_array($key, $this->_readOnlyFields)) { switch ($key) { case 'emailUserId': case 'emailUsername': // do nothing break; case 'emailPassword': $rawData[$property] = Hash_Password::generate($this->_config['emailScheme'], $value); break; case 'emailUID': $rawData[$property] = !empty($this->_config['uid']) ? $this->_config['uid'] : $value; break; case 'emailGID': $rawData[$property] = !empty($this->_config['gid']) ? $this->_config['gid'] : $value; break; case 'emailMailQuota': $rawData[$property] = empty($value) ? 0 : $value; break; default: $rawData[$property] = $value; break; } } } } foreach (array('uid', 'gid') as $key) { if (!(isset($rawData[$key]) || array_key_exists($key, $rawData))) { $rawData[$key] = $this->_config[$key]; } } $rawData[$this->_propertyMapping['emailUserId']] = $_user->getId(); if ($this->_config['domain'] !== null) { $emailUsername = $this->_appendDomain($_user->accountLoginName); } else { $emailUsername = $_newUserProperties->accountEmailAddress; } list($localPart, $domain) = explode('@', $emailUsername, 2); $rawData['domain'] = $domain; // replace home wildcards when storing to db // %d = domain // %n = user // %u == user@domain $search = array('%n', '%d', '%u'); $replace = array($localPart, $domain, $emailUsername); $rawData[$this->_propertyMapping['emailHome']] = str_replace($search, $replace, $this->_config['emailHome']); $rawData[$this->_propertyMapping['emailUsername']] = $emailUsername; if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($rawData, true)); } return $rawData; }
/** * set the password for given account * * @param string $_userId * @param string $_password * @param bool $_encrypt encrypt password * @param bool $_mustChange * @return void * @throws Tinebase_Exception_InvalidArgument */ public function setPassword($_userId, $_password, $_encrypt = TRUE, $_mustChange = null) { $userId = $_userId instanceof Tinebase_Model_User ? $_userId->getId() : $_userId; $user = $_userId instanceof Tinebase_Model_FullUser ? $_userId : $this->getFullUserById($userId); $this->checkPasswordPolicy($_password, $user); $accountsTable = new Tinebase_Db_Table(array('name' => SQL_TABLE_PREFIX . 'accounts')); $accountData['password'] = $_encrypt ? Hash_Password::generate('SSHA256', $_password) : $_password; $accountData['last_password_change'] = Tinebase_DateTime::now()->get(Tinebase_Record_Abstract::ISO8601LONG); $where = array($accountsTable->getAdapter()->quoteInto($accountsTable->getAdapter()->quoteIdentifier('id') . ' = ?', $userId)); $result = $accountsTable->update($accountData, $where); if ($result != 1) { throw new Tinebase_Exception_NotFound('Unable to update password! account not found in authentication backend.'); } $this->_setPluginsPassword($userId, $_password, $_encrypt); }
/** * try to set password */ public function testSetPassword() { $user = $this->testAddEmailAccount(); $newPassword = Tinebase_Record_Abstract::generateUID(); $this->_backend->inspectSetPassword($this->_objects['user']->getId(), $newPassword); // fetch email pw from db $queryResult = $this->_fetchUserFromDovecotUsersTable($user->getId()); $hashPw = new Hash_Password(); $this->assertTrue($hashPw->validate($queryResult[0]['password'], $newPassword), 'password mismatch'); }
/** * adds email properties for a new user * * @param Tinebase_Model_FullUser $_addedUser * @param Tinebase_Model_FullUser $_newUserProperties */ protected function _addUser(Tinebase_Model_FullUser $_addedUser, Tinebase_Model_FullUser $_newUserProperties) { if (!$_addedUser->accountEmailAddress) { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' User ' . $_addedUser->accountDisplayName . ' has no email address defined. Skipping email user creation.'); } return; } $emailUserData = $this->_recordToRawData($_addedUser, $_newUserProperties); $emailUsername = $emailUserData[$this->_propertyMapping['emailUsername']]; $this->_checkEmailExistance($emailUsername); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Adding new ' . $this->_configKey . ' email user ' . $emailUsername); } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($emailUserData, TRUE)); } try { $transactionId = Tinebase_TransactionManager::getInstance()->startTransaction($this->_db); // generate random password if not set if (isset($this->_propertyMapping['emailPassword']) && empty($emailUserData[$this->_propertyMapping['emailPassword']])) { $emailUserData[$this->_propertyMapping['emailPassword']] = Hash_Password::generate($this->_config['emailScheme'], Tinebase_Record_Abstract::generateUID()); } $insertData = $emailUserData; $this->_beforeAddOrUpdate($insertData); $this->_db->insert($this->_userTable, $insertData); $this->_afterAddOrUpdate($emailUserData); Tinebase_TransactionManager::getInstance()->commitTransaction($transactionId); $this->inspectGetUserByProperty($_addedUser); } catch (Zend_Db_Statement_Exception $zdse) { Tinebase_TransactionManager::getInstance()->rollBack(); Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' Error while creating email user: ' . $zdse); } }
/** * returns array of raw Dovecot data * * @param Tinebase_Model_FullUser $_user * @param Tinebase_Model_FullUser $_newUserProperties * @return array */ protected function _recordToRawData(Tinebase_Model_FullUser $_user, Tinebase_Model_FullUser $_newUserProperties) { $rawData = array(); if (isset($_newUserProperties->imapUser)) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($_newUserProperties->imapUser->toArray(), true)); } foreach ($_newUserProperties->imapUser as $key => $value) { $property = isset($this->_propertyMapping[$key]) || array_key_exists($key, $this->_propertyMapping) ? $this->_propertyMapping[$key] : false; if ($property && !in_array($key, $this->_readOnlyFields)) { switch ($key) { case 'emailUserId': case 'emailUsername': // set later break; case 'emailPassword': $rawData[$property] = Hash_Password::generate($this->_config['emailScheme'], $value); break; case 'emailMailQuota': $rawData[$property] = empty($value) ? 0 : $value; break; default: $rawData[$property] = $value; break; } } } } $rawData[$this->_propertyMapping['emailAddress']] = $_user->accountEmailAddress; $rawData[$this->_propertyMapping['emailForwardOnly']] = '0'; // will be overwritten later $rawData[$this->_propertyMapping['emailUserId']] = $_user->getId(); $rawData[$this->_propertyMapping['emailUsername']] = $_user->accountLoginName; $rawData[$this->_propertyMapping['emailHome']] = '/' . $_user->accountLoginName . '_' . substr($_user->getId(), 0, 8); $rawData['domain'] = $this->_config['domain']; if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($rawData, true)); } return $rawData; }
/** * try to update an email account */ public function testSetPassword() { // add smtp user $user = $this->testAddUser(); $newPassword = Tinebase_Record_Abstract::generateUID(); $this->_backend->setPassword($user->getId(), $newPassword); // fetch email pw from db $db = Tinebase_EmailUser::getInstance(Tinebase_Config::SMTP)->getDb(); $select = $db->select()->from(array('smtp_users'))->where($db->quoteIdentifier('userid') . ' = ?', $user->getId()); $stmt = $db->query($select); $queryResult = $stmt->fetch(); $stmt->closeCursor(); $this->assertTrue(isset($queryResult['passwd']), 'no password in result: ' . print_r($queryResult, TRUE)); $hashPw = new Hash_Password(); $this->assertTrue($hashPw->validate($queryResult['passwd'], $newPassword), 'password mismatch: ' . print_r($queryResult, TRUE)); }
/** * returns array of raw email user data * * @param Tinebase_Model_EmailUser $_user * @param Tinebase_Model_EmailUser $_newUserProperties * @throws Tinebase_Exception_UnexpectedValue * @return array * * @todo validate domains of aliases too */ protected function _recordToRawData(Tinebase_Model_FullUser $_user, Tinebase_Model_FullUser $_newUserProperties) { $rawData = array(); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($_newUserProperties->toArray(), true)); } if (isset($_newUserProperties->smtpUser)) { foreach ($_newUserProperties->smtpUser as $key => $value) { $property = isset($this->_propertyMapping[$key]) || array_key_exists($key, $this->_propertyMapping) ? $this->_propertyMapping[$key] : false; if ($property) { switch ($key) { case 'emailPassword': $rawData[$property] = Hash_Password::generate($this->_config['emailScheme'], $value); break; case 'emailAliases': $rawData[$property] = array(); foreach ((array) $value as $address) { if ($this->_checkDomain($address) === true) { $rawData[$property][] = $address; } } break; case 'emailForwards': $rawData[$property] = is_array($value) ? $value : array(); break; default: $rawData[$property] = $value; break; } } } } if (!empty($_user->accountEmailAddress)) { $this->_checkDomain($_user->accountEmailAddress, TRUE); } $rawData[$this->_propertyMapping['emailAddress']] = $_user->accountEmailAddress; $rawData[$this->_propertyMapping['emailUserId']] = $_user->getId(); $rawData[$this->_propertyMapping['emailUsername']] = $this->_appendDomain($_user->accountLoginName); if (empty($rawData[$this->_propertyMapping['emailAddress']])) { $rawData[$this->_propertyMapping['emailAliases']] = null; $rawData[$this->_propertyMapping['emailForwards']] = null; } if (empty($rawData[$this->_propertyMapping['emailForwards']])) { $rawData[$this->_propertyMapping['emailForwardOnly']] = 0; } $rawData['client_idnr'] = $this->_clientId; if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($rawData, true)); } return $rawData; }