From 9c4ad90e43932a82d8ada4b21e1b107ea94b8252 Mon Sep 17 00:00:00 2001 From: Gilles Chehade Date: Thu, 6 Aug 2009 14:12:49 +0000 Subject: - introduce message_set_errormsg() to set the error description that will appear in a bounce message, and message_get_errormsg() to retrieve that message. - when loop is detected, call message_set_errormsg() - in mta, call message_set_errormsg() for each recipient failure - in mta, call message_set_errormsg() to copy batch errors to recipients if we failed to deliver for a session related error - when bouncing, add the recipient and error reason to the bounce message --- usr.sbin/smtpd/bounce.c | 8 +++++++- usr.sbin/smtpd/mta.c | 7 ++++--- usr.sbin/smtpd/runner.c | 3 ++- usr.sbin/smtpd/smtpd.h | 4 +++- usr.sbin/smtpd/util.c | 29 ++++++++++++++++++++++++++++- 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/usr.sbin/smtpd/bounce.c b/usr.sbin/smtpd/bounce.c index 360bfe18402..3182a0dce10 100644 --- a/usr.sbin/smtpd/bounce.c +++ b/usr.sbin/smtpd/bounce.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bounce.c,v 1.1 2009/08/06 13:40:45 gilles Exp $ */ +/* $OpenBSD: bounce.c,v 1.2 2009/08/06 14:12:48 gilles Exp $ */ /* * Copyright (c) 2009 Gilles Chehade @@ -142,6 +142,12 @@ bounce_session_switch(struct smtpd *env, FILE *fp, enum session_state *state, ch fprintf(fp, "Hi !\r\n"); fprintf(fp, "This is the MAILER-DAEMON, please DO NOT REPLY t this e-mail.\r\n"); fprintf(fp, "An error has occurred while attempting to deliver a message.\r\n"); + fprintf(fp, "\r\n"); + fprintf(fp, "Recipient: %s@%s\r\n", messagep->recipient.user, + messagep->recipient.domain); + fprintf(fp, "Reason:\r\n"); + fprintf(fp, "%s\r\n", messagep->session_errorline); + fprintf(fp, "\r\n"); fprintf(fp, "Below is a copy of the original message:\r\n\r\n"); diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c index b4c453ec841..9864c1b66f7 100644 --- a/usr.sbin/smtpd/mta.c +++ b/usr.sbin/smtpd/mta.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mta.c,v 1.62 2009/08/06 13:40:45 gilles Exp $ */ +/* $OpenBSD: mta.c,v 1.63 2009/08/06 14:12:48 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard @@ -819,8 +819,7 @@ mta_reply_handler(struct bufferevent *bev, void *arg) case 550: if (sessionp->s_state == S_RCPT) { batchp->messagep->status = (S_MESSAGE_REJECTED|S_MESSAGE_PERMFAILURE); - strlcpy(batchp->messagep->session_errorline, line, - sizeof(batchp->messagep->session_errorline)); + message_set_errormsg(batchp->messagep, "%s", line); break; } case 354: @@ -1021,11 +1020,13 @@ mta_batch_update_queue(struct batch *batchp) if (batchp->status == S_BATCH_PERMFAILURE) { messagep->status |= S_MESSAGE_PERMFAILURE; + message_set_errormsg(messagep, "%s", batchp->errorline); } if (batchp->status == S_BATCH_TEMPFAILURE) { if (messagep->status != S_MESSAGE_PERMFAILURE) messagep->status |= S_MESSAGE_TEMPFAILURE; + message_set_errormsg(messagep, "%s", batchp->errorline); } if ((messagep->status & S_MESSAGE_TEMPFAILURE) == 0 && diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c index 510786537b9..2bc1a58fded 100644 --- a/usr.sbin/smtpd/runner.c +++ b/usr.sbin/smtpd/runner.c @@ -1,4 +1,4 @@ -/* $OpenBSD: runner.c,v 1.55 2009/08/06 13:40:45 gilles Exp $ */ +/* $OpenBSD: runner.c,v 1.56 2009/08/06 14:12:48 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -650,6 +650,7 @@ runner_process_queue(struct smtpd *env) continue; if (runner_check_loop(&message)) { + message_set_errormsg(&message, "loop has been detected"); bounce_record_message(&message); queue_remove_envelope(&message); continue; diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index 675efbb996b..f62491f1379 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.131 2009/08/06 13:40:45 gilles Exp $ */ +/* $OpenBSD: smtpd.h,v 1.132 2009/08/06 14:12:48 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -938,3 +938,5 @@ int valid_message_uid(char *); char *time_to_text(time_t); int secure_file(int, char *, struct passwd *); void lowercase(char *, char *, size_t); +void message_set_errormsg(struct message *, char *, ...); +char *message_get_errormsg(struct message *); diff --git a/usr.sbin/smtpd/util.c b/usr.sbin/smtpd/util.c index 3d64e4d5e6e..066febf9b75 100644 --- a/usr.sbin/smtpd/util.c +++ b/usr.sbin/smtpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.22 2009/06/01 18:24:01 deraadt Exp $ */ +/* $OpenBSD: util.c,v 1.23 2009/08/06 14:12:48 gilles Exp $ */ /* * Copyright (c) 2000,2001 Markus Friedl. All rights reserved. @@ -25,12 +25,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -365,3 +367,28 @@ lowercase(char *buf, char *s, size_t len) buf++; } } + +void +message_set_errormsg(struct message *messagep, char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + + ret = vsnprintf(messagep->session_errorline, MAX_LINE_SIZE, fmt, ap); + if (ret >= MAX_LINE_SIZE) + strlcpy(messagep->session_errorline + (MAX_LINE_SIZE - 4), "...", 4); + + /* this should not happen */ + if (ret == -1) + err(1, "vsnprintf"); + + va_end(ap); +} + +char * +message_get_errormsg(struct message *messagep) +{ + return messagep->session_errorline; +} -- cgit v1.2.3