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">&times;</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: