1/*++ 2/* NAME 3/* cleanup_map11 3 4/* SUMMARY 5/* one-to-one mapping 6/* SYNOPSIS 7/* #include <cleanup.h> 8/* 9/* int cleanup_map11_external(state, addr, maps, propagate) 10/* CLEANUP_STATE *state; 11/* VSTRING *addr; 12/* MAPS *maps; 13/* int propagate; 14/* 15/* int cleanup_map11_internal(state, addr, maps, propagate) 16/* CLEANUP_STATE *state; 17/* VSTRING *addr; 18/* MAPS *maps; 19/* int propagate; 20/* 21/* int cleanup_map11_tree(state, tree, maps, propagate) 22/* CLEANUP_STATE *state; 23/* TOK822 *tree; 24/* MAPS *maps; 25/* int propagate; 26/* DESCRIPTION 27/* This module performs one-to-one map lookups. 28/* 29/* If an address has a mapping, the lookup result is 30/* subjected to another iteration of rewriting and mapping. 31/* Recursion continues until an address maps onto itself, 32/* or until an unreasonable recursion level is reached. 33/* An unmatched address extension is propagated when 34/* \fIpropagate\fR is non-zero. 35/* These functions return non-zero when the address was changed. 36/* 37/* cleanup_map11_external() looks up the external (quoted) string 38/* form of an address in the maps specified via the \fImaps\fR argument. 39/* 40/* cleanup_map11_internal() is a wrapper around the 41/* cleanup_map11_external() routine that transforms from 42/* internal (quoted) string form to external form and back. 43/* 44/* cleanup_map11_tree() is a wrapper around the 45/* cleanup_map11_external() routine that transforms from 46/* internal parse tree form to external form and back. 47/* DIAGNOSTICS 48/* Recoverable errors: the global \fIcleanup_errs\fR flag is updated. 49/* SEE ALSO 50/* mail_addr_find(3) address lookups 51/* mail_addr_map(3) address mappings 52/* LICENSE 53/* .ad 54/* .fi 55/* The Secure Mailer license must be distributed with this software. 56/* AUTHOR(S) 57/* Wietse Venema 58/* IBM T.J. Watson Research 59/* P.O. Box 704 60/* Yorktown Heights, NY 10598, USA 61/*--*/ 62 63/* System library. */ 64 65#include <sys_defs.h> 66#include <string.h> 67 68#ifdef STRCASECMP_IN_STRINGS_H 69#include <strings.h> 70#endif 71 72/* Utility library. */ 73 74#include <msg.h> 75#include <vstring.h> 76#include <dict.h> 77#include <mymalloc.h> 78 79/* Global library. */ 80 81#include <cleanup_user.h> 82#include <mail_addr_map.h> 83#include <quote_822_local.h> 84 85/* Application-specific. */ 86 87#include "cleanup.h" 88 89#define STR vstring_str 90#define MAX_RECURSION 10 91 92/* cleanup_map11_external - one-to-one table lookups */ 93 94int cleanup_map11_external(CLEANUP_STATE *state, VSTRING *addr, 95 MAPS *maps, int propagate) 96{ 97 int count; 98 int expand_to_self; 99 ARGV *new_addr; 100 char *saved_addr; 101 int did_rewrite = 0; 102 103 /* 104 * Produce sensible output even in the face of a recoverable error. This 105 * simplifies error recovery considerably because we can do delayed error 106 * checking in one place, instead of having error handling code all over 107 * the place. 108 */ 109 for (count = 0; count < MAX_RECURSION; count++) { 110 if ((new_addr = mail_addr_map(maps, STR(addr), propagate)) != 0) { 111 if (new_addr->argc > 1) 112 msg_warn("%s: multi-valued %s entry for %s", 113 state->queue_id, maps->title, STR(addr)); 114 saved_addr = mystrdup(STR(addr)); 115 did_rewrite |= strcmp(new_addr->argv[0], STR(addr)); 116 vstring_strcpy(addr, new_addr->argv[0]); 117 expand_to_self = !strcasecmp(saved_addr, STR(addr)); 118 myfree(saved_addr); 119 argv_free(new_addr); 120 if (expand_to_self) 121 return (did_rewrite); 122 } else if (maps->error != 0) { 123 msg_warn("%s: %s map lookup problem for %s -- " 124 "message not accepted, try again later", 125 state->queue_id, maps->title, STR(addr)); 126 state->errs |= CLEANUP_STAT_WRITE; 127 return (did_rewrite); 128 } else { 129 return (did_rewrite); 130 } 131 } 132 msg_warn("%s: unreasonable %s map nesting for %s -- " 133 "message not accepted, try again later", 134 state->queue_id, maps->title, STR(addr)); 135 return (did_rewrite); 136} 137 138/* cleanup_map11_tree - rewrite address node */ 139 140int cleanup_map11_tree(CLEANUP_STATE *state, TOK822 *tree, 141 MAPS *maps, int propagate) 142{ 143 VSTRING *temp = vstring_alloc(100); 144 int did_rewrite; 145 146 /* 147 * Produce sensible output even in the face of a recoverable error. This 148 * simplifies error recovery considerably because we can do delayed error 149 * checking in one place, instead of having error handling code all over 150 * the place. 151 */ 152 tok822_externalize(temp, tree->head, TOK822_STR_DEFL); 153 did_rewrite = cleanup_map11_external(state, temp, maps, propagate); 154 tok822_free_tree(tree->head); 155 tree->head = tok822_scan(STR(temp), &tree->tail); 156 vstring_free(temp); 157 return (did_rewrite); 158} 159 160/* cleanup_map11_internal - rewrite address internal form */ 161 162int cleanup_map11_internal(CLEANUP_STATE *state, VSTRING *addr, 163 MAPS *maps, int propagate) 164{ 165 VSTRING *temp = vstring_alloc(100); 166 int did_rewrite; 167 168 /* 169 * Produce sensible output even in the face of a recoverable error. This 170 * simplifies error recovery considerably because we can do delayed error 171 * checking in one place, instead of having error handling code all over 172 * the place. 173 */ 174 quote_822_local(temp, STR(addr)); 175 did_rewrite = cleanup_map11_external(state, temp, maps, propagate); 176 unquote_822_local(addr, STR(temp)); 177 vstring_free(temp); 178 return (did_rewrite); 179} 180