Index | Thread | Search

From:
Sven M. Hallberg <pesco@khjk.org>
Subject:
vacation(1): consume all input
To:
tech@openbsd.org
Date:
Thu, 22 Aug 2024 09:45:31 +0200

Download raw body.

Thread
Another problem with vacation, at least in combination with smtpd(8) is
that it will exit(0) when it determines that it wants to do nothing with
the particular message. This happens, typically, after inspecting the
headers and finding that this message is not directly addressed (via To:
or Cc:) to the user. So it exits without consuming the rest of the
message.

OpenSMTPd will interpret this as "mda terminated prematurely", treat the
message as not delivered, keep it in the queue, and report warnings
and eventual failure to its unsuspecting originator.

Should smtpd be okay with an early exit(0) or should vacation always
fully consume its input? Patch for the latter case below; applies on top
of my previous one.

--- vacation.c.bak	Thu Aug 22 09:32:39 2024
+++ vacation.c	Wed Aug 21 10:45:09 2024
@@ -73,6 +73,7 @@
 char from[MAXLINE];
 char subj[MAXLINE];
 
+void done(void);
 int junkmail(void);
 int nsearch(char *, char *);
 void readheaders(void);
@@ -175,11 +176,28 @@
 		sendmessage(pw->pw_name);
 	} else
 		(void)(db->close)(db);
-	exit(0);
+	done();
 	/* NOTREACHED */
 }
 
 /*
+ * done --
+ *	consume all remaining input and exit with success
+ *
+ * This is a waste, but smtpd might interpret anything else as "premature
+ * termination" and keep the message queued as undelivered.
+ */
+void
+done(void)
+{
+	char buf[MAXLINE];
+
+	while (fgets(buf, sizeof(buf), stdin) != NULL)
+		;
+	exit(0);
+}
+
+/*
  * readheaders --
  *	read mail headers
  */
@@ -213,7 +231,7 @@
 				if (*p == '\0')
 					break;	/* Auto-Submitted: no */
 			}
-			exit(0);
+			done();
 		case 'F':		/* "From " */
 		case 'f':
 			cont = 0;
@@ -224,7 +242,7 @@
 				(void)strlcpy(from, buf + 5, sizeof(from));
 				from[strcspn(from, "\n")] = '\0';
 				if (junkmail())
-					exit(0);
+					done();
 			}
 			break;
 		case 'L':		/* "List-Id:" */
@@ -235,7 +253,7 @@
 			 * mailing list, cf. RFC2919.
 			 */
 			if (strncasecmp(buf, "List-Id:", 8) == 0)
-				exit(0);
+				done();
 			break;
 		case 'R':		/* "Return-Path:" */
 		case 'r':
@@ -257,7 +275,7 @@
 			}
 			from[strcspn(from, "\n")] = '\0';
 			if (junkmail())
-				exit(0);
+				done();
 			break;
 		case 'P':		/* "Precedence:" */
 		case 'p':
@@ -269,7 +287,7 @@
 			if (!strncasecmp(p, "junk", 4) ||
 			    !strncasecmp(p, "bulk", 4) ||
 			    !strncasecmp(p, "list", 4))
-				exit(0);
+				done();
 			break;
 		case 'S':		/* Subject: */
 		case 's':
@@ -308,7 +326,7 @@
 				tome += nsearch(cur->name, buf);
 		}
 	if (!tome)
-		exit(0);
+		done();
 	if (!*from) {
 		/*
 		 * No initial "From " line or "Return-Path:" header.
@@ -316,7 +334,7 @@
 		 * NB: Return-Path is optional. If it is not present, we
 		 * shall not respond, cf. RFC 3834.
 		 */
-		exit(0);
+		done();
 	}
 }