/*++ /* NAME /* cleanup_init 3 /* SUMMARY /* cleanup callable interface, initializations /* SYNOPSIS /* #include "cleanup.h" /* /* CONFIG_INT_TABLE cleanup_int_table[]; /* /* CONFIG_BOOL_TABLE cleanup_bool_table[]; /* /* CONFIG_STR_TABLE cleanup_str_table[]; /* /* CONFIG_TIME_TABLE cleanup_time_table[]; /* /* void cleanup_pre_jail(service_name, argv) /* char *service_name; /* char **argv; /* /* void cleanup_post_jail(service_name, argv) /* char *service_name; /* char **argv; /* /* char *cleanup_path; /* /* void cleanup_all() /* DESCRIPTION /* This module implements a callable interface to the cleanup service /* for one-time initializations that must be done before any message /* processing can take place. /* /* cleanup_{int,str,time}_table[] specify configuration /* parameters that must be initialized before calling any functions /* in this module. These tables satisfy the interface as specified in /* single_service(3). /* /* cleanup_pre_jail() and cleanup_post_jail() perform mandatory /* initializations before and after the process enters the optional /* chroot jail. These functions satisfy the interface as specified /* in single_service(3). /* /* cleanup_path is either a null pointer or it is the name of a queue /* file that currently is being written. This information is used /* by cleanup_all() to remove incomplete files after a fatal error. /* /* cleanup_all() must be called in case of fatal error, in order /* to remove an incomplete queue file. Normally, as part of process /* initialization, one registers a msg_cleanup() handler and a signal() /* handler that both call cleanup_all() before terminating the process. /* DIAGNOSTICS /* Problems and transactions are logged to \fBsyslogd\fR(8). /* SEE ALSO /* cleanup_api(3) cleanup callable interface, message processing /* LICENSE /* .ad /* .fi /* The Secure Mailer license must be distributed with this software. /* AUTHOR(S) /* Wietse Venema /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA /*--*/ /* System library. */ #include /* Utility library. */ #include #include #include /* Global library. */ #include #include #include #include /* Application-specific. */ #include "cleanup.h" /* * Global state: any queue files that we have open, so that the error * handler can clean up in case of trouble. */ char *cleanup_path; /* queue file name */ /* * Tunable parameters. */ int var_hopcount_limit; /* max mailer hop count */ char *var_canonical_maps; /* common canonical maps */ char *var_send_canon_maps; /* sender canonical maps */ char *var_rcpt_canon_maps; /* recipient canonical maps */ char *var_canon_classes; /* what to canonicalize */ char *var_send_canon_classes; /* what sender to canonicalize */ char *var_rcpt_canon_classes; /* what recipient to canonicalize */ char *var_virt_alias_maps; /* virtual alias maps */ char *var_masq_domains; /* masquerade domains */ char *var_masq_exceptions; /* users not masqueraded */ char *var_header_checks; /* primary header checks */ char *var_mimehdr_checks; /* mime header checks */ char *var_nesthdr_checks; /* nested header checks */ char *var_body_checks; /* any body checks */ int var_dup_filter_limit; /* recipient dup filter */ bool var_enable_orcpt; /* Include orcpt in dup filter? */ char *var_empty_addr; /* destination of bounced bounces */ int var_delay_warn_time; /* delay that triggers warning */ char *var_prop_extension; /* propagate unmatched extension */ char *var_always_bcc; /* big brother */ char *var_rcpt_witheld; /* recipients not disclosed */ char *var_masq_classes; /* what to masquerade */ int var_qattr_count_limit; /* named attribute limit */ int var_virt_recur_limit; /* maximum virtual alias recursion */ int var_virt_expan_limit; /* maximum virtual alias expansion */ int var_body_check_len; /* when to stop body scan */ char *var_send_bcc_maps; /* sender auto-bcc maps */ char *var_rcpt_bcc_maps; /* recipient auto-bcc maps */ char *var_remote_rwr_domain; /* header-only surrogate */ CONFIG_INT_TABLE cleanup_int_table[] = { VAR_HOPCOUNT_LIMIT, DEF_HOPCOUNT_LIMIT, &var_hopcount_limit, 1, 0, VAR_DUP_FILTER_LIMIT, DEF_DUP_FILTER_LIMIT, &var_dup_filter_limit, 0, 0, VAR_QATTR_COUNT_LIMIT, DEF_QATTR_COUNT_LIMIT, &var_qattr_count_limit, 1, 0, VAR_VIRT_RECUR_LIMIT, DEF_VIRT_RECUR_LIMIT, &var_virt_recur_limit, 1, 0, VAR_VIRT_EXPAN_LIMIT, DEF_VIRT_EXPAN_LIMIT, &var_virt_expan_limit, 1, 0, VAR_BODY_CHECK_LEN, DEF_BODY_CHECK_LEN, &var_body_check_len, 0, 0, 0, }; CONFIG_BOOL_TABLE cleanup_bool_table[] = { VAR_ENABLE_ORCPT, DEF_ENABLE_ORCPT, &var_enable_orcpt, 0, }; CONFIG_TIME_TABLE cleanup_time_table[] = { VAR_DELAY_WARN_TIME, DEF_DELAY_WARN_TIME, &var_delay_warn_time, 0, 0, 0, }; CONFIG_STR_TABLE cleanup_str_table[] = { VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0, VAR_SEND_CANON_MAPS, DEF_SEND_CANON_MAPS, &var_send_canon_maps, 0, 0, VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps, 0, 0, VAR_CANON_CLASSES, DEF_CANON_CLASSES, &var_canon_classes, 1, 0, VAR_SEND_CANON_CLASSES, DEF_SEND_CANON_CLASSES, &var_send_canon_classes, 1, 0, VAR_RCPT_CANON_CLASSES, DEF_RCPT_CANON_CLASSES, &var_rcpt_canon_classes, 1, 0, VAR_VIRT_ALIAS_MAPS, DEF_VIRT_ALIAS_MAPS, &var_virt_alias_maps, 0, 0, VAR_MASQ_DOMAINS, DEF_MASQ_DOMAINS, &var_masq_domains, 0, 0, VAR_EMPTY_ADDR, DEF_EMPTY_ADDR, &var_empty_addr, 1, 0, VAR_MASQ_EXCEPTIONS, DEF_MASQ_EXCEPTIONS, &var_masq_exceptions, 0, 0, VAR_HEADER_CHECKS, DEF_HEADER_CHECKS, &var_header_checks, 0, 0, VAR_MIMEHDR_CHECKS, DEF_MIMEHDR_CHECKS, &var_mimehdr_checks, 0, 0, VAR_NESTHDR_CHECKS, DEF_NESTHDR_CHECKS, &var_nesthdr_checks, 0, 0, VAR_BODY_CHECKS, DEF_BODY_CHECKS, &var_body_checks, 0, 0, VAR_PROP_EXTENSION, DEF_PROP_EXTENSION, &var_prop_extension, 0, 0, VAR_ALWAYS_BCC, DEF_ALWAYS_BCC, &var_always_bcc, 0, 0, VAR_RCPT_WITHELD, DEF_RCPT_WITHELD, &var_rcpt_witheld, 1, 0, VAR_MASQ_CLASSES, DEF_MASQ_CLASSES, &var_masq_classes, 0, 0, VAR_SEND_BCC_MAPS, DEF_SEND_BCC_MAPS, &var_send_bcc_maps, 0, 0, VAR_RCPT_BCC_MAPS, DEF_RCPT_BCC_MAPS, &var_rcpt_bcc_maps, 0, 0, VAR_REM_RWR_DOMAIN, DEF_REM_RWR_DOMAIN, &var_remote_rwr_domain, 0, 0, 0, }; /* * Mappings. */ MAPS *cleanup_comm_canon_maps; MAPS *cleanup_send_canon_maps; MAPS *cleanup_rcpt_canon_maps; int cleanup_comm_canon_flags; int cleanup_send_canon_flags; int cleanup_rcpt_canon_flags; MAPS *cleanup_header_checks; MAPS *cleanup_mimehdr_checks; MAPS *cleanup_nesthdr_checks; MAPS *cleanup_body_checks; MAPS *cleanup_virt_alias_maps; ARGV *cleanup_masq_domains; STRING_LIST *cleanup_masq_exceptions; int cleanup_masq_flags; MAPS *cleanup_send_bcc_maps; MAPS *cleanup_rcpt_bcc_maps; /* * Address extension propagation restrictions. */ int cleanup_ext_prop_mask; /* cleanup_all - callback for the runtime error handler */ void cleanup_all(void) { if (cleanup_path && REMOVE(cleanup_path)) msg_warn("cleanup_all: remove %s: %m", cleanup_path); } /* cleanup_pre_jail - initialize before entering the chroot jail */ void cleanup_pre_jail(char *unused_name, char **unused_argv) { static NAME_MASK send_canon_class_table[] = { CANON_CLASS_ENV_FROM, CLEANUP_CANON_FLAG_ENV_FROM, CANON_CLASS_HDR_FROM, CLEANUP_CANON_FLAG_HDR_FROM, 0, }; static NAME_MASK rcpt_canon_class_table[] = { CANON_CLASS_ENV_RCPT, CLEANUP_CANON_FLAG_ENV_RCPT, CANON_CLASS_HDR_RCPT, CLEANUP_CANON_FLAG_HDR_RCPT, 0, }; static NAME_MASK canon_class_table[] = { CANON_CLASS_ENV_FROM, CLEANUP_CANON_FLAG_ENV_FROM, CANON_CLASS_ENV_RCPT, CLEANUP_CANON_FLAG_ENV_RCPT, CANON_CLASS_HDR_FROM, CLEANUP_CANON_FLAG_HDR_FROM, CANON_CLASS_HDR_RCPT, CLEANUP_CANON_FLAG_HDR_RCPT, 0, }; static NAME_MASK masq_class_table[] = { MASQ_CLASS_ENV_FROM, CLEANUP_MASQ_FLAG_ENV_FROM, MASQ_CLASS_ENV_RCPT, CLEANUP_MASQ_FLAG_ENV_RCPT, MASQ_CLASS_HDR_FROM, CLEANUP_MASQ_FLAG_HDR_FROM, MASQ_CLASS_HDR_RCPT, CLEANUP_MASQ_FLAG_HDR_RCPT, 0, }; if (*var_canonical_maps) cleanup_comm_canon_maps = maps_create(VAR_CANONICAL_MAPS, var_canonical_maps, DICT_FLAG_LOCK); if (*var_send_canon_maps) cleanup_send_canon_maps = maps_create(VAR_SEND_CANON_MAPS, var_send_canon_maps, DICT_FLAG_LOCK); if (*var_rcpt_canon_maps) cleanup_rcpt_canon_maps = maps_create(VAR_RCPT_CANON_MAPS, var_rcpt_canon_maps, DICT_FLAG_LOCK); if (*var_virt_alias_maps) cleanup_virt_alias_maps = maps_create(VAR_VIRT_ALIAS_MAPS, var_virt_alias_maps, DICT_FLAG_LOCK); if (*var_canon_classes) cleanup_comm_canon_flags = name_mask(VAR_CANON_CLASSES, canon_class_table, var_canon_classes); if (*var_send_canon_classes) cleanup_send_canon_flags = name_mask(VAR_CANON_CLASSES, send_canon_class_table, var_send_canon_classes); if (*var_rcpt_canon_classes) cleanup_rcpt_canon_flags = name_mask(VAR_CANON_CLASSES, rcpt_canon_class_table, var_rcpt_canon_classes); if (*var_masq_domains) cleanup_masq_domains = argv_split(var_masq_domains, " ,\t\r\n"); if (*var_header_checks) cleanup_header_checks = maps_create(VAR_HEADER_CHECKS, var_header_checks, DICT_FLAG_LOCK); if (*var_mimehdr_checks) cleanup_mimehdr_checks = maps_create(VAR_MIMEHDR_CHECKS, var_mimehdr_checks, DICT_FLAG_LOCK); if (*var_nesthdr_checks) cleanup_nesthdr_checks = maps_create(VAR_NESTHDR_CHECKS, var_nesthdr_checks, DICT_FLAG_LOCK); if (*var_body_checks) cleanup_body_checks = maps_create(VAR_BODY_CHECKS, var_body_checks, DICT_FLAG_LOCK); if (*var_masq_exceptions) cleanup_masq_exceptions = string_list_init(MATCH_FLAG_NONE, var_masq_exceptions); if (*var_masq_classes) cleanup_masq_flags = name_mask(VAR_MASQ_CLASSES, masq_class_table, var_masq_classes); if (*var_send_bcc_maps) cleanup_send_bcc_maps = maps_create(VAR_SEND_BCC_MAPS, var_send_bcc_maps, DICT_FLAG_LOCK); if (*var_rcpt_bcc_maps) cleanup_rcpt_bcc_maps = maps_create(VAR_RCPT_BCC_MAPS, var_rcpt_bcc_maps, DICT_FLAG_LOCK); flush_init(); } /* cleanup_post_jail - initialize after entering the chroot jail */ void cleanup_post_jail(char *unused_name, char **unused_argv) { /* * Optionally set the file size resource limit. XXX This limits the * message content to somewhat less than requested, because the total * queue file size also includes envelope information. Unless people set * really low limit, the difference is going to matter only when a queue * file has lots of recipients. */ if (var_message_limit > 0) set_file_limit((off_t) var_message_limit); /* * Control how unmatched extensions are propagated. */ cleanup_ext_prop_mask = ext_prop_mask(VAR_PROP_EXTENSION, var_prop_extension); }