]>
Commit | Line | Data |
---|---|---|
41b11822 | 1 | --- src/smtpd/smtpd.h.org Wed Feb 9 03:00:14 2005 |
2 | +++ src/smtpd/smtpd.h Mon Feb 7 20:06:58 2005 | |
3 | @@ -111,6 +111,7 @@ | |
4 | int sender_rcptmap_checked; /* sender validated against maps */ | |
5 | int recipient_rcptmap_checked; /* recipient validated against maps */ | |
6 | int warn_if_reject; /* force reject into warning */ | |
7 | + int header_if_reject; /* add header instead of rejecting */ | |
8 | SMTPD_DEFER defer_if_reject; /* force reject into deferral */ | |
9 | SMTPD_DEFER defer_if_permit; /* force permit into deferral */ | |
10 | int defer_if_permit_client; /* force permit into warning */ | |
11 | --- src/global/mail_params.h.org Wed Feb 9 03:01:31 2005 | |
12 | +++ src/global/mail_params.h Wed Feb 9 02:01:01 2005 | |
13 | @@ -1578,6 +1578,7 @@ | |
14 | #define CHECK_RECIP_NS_ACL "check_recipient_ns_access" | |
15 | ||
16 | #define WARN_IF_REJECT "warn_if_reject" | |
17 | +#define HEADER_IF_REJECT "header_if_reject" | |
18 | ||
19 | #define REJECT_RBL "reject_rbl" /* LaMont compatibility */ | |
20 | #define REJECT_RBL_CLIENT "reject_rbl_client" | |
21 | --- src/smtpd/smtpd_check.c.org Sat Dec 27 03:54:03 2003 | |
22 | +++ src/smtpd/smtpd_check.c Wed Feb 9 06:04:25 2005 | |
23 | @@ -351,29 +351,29 @@ | |
24 | * permit-style restriction fails. Otherwise, we could reject legitimate | |
25 | * mail. | |
26 | */ | |
27 | -static void PRINTFLIKE(3, 4) defer_if(SMTPD_DEFER *, int, const char *,...); | |
28 | +static void PRINTFLIKE(4, 5) defer_if(SMTPD_STATE *, SMTPD_DEFER *, int, const char *,...); | |
29 | ||
30 | #define DEFER_IF_REJECT2(state, class, fmt, a1, a2) \ | |
31 | - defer_if(&(state)->defer_if_reject, (class), (fmt), (a1), (a2)) | |
32 | + defer_if((state), &(state)->defer_if_reject, (class), (fmt), (a1), (a2)) | |
33 | #define DEFER_IF_REJECT3(state, class, fmt, a1, a2, a3) \ | |
34 | - defer_if(&(state)->defer_if_reject, (class), (fmt), (a1), (a2), (a3)) | |
35 | + defer_if((state), &(state)->defer_if_reject, (class), (fmt), (a1), (a2), (a3)) | |
36 | #define DEFER_IF_REJECT4(state, class, fmt, a1, a2, a3, a4) \ | |
37 | defer_if(&(state)->defer_if_reject, (class), (fmt), (a1), (a2), (a3), (a4)) | |
38 | #define DEFER_IF_PERMIT2(state, class, fmt, a1, a2) do { \ | |
39 | if ((state)->warn_if_reject == 0) \ | |
40 | - defer_if(&(state)->defer_if_permit, (class), (fmt), (a1), (a2)); \ | |
41 | + defer_if((state), &(state)->defer_if_permit, (class), (fmt), (a1), (a2)); \ | |
42 | else \ | |
43 | (void) smtpd_check_reject((state), (class), (fmt), (a1), (a2)); \ | |
44 | } while (0) | |
45 | #define DEFER_IF_PERMIT3(state, class, fmt, a1, a2, a3) do { \ | |
46 | if ((state)->warn_if_reject == 0) \ | |
47 | - defer_if(&(state)->defer_if_permit, (class), (fmt), (a1), (a2), (a3)); \ | |
48 | + defer_if((state), &(state)->defer_if_permit, (class), (fmt), (a1), (a2), (a3)); \ | |
49 | else \ | |
50 | (void) smtpd_check_reject((state), (class), (fmt), (a1), (a2), (a3)); \ | |
51 | } while (0) | |
52 | #define DEFER_IF_PERMIT4(state, class, fmt, a1, a2, a3, a4) do { \ | |
53 | if ((state)->warn_if_reject == 0) \ | |
54 | - defer_if(&(state)->defer_if_permit, (class), (fmt), (a1), (a2), (a3), (a4)); \ | |
55 | + defer_if((state), &(state)->defer_if_permit, (class), (fmt), (a1), (a2), (a3), (a4)); \ | |
56 | else \ | |
57 | (void) smtpd_check_reject((state), (class), (fmt), (a1), (a2), (a3), (a4)); \ | |
58 | } while (0) | |
59 | @@ -712,7 +712,18 @@ | |
60 | char *format,...) | |
61 | { | |
62 | va_list ap; | |
63 | + | |
64 | + va_start(ap, format); | |
65 | + vstring_vsprintf(error_text, format, ap); | |
66 | + va_end(ap); | |
67 | + | |
68 | + return(xsmtpd_check_reject(state, error_class, error_text)); | |
69 | +} | |
70 | +static int xsmtpd_check_reject(SMTPD_STATE *state, int error_class, | |
71 | + VSTRING *error_text) | |
72 | +{ | |
73 | int warn_if_reject; | |
74 | + int header_if_reject; | |
75 | const char *whatsup; | |
76 | ||
77 | /* | |
78 | @@ -726,15 +737,18 @@ | |
79 | warn_if_reject = 0; | |
80 | whatsup = "reject"; | |
81 | } | |
82 | + if (state->header_if_reject && error_class != MAIL_ERROR_SOFTWARE) { | |
83 | + header_if_reject = 1; | |
84 | + whatsup = "header_warning"; | |
85 | + } else { | |
86 | + header_if_reject = 0; | |
87 | + } | |
88 | ||
89 | /* | |
90 | * Update the error class mask, and format the response. XXX What about | |
91 | * multi-line responses? For now we cheat and send whitespace. | |
92 | */ | |
93 | state->error_mask |= error_class; | |
94 | - va_start(ap, format); | |
95 | - vstring_vsprintf(error_text, format, ap); | |
96 | - va_end(ap); | |
97 | ||
98 | /* | |
99 | * Ensure RFC compliance. We could do this inside smtpd_chat_reply() and | |
100 | @@ -796,15 +810,58 @@ | |
101 | */ | |
102 | log_whatsup(state, whatsup, STR(error_text)); | |
103 | ||
104 | - return (warn_if_reject ? 0 : SMTPD_CHECK_REJECT); | |
105 | + if (state->header_if_reject) { | |
106 | + VSTRING *hbuf = vstring_alloc(100); | |
107 | + int elen = strlen(STR(error_text)); | |
108 | + | |
109 | + if (state->prepend == 0) | |
110 | + state->prepend = argv_alloc(1); | |
111 | + printable(STR(error_text), '?'); | |
112 | + | |
113 | +#define PRETTY_HEADER | |
114 | +#ifdef PRETTY_HEADER | |
115 | + if (elen > 65) { | |
116 | + int len = 0, n; | |
117 | + char *p; | |
118 | + | |
119 | + vstring_sprintf(hbuf, "%s", "X-Reject: "); | |
120 | + while (len < elen-65 && (p = strchr(STR(error_text)+len+64, ' '))) { | |
121 | + *p = '\t'; | |
122 | + n = p-(STR(error_text)+len); | |
123 | + vstring_sprintf_append(hbuf, "%.*s\n", n, STR(error_text)+len); | |
124 | + len+=n; | |
125 | + } | |
126 | + vstring_sprintf_append(hbuf, "%s", STR(error_text)+len); | |
127 | + } | |
128 | + else { | |
129 | + vstring_sprintf(hbuf, "X-Reject: %s", STR(error_text)); | |
130 | + } | |
131 | +#else | |
132 | + vstring_sprintf(hbuf, "X-Reject: %.*s", 999, STR(error_text)); | |
133 | +#endif | |
134 | + argv_add(state->prepend, STR(hbuf), ARGV_END); | |
135 | + vstring_free(hbuf); | |
136 | + } | |
137 | + | |
138 | + return (warn_if_reject || header_if_reject ? 0 : SMTPD_CHECK_REJECT); | |
139 | } | |
140 | ||
141 | /* defer_if - prepare to change our mind */ | |
142 | ||
143 | -static void defer_if(SMTPD_DEFER *defer, int error_class, const char *fmt,...) | |
144 | +static void defer_if(SMTPD_STATE *state, SMTPD_DEFER *defer, int error_class, const char *fmt,...) | |
145 | { | |
146 | va_list ap; | |
147 | ||
148 | + if (state->header_if_reject) { | |
149 | + va_start(ap, fmt); | |
150 | + vstring_vsprintf(error_text, fmt, ap); | |
151 | + va_end(ap); | |
152 | + if (STR(error_text)[0] == '5') { | |
153 | + xsmtpd_check_reject(state, error_class, error_text); | |
154 | + return; | |
155 | + } | |
156 | + } | |
157 | + | |
158 | /* | |
159 | * Keep the first reason for this type of deferral, to minimize | |
160 | * confusion. | |
161 | @@ -3147,6 +3204,11 @@ | |
162 | state->warn_if_reject = state->recursion; | |
163 | continue; | |
164 | } | |
165 | + if (strcasecmp(name, HEADER_IF_REJECT) == 0) { | |
166 | + if (state->header_if_reject == 0) | |
167 | + state->header_if_reject = state->recursion; | |
168 | + continue; | |
169 | + } | |
170 | ||
171 | /* | |
172 | * Spoof the is_map_command() routine, so that we do not have to make | |
173 | @@ -3500,6 +3562,8 @@ | |
174 | ||
175 | if (state->warn_if_reject >= state->recursion) | |
176 | state->warn_if_reject = 0; | |
177 | + if (state->header_if_reject >= state->recursion) | |
178 | + state->header_if_reject = 0; | |
179 | ||
180 | if (status != 0) | |
181 | break; | |
182 | @@ -3554,6 +3618,7 @@ | |
183 | #define SMTPD_CHECK_RESET() { \ | |
184 | state->recursion = 0; \ | |
185 | state->warn_if_reject = 0; \ | |
186 | + state->header_if_reject = 0; \ | |
187 | state->defer_if_reject.active = 0; \ | |
188 | } | |
189 |