1 /* $NetBSD: mail_params.c,v 1.1.1.4 2014/07/06 19:27:51 tron 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_queue_dir; 34 /* int var_use_limit; 35 /* int var_idle_limit; 36 /* int var_event_drain; 37 /* int var_bundle_rcpt; 38 /* char *var_procname; 39 /* int var_pid; 40 /* int var_ipc_timeout; 41 /* char *var_pid_dir; 42 /* int var_dont_remove; 43 /* char *var_inet_interfaces; 44 /* char *var_proxy_interfaces; 45 /* char *var_inet_protocols; 46 /* char *var_mynetworks; 47 /* char *var_double_bounce_sender; 48 /* int var_line_limit; 49 /* char *var_alias_db_map; 50 /* long var_message_limit; 51 /* char *var_mail_release; 52 /* char *var_mail_version; 53 /* int var_ipc_idle_limit; 54 /* int var_ipc_ttl_limit; 55 /* char *var_db_type; 56 /* char *var_hash_queue_names; 57 /* int var_hash_queue_depth; 58 /* int var_trigger_timeout; 59 /* char *var_rcpt_delim; 60 /* int var_fork_tries; 61 /* int var_fork_delay; 62 /* int var_flock_tries; 63 /* int var_flock_delay; 64 /* int var_flock_stale; 65 /* int var_disable_dns; 66 /* int var_soft_bounce; 67 /* time_t var_starttime; 68 /* int var_ownreq_special; 69 /* int var_daemon_timeout; 70 /* char *var_syslog_facility; 71 /* char *var_relay_domains; 72 /* char *var_fflush_domains; 73 /* char *var_mynetworks_style; 74 /* char *var_verp_delims; 75 /* char *var_verp_filter; 76 /* char *var_par_dom_match; 77 /* char *var_config_dirs; 78 /* 79 /* int var_inet_windowsize; 80 /* char *var_import_environ; 81 /* char *var_export_environ; 82 /* char *var_debug_peer_list; 83 /* int var_debug_peer_level; 84 /* int var_in_flow_delay; 85 /* int var_fault_inj_code; 86 /* char *var_bounce_service; 87 /* char *var_cleanup_service; 88 /* char *var_defer_service; 89 /* char *var_pickup_service; 90 /* char *var_queue_service; 91 /* char *var_rewrite_service; 92 /* char *var_showq_service; 93 /* char *var_error_service; 94 /* char *var_flush_service; 95 /* char *var_verify_service; 96 /* char *var_trace_service; 97 /* char *var_proxymap_service; 98 /* char *var_proxywrite_service; 99 /* int var_db_create_buf; 100 /* int var_db_read_buf; 101 /* long var_lmdb_map_size; 102 /* int var_proc_limit; 103 /* int var_mime_maxdepth; 104 /* int var_mime_bound_len; 105 /* int var_header_limit; 106 /* int var_token_limit; 107 /* int var_disable_mime_input; 108 /* int var_disable_mime_oconv; 109 /* int var_strict_8bitmime; 110 /* int var_strict_7bit_hdrs; 111 /* int var_strict_8bit_body; 112 /* int var_strict_encoding; 113 /* int var_verify_neg_cache; 114 /* int var_oldlog_compat; 115 /* int var_delay_max_res; 116 /* char *var_int_filt_classes; 117 /* int var_cyrus_sasl_authzid; 118 /* 119 /* char *var_multi_conf_dirs; 120 /* char *var_multi_wrapper; 121 /* char *var_multi_group; 122 /* char *var_multi_name; 123 /* bool var_multi_enable; 124 /* bool var_long_queue_ids; 125 /* bool var_daemon_open_fatal; 126 /* 127 /* void mail_params_init() 128 /* 129 /* const char null_format_string[1]; 130 /* DESCRIPTION 131 /* This module (actually the associated include file) define the names 132 /* and defaults of all mail configuration parameters. 133 /* 134 /* mail_params_init() initializes the built-in parameters listed above. 135 /* These parameters are relied upon by library routines, so they are 136 /* initialized globally so as to avoid hard-to-find errors due to 137 /* missing initialization. This routine must be called early, at 138 /* least before entering a chroot jail. 139 /* 140 /* null_format_string is a workaround for gcc compilers that complain 141 /* about empty or null format strings. 142 /* DIAGNOSTICS 143 /* Fatal errors: out of memory; null system or domain name. 144 /* LICENSE 145 /* .ad 146 /* .fi 147 /* The Secure Mailer license must be distributed with this software. 148 /* AUTHOR(S) 149 /* Wietse Venema 150 /* IBM T.J. Watson Research 151 /* P.O. Box 704 152 /* Yorktown Heights, NY 10598, USA 153 /*--*/ 154 155 /* System library. */ 156 157 #include <sys_defs.h> 158 #include <unistd.h> 159 #include <stdlib.h> 160 #include <string.h> 161 #include <pwd.h> 162 #include <grp.h> 163 #include <time.h> 164 #include <ctype.h> 165 166 #ifdef STRCASECMP_IN_STRINGS_H 167 #include <strings.h> 168 #endif 169 170 /* Utility library. */ 171 172 #include <msg.h> 173 #include <msg_syslog.h> 174 #include <get_hostname.h> 175 #include <valid_hostname.h> 176 #include <stringops.h> 177 #include <safe.h> 178 #include <safe_open.h> 179 #include <mymalloc.h> 180 #include <dict.h> 181 #ifdef HAS_DB 182 #include <dict_db.h> 183 #endif 184 #ifdef HAS_LMDB 185 #include <dict_lmdb.h> 186 #endif 187 #include <inet_proto.h> 188 #include <vstring_vstream.h> 189 #include <iostuff.h> 190 191 /* Global library. */ 192 193 #include <mynetworks.h> 194 #include <mail_conf.h> 195 #include <mail_version.h> 196 #include <mail_proto.h> 197 #include <verp_sender.h> 198 #include <own_inet_addr.h> 199 #include <mail_params.h> 200 201 /* 202 * Special configuration variables. 203 */ 204 char *var_myhostname; 205 char *var_mydomain; 206 char *var_myorigin; 207 char *var_mydest; 208 char *var_relayhost; 209 char *var_transit_origin; 210 char *var_transit_dest; 211 char *var_mail_name; 212 int var_helpful_warnings; 213 char *var_syslog_name; 214 char *var_mail_owner; 215 uid_t var_owner_uid; 216 gid_t var_owner_gid; 217 char *var_sgid_group; 218 gid_t var_sgid_gid; 219 char *var_default_privs; 220 uid_t var_default_uid; 221 gid_t var_default_gid; 222 char *var_config_dir; 223 char *var_daemon_dir; 224 char *var_data_dir; 225 char *var_command_dir; 226 char *var_queue_dir; 227 int var_use_limit; 228 int var_event_drain; 229 int var_idle_limit; 230 int var_bundle_rcpt; 231 char *var_procname; 232 int var_pid; 233 int var_ipc_timeout; 234 char *var_pid_dir; 235 int var_dont_remove; 236 char *var_inet_interfaces; 237 char *var_proxy_interfaces; 238 char *var_inet_protocols; 239 char *var_mynetworks; 240 char *var_double_bounce_sender; 241 int var_line_limit; 242 char *var_alias_db_map; 243 long var_message_limit; 244 char *var_mail_release; 245 char *var_mail_version; 246 int var_ipc_idle_limit; 247 int var_ipc_ttl_limit; 248 char *var_db_type; 249 char *var_hash_queue_names; 250 int var_hash_queue_depth; 251 int var_trigger_timeout; 252 char *var_rcpt_delim; 253 int var_fork_tries; 254 int var_fork_delay; 255 int var_flock_tries; 256 int var_flock_delay; 257 int var_flock_stale; 258 int var_disable_dns; 259 int var_soft_bounce; 260 time_t var_starttime; 261 int var_ownreq_special; 262 int var_daemon_timeout; 263 char *var_syslog_facility; 264 char *var_relay_domains; 265 char *var_fflush_domains; 266 char *var_mynetworks_style; 267 char *var_verp_delims; 268 char *var_verp_filter; 269 int var_in_flow_delay; 270 char *var_par_dom_match; 271 char *var_config_dirs; 272 273 int var_inet_windowsize; 274 char *var_import_environ; 275 char *var_export_environ; 276 char *var_debug_peer_list; 277 int var_debug_peer_level; 278 int var_fault_inj_code; 279 char *var_bounce_service; 280 char *var_cleanup_service; 281 char *var_defer_service; 282 char *var_pickup_service; 283 char *var_queue_service; 284 char *var_rewrite_service; 285 char *var_showq_service; 286 char *var_error_service; 287 char *var_flush_service; 288 char *var_verify_service; 289 char *var_trace_service; 290 char *var_proxymap_service; 291 char *var_proxywrite_service; 292 int var_db_create_buf; 293 int var_db_read_buf; 294 long var_lmdb_map_size; 295 int var_proc_limit; 296 int var_mime_maxdepth; 297 int var_mime_bound_len; 298 int var_header_limit; 299 int var_token_limit; 300 int var_disable_mime_input; 301 int var_disable_mime_oconv; 302 int var_strict_8bitmime; 303 int var_strict_7bit_hdrs; 304 int var_strict_8bit_body; 305 int var_strict_encoding; 306 int var_verify_neg_cache; 307 int var_oldlog_compat; 308 int var_delay_max_res; 309 char *var_int_filt_classes; 310 int var_cyrus_sasl_authzid; 311 312 char *var_multi_conf_dirs; 313 char *var_multi_wrapper; 314 char *var_multi_group; 315 char *var_multi_name; 316 bool var_multi_enable; 317 bool var_long_queue_ids; 318 bool var_daemon_open_fatal; 319 320 const char null_format_string[1] = ""; 321 322 /* check_myhostname - lookup hostname and validate */ 323 324 static const char *check_myhostname(void) 325 { 326 static const char *name; 327 const char *dot; 328 const char *domain; 329 330 /* 331 * Use cached result. 332 */ 333 if (name) 334 return (name); 335 336 /* 337 * If the local machine name is not in FQDN form, try to append the 338 * contents of $mydomain. Use a default domain as a final workaround. 339 */ 340 name = get_hostname(); 341 if ((dot = strchr(name, '.')) == 0) { 342 if ((domain = mail_conf_lookup_eval(VAR_MYDOMAIN)) == 0) 343 domain = DEF_MYDOMAIN; 344 name = concatenate(name, ".", domain, (char *) 0); 345 } 346 return (name); 347 } 348 349 /* check_mydomainname - lookup domain name and validate */ 350 351 static const char *check_mydomainname(void) 352 { 353 char *dot; 354 355 /* 356 * Use a default domain when the hostname is not a FQDN ("foo"). 357 */ 358 if ((dot = strchr(var_myhostname, '.')) == 0) 359 return (DEF_MYDOMAIN); 360 return (dot + 1); 361 } 362 363 /* check_default_privs - lookup default user attributes and validate */ 364 365 static void check_default_privs(void) 366 { 367 struct passwd *pwd; 368 369 if ((pwd = getpwnam(var_default_privs)) == 0) 370 msg_fatal("file %s/%s: parameter %s: unknown user name value: %s", 371 var_config_dir, MAIN_CONF_FILE, 372 VAR_DEFAULT_PRIVS, var_default_privs); 373 if ((var_default_uid = pwd->pw_uid) == 0) 374 msg_fatal("file %s/%s: parameter %s: user %s has privileged user ID", 375 var_config_dir, MAIN_CONF_FILE, 376 VAR_DEFAULT_PRIVS, var_default_privs); 377 if ((var_default_gid = pwd->pw_gid) == 0) 378 msg_fatal("file %s/%s: parameter %s: user %s has privileged group ID", 379 var_config_dir, MAIN_CONF_FILE, 380 VAR_DEFAULT_PRIVS, var_default_privs); 381 } 382 383 /* check_mail_owner - lookup owner user attributes and validate */ 384 385 static void check_mail_owner(void) 386 { 387 struct passwd *pwd; 388 389 if ((pwd = getpwnam(var_mail_owner)) == 0) 390 msg_fatal("file %s/%s: parameter %s: unknown user name value: %s", 391 var_config_dir, MAIN_CONF_FILE, 392 VAR_MAIL_OWNER, var_mail_owner); 393 if ((var_owner_uid = pwd->pw_uid) == 0) 394 msg_fatal("file %s/%s: parameter %s: user %s has privileged user ID", 395 var_config_dir, MAIN_CONF_FILE, 396 VAR_MAIL_OWNER, var_mail_owner); 397 if ((var_owner_gid = pwd->pw_gid) == 0) 398 msg_fatal("file %s/%s: parameter %s: user %s has privileged group ID", 399 var_config_dir, MAIN_CONF_FILE, 400 VAR_MAIL_OWNER, var_mail_owner); 401 402 /* 403 * This detects only some forms of sharing. Enumerating the entire 404 * password file name space could be expensive. The purpose of this code 405 * is to discourage user ID sharing by developers and package 406 * maintainers. 407 */ 408 if ((pwd = getpwuid(var_owner_uid)) != 0 409 && strcmp(pwd->pw_name, var_mail_owner) != 0) 410 msg_fatal("file %s/%s: parameter %s: user %s has same user ID as %s", 411 var_config_dir, MAIN_CONF_FILE, 412 VAR_MAIL_OWNER, var_mail_owner, pwd->pw_name); 413 } 414 415 /* check_sgid_group - lookup setgid group attributes and validate */ 416 417 static void check_sgid_group(void) 418 { 419 struct group *grp; 420 421 if ((grp = getgrnam(var_sgid_group)) == 0) 422 msg_fatal("file %s/%s: parameter %s: unknown group name: %s", 423 var_config_dir, MAIN_CONF_FILE, 424 VAR_SGID_GROUP, var_sgid_group); 425 if ((var_sgid_gid = grp->gr_gid) == 0) 426 msg_fatal("file %s/%s: parameter %s: group %s has privileged group ID", 427 var_config_dir, MAIN_CONF_FILE, 428 VAR_SGID_GROUP, var_sgid_group); 429 430 /* 431 * This detects only some forms of sharing. Enumerating the entire group 432 * file name space could be expensive. The purpose of this code is to 433 * discourage group ID sharing by developers and package maintainers. 434 */ 435 if ((grp = getgrgid(var_sgid_gid)) != 0 436 && strcmp(grp->gr_name, var_sgid_group) != 0) 437 msg_fatal("file %s/%s: parameter %s: group %s has same group ID as %s", 438 var_config_dir, MAIN_CONF_FILE, 439 VAR_SGID_GROUP, var_sgid_group, grp->gr_name); 440 } 441 442 /* check_overlap - disallow UID or GID sharing */ 443 444 static void check_overlap(void) 445 { 446 if (strcmp(var_default_privs, var_mail_owner) == 0) 447 msg_fatal("file %s/%s: parameters %s and %s specify the same user %s", 448 var_config_dir, MAIN_CONF_FILE, 449 VAR_DEFAULT_PRIVS, VAR_MAIL_OWNER, 450 var_default_privs); 451 if (var_default_uid == var_owner_uid) 452 msg_fatal("file %s/%s: parameters %s and %s: users %s and %s have the same user ID: %ld", 453 var_config_dir, MAIN_CONF_FILE, 454 VAR_DEFAULT_PRIVS, VAR_MAIL_OWNER, 455 var_default_privs, var_mail_owner, 456 (long) var_owner_uid); 457 if (var_default_gid == var_owner_gid) 458 msg_fatal("file %s/%s: parameters %s and %s: users %s and %s have the same group ID: %ld", 459 var_config_dir, MAIN_CONF_FILE, 460 VAR_DEFAULT_PRIVS, VAR_MAIL_OWNER, 461 var_default_privs, var_mail_owner, 462 (long) var_owner_gid); 463 if (var_default_gid == var_sgid_gid) 464 msg_fatal("file %s/%s: parameters %s and %s: user %s and group %s have the same group ID: %ld", 465 var_config_dir, MAIN_CONF_FILE, 466 VAR_DEFAULT_PRIVS, VAR_SGID_GROUP, 467 var_default_privs, var_sgid_group, 468 (long) var_sgid_gid); 469 if (var_owner_gid == var_sgid_gid) 470 msg_fatal("file %s/%s: parameters %s and %s: user %s and group %s have the same group ID: %ld", 471 var_config_dir, MAIN_CONF_FILE, 472 VAR_MAIL_OWNER, VAR_SGID_GROUP, 473 var_mail_owner, var_sgid_group, 474 (long) var_sgid_gid); 475 } 476 477 #ifdef MYORIGIN_FROM_FILE 478 479 /* read_param_from_file - read parameter value from file */ 480 481 static char *read_param_from_file(const char *path) 482 { 483 VSTRING *why = vstring_alloc(100); 484 VSTRING *buf = vstring_alloc(100); 485 VSTREAM *fp; 486 char *bp; 487 char *result; 488 489 /* 490 * Ugly macros to make complex expressions less unreadable. 491 */ 492 #define SKIP(start, var, cond) do { \ 493 for (var = start; *var && (cond); var++) \ 494 /* void */; \ 495 } while (0) 496 497 #define TRIM(s) do { \ 498 char *p; \ 499 for (p = (s) + strlen(s); p > (s) && ISSPACE(p[-1]); p--) \ 500 /* void */; \ 501 *p = 0; \ 502 } while (0) 503 504 fp = safe_open(path, O_RDONLY, 0, (struct stat *) 0, -1, -1, why); 505 if (fp == 0) 506 msg_fatal("%s: %s", path, vstring_str(why)); 507 vstring_get_nonl(buf, fp); 508 if (vstream_ferror(fp)) /* FIX 20070501 */ 509 msg_fatal("%s: read error: %m", path); 510 vstream_fclose(fp); 511 SKIP(vstring_str(buf), bp, ISSPACE(*bp)); 512 TRIM(bp); 513 result = mystrdup(bp); 514 515 vstring_free(why); 516 vstring_free(buf); 517 return (result); 518 } 519 520 #endif 521 522 /* mail_params_init - configure built-in parameters */ 523 524 void mail_params_init() 525 { 526 static const CONFIG_STR_TABLE first_str_defaults[] = { 527 VAR_SYSLOG_FACILITY, DEF_SYSLOG_FACILITY, &var_syslog_facility, 1, 0, 528 VAR_INET_PROTOCOLS, DEF_INET_PROTOCOLS, &var_inet_protocols, 0, 0, 529 VAR_MULTI_CONF_DIRS, DEF_MULTI_CONF_DIRS, &var_multi_conf_dirs, 0, 0, 530 /* multi_instance_wrapper may have dependencies but not dependents. */ 531 VAR_MULTI_GROUP, DEF_MULTI_GROUP, &var_multi_group, 0, 0, 532 VAR_MULTI_NAME, DEF_MULTI_NAME, &var_multi_name, 0, 0, 533 0, 534 }; 535 static const CONFIG_BOOL_TABLE first_bool_defaults[] = { 536 /* read and process the following before opening tables. */ 537 VAR_DAEMON_OPEN_FATAL, DEF_DAEMON_OPEN_FATAL, &var_daemon_open_fatal, 538 0, 539 }; 540 static const CONFIG_STR_FN_TABLE function_str_defaults[] = { 541 VAR_MYHOSTNAME, check_myhostname, &var_myhostname, 1, 0, 542 VAR_MYDOMAIN, check_mydomainname, &var_mydomain, 1, 0, 543 0, 544 }; 545 static const CONFIG_STR_TABLE other_str_defaults[] = { 546 VAR_MAIL_NAME, DEF_MAIL_NAME, &var_mail_name, 1, 0, 547 VAR_SYSLOG_NAME, DEF_SYSLOG_NAME, &var_syslog_name, 1, 0, 548 VAR_MAIL_OWNER, DEF_MAIL_OWNER, &var_mail_owner, 1, 0, 549 VAR_SGID_GROUP, DEF_SGID_GROUP, &var_sgid_group, 1, 0, 550 VAR_MYDEST, DEF_MYDEST, &var_mydest, 0, 0, 551 VAR_MYORIGIN, DEF_MYORIGIN, &var_myorigin, 1, 0, 552 VAR_RELAYHOST, DEF_RELAYHOST, &var_relayhost, 0, 0, 553 VAR_DAEMON_DIR, DEF_DAEMON_DIR, &var_daemon_dir, 1, 0, 554 VAR_DATA_DIR, DEF_DATA_DIR, &var_data_dir, 1, 0, 555 VAR_COMMAND_DIR, DEF_COMMAND_DIR, &var_command_dir, 1, 0, 556 VAR_QUEUE_DIR, DEF_QUEUE_DIR, &var_queue_dir, 1, 0, 557 VAR_PID_DIR, DEF_PID_DIR, &var_pid_dir, 1, 0, 558 VAR_INET_INTERFACES, DEF_INET_INTERFACES, &var_inet_interfaces, 0, 0, 559 VAR_PROXY_INTERFACES, DEF_PROXY_INTERFACES, &var_proxy_interfaces, 0, 0, 560 VAR_DOUBLE_BOUNCE, DEF_DOUBLE_BOUNCE, &var_double_bounce_sender, 1, 0, 561 VAR_DEFAULT_PRIVS, DEF_DEFAULT_PRIVS, &var_default_privs, 1, 0, 562 VAR_ALIAS_DB_MAP, DEF_ALIAS_DB_MAP, &var_alias_db_map, 0, 0, 563 VAR_MAIL_RELEASE, DEF_MAIL_RELEASE, &var_mail_release, 1, 0, 564 VAR_MAIL_VERSION, DEF_MAIL_VERSION, &var_mail_version, 1, 0, 565 VAR_DB_TYPE, DEF_DB_TYPE, &var_db_type, 1, 0, 566 VAR_HASH_QUEUE_NAMES, DEF_HASH_QUEUE_NAMES, &var_hash_queue_names, 1, 0, 567 VAR_RCPT_DELIM, DEF_RCPT_DELIM, &var_rcpt_delim, 0, 0, 568 VAR_RELAY_DOMAINS, DEF_RELAY_DOMAINS, &var_relay_domains, 0, 0, 569 VAR_FFLUSH_DOMAINS, DEF_FFLUSH_DOMAINS, &var_fflush_domains, 0, 0, 570 VAR_EXPORT_ENVIRON, DEF_EXPORT_ENVIRON, &var_export_environ, 0, 0, 571 VAR_IMPORT_ENVIRON, DEF_IMPORT_ENVIRON, &var_import_environ, 0, 0, 572 VAR_MYNETWORKS_STYLE, DEF_MYNETWORKS_STYLE, &var_mynetworks_style, 1, 0, 573 VAR_DEBUG_PEER_LIST, DEF_DEBUG_PEER_LIST, &var_debug_peer_list, 0, 0, 574 VAR_VERP_DELIMS, DEF_VERP_DELIMS, &var_verp_delims, 2, 2, 575 VAR_VERP_FILTER, DEF_VERP_FILTER, &var_verp_filter, 1, 0, 576 VAR_PAR_DOM_MATCH, DEF_PAR_DOM_MATCH, &var_par_dom_match, 0, 0, 577 VAR_CONFIG_DIRS, DEF_CONFIG_DIRS, &var_config_dirs, 0, 0, 578 VAR_BOUNCE_SERVICE, DEF_BOUNCE_SERVICE, &var_bounce_service, 1, 0, 579 VAR_CLEANUP_SERVICE, DEF_CLEANUP_SERVICE, &var_cleanup_service, 1, 0, 580 VAR_DEFER_SERVICE, DEF_DEFER_SERVICE, &var_defer_service, 1, 0, 581 VAR_PICKUP_SERVICE, DEF_PICKUP_SERVICE, &var_pickup_service, 1, 0, 582 VAR_QUEUE_SERVICE, DEF_QUEUE_SERVICE, &var_queue_service, 1, 0, 583 VAR_REWRITE_SERVICE, DEF_REWRITE_SERVICE, &var_rewrite_service, 1, 0, 584 VAR_SHOWQ_SERVICE, DEF_SHOWQ_SERVICE, &var_showq_service, 1, 0, 585 VAR_ERROR_SERVICE, DEF_ERROR_SERVICE, &var_error_service, 1, 0, 586 VAR_FLUSH_SERVICE, DEF_FLUSH_SERVICE, &var_flush_service, 1, 0, 587 VAR_VERIFY_SERVICE, DEF_VERIFY_SERVICE, &var_verify_service, 1, 0, 588 VAR_TRACE_SERVICE, DEF_TRACE_SERVICE, &var_trace_service, 1, 0, 589 VAR_PROXYMAP_SERVICE, DEF_PROXYMAP_SERVICE, &var_proxymap_service, 1, 0, 590 VAR_PROXYWRITE_SERVICE, DEF_PROXYWRITE_SERVICE, &var_proxywrite_service, 1, 0, 591 VAR_INT_FILT_CLASSES, DEF_INT_FILT_CLASSES, &var_int_filt_classes, 0, 0, 592 /* multi_instance_wrapper may have dependencies but not dependents. */ 593 VAR_MULTI_WRAPPER, DEF_MULTI_WRAPPER, &var_multi_wrapper, 0, 0, 594 0, 595 }; 596 static const CONFIG_STR_FN_TABLE function_str_defaults_2[] = { 597 VAR_MYNETWORKS, mynetworks, &var_mynetworks, 0, 0, 598 0, 599 }; 600 static const CONFIG_INT_TABLE other_int_defaults[] = { 601 VAR_PROC_LIMIT, DEF_PROC_LIMIT, &var_proc_limit, 1, 0, 602 VAR_MAX_USE, DEF_MAX_USE, &var_use_limit, 1, 0, 603 VAR_DONT_REMOVE, DEF_DONT_REMOVE, &var_dont_remove, 0, 0, 604 VAR_LINE_LIMIT, DEF_LINE_LIMIT, &var_line_limit, 512, 0, 605 VAR_HASH_QUEUE_DEPTH, DEF_HASH_QUEUE_DEPTH, &var_hash_queue_depth, 1, 0, 606 VAR_FORK_TRIES, DEF_FORK_TRIES, &var_fork_tries, 1, 0, 607 VAR_FLOCK_TRIES, DEF_FLOCK_TRIES, &var_flock_tries, 1, 0, 608 VAR_DEBUG_PEER_LEVEL, DEF_DEBUG_PEER_LEVEL, &var_debug_peer_level, 1, 0, 609 VAR_FAULT_INJ_CODE, DEF_FAULT_INJ_CODE, &var_fault_inj_code, 0, 0, 610 VAR_DB_CREATE_BUF, DEF_DB_CREATE_BUF, &var_db_create_buf, 1, 0, 611 VAR_DB_READ_BUF, DEF_DB_READ_BUF, &var_db_read_buf, 1, 0, 612 VAR_HEADER_LIMIT, DEF_HEADER_LIMIT, &var_header_limit, 1, 0, 613 VAR_TOKEN_LIMIT, DEF_TOKEN_LIMIT, &var_token_limit, 1, 0, 614 VAR_MIME_MAXDEPTH, DEF_MIME_MAXDEPTH, &var_mime_maxdepth, 1, 0, 615 VAR_MIME_BOUND_LEN, DEF_MIME_BOUND_LEN, &var_mime_bound_len, 1, 0, 616 VAR_DELAY_MAX_RES, DEF_DELAY_MAX_RES, &var_delay_max_res, MIN_DELAY_MAX_RES, MAX_DELAY_MAX_RES, 617 VAR_INET_WINDOW, DEF_INET_WINDOW, &var_inet_windowsize, 0, 0, 618 0, 619 }; 620 static const CONFIG_LONG_TABLE long_defaults[] = { 621 VAR_MESSAGE_LIMIT, DEF_MESSAGE_LIMIT, &var_message_limit, 0, 0, 622 VAR_LMDB_MAP_SIZE, DEF_LMDB_MAP_SIZE, &var_lmdb_map_size, 1, 0, 623 0, 624 }; 625 static const CONFIG_TIME_TABLE time_defaults[] = { 626 VAR_EVENT_DRAIN, DEF_EVENT_DRAIN, &var_event_drain, 1, 0, 627 VAR_MAX_IDLE, DEF_MAX_IDLE, &var_idle_limit, 1, 0, 628 VAR_IPC_TIMEOUT, DEF_IPC_TIMEOUT, &var_ipc_timeout, 1, 0, 629 VAR_IPC_IDLE, DEF_IPC_IDLE, &var_ipc_idle_limit, 1, 0, 630 VAR_IPC_TTL, DEF_IPC_TTL, &var_ipc_ttl_limit, 1, 0, 631 VAR_TRIGGER_TIMEOUT, DEF_TRIGGER_TIMEOUT, &var_trigger_timeout, 1, 0, 632 VAR_FORK_DELAY, DEF_FORK_DELAY, &var_fork_delay, 1, 0, 633 VAR_FLOCK_DELAY, DEF_FLOCK_DELAY, &var_flock_delay, 1, 0, 634 VAR_FLOCK_STALE, DEF_FLOCK_STALE, &var_flock_stale, 1, 0, 635 VAR_DAEMON_TIMEOUT, DEF_DAEMON_TIMEOUT, &var_daemon_timeout, 1, 0, 636 VAR_IN_FLOW_DELAY, DEF_IN_FLOW_DELAY, &var_in_flow_delay, 0, 10, 637 0, 638 }; 639 static const CONFIG_BOOL_TABLE bool_defaults[] = { 640 VAR_DISABLE_DNS, DEF_DISABLE_DNS, &var_disable_dns, 641 VAR_SOFT_BOUNCE, DEF_SOFT_BOUNCE, &var_soft_bounce, 642 VAR_OWNREQ_SPECIAL, DEF_OWNREQ_SPECIAL, &var_ownreq_special, 643 VAR_STRICT_8BITMIME, DEF_STRICT_8BITMIME, &var_strict_8bitmime, 644 VAR_STRICT_7BIT_HDRS, DEF_STRICT_7BIT_HDRS, &var_strict_7bit_hdrs, 645 VAR_STRICT_8BIT_BODY, DEF_STRICT_8BIT_BODY, &var_strict_8bit_body, 646 VAR_STRICT_ENCODING, DEF_STRICT_ENCODING, &var_strict_encoding, 647 VAR_DISABLE_MIME_INPUT, DEF_DISABLE_MIME_INPUT, &var_disable_mime_input, 648 VAR_DISABLE_MIME_OCONV, DEF_DISABLE_MIME_OCONV, &var_disable_mime_oconv, 649 VAR_VERIFY_NEG_CACHE, DEF_VERIFY_NEG_CACHE, &var_verify_neg_cache, 650 VAR_OLDLOG_COMPAT, DEF_OLDLOG_COMPAT, &var_oldlog_compat, 651 VAR_HELPFUL_WARNINGS, DEF_HELPFUL_WARNINGS, &var_helpful_warnings, 652 VAR_CYRUS_SASL_AUTHZID, DEF_CYRUS_SASL_AUTHZID, &var_cyrus_sasl_authzid, 653 VAR_MULTI_ENABLE, DEF_MULTI_ENABLE, &var_multi_enable, 654 VAR_LONG_QUEUE_IDS, DEF_LONG_QUEUE_IDS, &var_long_queue_ids, 655 0, 656 }; 657 const char *cp; 658 INET_PROTO_INFO *proto_info; 659 660 /* 661 * Extract syslog_facility early, so that from here on all errors are 662 * logged with the proper facility. 663 */ 664 get_mail_conf_str_table(first_str_defaults); 665 666 if (!msg_syslog_facility(var_syslog_facility)) 667 msg_fatal("file %s/%s: parameter %s: unrecognized value: %s", 668 var_config_dir, MAIN_CONF_FILE, 669 VAR_SYSLOG_FACILITY, var_syslog_facility); 670 671 /* 672 * Should daemons terminate after table open error, or should they 673 * continue execution with reduced functionality? 674 */ 675 get_mail_conf_bool_table(first_bool_defaults); 676 if (var_daemon_open_fatal) 677 dict_allow_surrogate = 0; 678 679 /* 680 * What protocols should we attempt to support? The result is stored in 681 * the global inet_proto_table variable. 682 */ 683 proto_info = inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols); 684 685 /* 686 * Variables whose defaults are determined at runtime. Some sites use 687 * short hostnames in the host table; some sites name their system after 688 * the domain. 689 */ 690 get_mail_conf_str_fn_table(function_str_defaults); 691 if (!valid_hostname(var_myhostname, DO_GRIPE)) 692 msg_fatal("file %s/%s: parameter %s: bad parameter value: %s", 693 var_config_dir, MAIN_CONF_FILE, 694 VAR_MYHOSTNAME, var_myhostname); 695 if (!valid_hostname(var_mydomain, DO_GRIPE)) 696 msg_fatal("file %s/%s: parameter %s: bad parameter value: %s", 697 var_config_dir, MAIN_CONF_FILE, 698 VAR_MYDOMAIN, var_mydomain); 699 700 /* 701 * Variables that are needed by almost every program. 702 * 703 * XXX Reading the myorigin value from file is originally a Debian Linux 704 * feature. This code is not enabled by default because of problems: 1) 705 * it re-implements its own parameter syntax checks, and 2) it does not 706 * implement $name expansions. 707 */ 708 get_mail_conf_str_table(other_str_defaults); 709 #ifdef MYORIGIN_FROM_FILE 710 if (*var_myorigin == '/') { 711 char *origin = read_param_from_file(var_myorigin); 712 713 if (*origin == 0) 714 msg_fatal("%s file %s is empty", VAR_MYORIGIN, var_myorigin); 715 myfree(var_myorigin); /* FIX 20070501 */ 716 var_myorigin = origin; 717 } 718 #endif 719 get_mail_conf_int_table(other_int_defaults); 720 get_mail_conf_long_table(long_defaults); 721 get_mail_conf_bool_table(bool_defaults); 722 get_mail_conf_time_table(time_defaults); 723 check_default_privs(); 724 check_mail_owner(); 725 check_sgid_group(); 726 check_overlap(); 727 #ifdef HAS_DB 728 dict_db_cache_size = var_db_read_buf; 729 #endif 730 #ifdef HAS_LMDB 731 dict_lmdb_map_size = var_lmdb_map_size; 732 #endif 733 inet_windowsize = var_inet_windowsize; 734 735 /* 736 * Variables whose defaults are determined at runtime, after other 737 * variables have been set. This dependency is admittedly a bit tricky. 738 * XXX Perhaps we should just register variables, and let the evaluator 739 * figure out in what order to evaluate things. 740 */ 741 get_mail_conf_str_fn_table(function_str_defaults_2); 742 743 /* 744 * FIX 200412 The IPv6 patch did not call own_inet_addr_list() before 745 * entering the chroot jail on Linux IPv6 systems. Linux has the IPv6 746 * interface list in /proc, which is not available after chrooting. 747 */ 748 (void) own_inet_addr_list(); 749 750 /* 751 * The PID variable cannot be set from the configuration file!! 752 */ 753 set_mail_conf_int(VAR_PID, var_pid = getpid()); 754 755 /* 756 * Neither can the start time variable. It isn't even visible. 757 */ 758 time(&var_starttime); 759 760 /* 761 * Export the syslog name so children can inherit and use it before they 762 * have initialized. 763 */ 764 if ((cp = safe_getenv(CONF_ENV_LOGTAG)) == 0 765 || strcmp(cp, var_syslog_name) != 0) 766 if (setenv(CONF_ENV_LOGTAG, var_syslog_name, 1) < 0) 767 msg_fatal("setenv %s %s: %m", CONF_ENV_LOGTAG, var_syslog_name); 768 769 /* 770 * I have seen this happen just too often. 771 */ 772 if (strcasecmp(var_myhostname, var_relayhost) == 0) 773 msg_fatal("%s and %s parameter settings must not be identical: %s", 774 VAR_MYHOSTNAME, VAR_RELAYHOST, var_myhostname); 775 776 /* 777 * XXX These should be caught by a proper parameter parsing algorithm. 778 */ 779 if (var_myorigin[strcspn(var_myorigin, ", \t\r\n")]) 780 msg_fatal("%s parameter setting must not contain multiple values: %s", 781 VAR_MYORIGIN, var_myorigin); 782 783 if (var_relayhost[strcspn(var_relayhost, ", \t\r\n")]) 784 msg_fatal("%s parameter setting must not contain multiple values: %s", 785 VAR_RELAYHOST, var_relayhost); 786 787 /* 788 * One more sanity check. 789 */ 790 if ((cp = verp_delims_verify(var_verp_delims)) != 0) 791 msg_fatal("file %s/%s: parameters %s and %s: %s", 792 var_config_dir, MAIN_CONF_FILE, 793 VAR_VERP_DELIMS, VAR_VERP_FILTER, cp); 794 } 795