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