Postfix3.3.1
全て データ構造 ファイル 関数 変数 型定義 マクロ定義
smtpd_resolve.c
[詳解]
1 /*++
2 /* NAME
3 /* smtpd_resolve 3
4 /* SUMMARY
5 /* caching resolve client
6 /* SYNOPSIS
7 /* #include <smtpd_resolve.h>
8 /*
9 /* void smtpd_resolve_init(cache_size)
10 /* int cache_size;
11 /*
12 /* const RESOLVE_REPLY *smtpd_resolve_addr(sender, addr)
13 /* const char *sender;
14 /* const char *addr;
15 /* DESCRIPTION
16 /* This module maintains a resolve client cache that persists
17 /* across SMTP sessions (not process life times). Addresses
18 /* are always resolved in local rewriting context.
19 /*
20 /* smtpd_resolve_init() initializes the cache and must be
21 /* called before the cache can be used. This function may also
22 /* be called to flush the cache after an address class update.
23 /*
24 /* smtpd_resolve_addr() resolves one address or returns
25 /* a known result from cache.
26 /*
27 /* Arguments:
28 /* .IP cache_size
29 /* The requested cache size.
30 /* .IP sender
31 /* The message sender, or null pointer.
32 /* .IP addr
33 /* The address to resolve.
34 /* DIAGNOSTICS
35 /* All errors are fatal.
36 /* BUGS
37 /* The recipient address is always case folded to lowercase.
38 /* Changing this requires great care, since the address is used
39 /* for policy lookups.
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 /*
50 /* Wietse Venema
51 /* Google, Inc.
52 /* 111 8th Avenue
53 /* New York, NY 10011, USA
54 /*--*/
55 
56 /* System library. */
57 
58 #include <sys_defs.h>
59 
60 /* Utility library. */
61 
62 #include <msg.h>
63 #include <mymalloc.h>
64 #include <vstring.h>
65 #include <ctable.h>
66 #include <stringops.h>
67 #include <split_at.h>
68 
69 /* Global library. */
70 
71 #include <rewrite_clnt.h>
72 #include <resolve_clnt.h>
73 #include <mail_proto.h>
74 
75 /* Application-specific. */
76 
77 #include <smtpd_resolve.h>
78 
79 static CTABLE *smtpd_resolve_cache;
80 
81 #define STR(x) vstring_str(x)
82 #define SENDER_ADDR_JOIN_CHAR '\n'
83 
84 /* resolve_pagein - page in an address resolver result */
85 
86 static void *resolve_pagein(const char *sender_plus_addr, void *unused_context)
87 {
88  const char myname[] = "resolve_pagein";
89  static VSTRING *query;
90  static VSTRING *junk;
91  static VSTRING *sender_buf;
92  RESOLVE_REPLY *reply;
93  const char *sender;
94  const char *addr;
95 
96  /*
97  * Initialize on the fly.
98  */
99  if (query == 0) {
100  query = vstring_alloc(10);
101  junk = vstring_alloc(10);
102  sender_buf = vstring_alloc(10);
103  }
104 
105  /*
106  * Initialize.
107  */
108  reply = (RESOLVE_REPLY *) mymalloc(sizeof(*reply));
109  resolve_clnt_init(reply);
110 
111  /*
112  * Split the sender and address.
113  */
114  vstring_strcpy(junk, sender_plus_addr);
115  sender = STR(junk);
116  if ((addr = split_at(STR(junk), SENDER_ADDR_JOIN_CHAR)) == 0)
117  msg_panic("%s: bad search key: \"%s\"", myname, sender_plus_addr);
118 
119  /*
120  * Resolve the address.
121  */
122  rewrite_clnt_internal(MAIL_ATTR_RWR_LOCAL, sender, sender_buf);
124  resolve_clnt_query_from(STR(sender_buf), STR(query), reply);
125  vstring_strcpy(junk, STR(reply->recipient));
126  casefold(reply->recipient, STR(junk)); /* XXX */
127 
128  /*
129  * Save the result.
130  */
131  return ((void *) reply);
132 }
133 
134 /* resolve_pageout - page out an address resolver result */
135 
136 static void resolve_pageout(void *data, void *unused_context)
137 {
138  RESOLVE_REPLY *reply = (RESOLVE_REPLY *) data;
139 
140  resolve_clnt_free(reply);
141  myfree((void *) reply);
142 }
143 
144 /* smtpd_resolve_init - set up global cache */
145 
146 void smtpd_resolve_init(int cache_size)
147 {
148 
149  /*
150  * Flush a pre-existing cache. The smtpd_check test program requires this
151  * after an address class change.
152  */
153  if (smtpd_resolve_cache)
154  ctable_free(smtpd_resolve_cache);
155 
156  /*
157  * Initialize the resolved address cache. Note: the cache persists across
158  * SMTP sessions so we cannot make it dependent on session state.
159  */
160  smtpd_resolve_cache = ctable_create(cache_size, resolve_pagein,
161  resolve_pageout, (void *) 0);
162 }
163 
164 /* smtpd_resolve_addr - resolve cached address */
165 
166 const RESOLVE_REPLY *smtpd_resolve_addr(const char *sender, const char *addr)
167 {
168  static VSTRING *sender_plus_addr_buf;
169 
170  /*
171  * Initialize on the fly.
172  */
173  if (sender_plus_addr_buf == 0)
174  sender_plus_addr_buf = vstring_alloc(10);
175 
176  /*
177  * Sanity check.
178  */
179  if (smtpd_resolve_cache == 0)
180  msg_panic("smtpd_resolve_addr: missing initialization");
181 
182  /*
183  * Reply from the read-through cache.
184  */
185  vstring_sprintf(sender_plus_addr_buf, "%s%c%s",
186  sender ? sender : RESOLVE_NULL_FROM,
187  SENDER_ADDR_JOIN_CHAR, addr);
188  return (const RESOLVE_REPLY *)
189  ctable_locate(smtpd_resolve_cache, STR(sender_plus_addr_buf));
190 }
void myfree(void *ptr)
Definition: mymalloc.c:207
#define CTABLE
Definition: ctable.h:19
#define RESOLVE_NULL_FROM
Definition: resolve_clnt.h:54
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
VSTRING * rewrite_clnt_internal(const char *ruleset, const char *addr, VSTRING *result)
Definition: rewrite_clnt.c:175
const void * ctable_locate(CTABLE *cache, const char *key)
Definition: ctable.c:140
void resolve_clnt_free(RESOLVE_REPLY *reply)
Definition: resolve_clnt.c:287
#define MAIL_ATTR_RWR_LOCAL
Definition: mail_proto.h:166
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
Definition: vstring.c:431
#define casefold(dst, src)
Definition: stringops.h:67
void resolve_clnt_init(RESOLVE_REPLY *reply)
Definition: resolve_clnt.c:147
CTABLE * ctable_create(ssize_t limit, CTABLE_CREATE_FN create, CTABLE_DELETE_FN delete, void *context)
Definition: ctable.c:119
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
#define STR(x)
Definition: smtpd_resolve.c:81
void smtpd_resolve_init(int cache_size)
const RESOLVE_REPLY * smtpd_resolve_addr(const char *sender, const char *addr)
VSTRING * vstring_sprintf(VSTRING *vp, const char *format,...)
Definition: vstring.c:602
VSTRING * recipient
Definition: resolve_clnt.h:46
#define SENDER_ADDR_JOIN_CHAR
Definition: smtpd_resolve.c:82
char * split_at(char *string, int delimiter)
Definition: split_at.c:53
#define resolve_clnt_query_from(f, a, r)
Definition: resolve_clnt.h:56
void ctable_free(CTABLE *cache)
Definition: ctable.c:226
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150