mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-31 06:05:37 +00:00
postfix-2.0.7-20030319
This commit is contained in:
committed by
Viktor Dukhovni
parent
e57de0df68
commit
1c1296a56f
1
postfix/.indent.pro
vendored
1
postfix/.indent.pro
vendored
@@ -136,7 +136,6 @@
|
||||
-TSINK_STATE
|
||||
-TSMTPD_CMD
|
||||
-TSMTPD_DEFER
|
||||
-TSMTPD_MSG_ACTION
|
||||
-TSMTPD_RBL_EXPAND_CONTEXT
|
||||
-TSMTPD_RBL_STATE
|
||||
-TSMTPD_STATE
|
||||
|
@@ -7895,12 +7895,12 @@ Apologies for any names omitted.
|
||||
systems against exploitation of the remote buffer overflow
|
||||
vulnerability described in CERT advisory CA-2003-07.
|
||||
|
||||
20030311-17
|
||||
20030311-19
|
||||
|
||||
Bugfix: the access map actions HOLD, DISCARD, FILTER and
|
||||
REDIRECT were broken with smtpd_delay_reject=no. This
|
||||
required re-architecting of the actions code. Files:
|
||||
smtpd/smtpd.[hc], smtpd/smtpd_check.c, smtpd/smtpd_state.c.
|
||||
REDIRECT were broken with smtpd_delay_reject=no and with
|
||||
ETRN. This required re-architecting of the actions code.
|
||||
Files: smtpd/smtpd.[hc], smtpd/smtpd_check.c, smtpd/smtpd_state.c.
|
||||
|
||||
20030315
|
||||
|
||||
@@ -7913,6 +7913,19 @@ Apologies for any names omitted.
|
||||
for non-existent addresses. This required re-architecting
|
||||
the recipient table lookup code. File: smtpd/smtpd_check.c.
|
||||
|
||||
20030319
|
||||
|
||||
Feature: configurable limit on virtual alias expansion size
|
||||
and nesting depth, via the virtual_alias_expansion_limit
|
||||
and virtual_alias_recursion_limit parameters. The default
|
||||
limits are compatible with past Postfix versions. Victor
|
||||
Duchovni, Morgan Stanley. Files: /sample-resource.cf,
|
||||
html/resource.html, cleanup/cleanup.c, cleanup/cleanup_init.c,
|
||||
cleanup/cleanup_map1n.c.
|
||||
|
||||
Feature: the installation procedure records build information
|
||||
(by default: in /etc/postfix/makedefs.out).
|
||||
|
||||
Open problems:
|
||||
|
||||
Med: make qmgr recipient bounce/defer activity asynchronous
|
||||
|
@@ -18,6 +18,9 @@ makefiles Makefiles:
|
||||
$(MAKE) -f Makefile.in Makefile MAKELEVEL=) || exit 1; \
|
||||
done;
|
||||
rm -f Makefile; (set -e; $(SHELL) makedefs && cat Makefile.in) >Makefile
|
||||
(echo "# Do not edit -- this file documents how Postfix was built for your machine."; $(SHELL) makedefs) >makedefs.tmp
|
||||
set +e; if cmp makedefs.tmp conf/makedefs.out; then rm makedefs.tmp; \
|
||||
else mv makedefs.tmp conf/makedefs.out; fi >/dev/null 2>/dev/null
|
||||
|
||||
update printfck tests:
|
||||
set -e; for i in $(DIRS); do \
|
||||
|
@@ -94,6 +94,7 @@ $config_directory/aliases:f:root:-:644:p
|
||||
$config_directory/canonical:f:root:-:644:p
|
||||
$config_directory/main.cf:f:root:-:644:p
|
||||
$config_directory/main.cf.default:f:root:-:644
|
||||
$config_directory/makedefs.out:f:root:-:644
|
||||
$config_directory/master.cf:f:root:-:644:p
|
||||
$config_directory/pcre_table:f:root:-:644:p
|
||||
$config_directory/postfix-files:f:root:-:644
|
||||
|
@@ -47,6 +47,19 @@ deliver_lock_delay = 1s
|
||||
#
|
||||
duplicate_filter_limit = 1000
|
||||
|
||||
# The virtual_alias_expansion_limit parameter limits the number of
|
||||
# addresses that virtual expansion produces from each original recipient.
|
||||
#
|
||||
virtual_alias_expansion_limit = 1000
|
||||
|
||||
# The virtual_alias_recursion_limit parameter limits the nesting depth of
|
||||
# virtual expansion. Currently the recursion limit is applied only to the
|
||||
# left branch of the expansion graph, so the depth of the tree can in the
|
||||
# worst case reach the sum of the expansion and recursion limits.
|
||||
# This may change in the future.
|
||||
#
|
||||
virtual_alias_recursion_limit = 1000
|
||||
|
||||
# The fork_attempts parameter limits the number of attempts to
|
||||
# fork() a process.
|
||||
#
|
||||
|
@@ -208,6 +208,15 @@ CLEANUP(8) CLEANUP(8)
|
||||
Limit the amount of recipients extracted from mes-
|
||||
sage headers.
|
||||
|
||||
<b>virtual</b><i>_</i><b>alias</b><i>_</i><b>expansion</b><i>_</i><b>limit</b>
|
||||
Limit the number of actual recipients produced by
|
||||
virtual alias expansion from each original recipi-
|
||||
ent.
|
||||
|
||||
<b>virtual</b><i>_</i><b>alias</b><i>_</i><b>recursion</b><i>_</i><b>limit</b>
|
||||
Limit the recursion depth of virtual alias expan-
|
||||
sion.
|
||||
|
||||
<b>SEE</b> <b>ALSO</b>
|
||||
<a href="canonical.5.html">canonical(5)</a> canonical address lookup table format
|
||||
<a href="qmgr.8.html">qmgr(8)</a> queue manager daemon
|
||||
@@ -220,7 +229,7 @@ CLEANUP(8) CLEANUP(8)
|
||||
/etc/postfix/virtual*, virtual mapping table
|
||||
|
||||
<b>LICENSE</b>
|
||||
The Secure Mailer license must be distributed with this
|
||||
The Secure Mailer license must be distributed with this
|
||||
software.
|
||||
|
||||
<b>AUTHOR(S)</b>
|
||||
|
@@ -164,6 +164,21 @@ delivery</a> agent and <a href="cleanup.8.html">address cleanup</a>
|
||||
daemon remember when delivering a message. A recipient address is
|
||||
ignored when it is found in the remembered list.
|
||||
|
||||
<dt> <b>virtual_alias_expansion_limit</b> (default: 1000)
|
||||
|
||||
<dd> This limits the number of addresses that result from each original
|
||||
recipient by virtual alias expansion in the <a href="cleanup.8.html">
|
||||
address cleanup</a> daemon. By default each original recipient is rewritten
|
||||
via <b>$virtual_alias_maps</b> to at most 1000 actual recipients.
|
||||
|
||||
<dt> <b>virtual_alias_recursion_limit</b> (default: 1000)
|
||||
|
||||
<dd> This limits the recursive nesting of virtual alias expansion performed
|
||||
by the <a href="cleanup.8.html">address cleanup</a> daemon. Virtual
|
||||
alias expansion is recursive, and stops only when an address is not
|
||||
found in the table, when an address maps to itself, or when the
|
||||
recursion limit is reached.
|
||||
|
||||
</dl>
|
||||
|
||||
<a name="time"><h2> Time limits</h2> </a>
|
||||
|
@@ -174,6 +174,11 @@ Amount of time to pause before accepting a message, when the
|
||||
message arrival rate exceeds the message delivery rate.
|
||||
.IP \fBextract_recipient_limit\fR
|
||||
Limit the amount of recipients extracted from message headers.
|
||||
.IP \fBvirtual_alias_expansion_limit\fR
|
||||
Limit the number of actual recipients produced by virtual alias
|
||||
expansion from each original recipient.
|
||||
.IP \fBvirtual_alias_recursion_limit\fR
|
||||
Limit the recursion depth of virtual alias expansion.
|
||||
.SH SEE ALSO
|
||||
.na
|
||||
.nf
|
||||
|
@@ -160,6 +160,11 @@
|
||||
/* message arrival rate exceeds the message delivery rate.
|
||||
/* .IP \fBextract_recipient_limit\fR
|
||||
/* Limit the amount of recipients extracted from message headers.
|
||||
/* .IP \fBvirtual_alias_expansion_limit\fR
|
||||
/* Limit the number of actual recipients produced by virtual alias
|
||||
/* expansion from each original recipient.
|
||||
/* .IP \fBvirtual_alias_recursion_limit\fR
|
||||
/* Limit the recursion depth of virtual alias expansion.
|
||||
/* SEE ALSO
|
||||
/* canonical(5) canonical address lookup table format
|
||||
/* qmgr(8) queue manager daemon
|
||||
|
@@ -110,6 +110,8 @@ int var_extra_rcpt_limit; /* recipient extract limit */
|
||||
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 */
|
||||
|
||||
CONFIG_INT_TABLE cleanup_int_table[] = {
|
||||
@@ -117,6 +119,8 @@ CONFIG_INT_TABLE cleanup_int_table[] = {
|
||||
VAR_DUP_FILTER_LIMIT, DEF_DUP_FILTER_LIMIT, &var_dup_filter_limit, 0, 0,
|
||||
VAR_EXTRA_RCPT_LIMIT, DEF_EXTRA_RCPT_LIMIT, &var_extra_rcpt_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,
|
||||
};
|
||||
|
@@ -55,6 +55,7 @@
|
||||
|
||||
/* Global library. */
|
||||
|
||||
#include <mail_params.h>
|
||||
#include <mail_addr_map.h>
|
||||
#include <cleanup_user.h>
|
||||
#include <quote_822_local.h>
|
||||
@@ -93,13 +94,11 @@ ARGV *cleanup_map1n_internal(CLEANUP_STATE *state, const char *addr,
|
||||
* pointer.
|
||||
*/
|
||||
#define UPDATE(ptr,new) { myfree(ptr); ptr = mystrdup(new); }
|
||||
#define MAX_RECURSION 1000
|
||||
#define MAX_EXPANSION 1000
|
||||
#define STR vstring_str
|
||||
#define RETURN(x) { been_here_free(been_here); return (x); }
|
||||
|
||||
for (arg = 0; arg < argv->argc; arg++) {
|
||||
if (argv->argc > MAX_EXPANSION) {
|
||||
if (argv->argc > var_virt_expan_limit) {
|
||||
msg_warn("%s: unreasonable %s map expansion size for %s",
|
||||
state->queue_id, maps->title, addr);
|
||||
break;
|
||||
@@ -111,7 +110,7 @@ ARGV *cleanup_map1n_internal(CLEANUP_STATE *state, const char *addr,
|
||||
*/
|
||||
if (been_here_check_fixed(been_here, argv->argv[arg]) != 0)
|
||||
break;
|
||||
if (count >= MAX_RECURSION) {
|
||||
if (count >= var_virt_recur_limit) {
|
||||
msg_warn("%s: unreasonable %s map nesting for %s",
|
||||
state->queue_id, maps->title, addr);
|
||||
break;
|
||||
|
@@ -1019,6 +1019,14 @@ extern int var_token_limit;
|
||||
#define DEF_EXTRA_RCPT_LIMIT 10240
|
||||
extern int var_extra_rcpt_limit;
|
||||
|
||||
#define VAR_VIRT_RECUR_LIMIT "virtual_alias_recursion_limit"
|
||||
#define DEF_VIRT_RECUR_LIMIT 1000
|
||||
extern int var_virt_recur_limit;
|
||||
|
||||
#define VAR_VIRT_EXPAN_LIMIT "virtual_alias_expansion_limit"
|
||||
#define DEF_VIRT_EXPAN_LIMIT 1000
|
||||
extern int var_virt_expan_limit;
|
||||
|
||||
/*
|
||||
* Message/queue size limits.
|
||||
*/
|
||||
|
@@ -20,7 +20,7 @@
|
||||
* 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 "20030317"
|
||||
#define MAIL_RELEASE_DATE "20030319"
|
||||
|
||||
#define VAR_MAIL_VERSION "mail_version"
|
||||
#define DEF_MAIL_VERSION "2.0.7-" MAIL_RELEASE_DATE
|
||||
|
@@ -495,8 +495,6 @@ static int helo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
smtpd_chat_reply(state, "501 Syntax: HELO hostname");
|
||||
return (-1);
|
||||
}
|
||||
if (state->helo_name != 0)
|
||||
helo_reset(state);
|
||||
if (argc > 2)
|
||||
collapse_args(argc - 1, argv + 1);
|
||||
if (SMTPD_STAND_ALONE(state) == 0
|
||||
@@ -505,6 +503,8 @@ static int helo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
smtpd_chat_reply(state, "%s", err);
|
||||
return (-1);
|
||||
}
|
||||
if (state->helo_name != 0)
|
||||
helo_reset(state);
|
||||
chat_reset(state, var_smtpd_hist_thrsh);
|
||||
mail_reset(state);
|
||||
rcpt_reset(state);
|
||||
@@ -531,8 +531,6 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
smtpd_chat_reply(state, "501 Syntax: EHLO hostname");
|
||||
return (-1);
|
||||
}
|
||||
if (state->helo_name != 0)
|
||||
helo_reset(state);
|
||||
if (argc > 2)
|
||||
collapse_args(argc - 1, argv + 1);
|
||||
if (SMTPD_STAND_ALONE(state) == 0
|
||||
@@ -541,6 +539,8 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
smtpd_chat_reply(state, "%s", err);
|
||||
return (-1);
|
||||
}
|
||||
if (state->helo_name != 0)
|
||||
helo_reset(state);
|
||||
chat_reset(state, var_smtpd_hist_thrsh);
|
||||
mail_reset(state);
|
||||
rcpt_reset(state);
|
||||
@@ -576,26 +576,6 @@ static void helo_reset(SMTPD_STATE *state)
|
||||
if (state->helo_name)
|
||||
myfree(state->helo_name);
|
||||
state->helo_name = 0;
|
||||
|
||||
/*
|
||||
* With smtpd_delay_reject=yes, smtpd_helo_restrictions is evaluated at
|
||||
* RCPT TO time, and may be evaluated multiple times per message.
|
||||
* Per-message smtpd_helo_restrictions side effects (HOLD, DISCARD, etc.)
|
||||
* accumulate from one evaluation to the next, and may also depend on
|
||||
* client, sender or recipient information. Therefore, any per-message
|
||||
* helo restriction side effects need to be reset at the end of a mail
|
||||
* delivery transaction.
|
||||
*
|
||||
* With smtpd_delay_reject=no, smtpd_helo_restrictions is evaluated when
|
||||
* HELO/EHLO is issued, and its per-message side effects change only when
|
||||
* another HELO/EHLO command is issued. Therefore, any per-message helo
|
||||
* restriction side effects must be reset before smtpd_helo_restrictions
|
||||
* is evaluated.
|
||||
*/
|
||||
if (var_smtpd_delay_reject == 0) {
|
||||
SMTPD_MSG_ACT_FREE(state->action_helo);
|
||||
SMTPD_MSG_ACT_ZERO(state->action_helo);
|
||||
}
|
||||
}
|
||||
|
||||
/* mail_open_stream - open mail destination */
|
||||
@@ -923,20 +903,7 @@ static void mail_reset(SMTPD_STATE *state)
|
||||
if (var_smtpd_sasl_enable)
|
||||
smtpd_sasl_mail_reset(state);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* With smtpd_delay_reject=yes, smtpd_sender_restrictions is evaluated at
|
||||
* RCPT TO time, and may be evaluated multiple times per message.
|
||||
* Per-message smtpd_sender_restrictions side effects (HOLD, DISCARD,
|
||||
* etc.) accumulate from one evaluation to the next, and may also depend
|
||||
* on client, helo or recipient information.
|
||||
*
|
||||
* The action_mailrcpt member accumulates both sender and recipient side
|
||||
* effects. It needs to be reset after each mail delivery, whether or not
|
||||
* it is actually completed.
|
||||
*/
|
||||
SMTPD_MSG_ACT_FREE(state->action_mailrcpt);
|
||||
SMTPD_MSG_ACT_ZERO(state->action_mailrcpt);
|
||||
state->discard = 0;
|
||||
}
|
||||
|
||||
/* rcpt_cmd - process RCPT TO command */
|
||||
@@ -1017,26 +984,6 @@ static void rcpt_reset(SMTPD_STATE *state)
|
||||
state->recipient = 0;
|
||||
}
|
||||
state->rcpt_count = 0;
|
||||
|
||||
/*
|
||||
* With smtpd_delay_reject=yes, smtpd_{client,helo}_restrictions are
|
||||
* evaluated at RCPT TO time. They may be evaluated multiple times per
|
||||
* message delivery. Per-message {client,helo} restriction side effects
|
||||
* (HOLD, DISCARD, etc.) accumulate from one evaluation to the next, and
|
||||
* the result may also depend on sender or recipient information.
|
||||
* Therefore, per-message {client,helo} restriction side effects need to
|
||||
* be reset between deliveries.
|
||||
*
|
||||
* With smtpd_delay_reject=no, smtpd_{client,helo}_restrictions are
|
||||
* evaluated once and take effect over multiple deliveries. Therefore,
|
||||
* their per-message side effects must not be reset between deliveries.
|
||||
*/
|
||||
if (var_smtpd_delay_reject) {
|
||||
SMTPD_MSG_ACT_FREE(state->action_client);
|
||||
SMTPD_MSG_ACT_ZERO(state->action_client);
|
||||
SMTPD_MSG_ACT_FREE(state->action_helo);
|
||||
SMTPD_MSG_ACT_ZERO(state->action_helo);
|
||||
}
|
||||
}
|
||||
|
||||
/* data_cmd - process DATA command */
|
||||
@@ -1051,7 +998,6 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
||||
int first = 1;
|
||||
VSTRING *why = 0;
|
||||
int saved_err;
|
||||
char *act_value;
|
||||
|
||||
/*
|
||||
* Sanity checks. With ESMTP command pipelining the client can send DATA
|
||||
@@ -1084,18 +1030,6 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
||||
*/
|
||||
if (*var_always_bcc)
|
||||
rec_fputs(state->cleanup, REC_TYPE_RCPT, var_always_bcc);
|
||||
if (SMTPD_MSG_ACT_FLAGS(state) & SMTPD_MSG_ACT_DISCARD) {
|
||||
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
|
||||
CLEANUP_FLAG_DISCARD);
|
||||
} else {
|
||||
if (SMTPD_MSG_ACT_FLAGS(state) & SMTPD_MSG_ACT_HOLD)
|
||||
rec_fprintf(state->cleanup, REC_TYPE_FLGS, "%d",
|
||||
CLEANUP_FLAG_HOLD);
|
||||
if ((act_value = SMTPD_MSG_ACT_VALUE(state, filter)) != 0)
|
||||
rec_fprintf(state->dest->stream, REC_TYPE_FILT, "%s", act_value);
|
||||
if ((act_value = SMTPD_MSG_ACT_VALUE(state, redirect)) != 0)
|
||||
rec_fprintf(state->dest->stream, REC_TYPE_RDR, "%s", act_value);
|
||||
}
|
||||
rec_fputs(state->cleanup, REC_TYPE_MESG, "");
|
||||
rec_fprintf(state->cleanup, REC_TYPE_NORM,
|
||||
"Received: from %s (%s [%s])",
|
||||
@@ -1332,7 +1266,7 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
return (-1);
|
||||
}
|
||||
if (SMTPD_STAND_ALONE(state) == 0
|
||||
&& (err = smtpd_check_vrfy(state, argv[1].strval)) != 0) {
|
||||
&& (err = smtpd_check_rcpt(state, argv[1].strval)) != 0) {
|
||||
smtpd_chat_reply(state, "%s", err);
|
||||
return (-1);
|
||||
}
|
||||
|
@@ -45,43 +45,6 @@ typedef struct SMTPD_DEFER {
|
||||
int class; /* error notification class */
|
||||
} SMTPD_DEFER;
|
||||
|
||||
/*
|
||||
* Actions that affect all recipients of a given message. That is, we don't
|
||||
* "undo" results from one recipient when evaluating the next recipient.
|
||||
*/
|
||||
typedef struct SMTPD_MSG_ACTION {
|
||||
int flags; /* see below */
|
||||
char *filter; /* filter destination */
|
||||
char *redirect; /* redirect destination */
|
||||
} SMTPD_MSG_ACTION;
|
||||
|
||||
#define SMTPD_MSG_ACT_HOLD (1<<0) /* place message on hold */
|
||||
#define SMTPD_MSG_ACT_DISCARD (1<<1) /* discard message */
|
||||
#define SMTPD_MSG_ACT_FILTER (1<<2) /* filter message */
|
||||
#define SMTPD_MSG_ACT_REDIRECT (1<<3) /* redirect message */
|
||||
|
||||
/*
|
||||
* Short-hand for when to stop searching restriction lists.
|
||||
*/
|
||||
#define SMTPD_MSG_ACT_FINAL (SMTPD_MSG_ACT_DISCARD)
|
||||
|
||||
#define SMTPD_MSG_ACT_ZERO(a) do { \
|
||||
(a).flags = 0; \
|
||||
(a).filter = 0; \
|
||||
(a).redirect = 0; \
|
||||
} while (0)
|
||||
|
||||
#define SMTPD_MSG_ACT_FREE(a) do { \
|
||||
if ((a).filter) myfree((a).filter); \
|
||||
if ((a).redirect) myfree((a).redirect); \
|
||||
} while (0)
|
||||
|
||||
#define SMTPD_MSG_ACT_COPY(d, s) do { \
|
||||
SMTPD_MSG_ACT_FREE(d); \
|
||||
(d).filter = ((s).filter ? mystrdup((s).filter) : 0); \
|
||||
(d).redirect = ((s).redirect ? mystrdup((s).redirect) : 0); \
|
||||
} while (0)
|
||||
|
||||
typedef struct SMTPD_STATE {
|
||||
int err;
|
||||
VSTREAM *client;
|
||||
@@ -123,10 +86,6 @@ typedef struct SMTPD_STATE {
|
||||
VSTRING *sasl_encoded;
|
||||
VSTRING *sasl_decoded;
|
||||
#endif
|
||||
SMTPD_MSG_ACTION *action; /* action from access map */
|
||||
SMTPD_MSG_ACTION action_client; /* action after connect */
|
||||
SMTPD_MSG_ACTION action_helo; /* action after helo/ehlo */
|
||||
SMTPD_MSG_ACTION action_mailrcpt; /* action after mail from/rcpt to */
|
||||
int rcptmap_checked;
|
||||
int warn_if_reject; /* force reject into warning */
|
||||
SMTPD_DEFER defer_if_reject; /* force reject into deferral */
|
||||
@@ -134,18 +93,10 @@ typedef struct SMTPD_STATE {
|
||||
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;
|
||||
|
||||
#define SMTPD_MSG_ACT_FLAGS(s) \
|
||||
((s)->action_client.flags | (s)->action_helo.flags \
|
||||
| (s)->action_mailrcpt.flags)
|
||||
|
||||
#define SMTPD_MSG_ACT_VALUE(s,m) \
|
||||
((s)->action_mailrcpt.m ? (s)->action_mailrcpt.m : \
|
||||
(s)->action_helo.m ? (s)->action_helo.m : \
|
||||
(s)->action_client.m)
|
||||
|
||||
extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *);
|
||||
extern void smtpd_state_reset(SMTPD_STATE *);
|
||||
|
||||
|
@@ -24,10 +24,6 @@
|
||||
/* SMTPD_STATE *state;
|
||||
/* char *recipient;
|
||||
/*
|
||||
/* char *smtpd_check_vrfy(state, recipient)
|
||||
/* SMTPD_STATE *state;
|
||||
/* char *recipient;
|
||||
/*
|
||||
/* char *smtpd_check_etrn(state, destination)
|
||||
/* SMTPD_STATE *state;
|
||||
/* char *destination;
|
||||
@@ -206,12 +202,6 @@
|
||||
/* Tables of user names (not addresses) that exist in $mydestination.
|
||||
/* Mail for local users not in these tables is rejected.
|
||||
/* .PP
|
||||
/* smtpd_check_vrfy() validates the recipient address provided
|
||||
/* with a VRFY request. Relevant configuration parameters:
|
||||
/* .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
|
||||
/* smtpd_check_etrn() validates the domain name provided with the
|
||||
/* ETRN command, and other client-provided information. Relevant
|
||||
/* configuration parameters:
|
||||
@@ -1702,6 +1692,31 @@ static int reject_unverified_address(SMTPD_STATE *state, const char *addr,
|
||||
return (rqst_status);
|
||||
}
|
||||
|
||||
/* 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,
|
||||
@@ -1753,8 +1768,12 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
|
||||
* mind, and reject/discard the message for other reasons.
|
||||
*/
|
||||
if (STREQUAL(value, "FILTER", cmd_len)) {
|
||||
if (state->action == 0)
|
||||
#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);
|
||||
@@ -1767,10 +1786,9 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
|
||||
vstring_sprintf(error_text, "<%s>: %s triggers FILTER %s",
|
||||
reply_name, reply_class, cmd_text);
|
||||
log_whatsup(state, "filter", STR(error_text));
|
||||
state->action->flags |= SMTPD_MSG_ACT_FILTER;
|
||||
if (state->action->filter)
|
||||
myfree(state->action->filter);
|
||||
state->action->filter = mystrdup(cmd_text);
|
||||
#ifndef TEST
|
||||
rec_fprintf(state->dest->stream, REC_TYPE_FILT, "%s", cmd_text);
|
||||
#endif
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
}
|
||||
@@ -1780,12 +1798,19 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
|
||||
* reject/discard the message for other reasons.
|
||||
*/
|
||||
if (STREQUAL(value, "HOLD", cmd_len)) {
|
||||
if (state->action == 0)
|
||||
#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));
|
||||
state->action->flags |= SMTPD_MSG_ACT_HOLD;
|
||||
#ifndef TEST
|
||||
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
|
||||
CLEANUP_FLAG_HOLD);
|
||||
#endif
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
|
||||
@@ -1793,12 +1818,20 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
|
||||
* DISCARD means silently discard and claim successful delivery.
|
||||
*/
|
||||
if (STREQUAL(value, "DISCARD", cmd_len)) {
|
||||
if (state->action == 0)
|
||||
#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));
|
||||
state->action->flags |= SMTPD_MSG_ACT_DISCARD;
|
||||
#ifndef TEST
|
||||
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
|
||||
CLEANUP_FLAG_DISCARD);
|
||||
state->discard = 1;
|
||||
#endif
|
||||
return (SMTPD_CHECK_OK);
|
||||
}
|
||||
|
||||
@@ -1807,8 +1840,12 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
|
||||
* change our mind, and reject/discard the message for other reasons.
|
||||
*/
|
||||
if (STREQUAL(value, "REDIRECT", cmd_len)) {
|
||||
if (state->action == 0)
|
||||
#ifndef TEST
|
||||
if (state->dest == 0) {
|
||||
warn_skip_access_action(table, "REDIRECT", reply_class);
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
#endif
|
||||
if (strchr(cmd_text, '@') == 0) {
|
||||
msg_warn("access map %s entry \"%s\" requires user@domain target",
|
||||
table, datum);
|
||||
@@ -1817,10 +1854,9 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
|
||||
vstring_sprintf(error_text, "<%s>: %s triggers REDIRECT %s",
|
||||
reply_name, reply_class, cmd_text);
|
||||
log_whatsup(state, "redirect", STR(error_text));
|
||||
state->action->flags |= SMTPD_MSG_ACT_REDIRECT;
|
||||
if (state->action->redirect)
|
||||
myfree(state->action->redirect);
|
||||
state->action->redirect = mystrdup(cmd_text);
|
||||
#ifndef TEST
|
||||
rec_fprintf(state->dest->stream, REC_TYPE_RDR, "%s", cmd_text);
|
||||
#endif
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
}
|
||||
@@ -2649,7 +2685,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
|
||||
|
||||
for (cpp = restrictions->argv; (name = *cpp) != 0; cpp++) {
|
||||
|
||||
if (state->action && SMTPD_MSG_ACT_FLAGS(state) & SMTPD_MSG_ACT_FINAL)
|
||||
if (state->discard != 0)
|
||||
break;
|
||||
|
||||
if (msg_verbose)
|
||||
@@ -2972,20 +3008,6 @@ char *smtpd_check_client(SMTPD_STATE *state)
|
||||
*/
|
||||
state->defer_if_permit.active = 0;
|
||||
|
||||
/*
|
||||
* With smtpd_delay_reject=yes, smtpd_client_restrictions is evaluated at
|
||||
* RCPT TO time, and may be evaluated multiple times. Per-message side
|
||||
* effects (HOLD, DISCARD, etc.) accumulate from one evaluation to the
|
||||
* next, and may also depend on helo, sender or recipient information.
|
||||
*
|
||||
* With smtpd_delay_reject=no, smtpd_{client,helo}_restrictions are
|
||||
* evaluated immediately, and HELO may be given multiple times. The same
|
||||
* {client,helo} per-message side effects (HOLD, DISCARD, etc.) apply to
|
||||
* multiple deliveries. Therefore, we need separate per-message side
|
||||
* effect storage for client, helo, and for sender+recipients.
|
||||
*/
|
||||
state->action = &state->action_client;
|
||||
|
||||
/*
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
@@ -3040,20 +3062,6 @@ char *smtpd_check_helo(SMTPD_STATE *state, char *helohost)
|
||||
*/
|
||||
state->defer_if_permit.active = state->defer_if_permit_client;
|
||||
|
||||
/*
|
||||
* With smtpd_delay_reject=yes, smtpd_helo_restrictions is evaluated at
|
||||
* RCPT TO time, and may be evaluated multiple times. Per-message side
|
||||
* effects (HOLD, DISCARD, etc.) accumulate from one evaluation to the
|
||||
* next, and may also depend on sender or recipient information.
|
||||
*
|
||||
* With smtpd_delay_reject=no, smtpd_{client,helo}_restrictions are
|
||||
* evaluated immediately, and HELO may be given multiple times. The same
|
||||
* {client,helo} per-message side effects (HOLD, DISCARD, etc.) apply to
|
||||
* multiple deliveries. Therefore, we need separate per-message side
|
||||
* effect storage for client, helo, and for sender+recipients.
|
||||
*/
|
||||
state->action = &state->action_helo;
|
||||
|
||||
/*
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
@@ -3099,14 +3107,6 @@ char *smtpd_check_mail(SMTPD_STATE *state, char *sender)
|
||||
state->defer_if_permit.active = state->defer_if_permit_client
|
||||
| state->defer_if_permit_helo;
|
||||
|
||||
/*
|
||||
* With smtpd_delay_reject=yes, smtpd_sender_restrictions is evaluated at
|
||||
* RCPT TO time, and may be evaluated multiple times. Per-message side
|
||||
* effects (HOLD, DISCARD, etc.) accumulate from one evaluation to the
|
||||
* next, and may also depend on client, helo or recipient information.
|
||||
*/
|
||||
state->action = &state->action_mailrcpt;
|
||||
|
||||
/*
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
@@ -3171,10 +3171,7 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
|
||||
|
||||
/*
|
||||
* 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).
|
||||
* responding to RCPT TO or VRFY.
|
||||
*/
|
||||
state->rcptmap_checked = 0;
|
||||
|
||||
@@ -3194,13 +3191,6 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
|
||||
*/
|
||||
state->defer_if_permit.active = state->defer_if_permit_sender;
|
||||
|
||||
/*
|
||||
* Per-message side effects (HOLD, DISCARD, etc.) accumulate from one
|
||||
* recipient to the next, and may also depend on client, helo or sender
|
||||
* information.
|
||||
*/
|
||||
state->action = &state->action_mailrcpt;
|
||||
|
||||
/*
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
@@ -3222,8 +3212,8 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
|
||||
* If the "check_recipient_maps" restriction was not applied, and if mail
|
||||
* is not being rejected or discarded, validate the recipient here.
|
||||
*/
|
||||
if (status == 0 && state->rcptmap_checked == 0
|
||||
&& (SMTPD_MSG_ACT_FLAGS(state) & SMTPD_MSG_ACT_FINAL) == 0)
|
||||
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);
|
||||
@@ -3270,11 +3260,6 @@ char *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
|
||||
state->defer_if_permit.active = state->defer_if_permit_client
|
||||
| state->defer_if_permit_helo;
|
||||
|
||||
/*
|
||||
* HOLD, DISCARD, FILTER, etc. are meaningless.
|
||||
*/
|
||||
state->action = 0;
|
||||
|
||||
/*
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
@@ -3295,32 +3280,20 @@ char *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
|
||||
SMTPD_CHECK_ETRN_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
|
||||
}
|
||||
|
||||
/* smtpd_check_vrfy - permit if recipient address matches lookup table */
|
||||
|
||||
char *smtpd_check_vrfy(SMTPD_STATE *state, char *recipient)
|
||||
{
|
||||
char *myname = "smtpd_check_vrfy";
|
||||
int status;
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s", myname, recipient);
|
||||
|
||||
/*
|
||||
* Return here in case of serious trouble.
|
||||
*/
|
||||
SMTPD_CHECK_RESET();
|
||||
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)
|
||||
{
|
||||
const RESOLVE_REPLY *reply;
|
||||
|
||||
/*
|
||||
* Duplicate suppression. There's an implicit check_recipient_maps
|
||||
* restriction at the end of all recipient restrictions.
|
||||
*/
|
||||
if (state->rcptmap_checked == 1)
|
||||
return (0);
|
||||
state->rcptmap_checked = 1;
|
||||
|
||||
/*
|
||||
* Resolve the address.
|
||||
*/
|
||||
@@ -3959,8 +3932,6 @@ int main(int argc, char **argv)
|
||||
state.namaddr = concatenate(state.name, "[", state.addr,
|
||||
"]", (char *) 0);
|
||||
resp = smtpd_check_client(&state);
|
||||
SMTPD_MSG_ACT_FREE(state.action_client);
|
||||
SMTPD_MSG_ACT_ZERO(state.action_client);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -4072,22 +4043,16 @@ int main(int argc, char **argv)
|
||||
if (strcasecmp(args->argv[0], "helo") == 0) {
|
||||
state.where = "HELO";
|
||||
resp = smtpd_check_helo(&state, args->argv[1]);
|
||||
SMTPD_MSG_ACT_FREE(state.action_helo);
|
||||
SMTPD_MSG_ACT_ZERO(state.action_helo);
|
||||
UPDATE_STRING(state.helo_name, args->argv[1]);
|
||||
} else if (strcasecmp(args->argv[0], "mail") == 0) {
|
||||
state.where = "MAIL";
|
||||
TRIM_ADDR(args->argv[1], addr);
|
||||
UPDATE_STRING(state.sender, addr);
|
||||
resp = smtpd_check_mail(&state, addr);
|
||||
SMTPD_MSG_ACT_FREE(state.action_mailrcpt);
|
||||
SMTPD_MSG_ACT_ZERO(state.action_mailrcpt);
|
||||
} else if (strcasecmp(args->argv[0], "rcpt") == 0) {
|
||||
state.where = "RCPT";
|
||||
TRIM_ADDR(args->argv[1], addr);
|
||||
resp = smtpd_check_rcpt(&state, addr);
|
||||
SMTPD_MSG_ACT_FREE(state.action_mailrcpt);
|
||||
SMTPD_MSG_ACT_ZERO(state.action_mailrcpt);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@@ -16,7 +16,6 @@ extern void smtpd_check_init(void);
|
||||
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_vrfy(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 *);
|
||||
|
@@ -92,14 +92,12 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream)
|
||||
state->recursion = 0;
|
||||
state->msg_size = 0;
|
||||
state->junk_cmds = 0;
|
||||
SMTPD_MSG_ACT_ZERO(state->action_client);
|
||||
SMTPD_MSG_ACT_ZERO(state->action_helo);
|
||||
SMTPD_MSG_ACT_ZERO(state->action_mailrcpt);
|
||||
state->defer_if_permit_client = 0;
|
||||
state->defer_if_permit_helo = 0;
|
||||
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
|
||||
@@ -139,9 +137,6 @@ void smtpd_state_reset(SMTPD_STATE *state)
|
||||
vstring_free(state->defer_if_reject.reason);
|
||||
if (state->expand_buf)
|
||||
vstring_free(state->expand_buf);
|
||||
SMTPD_MSG_ACT_FREE(state->action_client);
|
||||
SMTPD_MSG_ACT_FREE(state->action_helo);
|
||||
SMTPD_MSG_ACT_FREE(state->action_mailrcpt);
|
||||
|
||||
#ifdef USE_SASL_AUTH
|
||||
if (var_smtpd_sasl_enable)
|
||||
|
Reference in New Issue
Block a user