with the introduction of the asynchronous bounce client.
Patrik Rak.
+20010313
+
+ Bugfix: the RFC 822 untokenizer quoted newlines inside
+ comments. File: global/tok822_parse.c.
+
+20010316
+
+ Cleanup: removed an extraneous warning when a queue file
+ write error happened.
+
20010321
Workaround: LMTP connection caching never worked for
20010322
Portability: Solaris <2.6 does not have srandom() and
- random() in libc. File: util/rand_sleep.c. It does not
- have to be cryptographically strong.
+ random() in libc. File: util/rand_sleep.c. It does not have
+ to be cryptographically strong.
Bugfix: the fast ETRN flush server could not handle [ipaddr]
- or domain names with one-character hostname part. It should
- be OK now. File: flush/flush.c.
+ or domain names with one-character hostname part. This
+ fix changes the destination to logfile name mapping, so
+ that you need to populate the new files with "sendmail -q".
+ The old files go away automatically. File: flush/flush.c.
20010327
Speed up mailq (sendmail -bp) display by flushing output
after each file. File: showq/showq.c.
+
+ Portability: missing string.h includes, %p wants (void *),
+ Lamont Jones, HP.
+
+20010328
+
+ Bugfix: swapped logic caused cleanup to stall when the
+ queue file size exceeded the file size limit by less than
+ one the VSTREAM buffer size, so that the "file too big"
+ was detected after flushing the last queue file record.
+ File: cleanup/cleanup.c.
+
+20010329
+
+ Portability: workaround for missing prototype problem in
+ dict_ldap.c. This module should move to the global directory,
+ because it depends on Postfix main.cf parameter information.
+
+ Workaround: after sending a trigger message over a socket,
+ do not immediately close the client side, but close it from
+ a background thread that waits until the server closes the
+ socket first. This avoids trouble with socket implementations
+ that destroy a socket when the client closes a socket
+ before the server has received the client's data. Files:
+ util/{inet,unix,stream}_trigger.c, util/events.c,
+ master/master_trigger.c, postkick/postkick.c.
% egrep '(reject|warning|error|fatal|panic):' /some/log/file
+Typical logfile names are: /var/log/maillog or /var/log/syslog.
+See /etc/syslog.conf for actual logfile names.
+
When it is run for the first time, the Postfix startup shell script
will create a bunch of subdirectories below the Postfix spool
directory.
% egrep '(reject|warning|error|fatal|panic):' /some/log/file
+Typical logfile names are: /var/log/maillog or /var/log/syslog.
+See /etc/syslog.conf for actual logfile names.
+
When it is run for the first time, the Postfix startup shell script
will create a bunch of subdirectories below the Postfix spool
directory.
% egrep '(reject|warning|error|fatal|panic):' /some/log/file
+Typical logfile names are: /var/log/maillog or /var/log/syslog.
+See /etc/syslog.conf for actual logfile names.
+
When it is run for the first time, the Postfix startup shell script
will create a bunch of subdirectories below the Postfix spool
directory.
# postfix check
# egrep '(reject|warning|error|fatal|panic):' /some/log/file
+Typical logfile names are: /var/log/maillog or /var/log/syslog.
+See /etc/syslog.conf for actual logfile names.
+
+The first line (postfix check) causes Postfix to report file
+permission/ownership discrepancies.
+
The second line looks for problem reports from the mail software,
and reports how effective the anti-relay and anti-UCE blocks are.
We've written code to add a mysql map type. It utilizes the mysql
client library, which can be obtained from:
- http://www.tcx.se/download.html
+ http://www.mysql.com/downloads/
+ http://sourceforge.net/projects/mysql/
In order to build postfix with mysql map support, you will need to add
-DHAS_MYSQL and -I for the directory containing the mysql headers, and
-Release 20010228 differs from snapshot 20010228 in that the virtual
-delivery agent and nqmgr queue manager are left out. That software
-will become part of the official release when it has not changed
-in a while.
+Incompatible changes with snapshot-20010329
+===========================================
+
+This release changes the names of the "fast ETRN" logfiles with
+delayed mail per destination. These files are maintained by the
+Postfix "fast flush" daemon. The old scheme failed with addresses
+of the form user@[ip.address] and user@a.domain.name. In order to
+populate the new "fast ETRN" logfiles, execute the command "sendmail
+-q". The old "fast ETRN" logfiles go away by themselves (default:
+after 7 days).
+
+Major changes with snapshot-20010329
+====================================
+
+Better support for sites that run multiple Postfix instances on
+one machine. Each instance can now be recognized by its logging
+(default: "syslog_name = postfix"). File: global/mail_task.c.
+
+Workaround for nqmgr panic due to a race condition that was introduced
+with the asynchronous bounce client.
+
+Workaround for hostile socket implementations that discard data
+when a client closes a socket before the server reads the client
+data. Postfix now closes the client socket in a background thread
+that waits until the server closes the socket first.
Incompatible changes with snapshot-20010225
===========================================
permit_mynetworks permit_sasl_authenticated ...
In /usr/local/lib/sasl/smtpd.conf you need to specify how the server
-should validate client passwords. For example:
+should validate client passwords.
+
+In order to authenticate against the UNIX password database, try:
+
+ /usr/local/lib/sasl/smtpd.conf:
+ pwcheck_method: pwcheck
+
+The pwcheck daemon is contained in the cyrus-sasl source tarball.
+
+In order to authenticate against SASL's own password database:
/usr/local/lib/sasl/smtpd.conf:
pwcheck_method: sasldb
EXAMPLE: saslpasswd -c -u `postconf -h myhostname` exampleuser
-Instead of the SASL-specific password file you can configure the
-Postfix SMTP server to validate client passwords against the UNIX
-shadow password file:
-
- /usr/local/lib/sasl/smtpd.conf:
- pwcheck_method: shadow
-
-However this requires that Postfix has read access to the UNIX shadow
-password file, which is normally readable only by root. Shadow
-password support has been found to work for Solaris 2.7 and RedHat
-6.1 but not with FreeBSD 3.4.
+To run software chrooted with SASL support is an interesting
+exercise. It probably is not worth the trouble.
-To run software chrooted with SASL support is an interesting exercise.
-This is one of the many problems with the present SASL support.
+Testing SASL authentication in the Postfix SMTP server
+======================================================
To test the whole mess, connect to the SMTP server, and you should
be able to have a conversation like this:
syslog_facility = mail
# The syslog_name parameter specifies the mail system name that is
-# prepended to the process name in syslog records headers, so that
-# "smtpd" becomes "postfix/smtpd".
+# prepended to the process name in syslog records, so that "smtpd"
+# becomes, for example, "postfix/smtpd".
#
# Beware: a non-default syslog_name setting takes effect only
# after process initialization. Some initialization errors will be
mkdir etc
cp /etc/services etc
+mkdir -p usr/lib
+cp /usr/lib/tztab usr/lib
<dt>Syntax:
<dd>Specify a list of zero or more lookup tables. Whenever a header
-matches a table, a REJECT result means reject the message, and a
-SKIP result means delete the header from the message.
+matches a table, a REJECT result means reject the message, and an
+IGNORE result means delete the header from the message.
<p>
if (CLEANUP_OUT_OK(state) == 0 && type > 0) {
if ((state->errs & CLEANUP_STAT_CONT) == 0)
msg_warn("%s: skipping further client input", state->queue_id);
- while ((type = rec_get(src, buf, 0)) > 0
- && type != REC_TYPE_END)
+ while (type != REC_TYPE_END
+ && (type = rec_get(src, buf, 0)) > 0)
/* void */ ;
}
flush.o: ../../include/vstring.h
flush.o: ../../include/vstring_vstream.h
flush.o: ../../include/myflock.h
-flush.o: ../../include/valid_hostname.h
flush.o: ../../include/htable.h
flush.o: ../../include/dict.h
flush.o: ../../include/argv.h
VAR_OWNREQ_SPECIAL, DEF_OWNREQ_SPECIAL, &var_ownreq_special,
0,
};
-const char *cp;
+ const char *cp;
/*
* Extract syslog_facility early, so that from here on all errors are
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-20010327"
+#define DEF_MAIL_VERSION "Snapshot-20010329"
extern char *var_mail_version;
/* LICENSE
VSTRING *buf = vstring_alloc(100);
while (readlline(buf, VSTREAM_IN, (int *) 0, READLL_KEEPNL)) {
+ while (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\n') {
+ vstring_end(buf)[-1] = 0;
+ vstring_truncate(buf, VSTRING_LEN(buf) - 1);
+ }
if (!isatty(vstream_fileno(VSTREAM_IN)))
vstream_printf(">>>%s<<<\n\n", vstring_str(buf));
list = tok822_parse(vstring_str(buf));
wietse@[stuff
wietse@["stuff]
named group: foo@bar, baz@barf;
+wietse@foo (wietse
+ venema)
named group: foo@bar,
baz@barf;
+>>>wietse@foo (wietse
+ venema)<<<
+
+Parse tree:
+ address
+ atom "wietse"
+ OP "@"
+ atom "foo"
+ comment
+ text "wietse
+ venema"
+
+Internalized:
+wietse@foo (wietse
+ venema)
+
+Externalized, no newlines inserted:
+wietse@foo (wietse
+ venema)
+
+Externalized, newlines inserted:
+wietse@foo (wietse
+ venema)
+
postkick.o: ../../include/vbuf.h
postkick.o: ../../include/msg_vstream.h
postkick.o: ../../include/safe.h
+postkick.o: ../../include/events.h
postkick.o: ../../include/mail_proto.h
postkick.o: ../../include/iostuff.h
postkick.o: ../../include/mail_params.h
/*
* Kick the service.
*/
- if (mail_trigger(class, service, request, strlen(request) + 1) < 0) {
+ if (mail_trigger(class, service, request, strlen(request)) < 0) {
msg_warn("Cannot contact class %s service %s - perhaps the mail system is down",
class, service);
exit(1);
} else {
- event_loop(-1);
+ event_drain();
exit(0);
}
}
message_data = mymalloc(message_length);
memset(message_data, 'X', message_length);
for (i = 80; i < message_length; i += 80) {
+ message_data[i - 80] = "0123456789"[(i/80) % 10];
message_data[i - 2] = '\r';
message_data[i - 1] = '\n';
}
inet_trigger.o: msg.h
inet_trigger.o: connect.h
inet_trigger.o: iostuff.h
+inet_trigger.o: mymalloc.h
+inet_trigger.o: events.h
inet_trigger.o: trigger.h
inet_util.o: inet_util.c
inet_util.o: sys_defs.h
safe_open.o: safe_open.h
sane_accept.o: sane_accept.c
sane_accept.o: sys_defs.h
+sane_accept.o: msg.h
sane_accept.o: sane_accept.h
sane_link.o: sane_link.c
sane_link.o: sys_defs.h
stream_trigger.o: msg.h
stream_trigger.o: connect.h
stream_trigger.o: iostuff.h
+stream_trigger.o: mymalloc.h
+stream_trigger.o: events.h
stream_trigger.o: trigger.h
sys_compat.o: sys_compat.c
sys_compat.o: sys_defs.h
unix_trigger.o: msg.h
unix_trigger.o: connect.h
unix_trigger.o: iostuff.h
+unix_trigger.o: mymalloc.h
+unix_trigger.o: events.h
unix_trigger.o: trigger.h
unsafe.o: unsafe.c
unsafe.o: sys_defs.h
#include "dict.h"
#include "dict_ldap.h"
+/* AAARGH!! */
+
+#include "../global/mail_conf.h"
+
/*
* Structure containing all the configuration parameters for a given
* LDAP source, plus its connection handle.
/*
/* void event_disable_readwrite(fd)
/* int fd;
+/*
+/* void event_drain()
/* DESCRIPTION
/* This module delivers I/O and timer events.
/* Multiple I/O streams and timers can be monitored simultaneously.
/* event_disable_readwrite() disables further I/O events on the specified
/* I/O channel. The application is allowed to cancel non-existing
/* I/O event requests.
+/*
+/* event_drain() repeatedly calls event_loop() until no more timer
+/* events or I/O events are pending. This routine must not be called
+/* from an event_whatever() callback routine.
/* DIAGNOSTICS
/* Panics: interface violations. Fatal errors: out of memory,
/* system call failure. Warnings: the number of available
return (event_present);
}
+/* event_drain - loop until all pending events are done */
+
+void event_drain(void)
+{
+ fd_set zero_mask;
+
+ if (EVENT_INIT_NEEDED())
+ return;
+
+ FD_ZERO(&zero_mask);
+ while (event_timer_head.pred != event_timer_head.succ
+ || memcmp(&zero_mask, &event_xmask, sizeof(zero_mask)) != 0)
+ event_loop(-1);
+}
+
/* event_enable_read - enable read events */
void event_enable_read(int fd, EVENT_NOTIFY_RDWR callback, char *context)
extern time_t event_request_timer(EVENT_NOTIFY_TIME, char *, int);
extern int event_cancel_timer(EVENT_NOTIFY_TIME, char *);
extern void event_loop(int);
+extern void event_drain(void);
/*
* Event codes.
/* a brief connection to it and by writing the contents of the
/* named buffer.
/*
-/* The connection is closed by a background thread. Some kernels
-/* cannot handle client-side disconnect before the server has
-/* received the message.
+/* The connection is closed by a background thread. Some kernels
+/* cannot handle client-side disconnect before the server has
+/* received the message.
/*
/* Arguments:
/* .IP service
if (event == EVENT_TIME)
msg_warn("%s: read timeout for service %s", myname, ip->service);
event_disable_readwrite(ip->fd);
+ event_cancel_timer(inet_trigger_event, context);
if (close(ip->fd) < 0)
msg_warn("%s: close %s: %m", myname, ip->service);
myfree(ip->service);
/*
* Write the request...
*/
- if (write_buf(fd, buf, len, timeout) < 0)
+ if (write_buf(fd, buf, len, timeout) < 0
+ || write_buf(fd, "", 1, timeout) < 0)
if (msg_verbose)
msg_warn("%s: write to %s: %m", myname, service);
* Wakeup when the peer disconnects, or when we lose patience.
*/
if (timeout > 0)
- event_request_timer(inet_trigger_event, (char *) ip, timeout);
+ event_request_timer(inet_trigger_event, (char *) ip, timeout + 100);
event_enable_read(fd, inet_trigger_event, (char *) ip);
return (0);
}
if (event == EVENT_TIME)
msg_warn("%s: read timeout for service %s", myname, sp->service);
event_disable_readwrite(sp->fd);
+ event_cancel_timer(stream_trigger_event, context);
if (close(sp->fd) < 0)
msg_warn("%s: close %s: %m", myname, sp->service);
myfree(sp->service);
/*
* Write the request...
*/
- if (write_buf(fd, buf, len, timeout) < 0)
+ if (write_buf(fd, buf, len, timeout) < 0
+ || write_buf(fd, "", 1, timeout) < 0)
if (msg_verbose)
msg_warn("%s: write to %s: %m", myname, service);
* Wakeup when the peer disconnects, or when we lose patience.
*/
if (timeout > 0)
- event_request_timer(stream_trigger_event, (char *) sp, timeout);
+ event_request_timer(stream_trigger_event, (char *) sp, timeout + 100);
event_enable_read(fd, stream_trigger_event, (char *) sp);
return (0);
}
#if defined(IRIX5)
#define MISSING_USLEEP
+#endif
+
+#if defined(IRIX6)
+#define HAS_POSIX_REGEXP
#endif
/*
if (event == EVENT_TIME)
msg_warn("%s: read timeout for service %s", myname, up->service);
event_disable_readwrite(up->fd);
+ event_cancel_timer(unix_trigger_event, context);
if (close(up->fd) < 0)
msg_warn("%s: close %s: %m", myname, up->service);
myfree(up->service);
/*
* Write the request...
*/
- if (write_buf(fd, buf, len, timeout) < 0)
+ if (write_buf(fd, buf, len, timeout) < 0
+ || write_buf(fd, "", 1, timeout) < 0)
if (msg_verbose)
msg_warn("%s: write to %s: %m", myname, service);
* Wakeup when the peer disconnects, or when we lose patience.
*/
if (timeout > 0)
- event_request_timer(unix_trigger_event, (char *) up, timeout);
+ event_request_timer(unix_trigger_event, (char *) up, timeout + 100);
event_enable_read(fd, unix_trigger_event, (char *) up);
return (0);
}