diff --git src/listcontrol.c src/listcontrol.c
index d0c2e14..96e98d9 100644
--- src/listcontrol.c
+++ src/listcontrol.c
@@ -191,7 +191,7 @@ int listcontrol(struct email_container *fromemails, const char *listdir,
 	if(fromemails->emailcount != 1 && ctrl != CTRL_BOUNCES) {
 		errno = 0;
 		log_error(LOG_ARGS, "Ignoring mail with invalid From: "
-				"which was not a bounce");
+				"which was not a bounce: %d", fromemails->emailcount);
 		return -1;
 	}
 
diff --git src/mlmmj-process.c src/mlmmj-process.c
index 82e4d04..a9003e7 100644
--- src/mlmmj-process.c
+++ src/mlmmj-process.c
@@ -473,10 +473,12 @@ int main(int argc, char **argv)
 	struct stat st;
 	uid_t uid;
 	struct email_container fromemails = { 0, NULL };
+	struct email_container originalfromemails = { 0, NULL };
 	struct email_container toemails = { 0, NULL };
 	struct email_container ccemails = { 0, NULL };
 	struct email_container rpemails = { 0, NULL };
 	struct email_container dtemails = { 0, NULL };
+	struct email_container *testfrom = NULL;
 	struct strlist *access_rules = NULL;
 	struct strlist *delheaders = NULL;
 	struct strlist allheaders;
@@ -488,6 +490,7 @@ int main(int argc, char **argv)
 		{ "Return-Path:", 0, NULL },
 		{ "Delivered-To:", 0, NULL },
 		{ "Subject:", 0, NULL },
+		{ "X-Original-From:", 0, NULL },
 		{ NULL, 0, NULL }
 	};
 
@@ -708,6 +711,11 @@ int main(int argc, char **argv)
 	for(i = 0; i < readhdrs[0].valuecount; i++) {
 		find_email_adr(readhdrs[0].values[i], &fromemails);
 	}
+	/* X-Original-From: addresses */
+	for(i = 0; i < readhdrs[6].valuecount; i++) {
+		find_email_adr(readhdrs[6].values[i], &originalfromemails);
+	}
+
 	/* discard malformed mail with invalid From: unless it's a bounce */
 	if(fromemails.emailcount != 1 &&
 			(recipextra == NULL ||
@@ -812,7 +820,11 @@ int main(int argc, char **argv)
 		log_error(LOG_ARGS, "listcontrol(from, %s, %s, %s, %s, %s, %s, %s)\n", listdir, toemails.emaillist[0], mlmmjsub, mlmmjunsub, mlmmjsend, mlmmjbounce, donemailname);
 #endif
 		unlink(mailfile);
-		listcontrol(&fromemails, listdir, recipextra,
+		if (originalfromemails.emailcount > 0)
+			testfrom = &originalfromemails;
+		else
+			testfrom = &fromemails;
+		listcontrol(testfrom, listdir, recipextra,
 			    mlmmjsub, mlmmjunsub, mlmmjsend, mlmmjbounce,
 			    donemailname);
 
@@ -1036,7 +1048,10 @@ int main(int argc, char **argv)
 	if(!send && (subonlypost || modonlypost || modnonsubposts)) {
 		/* Don't send a mail about denial to the list, but silently
 		 * discard and exit. */
-		if (strcasecmp(listaddr, posteraddr) == 0) {
+		char *testaddr = posteraddr;
+		if (originalfromemails.emailcount > 0)
+			testaddr = originalfromemails.emaillist[0];
+		if (strcasecmp(listaddr, testaddr) == 0) {
 			log_error(LOG_ARGS, "Discarding %s because"
 					" there are sender restrictions but"
 					" From: was the list address",
@@ -1047,10 +1062,10 @@ int main(int argc, char **argv)
 			exit(EXIT_SUCCESS);
 		}
 		if(subonlypost) {
-			foundaddr = (is_subbed(listdir, posteraddr, 0) !=
+			foundaddr = (is_subbed(listdir, testaddr, 0) !=
 					SUB_NONE);
 		} else if (modonlypost) {
-			foundaddr = is_moderator(listdir, posteraddr, NULL);
+			foundaddr = is_moderator(listdir, testaddr, NULL);
 		}
 		if(!foundaddr) {
 			if(modnonsubposts) {
@@ -1086,10 +1101,10 @@ int main(int argc, char **argv)
 			    }
 			    MY_ASSERT(txt);
 			    register_unformatted(txt, "subject", subject);
-			    register_unformatted(txt, "posteraddr", posteraddr);
+			    register_unformatted(txt, "posteraddr", testaddr);
 			    register_originalmail(txt, donemailname);
 			    queuefilename = prepstdreply(txt, listdir,
-				    "$listowner$", posteraddr, NULL);
+				    "$listowner$", testaddr, NULL);
 			    MY_ASSERT(queuefilename)
 			    close_text(txt);
 			    myfree(listaddr);
@@ -1101,7 +1116,7 @@ int main(int argc, char **argv)
 			    execlp(mlmmjsend, mlmmjsend,
 				    "-L", listdir,
 				    "-l", "1",
-				    "-T", posteraddr,
+				    "-T", testaddr,
 				    "-F", fromaddr,
 				    "-m", queuefilename, (char *)NULL);
 
