1 /* $Cambridge: exim/src/src/moan.c,v 1.7 2007/01/08 10:50:18 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 * Send error message *
19 *************************************************/
21 /* This function sends an error message by opening a pipe to a new process
22 running Exim, and writing a message to it using the "-t" option. This is not
23 used for delivery failures, which have their own code for handing failed
27 recipient addressee for the message
28 ident identifies the type of error
29 eblock chain of error_blocks containing data about the error
30 headers the message's headers
31 message_file FILE containing the body of the message
32 firstline contains first line of file, if it was read to check for
33 "From ", but it turned out not to be
35 Returns: TRUE if message successfully sent
39 moan_send_message(uschar *recipient, int ident, error_block *eblock,
40 header_line *headers, FILE *message_file, uschar *firstline)
46 int size_limit = bounce_return_size_limit;
48 int pid = child_open_exim(&fd);
50 /* Creation of child failed */
54 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
58 else DEBUG(D_any) debug_printf("Child process %d for sending message\n", pid);
60 /* Creation of child succeeded */
63 if (errors_reply_to != NULL) fprintf(f, "Reply-To: %s\n", errors_reply_to);
64 fprintf(f, "Auto-Submitted: auto-replied\n");
65 fprintf(f, "From: Mail Delivery System <Mailer-Daemon@%s>\n",
66 qualify_domain_sender);
67 fprintf(f, "To: %s\n", recipient);
71 case ERRMESS_BADARGADDRESS:
73 "Subject: Mail failure - malformed recipient address\n\n");
75 "A message that you sent contained a recipient address that was incorrectly\n"
77 fprintf(f, " %s %s\n", eblock->text1, eblock->text2);
78 count = Ustrlen(eblock->text1);
79 if (count > 0 && eblock->text1[count-1] == '.')
81 "\nRecipient addresses must not end with a '.' character.\n");
83 "\nThe message has not been delivered to any recipients.\n");
86 case ERRMESS_BADNOADDRESS:
87 case ERRMESS_BADADDRESS:
89 "Subject: Mail failure - malformed recipient address\n\n");
91 "A message that you sent contained one or more recipient addresses that were\n"
92 "incorrectly constructed:\n\n");
94 while (eblock != NULL)
96 fprintf(f, " %s: %s\n", eblock->text1, eblock->text2);
98 eblock = eblock->next;
101 fprintf(f, (count == 1)? "\nThis address has been ignored. " :
102 "\nThese addresses have been ignored. ");
104 fprintf(f, (ident == ERRMESS_BADADDRESS)?
105 "The other addresses in the message were\n"
106 "syntactically valid and have been passed on for an attempt at delivery.\n" :
108 "There were no other addresses in your\n"
109 "message, and so no attempt at delivery was possible.\n");
112 case ERRMESS_IGADDRESS:
113 fprintf(f, "Subject: Mail failure - no recipient addresses\n\n");
115 "A message that you sent using the -t command line option contained no\n"
116 "addresses that were not also on the command line, and were therefore\n"
117 "suppressed. This left no recipient addresses, and so no delivery could\n"
121 case ERRMESS_NOADDRESS:
122 fprintf(f, "Subject: Mail failure - no recipient addresses\n\n");
124 "A message that you sent contained no recipient addresses, and therefore no\n"
125 "delivery could be attempted.\n");
129 fprintf(f, "Subject: Mail failure - system failure\n\n");
131 "A system failure was encountered while processing a message that you sent,\n"
132 "so it has not been possible to deliver it. The error was:\n\n%s\n",
136 case ERRMESS_VLONGHEADER:
137 fprintf(f, "Subject: Mail failure - overlong header section\n\n");
139 "A message that you sent contained a header section that was excessively\n"
140 "long and could not be handled by the mail transmission software. The\n"
141 "message has not been delivered to any recipients.\n");
144 case ERRMESS_VLONGHDRLINE:
145 fprintf(f, "Subject: Mail failure - overlong header line\n\n");
147 "A message that you sent contained a header line that was excessively\n"
148 "long and could not be handled by the mail transmission software. The\n"
149 "message has not been delivered to any recipients.\n");
153 fprintf(f, "Subject: Mail failure - message too big\n\n");
155 "A message that you sent was longer than the maximum size allowed on this\n"
156 "system. It was not delivered to any recipients.\n");
159 case ERRMESS_TOOMANYRECIP:
160 fprintf(f, "Subject: Mail failure - too many recipients\n\n");
162 "A message that you sent contained more recipients than allowed on this\n"
163 "system. It was not delivered to any recipients.\n");
166 case ERRMESS_LOCAL_SCAN:
167 case ERRMESS_LOCAL_ACL:
168 fprintf(f, "Subject: Mail failure - rejected by local scanning code\n\n");
170 "A message that you sent was rejected by the local scanning code that\n"
171 "checks incoming messages on this system.");
172 if (eblock->text1 != NULL)
175 " The following error was given:\n\n %s", eblock->text1);
181 fprintf(f, "Subject: Mail failure\n\n");
183 "A message that you sent has caused the error routine to be entered with\n"
184 "an unknown error number (%d).\n", ident);
188 /* Now, if configured, copy the message; first the headers and then the rest of
189 the input if available, up to the configured limit, if the option for including
190 message bodies in bounces is set. */
192 if (bounce_return_message)
194 if (bounce_return_body)
197 "------ This is a copy of your message, including all the headers.");
198 if (size_limit == 0 || size_limit > thismessage_size_limit)
199 size_limit = thismessage_size_limit;
200 if (size_limit > 0 && size_limit < message_size)
210 "------ No more than %d%s characters of the body are included.\n\n",
213 else fprintf(f, " ------\n\n");
218 "------ This is a copy of the headers that were received before the "
219 "error\n was detected.\n\n");
222 /* If the error occurred before the Received: header was created, its text
223 field will still be NULL; just omit such a header line. */
225 while (headers != NULL)
227 if (headers->text != NULL) fprintf(f, "%s", CS headers->text);
228 headers = headers->next;
231 if (ident != ERRMESS_VLONGHEADER && ident != ERRMESS_VLONGHDRLINE)
234 /* After early detection of an error, the message file may be STDIN,
235 in which case we might have to terminate on a line containing just "."
236 as well as on EOF. We may already have the first line in memory. */
238 if (bounce_return_body && message_file != NULL)
242 BOOL enddot = dot_ends && message_file == stdin;
243 if (firstline != NULL) fprintf(f, "%s", CS firstline);
244 while ((ch = fgetc(message_file)) != EOF)
247 if (size_limit > 0 && ++written > size_limit) break;
250 if (state == 0) { if (ch == '\n') state = 1; }
252 { if (ch == '.') state = 2; else if (ch != '\n') state = 0; }
254 { if (ch == '\n') break; else state = 0; }
260 /* Close the file, which should send an EOF to the child process
261 that is receiving the message. Wait for it to finish, without a timeout. */
264 status = child_close(pid, 0); /* Waits for child to close */
267 uschar *msg = US"Child mail process returned status";
269 log_write(0, LOG_MAIN, "%s %d: errno=%d: %s", msg, status, errno,
272 log_write(0, LOG_MAIN, "%s %d", msg, status);
281 /*************************************************
282 * Send message to sender *
283 *************************************************/
285 /* This function is called when errors are detected during the receipt of a
286 message. Delivery failures are handled separately in deliver.c.
288 If there is a valid sender_address, and the failing message is not a local
289 error message, then this function calls moan_send_message to send a message to
290 that person. If the sender's address is null, then an error has occurred with a
291 message that was generated by a mailer daemon. All we can do is to write
292 information to log files. The same action is taken if local_error_message is
293 set - this can happen for non null-senders in certain configurations where exim
294 doesn't run setuid root.
297 ident identifies the particular error
298 eblock chain of error_blocks containing data about the error
299 headers message's headers (chain)
300 message_file a FILE where the body of the message can be read
301 check_sender if TRUE, read the first line of the file for a possible
302 "From " sender (if a trusted caller)
304 Returns: FALSE if there is no sender_address to send to;
305 else the return from moan_send_message()
309 moan_to_sender(int ident, error_block *eblock, header_line *headers,
310 FILE *message_file, BOOL check_sender)
312 uschar *firstline = NULL;
313 uschar *msg = US"Error while reading message with no usable sender address";
315 if (message_reference != NULL)
316 msg = string_sprintf("%s (R=%s)", msg, message_reference);
318 /* Find the sender from a From line if permitted and possible */
320 if (check_sender && message_file != NULL && trusted_caller &&
321 Ufgets(big_buffer, BIG_BUFFER_SIZE, message_file) != NULL)
323 uschar *new_sender = NULL;
324 if (regex_match_and_setup(regex_From, big_buffer, 0, -1))
325 new_sender = expand_string(uucp_from_sender);
326 if (new_sender != NULL) sender_address = new_sender;
327 else firstline = big_buffer;
330 /* If viable sender address, send a message */
332 if (sender_address != NULL && sender_address[0] != 0 && !local_error_message)
333 return moan_send_message(sender_address, ident, eblock, headers,
334 message_file, firstline);
336 /* Otherwise, we can only log */
340 case ERRMESS_BADARGADDRESS:
341 case ERRMESS_BADNOADDRESS:
342 case ERRMESS_BADADDRESS:
343 log_write(0, LOG_MAIN, "%s: at least one malformed recipient address: "
344 "%s - %s", msg, eblock->text1, eblock->text2);
347 case ERRMESS_IGADDRESS:
348 case ERRMESS_NOADDRESS:
349 log_write(0, LOG_MAIN, "%s: no recipient addresses", msg);
352 /* This error has already been logged. */
356 case ERRMESS_VLONGHEADER:
357 log_write(0, LOG_MAIN, "%s: excessively long message header section read "
358 "(more than %d characters)", msg, header_maxsize);
361 case ERRMESS_VLONGHDRLINE:
362 log_write(0, LOG_MAIN, "%s: excessively long message header line read "
363 "(more than %d characters)", msg, header_line_maxsize);
367 log_write(0, LOG_MAIN, "%s: message too big (limit set to %d)", msg,
368 thismessage_size_limit);
371 case ERRMESS_TOOMANYRECIP:
372 log_write(0, LOG_MAIN, "%s: too many recipients (max set to %d)", msg,
376 case ERRMESS_LOCAL_SCAN:
377 log_write(0, LOG_MAIN, "%s: rejected by local_scan: %s", msg, eblock->text1);
380 case ERRMESS_LOCAL_ACL:
381 log_write(0, LOG_MAIN, "%s: rejected by non-SMTP ACL: %s", msg, eblock->text1);
385 log_write(0, LOG_MAIN|LOG_PANIC, "%s: unknown error number %d", msg,
395 /*************************************************
396 * Send message to someone *
397 *************************************************/
399 /* This is called when exim is configured to tell someone (often the
400 mailmaster) about some incident.
403 who address to send mail to
404 addr chain of deferred addresses whose details are to be included
405 subject subject text for the message
406 format a printf() format for the body of the message
407 ... arguments for the format
413 moan_tell_someone(uschar *who, address_item *addr, uschar *subject,
419 int pid = child_open_exim(&fd);
423 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
428 f = fdopen(fd, "wb");
429 fprintf(f, "Auto-Submitted: auto-replied\n");
430 fprintf(f, "From: Mail Delivery System <Mailer-Daemon@%s>\n",
431 qualify_domain_sender);
432 fprintf(f, "To: %s\n", who);
433 fprintf(f, "Subject: %s\n\n", subject);
434 va_start(ap, format);
435 vfprintf(f, format, ap);
440 fprintf(f, "\nThe following address(es) have yet to be delivered:\n");
441 for (; addr != NULL; addr = addr->next)
443 uschar *parent = (addr->parent == NULL)? NULL : addr->parent->address;
444 fprintf(f, " %s", addr->address);
445 if (parent != NULL) fprintf(f, " <%s>", parent);
446 if (addr->basic_errno > 0) fprintf(f, ": %s", strerror(addr->basic_errno));
447 if (addr->message != NULL) fprintf(f, ": %s", addr->message);
453 child_close(pid, 0); /* Waits for child to close; no timeout */
458 /*************************************************
459 * Handle SMTP batch error *
460 *************************************************/
462 /* This is called when something goes wrong in batched (-bS) SMTP input.
463 Information is written to stdout and/or stderr, and Exim exits with a non-zero
464 completion code. BSMTP is almost always called by some other program, so it is
465 up to that program to interpret the return code and do something with the error
466 information, and also to preserve the batch input file for human analysis.
468 Formerly, Exim used to attempt to continue after some errors, but this strategy
469 has been abandoned as it can lead to loss of messages.
472 cmd_buffer the command causing the error, or NULL
473 format a printf() format
474 ... arguments for the format
476 Returns: does not return; exits from the program
477 exit code = 1 if some messages were accepted
478 exit code = 2 if no messages were accepted
482 moan_smtp_batch(uschar *cmd_buffer, char *format, ...)
485 int yield = (receive_messagecount > 0)? 1 : 2;
487 DEBUG(D_any) debug_printf("Handling error in batched SMTP input\n");
489 /* On stdout, write stuff that a program could parse fairly easily. */
491 va_start(ap, format);
492 vfprintf(stdout, format, ap);
495 fprintf(stdout, "\nTransaction started in line %d\n",
496 bsmtp_transaction_linecount);
497 fprintf(stdout, "Error detected in line %d\n", receive_linecount);
498 if (cmd_buffer != NULL) fprintf(stdout, "%s\n", cmd_buffer);
500 /* On stderr, write stuff for human consumption */
503 "An error was detected while processing a file of BSMTP input.\n"
504 "The error message was:\n\n ");
506 va_start(ap, format);
507 vfprintf(stderr, format, ap);
511 "\n\nThe SMTP transaction started in line %d.\n"
512 "The error was detected in line %d.\n",
513 bsmtp_transaction_linecount, receive_linecount);
515 if (cmd_buffer != NULL)
517 fprintf(stderr, "The SMTP command at fault was:\n\n %s\n\n",
521 fprintf(stderr, "%d previous message%s successfully processed.\n",
522 receive_messagecount, (receive_messagecount == 1)? " was" : "s were");
524 fprintf(stderr, "The rest of the batch was abandoned.\n");
532 /*************************************************
533 * Check for error copies *
534 *************************************************/
536 /* This function is passed the recipient of an error message, and must check
537 the error_copies string to see whether there is an additional recipient list to
538 which errors for this recipient must be bcc'd. The incoming recipient is always
541 Argument: recipient address
542 Returns: additional recipient list or NULL
546 moan_check_errorcopy(uschar *recipient)
548 uschar *item, *localpart, *domain;
549 uschar *listptr = errors_copy;
550 uschar *yield = NULL;
555 if (errors_copy == NULL) return NULL;
557 /* Set up pointer to the local part and domain, and compute the
558 length of the local part. */
560 localpart = recipient;
561 domain = Ustrchr(recipient, '@');
562 if (domain == NULL) return NULL; /* should not occur, but avoid crash */
563 llen = domain++ - recipient;
565 /* Scan through the configured items */
567 while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))
570 uschar *newaddress = item;
571 uschar *pattern = string_dequote(&newaddress);
573 /* If no new address found, just skip this item. */
575 while (isspace(*newaddress)) newaddress++;
576 if (*newaddress == 0) continue;
578 /* We now have an item to match as an address in item, and the additional
579 address in newaddress. If the pattern matches, expand the new address string
580 and return it. During expansion, make local part and domain available for
581 insertion. This requires a copy to be made; we can't just temporarily
582 terminate it, as the whole address is required for $0. */
584 if (match_address_list(recipient, TRUE, TRUE, &pattern, NULL, 0, UCHAR_MAX+1,
588 Ustrncpy(temp, localpart, llen);
590 deliver_localpart = temp;
591 deliver_domain = domain;
592 yield = expand_string_copy(newaddress);
593 deliver_domain = deliver_localpart = NULL;
595 log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand %s when processing "
596 "errors_copy: %s", newaddress, expand_string_message);
601 DEBUG(D_any) debug_printf("errors_copy check returned %s\n",
602 (yield == NULL)? US"NULL" : yield);
610 /************************************************
611 * Handle skipped syntax errors *
612 ************************************************/
614 /* This function is called by the redirect router when it has skipped over one
615 or more syntax errors in the list of addresses. If there is an address to mail
616 to, send a message, and always write the information to the log. In the case of
617 a filter file, a "syntax error" might actually be something else, such as the
618 inability to open a log file. Thus, the wording of the error message is
622 rname the router name
623 eblock chain of error blocks
624 syntax_errors_to address to send mail to, or NULL
625 some TRUE if some addresses were generated; FALSE if none were
626 custom custom message text
628 Returns: FALSE if string expansion failed; TRUE otherwise
632 moan_skipped_syntax_errors(uschar *rname, error_block *eblock,
633 uschar *syntax_errors_to, BOOL some, uschar *custom)
640 for (e = eblock; e != NULL; e = e->next)
642 if (e->text2 != NULL)
643 log_write(0, LOG_MAIN, "%s router: skipped error: %s in \"%s\"",
644 rname, e->text1, e->text2);
646 log_write(0, LOG_MAIN, "%s router: skipped error: %s", rname,
650 if (syntax_errors_to == NULL) return TRUE;
652 s = expand_string(syntax_errors_to);
655 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
656 syntax_errors_to, expand_string_message);
660 /* If we can't create a process to send the message, just forget about
663 pid = child_open_exim(&fd);
667 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
672 f = fdopen(fd, "wb");
673 fprintf(f, "Auto-Submitted: auto-replied\n");
674 fprintf(f, "From: Mail Delivery System <Mailer-Daemon@%s>\n",
675 qualify_domain_sender);
676 fprintf(f, "To: %s\n", s);
677 fprintf(f, "Subject: error(s) in forwarding or filtering\n\n");
681 t = expand_string(custom);
684 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
685 custom, expand_string_message);
688 fprintf(f, "%s\n\n", t);
691 fprintf(f, "The %s router encountered the following error(s):\n\n",
694 for (e = eblock; e != NULL; e = e->next)
696 fprintf(f, " %s", e->text1);
697 if (e->text2 != NULL)
698 fprintf(f, " in the address\n \"%s\"", e->text2);
703 fprintf(f, "Other addresses were processed normally.\n");
705 fprintf(f, "No valid addresses were generated.\n");
708 child_close(pid, 0); /* Waits for child to close; no timeout */