Cleanup: document under what conditions these protections
work, with REENTRANCY sections in the relevant man pages.
- Files: util/vbuf.c. util/msg.c, util/msg_output.c.
+ Files: util/vbuf_print.c. util/msg.c, util/msg_output.c.
+20061211
+
+ When the remote SMTP client certificate isn't verified,
+ don't send ccert_subject and ccert_issuer attributes in
+ check_policy_service requests. Victor Duchovni. File:
+ smtpd/smtpd_check.c.
+
+ Bugfix: the postconf command still complained about an
+ unqualified machine name, because it was not updated with
+ the 20050513 change that introduced a default "mydomain =
+ localdomain". File: postconf/postconf.c.
+
+20061213
+
+ Cleanup: the sendmail and postqueue commands no longer
+ terminate with a non-standard error status after a run-time
+ error in some Postfix internal routine (typically, some
+ essential file is not accessible, or the system is out of
+ memory). Files: sendmail/sendmail.c, postqueue/postqueue.c.
+
+20061220
+
+ Workaround: PMilter 0.95 does not deliver SMFIC_EOB+data
+ to the application as SMFIC_BODY+data followed by SMFIC_EOB.
+ To avoid compatibility problems, Postfix now sends
+ SMFIC_BODY+data followed by SMFIC_EOB. File: milter/milter8.c.
+
+ Bugfix (introduced with Postfix 2.3): when inserting
+ Milter-generated headers at increasing positions in a
+ message, a later header could end up at a previously used
+ insertion point. Thus, inserting headers at positions (N,
+ N+M) could work as if (N, N) had been specified. Problem
+ reported by Mark Martinec. File: milter/milter8.c.
*
* Thus, header insert operations are relative to the content as delivered,
* that is, the content including our own Received: header.
+ *
+ * None of the above is applicable after a Milter inserts a header before
+ * our own Received: header. From then on, our own Received: header
+ * becomes just like other headers.
*/
#define CLEANUP_FIND_HEADER_NOTFOUND (-1)
#define CLEANUP_FIND_HEADER_IOERROR (-2)
}
/* The middle of a multi-record header. */
else if (last_type == REC_TYPE_CONT || IS_SPACE_TAB(STR(buf)[0])) {
- /* Reset the saved PTR record. */
- ptr_offset = 0;
+ /* Reset the saved PTR record and update last_type. */
}
/* No more message headers. */
else if ((len = is_header(STR(buf))) == 0) {
}
/* This the start of a message header. */
else if (hdr_count++ < skip_headers)
- continue;
+ /* Reset the saved PTR record and update last_type. */ ;
else if ((header_label == 0
|| (strncasecmp(header_label, STR(buf), len) == 0
&& (IS_SPACE_TAB(STR(buf)[len])
/* If we have a saved PTR record, it points to start of header. */
break;
}
+ ptr_offset = 0;
last_type = rec_type;
}
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20061211"
-#define MAIL_VERSION_NUMBER "2.3.5"
+#define MAIL_RELEASE_DATE "20061221"
+#define MAIL_VERSION_NUMBER "2.3.6-RC1"
#ifdef SNAPSHOT
# define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
vstring_memcat(milter->body, bp, count);
bp += count;
todo -= count;
- /* Flush body chunk buffer when full. */
+ /* Flush body chunk buffer when full. See also milter8_eob(). */
if (LEN(milter->body) == MILTER_CHUNK_SIZE) {
msg_ctx->resp =
milter8_event(milter, SMFIC_BODY, SMFIP_NOBODY,
DONT_SKIP_REPLY, msg_ctx->macros,
MILTER8_DATA_BUFFER, milter->body,
MILTER8_DATA_END);
- if (msg_ctx->resp != 0 || milter->state != MILTER8_STAT_MESSAGE)
+ if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
break;
VSTRING_RESET(milter->body);
}
return;
if (msg_verbose)
msg_info("%s: eob milter %s", myname, milter->m.name);
+
+ /*
+ * Flush partial body chunk buffer. See also milter8_body().
+ *
+ * XXX Sendmail 8 libmilter accepts SMFIC_EOB+data, and delivers it to the
+ * application as two events: SMFIC_BODY+data followed by SMFIC_EOB. This
+ * breaks with the PMilter 0.95 protocol re-implementation, which
+ * delivers the SMFIC_EOB event and ignores the data. To avoid such
+ * compatibility problems we separate the events in the client. With
+ * this, we also prepare for a future where different event types can
+ * have different macro lists.
+ */
+ if (LEN(milter->body) > 0) {
+ msg_ctx->resp =
+ milter8_event(milter, SMFIC_BODY, SMFIP_NOBODY,
+ DONT_SKIP_REPLY, msg_ctx->macros,
+ MILTER8_DATA_BUFFER, milter->body,
+ MILTER8_DATA_END);
+ if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
+ return;
+ }
msg_ctx->resp =
milter8_event(msg_ctx->milter, SMFIC_BODYEOB, 0,
DONT_SKIP_REPLY, msg_ctx->macros,
- MILTER8_DATA_BUFFER, milter->body,
MILTER8_DATA_END);
}
/*
* If the local machine name is not in FQDN form, try to append the
* contents of $mydomain.
- *
- * XXX Do not complain when running as "postconf -d".
*/
name = get_hostname();
- if ((cmd_mode & SHOW_DEFS) == 0 && (dot = strchr(name, '.')) == 0) {
- if ((domain = mail_conf_lookup_eval(VAR_MYDOMAIN)) == 0) {
- msg_warn("My hostname %s is not a fully qualified name - set %s or %s in %s/main.cf",
- name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir);
- } else {
- name = concatenate(name, ".", domain, (char *) 0);
- }
+ if ((dot = strchr(name, '.')) == 0) {
+ if ((domain = mail_conf_lookup_eval(VAR_MYDOMAIN)) == 0)
+ domain = DEF_MYDOMAIN;
+ name = concatenate(name, ".", domain, (char *) 0);
}
return (name);
}
if (var_myhostname == 0)
get_myhostname();
if ((dot = strchr(var_myhostname, '.')) == 0 || strchr(dot + 1, '.') == 0)
- return (var_myhostname);
+ return (DEF_MYDOMAIN);
return (dot + 1);
}
}
}
+/* unavailable - sanitize exit status from library run-time errors */
+
+static void unavailable(void)
+{
+ exit(EX_UNAVAILABLE);
+}
+
/* usage - scream and die */
static NORETURN usage(void)
if ((slash = strrchr(argv[0], '/')) != 0 && slash[1])
argv[0] = slash + 1;
msg_vstream_init(argv[0], VSTREAM_ERR);
+ msg_cleanup(unavailable);
msg_syslog_init(mail_task("postqueue"), LOG_PID, LOG_FACILITY);
set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0]));
myfree(saved_sender);
}
+/* tempfail - sanitize exit status after library run-time error */
+
+static void tempfail(void)
+{
+ exit(EX_TEMPFAIL);
+}
+
/* main - the main program */
int main(int argc, char **argv)
if ((slash = strrchr(argv[0], '/')) != 0 && slash[1])
argv[0] = slash + 1;
msg_vstream_init(argv[0], VSTREAM_ERR);
+ msg_cleanup(tempfail);
msg_syslog_init(mail_task("sendmail"), LOG_PID, LOG_FACILITY);
set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0]));
#define IF_VERIFIED(x) \
((state->tls_context && \
state->tls_context->peer_verified && ((x) != 0)) ? (x) : "")
- ATTR_TYPE_STR, MAIL_ATTR_CCERT_SUBJECT, subject,
- ATTR_TYPE_STR, MAIL_ATTR_CCERT_ISSUER, issuer,
+ ATTR_TYPE_STR, MAIL_ATTR_CCERT_SUBJECT,
+ IF_VERIFIED(subject),
+ ATTR_TYPE_STR, MAIL_ATTR_CCERT_ISSUER,
+ IF_VERIFIED(issuer),
ATTR_TYPE_STR, MAIL_ATTR_CCERT_FINGERPRINT,
IF_VERIFIED(state->tls_context->peer_fingerprint),
#define IF_ENCRYPTED(x, y) ((state->tls_context && ((x) != 0)) ? (x) : (y))