xref: /netbsd-src/external/ibm-public/postfix/dist/src/smtpd/smtpd_resolve.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: smtpd_resolve.c,v 1.1.1.1 2009/06/23 10:08:56 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	smtpd_resolve 3
6 /* SUMMARY
7 /*	caching resolve client
8 /* SYNOPSIS
9 /*	#include <smtpd_resolve.h>
10 /*
11 /*	void	smtpd_resolve_init(cache_size)
12 /*	int	cache_size;
13 /*
14 /*	const RESOLVE_REPLY *smtpd_resolve_addr(addr)
15 /*	const char *addr;
16 /* DESCRIPTION
17 /*	This module maintains a resolve client cache that persists
18 /*	across SMTP sessions (not process life times). Addresses
19 /*	are always resolved in local rewriting context.
20 /*
21 /*	smtpd_resolve_init() initializes the cache and must
22 /*	called once before the cache can be used.
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 addr
31 /*	The address to resolve.
32 /* DIAGNOSTICS
33 /*	All errors are fatal.
34 /* BUGS
35 /*	The recipient address is always case folded to lowercase.
36 /*	Changing this requires great care, since the address is used
37 /*	for policy lookups.
38 /* LICENSE
39 /* .ad
40 /* .fi
41 /*	The Secure Mailer license must be distributed with this software.
42 /* AUTHOR(S)
43 /*	Wietse Venema
44 /*	IBM T.J. Watson Research
45 /*	P.O. Box 704
46 /*	Yorktown Heights, NY 10598, USA
47 /*--*/
48 
49 /* System library. */
50 
51 #include <sys_defs.h>
52 
53 /* Utility library. */
54 
55 #include <msg.h>
56 #include <mymalloc.h>
57 #include <vstring.h>
58 #include <ctable.h>
59 #include <stringops.h>
60 
61 /* Global library. */
62 
63 #include <rewrite_clnt.h>
64 #include <resolve_clnt.h>
65 #include <mail_proto.h>
66 
67 /* Application-specific. */
68 
69 #include <smtpd_resolve.h>
70 
71 static CTABLE *smtpd_resolve_cache;
72 
73 #define STR(x) vstring_str(x)
74 
75 /* resolve_pagein - page in an address resolver result */
76 
77 static void *resolve_pagein(const char *addr, void *unused_context)
78 {
79     static VSTRING *query;
80     RESOLVE_REPLY *reply;
81 
82     /*
83      * Initialize on the fly.
84      */
85     if (query == 0)
86 	query = vstring_alloc(10);
87 
88     /*
89      * Initialize.
90      */
91     reply = (RESOLVE_REPLY *) mymalloc(sizeof(*reply));
92     resolve_clnt_init(reply);
93 
94     /*
95      * Resolve the address.
96      */
97     rewrite_clnt_internal(MAIL_ATTR_RWR_LOCAL, addr, query);
98     resolve_clnt_query(STR(query), reply);
99     lowercase(STR(reply->recipient));		/* XXX */
100 
101     /*
102      * Save the result.
103      */
104     return ((void *) reply);
105 }
106 
107 /* resolve_pageout - page out an address resolver result */
108 
109 static void resolve_pageout(void *data, void *unused_context)
110 {
111     RESOLVE_REPLY *reply = (RESOLVE_REPLY *) data;
112 
113     resolve_clnt_free(reply);
114     myfree((void *) reply);
115 }
116 
117 /* smtpd_resolve_init - set up global cache */
118 
119 void    smtpd_resolve_init(int cache_size)
120 {
121 
122     /*
123      * Sanity check.
124      */
125     if (smtpd_resolve_cache)
126 	msg_panic("smtpd_resolve_init: multiple initialization");
127 
128     /*
129      * Initialize the resolved address cache. Note: the cache persists across
130      * SMTP sessions so we cannot make it dependent on session state.
131      */
132     smtpd_resolve_cache = ctable_create(cache_size, resolve_pagein,
133 					resolve_pageout, (void *) 0);
134 }
135 
136 /* smtpd_resolve_addr - resolve cached addres */
137 
138 const RESOLVE_REPLY *smtpd_resolve_addr(const char *addr)
139 {
140 
141     /*
142      * Sanity check.
143      */
144     if (smtpd_resolve_cache == 0)
145 	msg_panic("smtpd_resolve_addr: missing initialization");
146 
147     /*
148      * Reply from the read-through cache.
149      */
150     return (const RESOLVE_REPLY *) ctable_locate(smtpd_resolve_cache, addr);
151 }
152