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