From b8b645075346d48c92856e6cad978c5505833829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristia=CC=81n=20Feldsam?= Date: Sat, 11 May 2019 11:16:40 +0200 Subject: [PATCH 1/5] Default quota for mailbox MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kristián Feldsam --- data/web/edit.php | 6 ++++ data/web/inc/functions.mailbox.inc.php | 47 ++++++++++++++++++++++++-- data/web/inc/init_db.inc.php | 3 +- data/web/js/site/mailbox.js | 5 ++- data/web/lang/lang.cs.php | 6 ++++ data/web/lang/lang.en.php | 6 ++++ data/web/modals/mailbox.php | 8 ++++- 7 files changed, 76 insertions(+), 5 deletions(-) diff --git a/data/web/edit.php b/data/web/edit.php index 6d387eb7..1d491f7f 100644 --- a/data/web/edit.php +++ b/data/web/edit.php @@ -273,6 +273,12 @@ if (isset($_SESSION['mailcow_cc_role'])) { +
+ +
+ +
+
diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index df4344f8..683bdd5e 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -326,9 +326,18 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $description = $_data['description']; $aliases = $_data['aliases']; $mailboxes = $_data['mailboxes']; + $defquota = $_data['defquota']; $maxquota = $_data['maxquota']; $restart_sogo = $_data['restart_sogo']; $quota = $_data['quota']; + if ($defquota > $maxquota) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'mailbox_defquota_exceeds_mailbox_maxquota' + ); + return false; + } if ($maxquota > $quota) { $_SESSION['return'][] = array( 'type' => 'danger', @@ -337,6 +346,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ); return false; } + if ($defquota == "0" || empty($defquota)) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'defquota_empty' + ); + return false; + } if ($maxquota == "0" || empty($maxquota)) { $_SESSION['return'][] = array( 'type' => 'danger', @@ -392,13 +409,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ); return false; } - $stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `maxquota`, `quota`, `backupmx`, `gal`, `active`, `relay_all_recipients`) - VALUES (:domain, :description, :aliases, :mailboxes, :maxquota, :quota, :backupmx, :gal, :active, :relay_all_recipients)"); + $stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `defquota`, `maxquota`, `quota`, `backupmx`, `gal`, `active`, `relay_all_recipients`) + VALUES (:domain, :description, :aliases, :mailboxes, :defquota, :maxquota, :quota, :backupmx, :gal, :active, :relay_all_recipients)"); $stmt->execute(array( ':domain' => $domain, ':description' => $description, ':aliases' => $aliases, ':mailboxes' => $mailboxes, + ':defquota' => $defquota, ':maxquota' => $maxquota, ':quota' => $quota, ':backupmx' => $backupmx, @@ -1861,6 +1879,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $relayhost = (isset($_data['relayhost'])) ? intval($_data['relayhost']) : $is_now['relayhost']; $aliases = (!empty($_data['aliases'])) ? $_data['aliases'] : $is_now['max_num_aliases_for_domain']; $mailboxes = (isset($_data['mailboxes']) && $_data['mailboxes'] != '') ? intval($_data['mailboxes']) : $is_now['max_num_mboxes_for_domain']; + $defquota = (!empty($_data['defquota'])) ? $_data['defquota'] : ($is_now['def_quota_for_mbox'] / 1048576); $maxquota = (!empty($_data['maxquota'])) ? $_data['maxquota'] : ($is_now['max_quota_for_mbox'] / 1048576); $quota = (!empty($_data['quota'])) ? $_data['quota'] : ($is_now['max_quota_for_domain'] / 1048576); $description = (!empty($_data['description'])) ? $_data['description'] : $is_now['description']; @@ -1892,6 +1911,22 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { )"); $stmt->execute(array(':domain' => $domain)); $AliasData = $stmt->fetch(PDO::FETCH_ASSOC); + if ($defquota > $maxquota) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'mailbox_defquota_exceeds_mailbox_maxquota' + ); + continue; + } + if ($defquota == "0" || empty($defquota)) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'defquota_empty' + ); + continue; + } if ($maxquota > $quota) { $_SESSION['return'][] = array( 'type' => 'danger', @@ -1946,6 +1981,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { `gal` = :gal, `active` = :active, `quota` = :quota, + `defquota` = :defquota, `maxquota` = :maxquota, `relayhost` = :relayhost, `mailboxes` = :mailboxes, @@ -1958,6 +1994,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ':gal' => $gal, ':active' => $active, ':quota' => $quota, + ':defquota' => $defquota, ':maxquota' => $maxquota, ':relayhost' => $relayhost, ':mailboxes' => $mailboxes, @@ -2907,6 +2944,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { `description`, `aliases`, `mailboxes`, + `defquota`, `maxquota`, `quota`, `relayhost`, @@ -2938,6 +2976,10 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { if ($domaindata['max_new_mailbox_quota'] > ($row['maxquota'] * 1048576)) { $domaindata['max_new_mailbox_quota'] = ($row['maxquota'] * 1048576); } + $domaindata['def_new_mailbox_quota'] = $domaindata['max_new_mailbox_quota']; + if ($domaindata['def_new_mailbox_quota'] > ($row['defquota'] * 1048576)) { + $domaindata['def_new_mailbox_quota'] = ($row['defquota'] * 1048576); + } $domaindata['quota_used_in_domain'] = $MailboxDataDomain['in_use']; $domaindata['mboxes_in_domain'] = $MailboxDataDomain['count']; $domaindata['mboxes_left'] = $row['mailboxes'] - $MailboxDataDomain['count']; @@ -2945,6 +2987,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $domaindata['description'] = $row['description']; $domaindata['max_num_aliases_for_domain'] = $row['aliases']; $domaindata['max_num_mboxes_for_domain'] = $row['mailboxes']; + $domaindata['def_quota_for_mbox'] = $row['defquota'] * 1048576; $domaindata['max_quota_for_mbox'] = $row['maxquota'] * 1048576; $domaindata['max_quota_for_domain'] = $row['quota'] * 1048576; $domaindata['relayhost'] = $row['relayhost']; diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index 27db8c1f..1c000204 100644 --- a/data/web/inc/init_db.inc.php +++ b/data/web/inc/init_db.inc.php @@ -189,7 +189,8 @@ function init_db_schema() { "description" => "VARCHAR(255)", "aliases" => "INT(10) NOT NULL DEFAULT '0'", "mailboxes" => "INT(10) NOT NULL DEFAULT '0'", - "maxquota" => "BIGINT(20) NOT NULL DEFAULT '0'", + "defquota" => "BIGINT(20) NOT NULL DEFAULT '3072'", + "maxquota" => "BIGINT(20) NOT NULL DEFAULT '102400'", "quota" => "BIGINT(20) NOT NULL DEFAULT '102400'", "relayhost" => "VARCHAR(255) NOT NULL DEFAULT '0'", "backupmx" => "TINYINT(1) NOT NULL DEFAULT '0'", diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index 2ed049f4..5653fdcd 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -62,11 +62,12 @@ $(document).ready(function() { auto_fill_quota = function(domain) { $.get("/api/v1/get/domain/" + domain, function(data){ var result = $.parseJSON(JSON.stringify(data)); + def_new_mailbox_quota = ( result.def_new_mailbox_quota / 1048576); max_new_mailbox_quota = ( result.max_new_mailbox_quota / 1048576); if (max_new_mailbox_quota != '0') { $("#quotaBadge").html('max. ' + max_new_mailbox_quota + ' MiB'); $('#addInputQuota').attr({"disabled": false, "value": "", "type": "number", "max": max_new_mailbox_quota}); - $('#addInputQuota').val(max_new_mailbox_quota); + $('#addInputQuota').val(def_new_mailbox_quota); } else { $("#quotaBadge").html('max. ' + max_new_mailbox_quota + ' MiB'); @@ -239,6 +240,7 @@ jQuery(function($){ return Number(res[0]); }, }, + {"name":"def_quota_for_mbox","title":lang.mailbox_defquota,"breakpoints":"xs sm md","style":{"width":"125px"}}, {"name":"max_quota_for_mbox","title":lang.mailbox_quota,"breakpoints":"xs sm","style":{"width":"125px"}}, {"name":"rl","title":"RL","breakpoints":"xs sm md lg","style":{"maxWidth":"100px","width":"100px"}}, {"name":"backupmx","filterable": false,"style":{"maxWidth":"120px","width":"120px"},"title":lang.backup_mx,"breakpoints":"xs sm md lg"}, @@ -264,6 +266,7 @@ jQuery(function($){ return e; }).join('/1'); } + item.def_quota_for_mbox = humanFileSize(item.def_quota_for_mbox); item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox); item.chkbox = ''; item.action = '
'; diff --git a/data/web/lang/lang.cs.php b/data/web/lang/lang.cs.php index efcac064..ce57ad2e 100644 --- a/data/web/lang/lang.cs.php +++ b/data/web/lang/lang.cs.php @@ -798,3 +798,9 @@ $lang['warning']['ip_invalid'] = 'Přeskočeno, vadná IP: %s'; $lang['danger']['text_empty'] = 'Text nesmí být prázdný'; $lang['danger']['subject_empty'] = 'Předmět nesmí být prázdný'; $lang['danger']['from_invalid'] = 'Odesílat nesmí být prázdný'; + +$lang['add']['mailbox_quota_def'] = 'Výchozí kvóta schránky'; +$lang['edit']['mailbox_quota_def'] = 'Výchozí kvóta schránky'; +$lang['danger']['mailbox_defquota_exceeds_mailbox_maxquota'] = 'Výchozí kvóta překračuje maximální kvótu schránky"'; +$lang['danger']['defquota_empty'] = 'Výchozí kvóta schránky nesmí být 0.'; +$lang['mailbox']['mailbox_defquota'] = 'Výchozí velikost schránky'; \ No newline at end of file diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php index 8044b018..d0289797 100644 --- a/data/web/lang/lang.en.php +++ b/data/web/lang/lang.en.php @@ -859,3 +859,9 @@ $lang['danger']['text_empty'] = 'Text must not be empty'; $lang['danger']['subject_empty'] = 'Subject must not be empty'; $lang['danger']['from_invalid'] = 'Sender must not be empty'; $lang['danger']['network_host_invalid'] = 'Invalid network or host: %s'; + +$lang['add']['mailbox_quota_def'] = 'Default mailbox quota'; +$lang['edit']['mailbox_quota_def'] = 'Default mailbox quota'; +$lang['danger']['mailbox_defquota_exceeds_mailbox_maxquota'] = 'Default quota exceeds max quota limit"'; +$lang['danger']['defquota_empty'] = 'Default quota per mailbox must not be 0.'; +$lang['mailbox']['mailbox_defquota'] = 'Default mailbox size'; diff --git a/data/web/modals/mailbox.php b/data/web/modals/mailbox.php index 123a5934..67516ac2 100644 --- a/data/web/modals/mailbox.php +++ b/data/web/modals/mailbox.php @@ -108,12 +108,18 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
+
+
+
+ +
+
- +
From f586b0e5a94552210b436d139104c16ee8034032 Mon Sep 17 00:00:00 2001 From: MAGIC Date: Sun, 2 Jun 2019 20:56:08 +0200 Subject: [PATCH 2/5] [update.sh] Rename enable_ipv6 option --- update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.sh b/update.sh index 73d6f615..16a3890e 100755 --- a/update.sh +++ b/update.sh @@ -376,7 +376,7 @@ if grep -q 'SYSCTL_IPV6_DISABLED=1' mailcow.conf; then echo echo '!! IMPORTANT !!' echo - echo 'SYSCTL_IPV6_DISABLED was removed due to complications. IPv6 can be disabled by editing "docker-compose.yml" and setting "enabled_ipv6: true" to "enabled_ipv6: false".' + echo 'SYSCTL_IPV6_DISABLED was removed due to complications. IPv6 can be disabled by editing "docker-compose.yml" and setting "enable_ipv6: true" to "enable_ipv6: false".' echo 'This setting will only be active after a complete shutdown of mailcow by running "docker-compose down" followed by "docker-compose up -d".' echo echo '!! IMPORTANT !!' From d5eeb3e8af18e9cee48452eae79bd142f7d24ebc Mon Sep 17 00:00:00 2001 From: dofl Date: Sat, 8 Jun 2019 15:10:46 +0200 Subject: [PATCH 3/5] Update main.cf I was looking into creating a backup mx server for a high availability mailcow setup. It seems that this is not easily done. While researching to find out how long an average SMTP server keeps trying to send to a server that is down I found that RFC 5321 advises at least 4 to 5 days. Mailcow has a custom setup of 1 day, which is very short. The user will be unaware for 5 days that his mail has not been delivered, which can be negative. But I still would like to follow the advice of the RFC. RFC 5321, in section 4.5.4.1, has this to say: Retries continue until the message is transmitted or the sender up; the give-up time generally needs to be at least 4-5 days. It MAY be appropriate to set a shorter maximum number of retries for non-delivery notifications and equivalent error messages than for standard messages. Postfix default is also 5 days: http://www.postfix.org/postconf.5.html https://tools.ietf.org/html/rfc5321#section-4.5.4 --- data/conf/postfix/main.cf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/conf/postfix/main.cf b/data/conf/postfix/main.cf index b0fda8bb..95301c43 100644 --- a/data/conf/postfix/main.cf +++ b/data/conf/postfix/main.cf @@ -19,7 +19,7 @@ bounce_queue_lifetime = 1d broken_sasl_auth_clients = yes disable_vrfy_command = yes maximal_backoff_time = 1800s -maximal_queue_lifetime = 1d +maximal_queue_lifetime = 5d message_size_limit = 104857600 milter_default_action = accept milter_protocol = 6 From fa4c4b138e4723938278f6658f7dcf56ba349604 Mon Sep 17 00:00:00 2001 From: dofl Date: Sun, 9 Jun 2019 07:39:36 +0200 Subject: [PATCH 4/5] Update main.cf Added the delay_warning_time (http://www.postfix.org/postconf.5.html#delay_warning_time) with 4 hours as setting. Postfix will inform the user that the e-mail has not been delivered, but that it will try for the next 5 days. There is also a setting called confirm_delay_cleared (http://www.postfix.org/postconf.5.html#confirm_delay_cleared), but according to the Postfix this can lead to a sudden burst of notifications at the end of a prolonged network outage. --- data/conf/postfix/main.cf | 1 + 1 file changed, 1 insertion(+) diff --git a/data/conf/postfix/main.cf b/data/conf/postfix/main.cf index 95301c43..bd8f76ed 100644 --- a/data/conf/postfix/main.cf +++ b/data/conf/postfix/main.cf @@ -20,6 +20,7 @@ broken_sasl_auth_clients = yes disable_vrfy_command = yes maximal_backoff_time = 1800s maximal_queue_lifetime = 5d +delay_warning_time = 4h message_size_limit = 104857600 milter_default_action = accept milter_protocol = 6 From 1634a486fc51990d6aa13feda17942c3641db953 Mon Sep 17 00:00:00 2001 From: Aiko Appeldorn Date: Sun, 9 Jun 2019 12:08:23 +0200 Subject: [PATCH 5/5] [web] increased db version --- data/web/inc/init_db.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index 1c000204..ea6fe15d 100644 --- a/data/web/inc/init_db.inc.php +++ b/data/web/inc/init_db.inc.php @@ -3,7 +3,7 @@ function init_db_schema() { try { global $pdo; - $db_version = "04052019_1210"; + $db_version = "09062019_1208"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));