Postfix3.3.1
verify.c
[詳解]
1 /*++
2 /* NAME
3 /* verify 8
4 /* SUMMARY
5 /* Postfix address verification server
6 /* SYNOPSIS
7 /* \fBverify\fR [generic Postfix daemon options]
8 /* DESCRIPTION
9 /* The \fBverify\fR(8) address verification server maintains a record
10 /* of what recipient addresses are known to be deliverable or
11 /* undeliverable.
12 /*
13 /* Addresses are verified by injecting probe messages into the
14 /* Postfix queue. Probe messages are run through all the routing
15 /* and rewriting machinery except for final delivery, and are
16 /* discarded rather than being deferred or bounced.
17 /*
18 /* Address verification relies on the answer from the nearest
19 /* MTA for the specified address, and will therefore not detect
20 /* all undeliverable addresses.
21 /*
22 /* The \fBverify\fR(8) server is designed to run under control
23 /* by the Postfix
24 /* master server. It maintains an optional persistent database.
25 /* To avoid being interrupted by "postfix stop" in the middle
26 /* of a database update, the process runs in a separate process
27 /* group.
28 /*
29 /* The \fBverify\fR(8) server implements the following requests:
30 /* .IP "\fBupdate\fI address status text\fR"
31 /* Update the status and text of the specified address.
32 /* .IP "\fBquery\fI address\fR"
33 /* Look up the \fIstatus\fR and \fItext\fR for the specified
34 /* \fIaddress\fR.
35 /* If the status is unknown, a probe is sent and an "in progress"
36 /* status is returned.
37 /* SECURITY
38 /* .ad
39 /* .fi
40 /* The address verification server is not security-sensitive. It does
41 /* not talk to the network, and it does not talk to local users.
42 /* The verify server can run chrooted at fixed low privilege.
43 /*
44 /* The address verification server can be coerced to store
45 /* unlimited amounts of garbage. Limiting the cache expiry
46 /* time
47 /* trades one problem (disk space exhaustion) for another
48 /* one (poor response time to client requests).
49 /*
50 /* With Postfix version 2.5 and later, the \fBverify\fR(8)
51 /* server no longer uses root privileges when opening the
52 /* \fBaddress_verify_map\fR cache file. The file should now
53 /* be stored under the Postfix-owned \fBdata_directory\fR. As
54 /* a migration aid, an attempt to open a cache file under a
55 /* non-Postfix directory is redirected to the Postfix-owned
56 /* \fBdata_directory\fR, and a warning is logged.
57 /* DIAGNOSTICS
58 /* Problems and transactions are logged to \fBsyslogd\fR(8).
59 /* BUGS
60 /* Address verification probe messages add additional traffic
61 /* to the mail queue.
62 /* Recipient verification may cause an increased load on
63 /* down-stream servers in the case of a dictionary attack or
64 /* a flood of backscatter bounces.
65 /* Sender address verification may cause your site to be
66 /* blacklisted by some providers.
67 /*
68 /* If the persistent database ever gets corrupted then the world
69 /* comes to an end and human intervention is needed. This violates
70 /* a basic Postfix principle.
71 /* CONFIGURATION PARAMETERS
72 /* .ad
73 /* .fi
74 /* Changes to \fBmain.cf\fR are not picked up automatically,
75 /* as \fBverify\fR(8)
76 /* processes are long-lived. Use the command "\fBpostfix reload\fR" after
77 /* a configuration change.
78 /*
79 /* The text below provides only a parameter summary. See
80 /* \fBpostconf\fR(5) for more details including examples.
81 /* PROBE MESSAGE CONTROLS
82 /* .ad
83 /* .fi
84 /* .IP "\fBaddress_verify_sender ($double_bounce_sender)\fR"
85 /* The sender address to use in address verification probes; prior
86 /* to Postfix 2.5 the default was "postmaster".
87 /* .PP
88 /* Available with Postfix 2.9 and later:
89 /* .IP "\fBaddress_verify_sender_ttl (0s)\fR"
90 /* The time between changes in the time-dependent portion of address
91 /* verification probe sender addresses.
92 /* CACHE CONTROLS
93 /* .ad
94 /* .fi
95 /* .IP "\fBaddress_verify_map (see 'postconf -d' output)\fR"
96 /* Lookup table for persistent address verification status
97 /* storage.
98 /* .IP "\fBaddress_verify_positive_expire_time (31d)\fR"
99 /* The time after which a successful probe expires from the address
100 /* verification cache.
101 /* .IP "\fBaddress_verify_positive_refresh_time (7d)\fR"
102 /* The time after which a successful address verification probe needs
103 /* to be refreshed.
104 /* .IP "\fBaddress_verify_negative_cache (yes)\fR"
105 /* Enable caching of failed address verification probe results.
106 /* .IP "\fBaddress_verify_negative_expire_time (3d)\fR"
107 /* The time after which a failed probe expires from the address
108 /* verification cache.
109 /* .IP "\fBaddress_verify_negative_refresh_time (3h)\fR"
110 /* The time after which a failed address verification probe needs to
111 /* be refreshed.
112 /* .PP
113 /* Available with Postfix 2.7 and later:
114 /* .IP "\fBaddress_verify_cache_cleanup_interval (12h)\fR"
115 /* The amount of time between \fBverify\fR(8) address verification
116 /* database cleanup runs.
117 /* PROBE MESSAGE ROUTING CONTROLS
118 /* .ad
119 /* .fi
120 /* By default, probe messages are delivered via the same route
121 /* as regular messages. The following parameters can be used to
122 /* override specific message routing mechanisms.
123 /* .IP "\fBaddress_verify_relayhost ($relayhost)\fR"
124 /* Overrides the relayhost parameter setting for address verification
125 /* probes.
126 /* .IP "\fBaddress_verify_transport_maps ($transport_maps)\fR"
127 /* Overrides the transport_maps parameter setting for address verification
128 /* probes.
129 /* .IP "\fBaddress_verify_local_transport ($local_transport)\fR"
130 /* Overrides the local_transport parameter setting for address
131 /* verification probes.
132 /* .IP "\fBaddress_verify_virtual_transport ($virtual_transport)\fR"
133 /* Overrides the virtual_transport parameter setting for address
134 /* verification probes.
135 /* .IP "\fBaddress_verify_relay_transport ($relay_transport)\fR"
136 /* Overrides the relay_transport parameter setting for address
137 /* verification probes.
138 /* .IP "\fBaddress_verify_default_transport ($default_transport)\fR"
139 /* Overrides the default_transport parameter setting for address
140 /* verification probes.
141 /* .PP
142 /* Available in Postfix 2.3 and later:
143 /* .IP "\fBaddress_verify_sender_dependent_relayhost_maps ($sender_dependent_relayhost_maps)\fR"
144 /* Overrides the sender_dependent_relayhost_maps parameter setting for address
145 /* verification probes.
146 /* .PP
147 /* Available in Postfix 2.7 and later:
148 /* .IP "\fBaddress_verify_sender_dependent_default_transport_maps ($sender_dependent_default_transport_maps)\fR"
149 /* Overrides the sender_dependent_default_transport_maps parameter
150 /* setting for address verification probes.
151 /* SMTPUTF8 CONTROLS
152 /* .ad
153 /* .fi
154 /* Preliminary SMTPUTF8 support is introduced with Postfix 3.0.
155 /* .IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
156 /* Detect that a message requires SMTPUTF8 support for the specified
157 /* mail origin classes.
158 /* .PP
159 /* Available in Postfix version 3.2 and later:
160 /* .IP "\fBenable_idna2003_compatibility (no)\fR"
161 /* Enable 'transitional' compatibility between IDNA2003 and IDNA2008,
162 /* when converting UTF-8 domain names to/from the ASCII form that is
163 /* used for DNS lookups.
164 /* MISCELLANEOUS CONTROLS
165 /* .ad
166 /* .fi
167 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
168 /* The default location of the Postfix main.cf and master.cf
169 /* configuration files.
170 /* .IP "\fBdaemon_timeout (18000s)\fR"
171 /* How much time a Postfix daemon process may take to handle a
172 /* request before it is terminated by a built-in watchdog timer.
173 /* .IP "\fBipc_timeout (3600s)\fR"
174 /* The time limit for sending or receiving information over an internal
175 /* communication channel.
176 /* .IP "\fBprocess_id (read-only)\fR"
177 /* The process ID of a Postfix command or daemon process.
178 /* .IP "\fBprocess_name (read-only)\fR"
179 /* The process name of a Postfix command or daemon process.
180 /* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
181 /* The location of the Postfix top-level queue directory.
182 /* .IP "\fBsyslog_facility (mail)\fR"
183 /* The syslog facility of Postfix logging.
184 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
185 /* A prefix that is prepended to the process name in syslog
186 /* records, so that, for example, "smtpd" becomes "prefix/smtpd".
187 /* .PP
188 /* Available in Postfix 3.3 and later:
189 /* .IP "\fBservice_name (read-only)\fR"
190 /* The master.cf service name of a Postfix daemon process.
191 /* SEE ALSO
192 /* smtpd(8), Postfix SMTP server
193 /* cleanup(8), enqueue Postfix message
194 /* postconf(5), configuration parameters
195 /* syslogd(5), system logging
196 /* README FILES
197 /* .ad
198 /* .fi
199 /* Use "\fBpostconf readme_directory\fR" or
200 /* "\fBpostconf html_directory\fR" to locate this information.
201 /* .na
202 /* .nf
203 /* ADDRESS_VERIFICATION_README, address verification howto
204 /* LICENSE
205 /* .ad
206 /* .fi
207 /* The Secure Mailer license must be distributed with this software.
208 /* HISTORY
209 /* .ad
210 /* .fi
211 /* This service was introduced with Postfix version 2.1.
212 /* AUTHOR(S)
213 /* Wietse Venema
214 /* IBM T.J. Watson Research
215 /* P.O. Box 704
216 /* Yorktown Heights, NY 10598, USA
217 /*
218 /* Wietse Venema
219 /* Google, Inc.
220 /* 111 8th Avenue
221 /* New York, NY 10011, USA
222 /*--*/
223 
224 /* System library. */
225 
226 #include <sys_defs.h>
227 #include <sys/stat.h>
228 #include <time.h>
229 #include <string.h>
230 #include <stdlib.h>
231 #include <unistd.h>
232 
233 /* Utility library. */
234 
235 #include <msg.h>
236 #include <mymalloc.h>
237 #include <htable.h>
238 #include <dict_ht.h>
239 #include <dict_cache.h>
240 #include <split_at.h>
241 #include <stringops.h>
242 #include <set_eugid.h>
243 #include <events.h>
244 
245 /* Global library. */
246 
247 #include <mail_conf.h>
248 #include <mail_params.h>
249 #include <mail_version.h>
250 #include <mail_proto.h>
251 #include <post_mail.h>
252 #include <data_redirect.h>
253 #include <verify_clnt.h>
254 #include <verify_sender_addr.h>
255 
256 /* Server skeleton. */
257 
258 #include <mail_server.h>
259 
260 /* Application-specific. */
261 
262  /*
263  * Tunable parameters.
264  */
271 
272  /*
273  * State.
274  */
275 static DICT_CACHE *verify_map;
276 
277  /*
278  * Silly little macros.
279  */
280 #define STR(x) vstring_str(x)
281 #define STREQ(x,y) (strcmp(x,y) == 0)
282 
283  /*
284  * The address verification database consists of (address, data) tuples. The
285  * format of the data field is "status:probed:updated:text". The meaning of
286  * each field is:
287  *
288  * status: one of the four recipient status codes (OK, DEFER, BOUNCE or TODO).
289  * In the case of TODO, we have no information about the address, and the
290  * address is being probed.
291  *
292  * probed: if non-zero, the time the currently outstanding address probe was
293  * sent. If zero, there is no outstanding address probe.
294  *
295  * updated: if non-zero, the time the address probe result was received. If
296  * zero, we have no information about the address, and the address is being
297  * probed.
298  *
299  * text: descriptive text from delivery agents etc.
300  */
301 
302  /*
303  * Quick test to see status without parsing the whole entry.
304  */
305 #define STATUS_FROM_RAW_ENTRY(e) atoi(e)
306 
307 /* verify_make_entry - construct table entry */
308 
309 static void verify_make_entry(VSTRING *buf, int status, long probed,
310  long updated, const char *text)
311 {
312  vstring_sprintf(buf, "%d:%ld:%ld:%s", status, probed, updated, text);
313 }
314 
315 /* verify_parse_entry - parse table entry */
316 
317 static int verify_parse_entry(char *buf, int *status, long *probed,
318  long *updated, char **text)
319 {
320  char *probed_text;
321  char *updated_text;
322 
323  if ((probed_text = split_at(buf, ':')) != 0
324  && (updated_text = split_at(probed_text, ':')) != 0
325  && (*text = split_at(updated_text, ':')) != 0
326  && alldig(buf)
327  && alldig(probed_text)
328  && alldig(updated_text)) {
329  *probed = atol(probed_text);
330  *updated = atol(updated_text);
331  *status = atoi(buf);
332 
333  /*
334  * Coverity 200604: the code incorrectly tested (probed || updated),
335  * so that the sanity check never detected all-zero time stamps. Such
336  * records are never written. If we read a record with all-zero time
337  * stamps, then something is badly broken.
338  */
339  if ((*status == DEL_RCPT_STAT_OK
340  || *status == DEL_RCPT_STAT_DEFER
341  || *status == DEL_RCPT_STAT_BOUNCE
342  || *status == DEL_RCPT_STAT_TODO)
343  && (*probed || *updated))
344  return (0);
345  }
346  msg_warn("bad address verify table entry: %.100s", buf);
347  return (-1);
348 }
349 
350 /* verify_stat2name - status to name */
351 
352 static const char *verify_stat2name(int addr_status)
353 {
354  if (addr_status == DEL_RCPT_STAT_OK)
355  return ("deliverable");
356  if (addr_status == DEL_RCPT_STAT_DEFER)
357  return ("undeliverable");
358  if (addr_status == DEL_RCPT_STAT_BOUNCE)
359  return ("undeliverable");
360  return (0);
361 }
362 
363 /* verify_update_service - update address service */
364 
365 static void verify_update_service(VSTREAM *client_stream)
366 {
367  VSTRING *buf = vstring_alloc(10);
368  VSTRING *addr = vstring_alloc(10);
369  int addr_status;
370  VSTRING *text = vstring_alloc(10);
371  const char *status_name;
372  const char *raw_data;
373  long probed;
374  long updated;
375 
376  if (attr_scan(client_stream, ATTR_FLAG_STRICT,
378  RECV_ATTR_INT(MAIL_ATTR_ADDR_STATUS, &addr_status),
380  ATTR_TYPE_END) == 3) {
381  /* FIX 200501 IPv6 patch did not neuter ":" in address literals. */
382  translit(STR(addr), ":", "_");
383  if ((status_name = verify_stat2name(addr_status)) == 0) {
384  msg_warn("bad recipient status %d for recipient %s",
385  addr_status, STR(addr));
386  attr_print(client_stream, ATTR_FLAG_NONE,
388  ATTR_TYPE_END);
389  } else {
390 
391  /*
392  * Robustness: don't allow a failed probe to clobber an OK
393  * address before it expires. The failed probe is ignored so that
394  * the address will be re-probed upon the next query. As long as
395  * some probes succeed the address will remain cached as OK.
396  */
397  if (addr_status == DEL_RCPT_STAT_OK
398  || (raw_data = dict_cache_lookup(verify_map, STR(addr))) == 0
399  || STATUS_FROM_RAW_ENTRY(raw_data) != DEL_RCPT_STAT_OK) {
400  probed = 0;
401  updated = (long) time((time_t *) 0);
402  verify_make_entry(buf, addr_status, probed, updated, STR(text));
403  if (msg_verbose)
404  msg_info("PUT %s status=%d probed=%ld updated=%ld text=%s",
405  STR(addr), addr_status, probed, updated, STR(text));
406  dict_cache_update(verify_map, STR(addr), STR(buf));
407  }
408  attr_print(client_stream, ATTR_FLAG_NONE,
410  ATTR_TYPE_END);
411  }
412  }
413  vstring_free(buf);
414  vstring_free(addr);
415  vstring_free(text);
416 }
417 
418 /* verify_post_mail_fclose_action - callback */
419 
420 static void verify_post_mail_fclose_action(int unused_status,
421  void *unused_context)
422 {
423  /* no code here, we just need to avoid blocking in post_mail_fclose() */
424 }
425 
426 /* verify_post_mail_action - callback */
427 
428 static void verify_post_mail_action(VSTREAM *stream, void *context)
429 {
430 
431  /*
432  * Probe messages need no body content, because they are never delivered,
433  * deferred, or bounced.
434  */
435  if (stream != 0)
436  post_mail_fclose_async(stream, verify_post_mail_fclose_action, context);
437 }
438 
439 /* verify_query_service - query address status */
440 
441 static void verify_query_service(VSTREAM *client_stream)
442 {
443  VSTRING *addr = vstring_alloc(10);
444  VSTRING *get_buf = 0;
445  VSTRING *put_buf = 0;
446  const char *raw_data;
447  int addr_status;
448  long probed;
449  long updated;
450  char *text;
451 
452  if (attr_scan(client_stream, ATTR_FLAG_STRICT,
454  ATTR_TYPE_END) == 1) {
455  long now = (long) time((time_t *) 0);
456 
457  /*
458  * Produce a default record when no usable record exists.
459  *
460  * If negative caching is disabled, purge an expired record from the
461  * database.
462  *
463  * XXX Assume that a probe is lost if no response is received in 1000
464  * seconds. If this number is too small the queue will slowly fill up
465  * with delayed probes.
466  *
467  * XXX Maintain a moving average for the probe turnaround time, and
468  * allow probe "retransmission" when a probe is outstanding for, say
469  * some minimal amount of time (1000 sec) plus several times the
470  * observed probe turnaround time. This causes probing to back off
471  * when the mail system becomes congested.
472  */
473 #define POSITIVE_ENTRY_EXPIRED(addr_status, updated) \
474  (addr_status == DEL_RCPT_STAT_OK && updated + var_verify_pos_exp < now)
475 #define NEGATIVE_ENTRY_EXPIRED(addr_status, updated) \
476  (addr_status != DEL_RCPT_STAT_OK && updated + var_verify_neg_exp < now)
477 #define PROBE_TTL 1000
478 
479  /* FIX 200501 IPv6 patch did not neuter ":" in address literals. */
480  translit(STR(addr), ":", "_");
481  if ((raw_data = dict_cache_lookup(verify_map, STR(addr))) == 0 /* not found */
482  || ((get_buf = vstring_alloc(10)),
483  vstring_strcpy(get_buf, raw_data), /* malformed */
484  verify_parse_entry(STR(get_buf), &addr_status, &probed,
485  &updated, &text) < 0)
486  || (now - probed > PROBE_TTL /* safe to probe */
487  && (POSITIVE_ENTRY_EXPIRED(addr_status, updated)
488  || NEGATIVE_ENTRY_EXPIRED(addr_status, updated)))) {
489  addr_status = DEL_RCPT_STAT_TODO;
490  probed = 0;
491  updated = 0;
492  text = "Address verification in progress";
493  if (raw_data != 0 && var_verify_neg_cache == 0)
494  dict_cache_delete(verify_map, STR(addr));
495  }
496  if (msg_verbose)
497  msg_info("GOT %s status=%d probed=%ld updated=%ld text=%s",
498  STR(addr), addr_status, probed, updated, text);
499 
500  /*
501  * Respond to the client.
502  */
503  attr_print(client_stream, ATTR_FLAG_NONE,
505  SEND_ATTR_INT(MAIL_ATTR_ADDR_STATUS, addr_status),
507  ATTR_TYPE_END);
508 
509  /*
510  * Send a new probe when the information needs to be refreshed.
511  *
512  * XXX For an initial proof of concept implementation, use synchronous
513  * mail submission. This needs to be made async for high-volume
514  * sites, which makes it even more interesting to eliminate duplicate
515  * queries while a probe is being built.
516  *
517  * If negative caching is turned off, update the database only when
518  * refreshing an existing entry.
519  */
520 #define POSITIVE_REFRESH_NEEDED(addr_status, updated) \
521  (addr_status == DEL_RCPT_STAT_OK && updated + var_verify_pos_try < now)
522 #define NEGATIVE_REFRESH_NEEDED(addr_status, updated) \
523  (addr_status != DEL_RCPT_STAT_OK && updated + var_verify_neg_try < now)
524 
525  if (now - probed > PROBE_TTL
526  && (POSITIVE_REFRESH_NEEDED(addr_status, updated)
527  || NEGATIVE_REFRESH_NEEDED(addr_status, updated))) {
528  if (msg_verbose)
529  msg_info("PROBE %s status=%d probed=%ld updated=%ld",
530  STR(addr), addr_status, now, updated);
535  (VSTRING *) 0,
536  verify_post_mail_action,
537  (void *) 0);
538  if (updated != 0 || var_verify_neg_cache != 0) {
539  put_buf = vstring_alloc(10);
540  verify_make_entry(put_buf, addr_status, now, updated, text);
541  if (msg_verbose)
542  msg_info("PUT %s status=%d probed=%ld updated=%ld text=%s",
543  STR(addr), addr_status, now, updated, text);
544  dict_cache_update(verify_map, STR(addr), STR(put_buf));
545  }
546  }
547  }
548  vstring_free(addr);
549  if (get_buf)
550  vstring_free(get_buf);
551  if (put_buf)
552  vstring_free(put_buf);
553 }
554 
555 /* verify_cache_validator - cache cleanup validator */
556 
557 static int verify_cache_validator(const char *addr, const char *raw_data,
558  void *context)
559 {
560  VSTRING *get_buf = (VSTRING *) context;
561  int addr_status;
562  long probed;
563  long updated;
564  char *text;
565  long now = (long) event_time();
566 
567 #define POS_OR_NEG_ENTRY_EXPIRED(stat, stamp) \
568  (POSITIVE_ENTRY_EXPIRED((stat), (stamp)) \
569  || NEGATIVE_ENTRY_EXPIRED((stat), (stamp)))
570 
571  vstring_strcpy(get_buf, raw_data);
572  return (verify_parse_entry(STR(get_buf), &addr_status, /* syntax OK */
573  &probed, &updated, &text) == 0
574  && (now - probed < PROBE_TTL /* probe in progress */
575  || !POS_OR_NEG_ENTRY_EXPIRED(addr_status, updated)));
576 }
577 
578 /* verify_service - perform service for client */
579 
580 static void verify_service(VSTREAM *client_stream, char *unused_service,
581  char **argv)
582 {
583  VSTRING *request = vstring_alloc(10);
584 
585  /*
586  * Sanity check. This service takes no command-line arguments.
587  */
588  if (argv[0])
589  msg_fatal("unexpected command-line argument: %s", argv[0]);
590 
591  /*
592  * This routine runs whenever a client connects to the socket dedicated
593  * to the address verification service. All connection-management stuff
594  * is handled by the common code in multi_server.c.
595  */
596  if (attr_scan(client_stream,
598  RECV_ATTR_STR(MAIL_ATTR_REQ, request),
599  ATTR_TYPE_END) == 1) {
600  if (STREQ(STR(request), VRFY_REQ_UPDATE)) {
601  verify_update_service(client_stream);
602  } else if (STREQ(STR(request), VRFY_REQ_QUERY)) {
603  verify_query_service(client_stream);
604  } else {
605  msg_warn("unrecognized request: \"%s\", ignored", STR(request));
606  attr_print(client_stream, ATTR_FLAG_NONE,
608  ATTR_TYPE_END);
609  }
610  }
611  vstream_fflush(client_stream);
612  vstring_free(request);
613 }
614 
615 /* verify_dump - dump some statistics */
616 
617 static void verify_dump(char *unused_name, char **unused_argv)
618 {
619 
620  /*
621  * Dump preliminary cache cleanup statistics when the process commits
622  * suicide while a cache cleanup run is in progress. We can't currently
623  * distinguish between "postfix reload" (we should restart) or "maximal
624  * idle time reached" (we could finish the cache cleanup first).
625  */
626  dict_cache_close(verify_map);
627  verify_map = 0;
628 }
629 
630 /* post_jail_init - post-jail initialization */
631 
632 static void post_jail_init(char *unused_name, char **unused_argv)
633 {
634 
635  /*
636  * If the database is in volatile memory only, prevent automatic process
637  * suicide after a limited number of client requests or after a limited
638  * amount of idle time.
639  */
640  if (*var_verify_map == 0) {
641  var_use_limit = 0;
642  var_idle_limit = 0;
643  }
644 
645  /*
646  * Start the cache cleanup thread.
647  */
648  if (var_verify_scan_cache > 0) {
649  int cache_flags;
650 
651  cache_flags = DICT_CACHE_FLAG_STATISTICS;
652  if (msg_verbose)
653  cache_flags |= DICT_CACHE_FLAG_VERBOSE;
654  dict_cache_control(verify_map,
655  CA_DICT_CACHE_CTL_FLAGS(cache_flags),
657  CA_DICT_CACHE_CTL_VALIDATOR(verify_cache_validator),
660  }
661 }
662 
663 /* pre_jail_init - pre-jail initialization */
664 
665 static void pre_jail_init(char *unused_name, char **unused_argv)
666 {
667  mode_t saved_mask;
668  VSTRING *redirect;
669 
670  /*
671  * Never, ever, get killed by a master signal, as that would corrupt the
672  * database when we're in the middle of an update.
673  */
674  setsid();
675 
676  /*
677  * Security: don't create root-owned files that contain untrusted data.
678  * And don't create Postfix-owned files in root-owned directories,
679  * either. We want a correct relationship between (file/directory)
680  * ownership and (file/directory) content.
681  *
682  * XXX Non-root open can violate the principle of least surprise: Postfix
683  * can't open an *SQL config file for database read-write access, even
684  * though it can open that same control file for database read-only
685  * access.
686  *
687  * The solution is to query a map type and obtain its properties before
688  * opening it. A clean solution is to add a dict_info() API that is
689  * similar to dict_open() except it returns properties (dict flags) only.
690  * A pragmatic solution is to overload the existing API and have
691  * dict_open() return a dummy map when given a null map name.
692  *
693  * However, the proxymap daemon has been opening *SQL maps as non-root for
694  * years now without anyone complaining, let's not solve a problem that
695  * doesn't exist.
696  */
698  redirect = vstring_alloc(100);
699 
700  /*
701  * Keep state in persistent (external) or volatile (internal) map.
702  *
703  * Start the cache cleanup thread after permanently dropping privileges.
704  */
705 #define VERIFY_DICT_OPEN_FLAGS (DICT_FLAG_DUP_REPLACE | DICT_FLAG_SYNC_UPDATE \
706  | DICT_FLAG_OPEN_LOCK | DICT_FLAG_UTF8_REQUEST)
707 
708  saved_mask = umask(022);
709  verify_map =
711  data_redirect_map(redirect, var_verify_map) :
712  "internal:verify",
713  O_CREAT | O_RDWR, VERIFY_DICT_OPEN_FLAGS);
714  (void) umask(saved_mask);
715 
716  /*
717  * Clean up and restore privilege.
718  */
719  vstring_free(redirect);
721 }
722 
724 
725 /* main - pass control to the multi-threaded skeleton */
726 
727 int main(int argc, char **argv)
728 {
729  static const CONFIG_STR_TABLE str_table[] = {
732  0,
733  };
734  static const CONFIG_TIME_TABLE time_table[] = {
741  0,
742  };
743 
744  /*
745  * Fingerprint executables and core dumps.
746  */
748 
749  multi_server_main(argc, argv, verify_service,
750  CA_MAIL_SERVER_STR_TABLE(str_table),
751  CA_MAIL_SERVER_TIME_TABLE(time_table),
752  CA_MAIL_SERVER_PRE_INIT(pre_jail_init),
753  CA_MAIL_SERVER_POST_INIT(post_jail_init),
755  CA_MAIL_SERVER_EXIT(verify_dump),
756  0);
757 }
int msg_verbose
Definition: msg.c:177
#define VAR_VERIFY_NEG_TRY
Definition: mail_params.h:2810
char * var_verify_sender
#define ATTR_FLAG_NONE
Definition: attr.h:98
#define RESTORE_SAVED_EUGID()
Definition: set_eugid.h:28
#define DEF_VERIFY_SENDER_TTL
Definition: mail_params.h:2827
#define SMTPUTF8_FLAG_NONE
Definition: smtputf8.h:96
#define CA_MAIL_SERVER_STR_TABLE(v)
Definition: mail_server.h:57
#define NEGATIVE_ENTRY_EXPIRED(addr_status, updated)
#define DEL_RCPT_STAT_TODO
int var_verify_neg_exp
Definition: verify.c:268
const char * dict_cache_lookup(DICT_CACHE *cp, const char *cache_key)
Definition: dict_cache.c:269
#define MAIL_ATTR_REQ
Definition: mail_proto.h:124
char * data_redirect_map(VSTRING *result, const char *map)
int var_verify_sender_ttl
#define SAVE_AND_SET_EUGID(uid, gid)
Definition: set_eugid.h:23
#define CA_MAIL_SERVER_EXIT(v)
Definition: mail_server.h:67
#define DEF_VERIFY_SENDER
Definition: mail_params.h:2823
#define RECV_ATTR_INT(name, val)
Definition: attr.h:71
#define ATTR_TYPE_END
Definition: attr.h:39
int var_idle_limit
Definition: mail_params.c:250
#define DEL_RCPT_STAT_BOUNCE
char * translit(char *, const char *, const char *)
Definition: translit.c:40
int alldig(const char *string)
Definition: alldig.c:38
#define CA_DICT_CACHE_CTL_INTERVAL(v)
Definition: dict_cache.h:48
#define STR(x)
Definition: verify.c:280
#define POS_OR_NEG_ENTRY_EXPIRED(stat, stamp)
#define POSITIVE_REFRESH_NEEDED(addr_status, updated)
#define MAIL_ATTR_ADDR
Definition: mail_proto.h:146
#define DEF_VERIFY_NEG_EXP
Definition: mail_params.h:2807
NORETURN multi_server_main(int, char **, MULTI_SERVER_FN,...)
Definition: multi_server.c:530
#define VRFY_REQ_QUERY
Definition: verify_clnt.h:27
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
Definition: vstring.c:431
#define CA_DICT_CACHE_CTL_FLAGS(v)
Definition: dict_cache.h:47
#define POSITIVE_ENTRY_EXPIRED(addr_status, updated)
void post_mail_fclose_async(VSTREAM *stream, void(*notify)(int status, void *context), void *context)
Definition: post_mail.c:519
#define CA_MAIL_SERVER_POST_INIT(v)
Definition: mail_server.h:65
#define VERIFY_DICT_OPEN_FLAGS
#define PROBE_TTL
#define attr_print
Definition: attr.h:109
#define STATUS_FROM_RAW_ENTRY(e)
Definition: verify.c:305
#define DICT_CACHE_FLAG_VERBOSE
Definition: dict_cache.h:35
#define VAR_VERIFY_NEG_EXP
Definition: mail_params.h:2806
gid_t var_owner_gid
Definition: mail_params.c:235
uid_t var_owner_uid
Definition: mail_params.c:234
#define DEF_VERIFY_NEG_TRY
Definition: mail_params.h:2811
#define VAR_VERIFY_SCAN_CACHE
Definition: mail_params.h:2818
#define MAIL_ATTR_WHY
Definition: mail_proto.h:135
void msg_warn(const char *fmt,...)
Definition: msg.c:215
int dict_cache_delete(DICT_CACHE *cp, const char *cache_key)
Definition: dict_cache.c:328
#define VRFY_REQ_UPDATE
Definition: verify_clnt.h:28
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
#define DEF_VERIFY_POS_EXP
Definition: mail_params.h:2799
#define CA_DICT_CACHE_CTL_END
Definition: dict_cache.h:46
#define MAIL_SRC_MASK_VERIFY
Definition: mail_proto.h:83
#define CA_DICT_CACHE_CTL_VALIDATOR(v)
Definition: dict_cache.h:49
int var_use_limit
Definition: mail_params.c:248
void const char long
Definition: opened.h:22
#define MAIL_VERSION_STAMP_ALLOCATE
Definition: mail_version.h:67
#define VAR_VERIFY_SENDER_TTL
Definition: mail_params.h:2826
int main(int argc, char **argv)
Definition: verify.c:727
void dict_cache_close(DICT_CACHE *cp)
Definition: dict_cache.c:656
VSTRING * vstring_sprintf(VSTRING *vp, const char *format,...)
Definition: vstring.c:602
#define STREQ(x, y)
Definition: verify.c:281
#define DEF_VERIFY_SCAN_CACHE
Definition: mail_params.h:2819
#define CA_DICT_CACHE_CTL_CONTEXT(v)
Definition: dict_cache.h:50
#define CA_MAIL_SERVER_TIME_TABLE(v)
Definition: mail_server.h:59
#define MAIL_ATTR_STATUS
Definition: mail_proto.h:126
#define SEND_ATTR_INT(name, val)
Definition: attr.h:63
char * var_verify_map
Definition: verify.c:265
int var_verify_pos_try
Definition: verify.c:267
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
int vstream_fflush(VSTREAM *stream)
Definition: vstream.c:1257
int var_verify_pos_exp
Definition: verify.c:266
time_t event_time(void)
Definition: events.c:647
#define DEF_VERIFY_POS_TRY
Definition: mail_params.h:2803
const char * make_verify_sender_addr(void)
#define MAIL_ATTR_ADDR_STATUS
Definition: mail_proto.h:150
void post_mail_fopen_async(const char *sender, const char *recipient, int source_class, int trace_flags, int utf8_flags, VSTRING *queue_id, void(*notify)(VSTREAM *, void *), void *context)
Definition: post_mail.c:381
#define DICT_CACHE_FLAG_STATISTICS
Definition: dict_cache.h:36
int var_verify_neg_cache
Definition: mail_params.c:328
#define VAR_VERIFY_SENDER
Definition: mail_params.h:2822
#define NEGATIVE_REFRESH_NEEDED(addr_status, updated)
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
MAIL_VERSION_STAMP_DECLARE
Definition: verify.c:723
int var_verify_scan_cache
Definition: verify.c:270
#define CA_MAIL_SERVER_SOLITARY
Definition: mail_server.h:69
char * split_at(char *string, int delimiter)
Definition: split_at.c:53
int dict_cache_update(DICT_CACHE *cp, const char *cache_key, const char *cache_val)
Definition: dict_cache.c:301
DICT_CACHE * dict_cache_open(const char *dbname, int open_flags, int dict_flags)
Definition: dict_cache.c:621
#define DEL_RCPT_STAT_OK
#define attr_scan
Definition: attr.h:111
#define DEL_RCPT_STAT_DEFER
#define VRFY_STAT_OK
Definition: verify_clnt.h:33
#define ATTR_FLAG_MORE
Definition: attr.h:101
#define SEND_ATTR_STR(name, val)
Definition: attr.h:64
#define DEF_VERIFY_MAP
Definition: mail_params.h:2795
#define DEL_REQ_FLAG_MTA_VRFY
#define VAR_VERIFY_MAP
Definition: mail_params.h:2794
#define VRFY_STAT_BAD
Definition: verify_clnt.h:35
int var_verify_neg_try
Definition: verify.c:269
#define VAR_VERIFY_POS_EXP
Definition: mail_params.h:2798
#define VAR_VERIFY_POS_TRY
Definition: mail_params.h:2802
#define CA_MAIL_SERVER_PRE_INIT(v)
Definition: mail_server.h:64
#define RECV_ATTR_STR(name, val)
Definition: attr.h:72
#define ATTR_FLAG_STRICT
Definition: attr.h:103
void msg_info(const char *fmt,...)
Definition: msg.c:199
void dict_cache_control(DICT_CACHE *cp,...)
Definition: dict_cache.c:538