diff -ru cyrus-imapd-2.2.8.orig/imap/lmtp_sieve.c cyrus-imapd-2.2.8/imap/lmtp_sieve.c
--- cyrus-imapd-2.2.8.orig/imap/lmtp_sieve.c	2004-06-01 10:47:16.000000000 -0300
+++ cyrus-imapd-2.2.8/imap/lmtp_sieve.c	2004-10-22 12:18:00.187080344 -0300
@@ -256,7 +256,7 @@
 }
 
 static int send_forward(const char *forwardto,
-			char *return_path,
+			const char *return_path,
 			struct protstream *file)
 {
     FILE *sm;
@@ -320,6 +320,7 @@
     script_data_t *sd = (script_data_t *) sc;
     message_data_t *m = ((sieve_msgdata_t *) mc)->m;
     char buf[8192], *sievedb = NULL;
+    const char *return_path;
     int res;
 
     /* if we have a msgid, we can track our redirects */
@@ -334,7 +335,13 @@
 	}
     }
 
-    if ((res = send_forward(rc->addr, m->return_path, m->data)) == 0) {
+    /* do we want to change the original MAIL FROM address? */
+    if (config_getswitch(IMAPOPT_SIEVEMAILFROMASUSER))
+	return_path = rc->fromaddr;
+    else
+	return_path = m->return_path;
+
+    if ((res = send_forward(rc->addr, return_path, m->data)) == 0) {
 	/* mark this message as redirected */
 	if (sievedb) duplicate_mark(buf, strlen(buf), 
 				    sievedb, strlen(sievedb), time(NULL), 0);
@@ -591,8 +598,13 @@
 
     smbuf[0] = "sendmail";
     smbuf[1] = "-i";		/* ignore dots */
-    smbuf[2] = "-f";
-    smbuf[3] = "<>";
+    if (config_getswitch(IMAPOPT_SIEVEMAILFROMASUSER)) {
+	smbuf[2] = "-f";
+	smbuf[3] = src->fromaddr;
+    } else {
+	smbuf[2] = "-f";
+	smbuf[3] = "<>";
+    }
     smbuf[4] = "--";
     smbuf[5] = src->addr;
     smbuf[6] = NULL;
diff -ru cyrus-imapd-2.2.8.orig/lib/imapoptions cyrus-imapd-2.2.8/lib/imapoptions
--- cyrus-imapd-2.2.8.orig/lib/imapoptions	2004-07-21 16:07:45.000000000 -0300
+++ cyrus-imapd-2.2.8/lib/imapoptions	2004-10-22 12:16:44.490942660 -0300
@@ -752,6 +752,12 @@
 /* If enabled, lmtpd will look for Sieve scripts in user's home
    directories: ~user/.sieve. */
 
+{ "sievemailfromasuser", 0, SWITCH }
+/* If enabled, the MAIL FROM address on redirect and vacation messages will
+   be set to the email of the user the message is being sent on behalf of.
+   The default is not to touch the MAIL FROM address on redirects and to use
+   the null-sender on vacation messages. */
+
 { "singleinstancestore", 1, SWITCH }
 /* If enabled, lmtpd and nntpd attempt to only write one copy of a message per
    partition and create hard links, resulting in a potentially large
diff -ru cyrus-imapd-2.2.8.orig/sieve/bc_eval.c cyrus-imapd-2.2.8/sieve/bc_eval.c
--- cyrus-imapd-2.2.8.orig/sieve/bc_eval.c	2004-07-29 12:42:31.000000000 -0300
+++ cyrus-imapd-2.2.8/sieve/bc_eval.c	2004-10-22 12:09:53.669747712 -0300
@@ -825,12 +825,23 @@
 
 	case B_REDIRECT:/*5*/
 	{
-	    ip = unwrap_string(bc, ip+1, &data, NULL);
-
-	    res = do_redirect(actions, data);
+	    char buf[128];
+	    char *fromaddr; /* relative to message we send */
+	    const char **s;
 
-	    if (res == SIEVE_RUN_ERROR)
-		*errmsg = "Redirect can not be used with Reject";
+	    strcpy(buf, "to");
+	    if (i->getenvelope(m, buf, &s) == SIEVE_OK) {
+		fromaddr = s[0];
+		
+		ip = unwrap_string(bc, ip+1, &data, NULL);
+		
+		res = do_redirect(actions, data, fromaddr);
+		
+		if (res == SIEVE_RUN_ERROR)
+		    *errmsg = "Redirect can not be used with Reject";
+	    } else {
+		res = SIEVE_RUN_ERROR; /* something is bad */
+	    }
 
 	    break;
 	}
diff -ru cyrus-imapd-2.2.8.orig/sieve/message.c cyrus-imapd-2.2.8/sieve/message.c
--- cyrus-imapd-2.2.8.orig/sieve/message.c	2004-07-15 12:02:51.000000000 -0300
+++ cyrus-imapd-2.2.8/sieve/message.c	2004-10-22 12:09:53.670747543 -0300
@@ -115,7 +115,7 @@
  *
  * incompatible with: reject
  */
-int do_redirect(action_list_t *a, const char *addr)
+int do_redirect(action_list_t *a, const char *addr, const char *fromaddr)
 {
     action_list_t *b = NULL;
 
@@ -135,6 +135,7 @@
 	return SIEVE_NOMEM;
     a->a = ACTION_REDIRECT;
     a->u.red.addr = addr;
+    a->u.red.fromaddr = fromaddr;
     a->next = NULL;
     b->next = a;
     return 0;
diff -ru cyrus-imapd-2.2.8.orig/sieve/message.h cyrus-imapd-2.2.8/sieve/message.h
--- cyrus-imapd-2.2.8.orig/sieve/message.h	2003-10-22 16:50:30.000000000 -0200
+++ cyrus-imapd-2.2.8/sieve/message.h	2004-10-22 12:09:53.671747373 -0300
@@ -114,7 +114,7 @@
 int do_reject(action_list_t *m, const char *msg);
 int do_fileinto(action_list_t *m, const char *mbox,
 		sieve_imapflags_t *imapflags);
-int do_redirect(action_list_t *m, const char *addr);
+int do_redirect(action_list_t *m, const char *addr, const char *fromaddr);
 int do_keep(action_list_t *m, sieve_imapflags_t *imapflags);
 int do_discard(action_list_t *m);
 int do_vacation(action_list_t *m, char *addr, char *fromaddr,
diff -ru cyrus-imapd-2.2.8.orig/sieve/sieve_interface.h cyrus-imapd-2.2.8/sieve/sieve_interface.h
--- cyrus-imapd-2.2.8.orig/sieve/sieve_interface.h	2003-10-22 16:50:30.000000000 -0200
+++ cyrus-imapd-2.2.8/sieve/sieve_interface.h	2004-10-22 12:09:53.672747203 -0300
@@ -73,6 +73,7 @@
 
 typedef struct sieve_redirect_context {
     const char *addr;
+    const char *fromaddr;
 } sieve_redirect_context_t;
 
 typedef struct sieve_reject_context {
