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