- Add a "flush" service entry to /etc/postfix/master.cf if you were
running an older Postfix version:
- flush unix n - n - 0 flushd
+ flush unix - - n - 0 flush
+
+ That is, the same line as bounce, except that bounce is replaced
+ by flush, twice.
- Execute "postconf hash_queue_names" and verify that the output
includes at the very least the "active", "bounce", "defer", and
src/lmtp src/trivial-rewrite src/qmgr src/smtp src/bounce src/pipe \
src/showq src/postalias src/postcat src/postconf src/postdrop \
src/postkick src/postlock src/postlog src/postmap src/postsuper \
- src/nqmgr src/spawn src/flushd # src/base64 proto man html
+ src/nqmgr src/spawn src/flush # src/base64 proto man html
default: update
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
defer unix - - n - 0 bounce
+flush unix - - n - 0 flush
smtp unix - - n - - smtp
showq unix n - n - - showq
-flush unix n - n - 0 flushd
error unix - - n - - error
local unix - n n - - local
lmtp unix - - n - - lmtp
DAEMONS = bounce.8.html cleanup.8.html defer.8.html error.8.html local.8.html \
lmtp.8.html master.8.html pickup.8.html pipe.8.html qmgr.8.html \
showq.8.html smtp.8.html smtpd.8.html trivial-rewrite.8.html \
- nqmgr.8.html spawn.8.html flushd.8.html
+ nqmgr.8.html spawn.8.html flush.8.html
COMMANDS= mailq.1.html newaliases.1.html postalias.1.html postcat.1.html \
postconf.1.html postfix.1.html postkick.1.html postlock.1.html \
postlog.1.html postdrop.1.html postmap.1.html sendmail.1.html \
error.8.html: ../src/error/error.c
srctoman $? | nroff -man | man2html | postlink >$@
-flushd.8.html: ../src/flushd/flushd.c
+flush.8.html: ../src/flush/flush.c
srctoman $? | nroff -man | man2html | postlink >$@
cleanup.8.html: ../src/cleanup/cleanup.c
--- /dev/null
+<html> <head> </head> <body> <pre>
+
+
+
+FLUSH(8) FLUSH(8)
+
+
+<b>NAME</b>
+ flush - Postfix fast flush daemon
+
+<b>SYNOPSIS</b>
+ <b>flush</b> [generic Postfix daemon options]
+
+<b>DESCRIPTION</b>
+ The flush server maintains so-called "fast flush" logfiles
+ with information about what messages are queued for a spe-
+ cific site. This program expects to be run from the <a href="master.8.html"><b>mas-</b>
+ <b>ter</b>(8)</a> process manager.
+
+ This server implements the following requests:
+
+ <b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>ENABLE</b> <i>sitename</i>
+ Enable fast flush logging for the specified site.
+
+ <b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>APPEND</b> <i>sitename</i> <i>queue_id</i>
+ Append <i>queue_id</i> to the fast flush log for the spec-
+ ified site.
+
+ <b>FLUSH</b><i>_</i><b>REQ</b><i>_</i><b>SEND</b> <i>sitename</i>
+ Arrange for the delivery of all messages that are
+ listed in the fast flush logfile for the specified
+ site. After the logfile is processed, the file is
+ truncated to length zero.
+
+ The response to the client is one of:
+
+ <b>FLUSH</b><i>_</i><b>STAT</b><i>_</i><b>OK</b>
+ The request completed normally.
+
+ <b>FLUSH</b><i>_</i><b>STAT</b><i>_</i><b>BAD</b>
+ The flush server rejected the request (bad request
+ name, bad request parameter value).
+
+ <b>FLUSH</b><i>_</i><b>STAT</b><i>_</i><b>UNKNOWN</b>
+ The specified site has no fast flush log.
+
+ Fast flush logfiles are truncated only after a flush
+ request. In order to prevent fast flush logs from growing
+ too large, and to prevent them from accumulating too much
+ outdated information, the flush service generates a pro-
+ active flush request once every every 1000 append
+ requests. This should not impact operation.
+
+<b>SECURITY</b>
+ The fast flush server is not security-sensitive. It does
+ not talk to the network, and it does not talk to local
+ users. The fast flush server can run chrooted at fixed
+ low privilege.
+
+<b>DIAGNOSTICS</b>
+ Problems and transactions are logged to <b>syslogd</b>(8).
+
+
+
+ 1
+
+
+
+
+
+FLUSH(8) FLUSH(8)
+
+
+<b>BUGS</b>
+ In reality, this server schedules delivery of messages,
+ regardless of their destination. This limitation is due to
+ the fact that one queue runner has to handle mail for mul-
+ tiple destinations.
+
+<b>CONFIGURATION</b> <b>PARAMETERS</b>
+ The following <b>main.cf</b> parameters are especially relevant
+ to this program. See the Postfix <b>main.cf</b> file for syntax
+ details and for default values. Use the <b>postfix</b> <b>reload</b>
+ command after a configuration change.
+
+ <b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
+ Maximal length of strings in a fast flush client
+ request.
+
+<b>SEE</b> <b>ALSO</b>
+ <a href="smtpd.8.html">smtpd(8)</a> Postfix SMTP server
+ <a href="qmgr.8.html">qmgr(8)</a> Postfix queue manager
+ syslogd(8) system logging
+
+<b>LICENSE</b>
+ The Secure Mailer license must be distributed with this
+ software.
+
+<b>AUTHOR(S)</b>
+ Wietse Venema
+ IBM T.J. Watson Research
+ P.O. Box 704
+ Yorktown Heights, NY 10598, USA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+</pre> </body> </html>
<b>-qR</b><i>site</i>
Schedule immediate delivery of all mail that is
- queued for the named <i>site</i>. This functionality is
- available only for sites that have a so-called <b>fast</b>
- <b>flush</b> logfile as described in <a href="flushd.8.html"><b>flushd</b>(8)</a>. For other
- sites, use the slower <b>sendmail</b> <b>-q</b> command instead.
+ queued for the named <i>site</i>. Depending on the desti-
+ nation, this uses "fast flush" service, or it has
+ the same effect as <b>sendmail</b> <b>-q</b>. This functionality
+ is implemented by connecting to the local SMTP
SENDMAIL(1) SENDMAIL(1)
+ server. See <a href="smtpd.8.html">smtpd(8)</a> for more information about the
+ "fast flush" service.
+
<b>-qS</b><i>site</i>
- This command is not implemented. Use the slower
+ This command is not implemented. Use the slower
<b>sendmail</b> <b>-q</b> command instead.
- <b>-t</b> Extract recipients from message headers. This
- requires that no recipients be specified on the
+ <b>-t</b> Extract recipients from message headers. This
+ requires that no recipients be specified on the
command line.
<b>-v</b> Enable verbose logging for debugging purposes. Mul-
- tiple <b>-v</b> options make the software increasingly
+ tiple <b>-v</b> options make the software increasingly
verbose.
<b>SECURITY</b>
- By design, this program is not set-user (or group) id.
- However, it must handle data from untrusted users or
- untrusted machines. Thus, the usual precautions need to
+ By design, this program is not set-user (or group) id.
+ However, it must handle data from untrusted users or
+ untrusted machines. Thus, the usual precautions need to
be taken against malicious inputs.
<b>DIAGNOSTICS</b>
- Problems are logged to <b>syslogd</b>(8) and to the standard
+ Problems are logged to <b>syslogd</b>(8) and to the standard
error stream.
<b>ENVIRONMENT</b>
<b>MAIL</b><i>_</i><b>DEBUG</b>
Enable debugging with an external command, as spec-
- ified with the <b>debugger</b><i>_</i><b>command</b> configuration
+ ified with the <b>debugger</b><i>_</i><b>command</b> configuration
parameter.
<b>FILES</b>
/etc/postfix, configuration files
<b>CONFIGURATION</b> <b>PARAMETERS</b>
- See the Postfix <b>main.cf</b> file for syntax details and for
- default values. Use the <b>postfix</b> <b>reload</b> command after a
+ See the Postfix <b>main.cf</b> file for syntax details and for
+ default values. Use the <b>postfix</b> <b>reload</b> command after a
configuration change.
<b>alias</b><i>_</i><b>database</b>
- Default alias database(s) for <b>newaliases</b>. The
- default value for this parameter is system-spe-
+ Default alias database(s) for <b>newaliases</b>. The
+ default value for this parameter is system-spe-
cific.
<b>bounce</b><i>_</i><b>size</b><i>_</i><b>limit</b>
The amount of original message context that is sent
along with a non-delivery notification.
- <b>database</b><i>_</i><b>type</b>
- Default alias etc. database type. On many UNIX
-
4
SENDMAIL(1) SENDMAIL(1)
- systems the default type is either <b>dbm</b> or <b>hash</b>.
+ <b>database</b><i>_</i><b>type</b>
+ Default alias etc. database type. On many UNIX sys-
+ tems the default type is either <b>dbm</b> or <b>hash</b>.
<b>debugger</b><i>_</i><b>command</b>
Command that is executed after a Postfix daemon has
initialized.
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
- Increment in verbose logging level when a remote
+ Increment in verbose logging level when a remote
host matches a pattern in the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
parameter.
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
- List of domain or network patterns. When a remote
- host matches a pattern, increase the verbose log-
- ging level by the amount specified in the
+ List of domain or network patterns. When a remote
+ host matches a pattern, increase the verbose log-
+ ging level by the amount specified in the
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
<b>fork</b><i>_</i><b>attempts</b>
- Number of attempts to <b>fork</b>() a process before giv-
+ Number of attempts to <b>fork</b>() a process before giv-
ing up.
<b>fork</b><i>_</i><b>delay</b>
- Delay in seconds between successive <b>fork</b>()
+ Delay in seconds between successive <b>fork</b>()
attempts.
<b>hopcount</b><i>_</i><b>limit</b>
Limit the number of <b>Received:</b> message headers.
<b>mail</b><i>_</i><b>owner</b>
- The owner of the mail queue and of most Postfix
+ The owner of the mail queue and of most Postfix
processes.
<b>command</b><i>_</i><b>directory</b>
- Directory with Postfix support commands (default:
+ Directory with Postfix support commands (default:
<b>$program</b><i>_</i><b>directory</b>).
<b>daemon</b><i>_</i><b>directory</b>
- Directory with Postfix daemon programs (default:
+ Directory with Postfix daemon programs (default:
<b>$program</b><i>_</i><b>directory</b>).
<b>queue</b><i>_</i><b>directory</b>
- Top-level directory of the Postfix queue. This is
+ Top-level directory of the Postfix queue. This is
also the root directory of Postfix daemons that run
chrooted.
<b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b>
- The time between successive scans of the deferred
+ The time between successive scans of the deferred
queue.
<b>SEE</b> <b>ALSO</b>
<a href="pickup.8.html">pickup(8)</a> mail pickup daemon
<a href="postalias.1.html">postalias(1)</a> maintain alias database
- <a href="postdrop.1.html">postdrop(1)</a> privileged posting agent
- <a href="postfix.1.html">postfix(1)</a> mail system control
SENDMAIL(1) SENDMAIL(1)
+ <a href="postdrop.1.html">postdrop(1)</a> privileged posting agent
+ <a href="postfix.1.html">postfix(1)</a> mail system control
<a href="postkick.1.html">postkick(1)</a> kick a Postfix daemon
<a href="qmgr.8.html">qmgr(8)</a> queue manager
<a href="showq.8.html">showq(8)</a> list mail queue
syslogd(8) system logging
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
-
-
SMTP session before it is penalized with tarpit
delays.
-<b>ETRN</b> <b>service</b>
- <b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
- Restrict what domain names can be used in <b>ETRN</b> com-
- mands, and what clients may issue <b>ETRN</b> commands.
- The restrictions are like the UCE restrictions
- below. Fast <b>ETRN</b> service is limited to destinations
- that list this MTA as mail exchanger.
-
<b>UCE</b> <b>control</b> <b>restrictions</b>
<b>smtpd</b><i>_</i><b>client</b><i>_</i><b>restrictions</b>
Restrict what clients may connect to this mail sys-
Restrict what client hostnames are allowed in <b>HELO</b>
and <b>EHLO</b> commands.
+ <b>smtpd</b><i>_</i><b>sender</b><i>_</i><b>restrictions</b>
+ Restrict what sender addresses are allowed in <b>MAIL</b>
+ <b>FROM</b> commands.
+
+ <b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>restrictions</b>
+ Restrict what recipient addresses are allowed in
+ <b>RCPT</b> <b>TO</b> commands.
+
4
SMTPD(8) SMTPD(8)
- <b>smtpd</b><i>_</i><b>sender</b><i>_</i><b>restrictions</b>
- Restrict what sender addresses are allowed in <b>MAIL</b>
- <b>FROM</b> commands.
-
- <b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>restrictions</b>
- Restrict what recipient addresses are allowed in
- <b>RCPT</b> <b>TO</b> commands.
+ <b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
+ Restrict what domain names can be used in <b>ETRN</b> com-
+ mands, and what clients may issue <b>ETRN</b> commands.
<b>allow</b><i>_</i><b>untrusted</b><i>_</i><b>routing</b>
- Allow untrusted clients to specify addresses with
- sender-specified routing. Enabling this opens up
- nasty relay loopholes involving trusted backup MX
+ Allow untrusted clients to specify addresses with
+ sender-specified routing. Enabling this opens up
+ nasty relay loopholes involving trusted backup MX
hosts.
<b>restriction</b><i>_</i><b>classes</b>
- Declares the name of zero or more parameters that
- contain a list of UCE restrictions. The names of
- these parameters can then be used instead of the
+ Declares the name of zero or more parameters that
+ contain a list of UCE restrictions. The names of
+ these parameters can then be used instead of the
restriction lists that they represent.
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b>
- List of DNS domains that publish the addresses of
+ List of DNS domains that publish the addresses of
blacklisted hosts.
<b>relay</b><i>_</i><b>domains</b>
- Restrict what domains or networks this mail system
+ Restrict what domains or networks this mail system
will relay mail from or to.
<b>UCE</b> <b>control</b> <b>responses</b>
<b>access</b><i>_</i><b>map</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates an access
+ Server response when a client violates an access
database restriction.
<b>invalid</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
+ Server response when a client violates the
<b>reject</b><i>_</i><b>invalid</b><i>_</i><b>hostname</b> restriction.
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
+ Server response when a client violates the
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b> restriction.
<b>reject</b><i>_</i><b>code</b>
- Response code when the client matches a <b>reject</b>
+ Response code when the client matches a <b>reject</b>
restriction.
<b>relay</b><i>_</i><b>domains</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client attempts to violate
+ Server response when a client attempts to violate
the mail relay policy.
<b>unknown</b><i>_</i><b>address</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
+ Server response when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>address</b> restriction.
+ <b>unknown</b><i>_</i><b>client</b><i>_</i><b>reject</b><i>_</i><b>code</b>
+ Server response when a client without address to
+ name mapping violates the <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>clients</b>
+ restriction.
SMTPD(8) SMTPD(8)
- <b>unknown</b><i>_</i><b>client</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client without address to
- name mapping violates the <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>clients</b>
- restriction.
-
<b>unknown</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
+ Server response when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>hostname</b> restriction.
<b>SEE</b> <b>ALSO</b>
syslogd(8) system logging
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
+
+
+
+
+
DAEMONS = man8/bounce.8 man8/defer.8 man8/cleanup.8 man8/error.8 man8/local.8 \
man8/lmtp.8 man8/master.8 man8/pickup.8 man8/pipe.8 man8/qmgr.8 \
man8/showq.8 man8/smtp.8 man8/smtpd.8 man8/trivial-rewrite.8 \
- man8/nqmgr.8 man8/spawn.8 man8/flushd.8
+ man8/nqmgr.8 man8/spawn.8 man8/flush.8
COMMANDS= man1/postalias.1 man1/postcat.1 man1/postconf.1 man1/postfix.1 \
man1/postkick.1 man1/postlock.1 man1/postlog.1 man1/postdrop.1 \
man1/postmap.1 man1/sendmail.1 man1/mailq.1 man1/newaliases.1 \
man8/error.8: ../src/error/error.c
../mantools/srctoman $? >$@
-man8/flushd.8: ../src/flushd/flushd.c
+man8/flush.8: ../src/flush/flush.c
../mantools/srctoman $? >$@
man8/local.8: ../src/local/local.c
configuration parameter instead.
.IP \fB-qR\fIsite\fR
Schedule immediate delivery of all mail that is queued for the named
-\fIsite\fR.
-This functionality is available only for sites that have a so-called
-\fBfast flush\fR logfile as described in \fBflushd\fR(8). For other
-sites, use the slower \fBsendmail -q\fR command instead.
+\fIsite\fR. Depending on the destination, this uses "fast flush"
+service, or it has the same effect as \fBsendmail -q\fR.
+This functionality is implemented by connecting to the local SMTP
+server. See smtpd(8) for more information about the "fast flush"
+service.
.IP \fB-qS\fIsite\fR
This command is not implemented. Use the slower \fBsendmail -q\fR
command instead.
--- /dev/null
+.TH FLUSH 8
+.ad
+.fi
+.SH NAME
+flush
+\-
+Postfix fast flush daemon
+.SH SYNOPSIS
+.na
+.nf
+\fBflush\fR [generic Postfix daemon options]
+.SH DESCRIPTION
+.ad
+.fi
+The flush server maintains so-called "fast flush" logfiles with
+information about what messages are queued for a specific site.
+This program expects to be run from the \fBmaster\fR(8) process
+manager.
+
+This server implements the following requests:
+.IP "\fBFLUSH_REQ_ENABLE\fI sitename\fR"
+Enable fast flush logging for the specified site.
+.IP "\fBFLUSH_REQ_APPEND\fI sitename queue_id\fR"
+Append \fIqueue_id\fR to the fast flush log for the
+specified site.
+.IP "\fBFLUSH_REQ_SEND\fI sitename\fR"
+Arrange for the delivery of all messages that are listed in the fast
+flush logfile for the specified site. After the logfile is processed,
+the file is truncated to length zero.
+.PP
+The response to the client is one of:
+.IP \fBFLUSH_STAT_OK\fR
+The request completed normally.
+.IP \fBFLUSH_STAT_BAD\fR
+The flush server rejected the request (bad request name, bad
+request parameter value).
+.IP \fBFLUSH_STAT_UNKNOWN\fR
+The specified site has no fast flush log.
+.PP
+Fast flush logfiles are truncated only after a flush request. In
+order to prevent fast flush logs from growing too large, and to
+prevent them from accumulating too much outdated information, the
+flush service generates a pro-active flush request once every
+every 1000 append requests. This should not impact operation.
+.SH SECURITY
+.na
+.nf
+.ad
+.fi
+The fast flush server is not security-sensitive. It does not
+talk to the network, and it does not talk to local users.
+The fast flush server can run chrooted at fixed low privilege.
+.SH DIAGNOSTICS
+.ad
+.fi
+Problems and transactions are logged to \fBsyslogd\fR(8).
+.SH BUGS
+.ad
+.fi
+In reality, this server schedules delivery of messages, regardless
+of their destination. This limitation is due to the fact that
+one queue runner has to handle mail for multiple destinations.
+.SH CONFIGURATION PARAMETERS
+.na
+.nf
+.ad
+.fi
+The following \fBmain.cf\fR parameters are especially relevant to
+this program. See the Postfix \fBmain.cf\fR file for syntax details
+and for default values. Use the \fBpostfix reload\fR command after
+a configuration change.
+.IP \fBline_length_limit\fR
+Maximal length of strings in a fast flush client request.
+.SH SEE ALSO
+.na
+.nf
+smtpd(8) Postfix SMTP server
+qmgr(8) Postfix queue manager
+syslogd(8) system logging
+.SH LICENSE
+.na
+.nf
+.ad
+.fi
+The Secure Mailer license must be distributed with this software.
+.SH AUTHOR(S)
+.na
+.nf
+Wietse Venema
+IBM T.J. Watson Research
+P.O. Box 704
+Yorktown Heights, NY 10598, USA
Limit the number of times a client can issue a junk command
such as NOOP, VRFY, ETRN or RSET in one SMTP session before
it is penalized with tarpit delays.
-.SH "ETRN service"
-.ad
-.fi
-.IP \fBsmtpd_etrn_restrictions\fR
-Restrict what domain names can be used in \fBETRN\fR commands,
-and what clients may issue \fBETRN\fR commands. The restrictions
-are like the UCE restrictions below. Fast \fBETRN\fR service is
-limited to destinations that list this MTA as mail exchanger.
.SH "UCE control restrictions"
.ad
.fi
Restrict what sender addresses are allowed in \fBMAIL FROM\fR commands.
.IP \fBsmtpd_recipient_restrictions\fR
Restrict what recipient addresses are allowed in \fBRCPT TO\fR commands.
+.IP \fBsmtpd_etrn_restrictions\fR
+Restrict what domain names can be used in \fBETRN\fR commands,
+and what clients may issue \fBETRN\fR commands.
.IP \fBallow_untrusted_routing\fR
Allow untrusted clients to specify addresses with sender-specified
routing. Enabling this opens up nasty relay loopholes involving
bounce_notify_service.o: ../../include/vbuf.h
bounce_notify_service.o: ../../include/name_mask.h
bounce_notify_service.o: ../../include/mail_params.h
+bounce_notify_service.o: ../../include/mail_queue.h
+bounce_notify_service.o: ../../include/vstring.h
bounce_notify_service.o: ../../include/post_mail.h
bounce_notify_service.o: ../../include/cleanup_user.h
bounce_notify_service.o: ../../include/mail_addr.h
bounce_notify_service.o: ../../include/mail_error.h
bounce_notify_service.o: bounce_service.h
-bounce_notify_service.o: ../../include/vstring.h
bounce_notify_service.o: ../../include/bounce_log.h
bounce_notify_util.o: bounce_notify_util.c
bounce_notify_util.o: ../../include/sys_defs.h
SHELL = /bin/sh
-SRCS = flushd.c
-OBJS = flushd.o
+SRCS = flush.c
+OBJS = flush.o
HDRS =
TESTSRC =
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
TESTPROG=
-PROG = flushd
+PROG = flush
INC_DIR = ../../include
LIBS = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libutil.a
@$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
-flushd.o: flushd.c
-flushd.o: ../../include/sys_defs.h
-flushd.o: ../../include/msg.h
-flushd.o: ../../include/events.h
-flushd.o: ../../include/vstream.h
-flushd.o: ../../include/vbuf.h
-flushd.o: ../../include/vstring.h
-flushd.o: ../../include/vstring_vstream.h
-flushd.o: ../../include/myflock.h
-flushd.o: ../../include/valid_hostname.h
-flushd.o: ../../include/htable.h
-flushd.o: ../../include/dict.h
-flushd.o: ../../include/argv.h
-flushd.o: ../../include/mail_params.h
-flushd.o: ../../include/mail_queue.h
-flushd.o: ../../include/mail_proto.h
-flushd.o: ../../include/iostuff.h
-flushd.o: ../../include/mail_flush.h
-flushd.o: ../../include/mail_conf.h
-flushd.o: ../../include/maps.h
-flushd.o: ../../include/mail_server.h
+flush.o: flush.c
+flush.o: ../../include/sys_defs.h
+flush.o: ../../include/msg.h
+flush.o: ../../include/events.h
+flush.o: ../../include/vstream.h
+flush.o: ../../include/vbuf.h
+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
+flush.o: ../../include/mail_params.h
+flush.o: ../../include/mail_queue.h
+flush.o: ../../include/mail_proto.h
+flush.o: ../../include/iostuff.h
+flush.o: ../../include/mail_flush.h
+flush.o: ../../include/mail_conf.h
+flush.o: ../../include/maps.h
+flush.o: ../../include/mail_server.h
/*++
/* NAME
-/* flushd 8
+/* flush 8
/* SUMMARY
/* Postfix fast flush daemon
/* SYNOPSIS
-/* \fBflushd\fR [generic Postfix daemon options]
+/* \fBflush\fR [generic Postfix daemon options]
/* DESCRIPTION
/* The flush server maintains so-called "fast flush" logfiles with
/* information about what messages are queued for a specific site.
/* manager.
/*
/* This server implements the following requests:
-/* .IP "\fBFLUSH_REQ_ADD\fI sitename queue_id\fR"
+/* .IP "\fBFLUSH_REQ_ENABLE\fI sitename\fR"
+/* Enable fast flush logging for the specified site.
+/* .IP "\fBFLUSH_REQ_APPEND\fI sitename queue_id\fR"
/* Append \fIqueue_id\fR to the fast flush log for the
/* specified site.
/* .IP "\fBFLUSH_REQ_SEND\fI sitename\fR"
/* SECURITY
/* .ad
/* .fi
-/* The fast flush server is moderately security-sensitive. It does not
-/* talk to the network, but it does talk to local unprivileged users, in
-/* order to emulate "sendmail -qRsite" behavior. For this reason all
-/* strings in a request are truncated at \fIline_length_limit\fR,
-/* before they are subjected to further validation.
-/*
+/* The fast flush server is not security-sensitive. It does not
+/* talk to the network, and it does not talk to local users.
/* The fast flush server can run chrooted at fixed low privilege.
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* Application-specific. */
#define STR(x) vstring_str(x)
-#define FLUSHD_DUP_FILTER_SIZE 10000 /* graceful degradation */
-#define FLUSHD_COMMAND_TIMEOUT 60 /* don't get stuck */
-#define FLUSHD_CHECK_RATE 1000 /* don't accumulate cruft */
+#define FLUSH_DUP_FILTER_SIZE 10000 /* graceful degradation */
+#define FLUSH_COMMAND_TIMEOUT 60 /* don't get stuck */
+#define FLUSH_CHECK_RATE 1000 /* don't accumulate cruft */
/* flush_append - append queue ID to per-site fast flush log */
VSTREAM *log;
struct utimbuf tbuf;
static char qmgr_trigger[] = {
- QMGR_REQ_SCAN_DEFERRED, /* scan deferred queue */
QMGR_REQ_SCAN_INCOMING, /* scan incoming queue */
+ QMGR_REQ_FLUSH_DEAD, /* flush dead site/transport cache */
};
HTABLE *dup_filter;
STR(queue_id), site);
continue;
}
- if (dup_filter->used >= FLUSHD_DUP_FILTER_SIZE
+ if (dup_filter->used >= FLUSH_DUP_FILTER_SIZE
|| htable_find(dup_filter, STR(queue_id)) == 0) {
if (msg_verbose)
msg_info("%s: site %s: update %s time stamps",
myname, site, STR(queue_file));
- if (dup_filter->used <= FLUSHD_DUP_FILTER_SIZE)
+ if (dup_filter->used <= FLUSH_DUP_FILTER_SIZE)
htable_enter(dup_filter, STR(queue_id), 0);
mail_queue_path(queue_file, MAIL_QUEUE_DEFERRED, STR(queue_id));
- if (utime(STR(queue_file), &tbuf) == 0)
- continue;
- if (errno != ENOENT)
- msg_fatal("%s: update %s time stamps: %m",
- myname, STR(queue_file));
-
- mail_queue_path(queue_file, MAIL_QUEUE_INCOMING, STR(queue_id));
- if (utime(STR(queue_file), &tbuf) == 0)
- continue;
- if (errno != ENOENT)
- msg_fatal("%s: update %s time stamps: %m",
- myname, STR(queue_file));
+ if (utime(STR(queue_file), &tbuf) < 0) {
+ if (errno != ENOENT)
+ msg_warn("%s: update %s time stamps: %m",
+ myname, STR(queue_file));
+ } else if (mail_queue_rename(STR(queue_id), MAIL_QUEUE_DEFERRED,
+ MAIL_QUEUE_INCOMING) < 0
+ && errno != ENOENT)
+ msg_warn("%s: rename from %s to %s: %m",
+ STR(queue_file), MAIL_QUEUE_DEFERRED,
+ MAIL_QUEUE_INCOMING);
} else {
if (msg_verbose)
msg_info("%s: site %s: skip file %s as duplicate",
return (FLUSH_STAT_OK);
}
+/* flush_enable - enable fast flush logging for site */
+
+static int flush_enable(const char *site)
+{
+ char *myname = "flush_enable";
+ VSTREAM *log;
+
+ if (msg_verbose)
+ msg_info("%s: site %s", myname, site);
+
+ /*
+ * Open or create the logfile. Multiple requests may arrive in parallel,
+ * so allow for the possibility that the file already exists.
+ */
+ if ((log = mail_queue_open(MAIL_QUEUE_FLUSH, site, O_CREAT | O_RDWR, 0600)) == 0)
+ msg_fatal("%s: open fast flush log for site %s: %m", myname, site);
+
+ if (vstream_fclose(log) != 0)
+ msg_warn("write fast flush log for site %s: %m", site);
+
+ return (FLUSH_STAT_OK);
+}
+
/* flush_service - perform service for client */
static void flush_service(VSTREAM *client_stream, char *unused_service,
if (argv[0])
msg_fatal("unexpected command-line argument: %s", argv[0]);
- /*
- * Vandalism control. Read no unlimited amounts of garbage from a public
- * socket. Of course we also have to make sure the content is sane.
- */
- vstring_ctl(request, VSTRING_CTL_MAXLEN, var_line_limit, VSTRING_CTL_END);
- vstring_ctl(site, VSTRING_CTL_MAXLEN, var_line_limit, VSTRING_CTL_END);
- vstream_control(client_stream, VSTREAM_CTL_TIMEOUT, FLUSHD_COMMAND_TIMEOUT,
- VSTREAM_CTL_END);
/*
* This routine runs whenever a client connects to the UNIX-domain socket
* dedicated to the fast flush service. What we see below is a little
if (mail_scan(client_stream, "%s %s", request, site) == 2
&& valid_hostname(STR(site))) {
- if (STREQ(STR(request), FLUSH_REQ_ADD)) {
+ if (STREQ(STR(request), FLUSH_REQ_APPEND)) {
queue_id = vstring_alloc(10);
- vstring_ctl(queue_id, VSTRING_CTL_MAXLEN, var_line_limit,
- VSTRING_CTL_END);
if (mail_scan(client_stream, "%s", queue_id) == 1
&& mail_queue_id_ok(STR(queue_id)))
status = flush_append(STR(site), STR(queue_id));
vstring_free(queue_id);
} else if (STREQ(STR(request), FLUSH_REQ_SEND)) {
status = flush_site(STR(site));
+ } else if (STREQ(STR(request), FLUSH_REQ_ENABLE)) {
+ status = flush_enable(STR(site));
}
}
mail_print(client_stream, "%d", status);
* contain too much outdated information. Flush our reply to the client
* so that it does not have to wait while the pro-active flush happens.
*/
- if (status == FLUSH_STAT_OK && STREQ(STR(request), FLUSH_REQ_ADD)
- && (++counter + event_time() + getpid()) % FLUSHD_CHECK_RATE == 0) {
+ if (status == FLUSH_STAT_OK && STREQ(STR(request), FLUSH_REQ_APPEND)
+ && (++counter + event_time() + getpid()) % FLUSH_CHECK_RATE == 0) {
vstream_fflush(client_stream);
if (msg_verbose)
msg_info("site %s: time for a pro-active flush", STR(site));
defer.o: ../../include/vstream.h
defer.o: mail_proto.h
defer.o: ../../include/iostuff.h
+defer.o: mail_params.h
+defer.o: mail_flush.h
defer.o: bounce.h
defer.o: defer.h
deliver_completed.o: deliver_completed.c
/* defer_append() appends a record to the per-message defer log,
/* with the reason for delayed delivery to the named recipient.
/* The result is a convenient non-zero value.
+/* When the fast flush cache is enabled, the fast flush server is
+/* notified of deferred mail.
/*
/* vdefer_append() implements an alternative client interface.
/*
#include <sys_defs.h>
#include <stdlib.h> /* 44BSD stdarg.h uses abort() */
#include <stdarg.h>
+#include <string.h>
/* Utility library. */
#include "mail_queue.h"
#include "mail_proto.h"
+#include "mail_params.h"
+#include "mail_flush.h"
#include "bounce.h"
#include "defer.h"
+#define STR(x) vstring_str(x)
+
/* defer_append - defer message delivery */
int defer_append(int flags, const char *id, const char *recipient,
{
VSTRING *why = vstring_alloc(100);
int delay = time((time_t *) 0) - entry;
+ const char *rcpt_domain;
vstring_vsprintf(why, fmt, ap);
if (mail_command_write(MAIL_CLASS_PRIVATE, MAIL_SERVICE_DEFER,
msg_info("%s: to=<%s>, relay=%s, delay=%d, status=deferred (%s)",
id, recipient, relay, delay, vstring_str(why));
vstring_free(why);
+
+ /*
+ * Notify the fast flush service.
+ */
+ if (var_enable_fflush
+ && (rcpt_domain = strrchr(recipient, '@')) != 0
+ && *++rcpt_domain != 0)
+ mail_flush_append(rcpt_domain, id);
+
return (-1);
}
/* opens the queue file, and acquires a shared lock.
/* A null result means that the client sent bad information or that
/* it went away unexpectedly.
+/* If the fast flush service is enabled, deliver_request_read()
+/* initializes the client-side fast flush duplicate filter.
/*
/* The \fBflags\fR structure member is the bit-wise OR of zero or more
/* of the following:
/* closes the queue file,
/* and destroys the DELIVER_REQUEST structure. The result is
/* non-zero when the status could not be reported to the client.
-/*
-/* When the fast flush cache is enabled, the fast flush server is
-/* notified of deferred mail.
/* DIAGNOSTICS
/* Warnings: bad data sent by the client. Fatal errors: out of
/* memory, queue file open errors.
#include "mail_queue.h"
#include "mail_proto.h"
+#include "mail_params.h"
+#include "mail_flush.h"
#include "mail_open_ok.h"
#include "recipient_list.h"
#include "deliver_request.h"
-#include "mail_flush.h"
-#include "mail_params.h"
/* deliver_request_initial - send initial status code */
request = deliver_request_alloc();
if (deliver_request_get(stream, request) < 0) {
deliver_request_free(request);
- request = 0;
+ return (0);
}
+
+ /*
+ * Make sure the mail flush dupfilter sees no false positive if we're
+ * repeatedly delivering the same message.
+ */
+ if (var_enable_fflush)
+ mail_flush_append_init();
+
return (request);
}
{
int err;
- /*
- * Optionally add this message to the fast flush log for this site.
- */
err = deliver_request_final(stream, request->hop_status, status);
- if (var_enable_fflush)
- mail_flush_append(request->nexthop, request->queue_id);
deliver_request_free(request);
return (err);
}
/*
/* int mail_flush_deferred()
/*
+/* int mail_flush_enable(site)
+/* const char *site;
+/*
/* int mail_flush_site(site)
/* const char *site;
/*
/* int mail_flush_append(site, queue_id)
/* const char *site;
/* const char *queue_id;
+/*
+/* void mail_flush_append_init()
/* DESCRIPTION
/* This module deals with delivery of delayed mail.
/*
/* for a given site, and are created on demand when, for example,
/* an eligible SMTP client issues the ETRN command.
/*
+/* mail_flush_enable() enables the "fast flush" service for
+/* the named site.
+/*
/* mail_flush_site() uses the "fast flush" service to trigger
/* delivery of messages queued for the specified site.
/*
/* mail_flush_append() appends a record to the "fast flush"
-/* logfile of the specified site, with the queue ID of mail
-/* that should still be delivered.
+/* logfile for the specified site, with the queue ID of mail
+/* that still should be delivered. This routine uses a little
+/* duplicate filter to avoid appending multiple identical
+/* records when one has to defer multi-recipient mail.
+/*
+/* mail_flush_append_init() initializes a duplicate filter that is used
+/* by mail_flush_append(). mail_flush_append_init() must be called once
+/* before calling mail_flush_append() and must be called whenever
+/* the application opens a new queue file, to prevent false
+/* positives with the duplicate filter when repeated attempts
+/* are made to deliver the same message.
/* DIAGNOSTICS
/* The result codes and their meaning are (see mail_flush(5h)):
/* .IP MAIL_FLUSH_OK
#include <msg.h>
#include <vstream.h>
+#include <vstring.h>
/* Global library. */
#include <mail_flush.h>
#include <mail_params.h>
+/* Application-specific. */
+
+#define STR(x) vstring_str(x)
+
+static VSTRING *mail_flush_saved_site;
+static VSTRING *mail_flush_saved_id;
+static int mail_flush_saved_status;
+
/* mail_flush_deferred - flush deferred queue */
int mail_flush_deferred(void)
qmgr_trigger, sizeof(qmgr_trigger)));
}
+/* mail_flush_append_init - initialize repeat filter */
+
+void mail_flush_append_init(void)
+{
+ if (mail_flush_saved_site == 0) {
+ mail_flush_saved_site = vstring_alloc(10);
+ mail_flush_saved_id = vstring_alloc(10);
+ }
+ vstring_strcpy(mail_flush_saved_site, "");
+ vstring_strcpy(mail_flush_saved_id, "");
+}
+
+/* mail_flush_cached - see if request repeats */
+
+static int mail_flush_cached(const char *site, const char *queue_id)
+{
+ if (strcmp(STR(mail_flush_saved_site), site) == 0
+ && strcmp(STR(mail_flush_saved_id), queue_id) == 0) {
+ return (1);
+ } else {
+ vstring_strcpy(mail_flush_saved_site, site);
+ vstring_strcpy(mail_flush_saved_id, queue_id);
+ return (0);
+ }
+}
+
/* mail_flush_clnt - generic fast flush service client */
static int mail_flush_clnt(const char *format,...)
/*
* Connect to the fast flush service over local IPC.
*/
- if ((flush = mail_connect(MAIL_CLASS_PUBLIC, MAIL_SERVICE_FLUSH,
+ if ((flush = mail_connect(MAIL_CLASS_PRIVATE, MAIL_SERVICE_FLUSH,
BLOCKING)) == 0)
return (FLUSH_STAT_FAIL);
return (status);
}
+/* mail_flush_enable - enable fast flush logging for site */
+
+int mail_flush_enable(const char *site)
+{
+ char *myname = "mail_flush_enable";
+ int status;
+
+ if (msg_verbose)
+ msg_info("%s: site %s", myname, site);
+ status = mail_flush_clnt("%s %s", FLUSH_REQ_ENABLE, site);
+ if (msg_verbose)
+ msg_info("%s: site %s status %d", myname, site, status);
+
+ return (status);
+}
+
/* mail_flush_site - flush deferred mail for site */
int mail_flush_site(const char *site)
int mail_flush_append(const char *site, const char *queue_id)
{
char *myname = "mail_flush_append";
- int status;
if (msg_verbose)
msg_info("%s: site %s id %s", myname, site, queue_id);
- status = mail_flush_clnt("%s %s %s", FLUSH_REQ_ADD, site, queue_id);
+ if (mail_flush_cached(site, queue_id) == 0)
+ mail_flush_saved_status =
+ mail_flush_clnt("%s %s %s", FLUSH_REQ_APPEND, site, queue_id);
if (msg_verbose)
- msg_info("%s: site %s id %s status %d", myname, site, queue_id, status);
+ msg_info("%s: site %s id %s status %d", myname, site, queue_id,
+ mail_flush_saved_status);
- return (status);
+ return (mail_flush_saved_status);
}
* External interface.
*/
extern int mail_flush_deferred(void);
+extern int mail_flush_enable(const char *);
extern int mail_flush_site(const char *);
extern int mail_flush_append(const char *, const char *);
+extern void mail_flush_append_init(void);
/*
* Mail flush server requests.
*/
-#define FLUSH_REQ_ADD "add" /* add queue ID to site log */
+#define FLUSH_REQ_APPEND "append"/* append queue ID to site log */
#define FLUSH_REQ_SEND "send" /* flush mail queued for site */
+#define FLUSH_REQ_ENABLE "enable"/* flush mail queued for site */
/*
* Mail flush server status codes.
int var_ownreq_special;
int var_daemon_timeout;
char *var_syslog_facility;
-int var_enable_fflush;
+int var_enable_fflush;
/* check_myhostname - lookup hostname and validate */
extern char *var_filter_xport;
/*
-Fast flush service support. */
+ * Fast flush service support.
+ */
#define VAR_ENABLE_FFLUSH "enable_fast_flush"
#define DEF_ENABLE_FFLUSH 0
extern bool var_enable_fflush;
* Try the operation. If it fails, see if it is because of missing
* intermediate directories.
*/
- error = rename(mail_queue_path(old_buf, old_queue, queue_id),
- mail_queue_path(new_buf, new_queue, queue_id));
+ error = sane_rename(mail_queue_path(old_buf, old_queue, queue_id),
+ mail_queue_path(new_buf, new_queue, queue_id));
if (error != 0 && mail_queue_mkdirs(STR(new_buf)) == 0)
- error = rename(STR(old_buf), STR(new_buf));
+ error = sane_rename(STR(old_buf), STR(new_buf));
/*
* Cleanup.
{
const char *cp;
+ if (strlen(queue_name) > 100)
+ return (0);
+
for (cp = queue_name; *cp; cp++)
if (!ISALNUM(*cp))
return (0);
- if (strlen(queue_name) > 100)
- return (0);
return (1);
}
return (0);
/*
- * Must be in valid hostname form.
+ * OK if in in time+inum form.
*/
- if ((strchr(queue_id, '.') || strchr(queue_id, '-'))
- && valid_hostname(queue_id))
- return (1);
+ for (cp = queue_id; /* void */ ; cp++) {
+ if (*cp == 0)
+ return (1);
+ if (!ISALNUM(*cp))
+ break;
+ }
/*
- * Must be in time+inum form.
+ * BAD if in time.pid form.
*/
- for (cp = queue_id; *cp; cp++)
- if (!ISALNUM(*cp))
+ for (cp = queue_id; /* void */ ; cp++) {
+ if (*cp == 0)
return (0);
- return (1);
+ if (!ISDIGIT(*cp) && *cp != '.')
+ break;
+ }
+
+ /*
+ * OK if in valid hostname form.
+ */
+ return (valid_hostname(queue_id));
}
/* mail_queue_enter - make mail queue entry with locally-unique name */
/* White space in the format string is ignored.
/* .IP %s
/* The corresponding argument has type (VSTRING *).
-/* If the string has a size limit, no more characters will be read
-/* into the string than is specified via that size limit.
/* .IP %d
/* The corresponding argument has type (int *).
/* .IP %ld
/* Global library. */
#include "mail_proto.h"
-#include "mail_params.h"
/*
* Provision for the user to register type-specific input conversion
static int mail_scan_any(VSTREAM *stream, VSTRING *vp, char *what)
{
- if ((vp->maxlen ? vstring_fgets_null_bound(vp, stream, vp->maxlen)
- : vstring_fgets_null(vp, stream)) == 0) {
+ if (vstring_fgets_null(vp, stream) == 0) {
msg_warn("mail_scan_any: got EOF; expected: %s", what);
return (-1);
}
static VSTRING *tmp;
MAIL_SCAN *tp;
- if (tmp == 0) {
+ if (tmp == 0)
tmp = vstring_alloc(100);
- tmp->maxlen = var_line_limit; /* good enough for numbers */
- }
+
for (count = 0, error = 0, cp = fmt; error == 0 && *cp != 0; cp++) {
if (ISSPACE(*cp))
continue;
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-20000929"
+#define DEF_MAIL_VERSION "Snapshot-20000930"
extern char *var_mail_version;
/* LICENSE
qmgr_active.o: ../../include/bounce.h
qmgr_active.o: ../../include/defer.h
qmgr_active.o: ../../include/rec_type.h
+qmgr_active.o: ../../include/mail_flush.h
qmgr_active.o: qmgr.h
qmgr_active.o: ../../include/scan_dir.h
qmgr_active.o: ../../include/maps.h
#include <bounce.h>
#include <defer.h>
#include <rec_type.h>
+#include <mail_flush.h>
/* Application-specific. */
*/
if (message->refcount == 0)
qmgr_active_done(message);
+
+ /*
+ * Make sure the mail flush dupfilter sees no false positive if we're
+ * repeatedly trying to deliver the same message.
+ */
+ else if (var_enable_fflush)
+ mail_flush_append_init();
}
}
/* Global library. */
#include <defer.h>
-#include <mail_params.h>
-#include <mail_flush.h>
/* Application-specific. */
recipient = entry->rcpt_list.info + nrcpt;
qmgr_defer_recipient(message, recipient->address, reason);
}
- if (var_enable_fflush)
- mail_flush_append(queue->name, message->queue_id);
qmgr_entry_done(entry, QMGR_QUEUE_TODO);
}
}
qmgr_active.o: ../../include/bounce.h
qmgr_active.o: ../../include/defer.h
qmgr_active.o: ../../include/rec_type.h
+qmgr_active.o: ../../include/mail_flush.h
qmgr_active.o: qmgr.h
qmgr_active.o: ../../include/scan_dir.h
qmgr_active.o: ../../include/maps.h
#include <bounce.h>
#include <defer.h>
#include <rec_type.h>
+#include <mail_flush.h>
/* Application-specific. */
*/
if (message->refcount == 0)
qmgr_active_done(message);
+
+ /*
+ * Make sure the mail flush dupfilter sees no false positive if we're
+ * repeatedly trying to deliver the same message.
+ */
+ else if (var_enable_fflush)
+ mail_flush_append_init();
}
}
/* Global library. */
#include <defer.h>
-#include <mail_params.h>
-#include <mail_flush.h>
/* Application-specific. */
recipient = entry->rcpt_list.info + nrcpt;
qmgr_defer_recipient(message, recipient->address, reason);
}
- if (var_enable_fflush)
- mail_flush_append(queue->name, message->queue_id);
qmgr_entry_done(entry, QMGR_QUEUE_TODO);
}
}
} else if (dict_errno != 0) {
qmgr_defer_recipient(message, recipient->address,
"relocated map lookup failure");
-XXX mail_flush_append
continue;
}
}
if (*cpp) {
qmgr_defer_recipient(message, recipient->address,
"deferred transport");
-XXX mail_flush_append
continue;
}
}
*/
if ((transport->flags & QMGR_TRANSPORT_STAT_DEAD) != 0) {
qmgr_defer_recipient(message, recipient->address, transport->reason);
-XXX mail_flush_append
continue;
}
*/
if (queue->window == 0) {
qmgr_defer_recipient(message, recipient->address, queue->reason);
-XXX mail_flush_append
continue;
}
qmgr_message_count : var_qmgr_active_limit)) {
qmgr_defer_recipient(message, recipient->address,
"site destination queue overflow");
-XXX mail_flush_append
continue;
}
}
sendmail.o: ../../include/resolve_clnt.h
sendmail.o: ../../include/mail_flush.h
sendmail.o: ../../include/mail_stream.h
-sendmail.o: ../../include/sys_exits.h
/* configuration parameter instead.
/* .IP \fB-qR\fIsite\fR
/* Schedule immediate delivery of all mail that is queued for the named
-/* \fIsite\fR.
-/* This functionality is available only for sites that have a so-called
-/* \fBfast flush\fR logfile as described in \fBflushd\fR(8). For other
-/* sites, use the slower \fBsendmail -q\fR command instead.
+/* \fIsite\fR. Depending on the destination, this uses "fast flush"
+/* service, or it has the same effect as \fBsendmail -q\fR.
+/* This functionality is implemented by connecting to the local SMTP
+/* server. See smtpd(8) for more information about the "fast flush"
+/* service.
/* .IP \fB-qS\fIsite\fR
/* This command is not implemented. Use the slower \fBsendmail -q\fR
/* command instead.
#include <time.h>
#include <errno.h>
#include <ctype.h>
+#include <stdarg.h>
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
#include <vstream.h>
-#include <vstring.h>
#include <msg_vstream.h>
#include <msg_syslog.h>
#include <vstring_vstream.h>
#include <iostuff.h>
#include <stringops.h>
#include <set_ugid.h>
+#include <connect.h>
/* Global library. */
#include <tok822.h>
#include <mail_flush.h>
#include <mail_stream.h>
+#include <smtp_stream.h>
/* Application-specific. */
msg_warn("Cannot flush mail queue - mail system is down");
}
+/* chat - send command and examine reply */
+
+static void chat(VSTREAM *fp, VSTRING *buf, const char *fmt,...)
+{
+ va_list ap;
+
+ smtp_get(buf, fp, var_line_limit);
+ if (STR(buf)[0] != '2')
+ msg_fatal("server rejected request: %s", STR(buf));
+
+ if (msg_verbose)
+ msg_info("<<< %s", STR(buf));
+
+ if (msg_verbose) {
+ va_start(ap, fmt);
+ vstring_vsprintf(buf, fmt, ap);
+ va_end(ap);
+ msg_info(">>> %s", STR(buf));
+ }
+ va_start(ap, fmt);
+ smtp_vprintf(fp, fmt, ap);
+ va_end(ap);
+}
+
/* flush_site - flush mail for site */
static void flush_site(const char *site)
{
- int code;
+ VSTRING *buf = vstring_alloc(10);
+ VSTREAM *fp;
+ int sock;
+ int status;
- switch (code = mail_flush_site(site)) {
- default:
- msg_panic("flush_site: unknown result code %d", code);
- case FLUSH_STAT_OK:
- break;
- case FLUSH_STAT_UNKNOWN:
- msg_fatal("No \"sendmail -qR\" support available for %s - use \"sendmail -q\" instead", site);
- break;
- case FLUSH_STAT_BAD:
- msg_fatal("invalid request: %s", site);
- case FLUSH_STAT_FAIL:
- msg_warn("Cannot flush mail queue - mail system is down");
- break;
+ /*
+ * Make connection to the local SMTP server. Translate "connection
+ * refused" into something less misleading.
+ */
+ vstring_sprintf(buf, "%s:smtp", var_myhostname);
+ if ((sock = inet_connect(STR(buf), BLOCKING, 10)) < 0) {
+ if (errno == ECONNREFUSED)
+ msg_fatal("mail service at %s is down", var_myhostname);
+ msg_fatal("connect to mail service at %s: %m", var_myhostname);
}
+ fp = vstream_fdopen(sock, O_RDWR);
+
+ /*
+ * Prepare for trouble.
+ */
+ vstream_control(fp, VSTREAM_CTL_EXCEPT, VSTREAM_CTL_END);
+ status = vstream_setjmp(fp);
+ if (status != 0) {
+ switch (status) {
+ case SMTP_ERR_EOF:
+ msg_fatal("server at %s aborted connection", var_myhostname);
+ case SMTP_ERR_TIME:
+ msg_fatal("timeout while talking to server at %s", var_myhostname);
+ }
+ }
+ smtp_timeout_setup(fp, 60);
+
+ /*
+ * Chat with the SMTP server.
+ */
+ chat(fp, buf, "helo %s", var_myhostname);
+ chat(fp, buf, "etrn %s", site);
+ chat(fp, buf, "quit");
+
+ vstream_fclose(fp);
+ vstring_free(buf);
}
/* sendmail_cleanup - callback for the runtime error handler */
/* The "fast flush" cache keeps a record of what mail is queued up for
/* specific destinations.
/* Currently, "fast flush" support is available only for destinations
-/* that the local MTA is willing to relay mail to (i.e. the policy
+/* that the local MTA is willing to relay mail to (i.e. the policy
/* is hard coded).
/* .IP \fBerror_notice_recipient\fR
/* Recipient of protocol/policy/resource/software error notices.
/* Limit the number of times a client can issue a junk command
/* such as NOOP, VRFY, ETRN or RSET in one SMTP session before
/* it is penalized with tarpit delays.
-/* .SH "ETRN service"
-/* .ad
-/* .fi
-/* .IP \fBsmtpd_etrn_restrictions\fR
-/* Restrict what domain names can be used in \fBETRN\fR commands,
-/* and what clients may issue \fBETRN\fR commands. The restrictions
-/* are like the UCE restrictions below. Fast \fBETRN\fR service is
-/* limited to destinations that list this MTA as mail exchanger.
/* .SH "UCE control restrictions"
/* .ad
/* .fi
/* Restrict what sender addresses are allowed in \fBMAIL FROM\fR commands.
/* .IP \fBsmtpd_recipient_restrictions\fR
/* Restrict what recipient addresses are allowed in \fBRCPT TO\fR commands.
+/* .IP \fBsmtpd_etrn_restrictions\fR
+/* Restrict what domain names can be used in \fBETRN\fR commands,
+/* and what clients may issue \fBETRN\fR commands.
/* .IP \fBallow_untrusted_routing\fR
/* Allow untrusted clients to specify addresses with sender-specified
/* routing. Enabling this opens up nasty relay loopholes involving
switch (mail_flush_site(argv[1].strval)) {
case FLUSH_STAT_UNKNOWN:
if (smtpd_check_etrn_cache_policy_ok(state, argv[1].strval)) {
- if ((fp = mail_queue_open(MAIL_QUEUE_FLUSH, argv[1].strval,
- O_CREAT | O_APPEND | O_WRONLY, 0600)) == 0) {
- msg_warn("create fast ETRN cache for %s: %m", argv[1].strval);
+ if (mail_flush_enable(argv[1].strval) != FLUSH_STAT_OK) {
+ msg_warn("can't create fast ETRN cache for %s", argv[1].strval);
} else {
- vstream_fclose(fp);
msg_info("created fast ETRN cache for %s (client=%s)",
argv[1].strval, state->namaddr);
+ vstream_fclose(fp);
}
} else {
msg_info("refused fast ETRN service for %s (client=%s)",