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