Postfix3.3.1
全て データ構造 ファイル 関数 変数 型定義 マクロ定義
smtp_unalias.c
[詳解]
1 /*++
2 /* NAME
3 /* smtp_unalias 3
4 /* SUMMARY
5 /* replace host/domain alias by official name
6 /* SYNOPSIS
7 /* #include "smtp.h"
8 /*
9 /* const char *smtp_unalias_name(name)
10 /* const char *name;
11 /*
12 /* VSTRING *smtp_unalias_addr(result, addr)
13 /* VSTRING *result;
14 /* const char *addr;
15 /* DESCRIPTION
16 /* smtp_unalias_name() looks up A or MX records for the specified
17 /* name and returns the official name provided in the reply. When
18 /* no A or MX record is found, the result is a copy of the input.
19 /* In order to improve performance, smtp_unalias_name() remembers
20 /* results in a private cache, so a name is looked up only once.
21 /*
22 /* smtp_unalias_addr() returns the input address, which is in
23 /* RFC 821 quoted form, after replacing the domain part by the
24 /* official name as found by smtp_unalias_name(). When the input
25 /* contains no domain part, the result is a copy of the input.
26 /* LICENSE
27 /* .ad
28 /* .fi
29 /* The Secure Mailer license must be distributed with this software.
30 /* AUTHOR(S)
31 /* Wietse Venema
32 /* IBM T.J. Watson Research
33 /* P.O. Box 704
34 /* Yorktown Heights, NY 10598, USA
35 /*--*/
36 
37 /* System library. */
38 
39 #include <sys_defs.h>
40 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #include <arpa/inet.h>
43 #include <stdlib.h>
44 #include <netdb.h>
45 #include <string.h>
46 
47 /* Utility library. */
48 
49 #include <htable.h>
50 #include <vstring.h>
51 #include <msg.h>
52 
53 /* DNS library. */
54 
55 #include <dns.h>
56 
57 /* Application-specific. */
58 
59 #include "smtp.h"
60 
61 static int smtp_unalias_flags;
62 
63 /* smtp_unalias_name - look up the official host or domain name. */
64 
65 const char *smtp_unalias_name(const char *name)
66 {
67  static HTABLE *cache;
68  VSTRING *fqdn;
69  char *result;
70 
71  if (*name == '[')
72  return (name);
73 
74  /*
75  * Initialize the cache on the fly. The smtp client is designed to exit
76  * after servicing a limited number of requests, so there is no need to
77  * prevent the cache from growing too large, or to expire old entries.
78  */
79  if (cache == 0)
80  cache = htable_create(10);
81 
82  /*
83  * Look up the fqdn. If none is found use the query name instead, so that
84  * we won't lose time looking up the same bad name again.
85  */
86  if ((result = htable_find(cache, name)) == 0) {
87  fqdn = vstring_alloc(10);
88  if (dns_lookup_l(name, smtp_unalias_flags, (DNS_RR **) 0, fqdn,
89  (VSTRING *) 0, DNS_REQ_FLAG_NONE, T_MX, T_A,
90 #ifdef HAS_IPV6
91  T_AAAA,
92 #endif
93  0) != DNS_OK)
94  vstring_strcpy(fqdn, name);
95  htable_enter(cache, name, result = vstring_export(fqdn));
96  }
97  return (result);
98 }
99 
100 /* smtp_unalias_addr - rewrite aliases in domain part of address */
101 
102 VSTRING *smtp_unalias_addr(VSTRING *result, const char *addr)
103 {
104  char *at;
105  const char *fqdn;
106 
107  if ((at = strrchr(addr, '@')) == 0 || at[1] == 0) {
108  vstring_strcpy(result, addr);
109  } else {
110  fqdn = smtp_unalias_name(at + 1);
111  vstring_strncpy(result, addr, at - addr + 1);
112  vstring_strcat(result, fqdn);
113  }
114  return (result);
115 }
116 
117 #ifdef TEST
118 
119  /*
120  * Test program - read address from stdin, print result on stdout.
121  */
122 
123 #include <vstring_vstream.h>
124 
125 int main(int unused_argc, char **unused_argv)
126 {
127  VSTRING *addr = vstring_alloc(10);
128  VSTRING *result = vstring_alloc(10);
129 
130  smtp_unalias_flags |= RES_DEBUG;
131 
132  while (vstring_fgets_nonl(addr, VSTREAM_IN)) {
133  smtp_unalias_addr(result, vstring_str(addr));
134  vstream_printf("%s -> %s\n", vstring_str(addr), vstring_str(result));
136  }
137  vstring_free(addr);
138  vstring_free(result);
139  return (0);
140 }
141 
142 #endif
#define vstring_fgets_nonl(s, p)
#define vstring_str(vp)
Definition: vstring.h:71
#define VSTREAM_OUT
Definition: vstream.h:67
int main(int argc, char **argv)
Definition: anvil.c:1010
#define dns_lookup_l(name, rflags, list, fqdn, why, lflags,...)
Definition: dns.h:235
#define VSTREAM_IN
Definition: vstream.h:66
Definition: htable.h:25
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
Definition: vstring.c:431
HTABLE * htable_create(ssize_t size)
Definition: htable.c:179
VSTRING * smtp_unalias_addr(VSTRING *result, const char *addr)
Definition: smtp_unalias.c:102
VSTREAM * vstream_printf(const char *fmt,...)
Definition: vstream.c:1335
#define DNS_OK
Definition: dns.h:284
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
void * htable_find(HTABLE *table, const char *key)
Definition: htable.c:227
int vstream_fflush(VSTREAM *stream)
Definition: vstream.c:1257
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
const char * smtp_unalias_name(const char *name)
Definition: smtp_unalias.c:65
#define DNS_REQ_FLAG_NONE
Definition: dns.h:250
Definition: dns.h:139
VSTRING * vstring_strncpy(VSTRING *vp, const char *src, ssize_t len)
Definition: vstring.c:445
VSTRING * vstring_strcat(VSTRING *vp, const char *src)
Definition: vstring.c:459
char * vstring_export(VSTRING *vp)
Definition: vstring.c:569
HTABLE_INFO * htable_enter(HTABLE *table, const char *key, void *value)
Definition: htable.c:212