1 /* $NetBSD: trivial-rewrite.c,v 1.6 2026/05/09 18:49:21 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* trivial-rewrite 8 6 /* SUMMARY 7 /* Postfix address rewriting and resolving daemon 8 /* SYNOPSIS 9 /* \fBtrivial-rewrite\fR [generic Postfix daemon options] 10 /* DESCRIPTION 11 /* The \fBtrivial-rewrite\fR(8) daemon processes three types of client 12 /* service requests: 13 /* .IP "\fBrewrite \fIcontext address\fR" 14 /* Rewrite an address to standard form, according to the 15 /* address rewriting context: 16 /* .RS 17 /* .IP \fBlocal\fR 18 /* Append the domain names specified with \fB$myorigin\fR or 19 /* \fB$mydomain\fR to incomplete addresses; do \fBswap_bangpath\fR 20 /* and \fBallow_percent_hack\fR processing as described below, and 21 /* strip source routed addresses (\fI@site,@site:user@domain\fR) 22 /* to \fIuser@domain\fR form. 23 /* .IP \fBremote\fR 24 /* Append the domain name specified with 25 /* \fB$remote_header_rewrite_domain\fR to incomplete 26 /* addresses. Otherwise the result is identical to that of 27 /* the \fBlocal\fR address rewriting context. This prevents 28 /* Postfix from appending the local domain to spam from poorly 29 /* written remote clients. 30 /* .RE 31 /* .IP "\fBresolve \fIsender\fR \fIaddress\fR" 32 /* Resolve the address to a (\fItransport\fR, \fInexthop\fR, 33 /* \fIrecipient\fR, \fIflags\fR) quadruple. The meaning of 34 /* the results is as follows: 35 /* .RS 36 /* .IP \fItransport\fR 37 /* The delivery agent to use. This is the first field of an entry 38 /* in the \fBmaster.cf\fR file. 39 /* .IP \fInexthop\fR 40 /* The host to send to and optional delivery method information. 41 /* .IP \fIrecipient\fR 42 /* The envelope recipient address that is passed on to \fInexthop\fR. 43 /* .IP \fIflags\fR 44 /* The address class, whether the address requires relaying, 45 /* whether the address has problems, and whether the request failed. 46 /* .RE 47 /* .IP "\fBverify \fIsender\fR \fIaddress\fR" 48 /* Resolve the address for address verification purposes. 49 /* SERVER PROCESS MANAGEMENT 50 /* .ad 51 /* .fi 52 /* The \fBtrivial-rewrite\fR(8) servers run under control by 53 /* the Postfix master(8) 54 /* server. Each server can handle multiple simultaneous connections. 55 /* When all servers are busy while a client connects, the master 56 /* creates a new server process, provided that the trivial-rewrite 57 /* server process limit is not exceeded. 58 /* Each trivial-rewrite server terminates after 59 /* serving at least \fB$max_use\fR clients of after \fB$max_idle\fR 60 /* seconds of idle time. 61 /* STANDARDS 62 /* .ad 63 /* .fi 64 /* None. The command does not interact with the outside world. 65 /* SECURITY 66 /* .ad 67 /* .fi 68 /* The \fBtrivial-rewrite\fR(8) daemon is not security sensitive. 69 /* By default, this daemon does not talk to remote or local users. 70 /* It can run at a fixed low privilege in a chrooted environment. 71 /* DIAGNOSTICS 72 /* Problems and transactions are logged to \fBsyslogd\fR(8) 73 /* or \fBpostlogd\fR(8). 74 /* CONFIGURATION PARAMETERS 75 /* .ad 76 /* .fi 77 /* On busy mail systems a long time may pass before a \fBmain.cf\fR 78 /* change affecting \fBtrivial-rewrite\fR(8) is picked up. Use the command 79 /* "\fBpostfix reload\fR" to speed up a change. 80 /* 81 /* The text below provides only a parameter summary. See 82 /* \fBpostconf\fR(5) for more details including examples. 83 /* COMPATIBILITY CONTROLS 84 /* .ad 85 /* .fi 86 /* .IP "\fBresolve_dequoted_address (yes)\fR" 87 /* Resolve a recipient address safely instead of correctly, by 88 /* looking inside quotes. 89 /* .PP 90 /* Available with Postfix version 2.1 and later: 91 /* .IP "\fBresolve_null_domain (no)\fR" 92 /* Resolve an address that ends in the "@" null domain as if the 93 /* local hostname were specified, instead of rejecting the address as 94 /* invalid. 95 /* .PP 96 /* Available with Postfix version 2.3 and later: 97 /* .IP "\fBresolve_numeric_domain (no)\fR" 98 /* Resolve "user@ipaddress" as "user@[ipaddress]", instead of 99 /* rejecting the address as invalid. 100 /* .PP 101 /* Available with Postfix version 2.5 and later: 102 /* .IP "\fBallow_min_user (no)\fR" 103 /* Allow a sender or recipient address to have `-' as the first 104 /* character. 105 /* ADDRESS REWRITING CONTROLS 106 /* .ad 107 /* .fi 108 /* .IP "\fBmyorigin ($myhostname)\fR" 109 /* The domain name that locally-posted mail appears to come 110 /* from, and that locally posted mail is delivered to. 111 /* .IP "\fBallow_percent_hack (yes)\fR" 112 /* Enable the rewriting of the form "user%domain" to "user@domain". 113 /* .IP "\fBappend_at_myorigin (yes)\fR" 114 /* With locally submitted mail, append the string "@$myorigin" to mail 115 /* addresses without domain information. 116 /* .IP "\fBappend_dot_mydomain (Postfix >= 3.0: no, Postfix < 3.0: yes)\fR" 117 /* With locally submitted mail, append the string ".$mydomain" to 118 /* addresses that have no ".domain" information. 119 /* .IP "\fBrecipient_delimiter (empty)\fR" 120 /* The set of characters that can separate an email address 121 /* localpart, user name, or a .forward file name from its extension. 122 /* .IP "\fBswap_bangpath (yes)\fR" 123 /* Enable the rewriting of "site!user" into "user@site". 124 /* .PP 125 /* Available in Postfix 2.2 and later: 126 /* .IP "\fBremote_header_rewrite_domain (empty)\fR" 127 /* Rewrite or add message headers in mail from remote clients if 128 /* the remote_header_rewrite_domain parameter value is non-empty, 129 /* updating incomplete addresses with the domain specified in the 130 /* remote_header_rewrite_domain parameter, and adding missing headers. 131 /* ROUTING CONTROLS 132 /* .ad 133 /* .fi 134 /* The following is applicable to Postfix version 2.0 and later. 135 /* Earlier versions do not have support for: virtual_transport, 136 /* relay_transport, virtual_alias_domains, virtual_mailbox_domains 137 /* or proxy_interfaces. 138 /* .IP "\fBlocal_transport (local:$myhostname)\fR" 139 /* The default mail delivery transport and next-hop destination 140 /* for final delivery to domains listed with mydestination, and for 141 /* [ipaddress] destinations that match $inet_interfaces or $proxy_interfaces. 142 /* .IP "\fBvirtual_transport (virtual)\fR" 143 /* The default mail delivery transport and next-hop destination for 144 /* final delivery to domains listed with $virtual_mailbox_domains. 145 /* .IP "\fBrelay_transport (relay)\fR" 146 /* The default mail delivery transport and next-hop destination for 147 /* the relay domain address class: recipient domains that match 148 /* $relay_domains. 149 /* .IP "\fBdefault_transport (smtp)\fR" 150 /* The default mail delivery transport and next-hop destination for 151 /* the default domain class: recipient domains that do not match 152 /* $mydestination, $inet_interfaces, 153 /* $proxy_interfaces, $virtual_alias_domains, $virtual_mailbox_domains, 154 /* or $relay_domains. 155 /* .IP "\fBparent_domain_matches_subdomains (see 'postconf -d' output)\fR" 156 /* A list of Postfix features where the pattern "example.com" also 157 /* matches subdomains of example.com, 158 /* instead of requiring an explicit ".example.com" pattern. 159 /* .IP "\fBrelayhost (empty)\fR" 160 /* The next-hop destination(s) for non-local mail; takes precedence 161 /* over non-local domains in recipient addresses. 162 /* .IP "\fBtransport_maps (empty)\fR" 163 /* Optional lookup tables with mappings from recipient address to 164 /* (message delivery transport, next-hop destination). 165 /* .PP 166 /* Available in Postfix version 2.3 and later: 167 /* .IP "\fBsender_dependent_relayhost_maps (empty)\fR" 168 /* A sender-dependent override for the global relayhost parameter 169 /* setting. 170 /* .PP 171 /* Available in Postfix version 2.5 and later: 172 /* .IP "\fBempty_address_relayhost_maps_lookup_key (<>)\fR" 173 /* The sender_dependent_relayhost_maps search string that will be 174 /* used instead of the null sender address. 175 /* .PP 176 /* Available in Postfix version 2.7 and later: 177 /* .IP "\fBempty_address_default_transport_maps_lookup_key (<>)\fR" 178 /* The sender_dependent_default_transport_maps search string that 179 /* will be used instead of the null sender address. 180 /* .IP "\fBsender_dependent_default_transport_maps (empty)\fR" 181 /* A sender-dependent override for the global default_transport 182 /* parameter setting. 183 /* ADDRESS VERIFICATION CONTROLS 184 /* .ad 185 /* .fi 186 /* Postfix version 2.1 introduces sender and recipient address verification. 187 /* This feature is implemented by sending probe email messages that 188 /* are not actually delivered. 189 /* By default, address verification probes use the same route 190 /* as regular mail. To override specific aspects of message 191 /* routing for address verification probes, specify one or more 192 /* of the following: 193 /* .IP "\fBaddress_verify_local_transport ($local_transport)\fR" 194 /* Overrides the local_transport parameter setting for address 195 /* verification probes. 196 /* .IP "\fBaddress_verify_virtual_transport ($virtual_transport)\fR" 197 /* Overrides the virtual_transport parameter setting for address 198 /* verification probes. 199 /* .IP "\fBaddress_verify_relay_transport ($relay_transport)\fR" 200 /* Overrides the relay_transport parameter setting for address 201 /* verification probes. 202 /* .IP "\fBaddress_verify_default_transport ($default_transport)\fR" 203 /* Overrides the default_transport parameter setting for address 204 /* verification probes. 205 /* .IP "\fBaddress_verify_relayhost ($relayhost)\fR" 206 /* Overrides the relayhost parameter setting for address verification 207 /* probes. 208 /* .IP "\fBaddress_verify_transport_maps ($transport_maps)\fR" 209 /* Overrides the transport_maps parameter setting for address verification 210 /* probes. 211 /* .PP 212 /* Available in Postfix version 2.3 and later: 213 /* .IP "\fBaddress_verify_sender_dependent_relayhost_maps ($sender_dependent_relayhost_maps)\fR" 214 /* Overrides the sender_dependent_relayhost_maps parameter setting for address 215 /* verification probes. 216 /* .PP 217 /* Available in Postfix version 2.7 and later: 218 /* .IP "\fBaddress_verify_sender_dependent_default_transport_maps ($sender_dependent_default_transport_maps)\fR" 219 /* Overrides the sender_dependent_default_transport_maps parameter 220 /* setting for address verification probes. 221 /* MISCELLANEOUS CONTROLS 222 /* .ad 223 /* .fi 224 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR" 225 /* The default location of the Postfix main.cf and master.cf 226 /* configuration files. 227 /* .IP "\fBdaemon_timeout (18000s)\fR" 228 /* How much time a Postfix daemon process may take to handle a 229 /* request before it is terminated by a built-in watchdog timer. 230 /* .IP "\fBempty_address_recipient (MAILER-DAEMON)\fR" 231 /* The recipient of mail addressed to the null address. 232 /* .IP "\fBipc_timeout (3600s)\fR" 233 /* The time limit for sending or receiving information over an internal 234 /* communication channel. 235 /* .IP "\fBmax_idle (100s)\fR" 236 /* The maximum amount of time that an idle Postfix daemon process waits 237 /* for an incoming connection before terminating voluntarily. 238 /* .IP "\fBmax_use (100)\fR" 239 /* The maximal number of incoming connections that a Postfix daemon 240 /* process will service before terminating voluntarily. 241 /* .IP "\fBrelocated_maps (empty)\fR" 242 /* Optional lookup tables with new contact information for users or 243 /* domains that no longer exist. 244 /* .IP "\fBprocess_id (read-only)\fR" 245 /* The process ID of a Postfix command or daemon process. 246 /* .IP "\fBprocess_name (read-only)\fR" 247 /* The process name of a Postfix command or daemon process. 248 /* .IP "\fBqueue_directory (see 'postconf -d' output)\fR" 249 /* The location of the Postfix top-level queue directory. 250 /* .IP "\fBshow_user_unknown_table_name (yes)\fR" 251 /* Display the name of the recipient table in the "User unknown" 252 /* responses. 253 /* .IP "\fBsyslog_facility (mail)\fR" 254 /* The syslog facility of Postfix logging. 255 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR" 256 /* A prefix that is prepended to the process name in syslog 257 /* records, so that, for example, "smtpd" becomes "prefix/smtpd". 258 /* .PP 259 /* Available in Postfix version 2.0 and later: 260 /* .IP "\fBhelpful_warnings (yes)\fR" 261 /* Log warnings about problematic configuration settings, and provide 262 /* helpful suggestions. 263 /* .PP 264 /* Available in Postfix 3.3 and later: 265 /* .IP "\fBservice_name (read-only)\fR" 266 /* The master.cf service name of a Postfix daemon process. 267 /* SEE ALSO 268 /* postconf(5), configuration parameters 269 /* transport(5), transport table format 270 /* relocated(5), format of the "user has moved" table 271 /* master(8), process manager 272 /* postlogd(8), Postfix logging 273 /* syslogd(8), system logging 274 /* README FILES 275 /* .ad 276 /* .fi 277 /* Use "\fBpostconf readme_directory\fR" or 278 /* "\fBpostconf html_directory\fR" to locate this information. 279 /* .na 280 /* .nf 281 /* ADDRESS_CLASS_README, Postfix address classes howto 282 /* ADDRESS_VERIFICATION_README, Postfix address verification 283 /* LICENSE 284 /* .ad 285 /* .fi 286 /* The Secure Mailer license must be distributed with this software. 287 /* AUTHOR(S) 288 /* Wietse Venema 289 /* IBM T.J. Watson Research 290 /* P.O. Box 704 291 /* Yorktown Heights, NY 10598, USA 292 /* 293 /* Wietse Venema 294 /* Google, Inc. 295 /* 111 8th Avenue 296 /* New York, NY 10011, USA 297 /*--*/ 298 299 /* System library. */ 300 301 #include <sys_defs.h> 302 #include <unistd.h> 303 #include <stdlib.h> 304 #include <string.h> 305 306 /* Utility library. */ 307 308 #include <msg.h> 309 #include <vstring.h> 310 #include <vstream.h> 311 #include <vstring_vstream.h> 312 #include <split_at.h> 313 #include <stringops.h> 314 #include <dict.h> 315 #include <events.h> 316 317 /* Global library. */ 318 319 #include <mail_params.h> 320 #include <mail_version.h> 321 #include <mail_proto.h> 322 #include <resolve_local.h> 323 #include <mail_conf.h> 324 #include <resolve_clnt.h> 325 #include <rewrite_clnt.h> 326 #include <tok822.h> 327 #include <mail_addr.h> 328 329 /* Multi server skeleton. */ 330 331 #include <mail_server.h> 332 333 /* Application-specific. */ 334 335 #include <trivial-rewrite.h> 336 #include <transport.h> 337 338 static VSTRING *command; 339 340 /* 341 * Tunable parameters. 342 */ 343 char *var_transport_maps; 344 bool var_swap_bangpath; 345 bool var_append_dot_mydomain; 346 bool var_append_at_myorigin; 347 bool var_percent_hack; 348 char *var_local_transport; 349 char *var_virt_transport; 350 char *var_relay_transport; 351 bool var_resolve_dequoted; 352 char *var_virt_alias_maps; /* XXX virtual_alias_domains */ 353 char *var_virt_mailbox_maps; /* XXX virtual_mailbox_domains */ 354 char *var_virt_alias_doms; 355 char *var_virt_mailbox_doms; 356 char *var_relocated_maps; 357 bool var_enb_relocated_pfx; 358 char *var_def_transport; 359 char *var_snd_def_xport_maps; 360 char *var_empty_addr; 361 bool var_show_unk_rcpt_table; 362 bool var_resolve_nulldom; 363 char *var_remote_rwr_domain; 364 char *var_snd_relay_maps; 365 char *var_null_relay_maps_key; 366 char *var_null_def_xport_maps_key; 367 bool var_resolve_num_dom; 368 bool var_allow_min_user; 369 370 /* 371 * Shadow personality for address verification. 372 */ 373 char *var_vrfy_xport_maps; 374 char *var_vrfy_local_xport; 375 char *var_vrfy_virt_xport; 376 char *var_vrfy_relay_xport; 377 char *var_vrfy_def_xport; 378 char *var_vrfy_snd_def_xport_maps; 379 char *var_vrfy_relayhost; 380 char *var_vrfy_relay_maps; 381 382 /* 383 * Different resolver personalities depending on the kind of request. 384 */ 385 RES_CONTEXT resolve_regular = { 386 VAR_LOCAL_TRANSPORT, &var_local_transport, 387 VAR_VIRT_TRANSPORT, &var_virt_transport, 388 VAR_RELAY_TRANSPORT, &var_relay_transport, 389 VAR_DEF_TRANSPORT, &var_def_transport, 390 VAR_SND_DEF_XPORT_MAPS, &var_snd_def_xport_maps, 0, 391 VAR_RELAYHOST, &var_relayhost, 392 VAR_SND_RELAY_MAPS, &var_snd_relay_maps, 0, 393 VAR_TRANSPORT_MAPS, &var_transport_maps, 0 394 }; 395 396 RES_CONTEXT resolve_verify = { 397 VAR_VRFY_LOCAL_XPORT, &var_vrfy_local_xport, 398 VAR_VRFY_VIRT_XPORT, &var_vrfy_virt_xport, 399 VAR_VRFY_RELAY_XPORT, &var_vrfy_relay_xport, 400 VAR_VRFY_DEF_XPORT, &var_vrfy_def_xport, 401 VAR_VRFY_SND_DEF_XPORT_MAPS, &var_vrfy_snd_def_xport_maps, 0, 402 VAR_VRFY_RELAYHOST, &var_vrfy_relayhost, 403 VAR_VRFY_RELAY_MAPS, &var_vrfy_relay_maps, 0, 404 VAR_VRFY_XPORT_MAPS, &var_vrfy_xport_maps, 0 405 }; 406 407 /* 408 * Connection management. When file-based lookup tables change we should 409 * restart at our convenience, but avoid client read errors. We restart 410 * rather than reopen, because the process may be chrooted (and if it isn't 411 * we still need code that handles the chrooted case anyway). 412 * 413 * Three variants are implemented. Only one should be used. 414 * 415 * ifdef DETACH_AND_ASK_CLIENTS_TO_RECONNECT 416 * 417 * This code detaches the trivial-rewrite process from the master, stops 418 * accepting new clients, and handles established clients in the background, 419 * asking them to reconnect the next time they send a request. The master 420 * creates a new process that accepts connections. This is reasonably safe 421 * because the number of trivial-rewrite server processes is small compared 422 * to the number of trivial-rewrite client processes. The few extra 423 * background processes should not make a difference in Postfix's footprint. 424 * However, once a daemon detaches from the master, its exit status will be 425 * lost, and abnormal termination may remain undetected. Timely restart is 426 * achieved by checking the table changed status every 10 seconds or so 427 * before responding to a client request. 428 * 429 * ifdef CHECK_TABLE_STATS_PERIODICALLY 430 * 431 * This code runs every 10 seconds and terminates the process when lookup 432 * tables have changed. This is subject to race conditions when established 433 * clients send a request while the server exits; those clients may read EOF 434 * instead of a server reply. If the experience with the oldest option 435 * (below) is anything to go by, however, then this is unlikely to be a 436 * problem during real deployment. 437 * 438 * ifdef CHECK_TABLE_STATS_BEFORE_ACCEPT 439 * 440 * This is the old code. It checks the table changed status when a new client 441 * connects (i.e. before the server calls accept()), and terminates 442 * immediately. This is invisible for the connecting client, but is subject 443 * to race conditions when established clients send a request while the 444 * server exits; those clients may read EOF instead of a server reply. This 445 * has, however, not been a problem in real deployment. With the old code, 446 * timely restart is achieved by setting the ipc_ttl parameter to 60 447 * seconds, so that the table change status is checked several times a 448 * minute. 449 */ 450 int server_flags; 451 452 /* 453 * Define exactly one of these. 454 */ 455 /* #define DETACH_AND_ASK_CLIENTS_TO_RECONNECT /* correct and complex */ 456 #define CHECK_TABLE_STATS_PERIODICALLY /* quick */ 457 /* #define CHECK_TABLE_STATS_BEFORE_ACCEPT /* slow */ 458 459 /* rewrite_service - read request and send reply */ 460 461 static void rewrite_service(VSTREAM *stream, char *unused_service, char **argv) 462 { 463 int status = -1; 464 465 #ifdef DETACH_AND_ASK_CLIENTS_TO_RECONNECT 466 static time_t last; 467 time_t now; 468 const char *table; 469 470 #endif 471 472 /* 473 * Sanity check. This service takes no command-line arguments. 474 */ 475 if (argv[0]) 476 msg_fatal("unexpected command-line argument: %s", argv[0]); 477 478 /* 479 * Client connections are long-lived. Be sure to refesh timely. 480 */ 481 #ifdef DETACH_AND_ASK_CLIENTS_TO_RECONNECT 482 if (server_flags == 0 && (now = event_time()) - last > 10) { 483 if ((table = dict_changed_name()) != 0) { 484 msg_info("table %s has changed -- restarting", table); 485 if (multi_server_drain() == 0) 486 server_flags = 1; 487 } 488 last = now; 489 } 490 #endif 491 492 /* 493 * This routine runs whenever a client connects to the UNIX-domain socket 494 * dedicated to address rewriting. All connection-management stuff is 495 * handled by the common code in multi_server.c. 496 */ 497 if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE, 498 RECV_ATTR_STR(MAIL_ATTR_REQ, command), 499 ATTR_TYPE_END) == 1) { 500 if (strcmp(vstring_str(command), REWRITE_ADDR) == 0) { 501 status = rewrite_proto(stream); 502 } else if (strcmp(vstring_str(command), RESOLVE_REGULAR) == 0) { 503 status = resolve_proto(&resolve_regular, stream); 504 } else if (strcmp(vstring_str(command), RESOLVE_VERIFY) == 0) { 505 status = resolve_proto(&resolve_verify, stream); 506 } else { 507 msg_warn("bad command %.30s", printable(vstring_str(command), '?')); 508 } 509 } 510 if (status < 0) 511 multi_server_disconnect(stream); 512 } 513 514 /* pre_accept - see if tables have changed */ 515 516 #ifdef CHECK_TABLE_STATS_BEFORE_ACCEPT 517 518 static void pre_accept(char *unused_name, char **unused_argv) 519 { 520 const char *table; 521 522 if ((table = dict_changed_name()) != 0) { 523 msg_info("table %s has changed -- restarting", table); 524 exit(0); 525 } 526 } 527 528 #endif 529 530 /* post_accept - announce our protocol name */ 531 532 static void post_accept(VSTREAM *stream, char *unused_name, char **unused_argv, 533 HTABLE *unused_attr) 534 { 535 536 /* 537 * Announce the protocol. 538 */ 539 attr_print(stream, ATTR_FLAG_NONE, 540 SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TRIVIAL), 541 ATTR_TYPE_END); 542 (void) vstream_fflush(stream); 543 } 544 545 static void check_table_stats(int unused_event, void *unused_context) 546 { 547 const char *table; 548 549 if ((table = dict_changed_name()) != 0) { 550 msg_info("table %s has changed -- restarting", table); 551 exit(0); 552 } 553 event_request_timer(check_table_stats, (void *) 0, 10); 554 } 555 556 /* pre_jail_init - initialize before entering chroot jail */ 557 558 static void pre_jail_init(char *unused_name, char **unused_argv) 559 { 560 command = vstring_alloc(100); 561 rewrite_init(); 562 resolve_init(); 563 if (*RES_PARAM_VALUE(resolve_regular.transport_maps)) 564 resolve_regular.transport_info = 565 transport_pre_init(resolve_regular.transport_maps_name, 566 RES_PARAM_VALUE(resolve_regular.transport_maps)); 567 if (*RES_PARAM_VALUE(resolve_verify.transport_maps)) 568 resolve_verify.transport_info = 569 transport_pre_init(resolve_verify.transport_maps_name, 570 RES_PARAM_VALUE(resolve_verify.transport_maps)); 571 if (*RES_PARAM_VALUE(resolve_regular.snd_relay_maps)) 572 resolve_regular.snd_relay_info = 573 maps_create(resolve_regular.snd_relay_maps_name, 574 RES_PARAM_VALUE(resolve_regular.snd_relay_maps), 575 DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX 576 | DICT_FLAG_NO_REGSUB | DICT_FLAG_UTF8_REQUEST); 577 if (*RES_PARAM_VALUE(resolve_verify.snd_relay_maps)) 578 resolve_verify.snd_relay_info = 579 maps_create(resolve_verify.snd_relay_maps_name, 580 RES_PARAM_VALUE(resolve_verify.snd_relay_maps), 581 DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX 582 | DICT_FLAG_NO_REGSUB | DICT_FLAG_UTF8_REQUEST); 583 if (*RES_PARAM_VALUE(resolve_regular.snd_def_xp_maps)) 584 resolve_regular.snd_def_xp_info = 585 maps_create(resolve_regular.snd_def_xp_maps_name, 586 RES_PARAM_VALUE(resolve_regular.snd_def_xp_maps), 587 DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX 588 | DICT_FLAG_NO_REGSUB | DICT_FLAG_UTF8_REQUEST); 589 if (*RES_PARAM_VALUE(resolve_verify.snd_def_xp_maps)) 590 resolve_verify.snd_def_xp_info = 591 maps_create(resolve_verify.snd_def_xp_maps_name, 592 RES_PARAM_VALUE(resolve_verify.snd_def_xp_maps), 593 DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX 594 | DICT_FLAG_NO_REGSUB | DICT_FLAG_UTF8_REQUEST); 595 } 596 597 /* post_jail_init - initialize after entering chroot jail */ 598 599 static void post_jail_init(char *unused_name, char **unused_argv) 600 { 601 if (resolve_regular.transport_info) 602 transport_post_init(resolve_regular.transport_info); 603 if (resolve_verify.transport_info) 604 transport_post_init(resolve_verify.transport_info); 605 check_table_stats(0, (void *) 0); 606 } 607 608 MAIL_VERSION_STAMP_DECLARE; 609 610 /* main - pass control to the multi-threaded skeleton code */ 611 612 int main(int argc, char **argv) 613 { 614 static const CONFIG_STR_TABLE str_table[] = { 615 VAR_TRANSPORT_MAPS, DEF_TRANSPORT_MAPS, &var_transport_maps, 0, 0, 616 VAR_LOCAL_TRANSPORT, DEF_LOCAL_TRANSPORT, &var_local_transport, 1, 0, 617 VAR_VIRT_TRANSPORT, DEF_VIRT_TRANSPORT, &var_virt_transport, 1, 0, 618 VAR_RELAY_TRANSPORT, DEF_RELAY_TRANSPORT, &var_relay_transport, 1, 0, 619 VAR_DEF_TRANSPORT, DEF_DEF_TRANSPORT, &var_def_transport, 1, 0, 620 VAR_VIRT_ALIAS_MAPS, DEF_VIRT_ALIAS_MAPS, &var_virt_alias_maps, 0, 0, 621 VAR_VIRT_ALIAS_DOMS, DEF_VIRT_ALIAS_DOMS, &var_virt_alias_doms, 0, 0, 622 VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps, 0, 0, 623 VAR_VIRT_MAILBOX_DOMS, DEF_VIRT_MAILBOX_DOMS, &var_virt_mailbox_doms, 0, 0, 624 VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0, 625 VAR_EMPTY_ADDR, DEF_EMPTY_ADDR, &var_empty_addr, 1, 0, 626 VAR_VRFY_XPORT_MAPS, DEF_VRFY_XPORT_MAPS, &var_vrfy_xport_maps, 0, 0, 627 VAR_VRFY_LOCAL_XPORT, DEF_VRFY_LOCAL_XPORT, &var_vrfy_local_xport, 1, 0, 628 VAR_VRFY_VIRT_XPORT, DEF_VRFY_VIRT_XPORT, &var_vrfy_virt_xport, 1, 0, 629 VAR_VRFY_RELAY_XPORT, DEF_VRFY_RELAY_XPORT, &var_vrfy_relay_xport, 1, 0, 630 VAR_VRFY_DEF_XPORT, DEF_VRFY_DEF_XPORT, &var_vrfy_def_xport, 1, 0, 631 VAR_VRFY_RELAYHOST, DEF_VRFY_RELAYHOST, &var_vrfy_relayhost, 0, 0, 632 VAR_REM_RWR_DOMAIN, DEF_REM_RWR_DOMAIN, &var_remote_rwr_domain, 0, 0, 633 VAR_SND_RELAY_MAPS, DEF_SND_RELAY_MAPS, &var_snd_relay_maps, 0, 0, 634 VAR_NULL_RELAY_MAPS_KEY, DEF_NULL_RELAY_MAPS_KEY, &var_null_relay_maps_key, 1, 0, 635 VAR_VRFY_RELAY_MAPS, DEF_VRFY_RELAY_MAPS, &var_vrfy_relay_maps, 0, 0, 636 VAR_SND_DEF_XPORT_MAPS, DEF_SND_DEF_XPORT_MAPS, &var_snd_def_xport_maps, 0, 0, 637 VAR_NULL_DEF_XPORT_MAPS_KEY, DEF_NULL_DEF_XPORT_MAPS_KEY, &var_null_def_xport_maps_key, 1, 0, 638 VAR_VRFY_SND_DEF_XPORT_MAPS, DEF_VRFY_SND_DEF_XPORT_MAPS, &var_vrfy_snd_def_xport_maps, 0, 0, 639 0, 640 }; 641 static const CONFIG_BOOL_TABLE bool_table[] = { 642 VAR_SWAP_BANGPATH, DEF_SWAP_BANGPATH, &var_swap_bangpath, 643 VAR_APP_AT_MYORIGIN, DEF_APP_AT_MYORIGIN, &var_append_at_myorigin, 644 VAR_PERCENT_HACK, DEF_PERCENT_HACK, &var_percent_hack, 645 VAR_RESOLVE_DEQUOTED, DEF_RESOLVE_DEQUOTED, &var_resolve_dequoted, 646 VAR_SHOW_UNK_RCPT_TABLE, DEF_SHOW_UNK_RCPT_TABLE, &var_show_unk_rcpt_table, 647 VAR_RESOLVE_NULLDOM, DEF_RESOLVE_NULLDOM, &var_resolve_nulldom, 648 VAR_RESOLVE_NUM_DOM, DEF_RESOLVE_NUM_DOM, &var_resolve_num_dom, 649 VAR_ALLOW_MIN_USER, DEF_ALLOW_MIN_USER, &var_allow_min_user, 650 0, 651 }; 652 static const CONFIG_NBOOL_TABLE nbool_table[] = { 653 VAR_APP_DOT_MYDOMAIN, DEF_APP_DOT_MYDOMAIN, &var_append_dot_mydomain, 654 VAR_ENB_RELOCATED_PFX, DEF_ENB_RELOCATED_PFX, &var_enb_relocated_pfx, 655 0, 656 }; 657 658 /* 659 * Fingerprint executables and core dumps. 660 */ 661 MAIL_VERSION_STAMP_ALLOCATE; 662 663 multi_server_main(argc, argv, rewrite_service, 664 CA_MAIL_SERVER_STR_TABLE(str_table), 665 CA_MAIL_SERVER_BOOL_TABLE(bool_table), 666 CA_MAIL_SERVER_NBOOL_TABLE(nbool_table), 667 CA_MAIL_SERVER_PRE_INIT(pre_jail_init), 668 CA_MAIL_SERVER_POST_INIT(post_jail_init), 669 #ifdef CHECK_TABLE_STATS_BEFORE_ACCEPT 670 CA_MAIL_SERVER_PRE_ACCEPT(pre_accept), 671 #endif 672 CA_MAIL_SERVER_POST_ACCEPT(post_accept), 673 0); 674 } 675