diff --git a/data/Dockerfiles/phpfpm/docker-entrypoint.sh b/data/Dockerfiles/phpfpm/docker-entrypoint.sh
index 0b8b303e4..8c986335b 100755
--- a/data/Dockerfiles/phpfpm/docker-entrypoint.sh
+++ b/data/Dockerfiles/phpfpm/docker-entrypoint.sh
@@ -6,7 +6,7 @@ if [[ $(stat -c %U /data/dkim/) != "www-data" ]] ; then chown -R www-data:www-da
# Wait for containers
-while ! mysqladmin ping --host mysql --silent; do
+while ! mysqladmin ping --host mysql -u${DBUSER} -p${DBPASS} --silent; do
sleep 2
done
diff --git a/data/Dockerfiles/sogo/bootstrap-sogo.sh b/data/Dockerfiles/sogo/bootstrap-sogo.sh
index 92acb5912..77fad5313 100755
--- a/data/Dockerfiles/sogo/bootstrap-sogo.sh
+++ b/data/Dockerfiles/sogo/bootstrap-sogo.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# Wait for MySQL to warm-up
-while mysqladmin ping --host 172.22.1.250 --silent; do
+while mysqladmin ping --host mysql -u${DBUSER} -p${DBPASS}${DBPASS} --silent; do
# Wait until port becomes free and send sig
until ! nc -z sogo-mailcow 20000;
diff --git a/data/conf/dovecot/dovecot.conf b/data/conf/dovecot/dovecot.conf
index e478f0b25..59362958f 100644
--- a/data/conf/dovecot/dovecot.conf
+++ b/data/conf/dovecot/dovecot.conf
@@ -23,6 +23,7 @@ ssl_dh_parameters_length = 2048
log_timestamp = "%Y-%m-%d %H:%M:%S "
recipient_delimiter = +
auth_master_user_separator = *
+mail_shared_explicit_inbox = yes
mail_prefetch_count = 30
passdb {
driver = passwd-file
diff --git a/data/web/edit.php b/data/web/edit.php
index 0e7460bc7..4c60fadfc 100644
--- a/data/web/edit.php
+++ b/data/web/edit.php
@@ -138,7 +138,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
!empty($_GET["domain"])) {
$domain = $_GET["domain"];
$result = mailbox('get', 'domain_details', $domain);
- $rl = mailbox('get', 'domain_ratelimit', $domain);
+ $rl = mailbox('get', 'ratelimit', $domain);
$rlyhosts = relayhost('get');
if (!empty($result)) {
?>
@@ -251,7 +251,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
-
+
@@ -314,7 +314,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
!empty($_GET["aliasdomain"])) {
$alias_domain = $_GET["aliasdomain"];
$result = mailbox('get', 'alias_domain_details', $alias_domain);
- $rl = mailbox('get', 'domain_ratelimit', $alias_domain);
+ $rl = mailbox('get', 'ratelimit', $alias_domain);
if (!empty($result)) {
?>
=$lang['edit']['edit_alias_domain'];?>
@@ -353,7 +353,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
-
+
=$lang['edit']['mailbox'];?>
@@ -478,6 +479,23 @@ if (isset($_SESSION['mailcow_cc_role'])) {
+
+
sprintf($lang['success']['mailbox_modified'], implode(', ', $usernames))
);
break;
- case 'domain_ratelimit':
+ case 'ratelimit':
$rl_value = intval($_data['rl_value']);
$rl_frame = $_data['rl_frame'];
if (!in_array($rl_frame, array('s', 'm', 'h'))) {
@@ -1199,24 +1199,38 @@ function mailbox($_action, $_type, $_data = null) {
);
return false;
}
- if (!is_array($_data['domain'])) {
- $domains = array();
- $domains[] = $_data['domain'];
+ if (!is_array($_data['object'])) {
+ $objects = array();
+ $objects[] = $_data['object'];
}
else {
- $domains = $_data['domain'];
+ $objects = $_data['object'];
}
- foreach ($domains as $domain) {
- if (!is_valid_domain_name($domain) || !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
+ foreach ($objects as $object) {
+ if (is_valid_domain_name($object)) {
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ }
+ elseif (filter_var($object, FILTER_VALIDATE_EMAIL)) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ }
+ else {
return false;
}
if (empty($rl_value)) {
try {
- $redis->hDel('RL_VALUE', $domain);
+ $redis->hDel('RL_VALUE', $object);
}
catch (RedisException $e) {
$_SESSION['return'] = array(
@@ -1228,7 +1242,7 @@ function mailbox($_action, $_type, $_data = null) {
}
else {
try {
- $redis->hSet('RL_VALUE', $domain, $rl_value . ' / 1' . $rl_frame);
+ $redis->hSet('RL_VALUE', $object, $rl_value . ' / 1' . $rl_frame);
}
catch (RedisException $e) {
$_SESSION['return'] = array(
@@ -1241,7 +1255,7 @@ function mailbox($_action, $_type, $_data = null) {
}
$_SESSION['return'] = array(
'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_modified'], implode(', ', $domains))
+ 'msg' => sprintf($lang['success']['domain_modified'], implode(', ', $objects))
);
break;
case 'syncjob':
@@ -2385,9 +2399,26 @@ function mailbox($_action, $_type, $_data = null) {
}
return $aliases;
break;
- case 'domain_ratelimit':
- $aliases = array();
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ case 'ratelimit':
+ if (is_valid_domain_name($_data)) {
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ }
+ elseif (filter_var($_data, FILTER_VALIDATE_EMAIL)) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ }
+ else {
return false;
}
try {
diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php
index f63a42d85..9fe50fe7c 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 = "31082017_0853";
+ $db_version = "12092017_2254";
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
@@ -649,7 +649,7 @@ function init_db_schema() {
// Inject admin if not exists
$stmt = $pdo->query("INSERT INTO `admin` (`username`, `password`, `superadmin`, `created`, `modified`, `active`)
- SELECT 'admin', '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1
+ SELECT 'admin', '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1 FROM `admin`
WHERE NOT EXISTS (SELECT * FROM `admin`);");
$stmt = $pdo->query("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
SELECT `username`, 'ALL', NOW(), 1 FROM `admin`
diff --git a/data/web/json_api.php b/data/web/json_api.php
index b7acb724e..ec7899c7c 100644
--- a/data/web/json_api.php
+++ b/data/web/json_api.php
@@ -2133,13 +2133,13 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
));
}
break;
- case "domain-ratelimit":
+ case "ratelimit":
if (isset($_POST['items']) && isset($_POST['attr'])) {
$items = (array)json_decode($_POST['items'], true);
$attr = (array)json_decode($_POST['attr'], true);
- $postarray = array_merge(array('domain' => $items), $attr);
- if (is_array($postarray['domain'])) {
- if (mailbox('edit', 'domain_ratelimit', $postarray) === false) {
+ $postarray = array_merge(array('object' => $items), $attr);
+ if (is_array($postarray['object'])) {
+ if (mailbox('edit', 'ratelimit', $postarray) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
diff --git a/docker-compose.yml b/docker-compose.yml
index 8704abb1c..2bee1e40d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -23,10 +23,10 @@ services:
- unbound
mysql-mailcow:
- image: mariadb:10.1
- command: mysqld --max_allowed_packet=128M --max-connections=1500
+ image: mariadb:10.2
+ command: mysqld --max_allowed_packet=192M --max-connections=1500 --innodb-strict-mode=0 --skip-host-cache --skip-name-resolve --log-warnings=0
healthcheck:
- test: ["CMD", "mysqladmin", "ping", "--host", "localhost", "--silent"]
+ test: ["CMD", "mysqladmin", "-u$DBUSER", "-p$DBPASS", "ping", "-h", "localhost"]
interval: 5s
timeout: 5s
retries: 10
@@ -108,7 +108,7 @@ services:
- rspamd
php-fpm-mailcow:
- image: mailcow/phpfpm:1.0
+ image: mailcow/phpfpm:1.1
build: ./data/Dockerfiles/phpfpm
command: "php-fpm -d date.timezone=${TZ}"
depends_on:
@@ -140,7 +140,7 @@ services:
- phpfpm
sogo-mailcow:
- image: mailcow/sogo:1.7
+ image: mailcow/sogo:1.8
build: ./data/Dockerfiles/sogo
depends_on:
unbound-mailcow:
diff --git a/update.sh b/update.sh
index 62b23d10e..af4fa1a79 100755
--- a/update.sh
+++ b/update.sh
@@ -74,7 +74,7 @@ else
exit 1
fi
-read -r -p "Are you sure you want to update mailcow: dockerized? All containers will be stopped. [y/N] " response
+read -r -p "Are you sure you want to update mailcow: dockerized? [y/N] " response
if [[ ! "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
echo "OK, exiting."
exit 0
@@ -92,6 +92,7 @@ git commit -am "Before update on ${DATE}" > /dev/null
echo -e "\e[32mFetching updated code from remote...\e[0m"
git fetch origin ${BRANCH}
echo -e "\e[32mMerging local with remote code (recursive, options: \"theirs\", \"patience\"...\e[0m"
+git config merge.defaultToUpstream true
git merge -Xtheirs -Xpatience -m "After update on ${DATE}"
# Need to use a variable to not pass return codes of if checks
MERGE_RETURN=$?