diff --git a/data/Dockerfiles/sogo/reconf-domains.sh b/data/Dockerfiles/sogo/reconf-domains.sh index 78482859..8cc24052 100755 --- a/data/Dockerfiles/sogo/reconf-domains.sh +++ b/data/Dockerfiles/sogo/reconf-domains.sh @@ -1,17 +1,27 @@ #!/bin/bash -# Go in a 5 minute loop -while true; do +# Recreate view - # Wait for MySQL to warm-up - while ! mysqladmin ping --host mysql --silent; do - sleep 1 - done +mysql --host mysql -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "DROP VIEW IF EXISTS sogo_view" - mkdir -p /var/lib/sogo/GNUstep/Defaults/ +mysql --host mysql -u ${DBUSER} -p${DBPASS} ${DBNAME} << EOF +CREATE VIEW sogo_view (c_uid, domain, c_name, c_password, c_cn, mail, aliases, ad_aliases, senderacl, home) AS +SELECT mailbox.username, mailbox.domain, mailbox.username, mailbox.password, mailbox.name, mailbox.username, IFNULL(ga.aliases, ''), IFNULL(gda.ad_alias, ''), IFNULL(gs.send_as, ''), CONCAT('/var/vmail/', maildir) FROM mailbox +LEFT OUTER JOIN grouped_mail_aliases ga ON ga.username = mailbox.username +LEFT OUTER JOIN grouped_sender_acl gs ON gs.username = mailbox.username +LEFT OUTER JOIN grouped_domain_alias_address gda ON gda.username = mailbox.username +WHERE mailbox.active = '1'; +EOF - # Generate plist header with timezone data - cat <<EOF > /var/lib/sogo/GNUstep/Defaults/sogod.plist +# Wait for MySQL to warm-up +while ! mysqladmin ping --host mysql --silent; do + sleep 1 +done + +mkdir -p /var/lib/sogo/GNUstep/Defaults/ + +# Generate plist header with timezone data +cat <<EOF > /var/lib/sogo/GNUstep/Defaults/sogod.plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//GNUstep//DTD plist 0.9//EN" "http://www.gnustep.org/plist-0_9.xml"> <plist version="0.9"> @@ -22,6 +32,8 @@ while true; do <string>mysql://${DBUSER}:${DBPASS}@mysql:3306/${DBNAME}/sogo_cache_folder</string> <key>OCSEMailAlarmsFolderURL</key> <string>mysql://${DBUSER}:${DBPASS}@mysql:3306/${DBNAME}/sogo_alarms_folder</string> + <key>DomainFieldName</key> + <string>domain</string> <key>OCSFolderInfoURL</key> <string>mysql://${DBUSER}:${DBPASS}@mysql:3306/${DBNAME}/sogo_folder_info</string> <key>OCSSessionsFolderURL</key> @@ -36,14 +48,14 @@ while true; do <dict> EOF - # Generate multi-domain setup - while read line +# Generate multi-domain setup +while read line do DOMAIN_SANE=$(echo ${line} | tr '-' 'b' | tr '.' 'p' | tr -cd '[[:alnum:]]') echo " <key>${line}</key> <dict> <key>SOGoMailDomain</key> - <string>$(echo ${line} | tr '-' 'b' | tr '.' 'p')</string> + <string>${DOMAIN_SANE}</string> <key>SOGoUserSources</key> <array> <dict> @@ -72,30 +84,19 @@ EOF <key>userPasswordAlgorithm</key> <string>ssha256</string> <key>viewURL</key> - <string>mysql://${DBUSER}:${DBPASS}@mysql:3306/${DBNAME}/sogo_view_${DOMAIN_SANE}</string> + <string>mysql://${DBUSER}:${DBPASS}@mysql:3306/${DBNAME}/sogo_view</string> </dict> </array> </dict>" >> /var/lib/sogo/GNUstep/Defaults/sogod.plist - mysql --host mysql -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "DROP VIEW IF EXISTS sogo_view_${DOMAIN_SANE}" - mysql --host mysql -u ${DBUSER} -p${DBPASS} ${DBNAME} << EOF -CREATE VIEW sogo_view_${DOMAIN_SANE} (c_uid, c_name, c_password, c_cn, mail, aliases, ad_aliases, senderacl, home) AS -SELECT mailbox.username, mailbox.username, mailbox.password, mailbox.name, mailbox.username, IFNULL(ga.aliases, ''), IFNULL(gda.ad_alias, ''), IFNULL(gs.send_as, ''), CONCAT('/var/vmail/', maildir) FROM mailbox -LEFT OUTER JOIN grouped_mail_aliases ga ON ga.username = mailbox.username -LEFT OUTER JOIN grouped_sender_acl gs ON gs.username = mailbox.username -LEFT OUTER JOIN grouped_domain_alias_address gda ON gda.username = mailbox.username -WHERE mailbox.active = '1' AND domain = '${line}'; -EOF done < <(mysql --host mysql -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "SELECT domain FROM domain;" -B -N) - # Generate footer - echo ' </dict> +# Generate footer +echo ' </dict> </dict> </plist>' >> /var/lib/sogo/GNUstep/Defaults/sogod.plist - # Fix permissions - chown sogo:sogo -R /var/lib/sogo/ - chmod 600 /var/lib/sogo/GNUstep/Defaults/sogod.plist +# Fix permissions +chown sogo:sogo -R /var/lib/sogo/ +chmod 600 /var/lib/sogo/GNUstep/Defaults/sogod.plist - sleep 300 - -done +sleep infinite diff --git a/data/conf/nginx/site.conf b/data/conf/nginx/site.conf index 43570d0c..ffc3f607 100644 --- a/data/conf/nginx/site.conf +++ b/data/conf/nginx/site.conf @@ -27,6 +27,10 @@ server { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param PHP_VALUE "max_execution_time = 1200 + max_input_time = 1200 + memory_limit = 64M"; + fastcgi_read_timeout 1200; } rewrite ^(/save.+)$ /rspamd$1 last; diff --git a/data/web/inc/footer.inc.php b/data/web/inc/footer.inc.php index 052f03b2..b2976bec 100644 --- a/data/web/inc/footer.inc.php +++ b/data/web/inc/footer.inc.php @@ -6,12 +6,12 @@ if ($_SESSION['mailcow_cc_role'] == "admin"): <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> - <h4 class="modal-title">Restart SOGo</h4> + <h4 class="modal-title"><?=$lang['footer']['restart_sogo'];?></h4> </div> <div class="modal-body"> - <p>Some tasks, e.g. adding a domain, require you to restart SOGo to catch changes made in the mailcow UI.</p> + <p><?=$lang['footer']['restart_sogo_info'];?></p> <hr /> - <button class="btn btn-md btn-primary" id="triggerRestartSogo">Restart SOGo</button> + <button class="btn btn-md btn-primary" id="triggerRestartSogo"><?=$lang['footer']['restart_now'];?></button> <br /><br /> <div id="statusTriggerRestartSogo"></div> </div> diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index ce1b374e..cfa3fdb4 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -8,11 +8,12 @@ function hasDomainAccess($username, $role, $domain) { if (!filter_var($username, FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) { return false; } - if (!is_valid_domain_name($domain)) { return false; } - + if ($role != 'admin' && $role != 'domainadmin' && $role != 'user') { + return false; + } try { $stmt = $pdo->prepare("SELECT `domain` FROM `domain_admins` WHERE ( @@ -2192,6 +2193,9 @@ function delete_domain_admin($postarray) { function get_spam_score($username) { global $pdo; $default = "5, 15"; + if ($_SESSION['mailcow_cc_role'] != "user") { + return false; + } if (!filter_var($username, FILTER_VALIDATE_EMAIL)) { return $default; } @@ -2235,6 +2239,13 @@ function get_spam_score($username) { function set_spam_score($postarray) { global $lang; global $pdo; + if ($_SESSION['mailcow_cc_role'] != "user") { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } $username = $_SESSION['mailcow_cc_username']; $lowspamlevel = explode(',', $postarray['score'])[0]; $highspamlevel = explode(',', $postarray['score'])[1]; @@ -2288,7 +2299,15 @@ function set_spam_score($postarray) { function set_policy_list($postarray) { global $lang; global $pdo; - + if ($_SESSION['mailcow_cc_role'] != "admin" && + $_SESSION['mailcow_cc_role'] != "domainadmin" && + $_SESSION['mailcow_cc_role'] != "user") { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } (isset($postarray['domain'])) ? $object = $postarray['domain'] : $object = $_SESSION['mailcow_cc_username']; ($postarray['object_list'] == "bl") ? $object_list = "blacklist_from" : $object_list = "whitelist_from"; $object_from = preg_replace('/\.+/', '.', rtrim(preg_replace("/\.\*/", "*", trim(strtolower($postarray['object_from']))), '.')); @@ -2389,6 +2408,13 @@ function set_policy_list($postarray) { function set_tls_policy($postarray) { global $lang; global $pdo; + if ($_SESSION['mailcow_cc_role'] != "user") { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } isset($postarray['tls_in']) ? $tls_in = '1' : $tls_in = '0'; isset($postarray['tls_out']) ? $tls_out = '1' : $tls_out = '0'; $username = $_SESSION['mailcow_cc_username']; @@ -2422,6 +2448,9 @@ function set_tls_policy($postarray) { function get_tls_policy($username) { global $lang; global $pdo; + if ($_SESSION['mailcow_cc_role'] != "user") { + return false; + } if (!filter_var($username, FILTER_VALIDATE_EMAIL)) { $_SESSION['return'] = array( 'type' => 'danger', diff --git a/data/web/inc/header.inc.php b/data/web/inc/header.inc.php index 2059f0e6..d72ec73f 100644 --- a/data/web/inc/header.inc.php +++ b/data/web/inc/header.inc.php @@ -226,7 +226,7 @@ endif; <?php if ($_SESSION['mailcow_cc_role'] == "admin"): ?> - <li><a href data-toggle="modal" data-target="#RestartSOGo"><span style="font-size:12px" class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Restart SOGo</a></li> + <li><a href data-toggle="modal" data-target="#RestartSOGo"><span style="font-size:12px" class="glyphicon glyphicon-refresh" aria-hidden="true"></span> <?=$lang['header']['restart_sogo'];?></a></li> <?php endif; ?> diff --git a/data/web/lang/lang.de.php b/data/web/lang/lang.de.php index dc96774e..09b79c9b 100644 --- a/data/web/lang/lang.de.php +++ b/data/web/lang/lang.de.php @@ -5,7 +5,10 @@ // */ $lang['footer']['loading'] = 'Einen Moment bitte...'; -$lang['getmail']['no_status'] = 'Keinen letzten Vorgang festgestellt.'; +$lang['header']['restart_sogo'] = 'SOGo neustarten'; +$lang['footer']['restart_sogo'] = 'SOGo neustarten'; +$lang['footer']['restart_now'] = 'Jetzt neustarten'; +$lang['footer']['restart_sogo_info'] = 'Einige Änderungen an Domains benötigen einen Neustart SOGos. Hier können Sie SOGo neustarten.<br /><br /><b>Wichtig:</b> Ein korrekter Neustart SOGos kann eine Weile in Anspruch nehmen, bitte warten Sie, bis der Prozess vollständig beendet wurde.'; $lang['dkim']['confirm'] = 'Sind Sie sicher?'; $lang['danger']['dkim_not_found'] = 'DKIM-Record nicht gefunden'; $lang['danger']['dkim_remove_failed'] = 'Kann DKIM-Record nicht entfernen'; diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php index 4f227ede..ce9906d5 100644 --- a/data/web/lang/lang.en.php +++ b/data/web/lang/lang.en.php @@ -5,7 +5,10 @@ // */ $lang['footer']['loading'] = "Please wait..."; -$lang['getmail']['no_status'] = "No previous status found."; +$lang['header']['restart_sogo'] = 'Restart SOGo'; +$lang['footer']['restart_sogo'] = 'Restart SOGo'; +$lang['footer']['restart_now'] = 'Restart now'; +$lang['footer']['restart_sogo_info'] = 'Some tasks, e.g. adding a domain, require you to restart SOGo to catch changes made in the mailcow UI.<br /><br /><b>Important:</b> A graceful restart may take a while to complete, please wait for it to finish.'; $lang['dkim']['confirm'] = "Are you sure?"; $lang['danger']['dkim_not_found'] = "DKIM record not found"; $lang['danger']['dkim_remove_failed'] = "Cannot remove selected DKIM record"; diff --git a/docker-compose.yml b/docker-compose.yml index b91c5516..3888762c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -58,6 +58,7 @@ services: - ./data/conf/rspamd/local.d/:/etc/rspamd/local.d:ro - ./data/conf/rspamd/lua/:/etc/rspamd/lua/:ro - dkim-vol-1:/data/dkim + - rspamd-vol-1:/var/lib/rspamd restart: always dns: - 172.22.1.254 @@ -234,3 +235,4 @@ volumes: mysql-vol-1: dkim-vol-1: redis-vol-1: + rspamd-vol-1: