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