git subrepo commit (merge) mailcow/src/mailcow-dockerized
subrepo: subdir: "mailcow/src/mailcow-dockerized"
merged: "c7b1dc37"
upstream: origin: "https://github.com/mailcow/mailcow-dockerized.git"
branch: "master"
commit: "a366494c"
git-subrepo: version: "0.4.6"
origin: "???"
commit: "???"
Change-Id: Id574ecd4e02e3c4fbf8a1efd49be11c0b6d19a3f
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/functions.mailbox.inc.php b/mailcow/src/mailcow-dockerized/data/web/inc/functions.mailbox.inc.php
index d67fa3e..68cb50f 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/functions.mailbox.inc.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/functions.mailbox.inc.php
@@ -1250,9 +1250,27 @@
));
}
else {
- $stmt = $pdo->prepare("INSERT INTO `user_acl` (`username`) VALUES (:username)");
+ $stmt = $pdo->prepare("INSERT INTO `user_acl`
+ (`username`, `spam_alias`, `tls_policy`, `spam_score`, `spam_policy`, `delimiter_action`, `syncjobs`, `eas_reset`, `sogo_profile_reset`,
+ `pushover`, `quarantine`, `quarantine_attachments`, `quarantine_notification`, `quarantine_category`, `app_passwds`)
+ VALUES (:username, :spam_alias, :tls_policy, :spam_score, :spam_policy, :delimiter_action, :syncjobs, :eas_reset, :sogo_profile_reset,
+ :pushover, :quarantine, :quarantine_attachments, :quarantine_notification, :quarantine_category, :app_passwds) ");
$stmt->execute(array(
- ':username' => $username
+ ':username' => $username,
+ ':spam_alias' => 0,
+ ':tls_policy' => 0,
+ ':spam_score' => 0,
+ ':spam_policy' => 0,
+ ':delimiter_action' => 0,
+ ':syncjobs' => 0,
+ ':eas_reset' => 0,
+ ':sogo_profile_reset' => 0,
+ ':pushover' => 0,
+ ':quarantine' => 0,
+ ':quarantine_attachments' => 0,
+ ':quarantine_notification' => 0,
+ ':quarantine_category' => 0,
+ ':app_passwds' => 0
));
}
@@ -1264,11 +1282,13 @@
));
}
+ update_sogo_static_view($username);
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => array('mailbox_added', htmlspecialchars($username))
);
+ return true;
break;
case 'resource':
$domain = idn_to_ascii(strtolower(trim($_data['domain'])), 0, INTL_IDNA_VARIANT_UTS46);
@@ -1531,20 +1551,20 @@
$attr['acl_app_passwds'] = (in_array('app_passwds', $_data['acl'])) ? 1 : 0;
} else {
$_data['acl'] = (array)$_data['acl'];
- $attr['acl_spam_alias'] = 1;
- $attr['acl_tls_policy'] = 1;
- $attr['acl_spam_score'] = 1;
- $attr['acl_spam_policy'] = 1;
- $attr['acl_delimiter_action'] = 1;
+ $attr['acl_spam_alias'] = 0;
+ $attr['acl_tls_policy'] = 0;
+ $attr['acl_spam_score'] = 0;
+ $attr['acl_spam_policy'] = 0;
+ $attr['acl_delimiter_action'] = 0;
$attr['acl_syncjobs'] = 0;
- $attr['acl_eas_reset'] = 1;
+ $attr['acl_eas_reset'] = 0;
$attr['acl_sogo_profile_reset'] = 0;
- $attr['acl_pushover'] = 1;
- $attr['acl_quarantine'] = 1;
- $attr['acl_quarantine_attachments'] = 1;
- $attr['acl_quarantine_notification'] = 1;
- $attr['acl_quarantine_category'] = 1;
- $attr['acl_app_passwds'] = 1;
+ $attr['acl_pushover'] = 0;
+ $attr['acl_quarantine'] = 0;
+ $attr['acl_quarantine_attachments'] = 0;
+ $attr['acl_quarantine_notification'] = 0;
+ $attr['acl_quarantine_category'] = 0;
+ $attr['acl_app_passwds'] = 0;
}
@@ -2879,67 +2899,68 @@
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => 'access_denied'
+ 'msg' => 'extended_sender_acl_denied'
);
- return false;
}
- $extra_acls = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['extended_sender_acl']));
- foreach ($extra_acls as $i => &$extra_acl) {
- if (empty($extra_acl)) {
- continue;
- }
- if (substr($extra_acl, 0, 1) === "@") {
- $extra_acl = ltrim($extra_acl, '@');
- }
- if (!filter_var($extra_acl, FILTER_VALIDATE_EMAIL) && !is_valid_domain_name($extra_acl)) {
- $_SESSION['return'][] = array(
- 'type' => 'danger',
- 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => array('extra_acl_invalid', htmlspecialchars($extra_acl))
- );
- unset($extra_acls[$i]);
- continue;
- }
- $domains = array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains'));
- if (filter_var($extra_acl, FILTER_VALIDATE_EMAIL)) {
- $extra_acl_domain = idn_to_ascii(substr(strstr($extra_acl, '@'), 1), 0, INTL_IDNA_VARIANT_UTS46);
- if (in_array($extra_acl_domain, $domains)) {
+ else {
+ $extra_acls = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['extended_sender_acl']));
+ foreach ($extra_acls as $i => &$extra_acl) {
+ if (empty($extra_acl)) {
+ continue;
+ }
+ if (substr($extra_acl, 0, 1) === "@") {
+ $extra_acl = ltrim($extra_acl, '@');
+ }
+ if (!filter_var($extra_acl, FILTER_VALIDATE_EMAIL) && !is_valid_domain_name($extra_acl)) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => array('extra_acl_invalid_domain', $extra_acl_domain)
+ 'msg' => array('extra_acl_invalid', htmlspecialchars($extra_acl))
);
unset($extra_acls[$i]);
continue;
}
- }
- else {
- if (in_array($extra_acl, $domains)) {
- $_SESSION['return'][] = array(
- 'type' => 'danger',
- 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => array('extra_acl_invalid_domain', $extra_acl_domain)
- );
- unset($extra_acls[$i]);
- continue;
+ $domains = array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains'));
+ if (filter_var($extra_acl, FILTER_VALIDATE_EMAIL)) {
+ $extra_acl_domain = idn_to_ascii(substr(strstr($extra_acl, '@'), 1), 0, INTL_IDNA_VARIANT_UTS46);
+ if (in_array($extra_acl_domain, $domains)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('extra_acl_invalid_domain', $extra_acl_domain)
+ );
+ unset($extra_acls[$i]);
+ continue;
+ }
}
- $extra_acl = '@' . $extra_acl;
+ else {
+ if (in_array($extra_acl, $domains)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('extra_acl_invalid_domain', $extra_acl_domain)
+ );
+ unset($extra_acls[$i]);
+ continue;
+ }
+ $extra_acl = '@' . $extra_acl;
+ }
}
- }
- $extra_acls = array_filter($extra_acls);
- $extra_acls = array_values($extra_acls);
- $extra_acls = array_unique($extra_acls);
- $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `external` = 1 AND `logged_in_as` = :username");
- $stmt->execute(array(
- ':username' => $username
- ));
- foreach ($extra_acls as $sender_acl_external) {
- $stmt = $pdo->prepare("INSERT INTO `sender_acl` (`send_as`, `logged_in_as`, `external`)
- VALUES (:sender_acl, :username, 1)");
+ $extra_acls = array_filter($extra_acls);
+ $extra_acls = array_values($extra_acls);
+ $extra_acls = array_unique($extra_acls);
+ $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `external` = 1 AND `logged_in_as` = :username");
$stmt->execute(array(
- ':sender_acl' => $sender_acl_external,
':username' => $username
));
+ foreach ($extra_acls as $sender_acl_external) {
+ $stmt = $pdo->prepare("INSERT INTO `sender_acl` (`send_as`, `logged_in_as`, `external`)
+ VALUES (:sender_acl, :username, 1)");
+ $stmt->execute(array(
+ ':sender_acl' => $sender_acl_external,
+ ':username' => $username
+ ));
+ }
}
}
if (isset($_data['sender_acl'])) {
@@ -3129,7 +3150,10 @@
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => array('mailbox_modified', $username)
);
+
+ update_sogo_static_view($username);
}
+ return true;
break;
case 'mailbox_templates':
if ($_SESSION['mailcow_cc_role'] != "admin") {
@@ -3314,6 +3338,45 @@
);
}
break;
+ case 'domain_wide_footer':
+ $domain = idn_to_ascii(strtolower(trim($_data['domain'])), 0, INTL_IDNA_VARIANT_UTS46);
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'domain_invalid'
+ );
+ return false;
+ }
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'access_denied'
+ );
+ return false;
+ }
+
+ $footers = array();
+ $footers['html'] = isset($_data['footer_html']) ? $_data['footer_html'] : '';
+ $footers['plain'] = isset($_data['footer_plain']) ? $_data['footer_plain'] : '';
+ try {
+ $redis->hSet('DOMAIN_WIDE_FOOTER', $domain, json_encode($footers));
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('redis_error', $e)
+ );
+ return false;
+ }
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('domain_footer_modified', htmlspecialchars($domain))
+ );
+ break;
}
break;
case 'get':
@@ -3959,6 +4022,39 @@
}
return $aliasdomaindata;
break;
+ case 'shared_aliases':
+ $shared_aliases = array();
+ $stmt = $pdo->query("SELECT `address` FROM `alias`
+ WHERE `goto` REGEXP ','
+ AND `address` NOT LIKE '@%'
+ AND `goto` != `address`");
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $domain = explode("@", $row['address'])[1];
+ if (hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $shared_aliases[] = $row['address'];
+ }
+ }
+
+ return $shared_aliases;
+ break;
+ case 'direct_aliases':
+ $direct_aliases = array();
+ $stmt = $pdo->query("SELECT `address` FROM `alias`
+ WHERE `goto` NOT LIKE '%,%'
+ AND `address` NOT LIKE '@%'
+ AND `goto` != `address`");
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+ while($row = array_shift($rows)) {
+ $domain = explode("@", $row['address'])[1];
+ if (hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $direct_aliases[] = $row['address'];
+ }
+ }
+
+ return $direct_aliases;
+ break;
case 'domains':
$domains = array();
if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
@@ -4393,6 +4489,40 @@
}
return $resourcedata;
break;
+ case 'domain_wide_footer':
+ $domain = idn_to_ascii(strtolower(trim($_data)), 0, INTL_IDNA_VARIANT_UTS46);
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'domain_invalid'
+ );
+ return false;
+ }
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'access_denied'
+ );
+ return false;
+ }
+
+ try {
+ $footers = $redis->hGet('DOMAIN_WIDE_FOOTER', $domain);
+ $footers = json_decode($footers, true);
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => array('redis_error', $e)
+ );
+ return false;
+ }
+
+ return $footers;
+ break;
}
break;
case 'delete':
@@ -4891,13 +5021,19 @@
if (!empty($mailbox_details['domain']) && !empty($mailbox_details['local_part'])) {
$maildir = $mailbox_details['domain'] . '/' . $mailbox_details['local_part'];
$exec_fields = array('cmd' => 'maildir', 'task' => 'cleanup', 'maildir' => $maildir);
- $maildir_gc = json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true);
- if ($maildir_gc['type'] != 'success') {
- $_SESSION['return'][] = array(
- 'type' => 'warning',
- 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => 'Could not move maildir to garbage collector: ' . $maildir_gc['msg']
- );
+
+ if (getenv("CLUSTERMODE") == "replication") {
+ // broadcast to each dovecot container
+ docker('broadcast', 'dovecot-mailcow', 'exec', $exec_fields);
+ } else {
+ $maildir_gc = json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true);
+ if ($maildir_gc['type'] != 'success') {
+ $_SESSION['return'][] = array(
+ 'type' => 'warning',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'Could not move maildir to garbage collector: ' . $maildir_gc['msg']
+ );
+ }
}
}
else {
@@ -4950,9 +5086,10 @@
$stmt->execute(array(
':username' => $username
));
- $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
+ $stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as OR `send_as` = :send_as");
$stmt->execute(array(
- ':username' => $username
+ ':logged_in_as' => $username,
+ ':send_as' => $username
));
// fk, better safe than sorry
$stmt = $pdo->prepare("DELETE FROM `user_acl` WHERE `username` = :username");
@@ -5052,12 +5189,15 @@
);
continue;
}
+
+ update_sogo_static_view($username);
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => array('mailbox_removed', htmlspecialchars($username))
);
}
+ return true;
break;
case 'mailbox_templates':
if ($_SESSION['mailcow_cc_role'] != "admin") {
@@ -5170,15 +5310,6 @@
$tags = $_data['tags'];
if (!is_array($tags)) $tags = array();
-
- if ($_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'][] = array(
- 'type' => 'danger',
- 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
- 'msg' => 'access_denied'
- );
- return false;
- }
$wasModified = false;
foreach ($domains as $domain) {
@@ -5190,7 +5321,15 @@
);
continue;
}
-
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'access_denied'
+ );
+ return false;
+ }
+
foreach($tags as $tag){
// delete tag
$wasModified = true;
@@ -5264,7 +5403,7 @@
}
break;
}
- if ($_action != 'get' && in_array($_type, array('domain', 'alias', 'alias_domain', 'mailbox', 'resource'))) {
+ if ($_action != 'get' && in_array($_type, array('domain', 'alias', 'alias_domain', 'resource')) && getenv('SKIP_SOGO') != "y") {
update_sogo_static_view();
}
}