/** * Update external mail server entries * * Note: In case all entries are marked as to be deleted, the external mail server is deactivated * * @throws iMSCP_Exception_Database * @param array $item Item data (item id and item type) * @return void */ function client_editExternalMailServerEntries($item) { $verifiedData = _client_getVerifiedData($item[0], $item[1]); if (!empty($_POST)) { // Preparing entries stack $data['to_update'] = isset($_POST['to_update']) ? $_POST['to_update'] : array(); $data['to_delete'] = isset($_POST['to_delete']) ? $_POST['to_delete'] : array(); $data['type'] = isset($_POST['type']) ? $_POST['type'] : array(); $data['priority'] = isset($_POST['priority']) ? $_POST['priority'] : array(); $data['host'] = isset($_POST['host']) ? $_POST['host'] : array(); $responses = iMSCP_Events_Aggregator::getInstance()->dispatch(iMSCP_Events::onBeforeAddExternalMailServer, array('externalMailServerEntries' => $data)); if (!$responses->isStopped()) { $entriesCount = count($data['type']); $error = false; // Validate all entries for ($index = 0; $index < $entriesCount; $index++) { if (isset($data['type'][$index]) && isset($data['priority'][$index]) && isset($data['host'][$index])) { $data['host'][$index] = strtolower(rtrim($data['host'][$index], '.')); if (empty($data['to_delete'][$index]) && !_client_validateDnsMxRecord($data['type'][$index], $data['priority'][$index], $data['host'][$index], $verifiedData)) { $error = true; } } else { // Not all expected data were received showBadRequestErrorPage(); } } // Add entries into database if (!$error) { /** @var $db iMSCP_Database */ $db = iMSCP_Database::getInstance(); try { $db->beginTransaction(); $dnsEntriesIds = ''; # Spam Filter ( filter ) MX type has highter precedence $spamFilterMX = false; $wildcardMxOnly = true; for ($index = 0; $index < $entriesCount; $index++) { if (!empty($data['to_delete'][$index]) && in_array($data['to_delete'][$index], $verifiedData['external_mail_dns_ids'])) { // Entry to delete if (empty($data['to_update']) && empty($data['type'])) { exec_query('UPDATE domain_dns SET domain_dns_status = ? WHERE domain_dns_id = ?', array('todelete', $data['to_delete'][$index])); } else { exec_query('DELETE FROM domain_dns WHERE domain_dns_id = ?', $data['to_delete'][$index]); } } elseif (!empty($data['to_update'][$index]) && in_array($data['to_update'][$index], $verifiedData['external_mail_dns_ids'])) { // Entry to update if ($data['type'][$index] == 'filter') { $spamFilterMX = true; $wildcardMxOnly = false; } elseif ($data['type'][$index] == 'domain') { $wildcardMxOnly = false; } exec_query(' UPDATE domain_dns SET domain_dns = ?, domain_text = ?, domain_dns_status = ? WHERE domain_dns_id = ? ', array($data['type'][$index] != 'wildcard' ? $verifiedData['item_name'] . '.' : '*.' . $verifiedData['item_name'] . '.', $data['priority'][$index] . "\t" . encode_idna($data['host'][$index]) . '.', 'tochange', $data['to_update'][$index])); $dnsEntriesIds .= ',' . $data['to_update'][$index]; } else { // Entry to add if ($data['type'][$index] == 'filter') { $spamFilterMX = true; $wildcardMxOnly = false; } elseif ($data['type'][$index] == 'domain') { $wildcardMxOnly = false; } exec_query(' INSERT INTO domain_dns ( domain_id, alias_id, domain_dns, domain_class, domain_type, domain_text, owned_by, domain_dns_status ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? ) ', array($verifiedData['domain_id'], $verifiedData['item_type'] == 'alias' ? $verifiedData['item_id'] : 0, $data['type'][$index] != 'wildcard' ? $verifiedData['item_name'] . '.' : '*.' . $verifiedData['item_name'] . '.', 'IN', 'MX', "{$data['priority'][$index]}\t" . encode_idna($data['host'][$index]) . '.', 'ext_mail_feature', 'toadd')); $dnsEntriesIds .= ',' . $db->insertId(); } } $externalMailServer = $dnsEntriesIds !== '' ? $spamFilterMX ? 'filter' : ($wildcardMxOnly ? 'wildcard' : 'domain') : 'off'; if ($verifiedData['item_type'] == 'normal') { exec_query(' UPDATE domain SET external_mail = ?, domain_status = ?, external_mail_dns_ids = ? WHERE domain_id = ? ', array($externalMailServer, 'tochange', ltrim($dnsEntriesIds, ','), $verifiedData['item_id'])); } else { exec_query(' UPDATE domain_aliasses SET external_mail = ?, alias_status = ?, external_mail_dns_ids = ? WHERE alias_id = ? ', array($externalMailServer, 'tochange', ltrim($dnsEntriesIds, ','), $verifiedData['item_id'])); } $db->commit(); iMSCP_Events_Aggregator::getInstance()->dispatch(iMSCP_Events::onAfterAddExternalMailServer, array('externalMailServerEntries' => $data)); send_request(); if ($externalMailServer !== 'off') { set_page_message(tr('External mail server successfully scheduled for update.'), 'success'); } else { set_page_message(tr('External mail server successfully scheduled for deactivation.'), 'success'); } redirectTo('mail_external.php'); } catch (iMSCP_Exception_Database $e) { $db->rollBack(); if ($e->getCode() === 23000) { set_page_message(tr('An entry is defined twice.'), 'error'); } else { throw $e; } } } } else { redirectTo('mail_external.php'); } } else { if (!empty($verifiedData['external_mail_dns_ids'])) { $stmt = execute_query(' SELECT * FROM domain_dns WHERE domain_dns_id IN(' . implode(',', $verifiedData['external_mail_dns_ids']) . ') '); if ($stmt->rowCount()) { $data = array(); while ($row = $stmt->fetchRow(PDO::FETCH_ASSOC)) { $data['to_update'][] = $row['domain_dns_id']; $data['type'][] = strpos($row['domain_dns'], '*') === false ? $verifiedData['external_mail_type'] == 'domain' ? 'domain' : 'filter' : 'wildcard'; list($priority, $host) = explode("\t", $row['domain_text'], 2); $data['priority'][] = trim($priority); $data['host'][] = rtrim($host, '.'); } } else { // DNS entries pointed by domain or domain alias were not found ( should never occurs ) if ($verifiedData['item_type'] == 'normal') { $query = ' UPDATE domain SET domain_status = ?, external_mail = ?, external_mail_dns_ids = ? WHERE domain_id = ? '; } else { $query = ' UPDATE domain_aliasses SET alias_status = ?, external_mail = ?, external_mail_dns_ids = ? WHERE alias_id = ? '; } exec_query($query, array('tochange', 'off', null, $verifiedData['item_id'])); send_request(); set_page_message(tr('Entries associated to your external mail servers were not found. A Resynchronization has been scheduled.'), 'warning'); redirectTo('mail_external.php'); exit; // Only to make some IDE happy } } else { set_page_message('An unexpected error occurred.', 'error'); redirectTo('mail_external.php'); // No domain or domain alias data found ( should never occurs ) exit; // Only to make some IDE happy } } client_generateView($verifiedData, $data); }
/** * Add external mail server entries * * @throws iMSCP_Exception_Database * @param array $item Item data (item id and item type) * @return void */ function client_addExternalMailServerEntries($item) { $verifiedData = _client_getVerifiedData($item[0], $item[1]); if (!empty($_POST)) { // Preparing entries stack $data['type'] = isset($_POST['type']) ? $_POST['type'] : array(); $data['priority'] = isset($_POST['priority']) ? $_POST['priority'] : array(); $data['host'] = isset($_POST['host']) ? $_POST['host'] : array(); $responses = iMSCP_Events_Aggregator::getInstance()->dispatch(iMSCP_Events::onBeforeAddExternalMailServer, array('externalMailServerEntries' => $data)); if (!$responses->isStopped()) { $entriesCount = count($data['type']); $error = false; # Spam Filter ( filter ) MX type has highter precedence $spamFilterMX = false; $wildcardMxOnly = true; // Validate all entries for ($index = 0; $index < $entriesCount; $index++) { if (isset($data['type'][$index]) && isset($data['priority'][$index]) && isset($data['host'][$index])) { $data['host'][$index] = strtolower(rtrim($data['host'][$index], '.')); if (!_client_validateDnsMxRecord($data['type'][$index], $data['priority'][$index], $data['host'][$index], $verifiedData)) { $error = true; } if ($data['type'][$index] == 'filter') { $spamFilterMX = true; $wildcardMxOnly = false; } elseif ($data['type'][$index] == 'domain') { $wildcardMxOnly = false; } } else { // Not all expected data were received showBadRequestErrorPage(); } } // Add DNS entries into database if (!$error) { /** @var $db iMSCP_Database */ $db = iMSCP_Database::getInstance(); try { $db->beginTransaction(); // All successfully inserted or nothing $dnsEntriesIds = ''; for ($index = 0; $index < $entriesCount; $index++) { // Add MX record exec_query(' INSERT INTO domain_dns ( domain_id, alias_id, domain_dns, domain_class, domain_type, domain_text, owned_by, domain_dns_status ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? ) ', array($verifiedData['domain_id'], $verifiedData['item_type'] == 'alias' ? $verifiedData['item_id'] : 0, $data['type'][$index] != 'wildcard' ? $verifiedData['item_name'] . '.' : '*.' . $verifiedData['item_name'] . '.', 'IN', 'MX', "{$data['priority'][$index]}\t" . encode_idna($data['host'][$index]) . '.', 'ext_mail_feature', 'toadd')); $dnsEntriesIds .= ',' . $db->insertId(); } if ($verifiedData['item_type'] == 'normal') { exec_query(' UPDATE domain SET external_mail = ?, domain_status = ?, external_mail_dns_ids = ? WHERE domain_id = ? ', array($spamFilterMX ? 'filter' : ($wildcardMxOnly ? 'wildcard' : 'domain'), 'tochange', ltrim($dnsEntriesIds, ','), $verifiedData['domain_id'])); } else { exec_query(' UPDATE domain_aliasses SET external_mail = ?, alias_status = ?, external_mail_dns_ids = ? WHERE alias_id = ? ', array($spamFilterMX ? 'filter' : ($wildcardMxOnly ? 'wildcard' : 'domain'), 'tochange', ltrim($dnsEntriesIds, ','), $verifiedData['item_id'])); } $db->commit(); iMSCP_Events_Aggregator::getInstance()->dispatch(iMSCP_Events::onAfterAddExternalMailServer, array('externalMailServerEntries' => $data)); send_request(); set_page_message(tr('External mail server successfully scheduled for addition.'), 'success'); redirectTo('mail_external.php'); } catch (iMSCP_Exception_Database $e) { $db->rollBack(); if ($e->getCode() === 23000) { set_page_message(tr('An entry is defined twice.'), 'error'); } else { throw $e; } } } } else { redirectTo('mail_external.php'); } } else { $data['type'][] = 'domain'; $data['priority'][] = '5'; $data['host'][] = ''; } client_generateView($verifiedData, $data); }