xref: /netbsd-src/external/ibm-public/postfix/dist/src/cleanup/cleanup_addr.c (revision 6a493d6bc668897c91594964a732d38505b70cbb)
1 /*	$NetBSD: cleanup_addr.c,v 1.1.1.3 2013/01/02 18:58:54 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	cleanup_addr 3
6 /* SUMMARY
7 /*	process envelope addresses
8 /* SYNOPSIS
9 /*	#include <cleanup.h>
10 /*
11 /*	void	cleanup_addr_sender(state, addr)
12 /*	CLEANUP_STATE *state;
13 /*	const char *addr;
14 /*
15 /*	void	cleanup_addr_recipient(state, addr)
16 /*	CLEANUP_STATE *state;
17 /*	const char *addr;
18 /*
19 /*	void	cleanup_addr_bcc_dsn(state, addr, dsn_orcpt, dsn_notify)
20 /*	CLEANUP_STATE *state;
21 /*	const char *addr;
22 /*	const char *dsn_orcpt;
23 /*	int	dsn_notify;
24 /*
25 /*	void	cleanup_addr_bcc(state, addr)
26 /*	CLEANUP_STATE *state;
27 /*	const char *addr;
28 /* DESCRIPTION
29 /*	This module processes envelope address records and writes the result
30 /*	to the queue file. Processing includes address rewriting and
31 /*	sender/recipient auto bcc address generation.
32 /*
33 /*	cleanup_addr_sender() processes sender envelope information and updates
34 /*	state->sender.
35 /*
36 /*	cleanup_addr_recipient() processes recipient envelope information
37 /*	and updates state->recip.
38 /*
39 /*	cleanup_addr_bcc_dsn() processes recipient envelope information. This
40 /*	is a separate function to avoid invoking cleanup_addr_recipient()
41 /*	recursively.
42 /*
43 /*	cleanup_addr_bcc() is a backwards-compatibility wrapper for
44 /*	cleanup_addr_bcc_dsn() that requests no delivery status
45 /*	notification for the recipient.
46 /*
47 /*	Arguments:
48 /* .IP state
49 /*	Queue file and message processing state. This state is updated
50 /*	as records are processed and as errors happen.
51 /* .IP buf
52 /*	Record content.
53 /* .IP dsn_orcpt
54 /*	The DSN original recipient (or NO_DSN_ORCPT to specify none).
55 /* .IP dsn_notify
56 /*	DSN notification options. Specify NO_DSN_NOTIFY to disable
57 /*	notification, and DEF_DSN_NOTIFY for default notification.
58 /* LICENSE
59 /* .ad
60 /* .fi
61 /*	The Secure Mailer license must be distributed with this software.
62 /* AUTHOR(S)
63 /*	Wietse Venema
64 /*	IBM T.J. Watson Research
65 /*	P.O. Box 704
66 /*	Yorktown Heights, NY 10598, USA
67 /*--*/
68 
69 /* System library. */
70 
71 #include <sys_defs.h>
72 #include <string.h>
73 #include <stdlib.h>
74 
75 #ifdef STRCASECMP_IN_STRINGS_H
76 #include <strings.h>
77 #endif
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 <cleanup_user.h>
91 #include <mail_params.h>
92 #include <ext_prop.h>
93 #include <mail_addr.h>
94 #include <canon_addr.h>
95 #include <mail_addr_find.h>
96 #include <mail_proto.h>
97 #include <dsn_mask.h>
98 
99 /* Application-specific. */
100 
101 #include "cleanup.h"
102 
103 #define STR			vstring_str
104 #define IGNORE_EXTENSION	(char **) 0
105 
106 /* cleanup_addr_sender - process envelope sender record */
107 
108 void    cleanup_addr_sender(CLEANUP_STATE *state, const char *buf)
109 {
110     VSTRING *clean_addr = vstring_alloc(100);
111     const char *bcc;
112 
113     /*
114      * Note: an unqualified envelope address is for all practical purposes
115      * equivalent to a fully qualified local address, both for delivery and
116      * for replying. Having to support both forms is error prone, therefore
117      * an incomplete envelope address is rewritten to fully qualified form in
118      * the local domain context.
119      *
120      * 20000520: Replace mailer-daemon@$myorigin by the null address, to handle
121      * bounced mail traffic more robustly.
122      */
123     cleanup_rewrite_internal(MAIL_ATTR_RWR_LOCAL, clean_addr, buf);
124     if (strncasecmp(STR(clean_addr), MAIL_ADDR_MAIL_DAEMON "@",
125 		    sizeof(MAIL_ADDR_MAIL_DAEMON)) == 0) {
126 	canon_addr_internal(state->temp1, MAIL_ADDR_MAIL_DAEMON);
127 	if (strcasecmp(STR(clean_addr), STR(state->temp1)) == 0)
128 	    vstring_strcpy(clean_addr, "");
129     }
130     if (state->flags & CLEANUP_FLAG_MAP_OK) {
131 	if (cleanup_send_canon_maps
132 	    && (cleanup_send_canon_flags & CLEANUP_CANON_FLAG_ENV_FROM))
133 	    cleanup_map11_internal(state, clean_addr, cleanup_send_canon_maps,
134 				cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
135 	if (cleanup_comm_canon_maps
136 	    && (cleanup_comm_canon_flags & CLEANUP_CANON_FLAG_ENV_FROM))
137 	    cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
138 				cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
139 	if (cleanup_masq_domains
140 	    && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_FROM))
141 	    cleanup_masquerade_internal(state, clean_addr, cleanup_masq_domains);
142     }
143     CLEANUP_OUT_BUF(state, REC_TYPE_FROM, clean_addr);
144     if (state->sender)				/* XXX Can't happen */
145 	myfree(state->sender);
146     state->sender = mystrdup(STR(clean_addr));	/* Used by Milter client */
147     if ((state->flags & CLEANUP_FLAG_BCC_OK)
148 	&& *STR(clean_addr)
149 	&& cleanup_send_bcc_maps) {
150 	if ((bcc = mail_addr_find(cleanup_send_bcc_maps, STR(clean_addr),
151 				  IGNORE_EXTENSION)) != 0) {
152 	    cleanup_addr_bcc(state, bcc);
153 	} else if (cleanup_send_bcc_maps->error) {
154 	    msg_warn("%s: %s lookup problem",
155 		     state->queue_id, cleanup_send_bcc_maps->title);
156 	    state->errs |= CLEANUP_STAT_WRITE;
157 	}
158     }
159     vstring_free(clean_addr);
160 }
161 
162 /* cleanup_addr_recipient - process envelope recipient */
163 
164 void    cleanup_addr_recipient(CLEANUP_STATE *state, const char *buf)
165 {
166     VSTRING *clean_addr = vstring_alloc(100);
167     const char *bcc;
168 
169     /*
170      * Note: an unqualified envelope address is for all practical purposes
171      * equivalent to a fully qualified local address, both for delivery and
172      * for replying. Having to support both forms is error prone, therefore
173      * an incomplete envelope address is rewritten to fully qualified form in
174      * the local domain context.
175      */
176     cleanup_rewrite_internal(MAIL_ATTR_RWR_LOCAL,
177 			     clean_addr, *buf ? buf : var_empty_addr);
178     if (state->flags & CLEANUP_FLAG_MAP_OK) {
179 	if (cleanup_rcpt_canon_maps
180 	    && (cleanup_rcpt_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT))
181 	    cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
182 				cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
183 	if (cleanup_comm_canon_maps
184 	    && (cleanup_comm_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT))
185 	    cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
186 				cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
187 	if (cleanup_masq_domains
188 	    && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
189 	    cleanup_masquerade_internal(state, clean_addr, cleanup_masq_domains);
190     }
191     cleanup_out_recipient(state, state->dsn_orcpt, state->dsn_notify,
192 			  state->orig_rcpt, STR(clean_addr));
193     if (state->recip)				/* This can happen */
194 	myfree(state->recip);
195     state->recip = mystrdup(STR(clean_addr));	/* Used by Milter client */
196     if ((state->flags & CLEANUP_FLAG_BCC_OK)
197 	&& *STR(clean_addr)
198 	&& cleanup_rcpt_bcc_maps) {
199 	if ((bcc = mail_addr_find(cleanup_rcpt_bcc_maps, STR(clean_addr),
200 				  IGNORE_EXTENSION)) != 0) {
201 	    cleanup_addr_bcc(state, bcc);
202 	} else if (cleanup_rcpt_bcc_maps->error) {
203 	    msg_warn("%s: %s lookup problem",
204 		     state->queue_id, cleanup_rcpt_bcc_maps->title);
205 	    state->errs |= CLEANUP_STAT_WRITE;
206 	}
207     }
208     vstring_free(clean_addr);
209 }
210 
211 /* cleanup_addr_bcc_dsn - process automatic BCC recipient */
212 
213 void    cleanup_addr_bcc_dsn(CLEANUP_STATE *state, const char *bcc,
214 			             const char *dsn_orcpt, int dsn_notify)
215 {
216     VSTRING *clean_addr = vstring_alloc(100);
217 
218     /*
219      * Note: BCC addresses are supplied locally, and must be rewritten in the
220      * local address rewriting context.
221      */
222     cleanup_rewrite_internal(MAIL_ATTR_RWR_LOCAL, clean_addr, bcc);
223     if (state->flags & CLEANUP_FLAG_MAP_OK) {
224 	if (cleanup_rcpt_canon_maps
225 	    && (cleanup_rcpt_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT))
226 	    cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
227 				cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
228 	if (cleanup_comm_canon_maps
229 	    && (cleanup_comm_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT))
230 	    cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
231 				cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
232 	if (cleanup_masq_domains
233 	    && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
234 	    cleanup_masquerade_internal(state, clean_addr, cleanup_masq_domains);
235     }
236     cleanup_out_recipient(state, dsn_orcpt, dsn_notify,
237 			  STR(clean_addr), STR(clean_addr));
238     vstring_free(clean_addr);
239 }
240