No empty .Rs/.Re
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / cleanup / cleanup_masquerade.c
blob780401c8a4aebbccbe883bde32be18ed8d2b2ab0
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* cleanup_masquerade 3
6 /* SUMMARY
7 /* address masquerading
8 /* SYNOPSIS
9 /* #include <cleanup.h>
11 /* int cleanup_masquerade_external(addr, masq_domains)
12 /* VSTRING *addr;
13 /* ARGV *masq_domains;
15 /* int cleanup_masquerade_internal(addr, masq_domains)
16 /* VSTRING *addr;
17 /* ARGV *masq_domains;
19 /* int cleanup_masquerade_tree(tree, masq_domains)
20 /* TOK822 *tree;
21 /* ARGV *masq_domains;
22 /* DESCRIPTION
23 /* This module masquerades addresses, that is, it strips subdomains
24 /* below domain names that are listed in the masquerade_domains
25 /* configuration parameter, except for user names listed in the
26 /* masquerade_exceptions configuration parameter.
27 /* These functions return non-zero when the address was changed.
29 /* cleanup_masquerade_external() rewrites the external (quoted) string
30 /* form of an address.
32 /* cleanup_masquerade_internal() is a wrapper around the
33 /* cleanup_masquerade_external() routine that transforms from
34 /* internal (quoted) string form to external form and back.
36 /* cleanup_masquerade_tree() is a wrapper around the
37 /* cleanup_masquerade_external() routine that transforms from
38 /* internal parse tree form to external form and back.
39 /* DIAGNOSTICS
40 /* LICENSE
41 /* .ad
42 /* .fi
43 /* The Secure Mailer license must be distributed with this software.
44 /* AUTHOR(S)
45 /* Wietse Venema
46 /* IBM T.J. Watson Research
47 /* P.O. Box 704
48 /* Yorktown Heights, NY 10598, USA
49 /*--*/
51 /* System library. */
53 #include <sys_defs.h>
54 #include <string.h>
56 #ifdef STRCASECMP_IN_STRINGS_H
57 #include <strings.h>
58 #endif
60 /* Utility library. */
62 #include <msg.h>
63 #include <vstring.h>
64 #include <argv.h>
65 #include <htable.h>
66 #include <mymalloc.h>
67 #include <stringops.h>
69 /* Global library. */
71 #include <mail_params.h>
72 #include <tok822.h>
73 #include <quote_822_local.h>
75 /* Application-specific. */
77 #include "cleanup.h"
79 #define STR vstring_str
81 /* cleanup_masquerade_external - masquerade address external form */
83 int cleanup_masquerade_external(VSTRING *addr, ARGV *masq_domains)
85 char *domain;
86 ssize_t domain_len;
87 char **masqp;
88 char *masq;
89 ssize_t masq_len;
90 char *parent;
91 int truncate;
92 int did_rewrite = 0;
94 /* Stuff for excluded names. */
95 char *name;
96 int excluded;
99 * Find the domain part.
101 if ((domain = strrchr(STR(addr), '@')) == 0)
102 return (0);
103 domain += 1;
104 domain_len = strlen(domain);
107 * Don't masquerade excluded names (regardless of domain).
109 if (*var_masq_exceptions) {
110 name = mystrndup(STR(addr), domain - 1 - STR(addr));
111 excluded = (string_list_match(cleanup_masq_exceptions, lowercase(name)) != 0);
112 myfree(name);
113 if (excluded)
114 return (0);
118 * If any parent domain matches the list of masquerade domains, replace
119 * the domain in the address and terminate. If the domain matches a
120 * masquerade domain, leave it alone. Order of specification matters.
122 for (masqp = masq_domains->argv; (masq = *masqp) != 0; masqp++) {
123 for (truncate = 1; *masq == '!'; masq++)
124 truncate = !truncate;
125 masq_len = strlen(masq);
126 if (masq_len == 0)
127 continue;
128 if (masq_len == domain_len) {
129 if (strcasecmp(masq, domain) == 0)
130 break;
131 } else if (masq_len < domain_len) {
132 parent = domain + domain_len - masq_len;
133 if (parent[-1] == '.' && strcasecmp(masq, parent) == 0) {
134 if (truncate) {
135 if (msg_verbose)
136 msg_info("masquerade: %s -> %s", domain, masq);
137 vstring_truncate(addr, domain - STR(addr));
138 vstring_strcat(addr, masq);
139 did_rewrite = 1;
141 break;
145 return (did_rewrite);
148 /* cleanup_masquerade_tree - masquerade address node */
150 int cleanup_masquerade_tree(TOK822 *tree, ARGV *masq_domains)
152 VSTRING *temp = vstring_alloc(100);
153 int did_rewrite;
155 tok822_externalize(temp, tree->head, TOK822_STR_DEFL);
156 did_rewrite = cleanup_masquerade_external(temp, masq_domains);
157 tok822_free_tree(tree->head);
158 tree->head = tok822_scan(STR(temp), &tree->tail);
160 vstring_free(temp);
161 return (did_rewrite);
164 /* cleanup_masquerade_internal - masquerade address internal form */
166 int cleanup_masquerade_internal(VSTRING *addr, ARGV *masq_domains)
168 VSTRING *temp = vstring_alloc(100);
169 int did_rewrite;
171 quote_822_local(temp, STR(addr));
172 did_rewrite = cleanup_masquerade_external(temp, masq_domains);
173 unquote_822_local(addr, STR(temp));
175 vstring_free(temp);
176 return (did_rewrite);
180 * Code for stand-alone testing. Instead of using main.cf, specify the strip
181 * list and the candidate domain on the command line. Specify null arguments
182 * for data that should be empty.
184 #ifdef TEST
186 #include <vstream.h>
188 char *var_masq_exceptions;
189 STRING_LIST *cleanup_masq_exceptions;
191 int main(int argc, char **argv)
193 VSTRING *addr;
194 ARGV *masq_domains;
196 if (argc != 4)
197 msg_fatal("usage: %s exceptions masquerade_list address", argv[0]);
199 var_masq_exceptions = argv[1];
200 cleanup_masq_exceptions =
201 string_list_init(MATCH_FLAG_NONE, var_masq_exceptions);
202 masq_domains = argv_split(argv[2], " ,\t\r\n");
203 addr = vstring_alloc(1);
204 if (strchr(argv[3], '@') == 0)
205 msg_fatal("address must be in user@domain form");
206 vstring_strcpy(addr, argv[3]);
208 vstream_printf("----------\n");
209 vstream_printf("exceptions: %s\n", argv[1]);
210 vstream_printf("masq_list: %s\n", argv[2]);
211 vstream_printf("address: %s\n", argv[3]);
213 cleanup_masquerade_external(addr, masq_domains);
215 vstream_printf("result: %s\n", STR(addr));
216 vstream_fflush(VSTREAM_OUT);
218 vstring_free(addr);
219 argv_free(masq_domains);
221 return (0);
224 #endif