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