Home | History | Annotate | Line # | Download | only in global
      1 /*	$NetBSD: mail_params.c,v 1.7 2026/05/09 18:49:16 christos Exp $	*/
      2 
      3 /*++
      4 /* NAME
      5 /*	mail_params 3
      6 /* SUMMARY
      7 /*	global mail configuration parameters
      8 /* SYNOPSIS
      9 /*	#include <mail_params.h>
     10 /*
     11 /*	char	*var_myhostname;
     12 /*	char	*var_mydomain;
     13 /*	char	*var_myorigin;
     14 /*	char	*var_mydest;
     15 /*	char	*var_relayhost;
     16 /*	char	*var_transit_origin;
     17 /*	char	*var_transit_dest;
     18 /*	char	*var_mail_name;
     19 /*	int	var_helpful_warnings;
     20 /*	char	*var_syslog_name;
     21 /*	char	*var_mail_owner;
     22 /*	uid_t	var_owner_uid;
     23 /*	gid_t	var_owner_gid;
     24 /*	char	*var_sgid_group;
     25 /*	gid_t	var_sgid_gid;
     26 /*	char	*var_default_privs;
     27 /*	uid_t	var_default_uid;
     28 /*	gid_t	var_default_gid;
     29 /*	char	*var_config_dir;
     30 /*	char	*var_daemon_dir;
     31 /*	char	*var_data_dir;
     32 /*	char	*var_command_dir;
     33 /*	char	*var_meta_dir;
     34 /*	char	*var_queue_dir;
     35 /*	char	*var_shlib_dir;
     36 /*	int	var_use_limit;
     37 /*	int	var_idle_limit;
     38 /*	int	var_event_drain;
     39 /*	int	var_bundle_rcpt;
     40 /*	char	*var_procname;
     41 /*	char	*var_servname;
     42 /*	int	var_pid;
     43 /*	int	var_ipc_timeout;
     44 /*	char	*var_pid_dir;
     45 /*	int	var_dont_remove;
     46 /*	char	*var_inet_interfaces;
     47 /*	char	*var_proxy_interfaces;
     48 /*	char	*var_inet_protocols;
     49 /*	char	*var_mynetworks;
     50 /*	char	*var_double_bounce_sender;
     51 /*	int	var_line_limit;
     52 /*	char	*var_alias_db_map;
     53 /*	long	var_message_limit;
     54 /*	char	*var_mail_release;
     55 /*	char	*var_mail_version;
     56 /*	int	var_ipc_idle_limit;
     57 /*	int	var_ipc_ttl_limit;
     58 /*	char	*var_db_type;
     59 /*	char	*var_cache_db_type;
     60 /*	char	*var_hash_queue_names;
     61 /*	int	var_hash_queue_depth;
     62 /*	int	var_trigger_timeout;
     63 /*	char	*var_rcpt_delim;
     64 /*	int	var_fork_tries;
     65 /*	int	var_fork_delay;
     66 /*	int	var_flock_tries;
     67 /*	int	var_flock_delay;
     68 /*	int	var_flock_stale;
     69 /*	int	var_disable_dns;
     70 /*	int	var_soft_bounce;
     71 /*	time_t	var_starttime;
     72 /*	int	var_ownreq_special;
     73 /*	int	var_daemon_timeout;
     74 /*	char	*var_syslog_facility;
     75 /*	char	*var_relay_domains;
     76 /*	char	*var_fflush_domains;
     77 /*	char	*var_mynetworks_style;
     78 /*	char	*var_verp_delims;
     79 /*	char	*var_verp_filter;
     80 /*	char	*var_par_dom_match;
     81 /*	char	*var_config_dirs;
     82 /*
     83 /*	int	var_inet_windowsize;
     84 /*	char	*var_import_environ;
     85 /*	char	*var_export_environ;
     86 /*	char	*var_debug_peer_list;
     87 /*	int	var_debug_peer_level;
     88 /*	int	var_in_flow_delay;
     89 /*	int	var_fault_inj_code;
     90 /*	char   *var_bounce_service;
     91 /*	char   *var_cleanup_service;
     92 /*	char   *var_defer_service;
     93 /*	char   *var_pickup_service;
     94 /*	char   *var_queue_service;
     95 /*	char   *var_rewrite_service;
     96 /*	char   *var_showq_service;
     97 /*	char   *var_error_service;
     98 /*	char   *var_flush_service;
     99 /*	char   *var_verify_service;
    100 /*	char   *var_trace_service;
    101 /*	char   *var_proxymap_service;
    102 /*	char   *var_proxywrite_service;
    103 /*	int	var_db_create_buf;
    104 /*	int	var_db_read_buf;
    105 /*	long	var_lmdb_map_size;
    106 /*	int	var_proc_limit;
    107 /*	int	var_mime_maxdepth;
    108 /*	int	var_mime_bound_len;
    109 /*	int	var_header_limit;
    110 /*	int	var_token_limit;
    111 /*	int	var_disable_mime_input;
    112 /*	int	var_disable_mime_oconv;
    113 /*	int     var_strict_8bitmime;
    114 /*	int     var_strict_7bit_hdrs;
    115 /*	int     var_strict_8bit_body;
    116 /*	int     var_strict_encoding;
    117 /*	int     var_verify_neg_cache;
    118 /*	int	var_oldlog_compat;
    119 /*	int	var_delay_max_res;
    120 /*	char	*var_int_filt_classes;
    121 /*	int	var_cyrus_sasl_authzid;
    122 /*
    123 /*	char	*var_multi_conf_dirs;
    124 /*	char	*var_multi_wrapper;
    125 /*	char	*var_multi_group;
    126 /*	char	*var_multi_name;
    127 /*	bool	var_multi_enable;
    128 /*	bool	var_long_queue_ids;
    129 /*	bool	var_daemon_open_fatal;
    130 /*	char	*var_dsn_filter;
    131 /*	int	var_smtputf8_enable;
    132 /*	int	var_strict_smtputf8;
    133 /*	char	*var_smtputf8_autoclass;
    134 /*	int	var_reqtls_enable;
    135 /*	int	var_tls_required_enable;
    136 /*	int     var_idna2003_compat;
    137 /*	char	*var_compatibility_level;
    138 /*	char	*var_drop_hdrs;
    139 /*	char	*var_info_log_addr_form;
    140 /*	bool	var_enable_orcpt;
    141 /*
    142 /*	void	mail_params_init()
    143 /*
    144 /*	const	char null_format_string[1];
    145 /*
    146 /*	long	compatibility_level;
    147 /*
    148 /*	int	warn_compat_break_app_dot_mydomain;
    149 /*	int	warn_compat_break_smtputf8_enable;
    150 /*	int	warn_compat_break_chroot;
    151 /*	int	warn_compat_break_relay_restrictions;
    152 /*
    153 /*	int	warn_compat_break_relay_domains;
    154 /*	int	warn_compat_break_flush_domains;
    155 /*	int	warn_compat_break_mynetworks_style;
    156 /*
    157 /*	int	warn_compat_break_smtpd_tls_fpt_dgst;
    158 /*	int	warn_compat_break_smtp_tls_fpt_dgst;
    159 /*	int	warn_compat_break_lmtp_tls_fpt_dgst;
    160 /*	int	warn_compat_relay_before_rcpt_checks;
    161 /*	int	warn_compat_respectful_logging;
    162 /*
    163 /*	char	*var_maillog_file;
    164 /*	char	*var_maillog_file_pfxs;
    165 /*	char	*var_maillog_file_comp;
    166 /*	char	*var_maillog_file_stamp;
    167 /*	char	*var_maillog_file_perms;
    168 /*	char	*var_postlog_service;
    169 /*
    170 /*	char	*var_dnssec_probe;
    171 /*	bool	var_relay_before_rcpt_checks;
    172 /*	bool	var_respectful_logging;
    173 /*	char	*var_known_tcp_ports;
    174 /*
    175 /*	char	*var_nbdb_level;
    176 /*	char	*var_nbdb_service;
    177 /*	char	*var_nbdb_cust_map;
    178 /*	bool	var_nbdb_log_redirect;
    179 /* DESCRIPTION
    180 /*	This module (actually the associated include file) defines
    181 /*	the names and defaults of all mail configuration parameters.
    182 /*
    183 /*	mail_params_init() initializes the built-in parameters listed above.
    184 /*	These parameters are relied upon by library routines, so they are
    185 /*	initialized globally so as to avoid hard-to-find errors due to
    186 /*	missing initialization. This routine must be called early, at
    187 /*	least before entering a chroot jail.
    188 /*
    189 /*	null_format_string is a workaround for gcc compilers that complain
    190 /*	about empty or null format strings.
    191 /*
    192 /*	The warn_compat_XXX variables enable warnings for the use
    193 /*	of legacy default settings after an incompatible change.
    194 /* DIAGNOSTICS
    195 /*	Fatal errors: out of memory; null system or domain name.
    196 /* LICENSE
    197 /* .ad
    198 /* .fi
    199 /*	The Secure Mailer license must be distributed with this software.
    200 /* AUTHOR(S)
    201 /*	Wietse Venema
    202 /*	IBM T.J. Watson Research
    203 /*	P.O. Box 704
    204 /*	Yorktown Heights, NY 10598, USA
    205 /*
    206 /*	Wietse Venema
    207 /*	Google, Inc.
    208 /*	111 8th Avenue
    209 /*	New York, NY 10011, USA
    210 /*
    211 /*	Wietse Venema
    212 /*	porcupine.org
    213 /*--*/
    214 
    215 /* System library. */
    216 
    217 #include <sys_defs.h>
    218 #include <unistd.h>
    219 #include <stdlib.h>
    220 #include <string.h>
    221 #include <pwd.h>
    222 #include <grp.h>
    223 #include <time.h>
    224 #include <ctype.h>
    225 
    226 /* Utility library. */
    227 
    228 #include <msg.h>
    229 #include <msg_syslog.h>
    230 #include <get_hostname.h>
    231 #include <valid_hostname.h>
    232 #include <stringops.h>
    233 #include <safe.h>
    234 #include <safe_open.h>
    235 #include <mymalloc.h>
    236 #include <dict.h>
    237 #include <dict_db.h>
    238 #include <dict_lmdb.h>
    239 #include <dict_sockmap.h>
    240 #include <inet_proto.h>
    241 #include <vstring_vstream.h>
    242 #include <iostuff.h>
    243 #include <midna_domain.h>
    244 #include <logwriter.h>
    245 #include <mac_midna.h>
    246 
    247 /* Global library. */
    248 
    249 #include <mynetworks.h>
    250 #include <mail_conf.h>
    251 #include <mail_version.h>
    252 #include <mail_proto.h>
    253 #include <verp_sender.h>
    254 #include <own_inet_addr.h>
    255 #include <mail_params.h>
    256 #include <nbdb_util.h>
    257 #include <compat_level.h>
    258 #include <config_known_tcp_ports.h>
    259 
    260  /*
    261   * Special configuration variables.
    262   */
    263 char   *var_myhostname;
    264 char   *var_mydomain;
    265 char   *var_myorigin;
    266 char   *var_mydest;
    267 char   *var_relayhost;
    268 char   *var_transit_origin;
    269 char   *var_transit_dest;
    270 char   *var_mail_name;
    271 bool    var_helpful_warnings;
    272 char   *var_syslog_name;
    273 char   *var_mail_owner;
    274 uid_t   var_owner_uid;
    275 gid_t   var_owner_gid;
    276 char   *var_sgid_group;
    277 gid_t   var_sgid_gid;
    278 char   *var_default_privs;
    279 uid_t   var_default_uid;
    280 gid_t   var_default_gid;
    281 char   *var_config_dir;
    282 char   *var_daemon_dir;
    283 char   *var_data_dir;
    284 char   *var_command_dir;
    285 char   *var_meta_dir;
    286 char   *var_queue_dir;
    287 char   *var_shlib_dir;
    288 int     var_use_limit;
    289 int     var_event_drain;
    290 int     var_idle_limit;
    291 int     var_bundle_rcpt;
    292 char   *var_procname;
    293 char   *var_servname;
    294 int     var_pid;
    295 int     var_ipc_timeout;
    296 char   *var_pid_dir;
    297 int     var_dont_remove;
    298 char   *var_inet_interfaces;
    299 char   *var_proxy_interfaces;
    300 char   *var_inet_protocols;
    301 char   *var_mynetworks;
    302 char   *var_double_bounce_sender;
    303 int     var_line_limit;
    304 char   *var_alias_db_map;
    305 long    var_message_limit;
    306 char   *var_mail_release;
    307 char   *var_mail_version;
    308 int     var_ipc_idle_limit;
    309 int     var_ipc_ttl_limit;
    310 char   *var_db_type;
    311 char   *var_cache_db_type;
    312 char   *var_hash_queue_names;
    313 int     var_hash_queue_depth;
    314 int     var_trigger_timeout;
    315 char   *var_rcpt_delim;
    316 int     var_fork_tries;
    317 int     var_fork_delay;
    318 int     var_flock_tries;
    319 int     var_flock_delay;
    320 int     var_flock_stale;
    321 bool    var_disable_dns;
    322 bool    var_soft_bounce;
    323 time_t  var_starttime;
    324 bool    var_ownreq_special;
    325 int     var_daemon_timeout;
    326 char   *var_syslog_facility;
    327 char   *var_relay_domains;
    328 char   *var_fflush_domains;
    329 char   *var_mynetworks_style;
    330 char   *var_verp_delims;
    331 char   *var_verp_filter;
    332 int     var_in_flow_delay;
    333 char   *var_par_dom_match;
    334 char   *var_config_dirs;
    335 
    336 int     var_inet_windowsize;
    337 char   *var_import_environ;
    338 char   *var_export_environ;
    339 char   *var_debug_peer_list;
    340 int     var_debug_peer_level;
    341 int     var_fault_inj_code;
    342 char   *var_bounce_service;
    343 char   *var_cleanup_service;
    344 char   *var_defer_service;
    345 char   *var_pickup_service;
    346 char   *var_queue_service;
    347 char   *var_rewrite_service;
    348 char   *var_showq_service;
    349 char   *var_error_service;
    350 char   *var_flush_service;
    351 char   *var_verify_service;
    352 char   *var_trace_service;
    353 char   *var_proxymap_service;
    354 char   *var_proxywrite_service;
    355 int     var_db_create_buf;
    356 int     var_db_read_buf;
    357 long    var_lmdb_map_size;
    358 int     var_proc_limit;
    359 int     var_mime_maxdepth;
    360 int     var_mime_bound_len;
    361 int     var_header_limit;
    362 int     var_token_limit;
    363 bool    var_disable_mime_input;
    364 bool    var_disable_mime_oconv;
    365 bool    var_strict_8bitmime;
    366 bool    var_strict_7bit_hdrs;
    367 bool    var_strict_8bit_body;
    368 bool    var_strict_encoding;
    369 bool    var_verify_neg_cache;
    370 bool    var_oldlog_compat;
    371 int     var_delay_max_res;
    372 int     var_sockmap_max_reply;
    373 char   *var_int_filt_classes;
    374 bool    var_cyrus_sasl_authzid;
    375 
    376 char   *var_multi_conf_dirs;
    377 char   *var_multi_wrapper;
    378 char   *var_multi_group;
    379 char   *var_multi_name;
    380 bool    var_multi_enable;
    381 bool    var_long_queue_ids;
    382 bool    var_daemon_open_fatal;
    383 bool    var_dns_ncache_ttl_fix;
    384 char   *var_dsn_filter;
    385 bool    var_smtputf8_enable;
    386 bool    var_strict_smtputf8;
    387 char   *var_smtputf8_autoclass;
    388 bool    var_reqtls_enable;
    389 bool    var_tls_required_enable;
    390 bool    var_idna2003_compat;
    391 char   *var_compatibility_level;
    392 char   *var_drop_hdrs;
    393 char   *var_info_log_addr_form;
    394 bool    var_enable_orcpt;
    395 
    396 char   *var_maillog_file;
    397 char   *var_maillog_file_pfxs;
    398 char   *var_maillog_file_comp;
    399 char   *var_maillog_file_stamp;
    400 char   *var_maillog_file_perms;
    401 char   *var_postlog_service;
    402 
    403 char   *var_dnssec_probe;
    404 bool    var_respectful_logging;
    405 char   *var_known_tcp_ports;
    406 
    407 char   *var_nbdb_level;
    408 char   *var_nbdb_service;
    409 char   *var_nbdb_cust_map;
    410 bool    var_nbdb_log_redirect;
    411 
    412 const char null_format_string[1] = "";
    413 
    414  /*
    415   * Compatibility level 3.11.
    416   */
    417 int     warn_compat_break_smtp_tlsrpt_skip_reused_hs;
    418 int     warn_compat_break_smtp_tls_level;
    419 int     warn_compat_break_tlsp_clnt_level;
    420 
    421  /*
    422   * Compatibility level 3.6.
    423   */
    424 int     warn_compat_break_smtpd_tls_fpt_dgst;
    425 int     warn_compat_break_smtp_tls_fpt_dgst;
    426 int     warn_compat_break_lmtp_tls_fpt_dgst;
    427 int     warn_compat_relay_before_rcpt_checks;
    428 int     warn_compat_respectful_logging;
    429 
    430  /*
    431   * Compatibility level 2.
    432   */
    433 int     warn_compat_break_relay_domains;
    434 int     warn_compat_break_flush_domains;
    435 int     warn_compat_break_mynetworks_style;
    436 
    437  /*
    438   * Compatibility level 1.
    439   */
    440 int     warn_compat_break_app_dot_mydomain;
    441 int     warn_compat_break_smtputf8_enable;
    442 int     warn_compat_break_chroot;
    443 int     warn_compat_break_relay_restrictions;
    444 
    445  /*
    446   * Parsed from var_compatibility_level;
    447   */
    448 long    compat_level;
    449 
    450 /* check_myhostname - lookup hostname and validate */
    451 
    452 static const char *check_myhostname(void)
    453 {
    454     static const char *name;
    455     const char *dot;
    456     const char *domain;
    457 
    458     /*
    459      * Use cached result.
    460      */
    461     if (name)
    462 	return (name);
    463 
    464     /*
    465      * If the local machine name is not in FQDN form, try to append the
    466      * contents of $mydomain. Use a default domain as a final workaround.
    467      *
    468      * DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - IT MAKES EVERY POSTFIX
    469      * PROGRAM HANG WHEN DNS SERVICE IS UNAVAILABLE. IF YOU DON'T LIKE THE
    470      * DEFAULT, THEN EDIT MAIN.CF.
    471      */
    472     name = get_hostname();
    473     /* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
    474     if ((dot = strchr(name, '.')) == 0) {
    475 	/* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
    476 	if ((domain = mail_conf_lookup_eval(VAR_MYDOMAIN)) == 0)
    477 	    domain = DEF_MYDOMAIN;
    478 	/* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
    479 	name = concatenate(name, ".", domain, (char *) 0);
    480     }
    481     /* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
    482     return (name);
    483 }
    484 
    485 /* check_mydomainname - lookup domain name and validate */
    486 
    487 static const char *check_mydomainname(void)
    488 {
    489     char   *dot;
    490 
    491     /*
    492      * Use a default domain when the hostname is not a FQDN ("foo").
    493      *
    494      * DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - IT MAKES EVERY POSTFIX
    495      * PROGRAM HANG WHEN DNS SERVICE IS UNAVAILABLE. IF YOU DON'T LIKE THE
    496      * DEFAULT, THEN EDIT MAIN.CF.
    497      */
    498     /* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
    499     if ((dot = strchr(var_myhostname, '.')) == 0)
    500 	/* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
    501 	return (DEF_MYDOMAIN);
    502     /* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
    503     /* TODO(wietse) handle Unicode variants for 'dot'. */
    504     return (dot + 1);
    505 }
    506 
    507 /* check_default_privs - lookup default user attributes and validate */
    508 
    509 static void check_default_privs(void)
    510 {
    511     struct passwd *pwd;
    512 
    513     if ((pwd = getpwnam(var_default_privs)) == 0)
    514 	msg_fatal("file %s/%s: parameter %s: unknown user name value: %s",
    515 		  var_config_dir, MAIN_CONF_FILE,
    516 		  VAR_DEFAULT_PRIVS, var_default_privs);
    517     if ((var_default_uid = pwd->pw_uid) == 0)
    518 	msg_fatal("file %s/%s: parameter %s: user %s has privileged user ID",
    519 		  var_config_dir, MAIN_CONF_FILE,
    520 		  VAR_DEFAULT_PRIVS, var_default_privs);
    521     if ((var_default_gid = pwd->pw_gid) == 0)
    522 	msg_fatal("file %s/%s: parameter %s: user %s has privileged group ID",
    523 		  var_config_dir, MAIN_CONF_FILE,
    524 		  VAR_DEFAULT_PRIVS, var_default_privs);
    525 }
    526 
    527 /* check_mail_owner - lookup owner user attributes and validate */
    528 
    529 static void check_mail_owner(void)
    530 {
    531     struct passwd *pwd;
    532 
    533     if ((pwd = getpwnam(var_mail_owner)) == 0)
    534 	msg_fatal("file %s/%s: parameter %s: unknown user name value: %s",
    535 		  var_config_dir, MAIN_CONF_FILE,
    536 		  VAR_MAIL_OWNER, var_mail_owner);
    537     if ((var_owner_uid = pwd->pw_uid) == 0)
    538 	msg_fatal("file %s/%s: parameter %s: user %s has privileged user ID",
    539 		  var_config_dir, MAIN_CONF_FILE,
    540 		  VAR_MAIL_OWNER, var_mail_owner);
    541     if ((var_owner_gid = pwd->pw_gid) == 0)
    542 	msg_fatal("file %s/%s: parameter %s: user %s has privileged group ID",
    543 		  var_config_dir, MAIN_CONF_FILE,
    544 		  VAR_MAIL_OWNER, var_mail_owner);
    545 
    546     /*
    547      * This detects only some forms of sharing. Enumerating the entire
    548      * password file name space could be expensive. The purpose of this code
    549      * is to discourage user ID sharing by developers and package
    550      * maintainers.
    551      */
    552     if ((pwd = getpwuid(var_owner_uid)) != 0
    553 	&& strcmp(pwd->pw_name, var_mail_owner) != 0)
    554 	msg_fatal("file %s/%s: parameter %s: user %s has the same"
    555 		  " user ID %ld as user %s",
    556 		  var_config_dir, MAIN_CONF_FILE,
    557 		  VAR_MAIL_OWNER, var_mail_owner,
    558 		  (long) var_owner_uid, pwd->pw_name);
    559 }
    560 
    561 /* check_sgid_group - lookup setgid group attributes and validate */
    562 
    563 static void check_sgid_group(void)
    564 {
    565     struct group *grp;
    566 
    567     if ((grp = getgrnam(var_sgid_group)) == 0)
    568 	msg_fatal("file %s/%s: parameter %s: unknown group name: %s",
    569 		  var_config_dir, MAIN_CONF_FILE,
    570 		  VAR_SGID_GROUP, var_sgid_group);
    571     if ((var_sgid_gid = grp->gr_gid) == 0)
    572 	msg_fatal("file %s/%s: parameter %s: group %s has privileged group ID",
    573 		  var_config_dir, MAIN_CONF_FILE,
    574 		  VAR_SGID_GROUP, var_sgid_group);
    575 
    576     /*
    577      * This detects only some forms of sharing. Enumerating the entire group
    578      * file name space could be expensive. The purpose of this code is to
    579      * discourage group ID sharing by developers and package maintainers.
    580      */
    581     if ((grp = getgrgid(var_sgid_gid)) != 0
    582 	&& strcmp(grp->gr_name, var_sgid_group) != 0)
    583 	msg_fatal("file %s/%s: parameter %s: group %s has the same"
    584 		  " group ID %ld as group %s",
    585 		  var_config_dir, MAIN_CONF_FILE,
    586 		  VAR_SGID_GROUP, var_sgid_group,
    587 		  (long) var_sgid_gid, grp->gr_name);
    588 }
    589 
    590 /* check_overlap - disallow UID or GID sharing */
    591 
    592 static void check_overlap(void)
    593 {
    594     if (strcmp(var_default_privs, var_mail_owner) == 0)
    595 	msg_fatal("file %s/%s: parameters %s and %s specify the same user %s",
    596 		  var_config_dir, MAIN_CONF_FILE,
    597 		  VAR_DEFAULT_PRIVS, VAR_MAIL_OWNER,
    598 		  var_default_privs);
    599     if (var_default_uid == var_owner_uid)
    600 	msg_fatal("file %s/%s: parameters %s and %s: users %s and %s have the same user ID: %ld",
    601 		  var_config_dir, MAIN_CONF_FILE,
    602 		  VAR_DEFAULT_PRIVS, VAR_MAIL_OWNER,
    603 		  var_default_privs, var_mail_owner,
    604 		  (long) var_owner_uid);
    605     if (var_default_gid == var_owner_gid)
    606 	msg_fatal("file %s/%s: parameters %s and %s: users %s and %s have the same group ID: %ld",
    607 		  var_config_dir, MAIN_CONF_FILE,
    608 		  VAR_DEFAULT_PRIVS, VAR_MAIL_OWNER,
    609 		  var_default_privs, var_mail_owner,
    610 		  (long) var_owner_gid);
    611     if (var_default_gid == var_sgid_gid)
    612 	msg_fatal("file %s/%s: parameters %s and %s: user %s and group %s have the same group ID: %ld",
    613 		  var_config_dir, MAIN_CONF_FILE,
    614 		  VAR_DEFAULT_PRIVS, VAR_SGID_GROUP,
    615 		  var_default_privs, var_sgid_group,
    616 		  (long) var_sgid_gid);
    617     if (var_owner_gid == var_sgid_gid)
    618 	msg_fatal("file %s/%s: parameters %s and %s: user %s and group %s have the same group ID: %ld",
    619 		  var_config_dir, MAIN_CONF_FILE,
    620 		  VAR_MAIL_OWNER, VAR_SGID_GROUP,
    621 		  var_mail_owner, var_sgid_group,
    622 		  (long) var_sgid_gid);
    623 }
    624 
    625 #ifdef MYORIGIN_FROM_FILE
    626 
    627 /* read_param_from_file - read parameter value from file */
    628 
    629 static char *read_param_from_file(const char *path)
    630 {
    631     VSTRING *why = vstring_alloc(100);
    632     VSTRING *buf = vstring_alloc(100);
    633     VSTREAM *fp;
    634     char   *bp;
    635     char   *result;
    636 
    637     /*
    638      * Ugly macros to make complex expressions less unreadable.
    639      */
    640 #define SKIP(start, var, cond) do { \
    641 	for (var = start; *var && (cond); var++) \
    642 	    /* void */; \
    643     } while (0)
    644 
    645 #define TRIM(s) do { \
    646 	char *p; \
    647 	for (p = (s) + strlen(s); p > (s) && ISSPACE(p[-1]); p--) \
    648 	    /* void */; \
    649 	*p = 0; \
    650     } while (0)
    651 
    652     fp = safe_open(path, O_RDONLY, 0, (struct stat *) 0, -1, -1, why);
    653     if (fp == 0)
    654 	msg_fatal("%s: %s", path, vstring_str(why));
    655     vstring_get_nonl(buf, fp);
    656     if (vstream_ferror(fp))			/* FIX 20070501 */
    657 	msg_fatal("%s: read error: %m", path);
    658     vstream_fclose(fp);
    659     SKIP(vstring_str(buf), bp, ISSPACE(*bp));
    660     TRIM(bp);
    661     result = mystrdup(bp);
    662 
    663     vstring_free(why);
    664     vstring_free(buf);
    665     return (result);
    666 }
    667 
    668 #endif
    669 
    670 /* check_legacy_defaults - flag parameters that require safety-net logging */
    671 
    672 static void check_legacy_defaults(void)
    673 {
    674 
    675     /*
    676      * Basic idea: when an existing parameter default is changed, or a new
    677      * parameter is introduced with incompatible default behavior, force
    678      * Postfix to run with backwards-compatible default settings and log a
    679      * warning when the backwards-compatible behavior is used.
    680      *
    681      * Based on a review of Postfix logging the system administrator can decide
    682      * whether or not to make backwards-compatible default settings permanent
    683      * in main.cf or master.cf.
    684      *
    685      * To turn off further warnings and deploy the new default settings, the
    686      * system administrator should update the compatibility_level setting as
    687      * recommended in the RELEASE_NOTES file.
    688      *
    689      * Each incompatible change has its own flag variable, instead of bit in a
    690      * shared variable. We don't want to rip up code when we need more flag
    691      * bits.
    692      *
    693      * Note: the purpose of these mail_conf_lookup() calls is to detect if a
    694      * parameter value is not specified. The calls must happen before
    695      * parameter default settings are enforced with mail_conf_update().
    696      *
    697      * The preferred flow is: 1) in mail_params.h, specify a configuration
    698      * parameter default value that depends on the compatibility level; 2)
    699      * below, set a flag to indicate that the parameter will be set to the
    700      * legacy default value; 3) in the program-specific code, log a message
    701      * when the legacy default value is actually used, and optionally clear
    702      * the flag to avoid spamming the log.
    703      */
    704 
    705     /*
    706      * Look for specific parameters whose default changed when the
    707      * compatibility level changed to 3.11.
    708      */
    709     if (compat_level < compat_level_from_string(COMPAT_LEVEL_3_11, msg_panic)) {
    710 #ifdef USE_TLS
    711 	if (mail_conf_lookup(VAR_SMTP_TLSRPT_SKIP_REUSED_HS) == 0)
    712 	    warn_compat_break_smtp_tlsrpt_skip_reused_hs = 1;
    713 	if (mail_conf_lookup(VAR_SMTP_TLS_LEVEL) == 0)
    714 	    warn_compat_break_smtp_tls_level = 1;
    715 	if (mail_conf_lookup(VAR_TLSP_CLNT_LEVEL) == 0)
    716 	    warn_compat_break_tlsp_clnt_level = 1;
    717 #endif
    718     }
    719 
    720     /*
    721      * Look for specific parameters whose default changed when the
    722      * compatibility level changed to 3.6.
    723      */
    724     if (compat_level < compat_level_from_string(COMPAT_LEVEL_3_6, msg_panic)) {
    725 	if (mail_conf_lookup(VAR_SMTPD_TLS_FPT_DGST) == 0)
    726 	    warn_compat_break_smtpd_tls_fpt_dgst = 1;
    727 	if (mail_conf_lookup(VAR_SMTP_TLS_FPT_DGST) == 0)
    728 	    warn_compat_break_smtp_tls_fpt_dgst = 1;
    729 	if (mail_conf_lookup(VAR_LMTP_TLS_FPT_DGST) == 0)
    730 	    warn_compat_break_lmtp_tls_fpt_dgst = 1;
    731 	if (mail_conf_lookup(VAR_RELAY_BEFORE_RCPT_CHECKS) == 0)
    732 	    warn_compat_relay_before_rcpt_checks = 1;
    733 	if (mail_conf_lookup(VAR_RESPECTFUL_LOGGING) == 0)
    734 	    warn_compat_respectful_logging = 1;
    735     }
    736 
    737     /*
    738      * Look for specific parameters whose default changed when the
    739      * compatibility level changed to 2.
    740      */
    741     if (compat_level < compat_level_from_string(COMPAT_LEVEL_2, msg_panic)) {
    742 	if (mail_conf_lookup(VAR_RELAY_DOMAINS) == 0) {
    743 	    warn_compat_break_relay_domains = 1;
    744 	    if (mail_conf_lookup(VAR_FFLUSH_DOMAINS) == 0)
    745 		warn_compat_break_flush_domains = 1;
    746 	}
    747 	if (mail_conf_lookup(VAR_MYNETWORKS) == 0
    748 	    && mail_conf_lookup(VAR_MYNETWORKS_STYLE) == 0)
    749 	    warn_compat_break_mynetworks_style = 1;
    750     }
    751 
    752     /*
    753      * Look for specific parameters whose default changed when the
    754      * compatibility level changed from 0 to 1.
    755      */
    756     if (compat_level < compat_level_from_string(COMPAT_LEVEL_1, msg_panic)) {
    757 	if (mail_conf_lookup(VAR_APP_DOT_MYDOMAIN) == 0)
    758 	    warn_compat_break_app_dot_mydomain = 1;
    759 
    760 	/*
    761 	 * Not: #ifndef NO_EAI. They must configure SMTPUTF8_ENABLE=no if a
    762 	 * warning message is logged, so that they don't suddenly start to
    763 	 * lose mail after Postfix is built with EAI support.
    764 	 */
    765 	if (mail_conf_lookup(VAR_SMTPUTF8_ENABLE) == 0)
    766 	    warn_compat_break_smtputf8_enable = 1;
    767 	warn_compat_break_chroot = 1;
    768 
    769 	/*
    770 	 * Grandfathered in to help sites migrating from Postfix <2.10.
    771 	 */
    772 	if (mail_conf_lookup(VAR_RELAY_CHECKS) == 0)
    773 	    warn_compat_break_relay_restrictions = 1;
    774     }
    775 }
    776 
    777 /* mail_params_init - configure built-in parameters */
    778 
    779 void    mail_params_init()
    780 {
    781     static const CONFIG_STR_TABLE compat_level_defaults[] = {
    782 	VAR_COMPAT_LEVEL, DEF_COMPAT_LEVEL, &var_compatibility_level, 0, 0,
    783 	0,
    784     };
    785     static const CONFIG_STR_TABLE first_str_defaults[] = {
    786 	/* $mail_version may appear in other parameters. */
    787 	VAR_MAIL_VERSION, DEF_MAIL_VERSION, &var_mail_version, 1, 0,
    788 	VAR_SYSLOG_FACILITY, DEF_SYSLOG_FACILITY, &var_syslog_facility, 1, 0,
    789 	VAR_INET_PROTOCOLS, DEF_INET_PROTOCOLS, &var_inet_protocols, 0, 0,
    790 	VAR_MULTI_CONF_DIRS, DEF_MULTI_CONF_DIRS, &var_multi_conf_dirs, 0, 0,
    791 	/* multi_instance_wrapper may have dependencies but not dependents. */
    792 	VAR_MULTI_GROUP, DEF_MULTI_GROUP, &var_multi_group, 0, 0,
    793 	VAR_MULTI_NAME, DEF_MULTI_NAME, &var_multi_name, 0, 0,
    794 	VAR_MAILLOG_FILE, DEF_MAILLOG_FILE, &var_maillog_file, 0, 0,
    795 	VAR_MAILLOG_FILE_PFXS, DEF_MAILLOG_FILE_PFXS, &var_maillog_file_pfxs, 1, 0,
    796 	VAR_MAILLOG_FILE_COMP, DEF_MAILLOG_FILE_COMP, &var_maillog_file_comp, 1, 0,
    797 	VAR_MAILLOG_FILE_STAMP, DEF_MAILLOG_FILE_STAMP, &var_maillog_file_stamp, 1, 0,
    798 	VAR_MAILLOG_FILE_PERMS, DEF_MAILLOG_FILE_PERMS, &var_maillog_file_perms, 1, 0,
    799 	VAR_POSTLOG_SERVICE, DEF_POSTLOG_SERVICE, &var_postlog_service, 1, 0,
    800 	VAR_DNSSEC_PROBE, DEF_DNSSEC_PROBE, &var_dnssec_probe, 0, 0,
    801 	VAR_KNOWN_TCP_PORTS, DEF_KNOWN_TCP_PORTS, &var_known_tcp_ports, 0, 0,
    802 	VAR_SERVNAME, DEF_SERVNAME, &var_servname, 0, 0,
    803 	0,
    804     };
    805     static const CONFIG_BOOL_TABLE first_bool_defaults[] = {
    806 	/* read and process the following before opening tables. */
    807 	VAR_DAEMON_OPEN_FATAL, DEF_DAEMON_OPEN_FATAL, &var_daemon_open_fatal,
    808 	VAR_DNS_NCACHE_TTL_FIX, DEF_DNS_NCACHE_TTL_FIX, &var_dns_ncache_ttl_fix,
    809 	0,
    810     };
    811     static const CONFIG_NBOOL_TABLE first_nbool_defaults[] = {
    812 	/* read and process the following before opening tables. */
    813 	VAR_SMTPUTF8_ENABLE, DEF_SMTPUTF8_ENABLE, &var_smtputf8_enable,
    814 	VAR_IDNA2003_COMPAT, DEF_IDNA2003_COMPAT, &var_idna2003_compat,
    815 	VAR_RESPECTFUL_LOGGING, DEF_RESPECTFUL_LOGGING, &var_respectful_logging,
    816 	VAR_REQTLS_ENABLE, DEF_REQTLS_ENABLE, &var_reqtls_enable,
    817 	VAR_TLSREQUIRED_ENABLE, DEF_TLSREQUIRED_ENABLE, &var_tls_required_enable,
    818 	VAR_NBDB_LOG_REDIRECT, DEF_NBDB_LOG_REDIRECT, &var_nbdb_log_redirect,
    819 	0,
    820     };
    821     static const CONFIG_STR_FN_TABLE function_str_defaults[] = {
    822 	VAR_MYHOSTNAME, check_myhostname, &var_myhostname, 1, 0,
    823 	VAR_MYDOMAIN, check_mydomainname, &var_mydomain, 1, 0,
    824 	0,
    825     };
    826     static const CONFIG_STR_TABLE other_str_defaults[] = {
    827 	VAR_MAIL_NAME, DEF_MAIL_NAME, &var_mail_name, 1, 0,
    828 	VAR_SYSLOG_NAME, DEF_SYSLOG_NAME, &var_syslog_name, 1, 0,
    829 	VAR_MAIL_OWNER, DEF_MAIL_OWNER, &var_mail_owner, 1, 0,
    830 	VAR_SGID_GROUP, DEF_SGID_GROUP, &var_sgid_group, 1, 0,
    831 	VAR_MYDEST, DEF_MYDEST, &var_mydest, 0, 0,
    832 	VAR_MYORIGIN, DEF_MYORIGIN, &var_myorigin, 1, 0,
    833 	VAR_RELAYHOST, DEF_RELAYHOST, &var_relayhost, 0, 0,
    834 	VAR_DAEMON_DIR, DEF_DAEMON_DIR, &var_daemon_dir, 1, 0,
    835 	VAR_DATA_DIR, DEF_DATA_DIR, &var_data_dir, 1, 0,
    836 	VAR_COMMAND_DIR, DEF_COMMAND_DIR, &var_command_dir, 1, 0,
    837 	VAR_META_DIR, DEF_META_DIR, &var_meta_dir, 1, 0,
    838 	VAR_QUEUE_DIR, DEF_QUEUE_DIR, &var_queue_dir, 1, 0,
    839 	VAR_SHLIB_DIR, DEF_SHLIB_DIR, &var_shlib_dir, 1, 0,
    840 	VAR_PID_DIR, DEF_PID_DIR, &var_pid_dir, 1, 0,
    841 	VAR_INET_INTERFACES, DEF_INET_INTERFACES, &var_inet_interfaces, 0, 0,
    842 	VAR_PROXY_INTERFACES, DEF_PROXY_INTERFACES, &var_proxy_interfaces, 0, 0,
    843 	VAR_DOUBLE_BOUNCE, DEF_DOUBLE_BOUNCE, &var_double_bounce_sender, 1, 0,
    844 	VAR_DEFAULT_PRIVS, DEF_DEFAULT_PRIVS, &var_default_privs, 1, 0,
    845 	VAR_MAIL_RELEASE, DEF_MAIL_RELEASE, &var_mail_release, 1, 0,
    846 	VAR_DB_TYPE, DEF_DB_TYPE, &var_db_type, 1, 0,
    847 	VAR_CACHE_DB_TYPE, DEF_CACHE_DB_TYPE, &var_cache_db_type, 1, 0,
    848 	VAR_ALIAS_DB_MAP, DEF_ALIAS_DB_MAP, &var_alias_db_map, 0, 0,
    849 	VAR_HASH_QUEUE_NAMES, DEF_HASH_QUEUE_NAMES, &var_hash_queue_names, 1, 0,
    850 	VAR_RCPT_DELIM, DEF_RCPT_DELIM, &var_rcpt_delim, 0, 0,
    851 	VAR_RELAY_DOMAINS, DEF_RELAY_DOMAINS, &var_relay_domains, 0, 0,
    852 	VAR_FFLUSH_DOMAINS, DEF_FFLUSH_DOMAINS, &var_fflush_domains, 0, 0,
    853 	VAR_EXPORT_ENVIRON, DEF_EXPORT_ENVIRON, &var_export_environ, 0, 0,
    854 	VAR_IMPORT_ENVIRON, DEF_IMPORT_ENVIRON, &var_import_environ, 0, 0,
    855 	VAR_MYNETWORKS_STYLE, DEF_MYNETWORKS_STYLE, &var_mynetworks_style, 1, 0,
    856 	VAR_DEBUG_PEER_LIST, DEF_DEBUG_PEER_LIST, &var_debug_peer_list, 0, 0,
    857 	VAR_VERP_DELIMS, DEF_VERP_DELIMS, &var_verp_delims, 2, 2,
    858 	VAR_VERP_FILTER, DEF_VERP_FILTER, &var_verp_filter, 1, 0,
    859 	VAR_PAR_DOM_MATCH, DEF_PAR_DOM_MATCH, &var_par_dom_match, 0, 0,
    860 	VAR_CONFIG_DIRS, DEF_CONFIG_DIRS, &var_config_dirs, 0, 0,
    861 	VAR_BOUNCE_SERVICE, DEF_BOUNCE_SERVICE, &var_bounce_service, 1, 0,
    862 	VAR_CLEANUP_SERVICE, DEF_CLEANUP_SERVICE, &var_cleanup_service, 1, 0,
    863 	VAR_DEFER_SERVICE, DEF_DEFER_SERVICE, &var_defer_service, 1, 0,
    864 	VAR_PICKUP_SERVICE, DEF_PICKUP_SERVICE, &var_pickup_service, 1, 0,
    865 	VAR_QUEUE_SERVICE, DEF_QUEUE_SERVICE, &var_queue_service, 1, 0,
    866 	VAR_REWRITE_SERVICE, DEF_REWRITE_SERVICE, &var_rewrite_service, 1, 0,
    867 	VAR_SHOWQ_SERVICE, DEF_SHOWQ_SERVICE, &var_showq_service, 1, 0,
    868 	VAR_ERROR_SERVICE, DEF_ERROR_SERVICE, &var_error_service, 1, 0,
    869 	VAR_FLUSH_SERVICE, DEF_FLUSH_SERVICE, &var_flush_service, 1, 0,
    870 	VAR_VERIFY_SERVICE, DEF_VERIFY_SERVICE, &var_verify_service, 1, 0,
    871 	VAR_TRACE_SERVICE, DEF_TRACE_SERVICE, &var_trace_service, 1, 0,
    872 	VAR_PROXYMAP_SERVICE, DEF_PROXYMAP_SERVICE, &var_proxymap_service, 1, 0,
    873 	VAR_PROXYWRITE_SERVICE, DEF_PROXYWRITE_SERVICE, &var_proxywrite_service, 1, 0,
    874 	VAR_INT_FILT_CLASSES, DEF_INT_FILT_CLASSES, &var_int_filt_classes, 0, 0,
    875 	/* multi_instance_wrapper may have dependencies but not dependents. */
    876 	VAR_MULTI_WRAPPER, DEF_MULTI_WRAPPER, &var_multi_wrapper, 0, 0,
    877 	VAR_DSN_FILTER, DEF_DSN_FILTER, &var_dsn_filter, 0, 0,
    878 	VAR_SMTPUTF8_AUTOCLASS, DEF_SMTPUTF8_AUTOCLASS, &var_smtputf8_autoclass, 1, 0,
    879 	VAR_DROP_HDRS, DEF_DROP_HDRS, &var_drop_hdrs, 0, 0,
    880 	VAR_INFO_LOG_ADDR_FORM, DEF_INFO_LOG_ADDR_FORM, &var_info_log_addr_form, 1, 0,
    881 	VAR_NBDB_LEVEL, DEF_NBDB_LEVEL, &var_nbdb_level, 1, 0,
    882 	VAR_NBDB_SERVICE, DEF_NBDB_SERVICE, &var_nbdb_service, 0, 0,
    883 	VAR_NBDB_CUST_MAP, DEF_NBDB_CUST_MAP, &var_nbdb_cust_map, 0, 0,
    884 	0,
    885     };
    886     static const CONFIG_STR_FN_TABLE function_str_defaults_2[] = {
    887 	VAR_MYNETWORKS, mynetworks, &var_mynetworks, 0, 0,
    888 	0,
    889     };
    890     static const CONFIG_INT_TABLE other_int_defaults[] = {
    891 	VAR_PROC_LIMIT, DEF_PROC_LIMIT, &var_proc_limit, 1, 0,
    892 	VAR_MAX_USE, DEF_MAX_USE, &var_use_limit, 1, 0,
    893 	VAR_DONT_REMOVE, DEF_DONT_REMOVE, &var_dont_remove, 0, 0,
    894 	VAR_LINE_LIMIT, DEF_LINE_LIMIT, &var_line_limit, 512, 0,
    895 	VAR_HASH_QUEUE_DEPTH, DEF_HASH_QUEUE_DEPTH, &var_hash_queue_depth, 1, 0,
    896 	VAR_FORK_TRIES, DEF_FORK_TRIES, &var_fork_tries, 1, 0,
    897 	VAR_FLOCK_TRIES, DEF_FLOCK_TRIES, &var_flock_tries, 1, 0,
    898 	VAR_DEBUG_PEER_LEVEL, DEF_DEBUG_PEER_LEVEL, &var_debug_peer_level, 1, 0,
    899 	VAR_FAULT_INJ_CODE, DEF_FAULT_INJ_CODE, &var_fault_inj_code, 0, 0,
    900 	VAR_DB_CREATE_BUF, DEF_DB_CREATE_BUF, &var_db_create_buf, 1, 0,
    901 	VAR_DB_READ_BUF, DEF_DB_READ_BUF, &var_db_read_buf, 1, 0,
    902 	VAR_HEADER_LIMIT, DEF_HEADER_LIMIT, &var_header_limit, 1, 0,
    903 	VAR_TOKEN_LIMIT, DEF_TOKEN_LIMIT, &var_token_limit, 1, 0,
    904 	VAR_MIME_MAXDEPTH, DEF_MIME_MAXDEPTH, &var_mime_maxdepth, 1, 0,
    905 	VAR_MIME_BOUND_LEN, DEF_MIME_BOUND_LEN, &var_mime_bound_len, 1, 0,
    906 	VAR_DELAY_MAX_RES, DEF_DELAY_MAX_RES, &var_delay_max_res, MIN_DELAY_MAX_RES, MAX_DELAY_MAX_RES,
    907 	VAR_INET_WINDOW, DEF_INET_WINDOW, &var_inet_windowsize, 0, 0,
    908 	VAR_SOCKMAP_MAX_REPLY, DEF_SOCKMAP_MAX_REPLY, &var_sockmap_max_reply, 1, 0,
    909 	0,
    910     };
    911     static const CONFIG_LONG_TABLE long_defaults[] = {
    912 	VAR_MESSAGE_LIMIT, DEF_MESSAGE_LIMIT, &var_message_limit, 0, 0,
    913 	VAR_LMDB_MAP_SIZE, DEF_LMDB_MAP_SIZE, &var_lmdb_map_size, 1, 0,
    914 	0,
    915     };
    916     static const CONFIG_TIME_TABLE time_defaults[] = {
    917 	VAR_EVENT_DRAIN, DEF_EVENT_DRAIN, &var_event_drain, 1, 0,
    918 	VAR_MAX_IDLE, DEF_MAX_IDLE, &var_idle_limit, 1, 0,
    919 	VAR_IPC_TIMEOUT, DEF_IPC_TIMEOUT, &var_ipc_timeout, 1, 0,
    920 	VAR_IPC_IDLE, DEF_IPC_IDLE, &var_ipc_idle_limit, 1, 0,
    921 	VAR_IPC_TTL, DEF_IPC_TTL, &var_ipc_ttl_limit, 1, 0,
    922 	VAR_TRIGGER_TIMEOUT, DEF_TRIGGER_TIMEOUT, &var_trigger_timeout, 1, 0,
    923 	VAR_FORK_DELAY, DEF_FORK_DELAY, &var_fork_delay, 1, 0,
    924 	VAR_FLOCK_DELAY, DEF_FLOCK_DELAY, &var_flock_delay, 1, 0,
    925 	VAR_FLOCK_STALE, DEF_FLOCK_STALE, &var_flock_stale, 1, 0,
    926 	VAR_DAEMON_TIMEOUT, DEF_DAEMON_TIMEOUT, &var_daemon_timeout, 1, 0,
    927 	VAR_IN_FLOW_DELAY, DEF_IN_FLOW_DELAY, &var_in_flow_delay, 0, 10,
    928 	0,
    929     };
    930     static const CONFIG_BOOL_TABLE bool_defaults[] = {
    931 	VAR_DISABLE_DNS, DEF_DISABLE_DNS, &var_disable_dns,
    932 	VAR_SOFT_BOUNCE, DEF_SOFT_BOUNCE, &var_soft_bounce,
    933 	VAR_OWNREQ_SPECIAL, DEF_OWNREQ_SPECIAL, &var_ownreq_special,
    934 	VAR_STRICT_8BITMIME, DEF_STRICT_8BITMIME, &var_strict_8bitmime,
    935 	VAR_STRICT_7BIT_HDRS, DEF_STRICT_7BIT_HDRS, &var_strict_7bit_hdrs,
    936 	VAR_STRICT_8BIT_BODY, DEF_STRICT_8BIT_BODY, &var_strict_8bit_body,
    937 	VAR_STRICT_ENCODING, DEF_STRICT_ENCODING, &var_strict_encoding,
    938 	VAR_DISABLE_MIME_INPUT, DEF_DISABLE_MIME_INPUT, &var_disable_mime_input,
    939 	VAR_DISABLE_MIME_OCONV, DEF_DISABLE_MIME_OCONV, &var_disable_mime_oconv,
    940 	VAR_VERIFY_NEG_CACHE, DEF_VERIFY_NEG_CACHE, &var_verify_neg_cache,
    941 	VAR_OLDLOG_COMPAT, DEF_OLDLOG_COMPAT, &var_oldlog_compat,
    942 	VAR_HELPFUL_WARNINGS, DEF_HELPFUL_WARNINGS, &var_helpful_warnings,
    943 	VAR_CYRUS_SASL_AUTHZID, DEF_CYRUS_SASL_AUTHZID, &var_cyrus_sasl_authzid,
    944 	VAR_MULTI_ENABLE, DEF_MULTI_ENABLE, &var_multi_enable,
    945 	VAR_LONG_QUEUE_IDS, DEF_LONG_QUEUE_IDS, &var_long_queue_ids,
    946 	VAR_STRICT_SMTPUTF8, DEF_STRICT_SMTPUTF8, &var_strict_smtputf8,
    947 	VAR_ENABLE_ORCPT, DEF_ENABLE_ORCPT, &var_enable_orcpt,
    948 	0,
    949     };
    950     const char *cp;
    951 
    952     /*
    953      * Register named functions.
    954      */
    955     mac_midna_register();
    956 
    957     /*
    958      * Extract compatibility level first, so that we can determine what
    959      * parameters of interest are left at their legacy defaults.
    960      */
    961     if (var_compatibility_level == 0)
    962 	compat_level_relop_register();
    963     get_mail_conf_str_table(compat_level_defaults);
    964     compat_level = compat_level_from_string(var_compatibility_level, msg_fatal);
    965     check_legacy_defaults();
    966 
    967     /*
    968      * Extract syslog_facility early, so that from here on all errors are
    969      * logged with the proper facility.
    970      */
    971     get_mail_conf_str_table(first_str_defaults);
    972 
    973     if (!msg_syslog_set_facility(var_syslog_facility))
    974 	msg_fatal("file %s/%s: parameter %s: unrecognized value: %s",
    975 		  var_config_dir, MAIN_CONF_FILE,
    976 		  VAR_SYSLOG_FACILITY, var_syslog_facility);
    977 
    978     /*
    979      * Should daemons terminate after table open error, or should they
    980      * continue execution with reduced functionality?
    981      */
    982     get_mail_conf_bool_table(first_bool_defaults);
    983     if (var_daemon_open_fatal)
    984 	dict_allow_surrogate = 0;
    985 
    986     /*
    987      * Should we open tables with UTF8 support, or in the legacy 8-bit clean
    988      * mode with ASCII-only casefolding?
    989      */
    990     get_mail_conf_nbool_table(first_nbool_defaults);
    991 
    992     /*
    993      * Report run-time versus compile-time discrepancies.
    994      */
    995 #ifdef NO_EAI
    996     if (var_smtputf8_enable)
    997 	msg_warn("%s is true, but EAI support is not compiled in",
    998 		 VAR_SMTPUTF8_ENABLE);
    999     var_smtputf8_enable = 0;
   1000 #else
   1001     midna_domain_transitional = var_idna2003_compat;
   1002     if (var_smtputf8_enable)
   1003 	midna_domain_pre_chroot();
   1004 #endif
   1005     util_utf8_enable = var_smtputf8_enable;
   1006 
   1007     /*
   1008      * Configure the known TCP port mappings.
   1009      */
   1010     config_known_tcp_ports(VAR_KNOWN_TCP_PORTS, var_known_tcp_ports);
   1011 
   1012     /*
   1013      * What protocols should we attempt to support? The result is stored in
   1014      * the global inet_proto_table variable.
   1015      */
   1016     (void) inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols);
   1017 
   1018     /*
   1019      * Variables whose defaults are determined at runtime. Some sites use
   1020      * short hostnames in the host table; some sites name their system after
   1021      * the domain.
   1022      */
   1023     get_mail_conf_str_fn_table(function_str_defaults);
   1024     if (!valid_hostname(var_myhostname, DO_GRIPE))
   1025 	msg_fatal("file %s/%s: parameter %s: bad parameter value: %s",
   1026 		  var_config_dir, MAIN_CONF_FILE,
   1027 		  VAR_MYHOSTNAME, var_myhostname);
   1028     if (!valid_hostname(var_mydomain, DO_GRIPE))
   1029 	msg_fatal("file %s/%s: parameter %s: bad parameter value: %s",
   1030 		  var_config_dir, MAIN_CONF_FILE,
   1031 		  VAR_MYDOMAIN, var_mydomain);
   1032 
   1033     /*
   1034      * Variables that are needed by almost every program.
   1035      *
   1036      * XXX Reading the myorigin value from file is originally a Debian Linux
   1037      * feature. This code is not enabled by default because of problems: 1)
   1038      * it re-implements its own parameter syntax checks, and 2) it does not
   1039      * implement $name expansions.
   1040      */
   1041     get_mail_conf_str_table(other_str_defaults);
   1042 #ifdef MYORIGIN_FROM_FILE
   1043     if (*var_myorigin == '/') {
   1044 	char   *origin = read_param_from_file(var_myorigin);
   1045 
   1046 	if (*origin == 0)
   1047 	    msg_fatal("%s file %s is empty", VAR_MYORIGIN, var_myorigin);
   1048 	myfree(var_myorigin);			/* FIX 20070501 */
   1049 	var_myorigin = origin;
   1050     }
   1051 #endif
   1052     get_mail_conf_int_table(other_int_defaults);
   1053     get_mail_conf_long_table(long_defaults);
   1054     get_mail_conf_bool_table(bool_defaults);
   1055     get_mail_conf_time_table(time_defaults);
   1056     check_default_privs();
   1057     check_mail_owner();
   1058     check_sgid_group();
   1059     check_overlap();
   1060     dict_db_cache_size = var_db_read_buf;
   1061     dict_lmdb_map_size = var_lmdb_map_size;
   1062     dict_sockmap_max_reply = var_sockmap_max_reply;
   1063     inet_windowsize = var_inet_windowsize;
   1064     if (set_logwriter_create_perms(var_maillog_file_perms) < 0)
   1065 	msg_warn("ignoring bad permissions: %s = %s",
   1066 		 VAR_MAILLOG_FILE_PERMS, var_maillog_file_perms);
   1067 
   1068     /*
   1069      * Variables whose defaults are determined at runtime, after other
   1070      * variables have been set. This dependency is admittedly a bit tricky.
   1071      * XXX Perhaps we should just register variables, and let the evaluator
   1072      * figure out in what order to evaluate things.
   1073      */
   1074     get_mail_conf_str_fn_table(function_str_defaults_2);
   1075 
   1076     /*
   1077      * FIX 200412 The IPv6 patch did not call own_inet_addr_list() before
   1078      * entering the chroot jail on Linux IPv6 systems. Linux has the IPv6
   1079      * interface list in /proc, which is not available after chrooting.
   1080      */
   1081     (void) own_inet_addr_list();
   1082 
   1083     /*
   1084      * The PID variable cannot be set from the configuration file!!
   1085      */
   1086     set_mail_conf_int(VAR_PID, var_pid = getpid());
   1087 
   1088     /*
   1089      * Neither can the start time variable. It isn't even visible.
   1090      */
   1091     time(&var_starttime);
   1092 
   1093     /*
   1094      * Export the syslog name so children can inherit and use it before they
   1095      * have initialized.
   1096      */
   1097     if ((cp = safe_getenv(CONF_ENV_LOGTAG)) == 0
   1098 	|| strcmp(cp, var_syslog_name) != 0)
   1099 	if (setenv(CONF_ENV_LOGTAG, var_syslog_name, 1) < 0)
   1100 	    msg_fatal("setenv %s %s: %m", CONF_ENV_LOGTAG, var_syslog_name);
   1101 
   1102     /*
   1103      * I have seen this happen just too often.
   1104      */
   1105     if (strcasecmp_utf8(var_myhostname, var_relayhost) == 0)
   1106 	msg_fatal("%s and %s parameter settings must not be identical: %s",
   1107 		  VAR_MYHOSTNAME, VAR_RELAYHOST, var_myhostname);
   1108 
   1109     /*
   1110      * XXX These should be caught by a proper parameter parsing algorithm.
   1111      */
   1112     if (var_myorigin[strcspn(var_myorigin, CHARS_COMMA_SP)])
   1113 	msg_fatal("%s parameter setting must not contain multiple values: %s",
   1114 		  VAR_MYORIGIN, var_myorigin);
   1115 
   1116     /*
   1117      * One more sanity check.
   1118      */
   1119     if ((cp = verp_delims_verify(var_verp_delims)) != 0)
   1120 	msg_fatal("file %s/%s: parameters %s and %s: %s",
   1121 		  var_config_dir, MAIN_CONF_FILE,
   1122 		  VAR_VERP_DELIMS, VAR_VERP_FILTER, cp);
   1123 
   1124     /*
   1125      * Non-Berkeley-DB migration support.
   1126      */
   1127     nbdb_util_init(var_nbdb_level);
   1128 }
   1129