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