xref: /netbsd-src/external/ibm-public/postfix/dist/src/cleanup/cleanup_init.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /*	$NetBSD: cleanup_init.c,v 1.6 2020/03/18 19:05:15 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	cleanup_init 3
6 /* SUMMARY
7 /*	cleanup callable interface, initializations
8 /* SYNOPSIS
9 /*	#include "cleanup.h"
10 /*
11 /*	CONFIG_BOOL_TABLE cleanup_bool_table[];
12 /*
13 /*	CONFIG_INT_TABLE cleanup_int_table[];
14 /*
15 /*	CONFIG_BOOL_TABLE cleanup_bool_table[];
16 /*
17 /*	CONFIG_STR_TABLE cleanup_str_table[];
18 /*
19 /*	CONFIG_TIME_TABLE cleanup_time_table[];
20 /*
21 /*	void	cleanup_pre_jail(service_name, argv)
22 /*	char	*service_name;
23 /*	char	**argv;
24 /*
25 /*	void	cleanup_post_jail(service_name, argv)
26 /*	char	*service_name;
27 /*	char	**argv;
28 /*
29 /*	char	*cleanup_path;
30 /*	VSTRING	*cleanup_trace_path;
31 /*
32 /*	void	cleanup_all()
33 /*
34 /*	void	cleanup_sig(sigval)
35 /*	int	sigval;
36 /* DESCRIPTION
37 /*	This module implements a callable interface to the cleanup service
38 /*	for one-time initializations that must be done before any message
39 /*	processing can take place.
40 /*
41 /*	cleanup_{bool,int,str,time}_table[] specify configuration
42 /*	parameters that must be initialized before calling any functions
43 /*	in this module. These tables satisfy the interface as specified in
44 /*	single_service(3).
45 /*
46 /*	cleanup_pre_jail() and cleanup_post_jail() perform mandatory
47 /*	initializations before and after the process enters the optional
48 /*	chroot jail. These functions satisfy the interface as specified
49 /*	in single_service(3).
50 /*
51 /*	cleanup_path is either a null pointer or it is the name of a queue
52 /*	file that currently is being written. This information is used
53 /*	by cleanup_all() to remove incomplete files after a fatal error,
54 /*	or by cleanup_sig() after arrival of a SIGTERM signal.
55 /*
56 /*	cleanup_trace_path is either a null pointer or the pathname of a
57 /*	trace logfile with DSN SUCCESS notifications. This information is
58 /*	used to remove a trace file when the mail transaction is canceled.
59 /*
60 /*	cleanup_all() must be called in case of fatal error, in order
61 /*	to remove an incomplete queue file.
62 /*
63 /*	cleanup_sig() must be called in case of SIGTERM, in order
64 /*	to remove an incomplete queue file.
65 /* DIAGNOSTICS
66 /*	Problems and transactions are logged to \fBsyslogd\fR(8)
67 /*	or \fBpostlogd\fR(8).
68 /* SEE ALSO
69 /*	cleanup_api(3) cleanup callable interface, message processing
70 /* LICENSE
71 /* .ad
72 /* .fi
73 /*	The Secure Mailer license must be distributed with this software.
74 /* AUTHOR(S)
75 /*	Wietse Venema
76 /*	IBM T.J. Watson Research
77 /*	P.O. Box 704
78 /*	Yorktown Heights, NY 10598, USA
79 /*
80 /*	Wietse Venema
81 /*	Google, Inc.
82 /*	111 8th Avenue
83 /*	New York, NY 10011, USA
84 /*--*/
85 
86 /* System library. */
87 
88 #include <sys_defs.h>
89 #include <signal.h>
90 #include <string.h>
91 
92 /* Utility library. */
93 
94 #include <msg.h>
95 #include <iostuff.h>
96 #include <name_code.h>
97 #include <name_mask.h>
98 #include <stringops.h>
99 
100 /* Global library. */
101 
102 #include <mail_addr.h>
103 #include <mail_params.h>
104 #include <mail_version.h>		/* milter_macro_v */
105 #include <ext_prop.h>
106 #include <flush_clnt.h>
107 
108 /* Application-specific. */
109 
110 #include "cleanup.h"
111 
112  /*
113   * Global state: any queue files that we have open, so that the error
114   * handler can clean up in case of trouble.
115   */
116 char   *cleanup_path;			/* queue file name */
117 
118  /*
119   * Another piece of global state: pathnames of partial bounce or trace
120   * logfiles that need to be cleaned up when the cleanup request is aborted.
121   */
122 VSTRING *cleanup_trace_path;
123 
124  /*
125   * Tunable parameters.
126   */
127 int     var_hopcount_limit;		/* max mailer hop count */
128 char   *var_canonical_maps;		/* common canonical maps */
129 char   *var_send_canon_maps;		/* sender canonical maps */
130 char   *var_rcpt_canon_maps;		/* recipient canonical maps */
131 char   *var_canon_classes;		/* what to canonicalize */
132 char   *var_send_canon_classes;		/* what sender to canonicalize */
133 char   *var_rcpt_canon_classes;		/* what recipient to canonicalize */
134 char   *var_virt_alias_maps;		/* virtual alias maps */
135 char   *var_masq_domains;		/* masquerade domains */
136 char   *var_masq_exceptions;		/* users not masqueraded */
137 char   *var_header_checks;		/* primary header checks */
138 char   *var_mimehdr_checks;		/* mime header checks */
139 char   *var_nesthdr_checks;		/* nested header checks */
140 char   *var_body_checks;		/* any body checks */
141 int     var_dup_filter_limit;		/* recipient dup filter */
142 char   *var_empty_addr;			/* destination of bounced bounces */
143 int     var_delay_warn_time;		/* delay that triggers warning */
144 char   *var_prop_extension;		/* propagate unmatched extension */
145 char   *var_always_bcc;			/* big brother */
146 char   *var_rcpt_witheld;		/* recipients not disclosed */
147 bool    var_canon_env_rcpt;		/* canonicalize envelope recipient */
148 char   *var_masq_classes;		/* what to masquerade */
149 int     var_qattr_count_limit;		/* named attribute limit */
150 int     var_virt_recur_limit;		/* maximum virtual alias recursion */
151 int     var_virt_expan_limit;		/* maximum virtual alias expansion */
152 int     var_body_check_len;		/* when to stop body scan */
153 char   *var_send_bcc_maps;		/* sender auto-bcc maps */
154 char   *var_rcpt_bcc_maps;		/* recipient auto-bcc maps */
155 char   *var_remote_rwr_domain;		/* header-only surrogate */
156 char   *var_msg_reject_chars;		/* reject these characters */
157 char   *var_msg_strip_chars;		/* strip these characters */
158 int     var_verp_bounce_off;		/* don't verp the bounces */
159 int     var_milt_conn_time;		/* milter connect/handshake timeout */
160 int     var_milt_cmd_time;		/* milter command timeout */
161 int     var_milt_msg_time;		/* milter content timeout */
162 char   *var_milt_protocol;		/* Sendmail 8 milter protocol */
163 char   *var_milt_def_action;		/* default milter action */
164 char   *var_milt_daemon_name;		/* {daemon_name} macro value */
165 char   *var_milt_v;			/* {v} macro value */
166 char   *var_milt_conn_macros;		/* connect macros */
167 char   *var_milt_helo_macros;		/* HELO macros */
168 char   *var_milt_mail_macros;		/* MAIL FROM macros */
169 char   *var_milt_rcpt_macros;		/* RCPT TO macros */
170 char   *var_milt_data_macros;		/* DATA macros */
171 char   *var_milt_eoh_macros;		/* end-of-header macros */
172 char   *var_milt_eod_macros;		/* end-of-data macros */
173 char   *var_milt_unk_macros;		/* unknown command macros */
174 char   *var_cleanup_milters;		/* non-SMTP mail */
175 char   *var_milt_head_checks;		/* post-Milter header checks */
176 char   *var_milt_macro_deflts;		/* default macro settings */
177 int     var_auto_8bit_enc_hdr;		/* auto-detect 8bit encoding header */
178 int     var_always_add_hdrs;		/* always add missing headers */
179 int     var_virt_addrlen_limit;		/* stop exponential growth */
180 char   *var_hfrom_format;		/* header_from_format */
181 
182 const CONFIG_INT_TABLE cleanup_int_table[] = {
183     VAR_HOPCOUNT_LIMIT, DEF_HOPCOUNT_LIMIT, &var_hopcount_limit, 1, 0,
184     VAR_DUP_FILTER_LIMIT, DEF_DUP_FILTER_LIMIT, &var_dup_filter_limit, 0, 0,
185     VAR_QATTR_COUNT_LIMIT, DEF_QATTR_COUNT_LIMIT, &var_qattr_count_limit, 1, 0,
186     VAR_VIRT_RECUR_LIMIT, DEF_VIRT_RECUR_LIMIT, &var_virt_recur_limit, 1, 0,
187     VAR_VIRT_EXPAN_LIMIT, DEF_VIRT_EXPAN_LIMIT, &var_virt_expan_limit, 1, 0,
188     VAR_VIRT_ADDRLEN_LIMIT, DEF_VIRT_ADDRLEN_LIMIT, &var_virt_addrlen_limit, 1, 0,
189     VAR_BODY_CHECK_LEN, DEF_BODY_CHECK_LEN, &var_body_check_len, 0, 0,
190     0,
191 };
192 
193 const CONFIG_BOOL_TABLE cleanup_bool_table[] = {
194     VAR_VERP_BOUNCE_OFF, DEF_VERP_BOUNCE_OFF, &var_verp_bounce_off,
195     VAR_AUTO_8BIT_ENC_HDR, DEF_AUTO_8BIT_ENC_HDR, &var_auto_8bit_enc_hdr,
196     VAR_ALWAYS_ADD_HDRS, DEF_ALWAYS_ADD_HDRS, &var_always_add_hdrs,
197     0,
198 };
199 
200 const CONFIG_TIME_TABLE cleanup_time_table[] = {
201     VAR_DELAY_WARN_TIME, DEF_DELAY_WARN_TIME, &var_delay_warn_time, 0, 0,
202     VAR_MILT_CONN_TIME, DEF_MILT_CONN_TIME, &var_milt_conn_time, 1, 0,
203     VAR_MILT_CMD_TIME, DEF_MILT_CMD_TIME, &var_milt_cmd_time, 1, 0,
204     VAR_MILT_MSG_TIME, DEF_MILT_MSG_TIME, &var_milt_msg_time, 1, 0,
205     0,
206 };
207 
208 const CONFIG_STR_TABLE cleanup_str_table[] = {
209     VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0,
210     VAR_SEND_CANON_MAPS, DEF_SEND_CANON_MAPS, &var_send_canon_maps, 0, 0,
211     VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps, 0, 0,
212     VAR_CANON_CLASSES, DEF_CANON_CLASSES, &var_canon_classes, 1, 0,
213     VAR_SEND_CANON_CLASSES, DEF_SEND_CANON_CLASSES, &var_send_canon_classes, 1, 0,
214     VAR_RCPT_CANON_CLASSES, DEF_RCPT_CANON_CLASSES, &var_rcpt_canon_classes, 1, 0,
215     VAR_VIRT_ALIAS_MAPS, DEF_VIRT_ALIAS_MAPS, &var_virt_alias_maps, 0, 0,
216     VAR_MASQ_DOMAINS, DEF_MASQ_DOMAINS, &var_masq_domains, 0, 0,
217     VAR_EMPTY_ADDR, DEF_EMPTY_ADDR, &var_empty_addr, 1, 0,
218     VAR_MASQ_EXCEPTIONS, DEF_MASQ_EXCEPTIONS, &var_masq_exceptions, 0, 0,
219     VAR_HEADER_CHECKS, DEF_HEADER_CHECKS, &var_header_checks, 0, 0,
220     VAR_MIMEHDR_CHECKS, DEF_MIMEHDR_CHECKS, &var_mimehdr_checks, 0, 0,
221     VAR_NESTHDR_CHECKS, DEF_NESTHDR_CHECKS, &var_nesthdr_checks, 0, 0,
222     VAR_BODY_CHECKS, DEF_BODY_CHECKS, &var_body_checks, 0, 0,
223     VAR_PROP_EXTENSION, DEF_PROP_EXTENSION, &var_prop_extension, 0, 0,
224     VAR_ALWAYS_BCC, DEF_ALWAYS_BCC, &var_always_bcc, 0, 0,
225     VAR_RCPT_WITHELD, DEF_RCPT_WITHELD, &var_rcpt_witheld, 0, 0,
226     VAR_MASQ_CLASSES, DEF_MASQ_CLASSES, &var_masq_classes, 0, 0,
227     VAR_SEND_BCC_MAPS, DEF_SEND_BCC_MAPS, &var_send_bcc_maps, 0, 0,
228     VAR_RCPT_BCC_MAPS, DEF_RCPT_BCC_MAPS, &var_rcpt_bcc_maps, 0, 0,
229     VAR_REM_RWR_DOMAIN, DEF_REM_RWR_DOMAIN, &var_remote_rwr_domain, 0, 0,
230     VAR_MSG_REJECT_CHARS, DEF_MSG_REJECT_CHARS, &var_msg_reject_chars, 0, 0,
231     VAR_MSG_STRIP_CHARS, DEF_MSG_STRIP_CHARS, &var_msg_strip_chars, 0, 0,
232     VAR_MILT_PROTOCOL, DEF_MILT_PROTOCOL, &var_milt_protocol, 1, 0,
233     VAR_MILT_DEF_ACTION, DEF_MILT_DEF_ACTION, &var_milt_def_action, 1, 0,
234     VAR_MILT_DAEMON_NAME, DEF_MILT_DAEMON_NAME, &var_milt_daemon_name, 1, 0,
235     VAR_MILT_V, DEF_MILT_V, &var_milt_v, 1, 0,
236     VAR_MILT_CONN_MACROS, DEF_MILT_CONN_MACROS, &var_milt_conn_macros, 0, 0,
237     VAR_MILT_HELO_MACROS, DEF_MILT_HELO_MACROS, &var_milt_helo_macros, 0, 0,
238     VAR_MILT_MAIL_MACROS, DEF_MILT_MAIL_MACROS, &var_milt_mail_macros, 0, 0,
239     VAR_MILT_RCPT_MACROS, DEF_MILT_RCPT_MACROS, &var_milt_rcpt_macros, 0, 0,
240     VAR_MILT_DATA_MACROS, DEF_MILT_DATA_MACROS, &var_milt_data_macros, 0, 0,
241     VAR_MILT_EOH_MACROS, DEF_MILT_EOH_MACROS, &var_milt_eoh_macros, 0, 0,
242     VAR_MILT_EOD_MACROS, DEF_MILT_EOD_MACROS, &var_milt_eod_macros, 0, 0,
243     VAR_MILT_UNK_MACROS, DEF_MILT_UNK_MACROS, &var_milt_unk_macros, 0, 0,
244     VAR_CLEANUP_MILTERS, DEF_CLEANUP_MILTERS, &var_cleanup_milters, 0, 0,
245     VAR_MILT_HEAD_CHECKS, DEF_MILT_HEAD_CHECKS, &var_milt_head_checks, 0, 0,
246     VAR_MILT_MACRO_DEFLTS, DEF_MILT_MACRO_DEFLTS, &var_milt_macro_deflts, 0, 0,
247     VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
248     0,
249 };
250 
251  /*
252   * Mappings.
253   */
254 MAPS   *cleanup_comm_canon_maps;
255 MAPS   *cleanup_send_canon_maps;
256 MAPS   *cleanup_rcpt_canon_maps;
257 int     cleanup_comm_canon_flags;
258 int     cleanup_send_canon_flags;
259 int     cleanup_rcpt_canon_flags;
260 MAPS   *cleanup_header_checks;
261 MAPS   *cleanup_mimehdr_checks;
262 MAPS   *cleanup_nesthdr_checks;
263 MAPS   *cleanup_body_checks;
264 MAPS   *cleanup_virt_alias_maps;
265 ARGV   *cleanup_masq_domains;
266 STRING_LIST *cleanup_masq_exceptions;
267 int     cleanup_masq_flags;
268 MAPS   *cleanup_send_bcc_maps;
269 MAPS   *cleanup_rcpt_bcc_maps;
270 
271  /*
272   * Character filters.
273   */
274 VSTRING *cleanup_reject_chars;
275 VSTRING *cleanup_strip_chars;
276 
277  /*
278   * Address extension propagation restrictions.
279   */
280 int     cleanup_ext_prop_mask;
281 
282  /*
283   * Milter support.
284   */
285 MILTERS *cleanup_milters;
286 
287  /*
288   * From: header format.
289   */
290 int     hfrom_format_code;
291 
292 /* cleanup_all - callback for the runtime error handler */
293 
294 void    cleanup_all(void)
295 {
296     cleanup_sig(0);
297 }
298 
299 /* cleanup_sig - callback for the SIGTERM handler */
300 
301 void    cleanup_sig(int sig)
302 {
303 
304     /*
305      * msg_fatal() is safe against calling itself recursively, but signals
306      * need extra safety.
307      *
308      * XXX While running as a signal handler, can't ask the memory manager to
309      * release VSTRING storage.
310      */
311     if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
312 	if (cleanup_trace_path) {
313 	    (void) REMOVE(vstring_str(cleanup_trace_path));
314 	    cleanup_trace_path = 0;
315 	}
316 	if (cleanup_path) {
317 	    (void) REMOVE(cleanup_path);
318 	    cleanup_path = 0;
319 	}
320 	if (sig)
321 	    _exit(sig);
322     }
323 }
324 
325 /* cleanup_pre_jail - initialize before entering the chroot jail */
326 
327 void    cleanup_pre_jail(char *unused_name, char **unused_argv)
328 {
329     static const NAME_MASK send_canon_class_table[] = {
330 	CANON_CLASS_ENV_FROM, CLEANUP_CANON_FLAG_ENV_FROM,
331 	CANON_CLASS_HDR_FROM, CLEANUP_CANON_FLAG_HDR_FROM,
332 	0,
333     };
334     static const NAME_MASK rcpt_canon_class_table[] = {
335 	CANON_CLASS_ENV_RCPT, CLEANUP_CANON_FLAG_ENV_RCPT,
336 	CANON_CLASS_HDR_RCPT, CLEANUP_CANON_FLAG_HDR_RCPT,
337 	0,
338     };
339     static const NAME_MASK canon_class_table[] = {
340 	CANON_CLASS_ENV_FROM, CLEANUP_CANON_FLAG_ENV_FROM,
341 	CANON_CLASS_ENV_RCPT, CLEANUP_CANON_FLAG_ENV_RCPT,
342 	CANON_CLASS_HDR_FROM, CLEANUP_CANON_FLAG_HDR_FROM,
343 	CANON_CLASS_HDR_RCPT, CLEANUP_CANON_FLAG_HDR_RCPT,
344 	0,
345     };
346     static const NAME_MASK masq_class_table[] = {
347 	MASQ_CLASS_ENV_FROM, CLEANUP_MASQ_FLAG_ENV_FROM,
348 	MASQ_CLASS_ENV_RCPT, CLEANUP_MASQ_FLAG_ENV_RCPT,
349 	MASQ_CLASS_HDR_FROM, CLEANUP_MASQ_FLAG_HDR_FROM,
350 	MASQ_CLASS_HDR_RCPT, CLEANUP_MASQ_FLAG_HDR_RCPT,
351 	0,
352     };
353 
354     if (*var_canonical_maps)
355 	cleanup_comm_canon_maps =
356 	    maps_create(VAR_CANONICAL_MAPS, var_canonical_maps,
357 			DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX
358 			| DICT_FLAG_UTF8_REQUEST);
359     if (*var_send_canon_maps)
360 	cleanup_send_canon_maps =
361 	    maps_create(VAR_SEND_CANON_MAPS, var_send_canon_maps,
362 			DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX
363 			| DICT_FLAG_UTF8_REQUEST);
364     if (*var_rcpt_canon_maps)
365 	cleanup_rcpt_canon_maps =
366 	    maps_create(VAR_RCPT_CANON_MAPS, var_rcpt_canon_maps,
367 			DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX
368 			| DICT_FLAG_UTF8_REQUEST);
369     if (*var_virt_alias_maps)
370 	cleanup_virt_alias_maps = maps_create(VAR_VIRT_ALIAS_MAPS,
371 					      var_virt_alias_maps,
372 					      DICT_FLAG_LOCK
373 					      | DICT_FLAG_FOLD_FIX
374 					      | DICT_FLAG_UTF8_REQUEST);
375     if (*var_canon_classes)
376 	cleanup_comm_canon_flags =
377 	    name_mask(VAR_CANON_CLASSES, canon_class_table,
378 		      var_canon_classes);
379     if (*var_send_canon_classes)
380 	cleanup_send_canon_flags =
381 	    name_mask(VAR_CANON_CLASSES, send_canon_class_table,
382 		      var_send_canon_classes);
383     if (*var_rcpt_canon_classes)
384 	cleanup_rcpt_canon_flags =
385 	    name_mask(VAR_CANON_CLASSES, rcpt_canon_class_table,
386 		      var_rcpt_canon_classes);
387     if (*var_masq_domains)
388 	cleanup_masq_domains = argv_split(var_masq_domains, CHARS_COMMA_SP);
389     if (*var_header_checks)
390 	cleanup_header_checks =
391 	    maps_create(VAR_HEADER_CHECKS, var_header_checks, DICT_FLAG_LOCK);
392     if (*var_mimehdr_checks)
393 	cleanup_mimehdr_checks =
394 	    maps_create(VAR_MIMEHDR_CHECKS, var_mimehdr_checks, DICT_FLAG_LOCK);
395     if (*var_nesthdr_checks)
396 	cleanup_nesthdr_checks =
397 	    maps_create(VAR_NESTHDR_CHECKS, var_nesthdr_checks, DICT_FLAG_LOCK);
398     if (*var_body_checks)
399 	cleanup_body_checks =
400 	    maps_create(VAR_BODY_CHECKS, var_body_checks, DICT_FLAG_LOCK);
401     if (*var_masq_exceptions)
402 	cleanup_masq_exceptions =
403 	    string_list_init(VAR_MASQ_EXCEPTIONS, MATCH_FLAG_RETURN,
404 			     var_masq_exceptions);
405     if (*var_masq_classes)
406 	cleanup_masq_flags = name_mask(VAR_MASQ_CLASSES, masq_class_table,
407 				       var_masq_classes);
408     if (*var_send_bcc_maps)
409 	cleanup_send_bcc_maps =
410 	    maps_create(VAR_SEND_BCC_MAPS, var_send_bcc_maps,
411 			DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX
412 			| DICT_FLAG_UTF8_REQUEST);
413     if (*var_rcpt_bcc_maps)
414 	cleanup_rcpt_bcc_maps =
415 	    maps_create(VAR_RCPT_BCC_MAPS, var_rcpt_bcc_maps,
416 			DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX
417 			| DICT_FLAG_UTF8_REQUEST);
418     if (*var_cleanup_milters)
419 	cleanup_milters = milter_create(var_cleanup_milters,
420 					var_milt_conn_time,
421 					var_milt_cmd_time,
422 					var_milt_msg_time,
423 					var_milt_protocol,
424 					var_milt_def_action,
425 					var_milt_conn_macros,
426 					var_milt_helo_macros,
427 					var_milt_mail_macros,
428 					var_milt_rcpt_macros,
429 					var_milt_data_macros,
430 					var_milt_eoh_macros,
431 					var_milt_eod_macros,
432 					var_milt_unk_macros,
433 					var_milt_macro_deflts);
434 
435     flush_init();
436 }
437 
438 /* cleanup_post_jail - initialize after entering the chroot jail */
439 
440 void    cleanup_post_jail(char *unused_name, char **unused_argv)
441 {
442     static const NAME_CODE hfrom_format_table[] = {
443 	HFROM_FORMAT_NAME_STD, HFROM_FORMAT_CODE_STD,
444 	HFROM_FORMAT_NAME_OBS, HFROM_FORMAT_CODE_OBS,
445 	0, -1,
446     };
447 
448     /*
449      * Optionally set the file size resource limit. XXX This limits the
450      * message content to somewhat less than requested, because the total
451      * queue file size also includes envelope information. Unless people set
452      * really low limit, the difference is going to matter only when a queue
453      * file has lots of recipients.
454      */
455     if (ENFORCING_SIZE_LIMIT(var_message_limit))
456 	set_file_limit((off_t) var_message_limit);
457 
458     /*
459      * Control how unmatched extensions are propagated.
460      */
461     cleanup_ext_prop_mask =
462 	ext_prop_mask(VAR_PROP_EXTENSION, var_prop_extension);
463 
464     /*
465      * Setup the filters for characters that should be rejected, and for
466      * characters that should be removed.
467      */
468     if (*var_msg_reject_chars) {
469 	cleanup_reject_chars = vstring_alloc(strlen(var_msg_reject_chars));
470 	unescape(cleanup_reject_chars, var_msg_reject_chars);
471     }
472     if (*var_msg_strip_chars) {
473 	cleanup_strip_chars = vstring_alloc(strlen(var_msg_strip_chars));
474 	unescape(cleanup_strip_chars, var_msg_strip_chars);
475     }
476 
477     /*
478      * From: header formatting.
479      */
480     if ((hfrom_format_code = name_code(hfrom_format_table,
481 				NAME_CODE_FLAG_NONE, var_hfrom_format)) < 0)
482 	msg_fatal("invalid setting: %s = %s",
483 		  VAR_HFROM_FORMAT, var_hfrom_format);
484 }
485