1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
6 /* See the file NOTICE for conditions of use and distribution. */
8 /* Functions for sending messages to sender or to mailmaster. */
15 /*************************************************
16 * Write From: line for DSN *
17 *************************************************/
19 /* This function is called to write the From: line in automatically generated
20 messages - bounces, warnings, etc. It expands a configuration item in order to
21 get the text. If the expansion fails, a panic is logged and the default value
22 for the option is used.
24 Argument: the FILE to write to
29 moan_write_from(FILE *f)
31 uschar * s = expand_string(dsn_from);
34 log_write(0, LOG_MAIN|LOG_PANIC,
35 "Failed to expand dsn_from (using default): %s", expand_string_message);
36 s = expand_string(US DEFAULT_DSN_FROM);
38 fprintf(f, "From: %s\n", s);
43 /*************************************************
44 * Write References: line for DSN *
45 *************************************************/
47 /* Generate a References: header if there is in the header_list
48 at least one of Message-ID:, References:, or In-Reply-To: (see RFC 2822).
50 Arguments: f the FILE to write to
51 message_id optional already-found message-id, or NULL
57 moan_write_references(FILE * fp, uschar * message_id)
62 for (h = header_list; h; h = h->next)
63 if (h->type == htype_id)
65 message_id = Ustrchr(h->text, ':') + 1;
66 while (isspace(*message_id)) message_id++;
69 for (h = header_list; h; h = h->next)
70 if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0)
74 for (h = header_list; h; h = h->next)
75 if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0)
78 /* We limit the total length of references. Although there is no fixed
79 limit, some systems do not like headers growing beyond recognition.
80 Keep the first message ID for the thread root and the last few for
81 the position inside the thread, up to a maximum of 12 altogether. */
85 fprintf(fp, "References:");
88 uschar * s, * id, * error;
89 uschar * referenced_ids[12];
90 int reference_count = 0;
92 s = Ustrchr(h->text, ':') + 1;
93 f.parse_allow_group = FALSE;
94 while (*s && (s = parse_message_id(s, &id, &error)))
95 if (reference_count == nelem(referenced_ids))
97 memmove(referenced_ids + 1, referenced_ids + 2,
98 sizeof(referenced_ids) - 2*sizeof(uschar *));
99 referenced_ids[reference_count - 1] = id;
102 referenced_ids[reference_count++] = id;
104 for (int i = 0; i < reference_count; ++i)
105 fprintf(fp, " %s", referenced_ids[i]);
108 /* The message id will have a newline on the end of it. */
110 if (message_id) fprintf(fp, " %s", message_id);
111 else fprintf(fp, "\n");
117 /*************************************************
118 * Send error message *
119 *************************************************/
121 /* This function sends an error message by opening a pipe to a new process
122 running Exim, and writing a message to it using the "-t" option. This is not
123 used for delivery failures, which have their own code for handing failed
127 recipient addressee for the message
128 ident identifies the type of error
129 eblock chain of error_blocks containing data about the error
130 headers the message's headers
131 message_file FILE containing the body of the message
132 firstline contains first line of file, if it was read to check for
133 "From ", but it turned out not to be
135 Returns: TRUE if message successfully sent
139 moan_send_message(uschar *recipient, int ident, error_block *eblock,
140 header_line *headers, FILE *message_file, uschar *firstline)
146 int size_limit = bounce_return_size_limit;
153 /* For DMARC if there is a specific sender set, expand the variable for the
154 header From: and grab the address from that for the envelope FROM. */
156 if ( ident == ERRMESS_DMARC_FORENSIC
157 && dmarc_forensic_sender
158 && (s = expand_string(dmarc_forensic_sender))
160 && (s2 = expand_string(string_sprintf("${address:%s}", s)))
163 pid = child_open_exim2(&fd, s2, bounce_sender_authentication,
164 US"moan_send_message");
168 pid = child_open_exim(&fd, US"moan_send_message");
172 pid = child_open_exim(&fd, US"moan_send_message");
177 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
181 else DEBUG(D_any) debug_printf("Child process %d for sending message\n", pid);
183 /* Creation of child succeeded */
185 fp = fdopen(fd, "wb");
186 if (errors_reply_to) fprintf(fp, "Reply-To: %s\n", errors_reply_to);
187 fprintf(fp, "Auto-Submitted: auto-replied\n");
191 fprintf(fp, "From: %s\n", s);
196 fprintf(fp, "To: %s\n", recipient);
197 moan_write_references(fp, NULL);
201 case ERRMESS_BADARGADDRESS:
203 "Subject: Mail failure - malformed recipient address\n\n");
205 "A message that you sent contained a recipient address that was incorrectly\n"
207 fprintf(fp, " %s %s\n", eblock->text1, eblock->text2);
208 count = Ustrlen(eblock->text1);
209 if (count > 0 && eblock->text1[count-1] == '.')
211 "\nRecipient addresses must not end with a '.' character.\n");
213 "\nThe message has not been delivered to any recipients.\n");
216 case ERRMESS_BADNOADDRESS:
217 case ERRMESS_BADADDRESS:
219 "Subject: Mail failure - malformed recipient address\n\n");
221 "A message that you sent contained one or more recipient addresses that were\n"
222 "incorrectly constructed:\n\n");
226 fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2);
228 eblock = eblock->next;
231 fprintf(fp, (count == 1)? "\nThis address has been ignored. " :
232 "\nThese addresses have been ignored. ");
234 fprintf(fp, (ident == ERRMESS_BADADDRESS)?
235 "The other addresses in the message were\n"
236 "syntactically valid and have been passed on for an attempt at delivery.\n" :
238 "There were no other addresses in your\n"
239 "message, and so no attempt at delivery was possible.\n");
242 case ERRMESS_IGADDRESS:
243 fprintf(fp, "Subject: Mail failure - no recipient addresses\n\n");
245 "A message that you sent using the -t command line option contained no\n"
246 "addresses that were not also on the command line, and were therefore\n"
247 "suppressed. This left no recipient addresses, and so no delivery could\n"
251 case ERRMESS_NOADDRESS:
252 fprintf(fp, "Subject: Mail failure - no recipient addresses\n\n");
254 "A message that you sent contained no recipient addresses, and therefore no\n"
255 "delivery could be attempted.\n");
259 fprintf(fp, "Subject: Mail failure - system failure\n\n");
261 "A system failure was encountered while processing a message that you sent,\n"
262 "so it has not been possible to deliver it. The error was:\n\n%s\n",
266 case ERRMESS_VLONGHEADER:
267 fprintf(fp, "Subject: Mail failure - overlong header section\n\n");
269 "A message that you sent contained a header section that was excessively\n"
270 "long and could not be handled by the mail transmission software. The\n"
271 "message has not been delivered to any recipients.\n");
274 case ERRMESS_VLONGHDRLINE:
275 fprintf(fp, "Subject: Mail failure - overlong header line\n\n");
277 "A message that you sent contained a header line that was excessively\n"
278 "long and could not be handled by the mail transmission software. The\n"
279 "message has not been delivered to any recipients.\n");
283 fprintf(fp, "Subject: Mail failure - message too big\n\n");
285 "A message that you sent was longer than the maximum size allowed on this\n"
286 "system. It was not delivered to any recipients.\n");
289 case ERRMESS_TOOMANYRECIP:
290 fprintf(fp, "Subject: Mail failure - too many recipients\n\n");
292 "A message that you sent contained more recipients than allowed on this\n"
293 "system. It was not delivered to any recipients.\n");
296 case ERRMESS_LOCAL_SCAN:
297 case ERRMESS_LOCAL_ACL:
298 fprintf(fp, "Subject: Mail failure - rejected by local scanning code\n\n");
300 "A message that you sent was rejected by the local scanning code that\n"
301 "checks incoming messages on this system.");
303 fprintf(fp, " The following error was given:\n\n %s", eblock->text1);
308 case ERRMESS_DMARC_FORENSIC:
309 bounce_return_message = TRUE;
310 bounce_return_body = FALSE;
311 fprintf(fp, "Subject: DMARC Forensic Report for %s from IP %s\n\n",
312 eblock ? eblock->text2 : US"Unknown",
313 sender_host_address);
315 "A message claiming to be from you has failed the published DMARC\n"
316 "policy for your domain.\n\n");
319 fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2);
321 eblock = eblock->next;
327 fprintf(fp, "Subject: Mail failure\n\n");
329 "A message that you sent has caused the error routine to be entered with\n"
330 "an unknown error number (%d).\n", ident);
334 /* Now, if configured, copy the message; first the headers and then the rest of
335 the input if available, up to the configured limit, if the option for including
336 message bodies in bounces is set. */
338 if (bounce_return_message)
340 if (bounce_return_body)
343 "------ This is a copy of your message, including all the headers.");
344 if (size_limit == 0 || size_limit > thismessage_size_limit)
345 size_limit = thismessage_size_limit;
346 if (size_limit > 0 && size_limit < message_size)
356 "------ No more than %d%s characters of the body are included.\n\n",
359 else fprintf(fp, " ------\n\n");
364 "------ This is a copy of the headers that were received before the "
365 "error\n was detected.\n\n");
368 /* If the error occurred before the Received: header was created, its text
369 field will still be NULL; just omit such a header line. */
373 if (headers->text != NULL) fprintf(fp, "%s", CS headers->text);
374 headers = headers->next;
377 if (ident != ERRMESS_VLONGHEADER && ident != ERRMESS_VLONGHDRLINE)
380 /* After early detection of an error, the message file may be STDIN,
381 in which case we might have to terminate on a line containing just "."
382 as well as on EOF. We may already have the first line in memory. */
384 if (bounce_return_body && message_file)
386 BOOL enddot = f.dot_ends && message_file == stdin;
387 uschar * buf = store_get(bounce_return_linesize_limit+2, TRUE);
389 if (firstline) fprintf(fp, "%s", CS firstline);
391 while (fgets(CS buf, bounce_return_linesize_limit+2, message_file))
395 if (enddot && *buf == '.' && buf[1] == '\n')
402 if (buf[len-1] != '\n')
403 { /* eat rest of partial line */
405 while ((ch = fgetc(message_file)) != EOF && ch != '\n') ;
408 if (size_limit > 0 && len > size_limit - written)
410 buf[size_limit - written] = '\0';
419 /* Overkill, but use exact test in case future code gets inserted */
420 else if (bounce_return_body && message_file == NULL)
422 /*XXX limit line length here? */
423 /* This doesn't print newlines, disable until can parse and fix
424 * output to be legible. */
425 fprintf(fp, "%s", expand_string(US"$message_body"));
429 /* Close the file, which should send an EOF to the child process
430 that is receiving the message. Wait for it to finish, without a timeout. */
433 status = child_close(pid, 0); /* Waits for child to close */
436 uschar *msg = US"Child mail process returned status";
438 log_write(0, LOG_MAIN, "%s %d: errno=%d: %s", msg, status, errno,
441 log_write(0, LOG_MAIN, "%s %d", msg, status);
450 /*************************************************
451 * Send message to sender *
452 *************************************************/
454 /* This function is called when errors are detected during the receipt of a
455 message. Delivery failures are handled separately in deliver.c.
457 If there is a valid sender_address, and the failing message is not a local
458 error message, then this function calls moan_send_message to send a message to
459 that person. If the sender's address is null, then an error has occurred with a
460 message that was generated by a mailer daemon. All we can do is to write
461 information to log files. The same action is taken if local_error_message is
462 set - this can happen for non null-senders in certain configurations where exim
463 doesn't run setuid root.
466 ident identifies the particular error
467 eblock chain of error_blocks containing data about the error
468 headers message's headers (chain)
469 message_file a FILE where the body of the message can be read
470 check_sender if TRUE, read the first line of the file for a possible
471 "From " sender (if a trusted caller)
473 Returns: FALSE if there is no sender_address to send to;
474 else the return from moan_send_message()
478 moan_to_sender(int ident, error_block *eblock, header_line *headers,
479 FILE *message_file, BOOL check_sender)
481 uschar *firstline = NULL;
482 uschar *msg = US"Error while reading message with no usable sender address";
484 if (message_reference)
485 msg = string_sprintf("%s (R=%s)", msg, message_reference);
487 /* Find the sender from a From line if permitted and possible */
489 if (check_sender && message_file && f.trusted_caller &&
490 Ufgets(big_buffer, BIG_BUFFER_SIZE, message_file) != NULL)
492 uschar *new_sender = NULL;
493 if (regex_match_and_setup(regex_From, big_buffer, 0, -1))
494 new_sender = expand_string(uucp_from_sender);
495 if (new_sender) sender_address = new_sender;
496 else firstline = big_buffer;
499 /* If viable sender address, send a message */
501 if (sender_address && sender_address[0] && !f.local_error_message)
502 return moan_send_message(sender_address, ident, eblock, headers,
503 message_file, firstline);
505 /* Otherwise, we can only log */
509 case ERRMESS_BADARGADDRESS:
510 case ERRMESS_BADNOADDRESS:
511 case ERRMESS_BADADDRESS:
512 log_write(0, LOG_MAIN, "%s: at least one malformed recipient address: "
513 "%s - %s", msg, eblock->text1, eblock->text2);
516 case ERRMESS_IGADDRESS:
517 case ERRMESS_NOADDRESS:
518 log_write(0, LOG_MAIN, "%s: no recipient addresses", msg);
521 /* This error has already been logged. */
525 case ERRMESS_VLONGHEADER:
526 log_write(0, LOG_MAIN, "%s: excessively long message header section read "
527 "(more than %d characters)", msg, header_maxsize);
530 case ERRMESS_VLONGHDRLINE:
531 log_write(0, LOG_MAIN, "%s: excessively long message header line read "
532 "(more than %d characters)", msg, header_line_maxsize);
536 log_write(0, LOG_MAIN, "%s: message too big (limit set to %d)", msg,
537 thismessage_size_limit);
540 case ERRMESS_TOOMANYRECIP:
541 log_write(0, LOG_MAIN, "%s: too many recipients (max set to %d)", msg,
545 case ERRMESS_LOCAL_SCAN:
546 log_write(0, LOG_MAIN, "%s: rejected by local_scan: %s", msg, eblock->text1);
549 case ERRMESS_LOCAL_ACL:
550 log_write(0, LOG_MAIN, "%s: rejected by non-SMTP ACL: %s", msg, eblock->text1);
554 log_write(0, LOG_MAIN|LOG_PANIC, "%s: unknown error number %d", msg,
564 /*************************************************
565 * Send message to someone *
566 *************************************************/
568 /* This is called when exim is configured to tell someone (often the
569 mailmaster) about some incident.
572 who address to send mail to
573 addr chain of deferred addresses whose details are to be included
574 subject subject text for the message
575 format a printf() format for the body of the message
576 ... arguments for the format
582 moan_tell_someone(uschar *who, address_item *addr,
583 const uschar *subject, const char *format, ...)
588 int pid = child_open_exim(&fd, US"moan_tell_someone");
592 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
597 f = fdopen(fd, "wb");
598 fprintf(f, "Auto-Submitted: auto-replied\n");
600 fprintf(f, "To: %s\n", who);
601 moan_write_references(f, NULL);
602 fprintf(f, "Subject: %s\n\n", subject);
603 va_start(ap, format);
604 vfprintf(f, format, ap);
609 fprintf(f, "\nThe following address(es) have yet to be delivered:\n");
610 for (; addr; addr = addr->next)
612 uschar * parent = addr->parent ? addr->parent->address : NULL;
613 fprintf(f, " %s", addr->address);
614 if (parent) fprintf(f, " <%s>", parent);
615 if (addr->basic_errno > 0) fprintf(f, ": %s", strerror(addr->basic_errno));
616 if (addr->message) fprintf(f, ": %s", addr->message);
622 child_close(pid, 0); /* Waits for child to close; no timeout */
627 /*************************************************
628 * Handle SMTP batch error *
629 *************************************************/
631 /* This is called when something goes wrong in batched (-bS) SMTP input.
632 Information is written to stdout and/or stderr, and Exim exits with a non-zero
633 completion code. BSMTP is almost always called by some other program, so it is
634 up to that program to interpret the return code and do something with the error
635 information, and also to preserve the batch input file for human analysis.
637 Formerly, Exim used to attempt to continue after some errors, but this strategy
638 has been abandoned as it can lead to loss of messages.
641 cmd_buffer the command causing the error, or NULL
642 format a printf() format
643 ... arguments for the format
645 Returns: does not return; exits from the program
646 exit code = 1 if some messages were accepted
647 exit code = 2 if no messages were accepted
651 moan_smtp_batch(uschar *cmd_buffer, const char *format, ...)
654 int yield = (receive_messagecount > 0)? 1 : 2;
656 DEBUG(D_any) debug_printf("Handling error in batched SMTP input\n");
658 /* On stdout, write stuff that a program could parse fairly easily. */
660 va_start(ap, format);
661 vfprintf(stdout, format, ap);
664 fprintf(stdout, "\nTransaction started in line %d\n",
665 bsmtp_transaction_linecount);
666 fprintf(stdout, "Error detected in line %d\n", receive_linecount);
667 if (cmd_buffer != NULL) fprintf(stdout, "%s\n", cmd_buffer);
669 /* On stderr, write stuff for human consumption */
672 "An error was detected while processing a file of BSMTP input.\n"
673 "The error message was:\n\n ");
675 va_start(ap, format);
676 vfprintf(stderr, format, ap);
680 "\n\nThe SMTP transaction started in line %d.\n"
681 "The error was detected in line %d.\n",
682 bsmtp_transaction_linecount, receive_linecount);
684 if (cmd_buffer != NULL)
686 fprintf(stderr, "The SMTP command at fault was:\n\n %s\n\n",
690 fprintf(stderr, "%d previous message%s successfully processed.\n",
691 receive_messagecount, (receive_messagecount == 1)? " was" : "s were");
693 fprintf(stderr, "The rest of the batch was abandoned.\n");
701 /*************************************************
702 * Check for error copies *
703 *************************************************/
705 /* This function is passed the recipient of an error message, and must check
706 the error_copies string to see whether there is an additional recipient list to
707 which errors for this recipient must be bcc'd. The incoming recipient is always
710 Argument: recipient address
711 Returns: additional recipient list or NULL
715 moan_check_errorcopy(uschar *recipient)
717 uschar *item, *localpart, *domain;
718 const uschar *listptr = errors_copy;
719 uschar *yield = NULL;
724 if (errors_copy == NULL) return NULL;
726 /* Set up pointer to the local part and domain, and compute the
727 length of the local part. */
729 localpart = recipient;
730 domain = Ustrrchr(recipient, '@');
731 if (domain == NULL) return NULL; /* should not occur, but avoid crash */
732 llen = domain++ - recipient;
734 /* Scan through the configured items */
736 while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))))
738 const uschar *newaddress = item;
739 const uschar *pattern = string_dequote(&newaddress);
741 /* If no new address found, just skip this item. */
743 while (isspace(*newaddress)) newaddress++;
744 if (*newaddress == 0) continue;
746 /* We now have an item to match as an address in item, and the additional
747 address in newaddress. If the pattern matches, expand the new address string
748 and return it. During expansion, make local part and domain available for
749 insertion. This requires a copy to be made; we can't just temporarily
750 terminate it, as the whole address is required for $0. */
752 if (match_address_list(recipient, TRUE, TRUE, &pattern, NULL, 0, UCHAR_MAX+1,
755 deliver_localpart = string_copyn(localpart, llen);
756 deliver_domain = domain;
757 yield = expand_string_copy(newaddress);
758 deliver_domain = deliver_localpart = NULL;
760 log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand %s when processing "
761 "errors_copy: %s", newaddress, expand_string_message);
766 DEBUG(D_any) debug_printf("errors_copy check returned %s\n",
767 (yield == NULL)? US"NULL" : yield);
775 /************************************************
776 * Handle skipped syntax errors *
777 ************************************************/
779 /* This function is called by the redirect router when it has skipped over one
780 or more syntax errors in the list of addresses. If there is an address to mail
781 to, send a message, and always write the information to the log. In the case of
782 a filter file, a "syntax error" might actually be something else, such as the
783 inability to open a log file. Thus, the wording of the error message is
787 rname the router name
788 eblock chain of error blocks
789 syntax_errors_to address to send mail to, or NULL
790 some TRUE if some addresses were generated; FALSE if none were
791 custom custom message text
793 Returns: FALSE if string expansion failed; TRUE otherwise
797 moan_skipped_syntax_errors(uschar *rname, error_block *eblock,
798 uschar *syntax_errors_to, BOOL some, uschar *custom)
804 for (error_block * e = eblock; e; e = e->next)
805 if (e->text2 != NULL)
806 log_write(0, LOG_MAIN, "%s router: skipped error: %s in \"%s\"",
807 rname, e->text1, e->text2);
809 log_write(0, LOG_MAIN, "%s router: skipped error: %s", rname,
812 if (!syntax_errors_to) return TRUE;
814 if (!(s = expand_string(syntax_errors_to)))
816 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
817 syntax_errors_to, expand_string_message);
821 /* If we can't create a process to send the message, just forget about
824 pid = child_open_exim(&fd, US"moan_skipped_syntax_errors");
828 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
833 f = fdopen(fd, "wb");
834 fprintf(f, "Auto-Submitted: auto-replied\n");
836 fprintf(f, "To: %s\n", s);
837 fprintf(f, "Subject: error(s) in forwarding or filtering\n\n");
838 moan_write_references(f, NULL);
842 if (!(t = expand_string(custom)))
844 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
845 custom, expand_string_message);
848 fprintf(f, "%s\n\n", t);
851 fprintf(f, "The %s router encountered the following error(s):\n\n",
854 for (error_block * e = eblock; e; e = e->next)
856 fprintf(f, " %s", e->text1);
857 if (e->text2 != NULL)
858 fprintf(f, " in the address\n \"%s\"", e->text2);
863 fprintf(f, "Other addresses were processed normally.\n");
865 fprintf(f, "No valid addresses were generated.\n");
868 child_close(pid, 0); /* Waits for child to close; no timeout */