diff --git a/doc/extensions/editheader.txt b/doc/extensions/editheader.txt
index 172ce9c52e6b85b5501a4240ae95128bf33e5e40..1ac00d1e92f2c79be3d21565f9ff7a491a73a679 100644
--- a/doc/extensions/editheader.txt
+++ b/doc/extensions/editheader.txt
@@ -26,11 +26,23 @@ sieve_editheader_max_header_size = 2048
   command. The minimum value for this setting is 1024 bytes. The value is in
   bytes, unless followed by a k(ilo).
 
+sieve_editheader_forbid_add =
+  A space-separated list of headers that cannot be added to the message header.
+  Addition of the `Subject:' header cannot be prohibited, as required by the RFC
+  specification. Therefore, adding this header to this setting has no effect.
+
+sieve_editheader_forbid_delete =
+  A space-separated list of headers that cannot be deleted from the message
+  header. Deleting the `Received:' and `Auto-Submitted:' fields is always 
+  forbidden, while removing the `Subject:' header cannot be prohibited,
+  as required by the RFC specification. Therefore, adding one of these headers
+  to this setting has no effect.
+
 sieve_editheader_protected =
-  A space-separated list of headers that cannot be added to nor removed from the
-  message header. The `Received:' and `Auto-Submitted:' fields are always
-  protected and the `Subject:' header cannot be protected, as required by the
-  RFC specification; adding one of these headers to this setting has no effect.
+  A space-separated list of headers that cannot be added to or deleted from
+  the message header. This setting is provided for backwards compatibility. It
+  is a combination of the sieve_editheader_forbid_add and
+  sieve_editheader_forbid_delete settings. The same limitations apply. 
 
 Invalid values for the settings above will make the Sieve interpreter log
 a warning and revert to the default values.
@@ -45,7 +57,8 @@ plugin {
   # Header fiels must not exceed one 1k
   sieve_editheader_max_header_size = 1k
 
-  # Protect special header
-  sieve_editheader_protected = X-Verified
+  # Protected special headers
+  sieve_editheader_forbid_add = X-Verified
+  sieve_editheader_forbid_delete = X-Verified X-Seen
 }
 
diff --git a/src/lib-sieve/plugins/editheader/cmd-addheader.c b/src/lib-sieve/plugins/editheader/cmd-addheader.c
index b84fd71ff9b38272d9311fbd673dae86cefb7f44..401d65e7a8ad3a35b74156c9f9ce35f2c20427b9 100644
--- a/src/lib-sieve/plugins/editheader/cmd-addheader.c
+++ b/src/lib-sieve/plugins/editheader/cmd-addheader.c
@@ -130,10 +130,13 @@ static bool cmd_addheader_validate
 			return FALSE;
 		}
 
-		if ( ext_editheader_header_is_protected(cmd->ext, str_c(fname)) ) {
-			sieve_argument_validate_warning(valdtr, arg, "addheader command: "
-				"specified header field `%s' is protected; "
-				"modification will be denied", str_sanitize(str_c(fname), 80));
+		if ( !ext_editheader_header_allow_add
+			(cmd->ext, str_c(fname)) ) {
+			sieve_argument_validate_warning
+				(valdtr, arg, "addheader command: "
+					"adding specified header field `%s' is forbidden; "
+					"modification will be denied",
+					str_sanitize(str_c(fname), 80));
 		}
 	}
 
@@ -298,10 +301,11 @@ static int cmd_addheader_operation_execute
 		return SIEVE_EXEC_FAILURE;
 	}
 
-	if ( ext_editheader_header_is_protected(this_ext, str_c(field_name)) ) {
+	if ( !ext_editheader_header_allow_add
+		(this_ext, str_c(field_name)) ) {
 		sieve_runtime_warning(renv, NULL, "addheader action: "
-			"specified header field `%s' is protected; modification denied",
-			str_sanitize(str_c(field_name), 80));
+			"adding specified header field `%s' is forbidden; "
+			"modification denied", str_sanitize(str_c(field_name), 80));
 		return SIEVE_EXEC_OK;
 	}
 
diff --git a/src/lib-sieve/plugins/editheader/cmd-deleteheader.c b/src/lib-sieve/plugins/editheader/cmd-deleteheader.c
index 9aa00fcb40dbc72fc8747f6aa15f425b76d668ab..e4ec54623c999b378ae78ac1482e20ff9c27b630 100644
--- a/src/lib-sieve/plugins/editheader/cmd-deleteheader.c
+++ b/src/lib-sieve/plugins/editheader/cmd-deleteheader.c
@@ -259,10 +259,13 @@ static bool cmd_deleteheader_validate
 			return FALSE;
 		}
 
-		if ( ext_editheader_header_is_protected(cmd->ext, str_c(fname)) ) {
-			sieve_argument_validate_warning(valdtr, arg, "deleteheader command: "
-				"specified header field `%s' is protected; "
-				"modification will be denied", str_sanitize(str_c(fname), 80));
+		if ( !ext_editheader_header_allow_delete
+			(cmd->ext, str_c(fname)) ) {
+			sieve_argument_validate_warning
+				(valdtr, arg, "deleteheader command: "
+					"deleting specified header field `%s' is forbidden; "
+					"modification will be denied",
+					str_sanitize(str_c(fname), 80));
 		}
 	}
 
@@ -426,9 +429,11 @@ static int cmd_deleteheader_operation_execute
 		return SIEVE_EXEC_FAILURE;
 	}
 
-	if ( ext_editheader_header_is_protected(this_ext, str_c(field_name)) ) {
+	if ( !ext_editheader_header_allow_delete
+		(this_ext, str_c(field_name)) ) {
 		sieve_runtime_warning(renv, NULL, "deleteheader action: "
-			"specified header field `%s' is protected; modification denied",
+			"deleting specified header field `%s' is forbidden; "
+			"modification denied",
 			str_sanitize(str_c(field_name), 80));
 		return SIEVE_EXEC_OK;
 	}
diff --git a/src/lib-sieve/plugins/editheader/ext-editheader-common.c b/src/lib-sieve/plugins/editheader/ext-editheader-common.c
index b886b8e262e690f7d82daa97d36711b280b40800..3b36509ba4e3e25dbe99de1935db15304794f421 100644
--- a/src/lib-sieve/plugins/editheader/ext-editheader-common.c
+++ b/src/lib-sieve/plugins/editheader/ext-editheader-common.c
@@ -22,8 +22,8 @@
 struct ext_editheader_header {
 	const char *name;
 
-	/* may extend this later */
-	unsigned int protected:1;
+	unsigned int forbid_add:1;
+	unsigned int forbid_delete:1;
 };
 
 struct ext_editheader_config {
@@ -49,12 +49,49 @@ static struct ext_editheader_header *ext_editheader_config_header_find
 	return NULL;
 }
 
+static void ext_editheader_config_headers
+(struct sieve_instance *svinst,
+	struct ext_editheader_config *ext_config,
+	const char *setting, bool forbid_add, bool forbid_delete)
+{
+	const char *setval;
+
+	setval = sieve_setting_get(svinst, setting);
+	if ( setval != NULL ) {
+		const char **headers = t_strsplit_spaces(setval, " \t");
+
+		while ( *headers != NULL ) {
+			struct ext_editheader_header *header;
+
+			if ( !rfc2822_header_field_name_verify
+				(*headers, strlen(*headers)) ) {
+				sieve_sys_warning(svinst, "editheader: "
+					"setting %s contains invalid header field name "
+					"`%s' (ignored)", setting, *headers);
+				continue;
+			}
+
+			header=ext_editheader_config_header_find(ext_config, *headers);
+			if ( header == NULL ) {
+				header = array_append_space(&ext_config->headers);
+				header->name = p_strdup(ext_config->pool, *headers);
+			}
+
+			if (forbid_add)
+				header->forbid_add = TRUE;
+			if (forbid_delete)
+				header->forbid_delete = TRUE;
+
+			headers++;
+		}
+	}
+}
+
 bool ext_editheader_load
 (const struct sieve_extension *ext, void **context)
 {
 	struct ext_editheader_config *ext_config;
 	struct sieve_instance *svinst = ext->svinst;
-	const char *protected;
 	size_t max_header_size;
 	pool_t pool;
 
@@ -71,31 +108,12 @@ bool ext_editheader_load
 
 		p_array_init(&ext_config->headers, pool, 16);
 
-		protected = sieve_setting_get(svinst, "sieve_editheader_protected");
-		if ( protected != NULL ) {
-			const char **headers = t_strsplit_spaces(protected, " \t");
-
-			while ( *headers != NULL ) {
-				struct ext_editheader_header *header;
-
-				if ( !rfc2822_header_field_name_verify(*headers, strlen(*headers)) ) {
-					sieve_sys_warning(svinst,
-						"editheader: setting sieve_editheader_protected contains "
-						"invalid header field name `%s' (ignored)", *headers);
-					continue;
-				}
-
-				header=ext_editheader_config_header_find(ext_config, *headers);
-				if ( header == NULL ) {
-					header = array_append_space(&ext_config->headers);
-					header->name = p_strdup(pool, *headers);
-				}
-
-				header->protected = TRUE;
-
-				headers++;
-			}
-		}
+		ext_editheader_config_headers(svinst, ext_config,
+			"sieve_editheader_protected", TRUE, TRUE);
+		ext_editheader_config_headers(svinst, ext_config,
+			"sieve_editheader_forbid_add", TRUE, FALSE);
+		ext_editheader_config_headers(svinst, ext_config,
+			"sieve_editheader_forbid_delete", FALSE, TRUE);
 
 		if ( sieve_setting_get_size_value
 			(svinst, "sieve_editheader_max_header_size", &max_header_size) ) {
@@ -129,26 +147,42 @@ void ext_editheader_unload(const struct sieve_extension *ext)
  * Protected headers
  */
 
-bool ext_editheader_header_is_protected
+bool ext_editheader_header_allow_add
 (const struct sieve_extension *ext, const char *hname)
 {
 	struct ext_editheader_config *ext_config =
 		(struct ext_editheader_config *) ext->context;
 	const struct ext_editheader_header *header;
 
-	if ( strcasecmp(hname, "received") == 0
-		|| strcasecmp(hname, "auto-submitted") == 0 ) {
+	if ( strcasecmp(hname, "subject") == 0 )
 		return TRUE;
-	}
 
-	if ( strcasecmp(hname, "subject") == 0 ) {
-		return FALSE;
-	}
+	if ( (header=ext_editheader_config_header_find
+		(ext_config, hname)) == NULL )
+		return TRUE;
+
+	return !header->forbid_add;
+}
 
-	if ( (header=ext_editheader_config_header_find(ext_config, hname)) == NULL )
+bool ext_editheader_header_allow_delete
+(const struct sieve_extension *ext, const char *hname)
+{
+	struct ext_editheader_config *ext_config =
+		(struct ext_editheader_config *) ext->context;
+	const struct ext_editheader_header *header;
+
+	if ( strcasecmp(hname, "received") == 0
+		|| strcasecmp(hname, "auto-submitted") == 0 )
 		return FALSE;
 
-	return header->protected;
+	if ( strcasecmp(hname, "subject") == 0 )
+		return TRUE;
+
+	if ( (header=ext_editheader_config_header_find
+		(ext_config, hname)) == NULL )
+		return TRUE;
+
+	return !header->forbid_delete;
 }
 
 /*
diff --git a/src/lib-sieve/plugins/editheader/ext-editheader-common.h b/src/lib-sieve/plugins/editheader/ext-editheader-common.h
index fc21d61c5bd7320f0f2967da7dba2c03ebcff341..f3d075b3f90f6bdd6c6f46af694a11504ec8d81a 100644
--- a/src/lib-sieve/plugins/editheader/ext-editheader-common.h
+++ b/src/lib-sieve/plugins/editheader/ext-editheader-common.h
@@ -37,8 +37,10 @@ void ext_editheader_unload(const struct sieve_extension *ext);
  * Protected headers
  */
 
-bool ext_editheader_header_is_protected
-	(const struct sieve_extension *ext, const char *header);
+bool ext_editheader_header_allow_add
+	(const struct sieve_extension *ext, const char *hname);
+bool ext_editheader_header_allow_delete
+	(const struct sieve_extension *ext, const char *hname);
 
 /*
  * Limits
diff --git a/tests/extensions/editheader/protected.svtest b/tests/extensions/editheader/protected.svtest
index e21415b02539c5da3c626975e643cab937f6363c..398fc9cb120f773eea80bde6e4264c0426c39284 100644
--- a/tests/extensions/editheader/protected.svtest
+++ b/tests/extensions/editheader/protected.svtest
@@ -9,6 +9,7 @@ Received: by example.com (Postfix, from userid 202)
 	id 32A131WFW23QWE4; Mon, 21 Nov 2011 05:25:26 +0200 (EET)
 Delivery-date: Mon, 21 Nov 2011 04:26:04 +0100
 Auto-Submitted: yes
+X-Friep: frop 3
 Subject: Frop!
 From: stephan@example.com
 To: tss@example.com
@@ -29,6 +30,7 @@ test "Default protected" {
 
 	deleteheader "received";
 	deleteheader "auto-submitted";
+	deleteheader "subject";
 
 	if not exists "received" {
 		test_fail "protected received header was deleted";
@@ -37,6 +39,10 @@ test "Default protected" {
 	if not exists "auto-submitted" {
 		test_fail "protected auto-submitted header was deleted";
 	}
+
+	if exists "subject" {
+		test_fail "subject header cannot be protected, but it was not deleted";
+	}
 }
 
 test_config_set "sieve_editheader_protected" "subject delivery-date x-frop";
@@ -72,3 +78,73 @@ test "Configured protected" {
 		test_fail "protected x-frop header was added";
 	}
 }
+
+test_config_set "sieve_editheader_protected" "";
+test_config_set "sieve_editheader_forbid_add" "subject x-frop";
+test_config_set "sieve_editheader_forbid_delete" "subject x-friep";
+test_config_reload :extension "editheader";
+
+test_set "message" "${message}";
+test "Configured forbid_add/forbid_delete" {
+	if not exists "delivery-date" {
+		test_fail "received header did not exist in the first place";
+	}
+
+	if not exists "subject" {
+		test_fail "received header did not exist in the first place";
+	}
+
+	if not exists "x-friep" {
+		test_fail "x-friep header did not exist in the first place";
+	}
+
+	if exists "x-frop" {
+		test_fail "x-frop header already present";
+	}
+
+	deleteheader "delivery-date";
+	deleteheader "subject";
+	deleteheader "x-friep";
+
+	if exists "delivery-date" {
+		test_fail "unprotected delivery-date header was not deleted";
+	}
+
+	if exists "subject" {
+		test_fail "subject header cannot be protected, but it was not deleted";
+	}
+
+	if not exists "x-friep" {
+		test_fail "protected x-friep header was deleted";
+	}
+
+	addheader "delivery-date" "Yesterday";
+	addheader "subject" "Fropfrop!";
+	addheader "x-frop" "Frop!";
+	addheader "received" text:
+by sieve.example.com (My little Sieve script)
+id 3jhl22khhf23f; Mon, 24 Aug 2015 04:11:54 -0600;
+.
+;
+	addheader "auto-submitted" "no way";
+
+	if not header "delivery-date" "Yesterday" {
+		test_fail "unprotected delivery-date header was not added";
+	}
+
+	if not header "subject" "Fropfrop!" {
+		test_fail "subject header cannot be protected, but it was not added";
+	}
+
+	if exists "x-frop" {
+		test_fail "protected x-frop header was added";
+	}
+
+	if not header :contains "received" "sieve.example.com" {
+		test_fail "received header was not added";
+	}
+
+	if not header "auto-submitted" "no way" {
+		test_fail "autosubmitted header was not added";
+	}
+}