Postfix 2.0.7 brings a few cosmetic patches. - The SMTP server access map actions HOLD, DISCARD, FILTER (and REDIRECT in snapshots) were broken with smtpd_delay_reject=no, and with ETRN. - The DISCARD action now works as expected and causes Postfix to skip other restrictions such as REJECT. - The postsuper manual page documented support for the -c command line option, but the feature was not implemented. - The VRFY command was broken as of Postfix 2.0, and would always reply with 252 (neutral) unless the service was disabled. Prereq: "2.0.6" diff -cr /tmp/postfix-2.0.6/src/global/mail_version.h ./src/global/mail_version.h *** /tmp/postfix-2.0.6/src/global/mail_version.h Wed Mar 5 21:09:55 2003 --- ./src/global/mail_version.h Wed Mar 19 10:26:08 2003 *************** *** 20,29 **** * Patches change the patchlevel and the release date. Snapshots change the * release date only, unless they include the same bugfix as a patch release. */ ! #define MAIL_RELEASE_DATE "20030305" #define VAR_MAIL_VERSION "mail_version" ! #define DEF_MAIL_VERSION "2.0.6" extern char *var_mail_version; /* --- 20,29 ---- * Patches change the patchlevel and the release date. Snapshots change the * release date only, unless they include the same bugfix as a patch release. */ ! #define MAIL_RELEASE_DATE "20030319" #define VAR_MAIL_VERSION "mail_version" ! #define DEF_MAIL_VERSION "2.0.7" extern char *var_mail_version; /* diff -cr /tmp/postfix-2.0.6/HISTORY ./HISTORY *** /tmp/postfix-2.0.6/HISTORY Wed Mar 5 20:52:11 2003 --- ./HISTORY Wed Mar 19 20:35:59 2003 *************** *** 7682,7687 **** --- 7682,7705 ---- systems against exploitation of the remote buffer overflow vulnerability described in CERT advisory CA-2003-07. + 20030311-19 + + Bugfix: the access map actions HOLD, DISCARD and FILTER + were broken with smtpd_delay_reject=no and with ETRN. Fixing + this required re-architecting of the actions code. Files: + smtpd/smtpd.[hc], smtpd/smtpd_check.c, smtpd/smtpd_state.c. + + 20030315 + + Bugfix: the postsuper manual page documented support for + the -c command line option, but it was not implemented. + File: postsuper/postsuper.c. + + Bugfix: the Postfix 2.0 recipient map checking code broke + the VRFY command, causing it to reply with status code 252 + for non-existent addresses. This required re-architecting + the recipient table lookup code. File: smtpd/smtpd_check.c. + Open problems: Low: after successful delivery, per-queue window += 1/window, diff -cr /tmp/postfix-2.0.6/conf/master.cf ./conf/master.cf *** /tmp/postfix-2.0.6/conf/master.cf Thu Jan 16 07:44:58 2003 --- ./conf/master.cf Sat Mar 8 15:46:58 2003 *************** *** 26,31 **** --- 26,33 ---- # directory (pathname is controlled by the queue_directory configuration # variable in the main.cf file). Presently, all Postfix daemons can run # chrooted, except for the pipe, virtual and local delivery daemons. + # The proxymap server can run chrooted, but doing so defeats most of + # the purpose of having that service in the first place. # The files in the examples/chroot-setup subdirectory describe how # to set up a Postfix chroot environment for your type of machine. # diff -cr /tmp/postfix-2.0.6/html/proxymap.8.html ./html/proxymap.8.html *** /tmp/postfix-2.0.6/html/proxymap.8.html Thu Feb 27 20:20:29 2003 --- ./html/proxymap.8.html Tue Mar 11 20:04:46 2003 *************** *** 88,94 **** The proxymap server opens only tables that are approved via the proxy_read_maps configuration parameter, does not talk to users, and can run at fixed low privilege, ! chrooted or not. The proxymap server is not a trusted daemon process, and must not be used to look up sensitive information such as --- 88,96 ---- The proxymap server opens only tables that are approved via the proxy_read_maps configuration parameter, does not talk to users, and can run at fixed low privilege, ! chrooted or not. However, running the proxymap server ! chrooted severely limits usability, because it can open ! only chrooted tables. The proxymap server is not a trusted daemon process, and must not be used to look up sensitive information such as diff -cr /tmp/postfix-2.0.6/html/uce.html ./html/uce.html *** /tmp/postfix-2.0.6/html/uce.html Sat Dec 21 19:52:34 2002 --- ./html/uce.html Sat Mar 8 09:19:20 2003 *************** *** 856,862 ****
  • Postfix is the final destination: any destination that matches $mydestination, $inet_interfaces, $virtual_alias_domains, or href="virtual.8.html">$virtual_mailbox_domains. --- 856,862 ----
  • Postfix is the final destination: any destination that matches $mydestination, $inet_interfaces, $virtual_alias_domains, or $virtual_mailbox_domains. diff -cr /tmp/postfix-2.0.6/man/man8/proxymap.8 ./man/man8/proxymap.8 *** /tmp/postfix-2.0.6/man/man8/proxymap.8 Thu Feb 27 20:20:28 2003 --- ./man/man8/proxymap.8 Tue Mar 11 20:04:46 2003 *************** *** 88,93 **** --- 88,95 ---- The proxymap server opens only tables that are approved via the \fBproxy_read_maps\fR configuration parameter, does not talk to users, and can run at fixed low privilege, chrooted or not. + However, running the proxymap server chrooted severely limits + usability, because it can open only chrooted tables. The proxymap server is not a trusted daemon process, and must not be used to look up sensitive information such as user or diff -cr /tmp/postfix-2.0.6/src/global/Makefile.in ./src/global/Makefile.in *** /tmp/postfix-2.0.6/src/global/Makefile.in Wed Mar 5 20:53:25 2003 --- ./src/global/Makefile.in Sat Mar 15 19:41:41 2003 *************** *** 1210,1215 **** --- 1210,1216 ---- tok822_parse.o: ../../include/vstring.h tok822_parse.o: ../../include/vbuf.h tok822_parse.o: ../../include/msg.h + tok822_parse.o: ../../include/stringops.h tok822_parse.o: lex_822.h tok822_parse.o: quote_822_local.h tok822_parse.o: quote_flags.h diff -cr /tmp/postfix-2.0.6/src/global/maps.c ./src/global/maps.c *** /tmp/postfix-2.0.6/src/global/maps.c Sun Dec 8 11:12:05 2002 --- ./src/global/maps.c Sun Mar 16 12:41:34 2003 *************** *** 184,197 **** continue; if ((expansion = dict_get(dict, name)) != 0) { if (msg_verbose) ! msg_info("%s: %s: %s = %s", myname, *map_name, name, expansion); return (expansion); } else if (dict_errno != 0) { break; } } if (msg_verbose) ! msg_info("%s: %s: %s", myname, name, dict_errno ? "search aborted" : "not found"); return (0); } --- 184,198 ---- continue; if ((expansion = dict_get(dict, name)) != 0) { if (msg_verbose) ! msg_info("%s: %s: %s: %s = %s", myname, maps->title, ! *map_name, name, expansion); return (expansion); } else if (dict_errno != 0) { break; } } if (msg_verbose) ! msg_info("%s: %s: %s: %s", myname, maps->title, name, dict_errno ? "search aborted" : "not found"); return (0); } diff -cr /tmp/postfix-2.0.6/src/global/tok822_parse.c ./src/global/tok822_parse.c *** /tmp/postfix-2.0.6/src/global/tok822_parse.c Wed Mar 5 20:52:23 2003 --- ./src/global/tok822_parse.c Sat Mar 8 11:34:35 2003 *************** *** 126,131 **** --- 126,132 ---- #include #include + #include /* Global library. */ *************** *** 250,256 **** * Emit plain
    . Discard any comments or phrases. */ msg_warn("stripping too many comments from address: %.100s...", ! vstring_str(vp) + start); vstring_truncate(vp, start); VSTRING_ADDCH(vp, '<'); if (addr) { --- 251,257 ---- * Emit plain
    . Discard any comments or phrases. */ msg_warn("stripping too many comments from address: %.100s...", ! printable(vstring_str(vp) + start, '?')); vstring_truncate(vp, start); VSTRING_ADDCH(vp, '<'); if (addr) { *************** *** 262,268 **** } VSTRING_ADDCH(vp, '>'); } - /* tok822_externalize - token tree to string, external form */ --- 263,268 ---- diff -cr /tmp/postfix-2.0.6/src/master/mail_flow.c ./src/master/mail_flow.c *** /tmp/postfix-2.0.6/src/master/mail_flow.c Fri Jan 11 10:21:01 2002 --- ./src/master/mail_flow.c Sat Mar 8 15:05:47 2003 *************** *** 47,52 **** --- 47,53 ---- #include #include #include + #include /* Utility library. */ diff -cr /tmp/postfix-2.0.6/src/postsuper/postsuper.c ./src/postsuper/postsuper.c *** /tmp/postfix-2.0.6/src/postsuper/postsuper.c Tue Jan 7 14:51:48 2003 --- ./src/postsuper/postsuper.c Sun Mar 16 19:50:29 2003 *************** *** 985,1000 **** msg_fatal("open /dev/null: %m"); /* ! * Process environment options as early as we can. We might be called ! * from a set-uid (set-gid) program, so be careful with importing ! * environment variables. */ if (safe_getenv(CONF_ENV_VERB)) msg_verbose = 1; /* ! * Initialize. Set up logging, read the global configuration file and ! * extract configuration information. */ if ((slash = strrchr(argv[0], '/')) != 0) argv[0] = slash + 1; --- 985,997 ---- msg_fatal("open /dev/null: %m"); /* ! * Process this environment option as early as we can, to aid debugging. */ if (safe_getenv(CONF_ENV_VERB)) msg_verbose = 1; /* ! * Initialize logging. */ if ((slash = strrchr(argv[0], '/')) != 0) argv[0] = slash + 1; *************** *** 1002,1048 **** msg_syslog_init(mail_task(argv[0]), LOG_PID, LOG_FACILITY); set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0])); - mail_conf_read(); - if (chdir(var_queue_dir)) - msg_fatal("chdir %s: %m", var_queue_dir); - /* ! * Be sure to log a warning if we do not finish structural repair. Maybe ! * we should have an fsck-style "clean" flag so Postfix will not start ! * with a broken queue. ! */ ! signal(SIGHUP, interrupted); ! signal(SIGINT, interrupted); ! signal(SIGQUIT, interrupted); ! signal(SIGTERM, interrupted); ! msg_cleanup(fatal_exit); ! ! /* ! * All file/directory updates must be done as the mail system owner. This ! * is because Postfix daemons manipulate the queue with those same ! * privileges, so directories must be created with the right ownership. ! * ! * Running as a non-root user is also required for security reasons. When ! * the Postfix queue hierarchy is compromised, an attacker could trick us ! * into entering other file hierarchies and afflicting damage. Running as ! * a non-root user limits the damage to the already compromised mail ! * owner. */ if (getuid()) msg_fatal("use of this command is reserved for the superuser"); - set_ugid(var_owner_uid, var_owner_gid); /* * Parse JCL. */ ! while ((c = GETOPT(argc, argv, "d:h:H:pr:sv")) > 0) { switch (c) { default: ! msg_fatal("usage: %s [-d queue_id (delete)] " "[-h queue_id (hold)] [-H queue_id (un-hold)] " "[-p (purge temporary files)] [-r queue_id (requeue)] " "[-s (structure fix)] [-v (verbose)] " "[queue...]", argv[0]); case 'd': if (delete_names == 0) delete_names = argv_alloc(1); --- 999,1035 ---- msg_syslog_init(mail_task(argv[0]), LOG_PID, LOG_FACILITY); set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0])); /* ! * Disallow unsafe practices, and refuse to run set-uid (or as the child ! * of a set-uid process). Whenever a privileged wrapper program is ! * needed, it must properly sanitize the real/effective/saved UID/GID, ! * the secondary groups, the process environment, and so on. Otherwise, ! * accidents can happen. If not with Postfix, then with other software. */ + if (unsafe() != 0) + msg_fatal("this postfix command must not run as a set-uid process"); if (getuid()) msg_fatal("use of this command is reserved for the superuser"); /* * Parse JCL. */ ! while ((c = GETOPT(argc, argv, "c:d:h:H:pr:sv")) > 0) { switch (c) { default: ! msg_fatal("usage: %s " ! "[-c config_dir] " ! "[-d queue_id (delete)] " "[-h queue_id (hold)] [-H queue_id (un-hold)] " "[-p (purge temporary files)] [-r queue_id (requeue)] " "[-s (structure fix)] [-v (verbose)] " "[queue...]", argv[0]); + case 'c': + if (*optarg != '/') + msg_fatal("-c requires absolute pathname"); + if (setenv(CONF_ENV_PATH, optarg, 1) < 0) + msg_fatal("setenv: %m"); + break; case 'd': if (delete_names == 0) delete_names = argv_alloc(1); *************** *** 1082,1087 **** --- 1069,1110 ---- break; } } + + /* + * Read the global configuration file and extract configuration + * information. The -c command option can override the default + * configuration directory location. + */ + mail_conf_read(); + if (chdir(var_queue_dir)) + msg_fatal("chdir %s: %m", var_queue_dir); + + /* + * All file/directory updates must be done as the mail system owner. This + * is because Postfix daemons manipulate the queue with those same + * privileges, so directories must be created with the right ownership. + * + * Running as a non-root user is also required for security reasons. When + * the Postfix queue hierarchy is compromised, an attacker could trick us + * into entering other file hierarchies and afflicting damage. Running as + * a non-root user limits the damage to the already compromised mail + * owner. + */ + set_ugid(var_owner_uid, var_owner_gid); + + /* + * Be sure to log a warning if we do not finish structural repair. Maybe + * we should have an fsck-style "clean" flag so Postfix will not start + * with a broken queue. + * + * Set up signal handlers after permanently dropping super-user privileges, + * so that signal handlers will always run with the correct privileges. + */ + signal(SIGHUP, interrupted); + signal(SIGINT, interrupted); + signal(SIGQUIT, interrupted); + signal(SIGTERM, interrupted); + msg_cleanup(fatal_exit); /* * Sanity checks. diff -cr /tmp/postfix-2.0.6/src/proxymap/proxymap.c ./src/proxymap/proxymap.c *** /tmp/postfix-2.0.6/src/proxymap/proxymap.c Thu Feb 27 20:06:01 2003 --- ./src/proxymap/proxymap.c Sat Mar 8 15:44:17 2003 *************** *** 78,83 **** --- 78,85 ---- /* The proxymap server opens only tables that are approved via the /* \fBproxy_read_maps\fR configuration parameter, does not talk to /* users, and can run at fixed low privilege, chrooted or not. + /* However, running the proxymap server chrooted severely limits + /* usability, because it can open only chrooted tables. /* /* The proxymap server is not a trusted daemon process, and must /* not be used to look up sensitive information such as user or diff -cr /tmp/postfix-2.0.6/src/smtpd/smtpd.c ./src/smtpd/smtpd.c *** /tmp/postfix-2.0.6/src/smtpd/smtpd.c Sat Mar 1 19:32:12 2003 --- ./src/smtpd/smtpd.c Wed Mar 19 11:25:39 2003 *************** *** 893,898 **** --- 893,899 ---- if (var_smtpd_sasl_enable) smtpd_sasl_mail_reset(state); #endif + state->discard = 0; } /* rcpt_cmd - process RCPT TO command */ *************** *** 951,960 **** smtpd_chat_reply(state, "%s", err); return (-1); } - if ((err = smtpd_check_rcptmap(state, argv[2].strval)) != 0) { - smtpd_chat_reply(state, "%s", err); - return (-1); - } } /* --- 952,957 ---- *************** *** 1259,1265 **** return (-1); } if (SMTPD_STAND_ALONE(state) == 0 ! && (err = smtpd_check_rcptmap(state, argv[1].strval)) != 0) { smtpd_chat_reply(state, "%s", err); return (-1); } --- 1256,1262 ---- return (-1); } if (SMTPD_STAND_ALONE(state) == 0 ! && (err = smtpd_check_rcpt(state, argv[1].strval)) != 0) { smtpd_chat_reply(state, "%s", err); return (-1); } diff -cr /tmp/postfix-2.0.6/src/smtpd/smtpd.h ./src/smtpd/smtpd.h *** /tmp/postfix-2.0.6/src/smtpd/smtpd.h Sat Dec 21 16:53:03 2002 --- ./src/smtpd/smtpd.h Wed Mar 19 10:35:49 2003 *************** *** 93,98 **** --- 93,99 ---- int defer_if_permit_client; /* force permit into warning */ int defer_if_permit_helo; /* force permit into warning */ int defer_if_permit_sender; /* force permit into warning */ + int discard; /* discard message */ VSTRING *expand_buf; /* scratch space for $name expansion */ } SMTPD_STATE; diff -cr /tmp/postfix-2.0.6/src/smtpd/smtpd_check.c ./src/smtpd/smtpd_check.c *** /tmp/postfix-2.0.6/src/smtpd/smtpd_check.c Sat Jan 25 17:56:39 2003 --- ./src/smtpd/smtpd_check.c Wed Mar 19 13:54:48 2003 *************** *** 24,33 **** /* SMTPD_STATE *state; /* char *recipient; /* - /* char *smtpd_check_rcptmap(state, recipient) - /* SMTPD_STATE *state; - /* char *recipient; - /* /* char *smtpd_check_etrn(state, destination) /* SMTPD_STATE *state; /* char *destination; --- 24,29 ---- *************** *** 192,202 **** /* .IP smtpd_recipient_restrictions /* Restrictions on the recipient address that is sent with the RCPT /* TO command. ! /* .PP ! /* smtpd_check_rcptmap() validates the recipient address provided ! /* with an RCPT TO request and sets the rcptmap_checked flag. ! /* Relevant configuration parameters: ! /* .IP local_recipients_map /* Tables of user names (not addresses) that exist in $mydestination. /* Mail for local users not in these tables is rejected. /* .PP --- 188,194 ---- /* .IP smtpd_recipient_restrictions /* Restrictions on the recipient address that is sent with the RCPT /* TO command. ! /* .IP local_recipient_maps /* Tables of user names (not addresses) that exist in $mydestination. /* Mail for local users not in these tables is rejected. /* .PP *************** *** 1622,1627 **** --- 1614,1644 ---- return (reject_unknown_mailhost(state, domain, reply_name, reply_class)); } + /* warn_skip_access_action - FILTER etc. action in unsupported context */ + + static void warn_skip_access_action(const char *table, const char *action, + const char *reply_class) + { + + /* + * Warn only about FILTER/HOLD/etc. access table actions that appear in + * restrictions where they will always be ignored. + */ + if (strcmp(reply_class, SMTPD_NAME_CLIENT) == 0 + || strcmp(reply_class, SMTPD_NAME_HELO) == 0 + || strcmp(reply_class, SMTPD_NAME_SENDER) == 0) { + if (var_smtpd_delay_reject == 0) + msg_warn("access table %s: with %s=%s, " + "action %s is always skipped in %s restrictions", + table, VAR_SMTPD_DELAY_REJECT, CONFIG_BOOL_NO, + action, reply_class); + } else { + msg_warn("access table %s: action %s is always " + "skipped in %s restrictions", + table, action, reply_class); + } + } + /* check_table_result - translate table lookup result into pass/reject */ static int check_table_result(SMTPD_STATE *state, const char *table, *************** *** 1673,1678 **** --- 1690,1701 ---- * mind, and reject/discard the message for other reasons. */ if (STREQUAL(value, "FILTER", cmd_len)) { + #ifndef TEST + if (state->dest == 0) { + warn_skip_access_action(table, "FILTER", reply_class); + return (SMTPD_CHECK_DUNNO); + } + #endif if (*cmd_text == 0) { msg_warn("access map %s entry \"%s\" has FILTER entry without value", table, datum); *************** *** 1697,1702 **** --- 1720,1731 ---- * reject/discard the message for other reasons. */ if (STREQUAL(value, "HOLD", cmd_len)) { + #ifndef TEST + if (state->dest == 0) { + warn_skip_access_action(table, "HOLD", reply_class); + return (SMTPD_CHECK_DUNNO); + } + #endif vstring_sprintf(error_text, "<%s>: %s %s", reply_name, reply_class, *cmd_text ? cmd_text : "triggers HOLD action"); log_whatsup(state, "hold", STR(error_text)); *************** *** 1709,1725 **** /* * DISCARD means silently discard and claim successful delivery. - * - * XXX Set some global flag that disables all further restrictions. - * Triggering a "reject" or "hold" action after "discard" is silly. */ if (STREQUAL(value, "DISCARD", cmd_len)) { vstring_sprintf(error_text, "<%s>: %s %s", reply_name, reply_class, *cmd_text ? cmd_text : "triggers DISCARD action"); log_whatsup(state, "discard", STR(error_text)); #ifndef TEST rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d", CLEANUP_FLAG_DISCARD); #endif return (SMTPD_CHECK_OK); } --- 1738,1758 ---- /* * DISCARD means silently discard and claim successful delivery. */ if (STREQUAL(value, "DISCARD", cmd_len)) { + #ifndef TEST + if (state->dest == 0) { + warn_skip_access_action(table, "DISCARD", reply_class); + return (SMTPD_CHECK_DUNNO); + } + #endif vstring_sprintf(error_text, "<%s>: %s %s", reply_name, reply_class, *cmd_text ? cmd_text : "triggers DISCARD action"); log_whatsup(state, "discard", STR(error_text)); #ifndef TEST rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d", CLEANUP_FLAG_DISCARD); + state->discard = 1; #endif return (SMTPD_CHECK_OK); } *************** *** 2548,2553 **** --- 2581,2589 ---- for (cpp = restrictions->argv; (name = *cpp) != 0; cpp++) { + if (state->discard != 0) + break; + if (msg_verbose) msg_info("%s: name=%s", myname, name); *************** *** 2998,3007 **** /* * The "check_recipient_maps" restriction is relevant only when ! * responding to RCPT TO. It's effectively disabled with DATA (recipient ! * context is explicitly turned off) and not applicable with undelayed ! * client/helo/sender restrictions (no recipient info) or with ETRN ! * (command not allowed in the middle of an ongoing MAIL transaction). */ state->rcptmap_checked = 0; --- 3034,3040 ---- /* * The "check_recipient_maps" restriction is relevant only when ! * responding to RCPT TO or VRFY. */ state->rcptmap_checked = 0; *************** *** 3027,3033 **** SMTPD_CHECK_RESET(); status = setjmp(smtpd_check_buf); if (status == 0 && rcpt_restrctions->argc) ! status = generic_checks(state, rcpt_restrctions, recipient, SMTPD_NAME_RECIPIENT, CHECK_RECIP_ACL); /* --- 3060,3066 ---- SMTPD_CHECK_RESET(); status = setjmp(smtpd_check_buf); if (status == 0 && rcpt_restrctions->argc) ! status = generic_checks(state, rcpt_restrctions, recipient, SMTPD_NAME_RECIPIENT, CHECK_RECIP_ACL); /* *************** *** 3038,3043 **** --- 3071,3084 ---- status = smtpd_check_reject(state, state->defer_if_permit.class, "%s", STR(state->defer_if_permit.reason)); + /* + * If the "check_recipient_maps" restriction was not applied, and if mail + * is not being rejected or discarded, validate the recipient here. + */ + if (status != SMTPD_CHECK_REJECT && state->rcptmap_checked == 0 + && state->discard == 0) + status = check_rcpt_maps(state, recipient); + SMTPD_CHECK_RCPT_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0); } *************** *** 3102,3126 **** SMTPD_CHECK_ETRN_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0); } - /* smtpd_check_rcptmap - permit if recipient address matches lookup table */ - - char *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient) - { - char *myname = "smtpd_check_rcptmap"; - int status; - - if (msg_verbose) - msg_info("%s: %s", myname, recipient); - - /* - * Return here in case of serious trouble. - */ - if ((status = setjmp(smtpd_check_buf)) == 0) - status = check_rcpt_maps(state, recipient); - - return (status == SMTPD_CHECK_REJECT ? STR(error_text) : 0); - } - /* check_rcpt_maps - generic_checks() interface for recipient table check */ static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient) --- 3143,3148 ---- *************** *** 3198,3210 **** if ((reply->flags & RESOLVE_CLASS_LOCAL) && *var_local_rcpt_maps ! /* Generated by bounce, absorbed by qmgr. */ && !MATCH_LEFT(var_double_bounce_sender, CONST_STR(reply->recipient), strlen(var_double_bounce_sender)) ! /* Absorbed by qmgr. */ && !MATCH_LEFT(MAIL_ADDR_POSTMASTER, CONST_STR(reply->recipient), strlen(MAIL_ADDR_POSTMASTER)) ! /* Generated by bounce. */ && !MATCH_LEFT(MAIL_ADDR_MAIL_DAEMON, CONST_STR(reply->recipient), strlen(MAIL_ADDR_MAIL_DAEMON)) && NOMATCH(local_rcpt_maps, CONST_STR(reply->recipient))) --- 3220,3232 ---- if ((reply->flags & RESOLVE_CLASS_LOCAL) && *var_local_rcpt_maps ! /* Generated by bounce, absorbed by qmgr. */ && !MATCH_LEFT(var_double_bounce_sender, CONST_STR(reply->recipient), strlen(var_double_bounce_sender)) ! /* Absorbed by qmgr. */ && !MATCH_LEFT(MAIL_ADDR_POSTMASTER, CONST_STR(reply->recipient), strlen(MAIL_ADDR_POSTMASTER)) ! /* Generated by bounce. */ && !MATCH_LEFT(MAIL_ADDR_MAIL_DAEMON, CONST_STR(reply->recipient), strlen(MAIL_ADDR_MAIL_DAEMON)) && NOMATCH(local_rcpt_maps, CONST_STR(reply->recipient))) *************** *** 3486,3491 **** --- 3508,3514 ---- int var_relay_rcpt_code; int var_virt_mailbox_code; int var_virt_alias_code; + int var_show_unk_rcpt_table; static INT_TABLE int_table[] = { "msg_verbose", 0, &msg_verbose, *************** *** 3505,3510 **** --- 3528,3534 ---- VAR_RELAY_RCPT_CODE, DEF_RELAY_RCPT_CODE, &var_relay_rcpt_code, VAR_VIRT_ALIAS_CODE, DEF_VIRT_ALIAS_CODE, &var_virt_alias_code, VAR_VIRT_MAILBOX_CODE, DEF_VIRT_MAILBOX_CODE, &var_virt_mailbox_code, + VAR_SHOW_UNK_RCPT_TABLE, DEF_SHOW_UNK_RCPT_TABLE, &var_show_unk_rcpt_table, 0, }; *************** *** 3883,3890 **** } else if (strcasecmp(args->argv[0], "rcpt") == 0) { state.where = "RCPT"; TRIM_ADDR(args->argv[1], addr); ! (resp = smtpd_check_rcpt(&state, addr)) ! || (resp = smtpd_check_rcptmap(&state, addr)); } break; --- 3907,3913 ---- } else if (strcasecmp(args->argv[0], "rcpt") == 0) { state.where = "RCPT"; TRIM_ADDR(args->argv[1], addr); ! resp = smtpd_check_rcpt(&state, addr); } break; diff -cr /tmp/postfix-2.0.6/src/smtpd/smtpd_check.h ./src/smtpd/smtpd_check.h *** /tmp/postfix-2.0.6/src/smtpd/smtpd_check.h Thu Sep 5 15:14:41 2002 --- ./src/smtpd/smtpd_check.h Wed Mar 19 10:35:04 2003 *************** *** 16,22 **** extern char *smtpd_check_client(SMTPD_STATE *); extern char *smtpd_check_helo(SMTPD_STATE *, char *); extern char *smtpd_check_mail(SMTPD_STATE *, char *); - extern char *smtpd_check_rcptmap(SMTPD_STATE *, char *); extern char *smtpd_check_size(SMTPD_STATE *, off_t); extern char *smtpd_check_rcpt(SMTPD_STATE *, char *); extern char *smtpd_check_etrn(SMTPD_STATE *, char *); --- 16,21 ---- diff -cr /tmp/postfix-2.0.6/src/smtpd/smtpd_check.in4 ./src/smtpd/smtpd_check.in4 *** /tmp/postfix-2.0.6/src/smtpd/smtpd_check.in4 Thu Oct 31 09:59:50 2002 --- ./src/smtpd/smtpd_check.in4 Tue Mar 11 19:18:40 2003 *************** *** 11,16 **** --- 11,17 ---- mail rejecttext@bad.domain mail filter@filter.domain mail filtertext@filter.domain + mail filtertexttext@filter.domain mail hold@hold.domain mail holdtext@hold.domain mail discard@hold.domain diff -cr /tmp/postfix-2.0.6/src/smtpd/smtpd_check.ref4 ./src/smtpd/smtpd_check.ref4 *** /tmp/postfix-2.0.6/src/smtpd/smtpd_check.ref4 Thu Oct 31 10:01:52 2002 --- ./src/smtpd/smtpd_check.ref4 Tue Mar 11 19:18:59 2003 *************** *** 14,23 **** ./smtpd_check: : reject: MAIL from localhost[127.0.0.1]: 554 : Sender address rejected: text; from= proto=SMTP 554 : Sender address rejected: text >>> mail filter@filter.domain ! ./smtpd_check: warning: access map hash:./smtpd_check_access entry filter@filter.domain has FILTER entry without value OK >>> mail filtertext@filter.domain ! ./smtpd_check: : filter: MAIL from localhost[127.0.0.1]: : Sender address triggers FILTER text; from= proto=SMTP OK >>> mail hold@hold.domain ./smtpd_check: : hold: MAIL from localhost[127.0.0.1]: : Sender address triggers HOLD action; from= proto=SMTP --- 14,26 ---- ./smtpd_check: : reject: MAIL from localhost[127.0.0.1]: 554 : Sender address rejected: text; from= proto=SMTP 554 : Sender address rejected: text >>> mail filter@filter.domain ! ./smtpd_check: warning: access map hash:./smtpd_check_access entry "filter@filter.domain" has FILTER entry without value OK >>> mail filtertext@filter.domain ! ./smtpd_check: warning: access map hash:./smtpd_check_access entry "filtertext@filter.domain" requires transport:destination ! OK ! >>> mail filtertexttext@filter.domain ! ./smtpd_check: : filter: MAIL from localhost[127.0.0.1]: : Sender address triggers FILTER text:text; from= proto=SMTP OK >>> mail hold@hold.domain ./smtpd_check: : hold: MAIL from localhost[127.0.0.1]: : Sender address triggers HOLD action; from= proto=SMTP diff -cr /tmp/postfix-2.0.6/src/smtpd/smtpd_check_access ./src/smtpd/smtpd_check_access *** /tmp/postfix-2.0.6/src/smtpd/smtpd_check_access Thu Oct 31 09:59:31 2002 --- ./src/smtpd/smtpd_check_access Tue Mar 11 19:18:57 2003 *************** *** 50,55 **** --- 50,56 ---- rejecttext@bad.domain reject text filter@filter.domain filter filtertext@filter.domain filter text + filtertexttext@filter.domain filter text:text hold@hold.domain hold holdtext@hold.domain hold text discard@hold.domain discard diff -cr /tmp/postfix-2.0.6/src/smtpd/smtpd_state.c ./src/smtpd/smtpd_state.c *** /tmp/postfix-2.0.6/src/smtpd/smtpd_state.c Fri Nov 8 12:34:55 2002 --- ./src/smtpd/smtpd_state.c Wed Mar 19 10:39:13 2003 *************** *** 97,102 **** --- 97,103 ---- state->defer_if_permit_sender = 0; state->defer_if_reject.reason = 0; state->defer_if_permit.reason = 0; + state->discard = 0; state->expand_buf = 0; #ifdef USE_SASL_AUTH