static void post_init(char *unused_name, char **unused_argv) { /* * Drop privileges most of the time. */ set_eugid(var_owner_uid, var_owner_gid); /* * No case folding needed: the recipient address is case folded. */ virtual_mailbox_maps = maps_create(VAR_VIRT_MAILBOX_MAPS, var_virt_mailbox_maps, DICT_FLAG_LOCK | DICT_FLAG_PARANOID); virtual_uid_maps = maps_create(VAR_VIRT_UID_MAPS, var_virt_uid_maps, DICT_FLAG_LOCK | DICT_FLAG_PARANOID); virtual_gid_maps = maps_create(VAR_VIRT_GID_MAPS, var_virt_gid_maps, DICT_FLAG_LOCK | DICT_FLAG_PARANOID); virtual_mbox_lock_mask = mbox_lock_mask(var_virt_mailbox_lock); }
void smtp_tls_list_init(void) { if (*var_smtp_tls_policy) { tls_policy = maps_create(VAR_SMTP_TLS_POLICY, var_smtp_tls_policy, DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); if (*var_smtp_tls_per_site) msg_warn("%s ignored when %s is not empty.", VAR_SMTP_TLS_PER_SITE, VAR_SMTP_TLS_POLICY); return; } if (*var_smtp_tls_per_site) { tls_per_site = maps_create(VAR_SMTP_TLS_PER_SITE, var_smtp_tls_per_site, DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); } }
static void pre_init(char *unused_name, char **unused_argv) { /* * Reset the file size limit from the message size limit to the mailbox * size limit. XXX This still isn't accurate because the file size limit * also affects delivery to command. * * A file size limit protects the machine against runaway software errors. * It is not suitable to enforce mail quota, because users can get around * mail quota by delivering to /file/name or to |command. * * We can't have mailbox size limit smaller than the message size limit, * because that prohibits the delivery agent from updating the queue * file. */ if (var_mailbox_limit) { if (var_mailbox_limit < var_message_limit || var_message_limit == 0) msg_fatal("main.cf configuration error: %s is smaller than %s", VAR_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT); set_file_limit(var_mailbox_limit); } alias_maps = maps_create("aliases", var_alias_maps, DICT_FLAG_LOCK | DICT_FLAG_PARANOID | DICT_FLAG_FOLD_FIX); flush_init(); }
int main(int argc, char **argv) { VSTRING *buf = vstring_alloc(100); MAPS *maps; msg_vstream_init(basename(argv[0]), VSTREAM_ERR); if (argc < 3) msg_fatal("usage: %s maptype:mapname address...", argv[0]); maps = maps_create(argv[1], argv[1], DICT_FLAG_FOLD_FIX); mail_params_init(); if (chdir(var_queue_dir) < 0) msg_fatal("chdir(%s): %m", var_queue_dir); argv += 1; msg_verbose = 1; while (--argc && *++argv) { msg_info("-- start %s --", *argv); smtp_map11_external(vstring_strcpy(buf, *argv), maps, 1); msg_info("-- end %s --", *argv); } vstring_free(buf); maps_free(maps); return (0); }
int main(int argc, char **argv) { VSTRING *buf = vstring_alloc(100); MAPS *maps; const char *result; if (argc != 2) msg_fatal("usage: %s maps", argv[0]); msg_verbose = 2; maps = maps_create("whatever", argv[1], DICT_FLAG_LOCK); while (vstring_fgets_nonl(buf, VSTREAM_IN)) { if ((result = maps_find(maps, vstring_str(buf), 0)) != 0) { vstream_printf("%s\n", result); } else if (dict_errno != 0) { msg_fatal("lookup error: %m"); } else { vstream_printf("not found\n"); } vstream_fflush(VSTREAM_OUT); } maps_free(maps); vstring_free(buf); return (0); }
void resolve_init(void) { query = vstring_alloc(100); channel = vstring_alloc(100); nexthop = vstring_alloc(100); nextrcpt = vstring_alloc(100); if (*var_virt_alias_doms) virt_alias_doms = string_list_init(MATCH_FLAG_NONE, var_virt_alias_doms); if (*var_virt_mailbox_doms) virt_mailbox_doms = string_list_init(MATCH_FLAG_NONE, var_virt_mailbox_doms); if (*var_relay_domains) relay_domains = domain_list_init(match_parent_style(VAR_RELAY_DOMAINS), var_relay_domains); if (*var_relocated_maps) relocated_maps = maps_create(VAR_RELOCATED_MAPS, var_relocated_maps, DICT_FLAG_LOCK); }
int main(int argc, char **argv) { VSTRING *buffer = vstring_alloc(100); MAPS *path; const char *result; char *extent; /* * Parse JCL. */ if (argc != 2) msg_fatal("usage: %s database", argv[0]); msg_verbose = 1; /* * Initialize. */ mail_conf_read(); path = maps_create(argv[0], argv[1], DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); while (vstring_fgets_nonl(buffer, VSTREAM_IN)) { extent = 0; result = mail_addr_find(path, STR(buffer), &extent); vstream_printf("%s -> %s (%s)\n", STR(buffer), result ? result : path->error ? "(try again)" : "(not found)", extent ? extent : "null extension"); vstream_fflush(VSTREAM_OUT); if (extent) myfree(extent); } vstring_free(buffer); maps_free(path); return (0); }
static void pre_jail_init(char *unused_name, char **unused_argv) { command = vstring_alloc(100); rewrite_init(); resolve_init(); if (*RES_PARAM_VALUE(resolve_regular.transport_maps)) resolve_regular.transport_info = transport_pre_init(resolve_regular.transport_maps_name, RES_PARAM_VALUE(resolve_regular.transport_maps)); if (*RES_PARAM_VALUE(resolve_verify.transport_maps)) resolve_verify.transport_info = transport_pre_init(resolve_verify.transport_maps_name, RES_PARAM_VALUE(resolve_verify.transport_maps)); if (*RES_PARAM_VALUE(resolve_regular.snd_relay_maps)) resolve_regular.snd_relay_info = maps_create(resolve_regular.snd_relay_maps_name, RES_PARAM_VALUE(resolve_regular.snd_relay_maps), DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX | DICT_FLAG_NO_REGSUB); if (*RES_PARAM_VALUE(resolve_verify.snd_relay_maps)) resolve_verify.snd_relay_info = maps_create(resolve_verify.snd_relay_maps_name, RES_PARAM_VALUE(resolve_verify.snd_relay_maps), DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX | DICT_FLAG_NO_REGSUB); if (*RES_PARAM_VALUE(resolve_regular.snd_def_xp_maps)) resolve_regular.snd_def_xp_info = maps_create(resolve_regular.snd_def_xp_maps_name, RES_PARAM_VALUE(resolve_regular.snd_def_xp_maps), DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX | DICT_FLAG_NO_REGSUB); if (*RES_PARAM_VALUE(resolve_verify.snd_def_xp_maps)) resolve_verify.snd_def_xp_info = maps_create(resolve_verify.snd_def_xp_maps_name, RES_PARAM_VALUE(resolve_verify.snd_def_xp_maps), DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX | DICT_FLAG_NO_REGSUB); }
void pcs_send_pre_jail_init(void) { static int init_count = 0; if (init_count++ != 0) msg_panic("pcs_send_pre_jail_init: multiple calls"); /* * SMTP server reject footer. */ if (*var_psc_rej_ftr_maps) psc_rej_ftr_maps = maps_create(VAR_SMTPD_REJ_FTR_MAPS, var_psc_rej_ftr_maps, DICT_FLAG_LOCK); }
TRANSPORT_INFO *transport_pre_init(const char *transport_maps_name, const char *transport_maps) { TRANSPORT_INFO *tp; tp = (TRANSPORT_INFO *) mymalloc(sizeof(*tp)); tp->transport_path = maps_create(transport_maps_name, transport_maps, DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX | DICT_FLAG_NO_REGSUB | DICT_FLAG_UTF8_REQUEST); tp->wildcard_channel = tp->wildcard_nexthop = 0; tp->wildcard_errno = 0; tp->expire = 0; return (tp); }
/** * Create sense operator, y = F S x, * where F is the Fourier transform and S is the sensitivity maps * * @param max_dims maximal dimensions across all data structures * @param sens_flags active map dimensions * @param sens sensitivities * @param gpu TRUE if using gpu */ struct linop_s* sense_init(const long max_dims[DIMS], unsigned int sens_flags, const complex float* sens, bool gpu) { long ksp_dims[DIMS]; md_select_dims(DIMS, ~MAPS_FLAG, ksp_dims, max_dims); struct linop_s* fft = linop_fft_create(DIMS, ksp_dims, FFT_FLAGS, gpu); struct linop_s* maps = maps_create(max_dims, sens_flags, sens, gpu); struct linop_s* sense_op = linop_chain(maps, fft); linop_free(fft); linop_free(maps); return sense_op; }
void smtp_sasl_initialize(void) { /* * Sanity check. */ if (smtp_sasl_passwd_map || smtp_sasl_impl) msg_panic("smtp_sasl_initialize: repeated call"); if (*var_smtp_sasl_passwd == 0) msg_fatal("specify a password table via the `%s' configuration parameter", VAR_SMTP_SASL_PASSWD); /* * Open the per-host password table and initialize the SASL library. Use * shared locks for reading, just in case someone updates the table. */ smtp_sasl_passwd_map = maps_create("smtp_sasl_passwd", var_smtp_sasl_passwd, DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); if ((smtp_sasl_impl = xsasl_client_init(var_smtp_sasl_type, var_smtp_sasl_path)) == 0) msg_fatal("SASL library initialization"); /* * Initialize optional supported mechanism matchlist */ if (*var_smtp_sasl_mechs) smtp_sasl_mechs = string_list_init(MATCH_FLAG_NONE, var_smtp_sasl_mechs); /* * Initialize the 535 SASL authentication failure cache. */ if (*var_smtp_sasl_auth_cache_name) { #ifdef HAVE_SASL_AUTH_CACHE smtp_sasl_auth_cache = smtp_sasl_auth_cache_init(var_smtp_sasl_auth_cache_name, var_smtp_sasl_auth_cache_time); #else msg_warn("not compiled with TLS support -- " "ignoring the " VAR_SMTP_SASL_AUTH_CACHE_NAME " setting"); #endif } }
int main(int argc, char **argv) { VSTRING *buffer = vstring_alloc(100); MAPS *path; ARGV *result; /* * Parse JCL. */ if (argc != 2) msg_fatal("usage: %s database", argv[0]); /* * Initialize. */ #define UPDATE(dst, src) { myfree(dst); dst = mystrdup(src); } mail_conf_read(); msg_verbose = 1; if (chdir(var_queue_dir) < 0) msg_fatal("chdir %s: %m", var_queue_dir); path = maps_create(argv[0], argv[1], DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); while (vstring_fgets_nonl(buffer, VSTREAM_IN)) { msg_info("=== Address extension on, extension propagation on ==="); UPDATE(var_rcpt_delim, "+"); if ((result = mail_addr_map(path, STR(buffer), 1)) != 0) argv_free(result); msg_info("=== Address extension on, extension propagation off ==="); if ((result = mail_addr_map(path, STR(buffer), 0)) != 0) argv_free(result); msg_info("=== Address extension off ==="); UPDATE(var_rcpt_delim, ""); if ((result = mail_addr_map(path, STR(buffer), 1)) != 0) argv_free(result); } vstring_free(buffer); maps_free(path); return (0); }
static void pre_init(char *unused_name, char **unused_argv) { int use_tls; static const NAME_CODE addr_pref_map[] = { INET_PROTO_NAME_IPV6, SMTP_MISC_FLAG_PREF_IPV6, INET_PROTO_NAME_IPV4, SMTP_MISC_FLAG_PREF_IPV4, INET_PROTO_NAME_ANY, 0, 0, -1, }; /* * Turn on per-peer debugging. */ debug_peer_init(); /* * SASL initialization. */ if (var_smtp_sasl_enable) #ifdef USE_SASL_AUTH smtp_sasl_initialize(); #else msg_warn("%s is true, but SASL support is not compiled in", VAR_SMTP_SASL_ENABLE); #endif if (*var_smtp_tls_level != 0) switch (tls_level_lookup(var_smtp_tls_level)) { case TLS_LEV_SECURE: case TLS_LEV_VERIFY: case TLS_LEV_FPRINT: case TLS_LEV_ENCRYPT: var_smtp_use_tls = var_smtp_enforce_tls = 1; break; case TLS_LEV_MAY: var_smtp_use_tls = 1; var_smtp_enforce_tls = 0; break; case TLS_LEV_NONE: var_smtp_use_tls = var_smtp_enforce_tls = 0; break; default: /* tls_level_lookup() logs no warning. */ /* session_tls_init() assumes that var_smtp_tls_level is sane. */ msg_fatal("Invalid TLS level \"%s\"", var_smtp_tls_level); } use_tls = (var_smtp_use_tls || var_smtp_enforce_tls); /* * Initialize the TLS data before entering the chroot jail */ if (use_tls || var_smtp_tls_per_site[0] || var_smtp_tls_policy[0]) { #ifdef USE_TLS TLS_CLIENT_INIT_PROPS props; int using_smtp = (strcmp(var_procname, "smtp") == 0); /* * We get stronger type safety and a cleaner interface by combining * the various parameters into a single tls_client_props structure. * * Large parameter lists are error-prone, so we emulate a language * feature that C does not have natively: named parameter lists. */ smtp_tls_ctx = TLS_CLIENT_INIT(&props, log_param = using_smtp ? VAR_SMTP_TLS_LOGLEVEL : VAR_LMTP_TLS_LOGLEVEL, log_level = var_smtp_tls_loglevel, verifydepth = var_smtp_tls_scert_vd, cache_type = using_smtp ? TLS_MGR_SCACHE_SMTP : TLS_MGR_SCACHE_LMTP, cert_file = var_smtp_tls_cert_file, key_file = var_smtp_tls_key_file, dcert_file = var_smtp_tls_dcert_file, dkey_file = var_smtp_tls_dkey_file, eccert_file = var_smtp_tls_eccert_file, eckey_file = var_smtp_tls_eckey_file, CAfile = var_smtp_tls_CAfile, CApath = var_smtp_tls_CApath, fpt_dgst = var_smtp_tls_fpt_dgst); smtp_tls_list_init(); #else msg_warn("TLS has been selected, but TLS support is not compiled in"); #endif } /* * Flush client. */ flush_init(); /* * Session cache domain list. */ if (*var_smtp_cache_dest) smtp_cache_dest = string_list_init(MATCH_FLAG_RETURN, var_smtp_cache_dest); /* * EHLO keyword filter. */ if (*var_smtp_ehlo_dis_maps) smtp_ehlo_dis_maps = maps_create(VAR_SMTP_EHLO_DIS_MAPS, var_smtp_ehlo_dis_maps, DICT_FLAG_LOCK); /* * PIX bug workarounds. */ if (*var_smtp_pix_bug_maps) smtp_pix_bug_maps = maps_create(VAR_SMTP_PIX_BUG_MAPS, var_smtp_pix_bug_maps, DICT_FLAG_LOCK); /* * Generic maps. */ if (*var_prop_extension) smtp_ext_prop_mask = ext_prop_mask(VAR_PROP_EXTENSION, var_prop_extension); if (*var_smtp_generic_maps) smtp_generic_maps = maps_create(VAR_SMTP_GENERIC_MAPS, var_smtp_generic_maps, DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); /* * Header/body checks. */ smtp_header_checks = hbc_header_checks_create( VAR_SMTP_HEAD_CHKS, var_smtp_head_chks, VAR_SMTP_MIME_CHKS, var_smtp_mime_chks, VAR_SMTP_NEST_CHKS, var_smtp_nest_chks, smtp_hbc_callbacks); smtp_body_checks = hbc_body_checks_create( VAR_SMTP_BODY_CHKS, var_smtp_body_chks, smtp_hbc_callbacks); /* * Server reply filter. */ if (*var_smtp_resp_filter) smtp_chat_resp_filter = dict_open(var_smtp_resp_filter, O_RDONLY, DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); /* * Address family preference. */ if (*var_smtp_addr_pref) { smtp_addr_pref = name_code(addr_pref_map, NAME_CODE_FLAG_NONE, var_smtp_addr_pref); if (smtp_addr_pref < 0) msg_fatal("bad %s value: %s", VAR_SMTP_ADDR_PREF, var_smtp_addr_pref); } }
int deliver_unknown(LOCAL_STATE state, USER_ATTR usr_attr) { const char *myname = "deliver_unknown"; int status; VSTRING *expand_luser; static MAPS *transp_maps; const char *map_transport; /* * Make verbose logging easier to understand. */ state.level++; if (msg_verbose) MSG_LOG_STATE(myname, state); /* * DUPLICATE/LOOP ELIMINATION * * Don't deliver the same user twice. */ if (been_here(state.dup_filter, "%s %s", myname, state.msg_attr.local)) return (0); /* * The fall-back transport specifies a delivery machanism that handles * users not found in the aliases or UNIX passwd databases. */ if (*var_fbck_transp_maps && transp_maps == 0) transp_maps = maps_create(VAR_FBCK_TRANSP_MAPS, var_fbck_transp_maps, DICT_FLAG_LOCK | DICT_FLAG_NO_REGSUB); /* The -1 is a hint for the down-stream deliver_completed() function. */ if (transp_maps && (map_transport = maps_find(transp_maps, state.msg_attr.user, DICT_FLAG_NONE)) != 0) { state.msg_attr.rcpt.offset = -1L; return (deliver_pass(MAIL_CLASS_PRIVATE, map_transport, state.request, &state.msg_attr.rcpt)); } else if (transp_maps && transp_maps->error != 0) { /* Details in the logfile. */ dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure"); return (defer_append(BOUNCE_FLAGS(state.request), BOUNCE_ATTR(state.msg_attr))); } if (*var_fallback_transport) { state.msg_attr.rcpt.offset = -1L; return (deliver_pass(MAIL_CLASS_PRIVATE, var_fallback_transport, state.request, &state.msg_attr.rcpt)); } /* * Subject the luser_relay address to $name expansion, disable * propagation of unmatched address extension, and re-inject the address * into the delivery machinery. Do not give special treatment to "|stuff" * or /stuff. */ if (*var_luser_relay) { state.msg_attr.unmatched = 0; expand_luser = vstring_alloc(100); local_expand(expand_luser, var_luser_relay, &state, &usr_attr, (char *) 0); status = deliver_resolve_addr(state, usr_attr, STR(expand_luser)); vstring_free(expand_luser); return (status); } /* * If no alias was found for a required reserved name, toss the message * into the bit bucket, and issue a warning instead. */ #define STREQ(x,y) (strcasecmp(x,y) == 0) if (STREQ(state.msg_attr.local, MAIL_ADDR_MAIL_DAEMON) || STREQ(state.msg_attr.local, MAIL_ADDR_POSTMASTER)) { msg_warn("required alias not found: %s", state.msg_attr.local); dsb_simple(state.msg_attr.why, "2.0.0", "discarded"); return (sent(BOUNCE_FLAGS(state.request), SENT_ATTR(state.msg_attr))); } /* * Bounce the message when no luser relay is specified. */ dsb_simple(state.msg_attr.why, "5.1.1", "unknown user: \"%s\"", state.msg_attr.local); return (bounce_append(BOUNCE_FLAGS(state.request), BOUNCE_ATTR(state.msg_attr))); }
int deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp) { const char *myname = "deliver_mailbox"; int status; struct mypasswd *mbox_pwd; char *path; static MAPS *transp_maps; const char *map_transport; static MAPS *cmd_maps; const char *map_command; /* * Make verbose logging easier to understand. */ state.level++; if (msg_verbose) MSG_LOG_STATE(myname, state); /* * DUPLICATE ELIMINATION * * Don't come here more than once, whether or not the recipient exists. */ if (been_here(state.dup_filter, "mailbox %s", state.msg_attr.local)) return (YES); /* * Delegate mailbox delivery to another message transport. */ if (*var_mbox_transp_maps && transp_maps == 0) transp_maps = maps_create(VAR_MBOX_TRANSP_MAPS, var_mbox_transp_maps, DICT_FLAG_LOCK | DICT_FLAG_NO_REGSUB); /* The -1 is a hint for the down-stream deliver_completed() function. */ if (transp_maps && (map_transport = maps_find(transp_maps, state.msg_attr.user, DICT_FLAG_NONE)) != 0) { state.msg_attr.rcpt.offset = -1L; *statusp = deliver_pass(MAIL_CLASS_PRIVATE, map_transport, state.request, &state.msg_attr.rcpt); return (YES); } else if (transp_maps && transp_maps->error != 0) { /* Details in the logfile. */ dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure"); *statusp = defer_append(BOUNCE_FLAGS(state.request), BOUNCE_ATTR(state.msg_attr)); return (YES); } if (*var_mailbox_transport) { state.msg_attr.rcpt.offset = -1L; *statusp = deliver_pass(MAIL_CLASS_PRIVATE, var_mailbox_transport, state.request, &state.msg_attr.rcpt); return (YES); } /* * Skip delivery when this recipient does not exist. */ if ((errno = mypwnam_err(state.msg_attr.user, &mbox_pwd)) != 0) { msg_warn("error looking up passwd info for %s: %m", state.msg_attr.user); dsb_simple(state.msg_attr.why, "4.0.0", "user lookup error"); *statusp = defer_append(BOUNCE_FLAGS(state.request), BOUNCE_ATTR(state.msg_attr)); return (YES); } if (mbox_pwd == 0) return (NO); /* * No early returns or we have a memory leak. */ /* * DELIVERY RIGHTS * * Use the rights of the recipient user. */ SET_USER_ATTR(usr_attr, mbox_pwd, state.level); /* * Deliver to mailbox, maildir or to external command. */ #define LAST_CHAR(s) (s[strlen(s) - 1]) if (*var_mailbox_cmd_maps && cmd_maps == 0) cmd_maps = maps_create(VAR_MAILBOX_CMD_MAPS, var_mailbox_cmd_maps, DICT_FLAG_LOCK | DICT_FLAG_PARANOID); if (cmd_maps && (map_command = maps_find(cmd_maps, state.msg_attr.user, DICT_FLAG_NONE)) != 0) { status = deliver_command(state, usr_attr, map_command); } else if (cmd_maps && cmd_maps->error != 0) { /* Details in the logfile. */ dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure"); status = defer_append(BOUNCE_FLAGS(state.request), BOUNCE_ATTR(state.msg_attr)); } else if (*var_mailbox_command) { status = deliver_command(state, usr_attr, var_mailbox_command); } else if (*var_home_mailbox && LAST_CHAR(var_home_mailbox) == '/') { path = concatenate(usr_attr.home, "/", var_home_mailbox, (char *) 0); status = deliver_maildir(state, usr_attr, path); myfree(path); } else if (*var_mail_spool_dir && LAST_CHAR(var_mail_spool_dir) == '/') { path = concatenate(var_mail_spool_dir, state.msg_attr.user, "/", (char *) 0); status = deliver_maildir(state, usr_attr, path); myfree(path); } else status = deliver_mailbox_file(state, usr_attr); /* * Cleanup. */ mypwfree(mbox_pwd); *statusp = status; return (YES); }
void cleanup_pre_jail(char *unused_name, char **unused_argv) { static const 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 const 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 const 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 const 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 | DICT_FLAG_FOLD_FIX); if (*var_send_canon_maps) cleanup_send_canon_maps = maps_create(VAR_SEND_CANON_MAPS, var_send_canon_maps, DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); if (*var_rcpt_canon_maps) cleanup_rcpt_canon_maps = maps_create(VAR_RCPT_CANON_MAPS, var_rcpt_canon_maps, DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); if (*var_virt_alias_maps) cleanup_virt_alias_maps = maps_create(VAR_VIRT_ALIAS_MAPS, var_virt_alias_maps, DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); 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 | DICT_FLAG_FOLD_FIX); if (*var_rcpt_bcc_maps) cleanup_rcpt_bcc_maps = maps_create(VAR_RCPT_BCC_MAPS, var_rcpt_bcc_maps, DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); if (*var_cleanup_milters) cleanup_milters = milter_create(var_cleanup_milters, var_milt_conn_time, var_milt_cmd_time, var_milt_msg_time, var_milt_protocol, var_milt_def_action, var_milt_conn_macros, var_milt_helo_macros, var_milt_mail_macros, var_milt_rcpt_macros, var_milt_data_macros, var_milt_eoh_macros, var_milt_eod_macros, var_milt_unk_macros); flush_init(); }
int main(int argc, char **argv) { VSTRING *buffer = vstring_alloc(100); char *bp; MAPS *path = 0; const char *result; char *extent; char *cmd; char *in_field; char *query_field; char *out_field; char *strategy_field; char *key_field; char *expect_res; char *expect_ext; int in_form; int query_form; int out_form; int strategy_flags; int ch; int errs = 0; /* * Parse JCL. */ while ((ch = GETOPT(argc, argv, "v")) > 0) { switch (ch) { case 'v': msg_verbose++; break; default: usage(argv[0]); } } if (argc != optind) usage(argv[0]); /* * Initialize. */ #define UPDATE(var, val) do { myfree(var); var = mystrdup(val); } while (0) mail_params_init(); /* * TODO: move these assignments into the read/eval loop. */ UPDATE(var_rcpt_delim, "+"); UPDATE(var_mydomain, "localdomain"); UPDATE(var_myorigin, "localdomain"); UPDATE(var_mydest, "localhost.localdomain"); while (vstring_fgets_nonl(buffer, VSTREAM_IN)) { bp = STR(buffer); if (msg_verbose) msg_info("> %s", bp); if ((cmd = mystrtok(&bp, CHARS_SPACE)) == 0 || *cmd == '#') continue; while (ISSPACE(*bp)) bp++; /* * Visible comment. */ if (strcmp(cmd, "echo") == 0) { vstream_printf("%s\n", bp); } /* * Open maps. */ else if (strcmp(cmd, "maps") == 0) { if (path) maps_free(path); path = maps_create(argv[0], bp, DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX | DICT_FLAG_UTF8_REQUEST); vstream_printf("%s\n", bp); continue; } /* * Lookup and verify. */ else if (path && strcmp(cmd, "test") == 0) { /* * Parse the input and expectations. */ /* internal, external. */ if ((in_field = mystrtok(&bp, ":")) == 0) msg_fatal("no input form"); if ((in_form = mail_addr_form_from_string(in_field)) < 0) msg_fatal("bad input form: '%s'", in_field); if ((query_field = mystrtok(&bp, ":")) == 0) msg_fatal("no query form"); /* internal, external, external-first. */ if ((query_form = mail_addr_form_from_string(query_field)) < 0) msg_fatal("bad query form: '%s'", query_field); if ((out_field = mystrtok(&bp, ":")) == 0) msg_fatal("no output form"); /* internal, external. */ if ((out_form = mail_addr_form_from_string(out_field)) < 0) msg_fatal("bad output form: '%s'", out_field); if ((strategy_field = mystrtok(&bp, ":")) == 0) msg_fatal("no strategy field"); if ((strategy_flags = strategy_from_string(strategy_field)) < 0) msg_fatal("bad strategy field: '%s'", strategy_field); if ((key_field = mystrtok(&bp, ":")) == 0) msg_fatal("no search key"); expect_res = mystrtok(&bp, ":"); expect_ext = mystrtok(&bp, ":"); if (mystrtok(&bp, ":") != 0) msg_fatal("garbage after extension field"); /* * Lookups. */ extent = 0; result = mail_addr_find_opt(path, key_field, &extent, in_form, query_form, out_form, strategy_flags); vstream_printf("%s:%s -%s-> %s:%s (%s)\n", in_field, key_field, query_field, out_field, result ? result : path->error ? "(try again)" : "(not found)", extent ? extent : "null extension"); vstream_fflush(VSTREAM_OUT); /* * Enforce expectations. */ if (expect_res && result) { if (strcmp(expect_res, result) != 0) { msg_warn("expect result '%s' but got '%s'", expect_res, result); errs = 1; if (expect_ext && extent) { if (strcmp(expect_ext, extent) != 0) msg_warn("expect extension '%s' but got '%s'", expect_ext, extent); errs = 1; } else if (expect_ext && !extent) { msg_warn("expect extension '%s' but got none", expect_ext); errs = 1; } else if (!expect_ext && extent) { msg_warn("expect no extension but got '%s'", extent); errs = 1; } } } else if (expect_res && !result) { msg_warn("expect result '%s' but got none", expect_res); errs = 1; } else if (!expect_res && result) { msg_warn("expected no result but got '%s'", result); errs = 1; } vstream_fflush(VSTREAM_OUT); if (extent) myfree(extent); } /* * Unknown request. */ else { msg_warn("bad request: %s", cmd); } } vstring_free(buffer); maps_free(path); return (errs != 0); }