1 /*++
2 /* NAME
3 /*	flush_clnt 3
4 /* SUMMARY
5 /*	fast flush cache manager client interface
6 /* SYNOPSIS
7 /*	#include <flush_clnt.h>
8 /*
9 /*	void	flush_init()
10 /*
11 /*	int	flush_add(site, queue_id)
12 /*	const char *site;
13 /*	const char *queue_id;
14 /*
15 /*	int	flush_send_site(site)
16 /*	const char *site;
17 /*
18 /*	int	flush_send_file(queue_id)
19 /*	const char *queue_id;
20 /*
21 /*	int	flush_refresh()
22 /*
23 /*	int	flush_purge()
24 /* DESCRIPTION
25 /*	The following routines operate through the "fast flush" service.
26 /*	This service maintains a cache of what mail is queued. The cache
27 /*	is maintained for eligible destinations. A destination is the
28 /*	right-hand side of a user@domain email address.
29 /*
30 /*	flush_init() initializes. It must be called before dropping
31 /*	privileges in a daemon process.
32 /*
33 /*	flush_add() informs the "fast flush" cache manager that mail is
34 /*	queued for the specified site with the specified queue ID.
35 /*
36 /*	flush_send_site() requests delivery of all mail that is queued for
37 /*	the specified destination.
38 /*
39 /*	flush_send_file() requests delivery of mail with the specified
40 /*	queue ID.
41 /*
42 /*	flush_refresh() requests the "fast flush" cache manager to refresh
43 /*	cached information that was not used for some configurable amount
44 /*	time.
45 /*
46 /*	flush_purge() requests the "fast flush" cache manager to refresh
47 /*	all cached information. This is incredibly expensive, and is not
48 /*	recommended.
49 /* DIAGNOSTICS
50 /*	The result codes and their meanings are (see flush_clnt(5h)):
51 /* .IP MAIL_FLUSH_OK
52 /*	The request completed successfully (in case of requests that
53 /*	complete in the background: the request was accepted by the server).
54 /* .IP MAIL_FLUSH_FAIL
55 /*	The request failed (the request could not be sent to the server,
56 /*	or the server reported failure).
57 /* .IP MAIL_FLUSH_BAD
58 /*	The "fast flush" server rejected the request (invalid request
59 /*	parameter).
60 /* .IP MAIL_FLUSH_DENY
61 /*	The specified domain is not eligible for "fast flush" service,
62 /*	or the "fast flush" service is disabled.
63 /* SEE ALSO
64 /*	flush(8) Postfix fast flush cache manager
65 /* LICENSE
66 /* .ad
67 /* .fi
68 /*	The Secure Mailer license must be distributed with this software.
69 /* AUTHOR(S)
70 /*	Wietse Venema
71 /*	IBM T.J. Watson Research
72 /*	P.O. Box 704
73 /*	Yorktown Heights, NY 10598, USA
74 /*
75 /*	Wietse Venema
76 /*	Google, Inc.
77 /*	111 8th Avenue
78 /*	New York, NY 10011, USA
79 /*--*/
80 
81 /* System library. */
82 
83 #include "sys_defs.h"
84 #include <unistd.h>
85 #include <stdarg.h>
86 
87 /* Utility library. */
88 
89 #include <msg.h>
90 #include <vstream.h>
91 
92 /* Global library. */
93 
94 #include <mail_proto.h>
95 #include <mail_flush.h>
96 #include <mail_params.h>
97 #include <domain_list.h>
98 #include <match_parent_style.h>
99 #include <flush_clnt.h>
100 
101 /* Application-specific. */
102 
103 #define STR(x)	vstring_str(x)
104 
105 static DOMAIN_LIST *flush_domains;
106 
107 /* flush_init - initialize */
108 
flush_init(void)109 void    flush_init(void)
110 {
111     flush_domains = domain_list_init(VAR_FFLUSH_DOMAINS, MATCH_FLAG_RETURN
112 				   | match_parent_style(VAR_FFLUSH_DOMAINS),
113 				     var_fflush_domains);
114 }
115 
116 /* flush_purge - house keeping */
117 
flush_purge(void)118 int     flush_purge(void)
119 {
120     const char *myname = "flush_purge";
121     int     status;
122 
123     if (msg_verbose)
124 	msg_info("%s", myname);
125 
126     /*
127      * Don't bother the server if the service is turned off.
128      */
129     if (*var_fflush_domains == 0)
130 	status = FLUSH_STAT_DENY;
131     else
132 	status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
133 				     MAIL_ATTR_PROTO_FLUSH,
134 			      SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_PURGE),
135 				     ATTR_TYPE_END);
136 
137     if (msg_verbose)
138 	msg_info("%s: status %d", myname, status);
139 
140     return (status);
141 }
142 
143 /* flush_refresh - house keeping */
144 
flush_refresh(void)145 int     flush_refresh(void)
146 {
147     const char *myname = "flush_refresh";
148     int     status;
149 
150     if (msg_verbose)
151 	msg_info("%s", myname);
152 
153     /*
154      * Don't bother the server if the service is turned off.
155      */
156     if (*var_fflush_domains == 0)
157 	status = FLUSH_STAT_DENY;
158     else
159 	status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
160 				     MAIL_ATTR_PROTO_FLUSH,
161 			    SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_REFRESH),
162 				     ATTR_TYPE_END);
163 
164     if (msg_verbose)
165 	msg_info("%s: status %d", myname, status);
166 
167     return (status);
168 }
169 
170 /* flush_send_site - deliver mail queued for site */
171 
flush_send_site(const char * site)172 int     flush_send_site(const char *site)
173 {
174     const char *myname = "flush_send_site";
175     int     status;
176 
177     if (msg_verbose)
178 	msg_info("%s: site %s", myname, site);
179 
180     /*
181      * Don't bother the server if the service is turned off, or if the site
182      * is not eligible.
183      */
184     if (flush_domains == 0)
185 	msg_panic("missing flush client initialization");
186     if (domain_list_match(flush_domains, site) != 0) {
187 	if (warn_compat_break_flush_domains)
188 	    msg_info("using backwards-compatible default setting "
189 		     VAR_RELAY_DOMAINS "=$mydestination to flush "
190 		     "mail for domain \"%s\"", site);
191 	status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
192 				     MAIL_ATTR_PROTO_FLUSH,
193 			  SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_SEND_SITE),
194 				     SEND_ATTR_STR(MAIL_ATTR_SITE, site),
195 				     ATTR_TYPE_END);
196     } else if (flush_domains->error == 0)
197 	status = FLUSH_STAT_DENY;
198     else
199 	status = FLUSH_STAT_FAIL;
200 
201     if (msg_verbose)
202 	msg_info("%s: site %s status %d", myname, site, status);
203 
204     return (status);
205 }
206 
207 /* flush_send_file - deliver specific message */
208 
flush_send_file(const char * queue_id)209 int     flush_send_file(const char *queue_id)
210 {
211     const char *myname = "flush_send_file";
212     int     status;
213 
214     if (msg_verbose)
215 	msg_info("%s: queue_id %s", myname, queue_id);
216 
217     /*
218      * Require that the service is turned on.
219      */
220     status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
221 				 MAIL_ATTR_PROTO_FLUSH,
222 			  SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_SEND_FILE),
223 				 SEND_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
224 				 ATTR_TYPE_END);
225 
226     if (msg_verbose)
227 	msg_info("%s: queue_id %s status %d", myname, queue_id, status);
228 
229     return (status);
230 }
231 
232 /* flush_add - inform "fast flush" cache manager */
233 
flush_add(const char * site,const char * queue_id)234 int     flush_add(const char *site, const char *queue_id)
235 {
236     const char *myname = "flush_add";
237     int     status;
238 
239     if (msg_verbose)
240 	msg_info("%s: site %s id %s", myname, site, queue_id);
241 
242     /*
243      * Don't bother the server if the service is turned off, or if the site
244      * is not eligible.
245      */
246     if (flush_domains == 0)
247 	msg_panic("missing flush client initialization");
248     if (domain_list_match(flush_domains, site) != 0) {
249 	if (warn_compat_break_flush_domains)
250 	    msg_info("using backwards-compatible default setting "
251 		     VAR_RELAY_DOMAINS "=$mydestination to update "
252 		     "fast-flush logfile for domain \"%s\"", site);
253 	status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
254 				     MAIL_ATTR_PROTO_FLUSH,
255 				SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_ADD),
256 				     SEND_ATTR_STR(MAIL_ATTR_SITE, site),
257 				 SEND_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
258 				     ATTR_TYPE_END);
259     } else if (flush_domains->error == 0)
260 	status = FLUSH_STAT_DENY;
261     else
262 	status = FLUSH_STAT_FAIL;
263 
264     if (msg_verbose)
265 	msg_info("%s: site %s id %s status %d", myname, site, queue_id,
266 		 status);
267 
268     return (status);
269 }
270