would corrupt files that rely on single-writer updates
(examples: verify(8) cache, tlsmgr(8) caches, etc.). File:
master/master.c.
+
+20080226
+
+ Cleanup: the postfix command did not set argv[0] to a sane
+ value when invoking postfix-script. Reported by Victor
+ Duchovni. File: postfix/postfix.c.
+
+20080228
+
+ Bugfix: bounce(8) segfault on one-line template text.
+ Problem found by Sacha Chlytor. File: bounce/bounce_template.c.
+
+20080310
+
+ Safety: the SMTP server's Dovecot authentication client now
+ enforces the SASL mechanism output filter also on client
+ command input. File: src/xsasl/xsasl_dovecot_server.c.
+
+20080311
+
+ Bugfix (introduced 20070811): the MAIL and RCPT Milter
+ application call-backs no longer received {mail_addr} or
+ {rcpt_addr} information. Problem reported by Anton Yuzhaninov.
+ File: smtpd/smtpd.c.
+
+ Bugfix (introduced 20080207): "cleanup -v" panic because
+ the new "SMTP reply" request flag did not have a printable
+ name. File: global/cleanup_strflags.c.
Wish list:
+ Encapsulate time_t comparisons so that they can be made
+ system dependent (use difftime() where available).
+
+ Encapsulate time_t conversions (e.g. REC_TYPE_TIME) so that
+ they can be made system dependent.
+
+ Make "AUTH=<>" appendage to MAIL FROM configurable, enabled
+ by default.
+
To support ternary operator without a huge parsing effort,
consider ${value?{xxx}:{yyy}} where ${name} is existing
syntax, and where ?{text} and :{text} are new syntax that
file ID, message size, arrival time, sender, and
the recipients that still need to be delivered. If
mail could not be delivered upon the last attempt,
- the reason for failure is shown. This mode of oper-
- ation is implemented by executing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a>
- command.
+ the reason for failure is shown. The queue ID
+ string is followed by an optional status character:
+
+ <b>*</b> The message is in the <b>active</b> queue, i.e. the
+ message is selected for delivery.
+
+ <b>!</b> The message is in the <b>hold</b> queue, i.e. no
+ further delivery attempt will be made until
+ the mail is taken off hold.
+
+ This mode of operation is implemented by executing
+ the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> command.
<b>newaliases</b>
Initialize the alias database. If no input file is
file ID, message size, arrival time, sender, and
the recipients that still need to be delivered. If
mail could not be delivered upon the last attempt,
- the reason for failure is shown. This mode of oper-
- ation is implemented by executing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a>
- command.
+ the reason for failure is shown. The queue ID
+ string is followed by an optional status character:
+
+ <b>*</b> The message is in the <b>active</b> queue, i.e. the
+ message is selected for delivery.
+
+ <b>!</b> The message is in the <b>hold</b> queue, i.e. no
+ further delivery attempt will be made until
+ the mail is taken off hold.
+
+ This mode of operation is implemented by executing
+ the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> command.
<b>newaliases</b>
Initialize the alias database. If no input file is
file ID, message size, arrival time, sender, and
the recipients that still need to be delivered. If
mail could not be delivered upon the last attempt,
- the reason for failure is shown. This mode of oper-
- ation is implemented by executing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a>
- command.
+ the reason for failure is shown. The queue ID
+ string is followed by an optional status character:
+
+ <b>*</b> The message is in the <b>active</b> queue, i.e. the
+ message is selected for delivery.
+
+ <b>!</b> The message is in the <b>hold</b> queue, i.e. no
+ further delivery attempt will be made until
+ the mail is taken off hold.
+
+ This mode of operation is implemented by executing
+ the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> command.
<b>newaliases</b>
Initialize the alias database. If no input file is
List the mail queue. Each entry shows the queue file ID, message
size, arrival time, sender, and the recipients that still need to
be delivered. If mail could not be delivered upon the last attempt,
-the reason for failure is shown. This mode of operation is implemented
-by executing the \fBpostqueue\fR(1) command.
+the reason for failure is shown. The queue ID string is
+followed by an optional status character:
+.RS
+.IP \fB*\fR
+The message is in the \fBactive\fR queue, i.e. the message is
+selected for delivery.
+.IP \fB!\fR
+The message is in the \fBhold\fR queue, i.e. no further delivery
+attempt will be made until the mail is taken off hold.
+.RE
+.IP
+This mode of operation is implemented by executing the
+\fBpostqueue\fR(1) command.
.IP \fBnewaliases\fR
Initialize the alias database. If no input file is specified (with
the \fB-oA\fR option, see below), the program processes the file(s)
* Is this 7bit or 8bit text? If the character set is US-ASCII, then
* don't allow 8bit text. Don't assume 8bit when charset was changed.
*/
-#define NON_ASCII(p) (*(p) && !allascii((p)))
+#define NON_ASCII(p) ((p) && *(p) && !allascii((p)))
if (NON_ASCII(cp) || NON_ASCII(tval)) {
if (strcasecmp(tp->mime_charset, "us-ascii") == 0) {
CLEANUP_FLAG_BCC_OK, "enable_automatic_bcc",
CLEANUP_FLAG_MAP_OK, "enable_address_mapping",
CLEANUP_FLAG_MILTER, "enable_milters",
+ CLEANUP_FLAG_SMTP_REPLY, "enable_smtp_reply",
};
/* cleanup_strflags - map flags code to printable string */
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20080221"
+#define MAIL_RELEASE_DATE "20080316"
#define MAIL_VERSION_NUMBER "2.6"
#ifdef SNAPSHOT
msg_fatal("chdir(%s): %m", var_queue_dir);
/*
- * Run the management script with as process name ourself.
+ * Run the management script.
*/
script = concatenate(var_daemon_dir, "/postfix-script", (char *) 0);
+ if (optind < 1)
+ msg_panic("bad optind value");
+ argv[optind - 1] = script;
execvp(script, argv + optind - 1);
msg_fatal("%s: %m", script);
}
/* List the mail queue. Each entry shows the queue file ID, message
/* size, arrival time, sender, and the recipients that still need to
/* be delivered. If mail could not be delivered upon the last attempt,
-/* the reason for failure is shown. This mode of operation is implemented
-/* by executing the \fBpostqueue\fR(1) command.
+/* the reason for failure is shown. The queue ID string is
+/* followed by an optional status character:
+/* .RS
+/* .IP \fB*\fR
+/* The message is in the \fBactive\fR queue, i.e. the message is
+/* selected for delivery.
+/* .IP \fB!\fR
+/* The message is in the \fBhold\fR queue, i.e. no further delivery
+/* attempt will be made until the mail is taken off hold.
+/* .RE
+/* .IP
+/* This mode of operation is implemented by executing the
+/* \fBpostqueue\fR(1) command.
/* .IP \fBnewaliases\fR
/* Initialize the alias database. If no input file is specified (with
/* the \fB-oA\fR option, see below), the program processes the file(s)
if (smtpd_milters != 0
&& SMTPD_STAND_ALONE(state) == 0
&& (state->saved_flags & MILTER_SKIP_FLAGS) == 0) {
+ PUSH_STRING(saved_sender, state->sender, STR(state->addr_buf));
err = milter_mail_event(smtpd_milters,
milter_argv(state, argc - 2, argv + 2));
if (err != 0) {
/* Log reject etc. with correct sender information. */
- PUSH_STRING(saved_sender, state->sender, STR(state->addr_buf));
err = check_milter_reply(state, err);
- POP_STRING(saved_sender, state->sender);
}
+ POP_STRING(saved_sender, state->sender);
if (err != 0) {
/* XXX Reset access map side effects. */
mail_reset(state);
}
if (smtpd_milters != 0
&& (state->saved_flags & MILTER_SKIP_FLAGS) == 0) {
+ PUSH_STRING(saved_rcpt, state->recipient, STR(state->addr_buf));
err = milter_rcpt_event(smtpd_milters,
milter_argv(state, argc - 2, argv + 2));
if (err != 0) {
/* Log reject etc. with correct recipient information. */
- PUSH_STRING(saved_rcpt, state->recipient, STR(state->addr_buf));
err = check_milter_reply(state, err);
- POP_STRING(saved_rcpt, state->recipient);
}
+ POP_STRING(saved_rcpt, state->recipient);
if (err != 0) {
smtpd_chat_reply(state, "%s", err);
return (-1);
/* The verified client hostname. This name is represented by
/* the string "unknown" when 1) the address->name lookup failed,
/* 2) the name->address mapping fails, or 3) the name->address
-/* does not produce the client IP address.
+/* mapping does not produce the client IP address.
/* .IP reverse_name
/* The unverified client hostname as found with address->name
/* lookup; it is not verified for consistency with the client
#include <stdlib.h>
#include <string.h>
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
/* Utility library. */
#include <msg.h>
#include <vstream.h>
#include <vstring_vstream.h>
#include <name_mask.h>
+#include <argv.h>
/* Global library. */
VSTRING *sasl_line;
unsigned int sec_props; /* Postfix mechanism filter */
char *mechanism_list; /* filtered mechanism list */
+ ARGV *mechanism_argv; /* ditto */
} XSASL_DOVECOT_SERVER;
/*
/* xsasl_dovecot_server_mech_filter - filter server mechanism list */
-static char *xsasl_dovecot_server_mech_filter(XSASL_DCSRV_MECH *mechanism_list,
+static char *xsasl_dovecot_server_mech_filter(ARGV *mechanism_argv,
+ XSASL_DCSRV_MECH *mechanism_list,
unsigned int conf_props)
{
const char *myname = "xsasl_dovecot_server_mech_filter";
if (VSTRING_LEN(mechanisms_str) > 0)
VSTRING_ADDCH(mechanisms_str, ' ');
vstring_strcat(mechanisms_str, mp->mech_name);
+ argv_add(mechanism_argv, mp->mech_name, (char *) 0);
if (msg_verbose)
msg_info("%s: keep mechanism: %s", myname, mp->mech_name);
} else {
server->service = mystrdup(service);
server->last_request_id = 0;
server->mechanism_list = 0;
+ server->mechanism_argv = 0;
server->sec_props =
name_mask_opt(myname, xsasl_dovecot_conf_sec_props,
sec_props, NAME_MASK_ANY_CASE | NAME_MASK_FATAL);
if (xsasl_dovecot_server_connect(server->impl) < 0)
return (0);
}
- if (server->mechanism_list == 0)
+ if (server->mechanism_list == 0) {
+ server->mechanism_argv = argv_alloc(2);
server->mechanism_list =
- xsasl_dovecot_server_mech_filter(server->impl->mechanism_list,
+ xsasl_dovecot_server_mech_filter(server->mechanism_argv,
+ server->impl->mechanism_list,
server->sec_props);
+ }
return (server->mechanism_list[0] ? server->mechanism_list : 0);
}
vstring_free(server->sasl_line);
if (server->username)
myfree(server->username);
- if (server->mechanism_list)
+ if (server->mechanism_list) {
myfree(server->mechanism_list);
+ argv_free(server->mechanism_argv);
+ }
myfree(server->service);
myfree((char *) server);
}
const char *myname = "xsasl_dovecot_server_first";
XSASL_DOVECOT_SERVER *server = (XSASL_DOVECOT_SERVER *) xp;
int i;
+ char **cpp;
#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3))
IFELSE(init_response, ", init_response ", ""),
IFELSE(init_response, init_response, ""));
+ if (server->mechanism_argv == 0)
+ msg_panic("%s: no mechanism list", myname);
+
+ for (cpp = server->mechanism_argv->argv; /* see below */ ; cpp++) {
+ if (*cpp == 0) {
+ vstring_strcpy(reply, "Invalid authentication mechanism");
+ return XSASL_AUTH_FAIL;
+ }
+ if (strcasecmp(sasl_method, *cpp) == 0)
+ break;
+ }
if (init_response)
if (!is_valid_base64(init_response)) {
vstring_strcpy(reply, "Invalid base64 data in initial response");