Postfix3.3.1
cleanup_addr.c
[詳解]
1 /*++
2 /* NAME
3 /* cleanup_addr 3
4 /* SUMMARY
5 /* process envelope addresses
6 /* SYNOPSIS
7 /* #include <cleanup.h>
8 /*
9 /* off_t cleanup_addr_sender(state, addr)
10 /* CLEANUP_STATE *state;
11 /* const char *addr;
12 /*
13 /* void cleanup_addr_recipient(state, addr)
14 /* CLEANUP_STATE *state;
15 /* const char *addr;
16 /*
17 /* void cleanup_addr_bcc_dsn(state, addr, dsn_orcpt, dsn_notify)
18 /* CLEANUP_STATE *state;
19 /* const char *addr;
20 /* const char *dsn_orcpt;
21 /* int dsn_notify;
22 /*
23 /* void cleanup_addr_bcc(state, addr)
24 /* CLEANUP_STATE *state;
25 /* const char *addr;
26 /* DESCRIPTION
27 /* This module processes envelope address records and writes the result
28 /* to the queue file. Processing includes address rewriting and
29 /* sender/recipient auto bcc address generation.
30 /*
31 /* cleanup_addr_sender() processes sender envelope information and updates
32 /* state->sender. The result value is the offset of the record that
33 /* follows the sender record if milters are enabled, otherwise zero.
34 /*
35 /* cleanup_addr_recipient() processes recipient envelope information
36 /* and updates state->recip.
37 /*
38 /* cleanup_addr_bcc_dsn() processes recipient envelope information. This
39 /* is a separate function to avoid invoking cleanup_addr_recipient()
40 /* recursively.
41 /*
42 /* cleanup_addr_bcc() is a backwards-compatibility wrapper for
43 /* cleanup_addr_bcc_dsn() that requests no delivery status
44 /* notification for the recipient.
45 /*
46 /* Arguments:
47 /* .IP state
48 /* Queue file and message processing state. This state is updated
49 /* as records are processed and as errors happen.
50 /* .IP buf
51 /* Record content.
52 /* .IP dsn_orcpt
53 /* The DSN original recipient (or NO_DSN_ORCPT to specify none).
54 /* .IP dsn_notify
55 /* DSN notification options. Specify NO_DSN_NOTIFY to disable
56 /* notification, and DEF_DSN_NOTIFY for default notification.
57 /* LICENSE
58 /* .ad
59 /* .fi
60 /* The Secure Mailer license must be distributed with this software.
61 /* AUTHOR(S)
62 /* Wietse Venema
63 /* IBM T.J. Watson Research
64 /* P.O. Box 704
65 /* Yorktown Heights, NY 10598, USA
66 /*
67 /* Wietse Venema
68 /* Google, Inc.
69 /* 111 8th Avenue
70 /* New York, NY 10011, USA
71 /*--*/
72 
73 /* System library. */
74 
75 #include <sys_defs.h>
76 #include <string.h>
77 #include <stdlib.h>
78 
79 /* Utility library. */
80 
81 #include <msg.h>
82 #include <vstring.h>
83 #include <vstream.h>
84 #include <mymalloc.h>
85 #include <stringops.h>
86 
87 /* Global library. */
88 
89 #include <rec_type.h>
90 #include <record.h>
91 #include <cleanup_user.h>
92 #include <mail_params.h>
93 #include <ext_prop.h>
94 #include <mail_addr.h>
95 #include <canon_addr.h>
96 #include <mail_addr_find.h>
97 #include <mail_proto.h>
98 #include <dsn_mask.h>
99 #include <smtputf8.h>
100 
101 /* Application-specific. */
102 
103 #include "cleanup.h"
104 
105 #define STR vstring_str
106 #define LEN VSTRING_LEN
107 #define IGNORE_EXTENSION (char **) 0
108 
109 /* cleanup_addr_sender - process envelope sender record */
110 
111 off_t cleanup_addr_sender(CLEANUP_STATE *state, const char *buf)
112 {
113  const char myname[] = "cleanup_addr_sender";
114  VSTRING *clean_addr = vstring_alloc(100);
115  off_t after_sender_offs = 0;
116  const char *bcc;
117  size_t len;
118 
119  /*
120  * Note: an unqualified envelope address is for all practical purposes
121  * equivalent to a fully qualified local address, both for delivery and
122  * for replying. Having to support both forms is error prone, therefore
123  * an incomplete envelope address is rewritten to fully qualified form in
124  * the local domain context.
125  *
126  * 20000520: Replace mailer-daemon@$myorigin by the null address, to handle
127  * bounced mail traffic more robustly.
128  */
130  if (strncasecmp_utf8(STR(clean_addr), MAIL_ADDR_MAIL_DAEMON "@",
131  sizeof(MAIL_ADDR_MAIL_DAEMON)) == 0) {
133  if (strcasecmp_utf8(STR(clean_addr), STR(state->temp1)) == 0)
134  vstring_strcpy(clean_addr, "");
135  }
136  if (state->flags & CLEANUP_FLAG_MAP_OK) {
142  && (cleanup_comm_canon_flags & CLEANUP_CANON_FLAG_ENV_FROM))
144  cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
148  }
149  /* Fix 20140711: Auto-detect an UTF8 sender. */
150  if (var_smtputf8_enable && *STR(clean_addr) && !allascii(STR(clean_addr))
151  && valid_utf8_string(STR(clean_addr), LEN(clean_addr))) {
152  state->smtputf8 |= SMTPUTF8_FLAG_SENDER;
153  /* Fix 20140713: request SMTPUTF8 support selectively. */
154  if (state->flags & CLEANUP_FLAG_AUTOUTF8)
156  }
157  CLEANUP_OUT_BUF(state, REC_TYPE_FROM, clean_addr);
158  if (state->sender) /* XXX Can't happen */
159  myfree(state->sender);
160  state->sender = mystrdup(STR(clean_addr)); /* Used by Milter client */
161  /* Fix 20160310: Moved from cleanup_envelope.c. */
162  if (state->milters || cleanup_milters) {
163  /* Make room to replace sender. */
164  if ((len = LEN(clean_addr)) < REC_TYPE_PTR_PAYL_SIZE)
166  /* Remember the after-sender record offset. */
167  if ((after_sender_offs = vstream_ftell(state->dst)) < 0)
168  msg_fatal("%s: vstream_ftell %s: %m:", myname, cleanup_path);
169  }
170  if ((state->flags & CLEANUP_FLAG_BCC_OK)
171  && *STR(clean_addr)
174  STR(clean_addr),
175  IGNORE_EXTENSION)) != 0) {
176  cleanup_addr_bcc(state, bcc);
177  } else if (cleanup_send_bcc_maps->error) {
178  msg_warn("%s: %s map lookup problem -- "
179  "message not accepted, try again later",
181  state->errs |= CLEANUP_STAT_WRITE;
182  }
183  }
184  vstring_free(clean_addr);
185  return after_sender_offs;
186 }
187 
188 /* cleanup_addr_recipient - process envelope recipient */
189 
190 void cleanup_addr_recipient(CLEANUP_STATE *state, const char *buf)
191 {
192  VSTRING *clean_addr = vstring_alloc(100);
193  const char *bcc;
194 
195  /*
196  * Note: an unqualified envelope address is for all practical purposes
197  * equivalent to a fully qualified local address, both for delivery and
198  * for replying. Having to support both forms is error prone, therefore
199  * an incomplete envelope address is rewritten to fully qualified form in
200  * the local domain context.
201  */
203  clean_addr, *buf ? buf : var_empty_addr);
204  if (state->flags & CLEANUP_FLAG_MAP_OK) {
210  && (cleanup_comm_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT))
212  cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
216  }
217  /* Fix 20140711: Auto-detect an UTF8 recipient. */
218  if (var_smtputf8_enable && *STR(clean_addr) && !allascii(STR(clean_addr))
219  && valid_utf8_string(STR(clean_addr), LEN(clean_addr))) {
220  /* Fix 20140713: request SMTPUTF8 support selectively. */
221  if (state->flags & CLEANUP_FLAG_AUTOUTF8)
223  }
224  /* Fix 20141024: Don't fake up a "bare" DSN original rcpt in smtp(8). */
225  if (state->dsn_orcpt == 0 && *STR(clean_addr) != 0)
226  state->dsn_orcpt = concatenate((!allascii(STR(clean_addr))
227  && (state->smtputf8 & SMTPUTF8_FLAG_REQUESTED)) ?
228  "utf-8" : "rfc822", ";", STR(clean_addr), (char *) 0);
229  cleanup_out_recipient(state, state->dsn_orcpt, state->dsn_notify,
230  state->orig_rcpt, STR(clean_addr));
231  if (state->recip) /* This can happen */
232  myfree(state->recip);
233  state->recip = mystrdup(STR(clean_addr)); /* Used by Milter client */
234  if ((state->flags & CLEANUP_FLAG_BCC_OK)
235  && *STR(clean_addr)
238  STR(clean_addr),
239  IGNORE_EXTENSION)) != 0) {
240  cleanup_addr_bcc(state, bcc);
241  } else if (cleanup_rcpt_bcc_maps->error) {
242  msg_warn("%s: %s map lookup problem -- "
243  "message not accepted, try again later",
245  state->errs |= CLEANUP_STAT_WRITE;
246  }
247  }
248  vstring_free(clean_addr);
249 }
250 
251 /* cleanup_addr_bcc_dsn - process automatic BCC recipient */
252 
253 void cleanup_addr_bcc_dsn(CLEANUP_STATE *state, const char *bcc,
254  const char *dsn_orcpt, int dsn_notify)
255 {
256  VSTRING *clean_addr = vstring_alloc(100);
257 
258  /*
259  * Note: BCC addresses are supplied locally, and must be rewritten in the
260  * local address rewriting context.
261  */
263  if (state->flags & CLEANUP_FLAG_MAP_OK) {
269  && (cleanup_comm_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT))
271  cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
275  }
276  /* Fix 20140711: Auto-detect an UTF8 recipient. */
277  if (var_smtputf8_enable && *STR(clean_addr) && !allascii(STR(clean_addr))
278  && valid_utf8_string(STR(clean_addr), LEN(clean_addr))) {
279  /* Fix 20140713: request SMTPUTF8 support selectively. */
280  if (state->flags & CLEANUP_FLAG_AUTOUTF8)
282  }
283  cleanup_out_recipient(state, dsn_orcpt, dsn_notify,
284  STR(clean_addr), STR(clean_addr));
285  vstring_free(clean_addr);
286 }
void cleanup_addr_bcc_dsn(CLEANUP_STATE *state, const char *bcc, const char *dsn_orcpt, int dsn_notify)
Definition: cleanup_addr.c:253
MAPS * cleanup_send_bcc_maps
Definition: cleanup_init.c:262
char * orig_rcpt
Definition: cleanup.h:61
void myfree(void *ptr)
Definition: mymalloc.c:207
int smtputf8
Definition: cleanup.h:134
MAPS * cleanup_rcpt_bcc_maps
Definition: cleanup_init.c:263
char * mystrdup(const char *str)
Definition: mymalloc.c:225
char * recip
Definition: cleanup.h:60
int cleanup_map11_internal(CLEANUP_STATE *, VSTRING *, MAPS *, int)
#define CLEANUP_FLAG_MAP_OK
Definition: cleanup_user.h:23
off_t vstream_ftell(VSTREAM *stream)
Definition: vstream.c:1157
MAPS * cleanup_rcpt_canon_maps
Definition: cleanup_init.c:250
int valid_utf8_string(const char *, ssize_t)
#define CLEANUP_CANON_FLAG_ENV_RCPT
Definition: cleanup.h:179
#define SMTPUTF8_FLAG_SENDER
Definition: smtputf8.h:99
#define REC_TYPE_PTR_PAYL_SIZE
Definition: rec_type.h:180
MILTERS * milters
Definition: cleanup.h:109
#define CLEANUP_OUT_BUF(s, t, b)
Definition: cleanup.h:236
int cleanup_comm_canon_flags
Definition: cleanup_init.c:251
#define MAIL_ATTR_RWR_LOCAL
Definition: mail_proto.h:166
#define LEN
Definition: cleanup_addr.c:106
VSTRING * canon_addr_internal(VSTRING *result, const char *addr)
Definition: canon_addr.c:64
int var_smtputf8_enable
Definition: mail_params.c:343
#define REC_TYPE_FROM
Definition: rec_type.h:43
#define strcasecmp_utf8(s1, s2)
Definition: stringops.h:75
ARGV * cleanup_masq_domains
Definition: cleanup_init.c:259
char * cleanup_path
Definition: cleanup_init.c:111
#define EXT_PROP_CANONICAL
Definition: ext_prop.h:17
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
Definition: vstring.c:431
int cleanup_ext_prop_mask
Definition: cleanup_init.c:274
#define SMTPUTF8_FLAG_REQUESTED
Definition: smtputf8.h:97
#define CLEANUP_MASQ_FLAG_ENV_RCPT
Definition: cleanup.h:187
int cleanup_rcpt_canon_flags
Definition: cleanup_init.c:253
#define STR
Definition: cleanup_addr.c:105
int dsn_notify
Definition: cleanup.h:99
char * var_empty_addr
Definition: cleanup_init.c:137
char * sender
Definition: cleanup.h:59
#define cleanup_addr_bcc(state, addr)
Definition: cleanup.h:304
char * dsn_orcpt
Definition: cleanup.h:100
char * title
Definition: maps.h:23
int rec_pad(VSTREAM *stream, int type, ssize_t len)
Definition: record.c:411
off_t cleanup_addr_sender(CLEANUP_STATE *state, const char *buf)
Definition: cleanup_addr.c:111
#define REC_TYPE_PTR
Definition: rec_type.h:67
#define MAIL_ADDR_MAIL_DAEMON
Definition: mail_addr.h:18
void msg_warn(const char *fmt,...)
Definition: msg.c:215
#define CLEANUP_FLAG_AUTOUTF8
Definition: cleanup_user.h:27
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
void cleanup_addr_recipient(CLEANUP_STATE *state, const char *buf)
Definition: cleanup_addr.c:190
#define IGNORE_EXTENSION
Definition: cleanup_addr.c:107
int cleanup_send_canon_flags
Definition: cleanup_init.c:252
char * queue_id
Definition: cleanup.h:56
#define allascii(s)
Definition: stringops.h:66
#define CLEANUP_MASQ_FLAG_ENV_FROM
Definition: cleanup.h:186
MAPS * cleanup_comm_canon_maps
Definition: cleanup_init.c:248
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
VSTREAM * dst
Definition: cleanup.h:53
char * concatenate(const char *arg0,...)
Definition: concatenate.c:42
int error
Definition: maps.h:25
VSTRING * temp1
Definition: cleanup.h:49
int cleanup_masquerade_internal(CLEANUP_STATE *, VSTRING *, ARGV *)
int cleanup_masq_flags
Definition: cleanup_init.c:261
#define strncasecmp_utf8(s1, s2, l)
Definition: stringops.h:77
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
MAPS * cleanup_send_canon_maps
Definition: cleanup_init.c:249
#define CLEANUP_STAT_WRITE
Definition: cleanup_user.h:58
MILTERS * cleanup_milters
Definition: cleanup_init.c:279
#define mail_addr_find_to_internal(maps, address, extension)
#define CLEANUP_FLAG_BCC_OK
Definition: cleanup_user.h:22
void cleanup_out_recipient(CLEANUP_STATE *, const char *, int, const char *, const char *)
#define CLEANUP_CANON_FLAG_ENV_FROM
Definition: cleanup.h:178
int cleanup_rewrite_internal(const char *, VSTRING *, const char *)