for the per-destination logfile, to prevent an excessive
rate of delivery attempts when the queue file system is
mounted with "noatime". File: flush/flush.c.
+
+20071030
+
+ Bugfix (introduced Postfix 2.3): Postfix mistakenly enforced
+ the 64kbyte limit (for sending body parts TO Milter
+ applications) also while receiving packets FROM Milter
+ applications. The limit is now at least 1GB. File:
+ milter/milter8.c.
+
+20071202
+
+ Bugfix (introduced Postfix 2.2): don't update the back-to-back
+ delivery time stamp while deferring mail. File: *qmgr/qmgr_entry.c.
+
+20071211
+
+ Bugfix (introduced 19980315): the "write" equivalent of
+ bugfix 20030104. File: util/vstream.c.
+
+20071213
+
+ Bugfix (introduced Postfix 2.3): the SMTP client never
+ marked corrupt files as corrupt. Victor Duchovni. File:
+ smtp/smtp_proto.c.
+
+20071229
+
+ Bugfix: the Milter client did not replace the Postfix-specific
+ form for unknown host names by the Sendmail-specific form.
+ File: milter/milter8.c.
+
+20080104
+
+ Workaround: minor change to the Dovecot AUTH request to
+ prevent dovecot-auth memory wastage. Timo Sirainen. File:
+ xsasl/xsasl_dovecot_server.c.
+
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
+#include <limits.h> /* INT_MAX */
#ifndef SHUT_RDWR
#define SHUT_RDWR 2
/*
* We don't accept insane amounts of data.
*/
-#define XXX_MAX_DATA (MILTER_CHUNK_SIZE * 2)
+#define XXX_MAX_DATA (INT_MAX / 2)
#define XXX_TIMEOUT 10
#ifndef USE_LIBMILTER_INCLUDES
const char *myname = "milter8_conn_event";
MILTER8 *milter = (MILTER8 *) m;
int port;
+ const char *sm_name;
+ char *ptr = 0;
+ const char *resp;
+
+ /*
+ * Need a global definition for "unknown" host name or address that is
+ * shared by smtpd, cleanup and libmilter.
+ */
+#define XXX_UNKNOWN "unknown"
+#define STR_EQ(x,y) (strcmp((x), (y)) == 0)
+#define STR_NE(x,y) (strcmp((x), (y)) != 0)
/*
* XXX Sendmail 8 libmilter closes the MTA-to-filter socket when it finds
port = 0;
}
milter->state = MILTER8_STAT_ENVELOPE;
+ /* Transform unknown hostname from Postfix to Sendmail form. */
+ sm_name = (STR_NE(client_name, XXX_UNKNOWN) ? client_name :
+ STR_EQ(client_addr, XXX_UNKNOWN) ? client_name :
+ (ptr = concatenate("[", client_addr, "]", (char *) 0)));
switch (addr_family) {
case AF_INET:
- return (milter8_event(milter, SMFIC_CONNECT, SMFIP_NOCONNECT,
- DONT_SKIP_REPLY, macros,
- MILTER8_DATA_STRING, client_name,
- MILTER8_DATA_OCTET, SMFIA_INET,
- MILTER8_DATA_NSHORT, htons(port),
- MILTER8_DATA_STRING, client_addr,
- MILTER8_DATA_END));
+ resp = milter8_event(milter, SMFIC_CONNECT, SMFIP_NOCONNECT,
+ DONT_SKIP_REPLY, macros,
+ MILTER8_DATA_STRING, sm_name,
+ MILTER8_DATA_OCTET, SMFIA_INET,
+ MILTER8_DATA_NSHORT, htons(port),
+ MILTER8_DATA_STRING, client_addr,
+ MILTER8_DATA_END);
+ break;
#ifdef HAS_IPV6
case AF_INET6:
- return (milter8_event(milter, SMFIC_CONNECT, SMFIP_NOCONNECT,
- DONT_SKIP_REPLY, macros,
- MILTER8_DATA_STRING, client_name,
- MILTER8_DATA_OCTET, SMFIA_INET6,
- MILTER8_DATA_NSHORT, htons(port),
- MILTER8_DATA_STRING, client_addr,
- MILTER8_DATA_END));
+ resp = milter8_event(milter, SMFIC_CONNECT, SMFIP_NOCONNECT,
+ DONT_SKIP_REPLY, macros,
+ MILTER8_DATA_STRING, sm_name,
+ MILTER8_DATA_OCTET, SMFIA_INET6,
+ MILTER8_DATA_NSHORT, htons(port),
+ MILTER8_DATA_STRING, client_addr,
+ MILTER8_DATA_END);
+ break;
#endif
case AF_UNIX:
- return (milter8_event(milter, SMFIC_CONNECT, SMFIP_NOCONNECT,
- DONT_SKIP_REPLY, macros,
- MILTER8_DATA_STRING, client_name,
- MILTER8_DATA_OCTET, SMFIA_UNIX,
- MILTER8_DATA_NSHORT, htons(0),
- MILTER8_DATA_STRING, client_addr,
- MILTER8_DATA_END));
+ resp = milter8_event(milter, SMFIC_CONNECT, SMFIP_NOCONNECT,
+ DONT_SKIP_REPLY, macros,
+ MILTER8_DATA_STRING, sm_name,
+ MILTER8_DATA_OCTET, SMFIA_UNIX,
+ MILTER8_DATA_NSHORT, htons(0),
+ MILTER8_DATA_STRING, client_addr,
+ MILTER8_DATA_END);
+ break;
default:
- return (milter8_event(milter, SMFIC_CONNECT, SMFIP_NOCONNECT,
- DONT_SKIP_REPLY, macros,
- MILTER8_DATA_STRING, client_name,
- MILTER8_DATA_OCTET, SMFIA_UNKNOWN,
- MILTER8_DATA_END));
+ resp = milter8_event(milter, SMFIC_CONNECT, SMFIP_NOCONNECT,
+ DONT_SKIP_REPLY, macros,
+ MILTER8_DATA_STRING, sm_name,
+ MILTER8_DATA_OCTET, SMFIA_UNKNOWN,
+ MILTER8_DATA_END);
+ break;
}
+ if (ptr != 0)
+ myfree(ptr);
+ return (resp);
default:
msg_panic("%s: milter %s: bad state %d",
myname, milter->m.name, milter->state);
static void vstream_buf_alloc(VBUF *bp, ssize_t len)
{
+ VSTREAM *stream = VBUF_TO_APPL(bp, VSTREAM, buf);
ssize_t used = bp->ptr - bp->data;
const char *myname = "vstream_buf_alloc";
bp->data = (unsigned char *)
(bp->data ? myrealloc((char *) bp->data, len) : mymalloc(len));
bp->len = len;
- if (bp->flags & VSTREAM_FLAG_READ)
+ if (bp->flags & VSTREAM_FLAG_READ) {
bp->ptr = bp->data + used;
- else
+ if (bp->flags & VSTREAM_FLAG_DOUBLE)
+ VSTREAM_SAVE_STATE(stream, read_buf, read_fd);
+ } else {
VSTREAM_BUF_AT_OFFSET(bp, used);
+ if (bp->flags & VSTREAM_FLAG_DOUBLE)
+ VSTREAM_SAVE_STATE(stream, write_buf, write_fd);
+ }
}
/* vstream_buf_wipe - reset buffer to initial state */
* allocation gives the application a chance to override the default
* buffering policy.
*/
- if (bp->data == 0) {
+ if (bp->data == 0)
vstream_buf_alloc(bp, VSTREAM_BUFSIZE);
- if (bp->flags & VSTREAM_FLAG_DOUBLE)
- VSTREAM_SAVE_STATE(stream, read_buf, read_fd);
- }
/*
* If the stream is double-buffered and the write buffer is not empty,