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