xref: /netbsd-src/external/ibm-public/postfix/dist/src/cleanup/cleanup_map11.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /*	$NetBSD: cleanup_map11.c,v 1.1.1.1 2009/06/23 10:08:43 tron 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 #ifdef STRCASECMP_IN_STRINGS_H
71 #include <strings.h>
72 #endif
73 
74 /* Utility library. */
75 
76 #include <msg.h>
77 #include <vstring.h>
78 #include <dict.h>
79 #include <mymalloc.h>
80 
81 /* Global library. */
82 
83 #include <cleanup_user.h>
84 #include <mail_addr_map.h>
85 #include <quote_822_local.h>
86 
87 /* Application-specific. */
88 
89 #include "cleanup.h"
90 
91 #define STR		vstring_str
92 #define MAX_RECURSION	10
93 
94 /* cleanup_map11_external - one-to-one table lookups */
95 
96 int     cleanup_map11_external(CLEANUP_STATE *state, VSTRING *addr,
97 			               MAPS *maps, int propagate)
98 {
99     int     count;
100     int     expand_to_self;
101     ARGV   *new_addr;
102     char   *saved_addr;
103     int     did_rewrite = 0;
104 
105     /*
106      * Produce sensible output even in the face of a recoverable error. This
107      * simplifies error recovery considerably because we can do delayed error
108      * checking in one place, instead of having error handling code all over
109      * the place.
110      */
111     for (count = 0; count < MAX_RECURSION; count++) {
112 	if ((new_addr = mail_addr_map(maps, STR(addr), propagate)) != 0) {
113 	    if (new_addr->argc > 1)
114 		msg_warn("%s: multi-valued %s entry for %s",
115 			 state->queue_id, maps->title, STR(addr));
116 	    saved_addr = mystrdup(STR(addr));
117 	    did_rewrite |= strcmp(new_addr->argv[0], STR(addr));
118 	    vstring_strcpy(addr, new_addr->argv[0]);
119 	    expand_to_self = !strcasecmp(saved_addr, STR(addr));
120 	    myfree(saved_addr);
121 	    argv_free(new_addr);
122 	    if (expand_to_self)
123 		return (did_rewrite);
124 	} else if (dict_errno != 0) {
125 	    msg_warn("%s: %s map lookup problem for %s",
126 		     state->queue_id, maps->title, STR(addr));
127 	    state->errs |= CLEANUP_STAT_WRITE;
128 	    return (did_rewrite);
129 	} else {
130 	    return (did_rewrite);
131 	}
132     }
133     msg_warn("%s: unreasonable %s map nesting for %s",
134 	     state->queue_id, maps->title, STR(addr));
135     return (did_rewrite);
136 }
137 
138 /* cleanup_map11_tree - rewrite address node */
139 
140 int     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 
162 int     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