]> TLD Linux GIT Repositories - packages/postfix.git/blob - postfix-header_if_reject.patch
- rel 3
[packages/postfix.git] / postfix-header_if_reject.patch
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