]>
Commit | Line | Data |
---|---|---|
9e602738 | 1 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/makedefs postfix-2.0.16/makedefs |
0b72d562 | 2 | --- postfix-2.0.16.orig/makedefs 2003-01-23 14:45:02.000000000 +0100 |
9e602738 | 3 | +++ postfix-2.0.16/makedefs 2005-01-07 18:25:30.197331464 +0100 |
23bbf6c1 JB |
4 | @@ -52,6 +52,21 @@ |
5 | SYSTEM=`(uname -s) 2>/dev/null` | |
6 | RELEASE=`(uname -r) 2>/dev/null` | |
7 | VERSION=`(uname -v) 2>/dev/null` | |
8 | +if test -f /usr/include/netinet6/in6.h; then | |
9 | + grep __KAME__ /usr/include/netinet6/in6.h 2>&1 >/dev/null | |
10 | + if [ $? = 1 ]; then | |
11 | + INET6= | |
12 | + else | |
13 | + if [ -f /usr/local/v6/lib/libinet6.a ]; then | |
14 | + INET6=kame | |
15 | + else | |
16 | + INET6=kame-merged | |
17 | + fi | |
18 | + fi | |
19 | +fi | |
20 | +if [ -z "$INET6" -a -f /usr/include/netinet/ip6.h -a -f /usr/include/linux/icmpv6.h ]; then | |
21 | + INET6=linux | |
22 | +fi | |
23 | ||
24 | case "$VERSION" in | |
25 | dcosx*) SYSTEM=$VERSION;; | |
1ce4542c | 26 | @@ -318,6 +333,26 @@ |
23bbf6c1 JB |
27 | |
28 | : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk} | |
830ba608 | 29 | |
23bbf6c1 JB |
30 | +case "$INET6" in |
31 | +kame) | |
32 | + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len" | |
33 | + if test -f /usr/local/v6/lib/libinet6.a; then | |
34 | + SYSLIBS="$SYSLIBS -L/usr/local/v6/lib -linet6" | |
35 | + fi | |
36 | + ;; | |
37 | +kame-merged) | |
38 | + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len" | |
39 | + ;; | |
40 | +linux) | |
41 | + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family" | |
73f07215 JK |
42 | + if test -f /usr/include/libinet6/netinet/ip6.h |
43 | + then | |
23bbf6c1 JB |
44 | + CCARGS="$CCARGS -I/usr/include/libinet6 -DUSAGI_LIBINET6" |
45 | + SYSLIBS="$SYSLIBS -linet6" | |
46 | + fi | |
47 | + ;; | |
48 | +esac | |
830ba608 | 49 | + |
23bbf6c1 JB |
50 | export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS |
51 | ||
830ba608 | 52 | sed 's/ / /g' <<EOF |
9e602738 JK |
53 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/Makefile.in postfix-2.0.16/src/global/Makefile.in |
54 | --- postfix-2.0.16.orig/src/global/Makefile.in 2005-01-07 18:22:25.286442192 +0100 | |
55 | +++ postfix-2.0.16/src/global/Makefile.in 2005-01-07 18:25:30.198331312 +0100 | |
23bbf6c1 JB |
56 | @@ -19,7 +19,7 @@ |
57 | timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \ | |
58 | tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \ | |
59 | flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \ | |
7e195e4d TO |
60 | - verp_sender.c match_parent_style.c mime_state.c header_token.c \ |
61 | + verp_sender.c match_parent_style.c mime_state.c header_token.c wildcard_inet_addr.c\ | |
62 | strip_addr.c virtual8_maps.c hold_message.c dict_proxy.c mail_dict.c \ | |
63 | pfixtls.c | |
23bbf6c1 | 64 | OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \ |
7e195e4d | 65 | @@ -42,7 +42,7 @@ |
23bbf6c1 JB |
66 | timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \ |
67 | tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \ | |
68 | flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \ | |
7e195e4d TO |
69 | - verp_sender.o match_parent_style.o mime_state.o header_token.o \ |
70 | + verp_sender.o match_parent_style.o mime_state.o header_token.o wildcard_inet_addr.o\ | |
71 | strip_addr.o virtual8_maps.o hold_message.o dict_proxy.o mail_dict.o \ | |
72 | pfixtls.o | |
23bbf6c1 | 73 | HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \ |
7e195e4d | 74 | @@ -61,7 +61,7 @@ |
23bbf6c1 JB |
75 | rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \ |
76 | sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \ | |
447bfc58 | 77 | mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \ |
7e195e4d TO |
78 | - match_parent_style.h quote_flags.h mime_state.h header_token.h \ |
79 | + match_parent_style.h quote_flags.h mime_state.h header_token.h wildcard_inet_addr.h\ | |
80 | lex_822.h strip_addr.h virtual8_maps.h hold_message.h dict_proxy.h \ | |
81 | mail_dict.h pfixtls.h | |
23bbf6c1 | 82 | TESTSRC = rec2stream.c stream2rec.c recdump.c |
9e602738 | 83 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/mynetworks.c postfix-2.0.16/src/global/mynetworks.c |
0b72d562 | 84 | --- postfix-2.0.16.orig/src/global/mynetworks.c 2001-02-25 02:46:07.000000000 +0100 |
9e602738 JK |
85 | +++ postfix-2.0.16/src/global/mynetworks.c 2005-01-07 18:32:30.872379136 +0100 |
86 | @@ -50,6 +50,12 @@ | |
23bbf6c1 JB |
87 | #include <vstring.h> |
88 | #include <inet_addr_list.h> | |
89 | #include <name_mask.h> | |
90 | +#ifdef INET6 | |
91 | +#include <sys/socket.h> | |
92 | +#include <netinet/in.h> | |
93 | +#include <netdb.h> | |
94 | +#endif | |
9e602738 | 95 | +#include <string.h> |
23bbf6c1 JB |
96 | |
97 | /* Global library. */ | |
98 | ||
9e602738 | 99 | @@ -75,6 +81,9 @@ |
23bbf6c1 JB |
100 | const char *mynetworks(void) |
101 | { | |
102 | static VSTRING *result; | |
103 | +#ifdef INET6 | |
104 | + char hbuf[NI_MAXHOST]; | |
105 | +#endif | |
106 | ||
107 | if (result == 0) { | |
108 | char *myname = "mynetworks"; | |
9e602738 | 109 | @@ -87,6 +96,13 @@ |
23bbf6c1 JB |
110 | int junk; |
111 | int i; | |
112 | int mask_style; | |
113 | +#ifdef INET6 | |
114 | + struct sockaddr *sa; | |
1ce4542c TO |
115 | + struct sockaddr_in6 *addr6; |
116 | + struct sockaddr_in6 *mask6; | |
117 | + struct in6_addr net6; | |
118 | + int j; | |
23bbf6c1 JB |
119 | +#endif |
120 | ||
121 | mask_style = name_mask("mynetworks mask style", mask_styles, | |
122 | var_mynetworks_style); | |
9e602738 | 123 | @@ -96,8 +112,45 @@ |
23bbf6c1 JB |
124 | my_mask_list = own_inet_mask_list(); |
125 | ||
126 | for (i = 0; i < my_addr_list->used; i++) { | |
127 | +#ifdef INET6 | |
128 | + sa = (struct sockaddr *)&my_addr_list->addrs[i]; | |
1ce4542c TO |
129 | + if (sa->sa_family == AF_INET6) { |
130 | + addr6 = (struct sockaddr_in6 *)sa; | |
131 | + mask6 = (struct sockaddr_in6 *)&my_mask_list->addrs[i]; | |
132 | + | |
133 | + switch (mask_style) { | |
134 | + case MASK_STYLE_CLASS: | |
135 | + /* treat as subnet for IPv6 */ | |
136 | + case MASK_STYLE_SUBNET: | |
137 | + for (j=0; j<16; j++) | |
138 | + net6.s6_addr[j] = addr6->sin6_addr.s6_addr[j] & mask6->sin6_addr.s6_addr[j]; | |
139 | + for(shift=128; shift>0; shift--) | |
140 | + if ((mask6->sin6_addr.s6_addr[(shift-1) / 8]) & (0x80 >> ((shift-1) % 8))) | |
141 | + break; | |
142 | + break; | |
143 | + case MASK_STYLE_HOST: | |
144 | + memcpy (&net6, &(addr6->sin6_addr), sizeof(net6)); | |
145 | + shift=128; | |
146 | + break; | |
147 | + default: | |
148 | + msg_panic("unknown mynetworks mask style: %s", | |
149 | + var_mynetworks_style); | |
150 | + } | |
151 | + inet_ntop(AF_INET6, &net6, hbuf, sizeof(hbuf)); | |
152 | + if (!shift) | |
153 | + msg_warn("%s: skipped network with zero mask: [%s/0]", myname, hbuf); | |
154 | + else | |
155 | + vstring_sprintf_append(result, "[%s/%d] ", hbuf, shift); | |
156 | + continue; | |
157 | + } else if (sa->sa_family != AF_INET) { | |
23bbf6c1 JB |
158 | + continue; |
159 | + } | |
160 | + addr = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); | |
161 | + mask = ntohl(((struct sockaddr_in *)&my_mask_list->addrs[i])->sin_addr.s_addr); | |
162 | +#else | |
163 | addr = ntohl(my_addr_list->addrs[i].s_addr); | |
164 | mask = ntohl(my_mask_list->addrs[i].s_addr); | |
165 | +#endif | |
166 | ||
167 | switch (mask_style) { | |
168 | ||
9e602738 | 169 | @@ -119,8 +172,15 @@ |
23bbf6c1 JB |
170 | mask = IN_CLASSD_NET; |
171 | shift = IN_CLASSD_NSHIFT; | |
172 | } else { | |
173 | +#ifdef INET6 | |
174 | + if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0, | |
175 | + NI_NUMERICHOST)) | |
176 | + strncpy(hbuf, "???", sizeof(hbuf)); | |
177 | + msg_fatal("%s: bad address class: %s", myname, hbuf); | |
178 | +#else | |
179 | msg_fatal("%s: bad address class: %s", | |
180 | myname, inet_ntoa(my_addr_list->addrs[i])); | |
181 | +#endif | |
182 | } | |
183 | break; | |
184 | ||
9e602738 | 185 | @@ -146,6 +206,18 @@ |
1ce4542c TO |
186 | var_mynetworks_style); |
187 | } | |
188 | net.s_addr = htonl(addr & mask); | |
189 | + if (shift == BITS_PER_ADDR) { | |
190 | +#ifdef INET6 | |
191 | + if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0, | |
192 | + NI_NUMERICHOST)) | |
193 | + strncpy(hbuf, "???", sizeof(hbuf)); | |
194 | + msg_warn("%s: skipped network with zero mask: %s/0", myname, hbuf); | |
195 | +#else | |
196 | + msg_warn("%s: skipped network with zero mask: %s/0", | |
197 | + myname, inet_ntoa(my_addr_list->addrs[i])); | |
198 | +#endif | |
199 | + continue; | |
200 | + } | |
201 | vstring_sprintf_append(result, "%s/%d ", | |
202 | inet_ntoa(net), BITS_PER_ADDR - shift); | |
203 | } | |
9e602738 | 204 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/own_inet_addr.c postfix-2.0.16/src/global/own_inet_addr.c |
0b72d562 | 205 | --- postfix-2.0.16.orig/src/global/own_inet_addr.c 2002-10-25 01:19:19.000000000 +0200 |
9e602738 | 206 | +++ postfix-2.0.16/src/global/own_inet_addr.c 2005-01-07 18:25:30.198331312 +0100 |
1ce4542c | 207 | @@ -50,6 +50,10 @@ |
23bbf6c1 JB |
208 | #include <netinet/in.h> |
209 | #include <arpa/inet.h> | |
210 | #include <string.h> | |
211 | +#ifdef INET6 | |
212 | +#include <sys/socket.h> | |
213 | +#include <netdb.h> | |
214 | +#endif | |
215 | ||
216 | #ifdef STRCASECMP_IN_STRINGS_H | |
217 | #include <strings.h> | |
1ce4542c | 218 | @@ -113,10 +117,11 @@ |
23bbf6c1 JB |
219 | */ |
220 | else { | |
221 | bufp = hosts = mystrdup(var_inet_interfaces); | |
222 | - while ((host = mystrtok(&bufp, sep)) != 0) | |
223 | + while ((host = mystrtok(&bufp, sep)) != 0) { | |
224 | if (inet_addr_host(addr_list, host) == 0) | |
225 | msg_fatal("config variable %s: host not found: %s", | |
226 | VAR_INET_INTERFACES, host); | |
227 | + } | |
228 | myfree(hosts); | |
229 | ||
35140025 | 230 | /* |
1ce4542c | 231 | @@ -133,15 +138,39 @@ |
23bbf6c1 JB |
232 | msg_fatal("could not find any active network interfaces"); |
233 | for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) { | |
234 | for (nlocal = 0; /* see below */ ; nlocal++) { | |
235 | - if (nlocal >= local_addrs.used) | |
236 | + if (nlocal >= local_addrs.used) { | |
237 | +#ifdef INET6 | |
238 | + char hbuf[NI_MAXHOST]; | |
239 | + if (getnameinfo((struct sockaddr *)&addr_list->addrs[nvirtual], | |
240 | + SS_LEN(addr_list->addrs[nvirtual]), hbuf, | |
241 | + sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) | |
242 | + strncpy(hbuf, "???", sizeof(hbuf)); | |
243 | + msg_fatal("parameter %s: no local interface found for %s", | |
244 | + VAR_INET_INTERFACES, hbuf); | |
245 | +#else | |
246 | msg_fatal("parameter %s: no local interface found for %s", | |
247 | VAR_INET_INTERFACES, | |
248 | inet_ntoa(addr_list->addrs[nvirtual])); | |
249 | +#endif | |
250 | + } | |
251 | +#ifdef INET6 | |
252 | + if (addr_list->addrs[nvirtual].ss_family == | |
253 | + local_addrs.addrs[nlocal].ss_family && | |
254 | + SS_LEN(addr_list->addrs[nvirtual]) == | |
255 | + SS_LEN(local_addrs.addrs[nlocal]) && | |
256 | + memcmp(&addr_list->addrs[nvirtual], | |
257 | + &local_addrs.addrs[nlocal], | |
258 | + SS_LEN(local_addrs.addrs[nlocal])) == 0) { | |
259 | + inet_addr_list_append(mask_list, (struct sockaddr *)&local_masks.addrs[nlocal]); | |
260 | + break; | |
261 | + } | |
262 | +#else | |
263 | if (addr_list->addrs[nvirtual].s_addr | |
264 | == local_addrs.addrs[nlocal].s_addr) { | |
265 | inet_addr_list_append(mask_list, &local_masks.addrs[nlocal]); | |
266 | break; | |
267 | } | |
268 | +#endif | |
269 | } | |
270 | } | |
271 | inet_addr_list_free(&local_addrs); | |
1ce4542c | 272 | @@ -151,6 +180,42 @@ |
23bbf6c1 JB |
273 | |
274 | /* own_inet_addr - is this my own internet address */ | |
275 | ||
276 | +#ifdef INET6 | |
277 | +int own_inet_addr(struct sockaddr * addr) | |
278 | +{ | |
279 | + int i; | |
280 | + char *p, *q; | |
281 | + int l; | |
282 | + struct sockaddr *sa; | |
283 | + | |
284 | + if (addr_list.used == 0) | |
285 | + own_inet_addr_init(&addr_list, &mask_list); | |
286 | + | |
287 | + for (i = 0; i < addr_list.used; i++) { | |
288 | + sa = (struct sockaddr *)&addr_list.addrs[i]; | |
289 | + if (addr->sa_family != sa->sa_family) | |
290 | + continue; | |
291 | + switch (addr->sa_family) { | |
292 | + case AF_INET: | |
293 | + p = (char *)&((struct sockaddr_in *)addr)->sin_addr; | |
294 | + q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr; | |
295 | + l = sizeof(struct in_addr); | |
296 | + break; | |
297 | + case AF_INET6: | |
298 | + /* XXX scope */ | |
299 | + p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr; | |
300 | + q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr; | |
301 | + l = sizeof(struct in6_addr); | |
302 | + break; | |
303 | + default: | |
304 | + continue; | |
305 | + } | |
306 | + if (memcmp(p, q, l) == 0) | |
307 | + return (1); | |
308 | + } | |
309 | + return (0); | |
310 | +} | |
311 | +#else | |
312 | int own_inet_addr(struct in_addr * addr) | |
313 | { | |
314 | int i; | |
1ce4542c | 315 | @@ -161,8 +226,8 @@ |
23bbf6c1 JB |
316 | for (i = 0; i < addr_list.used; i++) |
317 | if (addr->s_addr == addr_list.addrs[i].s_addr) | |
318 | return (1); | |
319 | - return (0); | |
320 | } | |
321 | +#endif | |
322 | ||
323 | /* own_inet_addr_list - return list of addresses */ | |
324 | ||
9d0b6835 TO |
325 | @@ -213,6 +278,45 @@ |
326 | ||
327 | /* proxy_inet_addr - is this my proxy internet address */ | |
328 | ||
329 | +#ifdef INET6 | |
330 | +int proxy_inet_addr(struct sockaddr * addr) | |
331 | +{ | |
332 | + int i; | |
333 | + char *p, *q; | |
334 | + int l; | |
335 | + struct sockaddr *sa; | |
336 | + | |
337 | + if (*var_proxy_interfaces == 0) | |
338 | + return (0); | |
339 | + | |
340 | + if (proxy_list.used == 0) | |
341 | + proxy_inet_addr_init(&proxy_list); | |
342 | + | |
343 | + for (i = 0; i < proxy_list.used; i++) { | |
344 | + sa = (struct sockaddr *)&proxy_list.addrs[i]; | |
345 | + if (addr->sa_family != sa->sa_family) | |
346 | + continue; | |
347 | + switch (addr->sa_family) { | |
348 | + case AF_INET: | |
349 | + p = (char *)&((struct sockaddr_in *)addr)->sin_addr; | |
350 | + q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr; | |
351 | + l = sizeof(struct in_addr); | |
352 | + break; | |
353 | + case AF_INET6: | |
354 | + /* XXX scope */ | |
355 | + p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr; | |
356 | + q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr; | |
357 | + l = sizeof(struct in6_addr); | |
358 | + break; | |
359 | + default: | |
360 | + continue; | |
361 | + } | |
362 | + if (memcmp(p, q, l) == 0) | |
363 | + return (1); | |
364 | + } | |
365 | + return (0); | |
366 | +} | |
367 | +#else | |
368 | int proxy_inet_addr(struct in_addr * addr) | |
369 | { | |
370 | int i; | |
371 | @@ -228,6 +332,7 @@ | |
372 | return (1); | |
373 | return (0); | |
374 | } | |
375 | +#endif | |
376 | ||
377 | /* proxy_inet_addr_list - return list of addresses */ | |
378 | ||
9e602738 | 379 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/own_inet_addr.h postfix-2.0.16/src/global/own_inet_addr.h |
0b72d562 | 380 | --- postfix-2.0.16.orig/src/global/own_inet_addr.h 2002-10-25 01:07:05.000000000 +0200 |
9e602738 | 381 | +++ postfix-2.0.16/src/global/own_inet_addr.h 2005-01-07 18:25:30.199331160 +0100 |
cc66c172 | 382 | @@ -15,14 +15,25 @@ |
23bbf6c1 JB |
383 | * System library. |
384 | */ | |
385 | #include <netinet/in.h> | |
386 | +#ifdef INET6 | |
387 | +#include <sys/socket.h> | |
388 | +#endif | |
389 | ||
390 | /* | |
391 | * External interface. | |
392 | */ | |
393 | +#ifdef INET6 | |
394 | +extern int own_inet_addr(struct sockaddr *); | |
395 | +#else | |
396 | extern int own_inet_addr(struct in_addr *); | |
397 | +#endif | |
398 | extern struct INET_ADDR_LIST *own_inet_addr_list(void); | |
399 | extern struct INET_ADDR_LIST *own_inet_mask_list(void); | |
cc66c172 TO |
400 | +#ifdef INET6 |
401 | +extern int proxy_inet_addr(struct sockaddr *); | |
402 | +#else | |
403 | extern int proxy_inet_addr(struct in_addr *); | |
404 | +#endif | |
405 | extern struct INET_ADDR_LIST *proxy_inet_addr_list(void); | |
23bbf6c1 | 406 | |
cc66c172 | 407 | /* LICENSE |
9e602738 | 408 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/peer_name.c postfix-2.0.16/src/global/peer_name.c |
0b72d562 | 409 | --- postfix-2.0.16.orig/src/global/peer_name.c 2001-01-28 16:23:02.000000000 +0100 |
9e602738 | 410 | +++ postfix-2.0.16/src/global/peer_name.c 2005-01-07 18:25:30.199331160 +0100 |
23bbf6c1 JB |
411 | @@ -69,12 +69,32 @@ |
412 | PEER_NAME *peer_name(int sock) | |
413 | { | |
414 | static PEER_NAME peer; | |
415 | - struct sockaddr_in sin; | |
416 | - SOCKADDR_SIZE len = sizeof(sin); | |
417 | + union sockunion { | |
418 | + struct { | |
419 | + u_char si_len; | |
420 | + u_char si_family; | |
421 | + u_short si_port; | |
422 | + } su_si; | |
423 | + struct sockaddr peer_un; | |
424 | + struct sockaddr_in peer_un4; | |
425 | +#ifdef INET6 | |
426 | + struct sockaddr_in6 peer_un6; | |
427 | +#endif | |
428 | + } p_un; | |
429 | +#define sun p_un.peer_un | |
430 | +#define sin p_un.peer_un4 | |
431 | +#ifdef INET6 | |
432 | +#define sin6 p_un.peer_un6 | |
433 | + static char hbuf[NI_MAXHOST]; | |
434 | + static char abuf[NI_MAXHOST]; | |
435 | +#else | |
436 | struct hostent *hp; | |
437 | +#endif | |
438 | + SOCKADDR_SIZE len = sizeof(p_un); | |
439 | ||
440 | - if (getpeername(sock, (struct sockaddr *) & sin, &len) == 0) { | |
441 | - switch (sin.sin_family) { | |
442 | + if (getpeername(sock, (struct sockaddr *)&p_un, &len) == 0) { | |
443 | + switch (p_un.peer_un.sa_family) { | |
444 | +#ifndef INET6 | |
445 | case AF_INET: | |
446 | peer.type = PEER_TYPE_INET; | |
447 | hp = gethostbyaddr((char *) &(sin.sin_addr), | |
448 | @@ -83,6 +103,24 @@ | |
449 | hp->h_name : "unknown"); | |
450 | peer.addr = inet_ntoa(sin.sin_addr); | |
451 | return (&peer); | |
452 | +#else | |
453 | + case AF_INET: | |
454 | + peer.type = PEER_TYPE_INET; | |
455 | + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0) | |
456 | + peer.name = "unknown"; | |
457 | + else | |
458 | + peer.name = hbuf; | |
459 | + peer.addr = abuf; | |
460 | + return (&peer); | |
461 | + case AF_INET6: | |
462 | + peer.type = PEER_TYPE_INET6; | |
463 | + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0) | |
464 | + peer.name = "unknown"; | |
465 | + else | |
466 | + peer.name = hbuf; | |
467 | + peer.addr = abuf; | |
468 | + return (&peer); | |
469 | +#endif | |
470 | case AF_UNSPEC: | |
471 | case AF_UNIX: | |
472 | peer.type = PEER_TYPE_LOCAL; | |
9e602738 | 473 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/peer_name.h postfix-2.0.16/src/global/peer_name.h |
0b72d562 | 474 | --- postfix-2.0.16.orig/src/global/peer_name.h 1998-12-11 19:55:32.000000000 +0100 |
9e602738 | 475 | +++ postfix-2.0.16/src/global/peer_name.h 2005-01-07 18:25:30.199331160 +0100 |
23bbf6c1 JB |
476 | @@ -22,6 +22,9 @@ |
477 | #define PEER_TYPE_UNKNOWN 0 | |
478 | #define PEER_TYPE_INET 1 | |
479 | #define PEER_TYPE_LOCAL 2 | |
480 | +#ifdef INET6 | |
481 | +#define PEER_TYPE_INET6 3 | |
482 | +#endif | |
483 | ||
484 | extern PEER_NAME *peer_name(int); | |
485 | ||
9e602738 | 486 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/resolve_local.c postfix-2.0.16/src/global/resolve_local.c |
0b72d562 | 487 | --- postfix-2.0.16.orig/src/global/resolve_local.c 2002-10-25 01:21:20.000000000 +0200 |
9e602738 | 488 | +++ postfix-2.0.16/src/global/resolve_local.c 2005-01-07 18:25:30.199331160 +0100 |
1ce4542c | 489 | @@ -43,6 +43,7 @@ |
23bbf6c1 JB |
490 | #include <netinet/in.h> |
491 | #include <arpa/inet.h> | |
492 | #include <string.h> | |
493 | +#include <netdb.h> | |
494 | ||
495 | #ifndef INADDR_NONE | |
496 | #define INADDR_NONE 0xffffffff | |
1ce4542c | 497 | @@ -80,7 +81,12 @@ |
23bbf6c1 JB |
498 | { |
499 | char *saved_addr = mystrdup(addr); | |
500 | char *dest; | |
501 | +#ifdef INET6 | |
502 | + struct addrinfo hints, *res, *res0; | |
503 | + int error; | |
504 | +#else | |
505 | struct in_addr ipaddr; | |
506 | +#endif | |
507 | int len; | |
508 | ||
509 | #define RETURN(x) { myfree(saved_addr); return(x); } | |
7e195e4d | 510 | @@ -118,9 +124,25 @@ |
23bbf6c1 JB |
511 | if (*dest == '[' && dest[len - 1] == ']') { |
512 | dest++; | |
513 | dest[len -= 2] = 0; | |
514 | +#ifdef INET6 | |
515 | + memset(&hints, 0, sizeof(hints)); | |
516 | + hints.ai_family = PF_UNSPEC; | |
517 | + hints.ai_socktype = SOCK_DGRAM; | |
518 | + error = getaddrinfo(dest, NULL, &hints, &res0); | |
519 | + if (!error) { | |
520 | + for (res = res0; res; res = res->ai_next) { | |
521 | + if (own_inet_addr(res->ai_addr)) { | |
522 | + freeaddrinfo(res0); | |
523 | + RETURN(1); | |
524 | + } | |
525 | + } | |
526 | + freeaddrinfo(res0); | |
527 | + } | |
528 | +#else | |
529 | if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE | |
7e195e4d | 530 | && (own_inet_addr(&ipaddr) || proxy_inet_addr(&ipaddr))) |
23bbf6c1 JB |
531 | RETURN(1); |
532 | +#endif | |
533 | } | |
534 | ||
535 | /* | |
9e602738 | 536 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/wildcard_inet_addr.c postfix-2.0.16/src/global/wildcard_inet_addr.c |
0b72d562 | 537 | --- postfix-2.0.16.orig/src/global/wildcard_inet_addr.c 1970-01-01 01:00:00.000000000 +0100 |
9e602738 | 538 | +++ postfix-2.0.16/src/global/wildcard_inet_addr.c 2005-01-07 18:25:30.200331008 +0100 |
23bbf6c1 JB |
539 | @@ -0,0 +1,82 @@ |
540 | +/* System library. */ | |
541 | + | |
542 | +#include <sys_defs.h> | |
543 | +#include <netinet/in.h> | |
544 | +#include <arpa/inet.h> | |
545 | +#include <string.h> | |
546 | +#ifdef INET6 | |
547 | +#include <sys/socket.h> | |
548 | +#endif | |
549 | +#include <netdb.h> | |
550 | + | |
551 | +#ifdef STRCASECMP_IN_STRINGS_H | |
552 | +#include <strings.h> | |
553 | +#endif | |
554 | + | |
555 | +/* Utility library. */ | |
556 | + | |
557 | +#include <msg.h> | |
558 | +#include <mymalloc.h> | |
559 | +#include <inet_addr_list.h> | |
560 | +#include <inet_addr_local.h> | |
561 | +#include <inet_addr_host.h> | |
562 | +#include <stringops.h> | |
563 | + | |
564 | +/* Global library. */ | |
565 | + | |
566 | +#include <mail_params.h> | |
567 | +#include <wildcard_inet_addr.h> | |
568 | + | |
569 | +/* Application-specific. */ | |
570 | +static INET_ADDR_LIST addr_list; | |
571 | + | |
572 | +/* wildcard_inet_addr_init - initialize my own address list */ | |
573 | + | |
574 | +static void wildcard_inet_addr_init(INET_ADDR_LIST *addr_list) | |
575 | +{ | |
576 | +#ifdef INET6 | |
577 | + struct addrinfo hints, *res, *res0; | |
578 | + char hbuf[NI_MAXHOST]; | |
579 | + int error; | |
580 | +#ifdef NI_WITHSCOPEID | |
581 | + const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID; | |
582 | +#else | |
583 | + const int niflags = NI_NUMERICHOST; | |
584 | +#endif | |
585 | + | |
586 | + inet_addr_list_init(addr_list); | |
587 | + | |
588 | + memset(&hints, 0, sizeof(hints)); | |
589 | + hints.ai_family = PF_UNSPEC; | |
590 | + hints.ai_socktype = SOCK_STREAM; | |
591 | + hints.ai_flags = AI_PASSIVE; | |
592 | + error = getaddrinfo(NULL, "0", &hints, &res0); | |
593 | + if (error) | |
594 | + msg_fatal("could not get list of wildcard addresses"); | |
595 | + for (res = res0; res; res = res->ai_next) { | |
596 | + if (res->ai_family != AF_INET && res->ai_family != AF_INET6) | |
597 | + continue; | |
598 | + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), | |
599 | + NULL, 0, niflags) != 0) | |
600 | + continue; | |
601 | + if (inet_addr_host(addr_list, hbuf) == 0) | |
602 | + continue; /* msg_fatal("config variable %s: host not found: %s", | |
603 | + VAR_INET_INTERFACES, hbuf); */ | |
604 | + } | |
605 | + freeaddrinfo(res0); | |
606 | +#else | |
607 | + if (inet_addr_host(addr_list, "0.0.0.0") == 0) | |
608 | + msg_fatal("config variable %s: host not found: %s", | |
609 | + VAR_INET_INTERFACES, "0.0.0.0"); | |
610 | +#endif | |
611 | +} | |
612 | + | |
613 | +/* wildcard_inet_addr_list - return list of addresses */ | |
614 | + | |
615 | +INET_ADDR_LIST *wildcard_inet_addr_list(void) | |
616 | +{ | |
617 | + if (addr_list.used == 0) | |
618 | + wildcard_inet_addr_init(&addr_list); | |
619 | + | |
620 | + return (&addr_list); | |
621 | +} | |
9e602738 | 622 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/global/wildcard_inet_addr.h postfix-2.0.16/src/global/wildcard_inet_addr.h |
0b72d562 | 623 | --- postfix-2.0.16.orig/src/global/wildcard_inet_addr.h 1970-01-01 01:00:00.000000000 +0100 |
9e602738 | 624 | +++ postfix-2.0.16/src/global/wildcard_inet_addr.h 2005-01-07 18:25:30.200331008 +0100 |
23bbf6c1 JB |
625 | @@ -0,0 +1,36 @@ |
626 | +#ifndef _WILDCARD_INET_ADDR_H_INCLUDED_ | |
627 | +#define _WILDCARD_INET_ADDR_H_INCLUDED_ | |
628 | + | |
629 | +/*++ | |
630 | +/* NAME | |
631 | +/* wildcard_inet_addr_list 3h | |
632 | +/* SUMMARY | |
633 | +/* grab the list of wildcard IP addresses. | |
634 | +/* SYNOPSIS | |
635 | +/* #include <own_inet_addr.h> | |
636 | +/* DESCRIPTION | |
637 | +/* .nf | |
638 | +/*--*/ | |
639 | + | |
640 | + /* | |
641 | + * System library. | |
642 | + */ | |
643 | +#include <netinet/in.h> | |
644 | +#ifdef INET6 | |
645 | +#include <sys/socket.h> | |
646 | +#endif | |
647 | + | |
648 | + /* | |
649 | + * External interface. | |
650 | + */ | |
651 | +extern struct INET_ADDR_LIST *wildcard_inet_addr_list(void); | |
652 | + | |
653 | +/* LICENSE | |
654 | +/* .ad | |
655 | +/* .fi | |
656 | +/* foo | |
657 | +/* AUTHOR(S) | |
658 | +/* Jun-ichiro itojun Hagino | |
659 | +/*--*/ | |
660 | + | |
661 | +#endif | |
9e602738 | 662 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/master/master_ent.c postfix-2.0.16/src/master/master_ent.c |
0b72d562 | 663 | --- postfix-2.0.16.orig/src/master/master_ent.c 2003-06-18 21:19:46.000000000 +0200 |
9e602738 JK |
664 | +++ postfix-2.0.16/src/master/master_ent.c 2005-01-07 18:35:28.571364784 +0100 |
665 | @@ -92,6 +92,7 @@ | |
666 | #include <mail_proto.h> | |
667 | #include <mail_params.h> | |
668 | #include <own_inet_addr.h> | |
669 | +#include <wildcard_inet_addr.h> | |
670 | ||
671 | /* Local stuff. */ | |
672 | ||
673 | @@ -307,8 +308,13 @@ | |
1ce4542c | 674 | inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv)); |
23bbf6c1 | 675 | serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used; |
48f922aa | 676 | } else if (strcasecmp(saved_interfaces, DEF_INET_INTERFACES) == 0) { |
23bbf6c1 | 677 | +#ifdef INET6 |
48f922aa TO |
678 | + MASTER_INET_ADDRLIST(serv) = wildcard_inet_addr_list(); |
679 | + serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used; | |
23bbf6c1 JB |
680 | +#else |
681 | MASTER_INET_ADDRLIST(serv) = 0; /* wild-card */ | |
682 | serv->listen_fd_count = 1; | |
683 | +#endif | |
684 | } else { | |
685 | MASTER_INET_ADDRLIST(serv) = own_inet_addr_list(); /* virtual */ | |
1ce4542c | 686 | inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv)); |
9e602738 | 687 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/master/master_listen.c postfix-2.0.16/src/master/master_listen.c |
0b72d562 | 688 | --- postfix-2.0.16.orig/src/master/master_listen.c 2001-05-01 00:47:57.000000000 +0200 |
9e602738 | 689 | +++ postfix-2.0.16/src/master/master_listen.c 2005-01-07 18:25:30.201330856 +0100 |
e38d57a7 | 690 | @@ -64,13 +64,22 @@ |
23bbf6c1 JB |
691 | |
692 | #include "master.h" | |
693 | ||
694 | +#ifdef INET6 | |
695 | +#include <netdb.h> | |
696 | +#include <stdio.h> | |
697 | +#endif | |
698 | + | |
699 | /* master_listen_init - enable connection requests */ | |
700 | ||
701 | void master_listen_init(MASTER_SERV *serv) | |
e38d57a7 | 702 | { |
23bbf6c1 JB |
703 | char *myname = "master_listen_init"; |
704 | char *end_point; | |
e38d57a7 JB |
705 | - int n; |
706 | + int n,m,tmpfd; | |
23bbf6c1 JB |
707 | +#ifdef INET6 |
708 | + char hbuf[NI_MAXHOST]; | |
709 | + SOCKADDR_SIZE salen; | |
710 | +#endif | |
711 | ||
712 | /* | |
713 | * Find out what transport we should use, then create one or more | |
e38d57a7 JB |
714 | @@ -111,18 +120,31 @@ |
715 | serv->listen_fd[0] = | |
716 | inet_listen(MASTER_INET_PORT(serv), | |
717 | serv->max_proc > var_proc_limit ? | |
718 | - serv->max_proc : var_proc_limit, NON_BLOCKING); | |
719 | + serv->max_proc : var_proc_limit, NON_BLOCKING, 1); | |
23bbf6c1 JB |
720 | close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC); |
721 | } else { /* virtual or host:port */ | |
e38d57a7 JB |
722 | - for (n = 0; n < serv->listen_fd_count; n++) { |
723 | + for (m = n = 0; n < serv->listen_fd_count; n++) { | |
23bbf6c1 JB |
724 | +#ifdef INET6 |
725 | + if (getnameinfo((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n], | |
726 | + SA_LEN((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n]), | |
727 | + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) { | |
728 | + strncpy(hbuf, "?????", sizeof(hbuf)); | |
729 | + } | |
730 | + end_point = concatenate(hbuf, ":", MASTER_INET_PORT(serv), (char *) 0); | |
731 | +#else | |
732 | end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]), | |
733 | ":", MASTER_INET_PORT(serv), (char *) 0); | |
e38d57a7 | 734 | - serv->listen_fd[n] |
23bbf6c1 | 735 | +#endif |
e38d57a7 | 736 | + tmpfd |
23bbf6c1 | 737 | = inet_listen(end_point, serv->max_proc > var_proc_limit ? |
e38d57a7 JB |
738 | - serv->max_proc : var_proc_limit, NON_BLOCKING); |
739 | - close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC); | |
740 | + serv->max_proc : var_proc_limit, NON_BLOCKING, 0); | |
741 | + if (tmpfd >= 0) { | |
742 | + serv->listen_fd[m] = tmpfd; | |
743 | + close_on_exec(serv->listen_fd[m++], CLOSE_ON_EXEC); | |
744 | + } | |
745 | myfree(end_point); | |
746 | } | |
747 | + serv->listen_fd_count=m; | |
748 | } | |
749 | break; | |
750 | default: | |
9e602738 JK |
751 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtp/Makefile.in postfix-2.0.16/src/smtp/Makefile.in |
752 | --- postfix-2.0.16.orig/src/smtp/Makefile.in 2005-01-07 18:22:25.253447208 +0100 | |
753 | +++ postfix-2.0.16/src/smtp/Makefile.in 2005-01-07 18:25:30.201330856 +0100 | |
0b72d562 | 754 | @@ -144,6 +144,7 @@ |
23bbf6c1 JB |
755 | smtp_connect.o: ../../include/mail_params.h |
756 | smtp_connect.o: ../../include/own_inet_addr.h | |
757 | smtp_connect.o: ../../include/dns.h | |
758 | +smtp_connect.o: ../../include/get_port.h | |
759 | smtp_connect.o: smtp.h | |
760 | smtp_connect.o: ../../include/argv.h | |
761 | smtp_connect.o: ../../include/deliver_request.h | |
9e602738 | 762 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtp/smtp_addr.c postfix-2.0.16/src/smtp/smtp_addr.c |
0b72d562 | 763 | --- postfix-2.0.16.orig/src/smtp/smtp_addr.c 2002-10-25 01:03:11.000000000 +0200 |
9e602738 | 764 | +++ postfix-2.0.16/src/smtp/smtp_addr.c 2005-01-07 18:25:30.201330856 +0100 |
35140025 | 765 | @@ -134,18 +134,68 @@ |
23bbf6c1 JB |
766 | static void smtp_print_addr(char *what, DNS_RR *addr_list) |
767 | { | |
768 | DNS_RR *addr; | |
769 | - struct in_addr in_addr; | |
770 | +#ifdef INET6 | |
771 | + struct sockaddr_storage ss; | |
772 | +#else | |
773 | + struct sockaddr ss; | |
774 | +#endif | |
775 | + struct sockaddr_in *sin; | |
776 | +#ifdef INET6 | |
777 | + struct sockaddr_in6 *sin6; | |
778 | + char hbuf[NI_MAXHOST]; | |
779 | +#else | |
780 | + char hbuf[sizeof("255.255.255.255") + 1]; | |
781 | +#endif | |
782 | ||
783 | msg_info("begin %s address list", what); | |
784 | for (addr = addr_list; addr; addr = addr->next) { | |
785 | - if (addr->data_len > sizeof(addr)) { | |
786 | - msg_warn("skipping address length %d", addr->data_len); | |
787 | - } else { | |
788 | - memcpy((char *) &in_addr, addr->data, sizeof(in_addr)); | |
789 | - msg_info("pref %4d host %s/%s", | |
790 | - addr->pref, addr->name, | |
791 | - inet_ntoa(in_addr)); | |
792 | + if (addr->class != C_IN) { | |
793 | + msg_warn("skipping unsupported address (class=%u)", addr->class); | |
794 | + continue; | |
9e602738 | 795 | } |
23bbf6c1 JB |
796 | + switch (addr->type) { |
797 | + case T_A: | |
798 | + if (addr->data_len != sizeof(sin->sin_addr)) { | |
799 | + msg_warn("skipping invalid address (AAAA, len=%u)", | |
800 | + addr->data_len); | |
801 | + continue; | |
802 | + } | |
803 | + sin = (struct sockaddr_in *)&ss; | |
804 | + memset(sin, 0, sizeof(*sin)); | |
805 | + sin->sin_family = AF_INET; | |
806 | +#ifdef HAS_SA_LEN | |
807 | + sin->sin_len = sizeof(*sin); | |
808 | +#endif | |
809 | + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr)); | |
810 | + break; | |
811 | +#ifdef INET6 | |
812 | + case T_AAAA: | |
813 | + if (addr->data_len != sizeof(sin6->sin6_addr)) { | |
814 | + msg_warn("skipping invalid address (AAAA, len=%u)", | |
815 | + addr->data_len); | |
816 | + continue; | |
817 | + } | |
818 | + sin6 = (struct sockaddr_in6 *)&ss; | |
819 | + memset(sin6, 0, sizeof(*sin6)); | |
820 | + sin6->sin6_family = AF_INET6; | |
821 | +#ifdef HAS_SA_LEN | |
822 | + sin6->sin6_len = sizeof(*sin6); | |
823 | +#endif | |
824 | + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr)); | |
825 | + break; | |
826 | +#endif | |
827 | + default: | |
828 | + msg_warn("skipping unsupported address (type=%u)", addr->type); | |
829 | + continue; | |
9e602738 | 830 | + } |
23bbf6c1 JB |
831 | + |
832 | +#ifdef INET6 | |
833 | + (void)getnameinfo((struct sockaddr *)&ss, SS_LEN(ss), | |
834 | + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST); | |
835 | +#else | |
836 | + (void)inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf)); | |
837 | +#endif | |
838 | + msg_info("pref %4d host %s/%s", addr->pref, addr->name, hbuf); | |
839 | } | |
840 | msg_info("end %s address list", what); | |
841 | } | |
35140025 | 842 | @@ -155,15 +205,23 @@ |
23bbf6c1 JB |
843 | static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why) |
844 | { | |
845 | char *myname = "smtp_addr_one"; | |
846 | +#ifndef INET6 | |
847 | struct in_addr inaddr; | |
848 | - DNS_FIXED fixed; | |
849 | DNS_RR *addr = 0; | |
850 | DNS_RR *rr; | |
851 | struct hostent *hp; | |
852 | +#else | |
853 | + struct addrinfo hints, *res0, *res; | |
854 | + int error = -1; | |
855 | + char *addr; | |
856 | + size_t addrlen; | |
857 | +#endif | |
858 | + DNS_FIXED fixed; | |
859 | ||
860 | if (msg_verbose) | |
861 | msg_info("%s: host %s", myname, host); | |
862 | ||
863 | +#ifndef INET6 | |
864 | /* | |
865 | * Interpret a numerical name as an address. | |
866 | */ | |
35140025 | 867 | @@ -216,6 +274,48 @@ |
23bbf6c1 JB |
868 | smtp_errno = SMTP_FAIL; |
869 | break; | |
870 | } | |
871 | +#else | |
872 | + memset(&hints, 0, sizeof(hints)); | |
873 | + hints.ai_family = PF_UNSPEC; | |
874 | + hints.ai_socktype = SOCK_STREAM; | |
875 | + error = getaddrinfo(host, NULL, &hints, &res0); | |
876 | + if (error) { | |
877 | + switch (error) { | |
878 | + case EAI_AGAIN: | |
879 | + smtp_errno = SMTP_RETRY; | |
880 | + break; | |
881 | + default: | |
882 | + vstring_sprintf(why, "[%s]: %s",host,gai_strerror(error)); | |
883 | + smtp_errno = SMTP_FAIL; | |
884 | + break; | |
885 | + } | |
886 | + return (addr_list); | |
887 | + } | |
888 | + for (res = res0; res; res = res->ai_next) { | |
889 | + memset((char *) &fixed, 0, sizeof(fixed)); | |
890 | + switch(res->ai_family) { | |
891 | + case AF_INET6: | |
892 | + /* XXX not scope friendly */ | |
893 | + fixed.type = T_AAAA; | |
894 | + addr = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; | |
895 | + addrlen = sizeof(struct in6_addr); | |
896 | + break; | |
897 | + case AF_INET: | |
898 | + fixed.type = T_A; | |
899 | + addr = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr; | |
900 | + addrlen = sizeof(struct in_addr); | |
901 | + break; | |
902 | + default: | |
903 | + msg_warn("%s: unknown address family %d for %s", | |
904 | + myname, res->ai_family, host); | |
905 | + continue; | |
906 | + } | |
907 | + addr_list = dns_rr_append(addr_list, | |
908 | + dns_rr_create(host, &fixed, pref, addr, addrlen)); | |
909 | + } | |
910 | + if (res0) | |
911 | + freeaddrinfo(res0); | |
912 | +#endif | |
913 | return (addr_list); | |
914 | } | |
915 | ||
35140025 | 916 | @@ -251,6 +351,9 @@ |
23bbf6c1 JB |
917 | INET_ADDR_LIST *self; |
918 | DNS_RR *addr; | |
919 | int i; | |
920 | +#ifdef INET6 | |
921 | + struct sockaddr *sa; | |
922 | +#endif | |
923 | ||
924 | /* | |
925 | * Find the first address that lists any address that this mail system is | |
35140025 | 926 | @@ -260,12 +363,36 @@ |
23bbf6c1 JB |
927 | |
928 | self = own_inet_addr_list(); | |
929 | for (addr = addr_list; addr; addr = addr->next) { | |
930 | - for (i = 0; i < self->used; i++) | |
931 | + for (i = 0; i < self->used; i++) { | |
932 | +#ifdef INET6 | |
933 | + sa = (struct sockaddr *)&self->addrs[i]; | |
934 | + switch(addr->type) { | |
935 | + case T_AAAA: | |
936 | + /* XXX scope */ | |
937 | + if (sa->sa_family != AF_INET6) | |
938 | + break; | |
939 | + if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr, | |
940 | + addr->data, sizeof(struct in6_addr)) == 0) { | |
941 | + return(addr); | |
942 | + } | |
943 | + break; | |
944 | + case T_A: | |
945 | + if (sa->sa_family != AF_INET) | |
946 | + break; | |
947 | + if (memcmp(&((struct sockaddr_in *)sa)->sin_addr, | |
948 | + addr->data, sizeof(struct in_addr)) == 0) { | |
949 | + return(addr); | |
950 | + } | |
951 | + break; | |
952 | + } | |
953 | +#else | |
954 | if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) { | |
955 | if (msg_verbose) | |
956 | msg_info("%s: found at pref %d", myname, addr->pref); | |
957 | return (addr); | |
958 | } | |
959 | +#endif | |
960 | + } | |
961 | } | |
962 | ||
368b25b6 | 963 | /* |
1ce4542c | 964 | @@ -273,12 +400,36 @@ |
368b25b6 TO |
965 | */ |
966 | self = proxy_inet_addr_list(); | |
967 | for (addr = addr_list; addr; addr = addr->next) { | |
968 | - for (i = 0; i < self->used; i++) | |
969 | + for (i = 0; i < self->used; i++) { | |
970 | +#ifdef INET6 | |
971 | + sa = (struct sockaddr *)&self->addrs[i]; | |
972 | + switch(addr->type) { | |
973 | + case T_AAAA: | |
974 | + /* XXX scope */ | |
975 | + if (sa->sa_family != AF_INET6) | |
976 | + break; | |
977 | + if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr, | |
978 | + addr->data, sizeof(struct in6_addr)) == 0) { | |
979 | + return(addr); | |
980 | + } | |
981 | + break; | |
982 | + case T_A: | |
983 | + if (sa->sa_family != AF_INET) | |
984 | + break; | |
985 | + if (memcmp(&((struct sockaddr_in *)sa)->sin_addr, | |
986 | + addr->data, sizeof(struct in_addr)) == 0) { | |
987 | + return(addr); | |
988 | + } | |
989 | + break; | |
990 | + } | |
991 | +#else | |
992 | if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) { | |
993 | if (msg_verbose) | |
994 | msg_info("%s: found at pref %d", myname, addr->pref); | |
995 | return (addr); | |
996 | } | |
997 | +#endif | |
998 | + } | |
999 | } | |
1000 | ||
23bbf6c1 | 1001 | /* |
9e602738 JK |
1002 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtp/smtp_connect.c postfix-2.0.16/src/smtp/smtp_connect.c |
1003 | --- postfix-2.0.16.orig/src/smtp/smtp_connect.c 2005-01-07 18:22:25.254447056 +0100 | |
1004 | +++ postfix-2.0.16/src/smtp/smtp_connect.c 2005-01-07 18:25:30.202330704 +0100 | |
23bbf6c1 JB |
1005 | @@ -81,6 +81,7 @@ |
1006 | /* System library. */ | |
1007 | ||
1008 | #include <sys_defs.h> | |
1009 | +#include <stdlib.h> | |
1010 | #include <sys/socket.h> | |
1011 | #include <netinet/in.h> | |
1012 | #include <arpa/inet.h> | |
1013 | @@ -110,6 +111,7 @@ | |
1014 | #include <inet_addr_list.h> | |
1015 | #include <iostuff.h> | |
1016 | #include <timed_connect.h> | |
1017 | +#include <get_port.h> | |
1018 | #include <stringops.h> | |
7e195e4d | 1019 | #include <host_port.h> |
0b72d562 | 1020 | #include <sane_connect.h> |
1021 | @@ -135,19 +137,45 @@ | |
23bbf6c1 JB |
1022 | VSTRING *why) |
1023 | { | |
1024 | char *myname = "smtp_connect_addr"; | |
1025 | - struct sockaddr_in sin; | |
1026 | - int sock; | |
1027 | +#ifdef INET6 | |
1028 | + struct sockaddr_storage ss; | |
1029 | +#else | |
1030 | + struct sockaddr ss; | |
1031 | +#endif | |
1032 | + struct sockaddr *sa; | |
1033 | + struct sockaddr_in *sin; | |
1034 | +#ifdef INET6 | |
1035 | + struct sockaddr_in6 *sin6; | |
1036 | +#endif | |
1037 | + SOCKADDR_SIZE salen; | |
1038 | +#ifdef INET6 | |
1039 | + char hbuf[NI_MAXHOST]; | |
1040 | +#else | |
1041 | + char hbuf[sizeof("255.255.255.255") + 1]; | |
1042 | +#endif | |
1043 | + int sock = -1; | |
1044 | INET_ADDR_LIST *addr_list; | |
1045 | int conn_stat; | |
1046 | int saved_errno; | |
1047 | VSTREAM *stream; | |
1048 | int ch; | |
1049 | - unsigned long inaddr; | |
1050 | + | |
1051 | + sa = (struct sockaddr *)&ss; | |
1052 | + sin = (struct sockaddr_in *)&ss; | |
1053 | +#ifdef INET6 | |
1054 | + sin6 = (struct sockaddr_in6 *)&ss; | |
1055 | +#endif | |
1056 | ||
1057 | /* | |
1058 | * Sanity checks. | |
1059 | */ | |
1060 | - if (addr->data_len > sizeof(sin.sin_addr)) { | |
1061 | +#ifdef INET6 | |
1062 | + if (((addr->type==T_A) && (addr->data_len > sizeof(sin->sin_addr))) || | |
1063 | + ((addr->type==T_AAAA) && (addr->data_len > sizeof(sin6->sin6_addr)))) | |
1064 | +#else | |
1065 | + if (addr->data_len > sizeof(sin->sin_addr)) | |
1066 | +#endif | |
1067 | + { | |
1068 | msg_warn("%s: skip address with length %d", myname, addr->data_len); | |
1069 | smtp_errno = SMTP_RETRY; | |
1070 | return (0); | |
0b72d562 | 1071 | @@ -156,17 +184,39 @@ |
23bbf6c1 JB |
1072 | /* |
1073 | * Initialize. | |
1074 | */ | |
1075 | - memset((char *) &sin, 0, sizeof(sin)); | |
1076 | - sin.sin_family = AF_INET; | |
1077 | - | |
1078 | - if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0) | |
1079 | - msg_fatal("%s: socket: %m", myname); | |
1080 | - | |
1081 | + switch (addr->type) { | |
1082 | +#ifdef INET6 | |
1083 | + case T_AAAA: | |
1084 | + memset(sin6, 0, sizeof(*sin6)); | |
1085 | + sin6->sin6_family = AF_INET6; | |
1086 | + salen = sizeof(*sin6); | |
1087 | + break; | |
1088 | +#endif | |
1089 | + default: /* T_A: */ | |
1090 | + memset(sin, 0, sizeof(*sin)); | |
1091 | + sin->sin_family = AF_INET; | |
1092 | + salen = sizeof(*sin); | |
1093 | + break; | |
1094 | + } | |
1095 | +#ifdef HAS_SA_LEN | |
1096 | + sa->sa_len = salen; | |
1097 | +#endif | |
1098 | + if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) | |
1099 | + msg_warn("%s: socket: %m", myname); | |
1100 | + | |
1101 | /* | |
1102 | * Allow the sysadmin to specify the source address, for example, as "-o | |
1103 | * smtp_bind_address=x.x.x.x" in the master.cf file. | |
1104 | */ | |
1105 | if (*var_smtp_bind_addr) { | |
1106 | +#ifndef INET6 | |
1107 | + struct sockaddr_in sin; | |
1108 | + | |
1109 | + memset(&sin, 0, sizeof(sin)); | |
1110 | + sin.sin_family = AF_INET; | |
1111 | +#ifdef HAS_SA_LEN | |
1112 | + sin.sin_len = sizeof(sin); | |
1113 | +#endif | |
1114 | sin.sin_addr.s_addr = inet_addr(var_smtp_bind_addr); | |
1115 | if (sin.sin_addr.s_addr == INADDR_NONE) | |
1116 | msg_fatal("%s: bad %s parameter: %s", | |
0b72d562 | 1117 | @@ -175,6 +225,25 @@ |
23bbf6c1 JB |
1118 | msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr)); |
1119 | if (msg_verbose) | |
1120 | msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr)); | |
1121 | +#else | |
1122 | + char hbufl[NI_MAXHOST]; | |
1123 | + struct addrinfo hints, *res; | |
1124 | + | |
1125 | + memset(&hints, 0, sizeof(hints)); | |
1126 | + hints.ai_family = sa->sa_family; | |
1127 | + hints.ai_socktype = SOCK_STREAM; | |
1128 | + hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST; | |
1129 | + snprintf(hbufl, sizeof(hbufl)-1, "%s", var_smtp_bind_addr); | |
1130 | + if (getaddrinfo(hbufl, NULL, &hints, &res) == 0) { | |
1131 | + (void)getnameinfo(res->ai_addr, res->ai_addrlen, hbufl, | |
1132 | + sizeof(hbufl), NULL, 0, NI_NUMERICHOST); | |
1133 | + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) | |
1134 | + msg_warn("%s: bind %s: %m", myname, hbufl); | |
1135 | + freeaddrinfo(res); | |
1136 | + if (msg_verbose) | |
1137 | + msg_info("%s: bind %s", myname, hbufl); | |
1138 | + } | |
1139 | +#endif | |
1140 | } | |
1141 | ||
1142 | /* | |
0b72d562 | 1143 | @@ -182,8 +251,17 @@ |
23bbf6c1 JB |
1144 | * the mail appears to come from the "right" machine address. |
1145 | */ | |
1146 | else if ((addr_list = own_inet_addr_list())->used == 1) { | |
1147 | +#ifndef INET6 | |
1148 | + struct sockaddr_in sin; | |
1149 | + unsigned long inaddr; /*XXX BAD!*/ | |
1150 | + | |
1151 | + memset(&sin, 0, sizeof(sin)); | |
1152 | + sin.sin_family = AF_INET; | |
1153 | +#ifdef HAS_SA_LEN | |
1154 | + sin.sin_len = sizeof(sin); | |
1155 | +#endif | |
1156 | memcpy((char *) &sin.sin_addr, addr_list->addrs, sizeof(sin.sin_addr)); | |
1157 | - inaddr = ntohl(sin.sin_addr.s_addr); | |
1158 | + inaddr = (unsigned long)ntohl(sin.sin_addr.s_addr); | |
1159 | if (!IN_CLASSA(inaddr) | |
1160 | || !(((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)) { | |
1161 | if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0) | |
0b72d562 | 1162 | @@ -191,30 +269,85 @@ |
23bbf6c1 JB |
1163 | if (msg_verbose) |
1164 | msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr)); | |
1165 | } | |
1166 | +#else | |
1167 | + char hbufl[NI_MAXHOST]; | |
1168 | + struct addrinfo hints, *res = NULL, *loopback = NULL; | |
1169 | + | |
1170 | + memset(&hints, 0, sizeof(hints)); | |
1171 | + hints.ai_family = sa->sa_family; | |
1172 | + hints.ai_socktype = SOCK_STREAM; | |
1173 | + if (getaddrinfo(NULL, "0", &hints, &loopback) != 0) | |
1174 | + loopback = NULL; | |
1175 | + | |
1176 | + /* | |
1177 | + * getnameinfo -> getaddrinfo loop is here so that we can | |
1178 | + * get rid of port. | |
1179 | + */ | |
1180 | + (void)getnameinfo((struct sockaddr *)addr_list->addrs, SA_LEN((struct sockaddr *)addr_list->addrs), | |
1181 | + hbufl, sizeof(hbufl), NULL, 0, NI_NUMERICHOST); | |
1182 | + hbufl[sizeof(hbufl)-1] = 0; | |
1183 | + memset(&hints, 0, sizeof(hints)); | |
1184 | + hints.ai_family = sa->sa_family; | |
1185 | + hints.ai_socktype = SOCK_STREAM; | |
1186 | + hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST; | |
1187 | + if (getaddrinfo(hbufl, NULL, &hints, &res) == 0 && | |
1188 | + !(res->ai_addrlen == loopback->ai_addrlen && | |
1189 | + memcmp(res->ai_addr, loopback->ai_addr, res->ai_addrlen) == 0)) { | |
1190 | + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) | |
0b72d562 | 1191 | + msg_warn("%s: bind %s: %m", myname, hbufl); |
23bbf6c1 | 1192 | + if (msg_verbose) |
0b72d562 | 1193 | + msg_info("%s: bind %s", myname, hbufl); |
23bbf6c1 JB |
1194 | + } |
1195 | + if (res) | |
1196 | + freeaddrinfo(res); | |
1197 | + if (loopback) | |
1198 | + freeaddrinfo(loopback); | |
1199 | +#endif | |
1200 | } | |
1201 | ||
1202 | /* | |
1203 | * Connect to the SMTP server. | |
1204 | */ | |
1205 | - sin.sin_port = port; | |
1206 | - memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr)); | |
1207 | + switch (addr->type) { | |
1208 | +#ifdef INET6 | |
1209 | + case T_AAAA: | |
0b72d562 | 1210 | + /* XXX scope unfriendly */ |
1211 | + memset(sin6, 0, sizeof(*sin6)); | |
1212 | + sin6->sin6_port = port; | |
1213 | + sin6->sin6_family = AF_INET6; | |
1214 | + salen = sizeof(*sin6); | |
1215 | + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr)); | |
1216 | + inet_ntop(AF_INET6, &sin6->sin6_addr, hbuf, sizeof(hbuf)); | |
1217 | + break; | |
23bbf6c1 JB |
1218 | +#endif |
1219 | + default: /* T_A */ | |
0b72d562 | 1220 | + memset(sin, 0, sizeof(*sin)); |
1221 | + sin->sin_port = port; | |
1222 | + sin->sin_family = AF_INET; | |
1223 | + salen = sizeof(*sin); | |
1224 | + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr)); | |
1225 | + inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf)); | |
1226 | + break; | |
23bbf6c1 JB |
1227 | + } |
1228 | +#ifdef HAS_SA_LEN | |
1229 | + sa->sa_len = salen; | |
1230 | +#endif | |
1231 | ||
1232 | if (msg_verbose) | |
1233 | msg_info("%s: trying: %s[%s] port %d...", | |
1234 | - myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port)); | |
1235 | + myname, addr->name, hbuf, ntohs(port)); | |
1236 | if (var_smtp_conn_tmout > 0) { | |
1237 | non_blocking(sock, NON_BLOCKING); | |
1238 | - conn_stat = timed_connect(sock, (struct sockaddr *) & sin, | |
1239 | - sizeof(sin), var_smtp_conn_tmout); | |
1240 | + conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout); | |
1241 | saved_errno = errno; | |
1242 | non_blocking(sock, BLOCKING); | |
1243 | errno = saved_errno; | |
1244 | } else { | |
0b72d562 | 1245 | - conn_stat = sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin)); |
23bbf6c1 JB |
1246 | + conn_stat = connect(sock, sa, salen); |
1247 | } | |
1248 | if (conn_stat < 0) { | |
1249 | vstring_sprintf(why, "connect to %s[%s]: %m", | |
1250 | - addr->name, inet_ntoa(sin.sin_addr)); | |
1251 | + addr->name, hbuf); | |
1252 | smtp_errno = SMTP_RETRY; | |
1253 | close(sock); | |
1254 | return (0); | |
0b72d562 | 1255 | @@ -224,8 +357,8 @@ |
23bbf6c1 JB |
1256 | * Skip this host if it takes no action within some time limit. |
1257 | */ | |
1258 | if (read_wait(sock, var_smtp_helo_tmout) < 0) { | |
1259 | - vstring_sprintf(why, "connect to %s[%s]: read timeout", | |
1260 | - addr->name, inet_ntoa(sin.sin_addr)); | |
1261 | + vstring_sprintf(why, "connect to %s [%s]: read timeout", | |
1262 | + addr->name, hbuf); | |
1263 | smtp_errno = SMTP_RETRY; | |
1264 | close(sock); | |
1265 | return (0); | |
0b72d562 | 1266 | @@ -237,7 +370,7 @@ |
368b25b6 TO |
1267 | stream = vstream_fdopen(sock, O_RDWR); |
1268 | if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) { | |
1269 | vstring_sprintf(why, "connect to %s[%s]: server dropped connection without sending the initial greeting", | |
1270 | - addr->name, inet_ntoa(sin.sin_addr)); | |
1271 | + addr->name, hbuf); | |
1272 | smtp_errno = SMTP_RETRY; | |
1273 | vstream_fclose(stream); | |
1274 | return (0); | |
0b72d562 | 1275 | @@ -249,7 +382,7 @@ |
368b25b6 TO |
1276 | */ |
1277 | if (ch == '4' && var_smtp_skip_4xx_greeting) { | |
1278 | vstring_sprintf(why, "connect to %s[%s]: server refused mail service", | |
1279 | - addr->name, inet_ntoa(sin.sin_addr)); | |
1280 | + addr->name, hbuf); | |
1281 | smtp_errno = SMTP_RETRY; | |
1282 | vstream_fclose(stream); | |
1283 | return (0); | |
0b72d562 | 1284 | @@ -260,12 +393,12 @@ |
368b25b6 TO |
1285 | */ |
1286 | if (ch == '5' && var_smtp_skip_5xx_greeting) { | |
1287 | vstring_sprintf(why, "connect to %s[%s]: server refused mail service", | |
1288 | - addr->name, inet_ntoa(sin.sin_addr)); | |
1289 | + addr->name, hbuf); | |
1290 | smtp_errno = SMTP_RETRY; | |
1291 | vstream_fclose(stream); | |
1292 | return (0); | |
1293 | } | |
1294 | - return (smtp_session_alloc(dest, stream, addr->name, inet_ntoa(sin.sin_addr))); | |
1295 | + return (smtp_session_alloc(dest, stream, addr->name, hbuf)); | |
1296 | } | |
1297 | ||
1298 | /* smtp_connect_host - direct connection to host */ | |
9e602738 | 1299 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtp/smtp_unalias.c postfix-2.0.16/src/smtp/smtp_unalias.c |
0b72d562 | 1300 | --- postfix-2.0.16.orig/src/smtp/smtp_unalias.c 2000-09-28 19:06:09.000000000 +0200 |
9e602738 | 1301 | +++ postfix-2.0.16/src/smtp/smtp_unalias.c 2005-01-07 18:25:30.202330704 +0100 |
23bbf6c1 JB |
1302 | @@ -86,7 +86,11 @@ |
1303 | if ((result = htable_find(cache, name)) == 0) { | |
1304 | fqdn = vstring_alloc(10); | |
1305 | if (dns_lookup_types(name, smtp_unalias_flags, (DNS_RR **) 0, | |
1306 | - fqdn, (VSTRING *) 0, T_MX, T_A, 0) != DNS_OK) | |
1307 | + fqdn, (VSTRING *) 0, T_MX, T_A, | |
1308 | +#ifdef INET6 | |
1309 | + T_AAAA, | |
1310 | +#endif | |
1311 | + 0) != DNS_OK) | |
1312 | vstring_strcpy(fqdn, name); | |
1313 | htable_enter(cache, name, result = vstring_export(fqdn)); | |
1314 | } | |
9e602738 JK |
1315 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtpd/smtpd_check.c postfix-2.0.16/src/smtpd/smtpd_check.c |
1316 | --- postfix-2.0.16.orig/src/smtpd/smtpd_check.c 2005-01-07 18:22:25.302439760 +0100 | |
1317 | +++ postfix-2.0.16/src/smtpd/smtpd_check.c 2005-01-07 18:25:30.218328272 +0100 | |
1318 | @@ -1393,6 +1393,49 @@ | |
1ce4542c TO |
1319 | static int has_my_addr(SMTPD_STATE *state, const char *host, |
1320 | const char *reply_name, const char *reply_class) | |
23bbf6c1 JB |
1321 | { |
1322 | +#ifdef INET6 | |
1323 | + char *myname = "has_my_addr"; | |
1324 | + struct addrinfo hints, *res, *res0; | |
1325 | + int error; | |
1326 | + char hbuf[NI_MAXHOST]; | |
1327 | + | |
1328 | + if (msg_verbose) | |
1329 | + msg_info("%s: host %s", myname, host); | |
1330 | + | |
1331 | + /* | |
1332 | + * If we can't lookup the host, play safe and assume it is OK. | |
1333 | + */ | |
1334 | +#define YUP 1 | |
1335 | +#define NOPE 0 | |
1336 | + | |
1337 | + memset(&hints, 0, sizeof(hints)); | |
1338 | + hints.ai_family = PF_UNSPEC; | |
1339 | + hints.ai_socktype = SOCK_DGRAM; | |
1340 | + error = getaddrinfo(host, NULL, &hints, &res0); | |
1341 | + if (error) { | |
1342 | + if (msg_verbose) | |
1343 | + msg_info("%s: host %s: %s", myname, host, gai_strerror(error)); | |
1344 | + return (YUP); | |
1345 | + } | |
1346 | + for (res = res0; res; res = res->ai_next) { | |
1347 | + if (msg_verbose) { | |
1348 | + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), | |
1349 | + NULL, 0, NI_NUMERICHOST)) { | |
1350 | + strncpy(hbuf, "???", sizeof(hbuf)); | |
1351 | + } | |
1352 | + msg_info("%s: addr %s", myname, hbuf); | |
1353 | + } | |
1354 | + if (own_inet_addr(res->ai_addr)) { | |
1355 | + freeaddrinfo(res0); | |
1356 | + return (YUP); | |
1357 | + } | |
1358 | + } | |
1359 | + freeaddrinfo(res0); | |
1360 | + if (msg_verbose) | |
1361 | + msg_info("%s: host %s: no match", myname, host); | |
1362 | + | |
1363 | + return (NOPE); | |
1364 | +#else | |
1365 | char *myname = "has_my_addr"; | |
1366 | struct in_addr addr; | |
1367 | char **cpp; | |
9e602738 | 1368 | @@ -1431,6 +1474,7 @@ |
23bbf6c1 JB |
1369 | msg_info("%s: host %s: no match", myname, host); |
1370 | ||
1371 | return (NOPE); | |
1372 | +#endif | |
1373 | } | |
1374 | ||
35140025 | 1375 | /* i_am_mx - is this machine listed as MX relay */ |
9e602738 | 1376 | @@ -2015,11 +2059,28 @@ |
a4192b77 JB |
1377 | #define CHK_ADDR_RETURN(x,y) { *found = y; return(x); } |
1378 | ||
1379 | addr = STR(vstring_strcpy(error_text, address)); | |
1380 | - | |
1381 | +#ifdef INET6 | |
1382 | + if (strncmp(addr, "::ffff:", 7) == 0 && msg_verbose) | |
1383 | + msg_info("%s: %s v6 addr in v4 compat-mode, " | |
1384 | + "converted to v4 for map checking compatibility (%s)", \ | |
1385 | + myname, addr, addr+7); | |
1386 | +#endif | |
1387 | + | |
1388 | if ((dict = dict_handle(table)) == 0) | |
1389 | msg_panic("%s: dictionary not found: %s", myname, table); | |
1390 | do { | |
1391 | if (flags == 0 || (flags & dict->flags) != 0) { | |
1392 | +#ifdef INET6 | |
1393 | + if (strncmp(addr, "::ffff:", 7) == 0) { | |
1394 | + /* try if ::ffff: formati is present in map, if not, try | |
1395 | + traditional IPv4 format striping :ffff: part */ | |
1396 | + if ((value = dict_get(dict, addr)) != 0 || \ | |
1397 | + (value = dict_get(dict, addr+7)) != 0) | |
1398 | + CHK_ADDR_RETURN(check_table_result(state, table, value, address, | |
1399 | + reply_name, reply_class, | |
1400 | + def_acl), FOUND); | |
1401 | + } else | |
1402 | +#endif | |
1403 | if ((value = dict_get(dict, addr)) != 0) | |
1404 | CHK_ADDR_RETURN(check_table_result(state, table, value, address, | |
1405 | reply_name, reply_class, | |
9e602738 | 1406 | @@ -2579,16 +2640,32 @@ |
c6bc5048 TO |
1407 | VSTRING *query; |
1408 | int i; | |
1409 | SMTPD_RBL_STATE *rbl; | |
1410 | +#ifdef INET6 | |
1411 | + struct in_addr a; | |
1412 | +#else | |
1413 | + struct in6_addr a; | |
1414 | +#endif | |
1415 | ||
23bbf6c1 | 1416 | if (msg_verbose) |
7e195e4d | 1417 | msg_info("%s: %s %s", myname, reply_class, addr); |
e38d57a7 | 1418 | |
da71bd09 JB |
1419 | - /* |
1420 | - * IPv4 only for now | |
1421 | - */ | |
1422 | -#ifdef INET6 | |
1423 | +#ifndef INET6 | |
23bbf6c1 | 1424 | + /* IPv4 only for now */ |
7e195e4d | 1425 | if (inet_pton(AF_INET, addr, &a) != 1) |
da71bd09 JB |
1426 | return SMTPD_CHECK_DUNNO; |
1427 | + octets = argv_split(state->addr, "."); | |
1428 | +#else | |
1429 | + /* IPv4 and IPv6-mapped IPv4 only for now */ | |
1430 | + if (inet_pton(AF_INET, state->addr, &a) == 1) | |
7e195e4d | 1431 | + octets = argv_split(state->addr, "."); |
da71bd09 | 1432 | + else { |
7e195e4d TO |
1433 | + struct in6_addr a6; |
1434 | + if (inet_pton(AF_INET6, state->addr, &a6) != 1) | |
da71bd09 | 1435 | + return SMTPD_CHECK_DUNNO; |
7e195e4d | 1436 | + if (!IN6_IS_ADDR_V4MAPPED(&a6) || (strrchr(state->addr,':') == NULL)) |
da71bd09 | 1437 | + return SMTPD_CHECK_DUNNO; |
7e195e4d | 1438 | + octets = argv_split(strrchr(state->addr,':')+1, "."); |
da71bd09 JB |
1439 | + } |
1440 | #endif | |
1441 | ||
23bbf6c1 | 1442 | /* |
9e602738 | 1443 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtpd/smtpd_peer.c postfix-2.0.16/src/smtpd/smtpd_peer.c |
0b72d562 | 1444 | --- postfix-2.0.16.orig/src/smtpd/smtpd_peer.c 2002-08-22 19:50:51.000000000 +0200 |
9e602738 | 1445 | +++ postfix-2.0.16/src/smtpd/smtpd_peer.c 2005-01-07 18:25:30.205330248 +0100 |
23bbf6c1 JB |
1446 | @@ -63,6 +63,15 @@ |
1447 | #include <netdb.h> | |
1448 | #include <string.h> | |
1449 | ||
1450 | +/* Utility library. */ | |
1451 | + | |
1452 | +#include <msg.h> | |
1453 | +#include <mymalloc.h> | |
1454 | +#include <valid_hostname.h> | |
1455 | +#include <stringops.h> | |
1456 | + | |
1457 | +/* Global library. */ | |
1458 | + | |
1459 | /* | |
1460 | * Older systems don't have h_errno. Even modern systems don't have | |
1461 | * hstrerror(). | |
1462 | @@ -84,16 +93,11 @@ | |
1463 | ) | |
1464 | #endif | |
1465 | ||
1466 | -/* Utility library. */ | |
1467 | - | |
1468 | -#include <msg.h> | |
1469 | -#include <mymalloc.h> | |
1470 | -#include <valid_hostname.h> | |
1471 | -#include <stringops.h> | |
1472 | - | |
1473 | -/* Global library. */ | |
1474 | - | |
1475 | - | |
1476 | +#ifdef INET6 | |
1477 | +#define GAI_STRERROR(error) \ | |
1478 | + ((error = EAI_SYSTEM) ? gai_strerror(error) : strerror(errno)) | |
1479 | +#endif | |
1480 | + | |
1481 | /* Application-specific. */ | |
1482 | ||
1483 | #include "smtpd.h" | |
c6bc5048 | 1484 | @@ -102,21 +106,28 @@ |
23bbf6c1 JB |
1485 | |
1486 | void smtpd_peer_init(SMTPD_STATE *state) | |
1487 | { | |
1488 | - struct sockaddr_in sin; | |
1489 | - SOCKADDR_SIZE len = sizeof(sin); | |
1490 | +#ifdef INET6 | |
1491 | + struct sockaddr_storage ss; | |
1492 | +#else | |
1493 | + struct sockaddr ss; | |
1494 | + struct in_addr *in; | |
1495 | struct hostent *hp; | |
1496 | - int i; | |
1497 | +#endif | |
1498 | + struct sockaddr *sa; | |
1499 | + SOCKADDR_SIZE len; | |
1500 | + | |
1501 | + sa = (struct sockaddr *)&ss; | |
1502 | + len = sizeof(ss); | |
1503 | ||
7e195e4d TO |
1504 | /* |
1505 | * Avoid suprious complaints from Purify on Solaris. | |
c6bc5048 TO |
1506 | */ |
1507 | - memset((char *) &sin, 0, len); | |
b733fb75 | 1508 | + memset((char *) sa, 0, len); |
c6bc5048 | 1509 | |
23bbf6c1 JB |
1510 | /* |
1511 | * Look up the peer address information. | |
1512 | */ | |
1513 | - if (getpeername(vstream_fileno(state->client), | |
1514 | - (struct sockaddr *) & sin, &len) >= 0) { | |
1515 | + if (getpeername(vstream_fileno(state->client), sa, &len) >= 0) { | |
1516 | errno = 0; | |
1517 | } | |
1518 | ||
7e195e4d | 1519 | @@ -132,23 +143,56 @@ |
23bbf6c1 JB |
1520 | /* |
1521 | * Look up and "verify" the client hostname. | |
1522 | */ | |
1523 | - else if (errno == 0 && sin.sin_family == AF_INET) { | |
1524 | - state->addr = mystrdup(inet_ntoa(sin.sin_addr)); | |
1525 | - hp = gethostbyaddr((char *) &(sin.sin_addr), | |
1526 | - sizeof(sin.sin_addr), AF_INET); | |
1527 | - if (hp == 0) { | |
1528 | + else if (errno == 0 && (sa->sa_family == AF_INET | |
1529 | +#ifdef INET6 | |
1530 | + || sa->sa_family == AF_INET6 | |
1531 | +#endif | |
1532 | + )) { | |
1533 | +#ifdef INET6 | |
1534 | + char hbuf[NI_MAXHOST]; | |
1535 | + char abuf[NI_MAXHOST]; | |
1536 | + struct addrinfo hints, *rnull = NULL; | |
1537 | +#else | |
1538 | + char abuf[sizeof("255.255.255.255") + 1]; | |
1539 | + char *hbuf; | |
1540 | +#endif | |
1541 | + int error = -1; | |
1542 | + | |
1543 | +#ifdef INET6 | |
1544 | + (void)getnameinfo(sa, len, abuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST); | |
1545 | +#else | |
1546 | + in = &((struct sockaddr_in *)sa)->sin_addr; | |
1547 | + inet_ntop(AF_INET, in, abuf, sizeof(hbuf)); | |
1548 | +#endif | |
1549 | + state->addr = mystrdup(abuf); | |
1550 | +#ifdef INET6 | |
1551 | + error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD); | |
1552 | +#else | |
1553 | + hbuf = NULL; | |
1554 | + hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET); | |
1555 | + if (hp) { | |
1556 | + error = 0; | |
1557 | + hbuf = mystrdup(hp->h_name); | |
1558 | + } else | |
1559 | + error = 1; | |
1560 | +#endif | |
1561 | + if (error) { | |
1562 | state->name = mystrdup("unknown"); | |
1563 | +#ifdef INET6 | |
1564 | + state->peer_code = (error == EAI_AGAIN ? 4 : 5); | |
1565 | +#else | |
1566 | state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5); | |
7e195e4d | 1567 | - } else if (valid_hostaddr(hp->h_name, DONT_GRIPE)) { |
23bbf6c1 | 1568 | +#endif |
7e195e4d TO |
1569 | + } else if (valid_hostaddr(hbuf, DONT_GRIPE)) { |
1570 | msg_warn("numeric result %s in address->name lookup for %s", | |
1571 | - hp->h_name, state->addr); | |
c6bc5048 | 1572 | + hbuf, state->addr); |
7e195e4d TO |
1573 | state->name = mystrdup("unknown"); |
1574 | state->peer_code = 5; | |
1575 | - } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) { | |
23bbf6c1 JB |
1576 | + } else if (!valid_hostname(hbuf, DONT_GRIPE)) { |
1577 | state->name = mystrdup("unknown"); | |
1578 | state->peer_code = 5; | |
1579 | } else { | |
1580 | - state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */ | |
c6bc5048 | 1581 | + state->name = mystrdup(hbuf); /* hp->name is clobbered!! */ |
23bbf6c1 JB |
1582 | state->peer_code = 2; |
1583 | ||
1584 | /* | |
1ce4542c | 1585 | @@ -160,16 +204,31 @@ |
23bbf6c1 JB |
1586 | state->peer_code = code; \ |
1587 | } | |
1588 | ||
1589 | +#ifdef INET6 | |
1590 | + memset(&hints, 0, sizeof(hints)); | |
1591 | + hints.ai_family = AF_UNSPEC; | |
1592 | + hints.ai_socktype = SOCK_STREAM; | |
1593 | + error = getaddrinfo(state->name, NULL, &hints, &rnull); | |
1594 | + if (error) { | |
1595 | + msg_warn("%s: hostname %s verification failed: %s", | |
1596 | + state->addr, state->name, GAI_STRERROR(error)); | |
1597 | + REJECT_PEER_NAME(state, (error == EAI_AGAIN ? 4 : 5)); | |
1598 | + } | |
1599 | + /* memcmp() isn't needed if we use getaddrinfo */ | |
1600 | + if (rnull) | |
1601 | + freeaddrinfo(rnull); | |
1602 | +#else | |
1603 | hp = gethostbyname(state->name); /* clobbers hp->name!! */ | |
1604 | if (hp == 0) { | |
1605 | msg_warn("%s: hostname %s verification failed: %s", | |
1606 | state->addr, state->name, HSTRERROR(h_errno)); | |
1607 | REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ? 4 : 5)); | |
1608 | - } else if (hp->h_length != sizeof(sin.sin_addr)) { | |
1609 | + } else if (hp->h_length != sizeof(*in)) { | |
1610 | msg_warn("%s: hostname %s verification failed: bad address size %d", | |
1611 | state->addr, state->name, hp->h_length); | |
1612 | REJECT_PEER_NAME(state, 5); | |
1613 | } else { | |
1614 | + int i; | |
1615 | for (i = 0; /* void */ ; i++) { | |
1616 | if (hp->h_addr_list[i] == 0) { | |
1617 | msg_warn("%s: address not listed for hostname %s", | |
1ce4542c | 1618 | @@ -177,12 +236,11 @@ |
23bbf6c1 JB |
1619 | REJECT_PEER_NAME(state, 5); |
1620 | break; | |
1621 | } | |
1622 | - if (memcmp(hp->h_addr_list[i], | |
1623 | - (char *) &sin.sin_addr, | |
1624 | - sizeof(sin.sin_addr)) == 0) | |
1625 | + if (memcmp(hp->h_addr_list[i], (char *)in, sizeof(*in)) == 0) | |
1626 | break; /* keep peer name */ | |
1627 | } | |
1628 | } | |
1629 | +#endif | |
1630 | } | |
1631 | } | |
1632 | ||
9e602738 | 1633 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/smtpstone/smtp-sink.c postfix-2.0.16/src/smtpstone/smtp-sink.c |
0b72d562 | 1634 | --- postfix-2.0.16.orig/src/smtpstone/smtp-sink.c 2003-09-13 02:46:56.000000000 +0200 |
9e602738 | 1635 | +++ postfix-2.0.16/src/smtpstone/smtp-sink.c 2005-01-07 18:25:30.205330248 +0100 |
0b72d562 | 1636 | @@ -607,7 +607,7 @@ |
e38d57a7 JB |
1637 | } else { |
1638 | if (strncmp(argv[optind], "inet:", 5) == 0) | |
1639 | argv[optind] += 5; | |
1640 | - sock = inet_listen(argv[optind], backlog, BLOCKING); | |
1641 | + sock = inet_listen(argv[optind], backlog, BLOCKING, 1); | |
1642 | } | |
1643 | ||
23bbf6c1 | 1644 | /* |
9e602738 JK |
1645 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/Makefile.in postfix-2.0.16/src/util/Makefile.in |
1646 | --- postfix-2.0.16.orig/src/util/Makefile.in 2005-01-07 18:22:25.293441128 +0100 | |
1647 | +++ postfix-2.0.16/src/util/Makefile.in 2005-01-07 18:25:30.209329640 +0100 | |
1648 | @@ -8,7 +8,7 @@ | |
1649 | dict_tcp.c dict_unix.c dir_forest.c doze.c duplex_pipe.c \ | |
1650 | environ.c events.c exec_command.c fifo_listen.c fifo_trigger.c \ | |
1651 | file_limit.c find_inet.c fsspace.c fullname.c get_domainname.c \ | |
1652 | - get_hostname.c hex_quote.c htable.c inet_addr_host.c \ | |
1653 | + get_hostname.c get_port.c hex_quote.c htable.c inet_addr_host.c \ | |
1654 | inet_addr_list.c inet_addr_local.c inet_connect.c inet_listen.c \ | |
1655 | inet_trigger.c inet_util.c intv.c line_wrap.c lowercase.c \ | |
1656 | lstat_as.c mac_expand.c mac_parse.c make_dirs.c match_list.c \ | |
1657 | @@ -37,7 +37,7 @@ | |
1658 | dict_tcp.o dict_unix.o dir_forest.o doze.o duplex_pipe.o \ | |
1659 | environ.o events.o exec_command.o fifo_listen.o fifo_trigger.o \ | |
1660 | file_limit.o find_inet.o fsspace.o fullname.o get_domainname.o \ | |
1661 | - get_hostname.o hex_quote.o htable.o inet_addr_host.o \ | |
1662 | + get_hostname.o get_port.o hex_quote.o htable.o inet_addr_host.o \ | |
1663 | inet_addr_list.o inet_addr_local.o inet_connect.o inet_listen.o \ | |
1664 | inet_trigger.o inet_util.o intv.o line_wrap.o lowercase.o \ | |
1665 | lstat_as.o mac_expand.o mac_parse.o make_dirs.o match_list.o \ | |
1666 | @@ -62,7 +62,7 @@ | |
1667 | dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \ | |
1668 | dict_nisplus.h dict_pcre.h dict_pgsql.h dict_regexp.h dict_static.h dict_tcp.h \ | |
1669 | dict_unix.h dir_forest.h events.h exec_command.h find_inet.h \ | |
1670 | - fsspace.h fullname.h get_domainname.h get_hostname.h hex_quote.h \ | |
1671 | + fsspace.h fullname.h get_domainname.h get_hostname.h get_port.h hex_quote.h \ | |
1672 | htable.h inet_addr_host.h inet_addr_list.h inet_addr_local.h \ | |
1673 | inet_util.h intv.h iostuff.h line_wrap.h listen.h lstat_as.h \ | |
1674 | mac_expand.h mac_parse.h make_dirs.h match_list.h match_ops.h \ | |
1675 | @@ -785,6 +785,7 @@ | |
1676 | get_domainname.o: mymalloc.h | |
1677 | get_domainname.o: get_hostname.h | |
1678 | get_domainname.o: get_domainname.h | |
1679 | +get_port.o: sys_defs.h | |
1680 | get_hostname.o: get_hostname.c | |
1681 | get_hostname.o: sys_defs.h | |
1682 | get_hostname.o: mymalloc.h | |
1683 | @@ -911,6 +912,7 @@ | |
1684 | match_list.o: stringops.h | |
1685 | match_list.o: argv.h | |
1686 | match_list.o: dict.h | |
1687 | +match_list.o: inet_util.h | |
1688 | match_list.o: match_ops.h | |
1689 | match_list.o: match_list.h | |
1690 | match_ops.o: match_ops.c | |
1691 | diff -durN -x '*~' -x '*.orig' postfix-2.0.16.orig/src/util/get_port.c postfix-2.0.16/src/util/get_port.c | |
0b72d562 | 1692 | --- postfix-2.0.16.orig/src/util/get_port.c 1970-01-01 01:00:00.000000000 +0100 |
9e602738 | 1693 | +++ postfix-2.0.16/src/util/get_port.c 2005-01-07 18:25:30.206330096 +0100 |
23bbf6c1 JB |
1694 | @@ -0,0 +1,65 @@ |
1695 | +/*++ | |
1696 | +/* NAME | |
1697 | +/* get_port 3 | |
1698 | +/* SUMMARY | |
1699 | +/* trivial host and port extracter | |
1700 | +/* SYNOPSIS | |
1701 | +/* #include <get_port.h> | |
1702 | +/* | |
1703 | +/* char *get_port(data) | |
1704 | +/* char *data; | |
1705 | +/* | |
1706 | +/* DESCRIPTION | |
1707 | +/* get_port() extract host name or ip address from | |
1708 | +/* strings such as [3ffe:902:12::10]:25, [::1] | |
1709 | +/* or 192.168.0.1:25, and null-terminates the | |
1710 | +/* \fIdata\fR at the first occurrence of port separator. | |
1711 | +/* DIAGNOSTICS | |
1712 | +/* If port not found return null pointer. | |
1713 | +/* LICENSE | |
1714 | +/* .ad | |
1715 | +/* .fi | |
1716 | +/* BSD Style (or BSD like) license. | |
1717 | +/* AUTHOR(S) | |
1718 |