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