xref: /netbsd-src/external/ibm-public/postfix/dist/src/cleanup/cleanup_addr.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /*	$NetBSD: cleanup_addr.c,v 1.1.1.2 2011/03/02 19:32:09 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(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 	&& (bcc = mail_addr_find(cleanup_send_bcc_maps, STR(clean_addr),
151 				 IGNORE_EXTENSION)) != 0)
152 	cleanup_addr_bcc(state, bcc);
153     vstring_free(clean_addr);
154 }
155 
156 /* cleanup_addr_recipient - process envelope recipient */
157 
158 void    cleanup_addr_recipient(CLEANUP_STATE *state, const char *buf)
159 {
160     VSTRING *clean_addr = vstring_alloc(100);
161     const char *bcc;
162 
163     /*
164      * Note: an unqualified envelope address is for all practical purposes
165      * equivalent to a fully qualified local address, both for delivery and
166      * for replying. Having to support both forms is error prone, therefore
167      * an incomplete envelope address is rewritten to fully qualified form in
168      * the local domain context.
169      */
170     cleanup_rewrite_internal(MAIL_ATTR_RWR_LOCAL,
171 			     clean_addr, *buf ? buf : var_empty_addr);
172     if (state->flags & CLEANUP_FLAG_MAP_OK) {
173 	if (cleanup_rcpt_canon_maps
174 	    && (cleanup_rcpt_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT))
175 	    cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
176 				cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
177 	if (cleanup_comm_canon_maps
178 	    && (cleanup_comm_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT))
179 	    cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
180 				cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
181 	if (cleanup_masq_domains
182 	    && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
183 	    cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
184     }
185     cleanup_out_recipient(state, state->dsn_orcpt, state->dsn_notify,
186 			  state->orig_rcpt, STR(clean_addr));
187     if (state->recip)				/* This can happen */
188 	myfree(state->recip);
189     state->recip = mystrdup(STR(clean_addr));	/* Used by Milter client */
190     if ((state->flags & CLEANUP_FLAG_BCC_OK)
191 	&& *STR(clean_addr)
192 	&& cleanup_rcpt_bcc_maps
193 	&& (bcc = mail_addr_find(cleanup_rcpt_bcc_maps, STR(clean_addr),
194 				 IGNORE_EXTENSION)) != 0)
195 	cleanup_addr_bcc(state, bcc);
196     vstring_free(clean_addr);
197 }
198 
199 /* cleanup_addr_bcc_dsn - process automatic BCC recipient */
200 
201 void    cleanup_addr_bcc_dsn(CLEANUP_STATE *state, const char *bcc,
202 			         const char *dsn_orcpt, int dsn_notify)
203 {
204     VSTRING *clean_addr = vstring_alloc(100);
205 
206     /*
207      * Note: BCC addresses are supplied locally, and must be rewritten in the
208      * local address rewriting context.
209      */
210     cleanup_rewrite_internal(MAIL_ATTR_RWR_LOCAL, clean_addr, bcc);
211     if (state->flags & CLEANUP_FLAG_MAP_OK) {
212 	if (cleanup_rcpt_canon_maps
213 	    && (cleanup_rcpt_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT))
214 	    cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
215 				cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
216 	if (cleanup_comm_canon_maps
217 	    && (cleanup_comm_canon_flags & CLEANUP_CANON_FLAG_ENV_RCPT))
218 	    cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
219 				cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
220 	if (cleanup_masq_domains
221 	    && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
222 	    cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
223     }
224     cleanup_out_recipient(state, dsn_orcpt, dsn_notify,
225 			  STR(clean_addr), STR(clean_addr));
226     vstring_free(clean_addr);
227 }
228