calls. This allows tlsproxy(8) to reset an I/O timer after
each event without having to make an nbbio_disable_readwrite()
call. Files: util/nbbio.c, tlsproxy/tlsproxy.c.
+
+20191013
+
+ Cleanup: code pattern ENFORCING_SIZE_LIMIT() for more
+ consistent enforcement of the 'no size limit' case (it now
+ requires "> 0" where previous code used "!= 0" or "> 0").
+ More relevant, this explicit pattern will help finding code
+ that does not implement the 'no size limit' case with
+ var_message_limit, etc. Files: cleanup/cleanup_init.c,
+ local/local.c, postdrop/postdrop.c, postscreen/postscreen_smtpd.c,
+ sendmail/sendmail.c, smtpd/smtpd.c, smtpd/smtpd_check.c,
+ util/netstring.c, util/sys_defs.h, virtual/virtual.c.
+
+ Cleanup; with message_size_limit>0, local(8) and virtual(8)
+ mailbox size limit checks would produce a misleading error
+ message when the mailbox size was unlimited. Files:
+ local/local.c, virtual/virtual.c.
+
+ Cleanup: queue_minfree changed from 'int' to 'long'. File:
+ global/mail_params.h, src/smtpd/smtpd.c.
+
+ Attribution: updated AUTHOR in file headers. Files:
+ global/bounce_log.c, global/deliver_request.h, smtp/smtp_chat.c,
+ smtp/smtp_rcpt.c, tls/tls_certkey.c, util/nbbio.c,
+ util/vstream_tweak.c.
+
* really low limit, the difference is going to matter only when a queue
* file has lots of recipients.
*/
- if (var_message_limit > 0)
+ if (ENFORCING_SIZE_LIMIT(var_message_limit))
set_file_limit((off_t) var_message_limit);
/*
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
/* System library. */
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
#endif
#define VAR_QUEUE_MINFREE "queue_minfree"
#define DEF_QUEUE_MINFREE 0
-extern int var_queue_minfree;
+extern long var_queue_minfree;
+ /*
+ * Light-weight content inspection.
+ */
#define VAR_HEADER_CHECKS "header_checks"
#define DEF_HEADER_CHECKS ""
extern char *var_header_checks;
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20190922"
+#define MAIL_RELEASE_DATE "20191013"
#define MAIL_VERSION_NUMBER "3.5"
#ifdef SNAPSHOT
* 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",
+ if (ENFORCING_SIZE_LIMIT(var_mailbox_limit)) {
+ if (!ENFORCING_SIZE_LIMIT(var_message_limit))
+ msg_fatal("configuration error: %s is limited but %s is "
+ "unlimited", VAR_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT);
+ if (var_mailbox_limit < var_message_limit)
+ msg_fatal("configuration error: %s is smaller than %s",
VAR_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT);
set_file_limit(var_mailbox_limit);
}
* Stop run-away process accidents by limiting the queue file size. This
* is not a defense against DOS attack.
*/
- if (var_message_limit > 0 && get_file_limit() > var_message_limit)
+ if (ENFORCING_SIZE_LIMIT(var_message_limit)
+ && get_file_limit() > var_message_limit)
set_file_limit((off_t) var_message_limit);
/*
vstring_sprintf(psc_temp, "250-%s\r\n", var_myhostname);
if ((discard_mask & EHLO_MASK_SIZE) == 0) {
- if (var_message_limit)
+ if (ENFORCING_SIZE_LIMIT(var_message_limit))
PSC_EHLO_APPEND1(saved_len, psc_temp, "250-SIZE %lu\r\n",
(unsigned long) var_message_limit);
else
* Stop run-away process accidents by limiting the queue file size. This
* is not a defense against DOS attack.
*/
- if (var_message_limit > 0 && get_file_limit() > var_message_limit)
+ if (ENFORCING_SIZE_LIMIT(var_message_limit)
+ && get_file_limit() > var_message_limit)
set_file_limit((off_t) var_message_limit);
/*
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
/* System library. */
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
/* System library. */
int var_smtpd_tmout;
int var_smtpd_soft_erlim;
int var_smtpd_hard_erlim;
-int var_queue_minfree; /* XXX use off_t */
+long var_queue_minfree; /* XXX use off_t */
char *var_smtpd_banner;
char *var_notify_classes;
char *var_client_checks;
if ((discard_mask & EHLO_MASK_PIPELINING) == 0)
EHLO_APPEND(state, "PIPELINING");
if ((discard_mask & EHLO_MASK_SIZE) == 0) {
- if (var_message_limit)
+ if (ENFORCING_SIZE_LIMIT(var_message_limit))
EHLO_APPEND1(state, "SIZE %lu",
(unsigned long) var_message_limit); /* XXX */
else
&& (proxy == 0 ? (++start, --len) == 0 : len == 1))
break;
if (state->err == CLEANUP_STAT_OK) {
- if (var_message_limit > 0 && var_message_limit - state->act_size < len + 2) {
+ if (ENFORCING_SIZE_LIMIT(var_message_limit)
+ && var_message_limit - state->act_size < len + 2) {
state->err = CLEANUP_STAT_SIZE;
msg_warn("%s: queue file size limit exceeded",
state->queue_id ? state->queue_id : "NOQUEUE");
}
}
/* Block too large chunks. */
- if (var_message_limit > 0
+ if (ENFORCING_SIZE_LIMIT(var_message_limit)
&& state->act_size > var_message_limit - chunk_size) {
state->error_mask |= MAIL_ERROR_POLICY;
msg_warn("%s: BDAT request from %s exceeds message size limit",
start = vstring_str(state->bdat_get_buffer);
len = VSTRING_LEN(state->bdat_get_buffer);
if (state->err == CLEANUP_STAT_OK) {
- if (var_message_limit > 0
+ if (ENFORCING_SIZE_LIMIT(var_message_limit)
&& var_message_limit - state->act_size < len + 2) {
state->err = CLEANUP_STAT_SIZE;
msg_warn("%s: queue file size limit exceeded",
* arbitrarily pick a small multiple of the per-message size limit. This
* helps to avoid many unneeded (re)transmissions.
*/
- if (var_queue_minfree > 0
- && var_message_limit > 0
+ if (ENFORCING_SIZE_LIMIT(var_queue_minfree)
+ && ENFORCING_SIZE_LIMIT(var_message_limit)
&& var_queue_minfree / 1.5 < var_message_limit)
msg_warn("%s(%lu) should be at least 1.5*%s(%lu)",
VAR_QUEUE_MINFREE, (unsigned long) var_queue_minfree,
};
static const CONFIG_INT_TABLE int_table[] = {
VAR_SMTPD_RCPT_LIMIT, DEF_SMTPD_RCPT_LIMIT, &var_smtpd_rcpt_limit, 1, 0,
- VAR_QUEUE_MINFREE, DEF_QUEUE_MINFREE, &var_queue_minfree, 0, 0,
VAR_UNK_CLIENT_CODE, DEF_UNK_CLIENT_CODE, &var_unk_client_code, 0, 0,
VAR_BAD_NAME_CODE, DEF_BAD_NAME_CODE, &var_bad_name_code, 0, 0,
VAR_UNK_NAME_CODE, DEF_UNK_NAME_CODE, &var_unk_name_code, 0, 0,
VAR_SMTPD_POLICY_TRY_LIMIT, DEF_SMTPD_POLICY_TRY_LIMIT, &var_smtpd_policy_try_limit, 1, 0,
0,
};
+ static const CONFIG_LONG_TABLE long_table[] = {
+ VAR_QUEUE_MINFREE, DEF_QUEUE_MINFREE, &var_queue_minfree, 0, 0,
+ 0,
+ };
static const CONFIG_TIME_TABLE time_table[] = {
VAR_SMTPD_TMOUT, DEF_SMTPD_TMOUT, &var_smtpd_tmout, 1, 0,
VAR_SMTPD_ERR_SLEEP, DEF_SMTPD_ERR_SLEEP, &var_smtpd_err_sleep, 0, 0,
single_server_main(argc, argv, smtpd_service,
CA_MAIL_SERVER_NINT_TABLE(nint_table),
CA_MAIL_SERVER_INT_TABLE(int_table),
+ CA_MAIL_SERVER_LONG_TABLE(long_table),
CA_MAIL_SERVER_STR_TABLE(str_table),
CA_MAIL_SERVER_RAW_TABLE(raw_table),
CA_MAIL_SERVER_BOOL_TABLE(bool_table),
/*
* Check against file size limit.
*/
- if (var_message_limit > 0 && size > var_message_limit) {
+ if (ENFORCING_SIZE_LIMIT(var_message_limit) && size > var_message_limit) {
(void) smtpd_check_reject(state, MAIL_ERROR_POLICY,
552, "5.3.4",
"Message size exceeds fixed limit");
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
/* System library. */
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
/*
ssize_t len;
len = netstring_get_length(stream);
- if (limit && len > limit)
+ if (ENFORCING_SIZE_LIMIT(limit) && len > limit)
netstring_except(stream, NETSTRING_ERR_SIZE);
netstring_get_data(stream, buf, len);
return (buf);
* Bit banging!! There is no official constant that defines the INT_MAX
* equivalent for off_t, ssize_t, etc. Wietse came up with the following
* macro that works as long as off_t, ssize_t, etc. use one's or two's
- * complement logic (that is, the maximum value is binary 01...1). Don't
- * use right-shift for signed types: the result is implementation-defined.
+ * complement logic (that is, the maximum value is binary 01...1). Don't use
+ * right-shift for signed types: the result is implementation-defined.
*/
#include <limits.h>
#define __MAXINT__(T) ((T) ~(((T) 1) << ((sizeof(T) * CHAR_BIT) - 1)))
#define SSIZE_T_MAX __MAXINT__(ssize_t)
#endif
+ /*
+ * Consistent enforcement of size limits.
+ */
+#define ENFORCING_SIZE_LIMIT(param) ((param) > 0)
+
/*
* Setting globals like h_errno can be problematic when Postfix is linked
* with multi-threaded libraries.
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
/* System library. */
* because that prohibits the delivery agent from updating the queue
* file.
*/
- if (var_virt_mailbox_limit) {
- if (var_virt_mailbox_limit < var_message_limit || var_message_limit == 0)
- msg_fatal("main.cf configuration error: %s is smaller than %s",
+ if (ENFORCING_SIZE_LIMIT(var_virt_mailbox_limit)) {
+ if (!ENFORCING_SIZE_LIMIT(var_message_limit))
+ msg_fatal("configuration error: %s is limited but %s is "
+ "unlimited", VAR_VIRT_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT);
+ if (var_virt_mailbox_limit < var_message_limit)
+ msg_fatal("configuration error: %s is smaller than %s",
VAR_VIRT_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT);
set_file_limit(var_virt_mailbox_limit);
}