1 /* $Cambridge: exim/src/src/moan.c,v 1.8 2007/02/06 11:11:40 ph10 Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Copyright (c) University of Cambridge 1995 - 2007 */
8 /* See the file NOTICE for conditions of use and distribution. */
10 /* Functions for sending messages to sender or to mailmaster. */
17 /*************************************************
18 * Write From: line for DSN *
19 *************************************************/
21 /* This function is called to write the From: line in automatically generated
22 messages - bounces, warnings, etc. It expands a configuration item in order to
23 get the text. If the expansion fails, a panic is logged and the default value
24 for the option is used.
26 Argument: the FILE to write to
31 moan_write_from(FILE *f)
33 uschar *s = expand_string(dsn_from);
36 log_write(0, LOG_MAIN|LOG_PANIC,
37 "Failed to expand dsn_from (using default): %s", expand_string_message);
38 s = expand_string(US DEFAULT_DSN_FROM);
40 fprintf(f, "From: %s\n", s);
45 /*************************************************
46 * Send error message *
47 *************************************************/
49 /* This function sends an error message by opening a pipe to a new process
50 running Exim, and writing a message to it using the "-t" option. This is not
51 used for delivery failures, which have their own code for handing failed
55 recipient addressee for the message
56 ident identifies the type of error
57 eblock chain of error_blocks containing data about the error
58 headers the message's headers
59 message_file FILE containing the body of the message
60 firstline contains first line of file, if it was read to check for
61 "From ", but it turned out not to be
63 Returns: TRUE if message successfully sent
67 moan_send_message(uschar *recipient, int ident, error_block *eblock,
68 header_line *headers, FILE *message_file, uschar *firstline)
74 int size_limit = bounce_return_size_limit;
76 int pid = child_open_exim(&fd);
78 /* Creation of child failed */
82 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
86 else DEBUG(D_any) debug_printf("Child process %d for sending message\n", pid);
88 /* Creation of child succeeded */
91 if (errors_reply_to != NULL) fprintf(f, "Reply-To: %s\n", errors_reply_to);
92 fprintf(f, "Auto-Submitted: auto-replied\n");
94 fprintf(f, "To: %s\n", recipient);
98 case ERRMESS_BADARGADDRESS:
100 "Subject: Mail failure - malformed recipient address\n\n");
102 "A message that you sent contained a recipient address that was incorrectly\n"
104 fprintf(f, " %s %s\n", eblock->text1, eblock->text2);
105 count = Ustrlen(eblock->text1);
106 if (count > 0 && eblock->text1[count-1] == '.')
108 "\nRecipient addresses must not end with a '.' character.\n");
110 "\nThe message has not been delivered to any recipients.\n");
113 case ERRMESS_BADNOADDRESS:
114 case ERRMESS_BADADDRESS:
116 "Subject: Mail failure - malformed recipient address\n\n");
118 "A message that you sent contained one or more recipient addresses that were\n"
119 "incorrectly constructed:\n\n");
121 while (eblock != NULL)
123 fprintf(f, " %s: %s\n", eblock->text1, eblock->text2);
125 eblock = eblock->next;
128 fprintf(f, (count == 1)? "\nThis address has been ignored. " :
129 "\nThese addresses have been ignored. ");
131 fprintf(f, (ident == ERRMESS_BADADDRESS)?
132 "The other addresses in the message were\n"
133 "syntactically valid and have been passed on for an attempt at delivery.\n" :
135 "There were no other addresses in your\n"
136 "message, and so no attempt at delivery was possible.\n");
139 case ERRMESS_IGADDRESS:
140 fprintf(f, "Subject: Mail failure - no recipient addresses\n\n");
142 "A message that you sent using the -t command line option contained no\n"
143 "addresses that were not also on the command line, and were therefore\n"
144 "suppressed. This left no recipient addresses, and so no delivery could\n"
148 case ERRMESS_NOADDRESS:
149 fprintf(f, "Subject: Mail failure - no recipient addresses\n\n");
151 "A message that you sent contained no recipient addresses, and therefore no\n"
152 "delivery could be attempted.\n");
156 fprintf(f, "Subject: Mail failure - system failure\n\n");
158 "A system failure was encountered while processing a message that you sent,\n"
159 "so it has not been possible to deliver it. The error was:\n\n%s\n",
163 case ERRMESS_VLONGHEADER:
164 fprintf(f, "Subject: Mail failure - overlong header section\n\n");
166 "A message that you sent contained a header section that was excessively\n"
167 "long and could not be handled by the mail transmission software. The\n"
168 "message has not been delivered to any recipients.\n");
171 case ERRMESS_VLONGHDRLINE:
172 fprintf(f, "Subject: Mail failure - overlong header line\n\n");
174 "A message that you sent contained a header line that was excessively\n"
175 "long and could not be handled by the mail transmission software. The\n"
176 "message has not been delivered to any recipients.\n");
180 fprintf(f, "Subject: Mail failure - message too big\n\n");
182 "A message that you sent was longer than the maximum size allowed on this\n"
183 "system. It was not delivered to any recipients.\n");
186 case ERRMESS_TOOMANYRECIP:
187 fprintf(f, "Subject: Mail failure - too many recipients\n\n");
189 "A message that you sent contained more recipients than allowed on this\n"
190 "system. It was not delivered to any recipients.\n");
193 case ERRMESS_LOCAL_SCAN:
194 case ERRMESS_LOCAL_ACL:
195 fprintf(f, "Subject: Mail failure - rejected by local scanning code\n\n");
197 "A message that you sent was rejected by the local scanning code that\n"
198 "checks incoming messages on this system.");
199 if (eblock->text1 != NULL)
202 " The following error was given:\n\n %s", eblock->text1);
208 fprintf(f, "Subject: Mail failure\n\n");
210 "A message that you sent has caused the error routine to be entered with\n"
211 "an unknown error number (%d).\n", ident);
215 /* Now, if configured, copy the message; first the headers and then the rest of
216 the input if available, up to the configured limit, if the option for including
217 message bodies in bounces is set. */
219 if (bounce_return_message)
221 if (bounce_return_body)
224 "------ This is a copy of your message, including all the headers.");
225 if (size_limit == 0 || size_limit > thismessage_size_limit)
226 size_limit = thismessage_size_limit;
227 if (size_limit > 0 && size_limit < message_size)
237 "------ No more than %d%s characters of the body are included.\n\n",
240 else fprintf(f, " ------\n\n");
245 "------ This is a copy of the headers that were received before the "
246 "error\n was detected.\n\n");
249 /* If the error occurred before the Received: header was created, its text
250 field will still be NULL; just omit such a header line. */
252 while (headers != NULL)
254 if (headers->text != NULL) fprintf(f, "%s", CS headers->text);
255 headers = headers->next;
258 if (ident != ERRMESS_VLONGHEADER && ident != ERRMESS_VLONGHDRLINE)
261 /* After early detection of an error, the message file may be STDIN,
262 in which case we might have to terminate on a line containing just "."
263 as well as on EOF. We may already have the first line in memory. */
265 if (bounce_return_body && message_file != NULL)
269 BOOL enddot = dot_ends && message_file == stdin;
270 if (firstline != NULL) fprintf(f, "%s", CS firstline);
271 while ((ch = fgetc(message_file)) != EOF)
274 if (size_limit > 0 && ++written > size_limit) break;
277 if (state == 0) { if (ch == '\n') state = 1; }
279 { if (ch == '.') state = 2; else if (ch != '\n') state = 0; }
281 { if (ch == '\n') break; else state = 0; }
287 /* Close the file, which should send an EOF to the child process
288 that is receiving the message. Wait for it to finish, without a timeout. */
291 status = child_close(pid, 0); /* Waits for child to close */
294 uschar *msg = US"Child mail process returned status";
296 log_write(0, LOG_MAIN, "%s %d: errno=%d: %s", msg, status, errno,
299 log_write(0, LOG_MAIN, "%s %d", msg, status);
308 /*************************************************
309 * Send message to sender *
310 *************************************************/
312 /* This function is called when errors are detected during the receipt of a
313 message. Delivery failures are handled separately in deliver.c.
315 If there is a valid sender_address, and the failing message is not a local
316 error message, then this function calls moan_send_message to send a message to
317 that person. If the sender's address is null, then an error has occurred with a
318 message that was generated by a mailer daemon. All we can do is to write
319 information to log files. The same action is taken if local_error_message is
320 set - this can happen for non null-senders in certain configurations where exim
321 doesn't run setuid root.
324 ident identifies the particular error
325 eblock chain of error_blocks containing data about the error
326 headers message's headers (chain)
327 message_file a FILE where the body of the message can be read
328 check_sender if TRUE, read the first line of the file for a possible
329 "From " sender (if a trusted caller)
331 Returns: FALSE if there is no sender_address to send to;
332 else the return from moan_send_message()
336 moan_to_sender(int ident, error_block *eblock, header_line *headers,
337 FILE *message_file, BOOL check_sender)
339 uschar *firstline = NULL;
340 uschar *msg = US"Error while reading message with no usable sender address";
342 if (message_reference != NULL)
343 msg = string_sprintf("%s (R=%s)", msg, message_reference);
345 /* Find the sender from a From line if permitted and possible */
347 if (check_sender && message_file != NULL && trusted_caller &&
348 Ufgets(big_buffer, BIG_BUFFER_SIZE, message_file) != NULL)
350 uschar *new_sender = NULL;
351 if (regex_match_and_setup(regex_From, big_buffer, 0, -1))
352 new_sender = expand_string(uucp_from_sender);
353 if (new_sender != NULL) sender_address = new_sender;
354 else firstline = big_buffer;
357 /* If viable sender address, send a message */
359 if (sender_address != NULL && sender_address[0] != 0 && !local_error_message)
360 return moan_send_message(sender_address, ident, eblock, headers,
361 message_file, firstline);
363 /* Otherwise, we can only log */
367 case ERRMESS_BADARGADDRESS:
368 case ERRMESS_BADNOADDRESS:
369 case ERRMESS_BADADDRESS:
370 log_write(0, LOG_MAIN, "%s: at least one malformed recipient address: "
371 "%s - %s", msg, eblock->text1, eblock->text2);
374 case ERRMESS_IGADDRESS:
375 case ERRMESS_NOADDRESS:
376 log_write(0, LOG_MAIN, "%s: no recipient addresses", msg);
379 /* This error has already been logged. */
383 case ERRMESS_VLONGHEADER:
384 log_write(0, LOG_MAIN, "%s: excessively long message header section read "
385 "(more than %d characters)", msg, header_maxsize);
388 case ERRMESS_VLONGHDRLINE:
389 log_write(0, LOG_MAIN, "%s: excessively long message header line read "
390 "(more than %d characters)", msg, header_line_maxsize);
394 log_write(0, LOG_MAIN, "%s: message too big (limit set to %d)", msg,
395 thismessage_size_limit);
398 case ERRMESS_TOOMANYRECIP:
399 log_write(0, LOG_MAIN, "%s: too many recipients (max set to %d)", msg,
403 case ERRMESS_LOCAL_SCAN:
404 log_write(0, LOG_MAIN, "%s: rejected by local_scan: %s", msg, eblock->text1);
407 case ERRMESS_LOCAL_ACL:
408 log_write(0, LOG_MAIN, "%s: rejected by non-SMTP ACL: %s", msg, eblock->text1);
412 log_write(0, LOG_MAIN|LOG_PANIC, "%s: unknown error number %d", msg,
422 /*************************************************
423 * Send message to someone *
424 *************************************************/
426 /* This is called when exim is configured to tell someone (often the
427 mailmaster) about some incident.
430 who address to send mail to
431 addr chain of deferred addresses whose details are to be included
432 subject subject text for the message
433 format a printf() format for the body of the message
434 ... arguments for the format
440 moan_tell_someone(uschar *who, address_item *addr, uschar *subject,
446 int pid = child_open_exim(&fd);
450 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
455 f = fdopen(fd, "wb");
456 fprintf(f, "Auto-Submitted: auto-replied\n");
458 fprintf(f, "To: %s\n", who);
459 fprintf(f, "Subject: %s\n\n", subject);
460 va_start(ap, format);
461 vfprintf(f, format, ap);
466 fprintf(f, "\nThe following address(es) have yet to be delivered:\n");
467 for (; addr != NULL; addr = addr->next)
469 uschar *parent = (addr->parent == NULL)? NULL : addr->parent->address;
470 fprintf(f, " %s", addr->address);
471 if (parent != NULL) fprintf(f, " <%s>", parent);
472 if (addr->basic_errno > 0) fprintf(f, ": %s", strerror(addr->basic_errno));
473 if (addr->message != NULL) fprintf(f, ": %s", addr->message);
479 child_close(pid, 0); /* Waits for child to close; no timeout */
484 /*************************************************
485 * Handle SMTP batch error *
486 *************************************************/
488 /* This is called when something goes wrong in batched (-bS) SMTP input.
489 Information is written to stdout and/or stderr, and Exim exits with a non-zero
490 completion code. BSMTP is almost always called by some other program, so it is
491 up to that program to interpret the return code and do something with the error
492 information, and also to preserve the batch input file for human analysis.
494 Formerly, Exim used to attempt to continue after some errors, but this strategy
495 has been abandoned as it can lead to loss of messages.
498 cmd_buffer the command causing the error, or NULL
499 format a printf() format
500 ... arguments for the format
502 Returns: does not return; exits from the program
503 exit code = 1 if some messages were accepted
504 exit code = 2 if no messages were accepted
508 moan_smtp_batch(uschar *cmd_buffer, char *format, ...)
511 int yield = (receive_messagecount > 0)? 1 : 2;
513 DEBUG(D_any) debug_printf("Handling error in batched SMTP input\n");
515 /* On stdout, write stuff that a program could parse fairly easily. */
517 va_start(ap, format);
518 vfprintf(stdout, format, ap);
521 fprintf(stdout, "\nTransaction started in line %d\n",
522 bsmtp_transaction_linecount);
523 fprintf(stdout, "Error detected in line %d\n", receive_linecount);
524 if (cmd_buffer != NULL) fprintf(stdout, "%s\n", cmd_buffer);
526 /* On stderr, write stuff for human consumption */
529 "An error was detected while processing a file of BSMTP input.\n"
530 "The error message was:\n\n ");
532 va_start(ap, format);
533 vfprintf(stderr, format, ap);
537 "\n\nThe SMTP transaction started in line %d.\n"
538 "The error was detected in line %d.\n",
539 bsmtp_transaction_linecount, receive_linecount);
541 if (cmd_buffer != NULL)
543 fprintf(stderr, "The SMTP command at fault was:\n\n %s\n\n",
547 fprintf(stderr, "%d previous message%s successfully processed.\n",
548 receive_messagecount, (receive_messagecount == 1)? " was" : "s were");
550 fprintf(stderr, "The rest of the batch was abandoned.\n");
558 /*************************************************
559 * Check for error copies *
560 *************************************************/
562 /* This function is passed the recipient of an error message, and must check
563 the error_copies string to see whether there is an additional recipient list to
564 which errors for this recipient must be bcc'd. The incoming recipient is always
567 Argument: recipient address
568 Returns: additional recipient list or NULL
572 moan_check_errorcopy(uschar *recipient)
574 uschar *item, *localpart, *domain;
575 uschar *listptr = errors_copy;
576 uschar *yield = NULL;
581 if (errors_copy == NULL) return NULL;
583 /* Set up pointer to the local part and domain, and compute the
584 length of the local part. */
586 localpart = recipient;
587 domain = Ustrchr(recipient, '@');
588 if (domain == NULL) return NULL; /* should not occur, but avoid crash */
589 llen = domain++ - recipient;
591 /* Scan through the configured items */
593 while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))
596 uschar *newaddress = item;
597 uschar *pattern = string_dequote(&newaddress);
599 /* If no new address found, just skip this item. */
601 while (isspace(*newaddress)) newaddress++;
602 if (*newaddress == 0) continue;
604 /* We now have an item to match as an address in item, and the additional
605 address in newaddress. If the pattern matches, expand the new address string
606 and return it. During expansion, make local part and domain available for
607 insertion. This requires a copy to be made; we can't just temporarily
608 terminate it, as the whole address is required for $0. */
610 if (match_address_list(recipient, TRUE, TRUE, &pattern, NULL, 0, UCHAR_MAX+1,
614 Ustrncpy(temp, localpart, llen);
616 deliver_localpart = temp;
617 deliver_domain = domain;
618 yield = expand_string_copy(newaddress);
619 deliver_domain = deliver_localpart = NULL;
621 log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand %s when processing "
622 "errors_copy: %s", newaddress, expand_string_message);
627 DEBUG(D_any) debug_printf("errors_copy check returned %s\n",
628 (yield == NULL)? US"NULL" : yield);
636 /************************************************
637 * Handle skipped syntax errors *
638 ************************************************/
640 /* This function is called by the redirect router when it has skipped over one
641 or more syntax errors in the list of addresses. If there is an address to mail
642 to, send a message, and always write the information to the log. In the case of
643 a filter file, a "syntax error" might actually be something else, such as the
644 inability to open a log file. Thus, the wording of the error message is
648 rname the router name
649 eblock chain of error blocks
650 syntax_errors_to address to send mail to, or NULL
651 some TRUE if some addresses were generated; FALSE if none were
652 custom custom message text
654 Returns: FALSE if string expansion failed; TRUE otherwise
658 moan_skipped_syntax_errors(uschar *rname, error_block *eblock,
659 uschar *syntax_errors_to, BOOL some, uschar *custom)
666 for (e = eblock; e != NULL; e = e->next)
668 if (e->text2 != NULL)
669 log_write(0, LOG_MAIN, "%s router: skipped error: %s in \"%s\"",
670 rname, e->text1, e->text2);
672 log_write(0, LOG_MAIN, "%s router: skipped error: %s", rname,
676 if (syntax_errors_to == NULL) return TRUE;
678 s = expand_string(syntax_errors_to);
681 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
682 syntax_errors_to, expand_string_message);
686 /* If we can't create a process to send the message, just forget about
689 pid = child_open_exim(&fd);
693 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
698 f = fdopen(fd, "wb");
699 fprintf(f, "Auto-Submitted: auto-replied\n");
701 fprintf(f, "To: %s\n", s);
702 fprintf(f, "Subject: error(s) in forwarding or filtering\n\n");
706 t = expand_string(custom);
709 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
710 custom, expand_string_message);
713 fprintf(f, "%s\n\n", t);
716 fprintf(f, "The %s router encountered the following error(s):\n\n",
719 for (e = eblock; e != NULL; e = e->next)
721 fprintf(f, " %s", e->text1);
722 if (e->text2 != NULL)
723 fprintf(f, " in the address\n \"%s\"", e->text2);
728 fprintf(f, "Other addresses were processed normally.\n");
730 fprintf(f, "No valid addresses were generated.\n");
733 child_close(pid, 0); /* Waits for child to close; no timeout */