~ubuntu-branches/ubuntu/vivid/postfix/vivid-proposed

« back to all changes in this revision

Viewing changes to src/bounce/bounce_warn_service.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2005-02-27 09:33:07 UTC
  • Revision ID: james.westby@ubuntu.com-20050227093307-cn789t27ibnlh6tf
Tags: upstream-2.1.5
ImportĀ upstreamĀ versionĀ 2.1.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*++
 
2
/* NAME
 
3
/*      bounce_warn_service 3
 
4
/* SUMMARY
 
5
/*      send non-delivery report to sender, server side
 
6
/* SYNOPSIS
 
7
/*      #include "bounce_service.h"
 
8
/*
 
9
/*      int     bounce_warn_service(flags, queue_name, queue_id, encoding, sender)
 
10
/*      int     flags;
 
11
/*      char    *queue_name;
 
12
/*      char    *queue_id;
 
13
/*      char    *encoding;
 
14
/*      char    *sender;
 
15
/* DESCRIPTION
 
16
/*      This module implements the server side of the bounce_warn()
 
17
/*      (send delay notice) request. The logfile
 
18
/*      is not removed, and a warning is sent instead of a bounce.
 
19
/*
 
20
/*      When a message bounces, a full copy is sent to the originator,
 
21
/*      and an optional  copy of the diagnostics with message headers is
 
22
/*      sent to the postmaster.  The result is non-zero when the operation
 
23
/*      should be tried again.
 
24
/*
 
25
/*      When a bounce is sent, the sender address is the empty
 
26
/*      address.  When a bounce bounces, an optional double bounce
 
27
/*      with the entire undeliverable mail is sent to the postmaster,
 
28
/*      with as sender address the double bounce address.
 
29
/* DIAGNOSTICS
 
30
/*      Fatal error: error opening existing file. Warnings: corrupt
 
31
/*      message file. A corrupt message is saved to the "corrupt"
 
32
/*      queue for further inspection.
 
33
/* BUGS
 
34
/* SEE ALSO
 
35
/*      bounce(3) basic bounce service client interface
 
36
/* LICENSE
 
37
/* .ad
 
38
/* .fi
 
39
/*      The Secure Mailer license must be distributed with this software.
 
40
/* AUTHOR(S)
 
41
/*      Wietse Venema
 
42
/*      IBM T.J. Watson Research
 
43
/*      P.O. Box 704
 
44
/*      Yorktown Heights, NY 10598, USA
 
45
/*--*/
 
46
 
 
47
/* System library. */
 
48
 
 
49
#include <sys_defs.h>
 
50
#include <fcntl.h>
 
51
#include <errno.h>
 
52
#include <string.h>
 
53
#include <ctype.h>
 
54
 
 
55
#ifdef STRCASECMP_IN_STRINGS_H
 
56
#include <strings.h>
 
57
#endif
 
58
 
 
59
/* Utility library. */
 
60
 
 
61
#include <msg.h>
 
62
#include <vstream.h>
 
63
#include <name_mask.h>
 
64
 
 
65
/* Global library. */
 
66
 
 
67
#include <mail_params.h>
 
68
#include <mail_queue.h>
 
69
#include <post_mail.h>
 
70
#include <mail_addr.h>
 
71
#include <mail_error.h>
 
72
 
 
73
/* Application-specific. */
 
74
 
 
75
#include "bounce_service.h"
 
76
 
 
77
#define STR vstring_str
 
78
 
 
79
/* bounce_warn_service - send a delayed mail notice */
 
80
 
 
81
int     bounce_warn_service(int unused_flags, char *service, char *queue_name,
 
82
                                    char *queue_id, char *encoding,
 
83
                                    char *recipient)
 
84
{
 
85
    BOUNCE_INFO *bounce_info;
 
86
    int     bounce_status = 1;
 
87
    int     postmaster_status = 1;
 
88
    VSTREAM *bounce;
 
89
    int     notify_mask = name_mask(VAR_NOTIFY_CLASSES, mail_error_masks,
 
90
                                    var_notify_classes);
 
91
    char   *postmaster;
 
92
 
 
93
    /*
 
94
     * Initialize. Open queue file, bounce log, etc.
 
95
     */
 
96
    bounce_info = bounce_mail_init(service, queue_name, queue_id,
 
97
                                   encoding, BOUNCE_MSG_WARN);
 
98
 
 
99
#define NULL_SENDER             MAIL_ADDR_EMPTY /* special address */
 
100
#define NULL_TRACE_FLAGS        0
 
101
#define BOUNCE_HEADERS          1
 
102
 
 
103
    /*
 
104
     * The choice of sender address depends on the recipient address. For a
 
105
     * single bounce (a non-delivery notification to the message originator),
 
106
     * the sender address is the empty string. For a double bounce (typically
 
107
     * a failed single bounce, or a postmaster notification that was produced
 
108
     * by any of the mail processes) the sender address is defined by the
 
109
     * var_double_bounce_sender configuration variable. When a double bounce
 
110
     * cannot be delivered, the queue manager blackholes the resulting triple
 
111
     * bounce message.
 
112
     */
 
113
 
 
114
    /*
 
115
     * Double bounce failed. Never send a triple bounce.
 
116
     * 
 
117
     * However, this does not prevent double bounces from bouncing on other
 
118
     * systems. In order to cope with this, either the queue manager must
 
119
     * recognize the double-bounce recipient address and discard mail, or
 
120
     * every delivery agent must recognize the double-bounce sender address
 
121
     * and substitute something else so mail does not come back at us.
 
122
     */
 
123
    if (strcasecmp(recipient, mail_addr_double_bounce()) == 0) {
 
124
        msg_warn("%s: undeliverable postmaster notification discarded",
 
125
                 queue_id);
 
126
        bounce_status = 0;
 
127
    }
 
128
 
 
129
    /*
 
130
     * Single bounce failed. Optionally send a double bounce to postmaster.
 
131
     */
 
132
#define ANY_BOUNCE (MAIL_ERROR_2BOUNCE | MAIL_ERROR_BOUNCE)
 
133
#define SKIP_IF_DELAY  ((notify_mask & MAIL_ERROR_DELAY) == 0)
 
134
 
 
135
    else if (*recipient == 0) {
 
136
        if (SKIP_IF_DELAY) {
 
137
            bounce_status = 0;
 
138
        } else {
 
139
            postmaster = var_delay_rcpt;
 
140
            if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
 
141
                                                 postmaster,
 
142
                                                 CLEANUP_FLAG_MASK_INTERNAL,
 
143
                                                 NULL_TRACE_FLAGS)) != 0) {
 
144
 
 
145
                /*
 
146
                 * Double bounce to Postmaster. This is the last opportunity
 
147
                 * for this message to be delivered. Send the text with
 
148
                 * reason for the bounce, and the headers of the original
 
149
                 * message. Don't bother sending the boiler-plate text.
 
150
                 */
 
151
                if (!bounce_header(bounce, bounce_info, postmaster)
 
152
                    && bounce_diagnostic_log(bounce, bounce_info) == 0
 
153
                    && bounce_header_dsn(bounce, bounce_info) == 0
 
154
                    && bounce_diagnostic_dsn(bounce, bounce_info) == 0)
 
155
                    bounce_original(bounce, bounce_info, BOUNCE_HEADERS);
 
156
                bounce_status = post_mail_fclose(bounce);
 
157
            }
 
158
        }
 
159
    }
 
160
 
 
161
    /*
 
162
     * Non-bounce failed. Send a single bounce.
 
163
     */
 
164
    else {
 
165
        if ((bounce = post_mail_fopen_nowait(NULL_SENDER, recipient,
 
166
                                             CLEANUP_FLAG_MASK_INTERNAL,
 
167
                                             NULL_TRACE_FLAGS)) != 0) {
 
168
 
 
169
            /*
 
170
             * Send the bounce message header, some boilerplate text that
 
171
             * pretends that we are a polite mail system, the text with
 
172
             * reason for the bounce, and a copy of the original message.
 
173
             */
 
174
            if (bounce_header(bounce, bounce_info, recipient) == 0
 
175
                && bounce_boilerplate(bounce, bounce_info) == 0
 
176
                && bounce_diagnostic_log(bounce, bounce_info) == 0
 
177
                && bounce_header_dsn(bounce, bounce_info) == 0
 
178
                && bounce_diagnostic_dsn(bounce, bounce_info) == 0)
 
179
                bounce_original(bounce, bounce_info, BOUNCE_HEADERS);
 
180
            bounce_status = post_mail_fclose(bounce);
 
181
        }
 
182
 
 
183
        /*
 
184
         * Optionally, send a postmaster notice.
 
185
         * 
 
186
         * This postmaster notice is not critical, so if it fails don't
 
187
         * retransmit the bounce that we just generated, just log a warning.
 
188
         */
 
189
#define WANT_IF_DELAY  ((notify_mask & MAIL_ERROR_DELAY))
 
190
 
 
191
        if (bounce_status == 0 && WANT_IF_DELAY
 
192
            && strcasecmp(recipient, mail_addr_double_bounce()) != 0) {
 
193
 
 
194
            /*
 
195
             * Send the text with reason for the bounce, and the headers of
 
196
             * the original message. Don't bother sending the boiler-plate
 
197
             * text. This postmaster notice is not critical, so if it fails
 
198
             * don't retransmit the bounce that we just generated, just log a
 
199
             * warning.
 
200
             */
 
201
            postmaster = var_delay_rcpt;
 
202
            if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
 
203
                                                 postmaster,
 
204
                                                 CLEANUP_FLAG_MASK_INTERNAL,
 
205
                                                 NULL_TRACE_FLAGS)) != 0) {
 
206
                if (bounce_header(bounce, bounce_info, postmaster) == 0
 
207
                    && bounce_diagnostic_log(bounce, bounce_info) == 0
 
208
                    && bounce_header_dsn(bounce, bounce_info) == 0
 
209
                    && bounce_diagnostic_dsn(bounce, bounce_info) == 0)
 
210
                    bounce_original(bounce, bounce_info, BOUNCE_HEADERS);
 
211
                postmaster_status = post_mail_fclose(bounce);
 
212
            }
 
213
            if (postmaster_status)
 
214
                msg_warn("postmaster notice failed while bouncing to %s",
 
215
                         recipient);
 
216
        }
 
217
    }
 
218
 
 
219
    /*
 
220
     * Cleanup.
 
221
     */
 
222
    bounce_mail_free(bounce_info);
 
223
 
 
224
    return (bounce_status);
 
225
}