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 * Send error message *
45 *************************************************/
47 /* This function sends an error message by opening a pipe to a new process
48 running Exim, and writing a message to it using the "-t" option. This is not
49 used for delivery failures, which have their own code for handing failed
53 recipient addressee for the message
54 ident identifies the type of error
55 eblock chain of error_blocks containing data about the error
56 headers the message's headers
57 message_file FILE containing the body of the message
58 firstline contains first line of file, if it was read to check for
59 "From ", but it turned out not to be
61 Returns: TRUE if message successfully sent
65 moan_send_message(uschar *recipient, int ident, error_block *eblock,
66 header_line *headers, FILE *message_file, uschar *firstline)
72 int size_limit = bounce_return_size_limit;
79 /* For DMARC if there is a specific sender set, expand the variable for the
80 header From: and grab the address from that for the envelope FROM. */
82 if ( ident == ERRMESS_DMARC_FORENSIC
83 && dmarc_forensic_sender
84 && (s = expand_string(dmarc_forensic_sender))
86 && (s2 = expand_string(string_sprintf("${address:%s}", s)))
89 pid = child_open_exim2(&fd, s2, bounce_sender_authentication);
93 pid = child_open_exim(&fd);
97 pid = child_open_exim(&fd);
102 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
106 else DEBUG(D_any) debug_printf("Child process %d for sending message\n", pid);
108 /* Creation of child succeeded */
110 fp = fdopen(fd, "wb");
111 if (errors_reply_to) fprintf(fp, "Reply-To: %s\n", errors_reply_to);
112 fprintf(fp, "Auto-Submitted: auto-replied\n");
116 fprintf(fp, "From: %s\n", s);
121 fprintf(fp, "To: %s\n", recipient);
125 case ERRMESS_BADARGADDRESS:
127 "Subject: Mail failure - malformed recipient address\n\n");
129 "A message that you sent contained a recipient address that was incorrectly\n"
131 fprintf(fp, " %s %s\n", eblock->text1, eblock->text2);
132 count = Ustrlen(eblock->text1);
133 if (count > 0 && eblock->text1[count-1] == '.')
135 "\nRecipient addresses must not end with a '.' character.\n");
137 "\nThe message has not been delivered to any recipients.\n");
140 case ERRMESS_BADNOADDRESS:
141 case ERRMESS_BADADDRESS:
143 "Subject: Mail failure - malformed recipient address\n\n");
145 "A message that you sent contained one or more recipient addresses that were\n"
146 "incorrectly constructed:\n\n");
148 while (eblock != NULL)
150 fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2);
152 eblock = eblock->next;
155 fprintf(fp, (count == 1)? "\nThis address has been ignored. " :
156 "\nThese addresses have been ignored. ");
158 fprintf(fp, (ident == ERRMESS_BADADDRESS)?
159 "The other addresses in the message were\n"
160 "syntactically valid and have been passed on for an attempt at delivery.\n" :
162 "There were no other addresses in your\n"
163 "message, and so no attempt at delivery was possible.\n");
166 case ERRMESS_IGADDRESS:
167 fprintf(fp, "Subject: Mail failure - no recipient addresses\n\n");
169 "A message that you sent using the -t command line option contained no\n"
170 "addresses that were not also on the command line, and were therefore\n"
171 "suppressed. This left no recipient addresses, and so no delivery could\n"
175 case ERRMESS_NOADDRESS:
176 fprintf(fp, "Subject: Mail failure - no recipient addresses\n\n");
178 "A message that you sent contained no recipient addresses, and therefore no\n"
179 "delivery could be attempted.\n");
183 fprintf(fp, "Subject: Mail failure - system failure\n\n");
185 "A system failure was encountered while processing a message that you sent,\n"
186 "so it has not been possible to deliver it. The error was:\n\n%s\n",
190 case ERRMESS_VLONGHEADER:
191 fprintf(fp, "Subject: Mail failure - overlong header section\n\n");
193 "A message that you sent contained a header section that was excessively\n"
194 "long and could not be handled by the mail transmission software. The\n"
195 "message has not been delivered to any recipients.\n");
198 case ERRMESS_VLONGHDRLINE:
199 fprintf(fp, "Subject: Mail failure - overlong header line\n\n");
201 "A message that you sent contained a header line that was excessively\n"
202 "long and could not be handled by the mail transmission software. The\n"
203 "message has not been delivered to any recipients.\n");
207 fprintf(fp, "Subject: Mail failure - message too big\n\n");
209 "A message that you sent was longer than the maximum size allowed on this\n"
210 "system. It was not delivered to any recipients.\n");
213 case ERRMESS_TOOMANYRECIP:
214 fprintf(fp, "Subject: Mail failure - too many recipients\n\n");
216 "A message that you sent contained more recipients than allowed on this\n"
217 "system. It was not delivered to any recipients.\n");
220 case ERRMESS_LOCAL_SCAN:
221 case ERRMESS_LOCAL_ACL:
222 fprintf(fp, "Subject: Mail failure - rejected by local scanning code\n\n");
224 "A message that you sent was rejected by the local scanning code that\n"
225 "checks incoming messages on this system.");
227 fprintf(fp, " The following error was given:\n\n %s", eblock->text1);
232 case ERRMESS_DMARC_FORENSIC:
233 bounce_return_message = TRUE;
234 bounce_return_body = FALSE;
235 fprintf(fp, "Subject: DMARC Forensic Report for %s from IP %s\n\n",
236 eblock ? eblock->text2 : US"Unknown",
237 sender_host_address);
239 "A message claiming to be from you has failed the published DMARC\n"
240 "policy for your domain.\n\n");
243 fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2);
245 eblock = eblock->next;
251 fprintf(fp, "Subject: Mail failure\n\n");
253 "A message that you sent has caused the error routine to be entered with\n"
254 "an unknown error number (%d).\n", ident);
258 /* Now, if configured, copy the message; first the headers and then the rest of
259 the input if available, up to the configured limit, if the option for including
260 message bodies in bounces is set. */
262 if (bounce_return_message)
264 if (bounce_return_body)
267 "------ This is a copy of your message, including all the headers.");
268 if (size_limit == 0 || size_limit > thismessage_size_limit)
269 size_limit = thismessage_size_limit;
270 if (size_limit > 0 && size_limit < message_size)
280 "------ No more than %d%s characters of the body are included.\n\n",
283 else fprintf(fp, " ------\n\n");
288 "------ This is a copy of the headers that were received before the "
289 "error\n was detected.\n\n");
292 /* If the error occurred before the Received: header was created, its text
293 field will still be NULL; just omit such a header line. */
297 if (headers->text != NULL) fprintf(fp, "%s", CS headers->text);
298 headers = headers->next;
301 if (ident != ERRMESS_VLONGHEADER && ident != ERRMESS_VLONGHDRLINE)
304 /* After early detection of an error, the message file may be STDIN,
305 in which case we might have to terminate on a line containing just "."
306 as well as on EOF. We may already have the first line in memory. */
308 if (bounce_return_body && message_file)
310 BOOL enddot = f.dot_ends && message_file == stdin;
311 uschar * buf = store_get(bounce_return_linesize_limit+2, TRUE);
313 if (firstline) fprintf(fp, "%s", CS firstline);
315 while (fgets(CS buf, bounce_return_linesize_limit+2, message_file))
319 if (enddot && *buf == '.' && buf[1] == '\n')
326 if (buf[len-1] != '\n')
327 { /* eat rest of partial line */
329 while ((ch = fgetc(message_file)) != EOF && ch != '\n') ;
332 if (size_limit > 0 && len > size_limit - written)
334 buf[size_limit - written] = '\0';
343 /* Overkill, but use exact test in case future code gets inserted */
344 else if (bounce_return_body && message_file == NULL)
346 /*XXX limit line length here? */
347 /* This doesn't print newlines, disable until can parse and fix
348 * output to be legible. */
349 fprintf(fp, "%s", expand_string(US"$message_body"));
353 /* Close the file, which should send an EOF to the child process
354 that is receiving the message. Wait for it to finish, without a timeout. */
357 status = child_close(pid, 0); /* Waits for child to close */
360 uschar *msg = US"Child mail process returned status";
362 log_write(0, LOG_MAIN, "%s %d: errno=%d: %s", msg, status, errno,
365 log_write(0, LOG_MAIN, "%s %d", msg, status);
374 /*************************************************
375 * Send message to sender *
376 *************************************************/
378 /* This function is called when errors are detected during the receipt of a
379 message. Delivery failures are handled separately in deliver.c.
381 If there is a valid sender_address, and the failing message is not a local
382 error message, then this function calls moan_send_message to send a message to
383 that person. If the sender's address is null, then an error has occurred with a
384 message that was generated by a mailer daemon. All we can do is to write
385 information to log files. The same action is taken if local_error_message is
386 set - this can happen for non null-senders in certain configurations where exim
387 doesn't run setuid root.
390 ident identifies the particular error
391 eblock chain of error_blocks containing data about the error
392 headers message's headers (chain)
393 message_file a FILE where the body of the message can be read
394 check_sender if TRUE, read the first line of the file for a possible
395 "From " sender (if a trusted caller)
397 Returns: FALSE if there is no sender_address to send to;
398 else the return from moan_send_message()
402 moan_to_sender(int ident, error_block *eblock, header_line *headers,
403 FILE *message_file, BOOL check_sender)
405 uschar *firstline = NULL;
406 uschar *msg = US"Error while reading message with no usable sender address";
408 if (message_reference)
409 msg = string_sprintf("%s (R=%s)", msg, message_reference);
411 /* Find the sender from a From line if permitted and possible */
413 if (check_sender && message_file && f.trusted_caller &&
414 Ufgets(big_buffer, BIG_BUFFER_SIZE, message_file) != NULL)
416 uschar *new_sender = NULL;
417 if (regex_match_and_setup(regex_From, big_buffer, 0, -1))
418 new_sender = expand_string(uucp_from_sender);
419 if (new_sender) sender_address = new_sender;
420 else firstline = big_buffer;
423 /* If viable sender address, send a message */
425 if (sender_address && sender_address[0] && !f.local_error_message)
426 return moan_send_message(sender_address, ident, eblock, headers,
427 message_file, firstline);
429 /* Otherwise, we can only log */
433 case ERRMESS_BADARGADDRESS:
434 case ERRMESS_BADNOADDRESS:
435 case ERRMESS_BADADDRESS:
436 log_write(0, LOG_MAIN, "%s: at least one malformed recipient address: "
437 "%s - %s", msg, eblock->text1, eblock->text2);
440 case ERRMESS_IGADDRESS:
441 case ERRMESS_NOADDRESS:
442 log_write(0, LOG_MAIN, "%s: no recipient addresses", msg);
445 /* This error has already been logged. */
449 case ERRMESS_VLONGHEADER:
450 log_write(0, LOG_MAIN, "%s: excessively long message header section read "
451 "(more than %d characters)", msg, header_maxsize);
454 case ERRMESS_VLONGHDRLINE:
455 log_write(0, LOG_MAIN, "%s: excessively long message header line read "
456 "(more than %d characters)", msg, header_line_maxsize);
460 log_write(0, LOG_MAIN, "%s: message too big (limit set to %d)", msg,
461 thismessage_size_limit);
464 case ERRMESS_TOOMANYRECIP:
465 log_write(0, LOG_MAIN, "%s: too many recipients (max set to %d)", msg,
469 case ERRMESS_LOCAL_SCAN:
470 log_write(0, LOG_MAIN, "%s: rejected by local_scan: %s", msg, eblock->text1);
473 case ERRMESS_LOCAL_ACL:
474 log_write(0, LOG_MAIN, "%s: rejected by non-SMTP ACL: %s", msg, eblock->text1);
478 log_write(0, LOG_MAIN|LOG_PANIC, "%s: unknown error number %d", msg,
488 /*************************************************
489 * Send message to someone *
490 *************************************************/
492 /* This is called when exim is configured to tell someone (often the
493 mailmaster) about some incident.
496 who address to send mail to
497 addr chain of deferred addresses whose details are to be included
498 subject subject text for the message
499 format a printf() format for the body of the message
500 ... arguments for the format
506 moan_tell_someone(uschar *who, address_item *addr,
507 const uschar *subject, const char *format, ...)
512 int pid = child_open_exim(&fd);
516 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
521 f = fdopen(fd, "wb");
522 fprintf(f, "Auto-Submitted: auto-replied\n");
524 fprintf(f, "To: %s\n", who);
525 fprintf(f, "Subject: %s\n\n", subject);
526 va_start(ap, format);
527 vfprintf(f, format, ap);
532 fprintf(f, "\nThe following address(es) have yet to be delivered:\n");
533 for (; addr; addr = addr->next)
535 uschar * parent = addr->parent ? addr->parent->address : NULL;
536 fprintf(f, " %s", addr->address);
537 if (parent) fprintf(f, " <%s>", parent);
538 if (addr->basic_errno > 0) fprintf(f, ": %s", strerror(addr->basic_errno));
539 if (addr->message) fprintf(f, ": %s", addr->message);
545 child_close(pid, 0); /* Waits for child to close; no timeout */
550 /*************************************************
551 * Handle SMTP batch error *
552 *************************************************/
554 /* This is called when something goes wrong in batched (-bS) SMTP input.
555 Information is written to stdout and/or stderr, and Exim exits with a non-zero
556 completion code. BSMTP is almost always called by some other program, so it is
557 up to that program to interpret the return code and do something with the error
558 information, and also to preserve the batch input file for human analysis.
560 Formerly, Exim used to attempt to continue after some errors, but this strategy
561 has been abandoned as it can lead to loss of messages.
564 cmd_buffer the command causing the error, or NULL
565 format a printf() format
566 ... arguments for the format
568 Returns: does not return; exits from the program
569 exit code = 1 if some messages were accepted
570 exit code = 2 if no messages were accepted
574 moan_smtp_batch(uschar *cmd_buffer, const char *format, ...)
577 int yield = (receive_messagecount > 0)? 1 : 2;
579 DEBUG(D_any) debug_printf("Handling error in batched SMTP input\n");
581 /* On stdout, write stuff that a program could parse fairly easily. */
583 va_start(ap, format);
584 vfprintf(stdout, format, ap);
587 fprintf(stdout, "\nTransaction started in line %d\n",
588 bsmtp_transaction_linecount);
589 fprintf(stdout, "Error detected in line %d\n", receive_linecount);
590 if (cmd_buffer != NULL) fprintf(stdout, "%s\n", cmd_buffer);
592 /* On stderr, write stuff for human consumption */
595 "An error was detected while processing a file of BSMTP input.\n"
596 "The error message was:\n\n ");
598 va_start(ap, format);
599 vfprintf(stderr, format, ap);
603 "\n\nThe SMTP transaction started in line %d.\n"
604 "The error was detected in line %d.\n",
605 bsmtp_transaction_linecount, receive_linecount);
607 if (cmd_buffer != NULL)
609 fprintf(stderr, "The SMTP command at fault was:\n\n %s\n\n",
613 fprintf(stderr, "%d previous message%s successfully processed.\n",
614 receive_messagecount, (receive_messagecount == 1)? " was" : "s were");
616 fprintf(stderr, "The rest of the batch was abandoned.\n");
618 exim_exit(yield, US"batch");
624 /*************************************************
625 * Check for error copies *
626 *************************************************/
628 /* This function is passed the recipient of an error message, and must check
629 the error_copies string to see whether there is an additional recipient list to
630 which errors for this recipient must be bcc'd. The incoming recipient is always
633 Argument: recipient address
634 Returns: additional recipient list or NULL
638 moan_check_errorcopy(uschar *recipient)
640 uschar *item, *localpart, *domain;
641 const uschar *listptr = errors_copy;
642 uschar *yield = NULL;
647 if (errors_copy == NULL) return NULL;
649 /* Set up pointer to the local part and domain, and compute the
650 length of the local part. */
652 localpart = recipient;
653 domain = Ustrrchr(recipient, '@');
654 if (domain == NULL) return NULL; /* should not occur, but avoid crash */
655 llen = domain++ - recipient;
657 /* Scan through the configured items */
659 while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))
662 const uschar *newaddress = item;
663 const uschar *pattern = string_dequote(&newaddress);
665 /* If no new address found, just skip this item. */
667 while (isspace(*newaddress)) newaddress++;
668 if (*newaddress == 0) continue;
670 /* We now have an item to match as an address in item, and the additional
671 address in newaddress. If the pattern matches, expand the new address string
672 and return it. During expansion, make local part and domain available for
673 insertion. This requires a copy to be made; we can't just temporarily
674 terminate it, as the whole address is required for $0. */
676 if (match_address_list(recipient, TRUE, TRUE, &pattern, NULL, 0, UCHAR_MAX+1,
679 deliver_localpart = string_copyn(localpart, llen);
680 deliver_domain = domain;
681 yield = expand_string_copy(newaddress);
682 deliver_domain = deliver_localpart = NULL;
684 log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand %s when processing "
685 "errors_copy: %s", newaddress, expand_string_message);
690 DEBUG(D_any) debug_printf("errors_copy check returned %s\n",
691 (yield == NULL)? US"NULL" : yield);
699 /************************************************
700 * Handle skipped syntax errors *
701 ************************************************/
703 /* This function is called by the redirect router when it has skipped over one
704 or more syntax errors in the list of addresses. If there is an address to mail
705 to, send a message, and always write the information to the log. In the case of
706 a filter file, a "syntax error" might actually be something else, such as the
707 inability to open a log file. Thus, the wording of the error message is
711 rname the router name
712 eblock chain of error blocks
713 syntax_errors_to address to send mail to, or NULL
714 some TRUE if some addresses were generated; FALSE if none were
715 custom custom message text
717 Returns: FALSE if string expansion failed; TRUE otherwise
721 moan_skipped_syntax_errors(uschar *rname, error_block *eblock,
722 uschar *syntax_errors_to, BOOL some, uschar *custom)
728 for (error_block * e = eblock; e; e = e->next)
729 if (e->text2 != NULL)
730 log_write(0, LOG_MAIN, "%s router: skipped error: %s in \"%s\"",
731 rname, e->text1, e->text2);
733 log_write(0, LOG_MAIN, "%s router: skipped error: %s", rname,
736 if (!syntax_errors_to) return TRUE;
738 if (!(s = expand_string(syntax_errors_to)))
740 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
741 syntax_errors_to, expand_string_message);
745 /* If we can't create a process to send the message, just forget about
748 pid = child_open_exim(&fd);
752 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
757 f = fdopen(fd, "wb");
758 fprintf(f, "Auto-Submitted: auto-replied\n");
760 fprintf(f, "To: %s\n", s);
761 fprintf(f, "Subject: error(s) in forwarding or filtering\n\n");
765 if (!(t = expand_string(custom)))
767 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
768 custom, expand_string_message);
771 fprintf(f, "%s\n\n", t);
774 fprintf(f, "The %s router encountered the following error(s):\n\n",
777 for (error_block * e = eblock; e; e = e->next)
779 fprintf(f, " %s", e->text1);
780 if (e->text2 != NULL)
781 fprintf(f, " in the address\n \"%s\"", e->text2);
786 fprintf(f, "Other addresses were processed normally.\n");
788 fprintf(f, "No valid addresses were generated.\n");
791 child_close(pid, 0); /* Waits for child to close; no timeout */