9 /* #include <smtpd_dsn_fix.h>
11 /* const char *smtpd_dsn_fix(status, reply_class)
12 /* const char *status;
13 /* const char *reply_class;
15 /* smtpd_dsn_fix() transforms DSN status codes according to the
16 /* status information that is actually being reported. The
17 /* following transformations are implemented:
19 /* Transform a recipient address DSN into a sender address DSN
20 /* when reporting sender address status information, and vice
21 /* versa. This transformation may be needed because some Postfix
22 /* access control features don't know whether the address being
23 /* rejected is a sender or recipient. Examples are smtpd access
24 /* tables, rbl reply templates, and the error mailer.
26 /* Transform a sender or recipient address DSN into a non-address
27 /* DSN when reporting non-address status information. For
28 /* example, if something rejects HELO with DSN status 4.1.1
29 /* (unknown recipient address), then we send the more neutral
30 /* 4.0.0 DSN instead. This transformation is needed when the
31 /* same smtpd access map entry or rbl reply template is used
32 /* for both address and non-address information.
34 /* A non-address DSN is not transformed
35 /* when reporting sender or recipient address status information,
36 /* as there are many legitimate instances of such usage.
38 /* It is left up to the caller to update the initial DSN digit
39 /* appropriately; in Postfix this is done as late as possible,
40 /* because hard rejects may be changed into soft rejects for
41 /* all kinds of reasons.
45 /* A DSN status as per RFC 3463.
47 /* SMTPD_NAME_SENDER, SMTPD_NAME_RECIPIENT or some other
48 /* null-terminated string.
52 /* The Secure Mailer license must be distributed with this software.
55 /* IBM T.J. Watson Research
57 /* Yorktown Heights, NY 10598, USA
65 /* Utility library. */
71 /* Application-specific. */
73 #include <smtpd_dsn_fix.h>
76 const char *micro_code
; /* Final digits in mailbox D.S.N. */
77 const char *sender_dsn
; /* Replacement sender D.S.N. */
78 const char *rcpt_dsn
; /* Replacement recipient D.S.N. */
81 static struct dsn_map dsn_map
[] = {
82 /* - Sender - Recipient */
83 "1", SND_DSN
, "4.1.1", /* 4.1.1: Bad dest mbox addr */
84 "2", "4.1.8", "4.1.2", /* 4.1.2: Bad dest system addr */
85 "3", "4.1.7", "4.1.3", /* 4.1.3: Bad dest mbox addr syntax */
86 "4", SND_DSN
, "4.1.4", /* 4.1.4: Dest mbox addr ambiguous */
87 "5", "4.1.0", "4.1.5", /* 4.1.5: Dest mbox addr valid */
88 "6", SND_DSN
, "4.1.6", /* 4.1.6: Mailbox has moved */
89 "7", "4.1.7", "4.1.3", /* 4.1.7: Bad sender mbox addr syntax */
90 "8", "4.1.8", "4.1.2", /* 4.1.8: Bad sender system addr */
91 0, "4.1.0", "4.1.0", /* Default mapping */
94 /* smtpd_dsn_fix - fix DSN status */
96 const char *smtpd_dsn_fix(const char *status
, const char *reply_class
)
99 const char *result
= status
;
102 * Update an address-specific DSN according to what is being rejected.
104 if (ISDIGIT(status
[0]) && strncmp(status
+ 1, ".1.", 3) == 0) {
107 * Fix recipient address DSN while rejecting a sender address. Don't
108 * let future recipient-specific DSN codes slip past us.
110 if (strcmp(reply_class
, SMTPD_NAME_SENDER
) == 0) {
111 for (dp
= dsn_map
; dp
->micro_code
!= 0; dp
++)
112 if (strcmp(status
+ 4, dp
->micro_code
) == 0)
114 result
= dp
->sender_dsn
;
118 * Fix sender address DSN while rejecting a recipient address. Don't
119 * let future sender-specific DSN codes slip past us.
121 else if (strcmp(reply_class
, SMTPD_NAME_RECIPIENT
) == 0) {
122 for (dp
= dsn_map
; dp
->micro_code
!= 0; dp
++)
123 if (strcmp(status
+ 4, dp
->micro_code
) == 0)
125 result
= dp
->rcpt_dsn
;
129 * Fix address-specific DSN while rejecting a non-address.
136 * Give them a clue of what is going on.
138 if (strcmp(status
+ 2, result
+ 2) != 0)
139 msg_info("mapping DSN status %s into %s status %c%s",
140 status
, reply_class
, status
[0], result
+ 1);
145 * Don't update a non-address DSN. There are many legitimate uses for
146 * these while rejecting address or non-address information.