Hi folks, 

First of all, let me say that I have just started experimenting with DBmail 
and have little knowledge of the C-syntax, so don't come to hard on me if I 
made an incorrect assumption somewhere. ;-)

Okay, that having said... DBmail looks to be a nice product, but I think I 
have come across a bug while using DBmail under Sendmail: When a mail is 
being send to a non-existent address the mail should be bounced but none will 
be sent. 

Using Google I found a note, and I think it was on this list, that the trick 
was adding the '-t' flag to the Sendmail parameter in dbmail.conf to tell 
Sendmail to parse the mail headers too for sender and recipients, which did 
the trick indeed. However, I then started trying forwards, and this caused 
loops. Well, logical actually, since the original address was kept in the To 
field, as I would like to and had expected. So the mail was being forwarded 
and received once again for being forwarded. So the '-t' flag was not a 
permanent solution. 
Looking at the code I noticed that the forwards were specifying the sender on 
the commandline while the other sendmail pipes where not.

Additionally I would prefer forwards being send with the original sender once 
again as the envelope sender (and not the DBmail configured postmaster 
address) and I would prefer to have bounces being sent with the null sender. 
Both things can be done by using the '-f' switch to the Sendmail binary. I do 
however not know if it goes the same for other mailservers.

Furthermore I've tried to make the Auto Notify address become a configuration 
setting instead of a hardcoded value (haven't tested this specific thing yet, 
since I am not planning on using it currently, but well, the code compiled 
<G>).

Then lastly I also would prefer it the auto-reply function worked in a 
differenct way (some testing seems to verify that it works the way I 
currently think it works): I believe it currently fetches the To and From 
fields from the mail headers, however I think it should be using the envelope 
sender and envelope recipient if possible. But well, that's a thing I might 
look into later perhaps... for now I am not planning on using that option 
either.

Well, I've attached my quick and dirty copy, paste and adapt patch (would have 
been better coding had a tried to add a function for it, but as said, my 
C-syntax knowledge isn't much; I can read it better then write it).

I think it is secure and so far it has not posed me any problems during my 
testing, but well, if you use it, it is all on your own risk, so don't blame 
me for what happens, especially not for catastrophic things like data losses. 
;-)

Then lastly but not least I wouldn't mind hearing comments about these issues 
from people who have been using the program a lot longer then I have. Have I 
been right, or wrong, misconfigured my installation perhaps, or is it 
Sendmail-only related. :P

Kind regards,

Guido

-- 
Chivalry, Schmivalry!
        Roger the thief has a
        method he uses for
        sneaky attacks:
Folks who are reading are
        Characteristically
        Always Forgetting to
        Guard their own bac ...
diff -urbN ./dbmail-1.2.1-orig/bounce.c ./dbmail-1.2.1-edited/bounce.c
--- ./dbmail-1.2.1-orig/bounce.c	2003-03-17 17:04:08.000000000 +0100
+++ ./dbmail-1.2.1-edited/bounce.c	2003-11-06 13:43:47.000000000 +0100
@@ -26,8 +26,9 @@
   void *sendmail_stream;
   struct list from_addresses;
   struct element *tmpelement;
+  char *sendmail_command, *escaped_to = NULL;
   field_t dbmail_from_address, sendmail, postmaster;
-
+  int i,j;
 
   /* reading configuration from db */
   GetConfigValue("DBMAIL_FROM_ADDRESS", &smtpItems, dbmail_from_address);
@@ -51,7 +52,6 @@
       return -1;
     }
 
-
   switch (type)
     {
     case BOUNCE_NO_SUCH_USER:
@@ -77,14 +77,48 @@
 	      /* open a stream to sendmail 
 		 the sendmail macro is defined in bounce.h */
 	      
-	      (FILE *)sendmail_stream=popen (sendmail,"w");
+		  /* Allocate a string twice the size of 'to' */
+		  escaped_to = (char*) my_malloc((strlen((char *)(tmpelement->data)) + 1) * 2 * sizeof(char));
+		  i = 0; j = 0;
+		  /* Get all characters from send_address, and escape every ' */
+		  while (i < (strlen((char *)(tmpelement->data)) + 1)) {
+			if (((char *)(tmpelement->data))[i] == '\'')
+		       	escaped_to[j++] = '\\';
+			escaped_to[j++] = ((char *)(tmpelement->data))[i++];
+		  }
+
+		  /* The leading 2 can be replaced by strlen(dbmail_from_address), but I chose to use the null sender */
+	      sendmail_command = (char *)my_malloc(2 + strlen(escaped_to) + strlen(sendmail)
+					    +9); /* +9 for (a) two extra spaces, (b) '-f', (c) four single quotes and (d) \0 */
+
+		  if (!sendmail_command)
+	      	  {
+	    	  	trace(TRACE_ERROR,"bounce(): out of memory");
+		      	my_free (escaped_to);
+		  	escaped_to = NULL;
+	    	  	return -1;
+    	          }
+		  sprintf (sendmail_command, "%s -f'%s' '%s'", sendmail, "<>", escaped_to);
+
+		  my_free (escaped_to);
+		  escaped_to = NULL;
+
+	      (FILE *)sendmail_stream=popen (sendmail_command,"w");
 
 	      if (sendmail_stream==NULL)
 		{
 		  /* could not open a succesfull stream */
-		  trace(TRACE_MESSAGE,"bounce(): could not open a pipe to %s",sendmail);
+			  trace(TRACE_MESSAGE,"bounce(): could not open a pipe to %s",sendmail_command);
+			  /* Clean up sendmail_command before returning */
+			  my_free (sendmail_command);
+			  sendmail_command = NULL;
 		  return -1;
 		}
+
+		  /* Clean up sendmail_command before continueing */
+		  my_free (sendmail_command);
+		  sendmail_command = NULL;
+
 	      fprintf ((FILE *)sendmail_stream,"From: %s\n",dbmail_from_address);
 	      fprintf ((FILE *)sendmail_stream,"To: %s\n",(char *)tmpelement->data);
 	      fprintf ((FILE *)sendmail_stream,"Subject: DBMAIL: delivery failure\n");
@@ -138,14 +172,48 @@
 	      /* open a stream to sendmail 
 		 the sendmail macro is defined in bounce.h */
 
-	      (FILE *)sendmail_stream=popen (sendmail,"w");
+		  /* Allocate a string twice the size of 'to' */
+		  escaped_to = (char*) my_malloc((strlen((char *)(tmpelement->data)) + 1) * 2 * sizeof(char));
+		  i = 0; j = 0;
+		  /* Get all characters from send_address, and escape every ' */
+		  while (i < (strlen((char *)(tmpelement->data)) + 1)) {
+			if (((char *)(tmpelement->data))[i] == '\'')
+		       	escaped_to[j++] = '\\';
+			escaped_to[j++] = ((char *)(tmpelement->data))[i++];
+		  }
+
+		  /* The leading 2 can be replaced by strlen(dbmail_from_address), but I chose to use the null sender */
+	      sendmail_command = (char *)my_malloc(2 + strlen(escaped_to) + strlen(sendmail)
+					    +9); /* +9 for (a) two extra spaces, (b) '-f', (c) four single quotes and (d) \0 */
+
+		  if (!sendmail_command)
+	      {
+	    	  trace(TRACE_ERROR,"bounce(): out of memory");
+		      my_free (escaped_to);
+		  	  escaped_to = NULL;
+	    	  return -1;
+    	  }
+		  sprintf (sendmail_command, "%s -f'%s' '%s'", sendmail, "<>", escaped_to);
+
+		  my_free (escaped_to);
+		  escaped_to = NULL;
+
+	      (FILE *)sendmail_stream=popen (sendmail_command,"w");
 
 	      if (sendmail_stream==NULL)
 		{
 		  /* could not open a succesfull stream */
-		  trace(TRACE_MESSAGE,"bounce(): could not open a pipe to %s",sendmail);
+			  trace(TRACE_MESSAGE,"bounce(): could not open a pipe to %s", sendmail_command);
+			  /* Clean up sendmail_command before returning */
+			  my_free (sendmail_command);
+			  sendmail_command = NULL;
 		  return -1;
 		}
+
+		  /* Clean up sendmail_command before continueing */
+		  my_free (sendmail_command);
+		  sendmail_command = NULL;
+
 	      fprintf ((FILE *)sendmail_stream,"From: %s\n",dbmail_from_address);
 	      fprintf ((FILE *)sendmail_stream,"To: %s\n",(char *)tmpelement->data);
 	      fprintf ((FILE *)sendmail_stream,"Subject: DBMAIL: delivery failure\n");
diff -urbN ./dbmail-1.2.1-orig/dbmail.conf ./dbmail-1.2.1-edited/dbmail.conf
--- ./dbmail-1.2.1-orig/dbmail.conf	2003-05-13 17:34:39.000000000 +0200
+++ ./dbmail-1.2.1-edited/dbmail.conf	2003-11-05 19:56:43.000000000 +0100
@@ -18,9 +18,10 @@
 [SMTP]
 SENDMAIL=/usr/sbin/sendmail			# your sendmail executable, this is needed for boucing mail
 [EMAIL PROTECTED]    # the email address where bounces come from 
[EMAIL PROTECTED]	# the email address where bounces come from 
 [EMAIL PROTECTED]			# postmaster's email address (which is used in the bounce messages)
 AUTO_NOTIFY=no
-AUTO_REPLY=yes
+AUTO_REPLY=no		# The code looks like it uses the TO header from the incoming email --> Mailinglists ?!?
 TRACE_LEVEL=5
 
 [POP]
diff -urbN ./dbmail-1.2.1-orig/forward.c ./dbmail-1.2.1-edited/forward.c
--- ./dbmail-1.2.1-orig/forward.c	2003-03-17 17:04:08.000000000 +0100
+++ ./dbmail-1.2.1-edited/forward.c	2003-11-06 13:45:12.000000000 +0100
@@ -27,7 +27,8 @@
   struct list descriptors; /* target streams */
   struct element *target=NULL;
   struct element *descriptor_temp=NULL;
-  char *sendmail_command=NULL;
+  char *sendmail_command, *escaped_from, *escaped_to =NULL;
+  int i,j;
   char *strblock=NULL;
   FILE *sendmail_pipe=NULL;
   int usedmem, totalmem;
@@ -87,19 +88,51 @@
       else
 	{
 	  /* pipe to sendmail */
-	  sendmail_command = (char *)my_malloc(strlen((char *)(target->data))+
-					    strlen(sendmail)+2); /* +2 for extra space and \0 */
+
+		  /* Allocate a string twice the size of 'to' */
+		  escaped_to = (char*) my_malloc((strlen((char *)(target->data)) + 1) * 2 * sizeof(char));
+		  i = 0; j = 0;
+		  /* Get all characters from send_address, and escape every ' */
+		  while (i < (strlen((char *)(target->data)) + 1)) {
+			if (((char *)(target->data))[i] == '\'')
+		       	escaped_to[j++] = '\\';
+			escaped_to[j++] = ((char *)(target->data))[i++];
+		  }
+
+		  /* Allocate a string twice the size of 'from' */
+		  escaped_from = (char*) my_malloc((strlen(from) + 1) * 2 * sizeof(char));
+		  i = 0; j = 0;
+		  /* Get all characters from send_address, and escape every ' */
+		  while (i < (strlen(from) + 1)) {
+			if (from[i] == '\'')
+		       	escaped_from[j++] = '\\';
+			escaped_from[j++] = from[i++];
+		  }
+
+	      sendmail_command = (char *)my_malloc(strlen(escaped_from) +
+			  			strlen(escaped_to) + strlen(sendmail)
+					    +9); /* +9 for (a) two extra spaces, (b) '-f', (c) four single quotes and (d) \0 */
+
 	  if (!sendmail_command)
 	    {
 	      trace(TRACE_ERROR,"pipe_forward(): out of memory");
 	      list_freelist(&descriptors.start);
 	      my_free(strblock);
+				my_free (escaped_to);
+				escaped_to = NULL;
+				my_free (escaped_from);
+				escaped_from = NULL;
 	      return -1;
 	    }
 
 	  trace (TRACE_DEBUG,"pipe_forward(): allocated memory for"
 		 " external command call");
-	  sprintf (sendmail_command, "%s %s",sendmail, (char *)(target->data));
+	  	  sprintf (sendmail_command, "%s -f'%s' '%s'", sendmail, escaped_from, escaped_to);
+
+		  my_free (escaped_to);
+		  escaped_to = NULL;
+		  my_free (escaped_from);
+		  escaped_from = NULL;
 	}
 
       trace (TRACE_INFO,"pipe_forward(): opening pipe to command "
diff -urbN ./dbmail-1.2.1-orig/injector.c ./dbmail-1.2.1-edited/injector.c
--- ./dbmail-1.2.1-orig/injector.c	2003-03-17 17:04:08.000000000 +0100
+++ ./dbmail-1.2.1-edited/injector.c	2003-11-06 11:57:28.000000000 +0100
@@ -658,6 +658,8 @@
 {
   struct element *el;
   FILE *bouncepipe;
+  char *sendmail_command, *escaped_bouncepath = NULL;
+  int i,j;
 
   if (!bouncepath)
     {
@@ -669,9 +671,43 @@
 
   while (el)
     {
-      bouncepipe = popen(sendmail, "w");
+	  /* Allocate a string twice the size of 'to' */
+	  escaped_bouncepath = (char*) my_malloc((strlen(bouncepath) + 1) * 2 * sizeof(char));
+	  i = 0; j = 0;
+	  /* Get all characters from send_address, and escape every ' */
+	  while (i < (strlen(bouncepath) + 1)) {
+		if (bouncepath[i] == '\'')
+	       	escaped_bouncepatho[j++] = '\\';
+		escaped_bouncepatho[j++] = bouncepath[i++];
+	  }
+
+	  /* The leading 2 can be replaced by strlen(postmaster), but I chose to use the null sender */
+	  sendmail_command = (char *)my_malloc(2 + strlen(escaped_bouncepath) +
+		strlen(sendmail) +9); /* +9 for (a) two extra spaces, (b) '-f', (c) four single quotes and (d) \0 */
+	  if (!sendmail_command)
+	  {
+		trace(TRACE_ERROR,"send_bounces(): out of memory");
+	    my_free (escaped_bouncepath);
+	    escaped_bouncepath = NULL;
+		return -1;
+	  }
+	  sprintf (sendmail_command, "%s -f'%s' '%s'", sendmail, "<>", escaped_bouncepath);
+
+	  my_free (escaped_bouncepath);
+	  escaped_bouncepath = NULL;
+
+	  bouncepipe = popen(sendmail_command, "w");
       if (!bouncepipe)
+	  {
+		/* Clean up sendmail_command before returning */
+		my_free (sendmail_command);
+		sendmail_command = NULL;
 	return -1;
+	  }
+
+	  /* Clean up sendmail_command before continueing */
+	  my_free (sendmail_command);
+	  sendmail_command = NULL;
 
       trace(TRACE_DEBUG, "send_bounces(): sending bounce to [%s] for [%s]", bouncepath, (char*)el->data);
 
@@ -706,6 +742,8 @@
 int send_quotum_bounce(const char *bouncepath, const char *sendmail, const char *postmaster, const char *fromaddr)
 {
   FILE *bouncepipe;
+  char *sendmail_command, *escaped_bouncepath = NULL;
+  int i,j;
 
   if (!bouncepath)
     {
@@ -713,9 +751,43 @@
       return 0;
     }
 
-  bouncepipe = popen(sendmail, "w");
+  /* Allocate a string twice the size of 'to' */
+  escaped_bouncepath = (char*) my_malloc((strlen(bouncepath) + 1) * 2 * sizeof(char));
+  i = 0; j = 0;
+  /* Get all characters from send_address, and escape every ' */
+  while (i < (strlen(bouncepath) + 1)) {
+	if (bouncepath[i] == '\'')
+       	escaped_bouncepatho[j++] = '\\';
+	escaped_bouncepatho[j++] = bouncepath[i++];
+  }
+
+  /* The leading 2 can be replaced by strlen(postmaster), but I chose to use the null sender */
+  sendmail_command = (char *)my_malloc(2 + strlen(escaped_bouncepath) +
+	strlen(sendmail) +9); /* +9 for (a) two extra spaces, (b) '-f', (c) four single quotes and (d) \0 */
+  if (!sendmail_command)
+  {
+	trace(TRACE_ERROR,"send_bounces(): out of memory");
+    my_free (escaped_bouncepath);
+    escaped_bouncepath = NULL;
+	return -1;
+  }
+  sprintf (sendmail_command, "%s -f'%s' '%s'", sendmail, "<>", escaped_bouncepath);
+
+  my_free (escaped_bouncepath);
+  escaped_bouncepath = NULL;
+
+  bouncepipe = popen(sendmail_command, "w");
   if (!bouncepipe)
+  {
+	  /* Clean up sendmail_command before returning */
+	  my_free (sendmail_command);
+	  sendmail_command = NULL;
     return -1;
+  }
+
+  /* Clean up sendmail_command before continueing */
+  my_free (sendmail_command);
+  sendmail_command = NULL;
 
   trace(TRACE_DEBUG, "send_bounces(): sending bounce to [%s]", bouncepath);
 
diff -urbN ./dbmail-1.2.1-orig/pipe.c ./dbmail-1.2.1-edited/pipe.c
--- ./dbmail-1.2.1-orig/pipe.c	2003-10-23 16:23:28.000000000 +0200
+++ ./dbmail-1.2.1-edited/pipe.c	2003-11-06 13:44:15.000000000 +0100
@@ -33,13 +33,12 @@
 #define MAX_U64_STRINGSIZE 40
 #define MAX_COMM_SIZE 512
 
-#define AUTO_NOTIFY_SENDER "[EMAIL PROTECTED]"
-#define AUTO_NOTIFY_SUBJECT "NEW MAIL NOTIFICATION"
+#define AUTO_NOTIFY_SUBJECT "New Mail Notification"
 
 extern struct list smtpItems, sysItems;
 
 
-int send_notification(const char *to, const char *from, const char *subject);
+int send_notification(const char *to, const char *subject);
 int send_reply(struct list *headerfields, const char *body);
 
 void create_unique_id(char *target, u64_t messageid)
@@ -459,7 +458,7 @@
 		      else
 			{
 			  trace(TRACE_DEBUG, "insert_messages(): sending notifcation to [%s]", notify_address);
-			  send_notification(notify_address, AUTO_NOTIFY_SENDER, AUTO_NOTIFY_SUBJECT);
+			  send_notification(notify_address, AUTO_NOTIFY_SUBJECT);
 			  my_free(notify_address);
 			}
 		    }
@@ -564,13 +563,15 @@
 }
 
 /*
- * send an automatic notification using sendmai
+ * send an automatic notification using sendmail
  */
-int send_notification(const char *to, const char *from, const char *subject)
+int send_notification(const char *to, const char *subject)
 {
   FILE *mailpipe = NULL;
-  field_t sendmail;
+  char *sendmail_command, *escaped_to = NULL;
+  field_t sendmail, an_from_address;
   int result;
+  int i,j;
 
   GetConfigValue("SENDMAIL", &smtpItems, sendmail);
   if (sendmail[0] == '\0')
@@ -578,16 +579,52 @@
 
   trace(TRACE_DEBUG, "send_notification(): found sendmail command to be [%s]", sendmail);
 
-  if (! (mailpipe = popen(sendmail, "w")) )
+  GetConfigValue("AUTO_NOTIFY_FROM_ADDRESS", &smtpItems, an_from_address);
+  if (an_from_address[0] == '\0')
+    trace(TRACE_FATAL, "send_notification(): AUTO_NOTIFY_FROM_ADDRESS not configured (see config file). Stop.");
+
+  /* Allocate a string twice the size of 'to' */
+  escaped_to = (char*) my_malloc((strlen(to) + 1) * 2 * sizeof(char));
+  i = 0; j = 0;
+  /* Get all characters from send_address, and escape every ' */
+  while (i < (strlen(to) + 1)) {
+	if (to[i] == '\'')
+       	escaped_to[j++] = '\\';
+	escaped_to[j++] = to[i++];
+  }
+
+  sendmail_command = (char *)my_malloc(	strlen(an_from_address) + strlen(escaped_to) + strlen(sendmail) + 9);
+  					/* +9 for (a) two extra spaces, (b) '-f', (c) four single quotes and (d) \0 */
+
+  if (!sendmail_command)
     {
-      trace(TRACE_ERROR, "send_notification(): could not open pipe to sendmail using cmd [%s]", sendmail);
+    	  trace(TRACE_ERROR,"send_notification(): out of memory");
+	  my_free (escaped_to);
+	  escaped_to = NULL;
+    	  return -1;
+  }
+  sprintf (sendmail_command, "%s -f'%s' '%s'", sendmail, an_from_address, escaped_to);
+
+  my_free (escaped_to);
+  escaped_to = NULL;
+
+  if (! (mailpipe = popen(sendmail_command, "w")) )
+  {
+      trace(TRACE_ERROR, "send_notification(): could not open pipe to sendmail using cmd [%s]", sendmail_command);
+	  /* Clean up sendmail_command before returning */
+	  my_free (sendmail_command);
+	  sendmail_command = NULL;
       return 1;
     }
 
+  /* Clean up sendmail_command before continueing */
+  my_free (sendmail_command);
+  sendmail_command = NULL;
+
   trace(TRACE_DEBUG, "send_notification(): pipe opened, sending data");
 
   fprintf(mailpipe, "To: %s\n", to);
-  fprintf(mailpipe, "From: %s\n", from);
+  fprintf(mailpipe, "From: %s\n", an_from_address);
   fprintf(mailpipe, "Subject: %s\n", subject);
   fprintf(mailpipe, "\n");
 
@@ -673,6 +710,9 @@
        escaped_send_address[j++] = send_address[i++];
   }
   snprintf(comm, MAX_COMM_SIZE, "%s '%s'", sendmail, escaped_send_address);   
+  		/*  I suppose I should add the -f flag here to, but the From address is not always known?
+  		    Ow, and if the TO address comes from the headers, then we are using the wrong one when
+  			it is received over a list, right? -- GD, 2003		*/
 
   if (! (mailpipe = popen(comm, "w")) )
     {

Reply via email to