From bcb028b46d57f72740418a72fe17496cc51b8890 Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Sat, 9 Oct 2004 00:00:00 -0500 Subject: [PATCH] postfix-2.2-20041009 --- postfix/.indent.pro | 1 + postfix/HISTORY | 37 ++++- postfix/RELEASE_NOTES | 23 +++ postfix/RELEASE_NOTES-2.1 | 19 ++- postfix/auxiliary/qshape/qshape.pl | 7 +- postfix/conf/access | 2 +- postfix/conf/header_checks | 2 +- postfix/conf/master.cf | 89 ++--------- postfix/conf/postfix-files | 2 + postfix/html/Makefile.in | 14 +- postfix/html/access.5.html | 2 +- postfix/html/anvil.8.html | 111 +++++++++---- postfix/html/header_checks.5.html | 2 +- postfix/html/index.html | 2 + postfix/html/ldap_table.5.html | 11 +- postfix/html/master.5.html | 228 +++++++++++++++++++++++++++ postfix/html/master.8.html | 16 +- postfix/html/pipe.8.html | 101 +++++++----- postfix/html/postconf.5.html | 118 +++++++++++--- postfix/html/postfix-manuals.html | 208 ++++++++++++++++++++++++ postfix/html/postfix.1.html | 3 +- postfix/html/postsuper.1.html | 2 +- postfix/html/qshape.1.html | 8 +- postfix/html/smtpd.8.html | 30 +++- postfix/man/Makefile.in | 5 +- postfix/man/man1/postfix.1 | 3 +- postfix/man/man1/postsuper.1 | 2 +- postfix/man/man1/qshape.1 | 4 +- postfix/man/man1/sendmail.1 | 5 +- postfix/man/man5/access.5 | 2 +- postfix/man/man5/header_checks.5 | 2 +- postfix/man/man5/ldap_table.5 | 14 +- postfix/man/man5/master.5 | 214 +++++++++++++++++++++++++ postfix/man/man5/postconf.5 | 90 +++++++++-- postfix/man/man8/anvil.8 | 72 ++++++++- postfix/man/man8/master.8 | 15 +- postfix/man/man8/pipe.8 | 27 +++- postfix/man/man8/smtpd.8 | 23 ++- postfix/mantools/makemanidx | 97 ++++++++++++ postfix/mantools/makereadme | 1 + postfix/mantools/postlink | 9 +- postfix/proto/access | 2 +- postfix/proto/header_checks | 2 +- postfix/proto/ldap_table | 14 +- postfix/proto/master | 201 +++++++++++++++++++++++ postfix/proto/postconf.man.epilog | 3 +- postfix/proto/postconf.proto | 98 ++++++++++-- postfix/src/anvil/anvil.c | 224 +++++++++++++++++++++++++- postfix/src/global/anvil_clnt.c | 134 ++++++++++++++-- postfix/src/global/anvil_clnt.h | 8 +- postfix/src/global/deliver_pass.c | 3 + postfix/src/global/deliver_request.c | 26 ++- postfix/src/global/deliver_request.h | 3 + postfix/src/global/mail_params.h | 12 +- postfix/src/global/mail_version.h | 2 +- postfix/src/master/master.c | 15 +- postfix/src/oqmgr/qmgr.h | 3 + postfix/src/oqmgr/qmgr_deliver.c | 3 + postfix/src/oqmgr/qmgr_message.c | 36 +++++ postfix/src/pipe/pipe.c | 39 ++++- postfix/src/postfix/postfix.c | 3 +- postfix/src/postsuper/postsuper.c | 2 +- postfix/src/qmgr/qmgr.h | 3 + postfix/src/qmgr/qmgr_deliver.c | 3 + postfix/src/qmgr/qmgr_message.c | 36 +++++ postfix/src/sendmail/sendmail.c | 10 +- postfix/src/smtpd/smtpd.c | 110 +++++++++++-- postfix/src/smtpd/smtpd.h | 3 +- postfix/src/smtpd/smtpd_state.c | 9 +- postfix/src/util/sys_defs.h | 1 + 70 files changed, 2280 insertions(+), 351 deletions(-) create mode 100644 postfix/html/master.5.html create mode 100644 postfix/html/postfix-manuals.html create mode 100644 postfix/man/man5/master.5 create mode 100755 postfix/mantools/makemanidx create mode 100644 postfix/proto/master diff --git a/postfix/.indent.pro b/postfix/.indent.pro index 442d5ed0b..d58f4db3f 100644 --- a/postfix/.indent.pro +++ b/postfix/.indent.pro @@ -1,5 +1,6 @@ -TABOUNCE -TALIAS_TOKEN +-TANVIL_CLNT -TANVIL_LOCAL -TANVIL_REMOTE -TARGV diff --git a/postfix/HISTORY b/postfix/HISTORY index 06277c628..749e21a13 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -9735,9 +9735,42 @@ Apologies for any names omitted. Feature: discard(8) mail delivery agent. Victor Duchovni, Morgan Stanley. File: discard/discard.c. -Open problems: +20041002 + + Long overdue, a master(5) manual page based on an initial + version by Magnus Baeck. + + By popular demand, a postfix-manuals.html web page with + totally useless links to UNIX-style manual pages (the same + information should already be available simply by typing + "apropos postfix"). To keep newbies from getting completely + lost due to information overload, the document starts with + a list of actually useful pointers to Postfix introductions, + duplicated from the already existing documents.html. + +20041006 + + Bugfix: "sendmail -bv" did not reject the -t option. File: + sendmail/sendmail.c. - Low: master(5) manual page. +20041007 + + Feature: SASL authentication attributes are now stored in + queue files and passed on to delivery agents, by Leandro + Santi. Files: deliver_pass.c, deliver_request.c, + qmgr_deliver.c, qmgr_message.c, pipe.c, smtpd.c. + +20041010 + + Feature: per SMTP client message rate limit and recipient + rate limit, by Ragnar Lonn, GHN network technologies. + Files: smtpd/smtpd.c, anvil/anvil.c, global/anvil_clnt.[hc]. + + Incompatibility: smtpd_client_connection_limit_exceptions + renamed to smtpd_client_event_limit_exceptions, because it + now also controls message and recipient rate limit control. + +Open problems: Low: should the Delivered-To: test in local(8) be configurable? diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 549f4862a..9b3e75a7e 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -7,6 +7,29 @@ snapshot release). Patches are issued for the official release and change the patchlevel and the release date. Patches are never issued for snapshot releases. +Incompatible changes with snapshot Postfix-2.2-20041009 +======================================================= + +You must reload or stop/start Postfix, because the queue manager +to delivery agent protocol has changed. If you forget this, mail +will remain queued until the queue manager is restarted. + +The smtpd_client_connection_limit_exceptions parameter is renamed +to smtpd_client_event_limit_exceptions. Besides connections it now +also applies to per-client message rate and recipient rate limits. + +Major changes with snapshot Postfix-2.2-20041009 +================================================ + +Per SMTP client message rate and recipient rate limits. These limit +the number of MAIL FROM or RCPT TO requests regardless of whether +or not Postfix would have accepted them otherwise. The user interface +(smtpd_client_message_rate_limit and smtpd_client_recipient_rate_limit) +is similar to that of the existing per SMTP client connection rate +limit, and the same warnings apply: these features are to be used +to stop abuse, and must not be used to regulate legitimate mail. +More details can be found in the postconf(5) manual. + Incompatible changes with snapshot Postfix-2.2-20040919 ======================================================= diff --git a/postfix/RELEASE_NOTES-2.1 b/postfix/RELEASE_NOTES-2.1 index 87e3d5b1d..7226f4bee 100644 --- a/postfix/RELEASE_NOTES-2.1 +++ b/postfix/RELEASE_NOTES-2.1 @@ -15,14 +15,12 @@ snapshot releases. Major changes - critical ------------------------ -If you run Postfix 1.x or earlier then you must stop Postfix before -upgrading. This is because the master-child protocols have changed, -and very little will work with the old master daemon process. - -[Incompat 20021119] You can upgrade Postfix 2.0 without stopping. -After upgrading an existing Postfix 2.0 system you must use "postfix -reload". Some internal protocols have changed, but the master-child -protocols are the same as with Postfix 2.0. +If you run Postfix 2.0 or earlier then you must stop Postfix before +upgrading. The master-child protocols have changed between Postfix +1.1 and 2.0, and version 2.1 sometimes writes queue files that the +2.0 and earlier queue managers complain about. If this happens move +the files from the corrupt directory to the maildrop directory and +give them another chance. [Incompat 20021119] The Postfix upgrade procedure will add two new services to your master.cf file: "trace" and "verify". These servers @@ -69,6 +67,11 @@ The form user@[ipaddress] is still allowed. [Incompat 20031226] Bounce messages now have a separate queue life time. This is controlled by the bounce_queue_lifetime parameter. +[Incompat 20031019] The authorized_verp_clients parameter was +renamed to smtpd_authorized_verp_clients, and the default value +was changed to disable this feature. You now have to turn it on +explicitly. + Major changes - build environment --------------------------------- diff --git a/postfix/auxiliary/qshape/qshape.pl b/postfix/auxiliary/qshape/qshape.pl index 13430dd4b..94b86d5e3 100644 --- a/postfix/auxiliary/qshape/qshape.pl +++ b/postfix/auxiliary/qshape/qshape.pl @@ -28,7 +28,7 @@ # domain distribution. By default the recipient distribution is # displayed. There can be more recipients than messages, but as # each message has only one sender, the sender distribution is a -# a message distribution. +# message distribution. # .IP \fB-p\fR # Generate aggregate statistics for parent domains. Top level domains # are not shown, nor are domains with fewer than \fImin_subdomains\fR @@ -56,7 +56,7 @@ # The output is right justified, with the counts for the last # bucket shown on the 80th column, the \fIterminal_width\fR can be # adjusted for wider screens allowing more buckets to be displayed -# with truncating the domain names on the left. When a row for a +# without truncating the domain names on the left. When a row for a # full domain name and its counters does not fit in the specified # number of columns, only the last 17 bytes of the domain name # are shown with the prefix replaced by a '+' character. Truncated @@ -263,8 +263,9 @@ sub wanted { ++$q{"TOTAL"}->[0]; ++$q{"TOTAL"}->[$b]; $a = "MAILER-DAEMON" if ($a eq ""); - $a =~ s/.*\@\.*(.*[^.])?\.*$/$1/; + $a =~ s/.*\@//; $a =~ s/\.\././g; + $a =~ s/\.?(.+?)\.?$/$1/; my $new = 0; do { my $old = (++$q{$a}->[0] > 1); diff --git a/postfix/conf/access b/postfix/conf/access index d5ef32a54..f8569dc7c 100644 --- a/postfix/conf/access +++ b/postfix/conf/access @@ -206,7 +206,7 @@ # # Note: use "postsuper -r" to release mail that was # kept on hold for a significant fraction of $maxi- -# mal_queue_lifetime or $bounce_queue_lifetime or +# mal_queue_lifetime or $bounce_queue_lifetime, or # longer. # # Note: this action currently affects all recipients diff --git a/postfix/conf/header_checks b/postfix/conf/header_checks index 71303d8a0..86ea9f5ac 100644 --- a/postfix/conf/header_checks +++ b/postfix/conf/header_checks @@ -181,7 +181,7 @@ # # Note: use "postsuper -r" to release mail that was # kept on hold for a significant fraction of $maxi- -# mal_queue_lifetime or $bounce_queue_lifetime or +# mal_queue_lifetime or $bounce_queue_lifetime, or # longer. # # Note: this action affects all recipients of the diff --git a/postfix/conf/master.cf b/postfix/conf/master.cf index ad74434a4..9ef138535 100644 --- a/postfix/conf/master.cf +++ b/postfix/conf/master.cf @@ -1,77 +1,6 @@ # -# Postfix master process configuration file. Each logical line -# describes how a Postfix daemon program should be run. -# -# A logical line starts with non-whitespace, non-comment text. -# Empty lines and whitespace-only lines are ignored, as are comment -# lines whose first non-whitespace character is a `#'. -# A line that starts with whitespace continues a logical line. -# -# The fields that make up each line are described below. A "-" field -# value requests that a default value be used for that field. -# -# Service: any name that is valid for the specified transport type -# (the next field). With INET transports, a service is specified as -# host:port. The host part (and colon) may be omitted. Either host -# or port may be given in symbolic form or in numeric form. Examples -# for the SMTP server: localhost:smtp receives mail via the loopback -# interface only; 10025 receives mail on port 10025. -# -# Transport type: "inet" for Internet sockets, "unix" for UNIX-domain -# sockets, "fifo" for named pipes. -# -# Private: whether or not access is restricted to the mail system. -# Default is private service. Internet (inet) sockets can't be private. -# -# Unprivileged: whether the service runs with root privileges or as -# the owner of the Postfix system (the owner name is controlled by the -# mail_owner configuration variable in the main.cf file). Only the -# pipe, virtual and local delivery daemons require privileges. -# -# Chroot: whether or not the service runs chrooted to the mail queue -# directory (pathname is controlled by the queue_directory configuration -# variable in the main.cf file). Presently, all Postfix daemons can run -# chrooted, except for the pipe, virtual and local delivery daemons. -# The proxymap server can run chrooted, but doing so defeats most of -# the purpose of having that service in the first place. -# The files in the examples/chroot-setup subdirectory describe how -# to set up a Postfix chroot environment for your type of machine. -# -# Wakeup time: automatically wake up the named service after the -# specified number of seconds. A ? at the end of the wakeup time -# field requests that wake up events be sent only to services that -# are actually being used. Specify 0 for no wakeup. Presently, only -# the pickup, queue manager and flush daemons need a wakeup timer. -# -# Max procs: the maximum number of processes that may execute this -# service simultaneously. Default is to use a globally configurable -# limit (the default_process_limit configuration parameter in main.cf). -# Specify 0 for no process count limit. -# -# Command + args: the command to be executed. The command name is -# relative to the Postfix program directory (pathname is controlled by -# the daemon_directory configuration variable). Adding one or more -# -v options turns on verbose logging for that service; adding a -D -# option enables symbolic debugging (see the debugger_command variable -# in the main.cf configuration file). See individual command man pages -# for specific command-line options, if any. -# -# General main.cf options can be overridden for specific services. -# To override one or more main.cf options, specify them as arguments -# below, preceding each option by "-o". There must be no whitespace -# in the option itself (separate multiple values for an option by -# commas). -# -# In order to use the "uucp" message tranport below, set up entries -# in the transport table. -# -# In order to use the "cyrus" message transport below, configure it -# in main.cf as the mailbox_transport. -# -# SPECIFY ONLY PROGRAMS THAT ARE WRITTEN TO RUN AS POSTFIX DAEMONS. -# ALL DAEMONS SPECIFIED HERE MUST SPEAK A POSTFIX-INTERNAL PROTOCOL. -# -# DO NOT SHARE THE POSTFIX QUEUE BETWEEN MULTIPLE POSTFIX INSTANCES. +# Postfix master process configuration file. For details on the format +# of the file, see master(5). # # ========================================================================== # service type private unpriv chroot wakeup maxproc command + args @@ -104,13 +33,17 @@ lmtp unix - - n - - lmtp anvil unix - - n - 1 anvil scache unix - - n - 1 scache # +# ==================================================================== # Interfaces to non-Postfix software. Be sure to examine the manual # pages of the non-Postfix software to find out what options it wants. # -# See the pipe(8) man page for information about ${recipient} and -# other message envelope options. +# Many of the following services use the Postfix pipe(8) delivery +# agent. See the pipe(8) man page for information about ${recipient} +# and other message envelope options. +# ==================================================================== # # maildrop. See the Postfix MAILDROP_README file for details. +# Also specify in main.cf: maildrop_destination_recipient_limit=1 # maildrop unix - n n - - pipe flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient} @@ -123,8 +56,14 @@ old-cyrus unix - n n - - pipe # Also specify in main.cf: cyrus_destination_recipient_limit=1 cyrus unix - n n - - pipe user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} +# +# See the Postfix UUCP_README file for configuration details. +# uucp unix - n n - - pipe flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) +# +# Other external delivery methods. +# ifmail unix - n n - - pipe flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) bsmtp unix - n n - - pipe diff --git a/postfix/conf/postfix-files b/postfix/conf/postfix-files index f18cb4f25..b125f4d8d 100644 --- a/postfix/conf/postfix-files +++ b/postfix/conf/postfix-files @@ -142,6 +142,7 @@ $manpage_directory/man5/canonical.5:f:root:-:644 $manpage_directory/man5/cidr_table.5:f:root:-:644 $manpage_directory/man5/header_checks.5:f:root:-:644 $manpage_directory/man5/ldap_table.5:f:root:-:644 +$manpage_directory/man5/master.5:f:root:-:644 $manpage_directory/man5/mysql_table.5:f:root:-:644 $manpage_directory/man5/pcre_table.5:f:root:-:644 $manpage_directory/man5/pgsql_table.5:f:root:-:644 @@ -309,6 +310,7 @@ $html_directory/ldap_table.5.html:f:root:-:644 $html_directory/lmtp.8.html:f:root:-:644 $html_directory/local.8.html:f:root:-:644 $html_directory/mailq.1.html:f:root:-:644 +$html_directory/master.5.html:f:root:-:644 $html_directory/master.8.html:f:root:-:644 $html_directory/mysql_table.5.html:f:root:-:644 $html_directory/newaliases.1.html:f:root:-:644 diff --git a/postfix/html/Makefile.in b/postfix/html/Makefile.in index 1fb6347b3..1b44044bc 100644 --- a/postfix/html/Makefile.in +++ b/postfix/html/Makefile.in @@ -17,11 +17,13 @@ COMMANDS= mailq.1.html newaliases.1.html postalias.1.html postcat.1.html \ CONFIG = access.5.html aliases.5.html canonical.5.html relocated.5.html \ transport.5.html virtual.5.html pcre_table.5.html regexp_table.5.html \ cidr_table.5.html tcp_table.5.html header_checks.5.html \ - ldap_table.5.html mysql_table.5.html pgsql_table.5.html + ldap_table.5.html mysql_table.5.html pgsql_table.5.html \ + master.5.html +OTHER = postfix-manuals.html AWK = awk '{ print; if (NR == 2) print ".pl 9999\n.ll 65" }' MAN2HTML = man2html -t "Postfix manual - `IFS=.; set \`echo $@\`; echo \"$$1($$2)\"`" -update: $(DAEMONS) $(COMMANDS) $(CONFIG) +update: $(DAEMONS) $(COMMANDS) $(CONFIG) $(OTHER) Makefile: Makefile.in (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../src/makedefs; cat $?) >$@ @@ -239,6 +241,10 @@ ldap_table.5.html: ../proto/ldap_table PATH=../mantools:$$PATH; \ srctoman - $? | $(AWK) | nroff -man | uniq | $(MAN2HTML) | postlink >$@ +master.5.html: ../proto/master + PATH=../mantools:$$PATH; \ + srctoman - $? | $(AWK) | nroff -man | uniq | $(MAN2HTML) | postlink >$@ + mysql_table.5.html: ../proto/mysql_table PATH=../mantools:$$PATH; \ srctoman - $? | $(AWK) | nroff -man | uniq | $(MAN2HTML) | postlink >$@ @@ -270,3 +276,7 @@ transport.5.html: ../proto/transport virtual.5.html: ../proto/virtual PATH=../mantools:$$PATH; \ srctoman - $? | $(AWK) | nroff -man | uniq | $(MAN2HTML) | postlink >$@ + +postfix-manuals.html: ../src/postfix/postfix.c ../mantools/makemanidx + PATH=../mantools:$$PATH; \ + makemanidx ../src/postfix/postfix.c | postlink >$@ diff --git a/postfix/html/access.5.html b/postfix/html/access.5.html index 89b5711f0..610397949 100644 --- a/postfix/html/access.5.html +++ b/postfix/html/access.5.html @@ -212,7 +212,7 @@ ACCESS(5) ACCESS(5) Note: use "postsuper -r" to release mail that was kept on hold for a significant fraction of $maxi- - mal_queue_lifetime or $bounce_queue_lifetime or + mal_queue_lifetime or $bounce_queue_lifetime, or longer. Note: this action currently affects all recipients diff --git a/postfix/html/anvil.8.html b/postfix/html/anvil.8.html index 0695a078f..ade52c523 100644 --- a/postfix/html/anvil.8.html +++ b/postfix/html/anvil.8.html @@ -7,7 +7,7 @@ ANVIL(8) ANVIL(8) NAME - anvil - Postfix client count and rate management + anvil - Postfix client count and request rate management SYNOPSIS anvil [generic Postfix daemon options] @@ -16,15 +16,15 @@ ANVIL(8) ANVIL(8) The Postfix anvil server maintains short-term statistics to defend against clients that hammer a server with either too many parallel connections or with too many successive - connection attempts within a configurable time interval. - This server is designed to run under control by the Post- - fix master server. + requests within a configurable time interval. This server + is designed to run under control by the Postfix master + server. The anvil server maintains no persistent database. Stan- dard library utilities do not meet Postfix performance and robustness requirements. -PROTOCOL +CONNECTION COUNT/RATE LIMITING When a remote client connects, a connection count (or rate) limited server should send the following request to the anvil server: @@ -60,59 +60,108 @@ ANVIL(8) ANVIL(8) status=0 +MESSAGE RATE LIMITING + When a remote client sends a message delivery request, a + message rate limited server should send the following + request to the anvil server: + + request=message + ident=string + + This registers a message delivery request for the (ser- + vice, client) combination specified with ident. The anvil + server answers with the number of message delivery + requests per unit time for that (service, client) combina- + tion: + + status=0 + rate=number + + In order prevent the anvil server from discarding client + request rates too early or too late, a message rate lim- + ited service should also register connect/disconnect + events. + + This feature is available in Postfix 2.2 and later. + +RECIPIENT RATE LIMITING + When a remote client sends a recipient address, a recipi- + ent rate limited server should send the following request + to the anvil server: + + request=recipient + ident=string + + This registers a recipient address for the (service, + client) combination specified with ident. The anvil server + answers with the number of recipient addresses per unit + time for that (service, client) combination: + + status=0 + rate=number + + In order prevent the anvil server from discarding client + request rates too early or too late, a recipient rate lim- + ited service should also register connect/disconnect + events. + + This feature is available in Postfix 2.2 and later. + SECURITY - The anvil server does not talk to the network or to local + The anvil server does not talk to the network or to local users, and can run chrooted at fixed low privilege. - The anvil server maintains an in-memory table with infor- - mation about recent clients of a connection count (or - rate) limited service. Although state is kept only tem- + The anvil server maintains an in-memory table with infor- + mation about recent clients of a connection count (or + rate) limited service. Although state is kept only tem- porarily, this may require a lot of memory on systems that - handle connections from many remote clients. To reduce - memory usage, reduce the time unit over which state is + handle connections from many remote clients. To reduce + memory usage, reduce the time unit over which state is kept. DIAGNOSTICS Problems and transactions are logged to syslogd(8). Upon exit, and every anvil_status_update_time seconds, the - server logs the maximal count and rate values measured, - together with (service, client) information and the time - of day associated with those events. + server logs the maximal count and rate values measured, + together with (service, client) information and the time + of day associated with those events. In order to avoid + unnecessary overhead, no measurements are done for activ- + ity that isn't concurrency limited or rate limited. BUGS - Systems behind network address translating routers or + Systems behind network address translating routers or proxies appear to have the same client address and can run into connection count and/or rate limits falsely. In this preliminary implementation, a count (or rate) lim- - ited server can have only one remote client at a time. If - a server reports multiple simultaneous clients, all but + ited server can have only one remote client at a time. If + a server reports multiple simultaneous clients, all but the last reported client are ignored. CONFIGURATION PARAMETERS Changes to main.cf are picked up automatically as anvil(8) - processes run for only a limited amount of time. Use the + processes run for only a limited amount of time. Use the command "postfix reload" to speed up a change. - The text below provides only a parameter summary. See + The text below provides only a parameter summary. See postconf(5) for more details including examples. anvil_rate_time_unit (60s) - The time unit over which client connection rates + The time unit over which client connection rates and other rates are calculated. anvil_status_update_time (600s) - How frequently the anvil(8) connection and rate + How frequently the anvil(8) connection and rate limiting server logs peak usage information. config_directory (see 'postconf -d' output) - The default location of the Postfix main.cf and + The default location of the Postfix main.cf and master.cf configuration files. daemon_timeout (18000s) - How much time a Postfix daemon process may take to - handle a request before it is terminated by a + How much time a Postfix daemon process may take to + handle a request before it is terminated by a built-in watchdog timer. ipc_timeout (3600s) @@ -120,27 +169,27 @@ ANVIL(8) ANVIL(8) over an internal communication channel. max_idle (100s) - The maximum amount of time that an idle Postfix - daemon process waits for the next service request + The maximum amount of time that an idle Postfix + daemon process waits for the next service request before exiting. max_use (100) - The maximal number of connection requests before a + The maximal number of connection requests before a Postfix daemon process terminates. process_id (read-only) - The process ID of a Postfix command or daemon pro- + The process ID of a Postfix command or daemon pro- cess. process_name (read-only) - The process name of a Postfix command or daemon + The process name of a Postfix command or daemon process. syslog_facility (mail) The syslog facility of Postfix logging. syslog_name (postfix) - The mail system name that is prepended to the pro- + The mail system name that is prepended to the pro- cess name in syslog records, so that "smtpd" becomes, for example, "postfix/smtpd". @@ -152,7 +201,7 @@ ANVIL(8) ANVIL(8) TUNING_README, performance tuning LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. HISTORY diff --git a/postfix/html/header_checks.5.html b/postfix/html/header_checks.5.html index 3d13e7bb5..581164174 100644 --- a/postfix/html/header_checks.5.html +++ b/postfix/html/header_checks.5.html @@ -187,7 +187,7 @@ HEADER_CHECKS(5) HEADER_CHECKS(5) Note: use "postsuper -r" to release mail that was kept on hold for a significant fraction of $maxi- - mal_queue_lifetime or $bounce_queue_lifetime or + mal_queue_lifetime or $bounce_queue_lifetime, or longer. Note: this action affects all recipients of the diff --git a/postfix/html/index.html b/postfix/html/index.html index b603be788..3eb80bf48 100644 --- a/postfix/html/index.html +++ b/postfix/html/index.html @@ -167,6 +167,8 @@ Per-client/user/etc. access
  • All main.cf parameters +
  • All Postfix manual pages +
  • Rejecting Unknown Local Recipients diff --git a/postfix/html/ldap_table.5.html b/postfix/html/ldap_table.5.html index d8d363cac..55f1a743e 100644 --- a/postfix/html/ldap_table.5.html +++ b/postfix/html/ldap_table.5.html @@ -88,7 +88,7 @@ LDAP_TABLE(5) LDAP_TABLE(5) server_host (default: localhost) The name of the host running the LDAP server, e.g. - server_host = ldap.your.com + server_host = ldap.example.com Depending on the LDAP client library you're using, it should be possible to specify multiple servers @@ -96,18 +96,19 @@ LDAP_TABLE(5) LDAP_TABLE(5) the first one fail. It should also be possible to give each server in the list a different port (overriding server_port below), by naming them like - server_host = ldap.your.com:1444 + server_host = ldap.example.com:1444 With OpenLDAP, a (list of) LDAP URLs can be used to specify both the hostname(s) and the port(s): - server_host = ldap://ldap.your.com:1444 + server_host = ldap://ldap.example.com:1444 + ldap://ldap2.example.com:1444 All LDAP URLs accepted by the OpenLDAP library are supported, including connections over UNIX domain sockets, and LDAP SSL (the last one provided that OpenLDAP was compiled with support for SSL): server_host = ldapi://%2Fsome%2Fpath - server_host = ldaps://ldap.your.com:636 + ldaps://ldap.example.com:636 server_port (default: 389) The port the LDAP server listens on, e.g. @@ -344,7 +345,7 @@ LDAP_TABLE(5) LDAP_TABLE(5) LDAP SSL service can be requested by using a LDAP SSL URL in the server_host parameter: - server_host = ldaps://ldap.your.com:636 + server_host = ldaps://ldap.example.com:636 STARTTLS can be turned on with the start_tls parameter: start_tls = yes diff --git a/postfix/html/master.5.html b/postfix/html/master.5.html new file mode 100644 index 000000000..f0dbe4e89 --- /dev/null +++ b/postfix/html/master.5.html @@ -0,0 +1,228 @@ + + + + Postfix manual - master(5) +
    +MASTER(5)                                               MASTER(5)
    +
    +NAME
    +       master - Postfix master process configuration file format
    +
    +DESCRIPTION
    +       The  Postfix mail system is implemented by small number of
    +       (mostly) client commands that are invoked by users, and by
    +       a larger number of services that run in the background.
    +
    +       Postfix  services  run under control of the master(8) pro-
    +       cess.  The master.cf  configuration  file  defines  how  a
    +       client program connects to a service, and what daemon pro-
    +       gram runs when a service is requested.  Most  daemon  pro-
    +       cesses are short-lived and terminate after serving max_use
    +       clients, or after inactivity for max_idle or more units of
    +       time.
    +
    +       All  daemons  specified here must speak a Postfix-internal
    +       protocol. In order to execute non-Postfix software use the
    +       local(8),  pipe(8) or spawn(8) services, or run the server
    +       under control by inetd(8) or equivalent.
    +
    +       Changes in master.cf requires  that  "postfix  reload"  be
    +       executed in order to reload the configuration.
    +
    +SYNTAX
    +       The general format of the master.cf file is as follows:
    +
    +       o      Each logical line defines a single Postfix service.
    +              Each service is identified by its name and type  as
    +              described  below.   When multiple lines specify the
    +              same service name and type, only the  last  one  is
    +              remembered.  Otherwise, the order of master.cf ser-
    +              vice definitions does not matter.
    +
    +       o      Empty lines and whitespace-only lines are  ignored,
    +              as  are  lines whose first non-whitespace character
    +              is a `#'.
    +
    +       o      A logical line starts with non-whitespace  text.  A
    +              line  that starts with whitespace continues a logi-
    +              cal line.
    +
    +       Each logical line consists of eight  fields  separated  by
    +       whitespace.   These  are  described  below in the order as
    +       they appear in the master.cf file.
    +
    +       Where applicable a field of "-" requests that the built-in
    +       default  value  be used. For boolean fields specify "y" or
    +       "n" to override the default value.
    +
    +       Service name
    +              The service name syntax depends on the service type
    +              as described next.
    +
    +       Service type
    +              Specify one of the following service types:
    +
    +              inet   The  service  listens on a TCP/IP socket and
    +                     is therefore accessible via the network.
    +
    +                     The service name is specified as  host:port,
    +                     denoting the host and port on which new con-
    +                     nections should be accepted. The  host  part
    +                     (and  colon) may be omitted.  Either host or
    +                     port may be given in symbolic form (host  or
    +                     service name) or in numeric form (IP address
    +                     or port number).
    +
    +                     Examples: a service name of   127.0.0.1:smtp
    +                     receives  mail  via  the  loopback interface
    +                     only; and a service name  of  10025  accepts
    +                     connections on TCP port 10025 via all inter-
    +                     faces configured  with  the  inet_interfaces
    +                     parameter.
    +
    +              unix   The  service listens on a UNIX-domain socket
    +                     and is accessible for local clients only.
    +
    +                     The service name is a pathname  relative  to
    +                     the  Postfix  queue directory (pathname con-
    +                     trolled with the queue_directory  configura-
    +                     tion parameter in main.cf).
    +
    +                     On  Solaris  systems the unix type is imple-
    +                     mented with streams sockets.
    +
    +              fifo   The service listens on a FIFO  (named  pipe)
    +                     and is accessible for local clients only.
    +
    +                     The  service  name is a pathname relative to
    +                     the Postfix queue directory  (pathname  con-
    +                     trolled  with the queue_directory configura-
    +                     tion parameter in main.cf).
    +
    +       Private (default: y)
    +              Whether or not access is  restricted  to  the  mail
    +              system.   Internet  (type  inet)  services can't be
    +              private.
    +
    +       Unprivileged (default: y)
    +              Whether the service runs with root privileges or as
    +              the  owner of the Postfix system (the owner name is
    +              controlled by the mail_owner configuration variable
    +              in the main.cf file).
    +
    +              The  local(8),  pipe(8),  spawn(8),  and virtual(8)
    +              daemons require privileges.
    +
    +       Chroot (default: y)
    +              Whether or not the service  runs  chrooted  to  the
    +              mail queue directory (pathname is controlled by the
    +              queue_directory  configuration  variable   in   the
    +              main.cf file).
    +
    +              Chroot  should  not  be  used  with  the  local(8),
    +              pipe(8) and spawn(8) daemons.  Although  the  prox-
    +              ymap(8)  server  can run chrooted, doing so defeats
    +              most of the purpose of having that service  in  the
    +              first place.
    +
    +              The files in the examples/chroot-setup subdirectory
    +              of the Postfix source archive describe how  to  set
    +              up  a  Postfix  chroot environment for your type of
    +              machine, and  BASIC_CONFIGURATION_README  discusses
    +              issues related to running daemons chrooted.
    +
    +       Wakeup time (default: 0)
    +              Automatically  wake  up the named service after the
    +              specified number of seconds. The wake up is  imple-
    +              mented  by  connecting to the service and sending a
    +              wake up request.  A ? at the end  of  the  wake  up
    +              time  field  requests  that  wake up events be sent
    +              only to services  that  are  actually  being  used.
    +              Specify 0 for no automatic wake up.
    +
    +              The pickup(8), qmgr(8) and flush(8) daemons require
    +              a wake up timer.
    +
    +       Process limit (default: $default_process_limit)
    +              The maximum number of processes  that  may  execute
    +              this  service simultaneously. Specify 0 for no pro-
    +              cess count limit.
    +
    +              NOTE: Some Postfix services must be configured as a
    +              single-process  service  (for example, qmgr(8)) and
    +              some services must be configured  with  no  process
    +              limit (for example, cleanup(8)).  These limits must
    +              not be changed.
    +
    +       Command name + arguments
    +              The command to be executed.   Characters  that  are
    +              special  to  the  shell  such as ">" or "|" have no
    +              special meaning here, and quotes cannot be used  to
    +              protect arguments containing whitespace.
    +
    +              The  command name is relative to the Postfix daemon
    +              directory  (pathname  is  controlled  by  the  dae-
    +              mon_directory configuration variable).
    +
    +              The  command  argument syntax for specific commands
    +              is specified in the respective daemon manual  page.
    +
    +              The  following  command-line  options have the same
    +              effect for all daemon programs:
    +
    +              -D     Run the daemon under control by the  command
    +                     specified with the debugger_command variable
    +                     in  the  main.cf  configuration  file.   See
    +                     DEBUG_README for hints and tips.
    +
    +              -o name=value
    +                     Override  the  named  main.cf  configuration
    +                     parameter. The parameter value can refer  to
    +                     other parameters as $name etc., just like in
    +                     main.cf.  See postconf(5) for syntax.
    +
    +                     NOTE 1: do not specify whitespace around the
    +                     "=".   In  parameter  values,  either  avoid
    +                     whitespace altogether, use commas instead of
    +                     spaces,   or  consider  overrides  like  "-o
    +                     name=$override_parameter"    with     $over-
    +                     ride_parameter set in main.cf.
    +
    +                     NOTE  2: Over-zealous use of parameter over-
    +                     rides makes the Postfix  configuration  hard
    +                     to  understand  and  maintain.  At a certain
    +                     point, it might be easier to configure  mul-
    +                     tiple  instances of Postfix, instead of con-
    +                     figuring  multiple  personalities  via  mas-
    +                     ter.cf.
    +
    +              -v     Increase  the verbose logging level. Specify
    +                     multiple -v options to make a  command  more
    +                     verbose.
    +
    +SEE ALSO
    +       master(8), process manager
    +       postconf(5), configuration parameters
    +
    +README FILES
    +       BASIC_CONFIGURATION_README, basic configuration
    +       DEBUG_README, Postfix debugging
    +
    +LICENSE
    +       The Secure Mailer license must be  distributed  with  this
    +       software.
    +
    +AUTHOR(S)
    +       Initial version by
    +       Magnus Baeck
    +       Lund Institute of Technology
    +       Sweden
    +
    +       Wietse Venema
    +       IBM T.J. Watson Research
    +       P.O. Box 704
    +       Yorktown Heights, NY 10598, USA
    +
    +                                                        MASTER(5)
    +
    diff --git a/postfix/html/master.8.html b/postfix/html/master.8.html index c3dfc9938..81ef97709 100644 --- a/postfix/html/master.8.html +++ b/postfix/html/master.8.html @@ -10,8 +10,7 @@ MASTER(8) MASTER(8) master - Postfix master process SYNOPSIS - master [-Dtv] [-c config_dir] - [-e exit_time] + master [-Dtv] [-c config_dir] [-e exit_time] DESCRIPTION The master daemon is the resident process that runs Post- @@ -27,18 +26,16 @@ MASTER(8) MASTER(8) address verification server. The behavior of the master daemon is controlled by the - master.cf configuration file. The table specifies zero or - more servers in the UNIX or INET domain, or servers that - take requests from a FIFO. Precise configuration details - are given in the master.cf file, and in the manual pages - of the respective daemons. + master.cf configuration file, as described in master(5). Options: -c config_dir Read the main.cf and master.cf configuration files in the named directory instead of the default con- - figuration directory. + figuration directory. This also overrides the con- + figuration files for other Postfix daemon pro- + cesses. -e exit_time Terminate the master process after exit_time sec- @@ -173,7 +170,8 @@ MASTER(8) MASTER(8) SEE ALSO qmgr(8), queue manager verify(8), address verification - postconf(5), configuration parameters + master(5), master.cf configuration file syntax + postconf(5), main.cf configuration parameter syntax syslogd(8), system logging LICENSE diff --git a/postfix/html/pipe.8.html b/postfix/html/pipe.8.html index 4b9ca85b6..2f9795c15 100644 --- a/postfix/html/pipe.8.html +++ b/postfix/html/pipe.8.html @@ -149,7 +149,11 @@ PIPE(8) PIPE(8) In the command argument vector, the following macros are recognized and replaced with correspond- ing information from the Postfix queue manager - delivery request: + delivery request. + + In addition to the form ${name}, the forms $name + and $(name) are also recognized. Specify $$ where + a single $ is wanted. ${extension} This macro expands to the extension part of @@ -194,90 +198,111 @@ PIPE(8) PIPE(8) This information is modified by the hqu flags for quoting and case folding. + ${sasl_method} + This macro expands to the SASL authentica- + tion mechanism used during the reception of + the message. An empty string is passed if + the message has been received without SASL + authentication. + + This is available in Postfix 2.2 and later. + + ${sasl_sender} + This macro expands to the SASL sender name + (i.e. the original submitter as per RFC + 2554) used during the reception of the mes- + sage. + + This is available in Postfix 2.2 and later. + + ${sasl_username} + This macro expands to the SASL user name + used during the reception of the message. An + empty string is passed if the message has + been received without SASL authentication. + + This is available in Postfix 2.2 and later. + ${sender} - This macro expands to the envelope sender + This macro expands to the envelope sender address. - This information is modified by the q flag + This information is modified by the q flag for quoting. ${size} - This macro expands to Postfix's idea of the - message size, which is an approximation of + This macro expands to Postfix's idea of the + message size, which is an approximation of the size of the message as delivered. ${user} This macro expands to the username part of a - recipient address. For example, with an + recipient address. For example, with an address user+foo@domain the username part is user. - A command-line argument that contains - ${user} expands into as many command-line + A command-line argument that contains + ${user} expands into as many command-line arguments as there are recipients. - This information is modified by the u flag + This information is modified by the u flag for case folding. - In addition to the form ${name}, the forms $name and - $(name) are also recognized. Specify $$ where a single $ - is wanted. - DIAGNOSTICS - Command exit status codes are expected to follow the con- + Command exit status codes are expected to follow the con- ventions defined in <sysexits.h>. - Problems and transactions are logged to syslogd(8). Cor- - rupted message files are marked so that the queue manager + Problems and transactions are logged to syslogd(8). Cor- + rupted message files are marked so that the queue manager can move them to the corrupt queue for further inspection. SECURITY - This program needs a dual personality 1) to access the - private Postfix queue and IPC mechanisms, and 2) to exe- + This program needs a dual personality 1) to access the + private Postfix queue and IPC mechanisms, and 2) to exe- cute external commands as the specified user. It is there- fore security sensitive. CONFIGURATION PARAMETERS - Changes to main.cf are picked up automatically as pipe(8) - processes run for only a limited amount of time. Use the + Changes to main.cf are picked up automatically as pipe(8) + processes run for only a limited amount of time. Use the command "postfix reload" to speed up a change. - The text below provides only a parameter summary. See + The text below provides only a parameter summary. See postconf(5) for more details including examples. RESOURCE AND RATE CONTROLS - In the text below, transport is the first field in a mas- + In the text below, transport is the first field in a mas- ter.cf entry. transport_destination_concurrency_limit ($default_destina- tion_concurrency_limit) Limit the number of parallel deliveries to the same - destination, for delivery via the named transport. + destination, for delivery via the named transport. The limit is enforced by the Postfix queue manager. transport_destination_recipient_limit ($default_destina- tion_recipient_limit) - Limit the number of recipients per message deliv- - ery, for delivery via the named transport. The + Limit the number of recipients per message deliv- + ery, for delivery via the named transport. The limit is enforced by the Postfix queue manager. transport_time_limit ($command_time_limit) - Limit the time for delivery to external command, + Limit the time for delivery to external command, for delivery via the named transport. The limit is enforced by the pipe delivery agent. MISCELLANEOUS CONTROLS config_directory (see 'postconf -d' output) - The default location of the Postfix main.cf and + The default location of the Postfix main.cf and master.cf configuration files. daemon_timeout (18000s) - How much time a Postfix daemon process may take to - handle a request before it is terminated by a + How much time a Postfix daemon process may take to + handle a request before it is terminated by a built-in watchdog timer. export_environment (see 'postconf -d' output) - The list of environment variables that a Postfix + The list of environment variables that a Postfix process will export to non-Postfix processes. ipc_timeout (3600s) @@ -289,24 +314,24 @@ PIPE(8) PIPE(8) and most Postfix daemon processes. max_idle (100s) - The maximum amount of time that an idle Postfix - daemon process waits for the next service request + The maximum amount of time that an idle Postfix + daemon process waits for the next service request before exiting. max_use (100) - The maximal number of connection requests before a + The maximal number of connection requests before a Postfix daemon process terminates. process_id (read-only) - The process ID of a Postfix command or daemon pro- + The process ID of a Postfix command or daemon pro- cess. process_name (read-only) - The process name of a Postfix command or daemon + The process name of a Postfix command or daemon process. queue_directory (see 'postconf -d' output) - The location of the Postfix top-level queue direc- + The location of the Postfix top-level queue direc- tory. recipient_delimiter (empty) @@ -317,7 +342,7 @@ PIPE(8) PIPE(8) The syslog facility of Postfix logging. syslog_name (postfix) - The mail system name that is prepended to the pro- + The mail system name that is prepended to the pro- cess name in syslog records, so that "smtpd" becomes, for example, "postfix/smtpd". @@ -329,7 +354,7 @@ PIPE(8) PIPE(8) syslogd(8), system logging LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index 841d702ce..9884581f8 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -2042,7 +2042,8 @@ time keeping on System-V-ish systems.

    Specify a list of names and/or name=value pairs, separated by -whitespace or comma. +whitespace or comma. The name=value form is supported with +Postfix 2.1 and later.

    @@ -5370,7 +5371,7 @@ ignored. -

    +

    This feature is available in Postfix 2.2 and later.

    @@ -5398,6 +5399,8 @@ delivery performance.

    an SMTP session is reused before it is closed.

    +

    This feature is available in Postfix 2.2 and later.

    + @@ -5409,6 +5412,8 @@ an unused SMTP client socket is kept open before it is closed. Do not specify larger values without permission from the remote sites.

    +

    This feature is available in Postfix 2.2 and later.

    + @@ -6123,8 +6128,8 @@ Example: (default: 50)

    -How many simultaneous connections any SMTP client is allowed to -make to the SMTP service. By default, the limit is set it to half +How many simultaneous connections any client is allowed to +make to this service. By default, the limit is set to half the default process limit value.

    @@ -6138,18 +6143,56 @@ not be used to regulate legitimate mail traffic.

    -This feature is not part of the stable Postfix 2.1 release. +This feature is available in Postfix 2.2 and later.

    -
    smtpd_client_connection_limit_exceptions +
    smtpd_client_connection_rate_limit +(default: 0)
    + +

    +The maximal number of connection attempts any client is allowed to +make to this service per time unit. The time unit is specified +with the anvil_rate_time_unit configuration parameter. +

    + +

    +By default, a client can make as many connections per time unit as +Postfix can accept. +

    + +

    +To disable this feature, specify a limit of 0. +

    + +

    +WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +

    + +

    +This feature is available in Postfix 2.2 and later. +

    + +

    +Example: +

    + +
    +smtpd_client_connection_rate_limit = 1000
    +
    + + +
    + +
    smtpd_client_event_limit_exceptions (default: $mynetworks)

    -Clients that are excluded from connection count or connection rate -restrictions. +Clients that are excluded from connection count, connection rate, +message rate or recipient rate restrictions.

    @@ -6159,25 +6202,25 @@ dot causes the domain to match any name below it).

    -This feature is not part of the stable Postfix 2.1 release. +This feature is available in Postfix 2.2 and later.

    -
    smtpd_client_connection_rate_limit +
    smtpd_client_message_rate_limit (default: 0)

    -The maximal number of connection attempts any client is allowed to -make to this service per time unit. The time unit is specified -with the anvil_rate_time_unit configuration parameter, and defaults -to one minute. +The maximal number of message delivery requests that any client is +allowed to make to this service per time unit, regardless of whether +or not Postfix actually accepts those messages. The time unit is +specified with the anvil_rate_time_unit configuration parameter.

    -By default, a client can make as many connections per time unit as -Postfix can accept. +By default, a client can send as many message delivery requests +requests per time unit as Postfix can accept.

    @@ -6190,7 +6233,7 @@ not be used to regulate legitimate mail traffic.

    -This feature is not part of the stable Postfix 2.1 release. +This feature is available in Postfix 2.2 and later.

    @@ -6198,7 +6241,46 @@ Example:

    -smtpd_client_connection_rate_limit = 1000
    +smtpd_client_message_rate_limit = 1000
    +
    + + +
    + +
    smtpd_client_recipient_rate_limit +(default: 0)
    + +

    +The maximal number of recipient addresses that any client is allowed +to send to this service per time unit, regardless of whether or not +Postfix actually accepts those recipients. The time unit is specified +with the anvil_rate_time_unit configuration parameter. +

    + +

    +By default, a client can make as many recipient addresses per time +unit as Postfix can accept. +

    + +

    +To disable this feature, specify a limit of 0. +

    + +

    +WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +

    + +

    +This feature is available in Postfix 2.2 and later. +

    + +

    +Example: +

    + +
    +smtpd_client_recipient_rate_limit = 1000
     
    diff --git a/postfix/html/postfix-manuals.html b/postfix/html/postfix-manuals.html new file mode 100644 index 000000000..e286b3f18 --- /dev/null +++ b/postfix/html/postfix-manuals.html @@ -0,0 +1,208 @@ + + + + + + +Postfix Manual Pages + + + + + + + +

    Postfix +Manual Pages

    + +
    + +

    Information for new Postfix users

    + +

    New Postfix users should first look at the following introductory +documents. These introductions are hyperlinked to more advanced +documents and to UNIX-style manual pages. The UNIX-style manual +pages are intended for people who are already familiar with Postfix. +

    + + + +

    Postfix manual page organization

    + +

    Each Postfix manual page is numbered after a section of the +UNIX manual: examples are mailq(1) or access(5). Unfortunately, +the organization of manual pages depends on the UNIX version being +used. Postfix documentation assumes the following convention: +

    + +
    + + + + + + + + + + + + + + + +
    Section Topic

    1 Commands
    3 Library routines
    5 File formats
    8 Daemons
    + +
    + +

    Commands

    + + + +

    Postfix configuration

    + + + +

    Table-driven mechanisms

    + + + +

    Table lookup mechanisms

    + + + +

    Daemon processes

    + + + + + + + diff --git a/postfix/html/postfix.1.html b/postfix/html/postfix.1.html index 952a42474..255a872b4 100644 --- a/postfix/html/postfix.1.html +++ b/postfix/html/postfix.1.html @@ -206,7 +206,8 @@ POSTFIX(1) POSTFIX(1) sendmail(1), Sendmail compatibility interface Postfix configuration: - postconf(5), Postfix configuration parameters + master(5), Postfix master.cf file syntax + postconf(5), Postfix main.cf file syntax Table-driven mechanisms: access(5), Postfix SMTP access control table diff --git a/postfix/html/postsuper.1.html b/postfix/html/postsuper.1.html index ff965336b..38197a935 100644 --- a/postfix/html/postsuper.1.html +++ b/postfix/html/postsuper.1.html @@ -104,7 +104,7 @@ POSTSUPER(1) POSTSUPER(1) Note: use "postsuper -r" to release mail that was kept on hold for a significant fraction of $maxi- - mal_queue_lifetime or $bounce_queue_lifetime or + mal_queue_lifetime or $bounce_queue_lifetime, or longer. Specify -H ALL to release all mail that is "on diff --git a/postfix/html/qshape.1.html b/postfix/html/qshape.1.html index 398cf1553..9b378ae42 100644 --- a/postfix/html/qshape.1.html +++ b/postfix/html/qshape.1.html @@ -29,7 +29,7 @@ QSHAPE(1) QSHAPE(1) the recipient domain distribution. By default the recipient distribution is displayed. There can be more recipients than messages, but as each message - has only one sender, the sender distribution is a a + has only one sender, the sender distribution is a message distribution. -p Generate aggregate statistics for parent domains. @@ -66,9 +66,9 @@ QSHAPE(1) QSHAPE(1) The output is right justified, with the counts for the last bucket shown on the 80th column, the ter- minal_width can be adjusted for wider screens - allowing more buckets to be displayed with truncat- - ing the domain names on the left. When a row for a - full domain name and its counters does not fit in + allowing more buckets to be displayed without trun- + cating the domain names on the left. When a row for + a full domain name and its counters does not fit in the specified number of columns, only the last 17 bytes of the domain name are shown with the prefix replaced by a '+' character. Truncated parent diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html index 735d09388..98026c336 100644 --- a/postfix/html/smtpd.8.html +++ b/postfix/html/smtpd.8.html @@ -390,20 +390,35 @@ SMTPD(8) SMTPD(8) server command history before it is flushed upon receipt of EHLO, RSET, or end of DATA. - Not available in Postfix version 2.1: + The per SMTP client connection count and request rate lim- + its are implemented in co-operation with the anvil(8) ser- + vice, and are available in Postfix version 2.2 and later. smtpd_client_connection_count_limit (50) - How many simultaneous connections any SMTP client - is allowed to make to the SMTP service. + How many simultaneous connections any client is + allowed to make to this service. smtpd_client_connection_rate_limit (0) The maximal number of connection attempts any - client is allowed to make to this service per time + client is allowed to make to this service per time unit. - smtpd_client_connection_limit_exceptions ($mynetworks) - Clients that are excluded from connection count or - connection rate restrictions. + smtpd_client_message_rate_limit (0) + The maximal number of message delivery requests + that any client is allowed to make to this service + per time unit, regardless of whether or not Postfix + actually accepts those messages. + + smtpd_client_recipient_rate_limit (0) + The maximal number of recipient addresses that any + client is allowed to send to this service per time + unit, regardless of whether or not Postfix actually + accepts those recipients. + + smtpd_client_event_limit_exceptions ($mynetworks) + Clients that are excluded from connection count, + connection rate, message rate or recipient rate + restrictions. TARPIT CONTROLS When a remote SMTP client makes errors, the Postfix SMTP @@ -742,6 +757,7 @@ SMTPD(8) SMTPD(8) becomes, for example, "postfix/smtpd". SEE ALSO + anvil(8), client count and request rate management cleanup(8), message canonicalization trivial-rewrite(8), address resolver verify(8), address verification service diff --git a/postfix/man/Makefile.in b/postfix/man/Makefile.in index 8bcb4e41b..64e998971 100644 --- a/postfix/man/Makefile.in +++ b/postfix/man/Makefile.in @@ -16,7 +16,7 @@ CONFIG = man5/access.5 man5/aliases.5 man5/canonical.5 man5/relocated.5 \ man5/transport.5 man5/virtual.5 man5/pcre_table.5 man5/regexp_table.5 \ man5/cidr_table.5 man5/tcp_table.5 man5/header_checks.5 \ man5/body_checks.5 man5/ldap_table.5 man5/mysql_table.5 \ - man5/pgsql_table.5 + man5/pgsql_table.5 man5/master.5 TOOLS = man1/smtp-sink.1 man1/smtp-source.1 man1/qmqp-sink.1 \ man1/qmqp-source.1 man1/qshape.1 @@ -244,6 +244,9 @@ man5/body_checks.5: ../proto/header_checks man5/ldap_table.5: ../proto/ldap_table ../mantools/srctoman - $? >$@ +man5/master.5: ../proto/master + ../mantools/srctoman - $? >$@ + man5/mysql_table.5: ../proto/mysql_table ../mantools/srctoman - $? >$@ diff --git a/postfix/man/man1/postfix.1 b/postfix/man/man1/postfix.1 index a8407c923..c4802261b 100644 --- a/postfix/man/man1/postfix.1 +++ b/postfix/man/man1/postfix.1 @@ -171,7 +171,8 @@ postsuper(1), Postfix housekeeping sendmail(1), Sendmail compatibility interface Postfix configuration: -postconf(5), Postfix configuration parameters +master(5), Postfix master.cf file syntax +postconf(5), Postfix main.cf file syntax Table-driven mechanisms: access(5), Postfix SMTP access control table diff --git a/postfix/man/man1/postsuper.1 b/postfix/man/man1/postsuper.1 index fa2f7d639..a63a8ebf8 100644 --- a/postfix/man/man1/postsuper.1 +++ b/postfix/man/man1/postsuper.1 @@ -98,7 +98,7 @@ queue IDs from standard input. .sp Note: use "\fBpostsuper -r\fR" to release mail that was kept on hold for a significant fraction of \fB$maximal_queue_lifetime\fR -or \fB$bounce_queue_lifetime\fR or longer. +or \fB$bounce_queue_lifetime\fR, or longer. .sp Specify \fB-H ALL\fR to release all mail that is "on hold". As a safety measure, the word \fBALL\fR must be specified in upper diff --git a/postfix/man/man1/qshape.1 b/postfix/man/man1/qshape.1 index baa7e69aa..7a23b810a 100644 --- a/postfix/man/man1/qshape.1 +++ b/postfix/man/man1/qshape.1 @@ -29,7 +29,7 @@ Display the sender domain distribution instead of the recipient domain distribution. By default the recipient distribution is displayed. There can be more recipients than messages, but as each message has only one sender, the sender distribution is a -a message distribution. +message distribution. .IP \fB-p\fR Generate aggregate statistics for parent domains. Top level domains are not shown, nor are domains with fewer than \fImin_subdomains\fR @@ -57,7 +57,7 @@ This feature is available in Postfix 2.2 and later. The output is right justified, with the counts for the last bucket shown on the 80th column, the \fIterminal_width\fR can be adjusted for wider screens allowing more buckets to be displayed -with truncating the domain names on the left. When a row for a +without truncating the domain names on the left. When a row for a full domain name and its counters does not fit in the specified number of columns, only the last 17 bytes of the domain name are shown with the prefix replaced by a '+' character. Truncated diff --git a/postfix/man/man1/sendmail.1 b/postfix/man/man1/sendmail.1 index 3e7b1d72f..f82837eeb 100644 --- a/postfix/man/man1/sendmail.1 +++ b/postfix/man/man1/sendmail.1 @@ -258,9 +258,8 @@ List of users who are authorized to flush the queue. .IP "\fBauthorized_mailq_users (static:anyone)\fR" List of users who are authorized to view the queue. .IP "\fBauthorized_submit_users (static:anyone)\fR" -List of users who are authorized to submit mail with the -sendmail(1) command (and with the privileged postdrop(1) -helper command). +List of users who are authorized to submit mail with the sendmail(1) +command (and with the privileged postdrop(1) helper command). .SH "RESOURCE AND RATE CONTROLS" .na .nf diff --git a/postfix/man/man5/access.5 b/postfix/man/man5/access.5 index 0ae0f66a3..929411a1e 100644 --- a/postfix/man/man5/access.5 +++ b/postfix/man/man5/access.5 @@ -198,7 +198,7 @@ the \fBpostsuper\fR(1) command. .sp Note: use "\fBpostsuper -r\fR" to release mail that was kept on hold for a significant fraction of \fB$maximal_queue_lifetime\fR -or \fB$bounce_queue_lifetime\fR or longer. +or \fB$bounce_queue_lifetime\fR, or longer. .sp Note: this action currently affects all recipients of the message. .sp diff --git a/postfix/man/man5/header_checks.5 b/postfix/man/man5/header_checks.5 index 0c2e77d83..4d09189f8 100644 --- a/postfix/man/man5/header_checks.5 +++ b/postfix/man/man5/header_checks.5 @@ -175,7 +175,7 @@ the \fBpostsuper\fR(1) command. .sp Note: use "\fBpostsuper -r\fR" to release mail that was kept on hold for a significant fraction of \fB$maximal_queue_lifetime\fR -or \fB$bounce_queue_lifetime\fR or longer. +or \fB$bounce_queue_lifetime\fR, or longer. .sp Note: this action affects all recipients of the message. .sp diff --git a/postfix/man/man5/ldap_table.5 b/postfix/man/man5/ldap_table.5 index bb7e97f3f..594f4c4e6 100644 --- a/postfix/man/man5/ldap_table.5 +++ b/postfix/man/man5/ldap_table.5 @@ -99,7 +99,7 @@ strings. .IP "\fBserver_host (default: localhost)\fR" The name of the host running the LDAP server, e.g. .ti +4 -server_host = ldap.your.com +server_host = ldap.example.com Depending on the LDAP client library you're using, it should be possible to specify multiple servers here, with the library @@ -107,12 +107,14 @@ trying them in order should the first one fail. It should also be possible to give each server in the list a different port (overriding \fBserver_port\fR below), by naming them like .ti +4 -server_host = ldap.your.com:1444 +server_host = ldap.example.com:1444 With OpenLDAP, a (list of) LDAP URLs can be used to specify both the hostname(s) and the port(s): .ti +4 -server_host = ldap://ldap.your.com:1444 +server_host = ldap://ldap.example.com:1444 +.ti +8 + ldap://ldap2.example.com:1444 All LDAP URLs accepted by the OpenLDAP library are supported, including connections over UNIX domain sockets, and LDAP SSL @@ -120,8 +122,8 @@ including connections over UNIX domain sockets, and LDAP SSL for SSL): .ti +4 server_host = ldapi://%2Fsome%2Fpath -.ti +4 -server_host = ldaps://ldap.your.com:636 +.ti +8 + ldaps://ldap.example.com:636 .IP "\fBserver_port (default: 389)\fR" The port the LDAP server listens on, e.g. .ti +4 @@ -334,7 +336,7 @@ issue the STARTTLS command. LDAP SSL service can be requested by using a LDAP SSL URL in the server_host parameter: .ti +4 -server_host = ldaps://ldap.your.com:636 +server_host = ldaps://ldap.example.com:636 STARTTLS can be turned on with the start_tls parameter: .ti +4 diff --git a/postfix/man/man5/master.5 b/postfix/man/man5/master.5 new file mode 100644 index 000000000..182b3e3bc --- /dev/null +++ b/postfix/man/man5/master.5 @@ -0,0 +1,214 @@ +.TH MASTER 5 +.ad +.fi +.SH NAME +master +\- +Postfix master process configuration file format +.SH DESCRIPTION +.ad +.fi +The Postfix mail system is implemented by small number of +(mostly) client commands that are invoked by users, and by +a larger number of services that run in the background. + +Postfix services run under control of the \fBmaster\fR(8) +process. The master.cf configuration file defines how a +client program connects to a service, and what daemon +program runs when a service is requested. Most daemon +processes are short-lived and terminate after serving +\fBmax_use\fR clients, or after inactivity for \fBmax_idle\fR +or more units of time. + +All daemons specified here must speak a Postfix-internal +protocol. In order to execute non-Postfix software use the +\fBlocal\fR(8), \fBpipe\fR(8) or \fBspawn\fR(8) services, or +run the server under control by \fBinetd\fR(8) or equivalent. +.PP +Changes in master.cf requires that "\fBpostfix reload\fR" be +executed in order to reload the configuration. +.SH "SYNTAX" +.na +.nf +.ad +.fi +The general format of the master.cf file is as follows: +.IP \(bu +Each logical line defines a single Postfix service. +Each service is identified by its name and type as described +below. When multiple lines specify the same service name +and type, only the last one is remembered. Otherwise, the +order of master.cf service definitions does not matter. +.IP \(bu +Empty lines and whitespace-only lines are ignored, as are +lines whose first non-whitespace character is a `#'. +.IP \(bu +A logical line starts with non-whitespace text. A line that +starts with whitespace continues a logical line. +.PP +Each logical line consists of eight fields separated by +whitespace. These are described below in the order as they +appear in the master.cf file. + +Where applicable a field of "-" requests that the built-in +default value be used. For boolean fields specify "y" or +"n" to override the default value. +.IP "\fBService name\fR" +The service name syntax depends on the service type as +described next. +.IP "\fBService type\fR" +Specify one of the following service types: +.RS +.IP \fBinet\fR +The service listens on a TCP/IP socket and is therefore +accessible via the network. + +The service name is specified as \fIhost:port\fR, denoting +the host and port on which new connections should be +accepted. The host part (and colon) may be omitted. Either +host or port may be given in symbolic form (host or service +name) or in numeric form (IP address or port number). +.sp +Examples: a service name of \fB127.0.0.1:smtp\fR receives +mail via the loopback interface only; and a service name +of \fB10025\fR accepts connections on TCP port 10025 via +all interfaces configured with the \fBinet_interfaces\fR +parameter. +.IP \fBunix\fR +The service listens on a UNIX-domain socket and is accessible +for local clients only. + +The service name is a pathname relative to the Postfix +queue directory (pathname controlled with the \fBqueue_directory\fR +configuration parameter in main.cf). +.sp +On Solaris systems the \fBunix\fR type is implemented with +streams sockets. +.IP \fBfifo\fR +The service listens on a FIFO (named pipe) and is accessible +for local clients only. + +The service name is a pathname relative to the Postfix +queue directory (pathname controlled with the \fBqueue_directory\fR +configuration parameter in main.cf). +.RE +.IP "\fBPrivate (default: y)\fR" +Whether or not access is restricted to the mail system. +Internet (type \fBinet\fR) services can't be private. +.IP "\fBUnprivileged (default: y)\fR" +Whether the service runs with root privileges or as the +owner of the Postfix system (the owner name is controlled +by the \fBmail_owner\fR configuration variable in the +main.cf file). +.sp +The \fBlocal\fR(8), \fBpipe\fR(8), \fBspawn\fR(8), and +\fBvirtual\fR(8) daemons require privileges. +.IP "\fBChroot (default: y)\fR" +Whether or not the service runs chrooted to the mail queue +directory (pathname is controlled by the \fBqueue_directory\fR +configuration variable in the main.cf file). +.sp +Chroot should not be used with the \fBlocal\fR(8), +\fBpipe\fR(8) and \fBspawn\fR(8) daemons. Although the +\fBproxymap\fR(8) server can run chrooted, doing so defeats +most of the purpose of having that service in the first +place. +.sp +The files in the examples/chroot-setup subdirectory of the +Postfix source archive describe how to set up a Postfix +chroot environment for your type of machine, and +BASIC_CONFIGURATION_README discusses issues related to +running daemons chrooted. +.IP "\fBWakeup time (default: 0)\fR" +Automatically wake up the named service after the specified +number of seconds. The wake up is implemented by connecting +to the service and sending a wake up request. A ? at the +end of the wake up time field requests that wake up events +be sent only to services that are actually being used. +Specify 0 for no automatic wake up. +.sp +The \fBpickup\fR(8), \fBqmgr\fR(8) and \fBflush\fR(8) +daemons require a wake up timer. +.IP "\fBProcess limit (default: $default_process_limit)\fR" +The maximum number of processes that may execute this +service simultaneously. Specify 0 for no process count limit. +.sp +NOTE: Some Postfix services must be configured as a +single-process service (for example, \fBqmgr\fR(8)) and +some services must be configured with no process limit (for +example, \fBcleanup\fR(8)). These limits must not be +changed. +.IP "\fBCommand name + arguments\fR" +The command to be executed. Characters that are special +to the shell such as ">" or "|" have no special meaning +here, and quotes cannot be used to protect arguments +containing whitespace. +.sp +The command name is relative to the Postfix daemon directory +(pathname is controlled by the \fBdaemon_directory\fR +configuration variable). +.sp +The command argument syntax for specific commands is +specified in the respective daemon manual page. +.sp +The following command-line options have the same effect for +all daemon programs: +.RS +.IP \fB-D\fR +Run the daemon under control by the command specified with +the \fBdebugger_command\fR variable in the main.cf +configuration file. See DEBUG_README for hints and tips. +.IP "\fB-o \fIname\fR=\fIvalue\fR" +Override the named main.cf configuration parameter. The +parameter value can refer to other parameters as \fI$name\fR +etc., just like in main.cf. See \fBpostconf\fR(5) for +syntax. +.sp +NOTE 1: do not specify whitespace around the "=". In parameter +values, either avoid whitespace altogether, use commas +instead of spaces, or consider overrides like "-o +name=$override_parameter" with $override_parameter set in +main.cf. +.sp +NOTE 2: Over-zealous use of parameter overrides makes the +Postfix configuration hard to understand and maintain. At +a certain point, it might be easier to configure multiple +instances of Postfix, instead of configuring multiple +personalities via master.cf. +.IP \fB-v\fR +Increase the verbose logging level. Specify multiple \fB-v\fR +options to make a command more verbose. +.SH "SEE ALSO" +.na +.nf +master(8), process manager +postconf(5), configuration parameters +.SH "README FILES" +.na +.nf +.ad +.fi +Use "\fBpostconf readme_directory\fR" or +"\fBpostconf html_directory\fR" to locate this information. +.na +.nf +BASIC_CONFIGURATION_README, basic configuration +DEBUG_README, Postfix debugging +.SH "LICENSE" +.na +.nf +.ad +.fi +The Secure Mailer license must be distributed with this software. +.SH "AUTHOR(S)" +.na +.nf +Initial version by +Magnus Baeck +Lund Institute of Technology +Sweden + +Wietse Venema +IBM T.J. Watson Research +P.O. Box 704 +Yorktown Heights, NY 10598, USA diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index 2f25f165f..e54d11306 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -1053,7 +1053,8 @@ to non-Postfix processes. The TZ variable is needed for sane time keeping on System-V-ish systems. .PP Specify a list of names and/or name=value pairs, separated by -whitespace or comma. +whitespace or comma. The name=value form is supported with +Postfix 2.1 and later. .PP Example: .PP @@ -2836,6 +2837,7 @@ a "type:table" with domains and/or relay hosts on the left-hand side. The right-hand side result from "type:table" lookups is ignored. .PP +This feature is available in Postfix 2.2 and later. .SH smtp_connection_cache_on_demand (default: yes) Temporarily enable SMTP session caching while a destination has a high volume of mail in the active queue. With SMTP connection @@ -2849,10 +2851,14 @@ This feature is available in Postfix 2.2 and later. .SH smtp_connection_cache_reuse_limit (default: 10) When SMTP session caching is enabled, the number of times that an SMTP session is reused before it is closed. +.PP +This feature is available in Postfix 2.2 and later. .SH smtp_connection_cache_time_limit (default: 2s) When SMTP session caching is enabled, the amount of time that an unused SMTP client socket is kept open before it is closed. Do not specify larger values without permission from the remote sites. +.PP +This feature is available in Postfix 2.2 and later. .SH smtp_data_done_timeout (default: 600s) The SMTP client time limit for sending the SMTP ".", and for receiving the server response. @@ -3219,8 +3225,8 @@ smtpd_banner = $myhostname ESMTP $mail_name ($mail_version) .ad .ft R .SH smtpd_client_connection_count_limit (default: 50) -How many simultaneous connections any SMTP client is allowed to -make to the SMTP service. By default, the limit is set it to half +How many simultaneous connections any client is allowed to +make to this service. By default, the limit is set to half the default process limit value. .PP To disable this feature, specify a limit of 0. @@ -3228,21 +3234,11 @@ To disable this feature, specify a limit of 0. WARNING: The purpose of this feature is to limit abuse. It must not be used to regulate legitimate mail traffic. .PP -This feature is not part of the stable Postfix 2.1 release. -.SH smtpd_client_connection_limit_exceptions (default: $mynetworks) -Clients that are excluded from connection count or connection rate -restrictions. -.PP -By default, clients in trusted networks are excluded. Specify a -list of network blocks, hostnames or .domain names (the initial -dot causes the domain to match any name below it). -.PP -This feature is not part of the stable Postfix 2.1 release. +This feature is available in Postfix 2.2 and later. .SH smtpd_client_connection_rate_limit (default: 0) The maximal number of connection attempts any client is allowed to make to this service per time unit. The time unit is specified -with the anvil_rate_time_unit configuration parameter, and defaults -to one minute. +with the anvil_rate_time_unit configuration parameter. .PP By default, a client can make as many connections per time unit as Postfix can accept. @@ -3252,7 +3248,7 @@ To disable this feature, specify a limit of 0. WARNING: The purpose of this feature is to limit abuse. It must not be used to regulate legitimate mail traffic. .PP -This feature is not part of the stable Postfix 2.1 release. +This feature is available in Postfix 2.2 and later. .PP Example: .PP @@ -3263,6 +3259,65 @@ smtpd_client_connection_rate_limit = 1000 .fi .ad .ft R +.SH smtpd_client_event_limit_exceptions (default: $mynetworks) +Clients that are excluded from connection count, connection rate, +message rate or recipient rate restrictions. +.PP +By default, clients in trusted networks are excluded. Specify a +list of network blocks, hostnames or .domain names (the initial +dot causes the domain to match any name below it). +.PP +This feature is available in Postfix 2.2 and later. +.SH smtpd_client_message_rate_limit (default: 0) +The maximal number of message delivery requests that any client is +allowed to make to this service per time unit, regardless of whether +or not Postfix actually accepts those messages. The time unit is +specified with the anvil_rate_time_unit configuration parameter. +.PP +By default, a client can send as many message delivery requests +requests per time unit as Postfix can accept. +.PP +To disable this feature, specify a limit of 0. +.PP +WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +.PP +This feature is available in Postfix 2.2 and later. +.PP +Example: +.PP +.nf +.na +.ft C +smtpd_client_message_rate_limit = 1000 +.fi +.ad +.ft R +.SH smtpd_client_recipient_rate_limit (default: 0) +The maximal number of recipient addresses that any client is allowed +to send to this service per time unit, regardless of whether or not +Postfix actually accepts those recipients. The time unit is specified +with the anvil_rate_time_unit configuration parameter. +.PP +By default, a client can make as many recipient addresses per time +unit as Postfix can accept. +.PP +To disable this feature, specify a limit of 0. +.PP +WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +.PP +This feature is available in Postfix 2.2 and later. +.PP +Example: +.PP +.nf +.na +.ft C +smtpd_client_recipient_rate_limit = 1000 +.fi +.ad +.ft R .SH smtpd_client_restrictions (default: empty) Optional SMTP server access restrictions in the context of a client SMTP connection request. @@ -4572,7 +4627,8 @@ virtual(8) delivery agent will terminate with a fatal error. .SH SEE ALSO .na .nf -postconf(1) postfix configuration maintenance +postconf(1) Postfix configuration parameter maintenance +master(5) Postfix daemon configuration maintenance .SH LICENSE .ad .fi diff --git a/postfix/man/man8/anvil.8 b/postfix/man/man8/anvil.8 index f39f4327a..235f262cc 100644 --- a/postfix/man/man8/anvil.8 +++ b/postfix/man/man8/anvil.8 @@ -4,7 +4,7 @@ .SH NAME anvil \- -Postfix client count and rate management +Postfix client count and request rate management .SH "SYNOPSIS" .na .nf @@ -14,15 +14,15 @@ Postfix client count and rate management .fi The Postfix \fBanvil\fR server maintains short-term statistics to defend against clients that hammer a server with either too -many parallel connections or with too many successive connection -attempts within a configurable time interval. +many parallel connections or with too many successive requests +within a configurable time interval. This server is designed to run under control by the Postfix master server. The \fBanvil\fR server maintains no persistent database. Standard library utilities do not meet Postfix performance and robustness requirements. -.SH "PROTOCOL" +.SH "CONNECTION COUNT/RATE LIMITING" .na .nf .ad @@ -70,7 +70,68 @@ server replies with: .PP .ti +4 \fBstatus=0\fR +.SH "MESSAGE RATE LIMITING" +.na +.nf +.ad +.fi +When a remote client sends a message delivery request, a +message rate limited server should send the following +request to the \fBanvil\fR server: +.PP +.in +4 +\fBrequest=message\fR +.br +\fBident=\fIstring\fR +.in +.PP +This registers a message delivery request for the (service, client) +combination specified with \fBident\fR. The \fBanvil\fR server +answers with the number of message delivery requests per unit time +for that (service, client) combination: +.PP +.in +4 +\fBstatus=0\fR +.br +\fBrate=\fInumber\fR +.in +.PP +In order prevent the anvil server from discarding client +request rates too early or too late, a message rate limited +service should also register connect/disconnect events. +.PP +This feature is available in Postfix 2.2 and later. +.SH "RECIPIENT RATE LIMITING" +.na +.nf +.ad +.fi +When a remote client sends a recipient address, a recipient +rate limited server should send the following request to +the \fBanvil\fR server: +.PP +.in +4 +\fBrequest=recipient\fR +.br +\fBident=\fIstring\fR +.in +.PP +This registers a recipient address for the (service, client) +combination specified with \fBident\fR. The \fBanvil\fR server +answers with the number of recipient addresses per unit time +for that (service, client) combination: +.PP +.in +4 +\fBstatus=0\fR +.br +\fBrate=\fInumber\fR +.in +.PP +In order prevent the anvil server from discarding client +request rates too early or too late, a recipient rate limited +service should also register connect/disconnect events. .PP +This feature is available in Postfix 2.2 and later. .SH "SECURITY" .na .nf @@ -94,6 +155,9 @@ Upon exit, and every \fBanvil_status_update_time\fR seconds, the server logs the maximal count and rate values measured, together with (service, client) information and the time of day associated with those events. +In order to avoid unnecessary overhead, no measurements +are done for activity that isn't concurrency limited or +rate limited. .SH BUGS .ad .fi diff --git a/postfix/man/man8/master.8 b/postfix/man/man8/master.8 index a16437ba6..399f0a47c 100644 --- a/postfix/man/man8/master.8 +++ b/postfix/man/man8/master.8 @@ -8,9 +8,7 @@ Postfix master process .SH "SYNOPSIS" .na .nf -.fi -\fBmaster\fR [\fB-Dtv\fR] [\fB-c \fIconfig_dir\fR] - [\fB-e \fIexit_time\fR] +\fBmaster\fR [\fB-Dtv\fR] [\fB-c \fIconfig_dir\fR] [\fB-e \fIexit_time\fR] .SH DESCRIPTION .ad .fi @@ -25,16 +23,14 @@ configurable number of requests. Exceptions to this rule are the resident queue manager and the resident address verification server. The behavior of the \fBmaster\fR daemon is controlled by the -\fBmaster.cf\fR configuration file. The table specifies zero or -more servers in the \fBUNIX\fR or \fBINET\fR domain, or servers -that take requests from a FIFO. Precise configuration details are -given in the \fBmaster.cf\fR file, and in the manual pages of the -respective daemons. +\fBmaster.cf\fR configuration file, as described in master(5). Options: .IP "\fB-c \fIconfig_dir\fR" Read the \fBmain.cf\fR and \fBmaster.cf\fR configuration files in the named directory instead of the default configuration directory. +This also overrides the configuration files for other Postfix +daemon processes. .IP "\fB-e \fIexit_time\fR" Terminate the master process after \fIexit_time\fR seconds. Child processes terminate at their convenience. @@ -155,7 +151,8 @@ records, so that "smtpd" becomes, for example, "postfix/smtpd". .nf qmgr(8), queue manager verify(8), address verification -postconf(5), configuration parameters +master(5), master.cf configuration file syntax +postconf(5), main.cf configuration parameter syntax syslogd(8), system logging .SH "LICENSE" .na diff --git a/postfix/man/man8/pipe.8 b/postfix/man/man8/pipe.8 index d450e3774..208136367 100644 --- a/postfix/man/man8/pipe.8 +++ b/postfix/man/man8/pipe.8 @@ -135,7 +135,11 @@ shell meta characters by a shell command interpreter. .sp In the command argument vector, the following macros are recognized and replaced with corresponding information from the Postfix queue -manager delivery request: +manager delivery request. +.sp +In addition to the form ${\fIname\fR}, the forms $\fIname\fR and +$(\fIname\fR) are also recognized. Specify \fB$$\fR where a single +\fB$\fR is wanted. .RS .IP \fB${\fBextension\fR}\fR This macro expands to the extension part of a recipient address. @@ -167,6 +171,23 @@ expands into as many command-line arguments as there are recipients. .sp This information is modified by the \fBhqu\fR flags for quoting and case folding. +.IP \fB${\fBsasl_method\fR}\fR +This macro expands to the SASL authentication mechanism used +during the reception of the message. An empty string is passed +if the message has been received without SASL authentication. +.sp +This is available in Postfix 2.2 and later. +.IP \fB${\fBsasl_sender\fR}\fR +This macro expands to the SASL sender name (i.e. the original +submitter as per RFC 2554) used during the reception of the message. +.sp +This is available in Postfix 2.2 and later. +.IP \fB${\fBsasl_username\fR}\fR +This macro expands to the SASL user name used during the reception +of the message. An empty string is passed if the message has been +received without SASL authentication. +.sp +This is available in Postfix 2.2 and later. .IP \fB${\fBsender\fR}\fR This macro expands to the envelope sender address. .sp @@ -184,10 +205,6 @@ into as many command-line arguments as there are recipients. .sp This information is modified by the \fBu\fR flag for case folding. .RE -.PP -In addition to the form ${\fIname\fR}, the forms $\fIname\fR and -$(\fIname\fR) are also recognized. Specify \fB$$\fR where a single -\fB$\fR is wanted. .SH DIAGNOSTICS .ad .fi diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8 index 7d2e46ac2..b44297142 100644 --- a/postfix/man/man8/smtpd.8 +++ b/postfix/man/man8/smtpd.8 @@ -339,16 +339,26 @@ receiving a remote SMTP client request. The maximal number of lines in the Postfix SMTP server command history before it is flushed upon receipt of EHLO, RSET, or end of DATA. .PP -Not available in Postfix version 2.1: +The per SMTP client connection count and request rate limits are +implemented in co-operation with the anvil(8) service, and +are available in Postfix version 2.2 and later. .IP "\fBsmtpd_client_connection_count_limit (50)\fR" -How many simultaneous connections any SMTP client is allowed to -make to the SMTP service. +How many simultaneous connections any client is allowed to +make to this service. .IP "\fBsmtpd_client_connection_rate_limit (0)\fR" The maximal number of connection attempts any client is allowed to make to this service per time unit. -.IP "\fBsmtpd_client_connection_limit_exceptions ($mynetworks)\fR" -Clients that are excluded from connection count or connection rate -restrictions. +.IP "\fBsmtpd_client_message_rate_limit (0)\fR" +The maximal number of message delivery requests that any client is +allowed to make to this service per time unit, regardless of whether +or not Postfix actually accepts those messages. +.IP "\fBsmtpd_client_recipient_rate_limit (0)\fR" +The maximal number of recipient addresses that any client is allowed +to send to this service per time unit, regardless of whether or not +Postfix actually accepts those recipients. +.IP "\fBsmtpd_client_event_limit_exceptions ($mynetworks)\fR" +Clients that are excluded from connection count, connection rate, +message rate or recipient rate restrictions. .SH "TARPIT CONTROLS" .na .nf @@ -601,6 +611,7 @@ records, so that "smtpd" becomes, for example, "postfix/smtpd". .SH "SEE ALSO" .na .nf +anvil(8), client count and request rate management cleanup(8), message canonicalization trivial-rewrite(8), address resolver verify(8), address verification service diff --git a/postfix/mantools/makemanidx b/postfix/mantools/makemanidx new file mode 100755 index 000000000..39afc08fb --- /dev/null +++ b/postfix/mantools/makemanidx @@ -0,0 +1,97 @@ +#!/bin/sh + +cat < + + + + + +Postfix Manual Pages + + + + + + + +

    Postfix +Manual Pages

    + +
    + +

    Information for new Postfix users

    + +

    New Postfix users should first look at the following introductory +documents. These introductions are hyperlinked to more advanced +documents and to UNIX-style manual pages. The UNIX-style manual +pages are intended for people who are already familiar with Postfix. +

    + + + +

    Postfix manual page organization

    + +

    Each Postfix manual page is numbered after a section of the +UNIX manual: examples are mailq(1) or access(5). Unfortunately, +the organization of manual pages depends on the UNIX version being +used. Postfix documentation assumes the following convention: +

    + +
    + + + + + + + + + + + + + + + +
    Section Topic

    1 Commands
    3 Library routines
    5 File formats
    8 Daemons
    + +
    + +EOF + +srctoman "$@" | awk ' + +NR == 1,/SH "*SEE ALSO"*/ { next } + +/^Other:$/ { print ul; exit } + +/^[A-Z].*:$/ { print ul "

    ", $0, "

    \n\n
      \n\n"; ul = "
    \n\n" } + +/^[a-z][a-z0-9_]+\(/ { print "
  • ", $0, "\n" } + +' | sed 's;: $; ;' + +cat < + + +EOF diff --git a/postfix/mantools/makereadme b/postfix/mantools/makereadme index 16f1d7015..e6a063d90 100755 --- a/postfix/mantools/makereadme +++ b/postfix/mantools/makereadme @@ -6,6 +6,7 @@ sed ' s/<\/td[^>]*>//g s/"\([A-Z_]*\)\.html">/&\1:/ s/All main.cf parameters/postconf(5): &/ + /All Postfix manual pages/d ' "$@" diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink index 7f7a8dc7c..b9abb42cc 100755 --- a/postfix/mantools/postlink +++ b/postfix/mantools/postlink @@ -118,7 +118,7 @@ while (<>) { s;\bcommand_time_limit\b;$&;g; s;\bconfig_direc[-]*\n*[ ]*tory\b;$&;g; s;\bcon[-]*\n*[ ]*tent_filter\b;$&;g; - s;\bdaemon_directory\b;$&;g; + s;\bdae[-]*\n*[ ]*mon_directory\b;$&;g; s;\bdaemon_timeout\b;$&;g; s;\bdebug_peer_level\b;$&;g; s;\bdebug_peer_list\b;$&;g; @@ -357,8 +357,10 @@ while (<>) { s;\bsmtpd_autho[-]*\n*[ ]*rized_xforward_hosts\b;$&;g; s;\bsmtpd_banner\b;$&;g; s;\bsmtpd_client_connection_count_limit\b;$&;g; - s;\bsmtpd_client_connection_limit_exceptions\b;$&;g; + s;\bsmtpd_client_event_limit_exceptions\b;$&;g; s;\bsmtpd_client_connection_rate_limit\b;$&;g; + s;\bsmtpd_client_message_rate_limit\b;$&;g; + s;\bsmtpd_client_recipient_rate_limit\b;$&;g; s;\bsmtpd_client_restrictions\b;$&;g; s;\bsmtpd_data_restrictions\b;$&;g; s;\bsmtpd_delay_reject\b;$&;g; @@ -490,11 +492,12 @@ while (<>) { s/[]*canonical[<\/bB>]*\(5\)/$&<\/a>/g; s/[]*etrn[<\/bB>]*\(5\)/$&<\/a>/g; s/[]*ldap[<\/bBiI>]*_[<\/iIbB>]*table[<\/bB>]*\(5\)/$&<\/a>/g; + s/[]*mas[-<\/bB>]*\n* *[]*ter[<\/bB>]*\(5\)/$&<\/a>/g; s/[]*mysql[<\/bBiI>]*_[<\/iIbB>]*table[<\/bB>]*\(5\)/$&<\/a>/g; s/[]*pcre[<\/bBiI>]*_[<\/iIbB>]*table[<\/bB>]*\(5\)/$&<\/a>/g; s/[]*pgsql[<\/bBiI>]*_[<\/iIbB>]*table[<\/bB>]*\(5\)/$&<\/a>/g; s/[]*postconf[<\/bB>]*\(5\)/$&<\/a>/g; - s/[]*proxymap[<\/bB>]*\(8\)/$&<\/a>/g; + s/[]*prox[-<\/bB>]*\n*[ ]*ymap[<\/bB>]*\(8\)/$&<\/a>/g; s/[]*reg[-<\/bB>]*\n*[ ]*exp[<\/bBiI>]*_[<\/iIbB>]*table[<\/bB>]*\(5\)/$&<\/a>/g; s/[]*relocated[<\/bB>]*\(5\)/$&<\/a>/g; s/[]*scache[<\/bB>]*\(8\)/$&<\/a>/g; diff --git a/postfix/proto/access b/postfix/proto/access index 46c1fbe32..f5825882d 100644 --- a/postfix/proto/access +++ b/postfix/proto/access @@ -178,7 +178,7 @@ # .sp # Note: use "\fBpostsuper -r\fR" to release mail that was kept on # hold for a significant fraction of \fB$maximal_queue_lifetime\fR -# or \fB$bounce_queue_lifetime\fR or longer. +# or \fB$bounce_queue_lifetime\fR, or longer. # .sp # Note: this action currently affects all recipients of the message. # .sp diff --git a/postfix/proto/header_checks b/postfix/proto/header_checks index d5b883c51..db78644d2 100644 --- a/postfix/proto/header_checks +++ b/postfix/proto/header_checks @@ -161,7 +161,7 @@ # .sp # Note: use "\fBpostsuper -r\fR" to release mail that was kept on # hold for a significant fraction of \fB$maximal_queue_lifetime\fR -# or \fB$bounce_queue_lifetime\fR or longer. +# or \fB$bounce_queue_lifetime\fR, or longer. # .sp # Note: this action affects all recipients of the message. # .sp diff --git a/postfix/proto/ldap_table b/postfix/proto/ldap_table index 1aa612797..3c840c309 100644 --- a/postfix/proto/ldap_table +++ b/postfix/proto/ldap_table @@ -87,7 +87,7 @@ # .IP "\fBserver_host (default: localhost)\fR" # The name of the host running the LDAP server, e.g. # .ti +4 -# server_host = ldap.your.com +# server_host = ldap.example.com # # Depending on the LDAP client library you're using, it should # be possible to specify multiple servers here, with the library @@ -95,12 +95,14 @@ # be possible to give each server in the list a different port # (overriding \fBserver_port\fR below), by naming them like # .ti +4 -# server_host = ldap.your.com:1444 +# server_host = ldap.example.com:1444 # # With OpenLDAP, a (list of) LDAP URLs can be used to specify both # the hostname(s) and the port(s): # .ti +4 -# server_host = ldap://ldap.your.com:1444 +# server_host = ldap://ldap.example.com:1444 +# .ti +8 +# ldap://ldap2.example.com:1444 # # All LDAP URLs accepted by the OpenLDAP library are supported, # including connections over UNIX domain sockets, and LDAP SSL @@ -108,8 +110,8 @@ # for SSL): # .ti +4 # server_host = ldapi://%2Fsome%2Fpath -# .ti +4 -# server_host = ldaps://ldap.your.com:636 +# .ti +8 +# ldaps://ldap.example.com:636 # .IP "\fBserver_port (default: 389)\fR" # The port the LDAP server listens on, e.g. # .ti +4 @@ -320,7 +322,7 @@ # LDAP SSL service can be requested by using a LDAP SSL URL # in the server_host parameter: # .ti +4 -# server_host = ldaps://ldap.your.com:636 +# server_host = ldaps://ldap.example.com:636 # # STARTTLS can be turned on with the start_tls parameter: # .ti +4 diff --git a/postfix/proto/master b/postfix/proto/master new file mode 100644 index 000000000..e7aa5fa91 --- /dev/null +++ b/postfix/proto/master @@ -0,0 +1,201 @@ +#++ +# NAME +# master 5 +# SUMMARY +# Postfix master process configuration file format +# DESCRIPTION +# The Postfix mail system is implemented by small number of +# (mostly) client commands that are invoked by users, and by +# a larger number of services that run in the background. +# +# Postfix services run under control of the \fBmaster\fR(8) +# process. The master.cf configuration file defines how a +# client program connects to a service, and what daemon +# program runs when a service is requested. Most daemon +# processes are short-lived and terminate after serving +# \fBmax_use\fR clients, or after inactivity for \fBmax_idle\fR +# or more units of time. +# +# All daemons specified here must speak a Postfix-internal +# protocol. In order to execute non-Postfix software use the +# \fBlocal\fR(8), \fBpipe\fR(8) or \fBspawn\fR(8) services, or +# run the server under control by \fBinetd\fR(8) or equivalent. +# .PP +# Changes in master.cf requires that "\fBpostfix reload\fR" be +# executed in order to reload the configuration. +# SYNTAX +# .ad +# .fi +# The general format of the master.cf file is as follows: +# .IP \(bu +# Each logical line defines a single Postfix service. +# Each service is identified by its name and type as described +# below. When multiple lines specify the same service name +# and type, only the last one is remembered. Otherwise, the +# order of master.cf service definitions does not matter. +# .IP \(bu +# Empty lines and whitespace-only lines are ignored, as are +# lines whose first non-whitespace character is a `#'. +# .IP \(bu +# A logical line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# .PP +# Each logical line consists of eight fields separated by +# whitespace. These are described below in the order as they +# appear in the master.cf file. +# +# Where applicable a field of "-" requests that the built-in +# default value be used. For boolean fields specify "y" or +# "n" to override the default value. +# .IP "\fBService name\fR" +# The service name syntax depends on the service type as +# described next. +# .IP "\fBService type\fR" +# Specify one of the following service types: +# .RS +# .IP \fBinet\fR +# The service listens on a TCP/IP socket and is therefore +# accessible via the network. +# +# The service name is specified as \fIhost:port\fR, denoting +# the host and port on which new connections should be +# accepted. The host part (and colon) may be omitted. Either +# host or port may be given in symbolic form (host or service +# name) or in numeric form (IP address or port number). +# .sp +# Examples: a service name of \fB127.0.0.1:smtp\fR receives +# mail via the loopback interface only; and a service name +# of \fB10025\fR accepts connections on TCP port 10025 via +# all interfaces configured with the \fBinet_interfaces\fR +# parameter. +# .IP \fBunix\fR +# The service listens on a UNIX-domain socket and is accessible +# for local clients only. +# +# The service name is a pathname relative to the Postfix +# queue directory (pathname controlled with the \fBqueue_directory\fR +# configuration parameter in main.cf). +# .sp +# On Solaris systems the \fBunix\fR type is implemented with +# streams sockets. +# .IP \fBfifo\fR +# The service listens on a FIFO (named pipe) and is accessible +# for local clients only. +# +# The service name is a pathname relative to the Postfix +# queue directory (pathname controlled with the \fBqueue_directory\fR +# configuration parameter in main.cf). +# .RE +# .IP "\fBPrivate (default: y)\fR" +# Whether or not access is restricted to the mail system. +# Internet (type \fBinet\fR) services can't be private. +# .IP "\fBUnprivileged (default: y)\fR" +# Whether the service runs with root privileges or as the +# owner of the Postfix system (the owner name is controlled +# by the \fBmail_owner\fR configuration variable in the +# main.cf file). +# .sp +# The \fBlocal\fR(8), \fBpipe\fR(8), \fBspawn\fR(8), and +# \fBvirtual\fR(8) daemons require privileges. +# .IP "\fBChroot (default: y)\fR" +# Whether or not the service runs chrooted to the mail queue +# directory (pathname is controlled by the \fBqueue_directory\fR +# configuration variable in the main.cf file). +# .sp +# Chroot should not be used with the \fBlocal\fR(8), +# \fBpipe\fR(8) and \fBspawn\fR(8) daemons. Although the +# \fBproxymap\fR(8) server can run chrooted, doing so defeats +# most of the purpose of having that service in the first +# place. +# .sp +# The files in the examples/chroot-setup subdirectory of the +# Postfix source archive describe how to set up a Postfix +# chroot environment for your type of machine, and +# BASIC_CONFIGURATION_README discusses issues related to +# running daemons chrooted. +# .IP "\fBWakeup time (default: 0)\fR" +# Automatically wake up the named service after the specified +# number of seconds. The wake up is implemented by connecting +# to the service and sending a wake up request. A ? at the +# end of the wake up time field requests that wake up events +# be sent only to services that are actually being used. +# Specify 0 for no automatic wake up. +# .sp +# The \fBpickup\fR(8), \fBqmgr\fR(8) and \fBflush\fR(8) +# daemons require a wake up timer. +# .IP "\fBProcess limit (default: $default_process_limit)\fR" +# The maximum number of processes that may execute this +# service simultaneously. Specify 0 for no process count limit. +# .sp +# NOTE: Some Postfix services must be configured as a +# single-process service (for example, \fBqmgr\fR(8)) and +# some services must be configured with no process limit (for +# example, \fBcleanup\fR(8)). These limits must not be +# changed. +# .IP "\fBCommand name + arguments\fR" +# The command to be executed. Characters that are special +# to the shell such as ">" or "|" have no special meaning +# here, and quotes cannot be used to protect arguments +# containing whitespace. +# .sp +# The command name is relative to the Postfix daemon directory +# (pathname is controlled by the \fBdaemon_directory\fR +# configuration variable). +# .sp +# The command argument syntax for specific commands is +# specified in the respective daemon manual page. +# .sp +# The following command-line options have the same effect for +# all daemon programs: +# .RS +# .IP \fB-D\fR +# Run the daemon under control by the command specified with +# the \fBdebugger_command\fR variable in the main.cf +# configuration file. See DEBUG_README for hints and tips. +# .IP "\fB-o \fIname\fR=\fIvalue\fR" +# Override the named main.cf configuration parameter. The +# parameter value can refer to other parameters as \fI$name\fR +# etc., just like in main.cf. See \fBpostconf\fR(5) for +# syntax. +# .sp +# NOTE 1: do not specify whitespace around the "=". In parameter +# values, either avoid whitespace altogether, use commas +# instead of spaces, or consider overrides like "-o +# name=$override_parameter" with $override_parameter set in +# main.cf. +# .sp +# NOTE 2: Over-zealous use of parameter overrides makes the +# Postfix configuration hard to understand and maintain. At +# a certain point, it might be easier to configure multiple +# instances of Postfix, instead of configuring multiple +# personalities via master.cf. +# .IP \fB-v\fR +# Increase the verbose logging level. Specify multiple \fB-v\fR +# options to make a command more verbose. +# SEE ALSO +# master(8), process manager +# postconf(5), configuration parameters +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# BASIC_CONFIGURATION_README, basic configuration +# DEBUG_README, Postfix debugging +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# Initial version by +# Magnus Baeck +# Lund Institute of Technology +# Sweden +# +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +#-- diff --git a/postfix/proto/postconf.man.epilog b/postfix/proto/postconf.man.epilog index 67f4c3f8f..fedf47b1e 100644 --- a/postfix/proto/postconf.man.epilog +++ b/postfix/proto/postconf.man.epilog @@ -1,7 +1,8 @@ .SH SEE ALSO .na .nf -postconf(1) postfix configuration maintenance +postconf(1) Postfix configuration parameter maintenance +master(5) Postfix daemon configuration maintenance .SH LICENSE .ad .fi diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index 776577656..2c0388fad 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -1140,7 +1140,8 @@ time keeping on System-V-ish systems.

    Specify a list of names and/or name=value pairs, separated by -whitespace or comma. +whitespace or comma. The name=value form is supported with +Postfix 2.1 and later.

    @@ -3244,12 +3245,16 @@ an unused SMTP client socket is kept open before it is closed. Do not specify larger values without permission from the remote sites.

    +

    This feature is available in Postfix 2.2 and later.

    + %PARAM smtp_connection_cache_reuse_limit 10

    When SMTP session caching is enabled, the number of times that an SMTP session is reused before it is closed.

    +

    This feature is available in Postfix 2.2 and later.

    + %PARAM smtp_connection_cache_destinations

    Permanently enable SMTP connection caching for the specified @@ -3280,7 +3285,7 @@ ignored. -

    +

    This feature is available in Postfix 2.2 and later.

    %PARAM smtp_connection_cache_on_demand yes @@ -3939,8 +3944,8 @@ smtpd_banner = $myhostname ESMTP $mail_name ($mail_version) %PARAM smtpd_client_connection_count_limit 50

    -How many simultaneous connections any SMTP client is allowed to -make to the SMTP service. By default, the limit is set it to half +How many simultaneous connections any client is allowed to +make to this service. By default, the limit is set to half the default process limit value.

    @@ -3954,14 +3959,14 @@ not be used to regulate legitimate mail traffic.

    -This feature is not part of the stable Postfix 2.1 release. +This feature is available in Postfix 2.2 and later.

    -%PARAM smtpd_client_connection_limit_exceptions $mynetworks +%PARAM smtpd_client_event_limit_exceptions $mynetworks

    -Clients that are excluded from connection count or connection rate -restrictions. +Clients that are excluded from connection count, connection rate, +message rate or recipient rate restrictions.

    @@ -3971,7 +3976,7 @@ dot causes the domain to match any name below it).

    -This feature is not part of the stable Postfix 2.1 release. +This feature is available in Postfix 2.2 and later.

    %PARAM smtpd_client_connection_rate_limit 0 @@ -3979,8 +3984,7 @@ This feature is not part of the stable Postfix 2.1 release.

    The maximal number of connection attempts any client is allowed to make to this service per time unit. The time unit is specified -with the anvil_rate_time_unit configuration parameter, and defaults -to one minute. +with the anvil_rate_time_unit configuration parameter.

    @@ -3998,7 +4002,7 @@ not be used to regulate legitimate mail traffic.

    -This feature is not part of the stable Postfix 2.1 release. +This feature is available in Postfix 2.2 and later.

    @@ -4009,6 +4013,76 @@ Example: smtpd_client_connection_rate_limit = 1000 +%PARAM smtpd_client_message_rate_limit 0 + +

    +The maximal number of message delivery requests that any client is +allowed to make to this service per time unit, regardless of whether +or not Postfix actually accepts those messages. The time unit is +specified with the anvil_rate_time_unit configuration parameter. +

    + +

    +By default, a client can send as many message delivery requests +requests per time unit as Postfix can accept. +

    + +

    +To disable this feature, specify a limit of 0. +

    + +

    +WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +

    + +

    +This feature is available in Postfix 2.2 and later. +

    + +

    +Example: +

    + +
    +smtpd_client_message_rate_limit = 1000
    +
    + +%PARAM smtpd_client_recipient_rate_limit 0 + +

    +The maximal number of recipient addresses that any client is allowed +to send to this service per time unit, regardless of whether or not +Postfix actually accepts those recipients. The time unit is specified +with the anvil_rate_time_unit configuration parameter. +

    + +

    +By default, a client can make as many recipient addresses per time +unit as Postfix can accept. +

    + +

    +To disable this feature, specify a limit of 0. +

    + +

    +WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +

    + +

    +This feature is available in Postfix 2.2 and later. +

    + +

    +Example: +

    + +
    +smtpd_client_recipient_rate_limit = 1000
    +
    + %PARAM smtpd_client_restrictions

    diff --git a/postfix/src/anvil/anvil.c b/postfix/src/anvil/anvil.c index 0968e2270..cd541253e 100644 --- a/postfix/src/anvil/anvil.c +++ b/postfix/src/anvil/anvil.c @@ -2,21 +2,21 @@ /* NAME /* anvil 8 /* SUMMARY -/* Postfix client count and rate management +/* Postfix client count and request rate management /* SYNOPSIS /* \fBanvil\fR [generic Postfix daemon options] /* DESCRIPTION /* The Postfix \fBanvil\fR server maintains short-term statistics /* to defend against clients that hammer a server with either too -/* many parallel connections or with too many successive connection -/* attempts within a configurable time interval. +/* many parallel connections or with too many successive requests +/* within a configurable time interval. /* This server is designed to run under control by the Postfix /* master server. /* /* The \fBanvil\fR server maintains no persistent database. Standard /* library utilities do not meet Postfix performance and robustness /* requirements. -/* PROTOCOL +/* CONNECTION COUNT/RATE LIMITING /* .ad /* .fi /* When a remote client connects, a connection count (or rate) limited @@ -62,7 +62,64 @@ /* .PP /* .ti +4 /* \fBstatus=0\fR +/* MESSAGE RATE LIMITING +/* .ad +/* .fi +/* When a remote client sends a message delivery request, a +/* message rate limited server should send the following +/* request to the \fBanvil\fR server: +/* .PP +/* .in +4 +/* \fBrequest=message\fR +/* .br +/* \fBident=\fIstring\fR +/* .in /* .PP +/* This registers a message delivery request for the (service, client) +/* combination specified with \fBident\fR. The \fBanvil\fR server +/* answers with the number of message delivery requests per unit time +/* for that (service, client) combination: +/* .PP +/* .in +4 +/* \fBstatus=0\fR +/* .br +/* \fBrate=\fInumber\fR +/* .in +/* .PP +/* In order prevent the anvil server from discarding client +/* request rates too early or too late, a message rate limited +/* service should also register connect/disconnect events. +/* .PP +/* This feature is available in Postfix 2.2 and later. +/* RECIPIENT RATE LIMITING +/* .ad +/* .fi +/* When a remote client sends a recipient address, a recipient +/* rate limited server should send the following request to +/* the \fBanvil\fR server: +/* .PP +/* .in +4 +/* \fBrequest=recipient\fR +/* .br +/* \fBident=\fIstring\fR +/* .in +/* .PP +/* This registers a recipient address for the (service, client) +/* combination specified with \fBident\fR. The \fBanvil\fR server +/* answers with the number of recipient addresses per unit time +/* for that (service, client) combination: +/* .PP +/* .in +4 +/* \fBstatus=0\fR +/* .br +/* \fBrate=\fInumber\fR +/* .in +/* .PP +/* In order prevent the anvil server from discarding client +/* request rates too early or too late, a recipient rate limited +/* service should also register connect/disconnect events. +/* .PP +/* This feature is available in Postfix 2.2 and later. /* SECURITY /* .ad /* .fi @@ -82,6 +139,9 @@ /* seconds, the server logs the maximal count and rate values measured, /* together with (service, client) information and the time of day /* associated with those events. +/* In order to avoid unnecessary overhead, no measurements +/* are done for activity that isn't concurrency limited or +/* rate limited. /* BUGS /* Systems behind network address translating routers or proxies /* appear to have the same client address and can run into connection @@ -203,6 +263,14 @@ static int max_rate; static char *max_rate_user; static time_t max_rate_time; +static int max_mail; +static char *max_mail_user; +static time_t max_mail_time; + +static int max_rcpt; +static char *max_rcpt_user; +static time_t max_rcpt_time; + /* * Remote connection state, one instance for each (service, client) pair. */ @@ -210,6 +278,8 @@ typedef struct { char *ident; /* lookup key */ int count; /* connection count */ int rate; /* connection rate */ + int mail; /* message rate */ + int rcpt; /* recipient rate */ time_t start; /* time of first rate sample */ } ANVIL_REMOTE; @@ -242,6 +312,8 @@ typedef struct { (remote)->ident = mystrdup(id); \ (remote)->count = 1; \ (remote)->rate = 1; \ + (remote)->mail = 0; \ + (remote)->rcpt = 0; \ (remote)->start = event_time(); \ } while(0) @@ -260,6 +332,8 @@ typedef struct { time_t _now = event_time(); \ if ((remote)->start + var_anvil_time_unit < _now) { \ (remote)->rate = 1; \ + (remote)->mail = 0; \ + (remote)->rcpt = 0; \ (remote)->start = _now; \ } else if ((remote)->rate < INT_MAX) { \ (remote)->rate += 1; \ @@ -269,6 +343,32 @@ typedef struct { (remote)->count++; \ } while(0) +#define ANVIL_ADD_MAIL(remote) \ + do { \ + time_t _now = event_time(); \ + if ((remote)->start + var_anvil_time_unit < _now) { \ + (remote)->rate = 0; \ + (remote)->mail = 1; \ + (remote)->rcpt = 0; \ + (remote)->start = _now; \ + } else if ((remote)->mail < INT_MAX) { \ + (remote)->mail += 1; \ + } \ + } while(0) + +#define ANVIL_ADD_RCPT(remote) \ + do { \ + time_t _now = event_time(); \ + if ((remote)->start + var_anvil_time_unit < _now) { \ + (remote)->rate = 0; \ + (remote)->mail = 0; \ + (remote)->rcpt = 1; \ + (remote)->start = _now; \ + } else if ((remote)->rcpt < INT_MAX) { \ + (remote)->rcpt += 1; \ + } \ + } while(0) + /* Drop connection from (service, client) state. */ #define ANVIL_REMOTE_DROP_ONE(remote) \ @@ -371,6 +471,8 @@ static void anvil_remote_lookup(VSTREAM *client_stream, const char *ident) ATTR_TYPE_STR, ANVIL_ATTR_IDENT, ht[0]->key, ATTR_TYPE_NUM, ANVIL_ATTR_COUNT, anvil_remote->count, ATTR_TYPE_NUM, ANVIL_ATTR_RATE, anvil_remote->rate, + ATTR_TYPE_NUM, ANVIL_ATTR_MAIL, anvil_remote->mail, + ATTR_TYPE_NUM, ANVIL_ATTR_RCPT, anvil_remote->rcpt, ATTR_TYPE_END); } attr_print_plain(client_stream, ATTR_FLAG_NONE, ATTR_TYPE_END); @@ -381,23 +483,27 @@ static void anvil_remote_lookup(VSTREAM *client_stream, const char *ident) ATTR_TYPE_NUM, ANVIL_ATTR_STATUS, ANVIL_STAT_FAIL, ATTR_TYPE_NUM, ANVIL_ATTR_COUNT, 0, ATTR_TYPE_NUM, ANVIL_ATTR_RATE, 0, + ATTR_TYPE_NUM, ANVIL_ATTR_MAIL, 0, + ATTR_TYPE_NUM, ANVIL_ATTR_RCPT, 0, ATTR_TYPE_END); } else { attr_print_plain(client_stream, ATTR_FLAG_NONE, ATTR_TYPE_NUM, ANVIL_ATTR_STATUS, ANVIL_STAT_OK, ATTR_TYPE_NUM, ANVIL_ATTR_COUNT, anvil_remote->count, ATTR_TYPE_NUM, ANVIL_ATTR_RATE, anvil_remote->rate, + ATTR_TYPE_NUM, ANVIL_ATTR_MAIL, anvil_remote->mail, + ATTR_TYPE_NUM, ANVIL_ATTR_RCPT, anvil_remote->rcpt, ATTR_TYPE_END); } } -/* anvil_remote_connect - report connection event, query address status */ +/* anvil_remote_conn_update - instantiate or update connection info */ -static void anvil_remote_connect(VSTREAM *client_stream, const char *ident) +static ANVIL_REMOTE *anvil_remote_conn_update(VSTREAM *client_stream, const char *ident) { ANVIL_REMOTE *anvil_remote; ANVIL_LOCAL *anvil_local; - char *myname = "anvil_remote_connect"; + char *myname = "anvil_remote_conn_update"; if (msg_verbose) msg_info("%s fd=%d stream=0x%lx ident=%s", @@ -435,6 +541,20 @@ static void anvil_remote_connect(VSTREAM *client_stream, const char *ident) msg_info("%s: anvil_local 0x%lx", myname, (unsigned long) anvil_local); + return (anvil_remote); +} + +/* anvil_remote_connect - report connection event, query address status */ + +static void anvil_remote_connect(VSTREAM *client_stream, const char *ident) +{ + ANVIL_REMOTE *anvil_remote; + + /* + * Update or instantiate connection info. + */ + anvil_remote = anvil_remote_conn_update(client_stream, ident); + /* * Respond to the local client. */ @@ -469,6 +589,80 @@ static void anvil_remote_connect(VSTREAM *client_stream, const char *ident) } } +/* anvil_remote_mail - register message delivery request */ + +static void anvil_remote_mail(VSTREAM *client_stream, const char *ident) +{ + ANVIL_REMOTE *anvil_remote; + + /* + * Be prepared for "postfix reload" after "connect". + */ + if ((anvil_remote = + (ANVIL_REMOTE *) htable_find(anvil_remote_map, ident)) == 0) + anvil_remote = anvil_remote_conn_update(client_stream, ident); + + /* + * Update message delivery request rate and respond to local client. + */ + ANVIL_ADD_MAIL(anvil_remote); + attr_print_plain(client_stream, ATTR_FLAG_NONE, + ATTR_TYPE_NUM, ANVIL_ATTR_STATUS, ANVIL_STAT_OK, + ATTR_TYPE_NUM, ANVIL_ATTR_RATE, anvil_remote->mail, + ATTR_TYPE_END); + + /* + * Update local statistics. + */ + if (anvil_remote->mail > max_mail) { + max_mail = anvil_remote->mail; + if (max_mail_user == 0) { + max_mail_user = mystrdup(anvil_remote->ident); + } else if (!STREQ(max_mail_user, anvil_remote->ident)) { + myfree(max_mail_user); + max_mail_user = mystrdup(anvil_remote->ident); + } + max_mail_time = event_time(); + } +} + +/* anvil_remote_rcpt - register recipient address event */ + +static void anvil_remote_rcpt(VSTREAM *client_stream, const char *ident) +{ + ANVIL_REMOTE *anvil_remote; + + /* + * Be prepared for "postfix reload" after "connect". + */ + if ((anvil_remote = + (ANVIL_REMOTE *) htable_find(anvil_remote_map, ident)) == 0) + anvil_remote = anvil_remote_conn_update(client_stream, ident); + + /* + * Update recipient address rate and respond to local client. + */ + ANVIL_ADD_RCPT(anvil_remote); + attr_print_plain(client_stream, ATTR_FLAG_NONE, + ATTR_TYPE_NUM, ANVIL_ATTR_STATUS, ANVIL_STAT_OK, + ATTR_TYPE_NUM, ANVIL_ATTR_RATE, anvil_remote->rcpt, + ATTR_TYPE_END); + + /* + * Update local statistics. + */ + if (anvil_remote->rcpt > max_rcpt) { + max_rcpt = anvil_remote->rcpt; + if (max_rcpt_user == 0) { + max_rcpt_user = mystrdup(anvil_remote->ident); + } else if (!STREQ(max_rcpt_user, anvil_remote->ident)) { + myfree(max_rcpt_user); + max_rcpt_user = mystrdup(anvil_remote->ident); + } + max_rcpt_time = event_time(); + } +} + /* anvil_remote_disconnect - report disconnect event */ static void anvil_remote_disconnect(VSTREAM *client_stream, const char *ident) @@ -562,6 +756,10 @@ static void anvil_service(VSTREAM *client_stream, char *unused_service, char **a ATTR_TYPE_END) == 2) { if (STREQ(STR(request), ANVIL_REQ_CONN)) { anvil_remote_connect(client_stream, STR(ident)); + } else if (STREQ(STR(request), ANVIL_REQ_MAIL)) { + anvil_remote_mail(client_stream, STR(ident)); + } else if (STREQ(STR(request), ANVIL_REQ_RCPT)) { + anvil_remote_rcpt(client_stream, STR(ident)); } else if (STREQ(STR(request), ANVIL_REQ_DISC)) { anvil_remote_disconnect(client_stream, STR(ident)); } else if (STREQ(STR(request), ANVIL_REQ_LOOKUP)) { @@ -621,6 +819,18 @@ static void anvil_status_dump(char *unused_name, char **unused_argv) max_count, max_count_user, ctime(&max_count_time) + 4); max_count = 0; } + if (max_mail > 1) { + msg_info("statistics: max message rate %d/%ds for (%s) at %.15s", + max_mail, var_anvil_time_unit, + max_mail_user, ctime(&max_mail_time) + 4); + max_mail = 0; + } + if (max_rcpt > 1) { + msg_info("statistics: max recipient rate %d/%ds for (%s) at %.15s", + max_rcpt, var_anvil_time_unit, + max_rcpt_user, ctime(&max_rcpt_time) + 4); + max_rcpt = 0; + } } /* anvil_status_update - log and reset extreme usage periodically */ diff --git a/postfix/src/global/anvil_clnt.c b/postfix/src/global/anvil_clnt.c index 3ff1556db..cfa84550d 100644 --- a/postfix/src/global/anvil_clnt.c +++ b/postfix/src/global/anvil_clnt.c @@ -19,18 +19,32 @@ /* int *count; /* int *rate; /* +/* int anvil_clnt_mail(anvil_clnt, service, addr, msgs) +/* ANVIL_CLNT *anvil_clnt; +/* const char *service; +/* const char *addr; +/* int *msgs; +/* +/* int anvil_clnt_rcpt(anvil_clnt, service, addr, rcpts) +/* ANVIL_CLNT *anvil_clnt; +/* const char *service; +/* const char *addr; +/* int *rcpts; +/* /* int anvil_clnt_disconnect(anvil_clnt, service, addr) /* ANVIL_CLNT *anvil_clnt; /* const char *service; /* const char *addr; /* /* int anvil_clnt_lookup(anvil_clnt, service, addr, -/* count, rate) +/* count, rate, msgs, rcpts) /* ANVIL_CLNT *anvil_clnt; /* const char *service; /* const char *addr; /* int *count; /* int *rate; +/* int *msgs; +/* int *rcpts; /* DESCRIPTION /* anvil_clnt_create() instantiates an anvil service client endpoint. /* @@ -38,6 +52,12 @@ /* client has connected, and returns the current connection /* count and connection rate for that client. /* +/* anvil_clnt_mail() registers a MAIL FROM event and returns +/* the current MAIL FROM rate for the specified client. +/* +/* anvil_clnt_rcpt() registers a RCPT TO event and returns +/* the current RCPT TO rate for the specified client. +/* /* anvil_clnt_disconnect() informs the anvil server that a /* client has disconnected. /* @@ -59,6 +79,12 @@ /* .IP rate /* Pointer to storage for the current connection rate for this /* remote client. +/* .IP msgs +/* Pointer to storage for the current message rate for this +/* remote client. +/* .IP rcpts +/* Pointer to storage for the current recipient rate for this +/* remote client. /* DIAGNOSTICS /* anvil_clnt_connect() and anvil_clnt_disconnect() return /* ANVIL_STAT_OK in case of success, ANVIL_STAT_FAIL otherwise @@ -120,15 +146,16 @@ ANVIL_CLNT *anvil_clnt_create(void) /* anvil_clnt_free - destroy connection rate service client */ -void anvil_clnt_free(ANVIL_CLNT * anvil_clnt) +void anvil_clnt_free(ANVIL_CLNT *anvil_clnt) { attr_clnt_free((ATTR_CLNT *) anvil_clnt); } /* anvil_clnt_lookup - status query */ -int anvil_clnt_lookup(ANVIL_CLNT * anvil_clnt, const char *service, - const char *addr, int *count, int *rate) +int anvil_clnt_lookup(ANVIL_CLNT *anvil_clnt, const char *service, + const char *addr, int *count, int *rate, + int *msgs, int *rcpts) { char *ident = ANVIL_IDENT(service, addr); int status; @@ -142,7 +169,9 @@ int anvil_clnt_lookup(ANVIL_CLNT * anvil_clnt, const char *service, ATTR_TYPE_NUM, ANVIL_ATTR_STATUS, &status, ATTR_TYPE_NUM, ANVIL_ATTR_COUNT, count, ATTR_TYPE_NUM, ANVIL_ATTR_RATE, rate, - ATTR_TYPE_END) != 3) + ATTR_TYPE_NUM, ANVIL_ATTR_MAIL, msgs, + ATTR_TYPE_NUM, ANVIL_ATTR_RCPT, rcpts, + ATTR_TYPE_END) != 5) status = ANVIL_STAT_FAIL; else if (status != ANVIL_STAT_OK) status = ANVIL_STAT_FAIL; @@ -152,7 +181,7 @@ int anvil_clnt_lookup(ANVIL_CLNT * anvil_clnt, const char *service, /* anvil_clnt_connect - heads-up and policy query */ -int anvil_clnt_connect(ANVIL_CLNT * anvil_clnt, const char *service, +int anvil_clnt_connect(ANVIL_CLNT *anvil_clnt, const char *service, const char *addr, int *count, int *rate) { char *ident = ANVIL_IDENT(service, addr); @@ -175,9 +204,57 @@ int anvil_clnt_connect(ANVIL_CLNT * anvil_clnt, const char *service, return (status); } +/* anvil_clnt_mail - heads-up and policy query */ + +int anvil_clnt_mail(ANVIL_CLNT *anvil_clnt, const char *service, + const char *addr, int *msgs) +{ + char *ident = ANVIL_IDENT(service, addr); + int status; + + if (attr_clnt_request((ATTR_CLNT *) anvil_clnt, + ATTR_FLAG_NONE, /* Query attributes. */ + ATTR_TYPE_STR, ANVIL_ATTR_REQ, ANVIL_REQ_MAIL, + ATTR_TYPE_STR, ANVIL_ATTR_IDENT, ident, + ATTR_TYPE_END, + ATTR_FLAG_MISSING, /* Reply attributes. */ + ATTR_TYPE_NUM, ANVIL_ATTR_STATUS, &status, + ATTR_TYPE_NUM, ANVIL_ATTR_RATE, msgs, + ATTR_TYPE_END) != 2) + status = ANVIL_STAT_FAIL; + else if (status != ANVIL_STAT_OK) + status = ANVIL_STAT_FAIL; + myfree(ident); + return (status); +} + +/* anvil_clnt_rcpt - heads-up and policy query */ + +int anvil_clnt_rcpt(ANVIL_CLNT *anvil_clnt, const char *service, + const char *addr, int *rcpts) +{ + char *ident = ANVIL_IDENT(service, addr); + int status; + + if (attr_clnt_request((ATTR_CLNT *) anvil_clnt, + ATTR_FLAG_NONE, /* Query attributes. */ + ATTR_TYPE_STR, ANVIL_ATTR_REQ, ANVIL_REQ_RCPT, + ATTR_TYPE_STR, ANVIL_ATTR_IDENT, ident, + ATTR_TYPE_END, + ATTR_FLAG_MISSING, /* Reply attributes. */ + ATTR_TYPE_NUM, ANVIL_ATTR_STATUS, &status, + ATTR_TYPE_NUM, ANVIL_ATTR_RATE, rcpts, + ATTR_TYPE_END) != 2) + status = ANVIL_STAT_FAIL; + else if (status != ANVIL_STAT_OK) + status = ANVIL_STAT_FAIL; + myfree(ident); + return (status); +} + /* anvil_clnt_disconnect - heads-up only */ -int anvil_clnt_disconnect(ANVIL_CLNT * anvil_clnt, const char *service, +int anvil_clnt_disconnect(ANVIL_CLNT *anvil_clnt, const char *service, const char *addr) { char *ident = ANVIL_IDENT(service, addr); @@ -210,15 +287,26 @@ int anvil_clnt_disconnect(ANVIL_CLNT * anvil_clnt, const char *service, #include #include +static void usage(void) +{ + vstream_printf("usage: %s service addr | %s service addr |" + " %s service addr | %s service addr\n", + ANVIL_REQ_CONN, ANVIL_REQ_DISC, + ANVIL_REQ_MAIL, ANVIL_REQ_RCPT); +} + int main(int unused_argc, char **argv) { VSTRING *inbuf = vstring_alloc(1); char *bufp; char *cmd; + int cmd_len; char *service; char *addr; int count; int rate; + int msgs; + int rcpts; ANVIL_CLNT *anvil; msg_vstream_init(argv[0], VSTREAM_ERR); @@ -238,27 +326,43 @@ int main(int unused_argc, char **argv) || (service = mystrtok(&bufp, " ")) == 0 || *service == 0 || (addr = mystrtok(&bufp, " ")) == 0 || *addr == 0 || mystrtok(&bufp, " ") != 0) { - vstream_printf("usage: connect service addr|disconnect service addr\n"); + vstream_printf("bad command syntax\n"); + usage(); vstream_fflush(VSTREAM_OUT); continue; } - if (strncmp(cmd, "connect", 1) == 0) { + cmd_len = strlen(cmd); + if (strncmp(cmd, ANVIL_REQ_CONN, cmd_len) == 0) { if (anvil_clnt_connect(anvil, service, addr, &count, &rate) != ANVIL_STAT_OK) msg_warn("error!"); else vstream_printf("count=%d, rate=%d\n", count, rate); - } else if (strncmp(cmd, "disconnect", 1) == 0) { + } else if (strncmp(cmd, ANVIL_REQ_MAIL, cmd_len) == 0) { + if (anvil_clnt_mail(anvil, service, addr, &msgs) != ANVIL_STAT_OK) + msg_warn("error!"); + else + vstream_printf("rate=%d\n", msgs); + } else if (strncmp(cmd, ANVIL_REQ_RCPT, cmd_len) == 0) { + if (anvil_clnt_rcpt(anvil, service, addr, &rcpts) != ANVIL_STAT_OK) + msg_warn("error!"); + else + vstream_printf("rate=%d\n", rcpts); + } else if (strncmp(cmd, ANVIL_REQ_DISC, cmd_len) == 0) { if (anvil_clnt_disconnect(anvil, service, addr) != ANVIL_STAT_OK) msg_warn("error!"); else vstream_printf("OK\n"); - } else if (strncmp(cmd, "lookup", 1) == 0) { - if (anvil_clnt_lookup(anvil, service, addr, &count, &rate) != ANVIL_STAT_OK) + } else if (strncmp(cmd, ANVIL_REQ_LOOKUP, cmd_len) == 0) { + if (anvil_clnt_lookup(anvil, service, addr, &count, &rate, + &msgs, &rcpts) != ANVIL_STAT_OK) msg_warn("error!"); else - vstream_printf("count=%d, rate=%d\n", count, rate); - } else - vstream_printf("usage: connect ident|disconnect ident\n"); + vstream_printf("count=%d, rate=%d msgs=%d rcpt=%d\n", + count, rate, msgs, rcpts); + } else { + vstream_printf("bad command: \"%s\"\n", cmd); + usage(); + } vstream_fflush(VSTREAM_OUT); } vstring_free(inbuf); diff --git a/postfix/src/global/anvil_clnt.h b/postfix/src/global/anvil_clnt.h index d44a98122..257c6f475 100644 --- a/postfix/src/global/anvil_clnt.h +++ b/postfix/src/global/anvil_clnt.h @@ -30,10 +30,14 @@ #define ANVIL_ATTR_REQ "request" #define ANVIL_REQ_CONN "connect" #define ANVIL_REQ_DISC "disconnect" +#define ANVIL_REQ_MAIL "message" +#define ANVIL_REQ_RCPT "recipient" #define ANVIL_REQ_LOOKUP "lookup" #define ANVIL_ATTR_IDENT "ident" #define ANVIL_ATTR_COUNT "count" #define ANVIL_ATTR_RATE "rate" +#define ANVIL_ATTR_MAIL "mail" +#define ANVIL_ATTR_RCPT "rcpt" #define ANVIL_ATTR_STATUS "status" #define ANVIL_STAT_OK 0 @@ -46,7 +50,9 @@ typedef struct ANVIL_CLNT ANVIL_CLNT; extern ANVIL_CLNT *anvil_clnt_create(void); extern int anvil_clnt_connect(ANVIL_CLNT *, const char *, const char *, int *, int *); -extern int anvil_clnt_lookup(ANVIL_CLNT *, const char *, const char *, int *, int *); +extern int anvil_clnt_mail(ANVIL_CLNT *, const char *, const char *, int *); +extern int anvil_clnt_rcpt(ANVIL_CLNT *, const char *, const char *, int *); +extern int anvil_clnt_lookup(ANVIL_CLNT *, const char *, const char *, int *, int *, int *, int *); extern int anvil_clnt_disconnect(ANVIL_CLNT *, const char *, const char *); extern void anvil_clnt_free(ANVIL_CLNT *); diff --git a/postfix/src/global/deliver_pass.c b/postfix/src/global/deliver_pass.c index 4eabb3673..7a87b9d55 100644 --- a/postfix/src/global/deliver_pass.c +++ b/postfix/src/global/deliver_pass.c @@ -111,6 +111,9 @@ static int deliver_pass_send_request(VSTREAM *stream, DELIVER_REQUEST *request, ATTR_TYPE_STR, MAIL_ATTR_CLIENT_ADDR, request->client_addr, ATTR_TYPE_STR, MAIL_ATTR_PROTO_NAME, request->client_proto, ATTR_TYPE_STR, MAIL_ATTR_HELO_NAME, request->client_helo, + ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD, request->sasl_method, + ATTR_TYPE_STR, MAIL_ATTR_SASL_USERNAME, request->sasl_username, + ATTR_TYPE_STR, MAIL_ATTR_SASL_SENDER, request->sasl_sender, ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, offs, ATTR_TYPE_STR, MAIL_ATTR_ORCPT, orcpt, ATTR_TYPE_STR, MAIL_ATTR_RECIP, addr, diff --git a/postfix/src/global/deliver_request.c b/postfix/src/global/deliver_request.c index 1ad6defb2..7ec796899 100644 --- a/postfix/src/global/deliver_request.c +++ b/postfix/src/global/deliver_request.c @@ -26,6 +26,9 @@ /* char *client_addr; /* char *client_proto; /* char *client_helo; +/* char *sasl_method; +/* char *sasl_username; +/* char *sasl_sender; /* .in -5 /* } DELIVER_REQUEST; /* @@ -183,6 +186,9 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) static VSTRING *client_addr; static VSTRING *client_proto; static VSTRING *client_helo; + static VSTRING *sasl_method; + static VSTRING *sasl_username; + static VSTRING *sasl_sender; long offset; /* @@ -203,6 +209,9 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) client_addr = vstring_alloc(10); client_proto = vstring_alloc(10); client_helo = vstring_alloc(10); + sasl_method = vstring_alloc(10); + sasl_username = vstring_alloc(10); + sasl_sender = vstring_alloc(10); } /* @@ -225,7 +234,10 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) ATTR_TYPE_STR, MAIL_ATTR_CLIENT_ADDR, client_addr, ATTR_TYPE_STR, MAIL_ATTR_PROTO_NAME, client_proto, ATTR_TYPE_STR, MAIL_ATTR_HELO_NAME, client_helo, - ATTR_TYPE_END) != 15) { + ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD, sasl_method, + ATTR_TYPE_STR, MAIL_ATTR_SASL_USERNAME, sasl_username, + ATTR_TYPE_STR, MAIL_ATTR_SASL_SENDER, sasl_sender, + ATTR_TYPE_END) != 18) { msg_warn("%s: error receiving common attributes", myname); return (-1); } @@ -244,6 +256,9 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) request->client_addr = mystrdup(vstring_str(client_addr)); request->client_proto = mystrdup(vstring_str(client_proto)); request->client_helo = mystrdup(vstring_str(client_helo)); + request->sasl_method = mystrdup(vstring_str(sasl_method)); + request->sasl_username = mystrdup(vstring_str(sasl_username)); + request->sasl_sender = mystrdup(vstring_str(sasl_sender)); /* * Extract the recipient offset and address list. Skip over any @@ -322,6 +337,9 @@ static DELIVER_REQUEST *deliver_request_alloc(void) request->client_addr = 0; request->client_proto = 0; request->client_helo = 0; + request->sasl_method = 0; + request->sasl_username = 0; + request->sasl_sender = 0; return (request); } @@ -356,6 +374,12 @@ static void deliver_request_free(DELIVER_REQUEST *request) myfree(request->client_proto); if (request->client_helo) myfree(request->client_helo); + if (request->sasl_method) + myfree(request->sasl_method); + if (request->sasl_username) + myfree(request->sasl_username); + if (request->sasl_sender) + myfree(request->sasl_sender); myfree((char *) request); } diff --git a/postfix/src/global/deliver_request.h b/postfix/src/global/deliver_request.h index ef541ed96..badeba965 100644 --- a/postfix/src/global/deliver_request.h +++ b/postfix/src/global/deliver_request.h @@ -44,6 +44,9 @@ typedef struct DELIVER_REQUEST { char *client_addr; /* client address */ char *client_proto; /* client protocol */ char *client_helo; /* helo parameter */ + char *sasl_method; /* SASL method */ + char *sasl_username; /* SASL user name */ + char *sasl_sender; /* SASL sender */ } DELIVER_REQUEST; /* diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 1fc90b6a9..30811aa64 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -2060,8 +2060,16 @@ extern int var_smtpd_crate_limit; #define DEF_SMTPD_CCONN_LIMIT ((DEF_PROC_LIMIT + 1) / 2) extern int var_smtpd_cconn_limit; -#define VAR_SMTPD_HOGGERS "smtpd_client_connection_limit_exceptions" -#define DEF_SMTPD_HOGGERS "$" VAR_MYNETWORKS +#define VAR_SMTPD_CMAIL_LIMIT "smtpd_client_message_rate_limit" +#define DEF_SMTPD_CMAIL_LIMIT 0 +extern int var_smtpd_cmail_limit; + +#define VAR_SMTPD_CRCPT_LIMIT "smtpd_client_recipient_rate_limit" +#define DEF_SMTPD_CRCPT_LIMIT 0 +extern int var_smtpd_crcpt_limit; + +#define VAR_SMTPD_HOGGERS "smtpd_client_event_limit_exceptions" +#define DEF_SMTPD_HOGGERS "${smtpd_client_connection_limit_exceptions:$" VAR_MYNETWORKS "}" extern char *var_smtpd_hoggers; #define VAR_ANVIL_TIME_UNIT "anvil_rate_time_unit" diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 7d5fa76e2..43efd222f 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change the patchlevel and the release date. Snapshots change the * release date only. */ -#define MAIL_RELEASE_DATE "20040919" +#define MAIL_RELEASE_DATE "20041009" #define MAIL_VERSION_NUMBER "2.2" #define VAR_MAIL_VERSION "mail_version" diff --git a/postfix/src/master/master.c b/postfix/src/master/master.c index 539fa13e8..e1b21ab13 100644 --- a/postfix/src/master/master.c +++ b/postfix/src/master/master.c @@ -4,9 +4,7 @@ /* SUMMARY /* Postfix master process /* SYNOPSIS -/* .fi -/* \fBmaster\fR [\fB-Dtv\fR] [\fB-c \fIconfig_dir\fR] -/* [\fB-e \fIexit_time\fR] +/* \fBmaster\fR [\fB-Dtv\fR] [\fB-c \fIconfig_dir\fR] [\fB-e \fIexit_time\fR] /* DESCRIPTION /* The \fBmaster\fR daemon is the resident process that runs Postfix /* daemons on demand: daemons to send or receive messages via the @@ -19,16 +17,14 @@ /* resident queue manager and the resident address verification server. /* /* The behavior of the \fBmaster\fR daemon is controlled by the -/* \fBmaster.cf\fR configuration file. The table specifies zero or -/* more servers in the \fBUNIX\fR or \fBINET\fR domain, or servers -/* that take requests from a FIFO. Precise configuration details are -/* given in the \fBmaster.cf\fR file, and in the manual pages of the -/* respective daemons. +/* \fBmaster.cf\fR configuration file, as described in master(5). /* /* Options: /* .IP "\fB-c \fIconfig_dir\fR" /* Read the \fBmain.cf\fR and \fBmaster.cf\fR configuration files in /* the named directory instead of the default configuration directory. +/* This also overrides the configuration files for other Postfix +/* daemon processes. /* .IP "\fB-e \fIexit_time\fR" /* Terminate the master process after \fIexit_time\fR seconds. Child /* processes terminate at their convenience. @@ -135,7 +131,8 @@ /* SEE ALSO /* qmgr(8), queue manager /* verify(8), address verification -/* postconf(5), configuration parameters +/* master(5), master.cf configuration file syntax +/* postconf(5), main.cf configuration parameter syntax /* syslogd(8), system logging /* LICENSE /* .ad diff --git a/postfix/src/oqmgr/qmgr.h b/postfix/src/oqmgr/qmgr.h index 2c47e1640..b11418366 100644 --- a/postfix/src/oqmgr/qmgr.h +++ b/postfix/src/oqmgr/qmgr.h @@ -243,6 +243,9 @@ struct QMGR_MESSAGE { char *client_addr; /* client address */ char *client_proto; /* client protocol */ char *client_helo; /* helo parameter */ + char *sasl_method; /* SASL method */ + char *sasl_username; /* SASL user name */ + char *sasl_sender; /* SASL sender */ QMGR_RCPT_LIST rcpt_list; /* complete addresses */ }; diff --git a/postfix/src/oqmgr/qmgr_deliver.c b/postfix/src/oqmgr/qmgr_deliver.c index ea6650666..f9556efd5 100644 --- a/postfix/src/oqmgr/qmgr_deliver.c +++ b/postfix/src/oqmgr/qmgr_deliver.c @@ -161,6 +161,9 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream) ATTR_TYPE_STR, MAIL_ATTR_CLIENT_ADDR, message->client_addr, ATTR_TYPE_STR, MAIL_ATTR_PROTO_NAME, message->client_proto, ATTR_TYPE_STR, MAIL_ATTR_HELO_NAME, message->client_helo, + ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD, message->sasl_method, + ATTR_TYPE_STR, MAIL_ATTR_SASL_USERNAME, message->sasl_username, + ATTR_TYPE_STR, MAIL_ATTR_SASL_SENDER, message->sasl_sender, ATTR_TYPE_END); if (sender_buf != 0) vstring_free(sender_buf); diff --git a/postfix/src/oqmgr/qmgr_message.c b/postfix/src/oqmgr/qmgr_message.c index 658d1d74e..fbe0606c8 100644 --- a/postfix/src/oqmgr/qmgr_message.c +++ b/postfix/src/oqmgr/qmgr_message.c @@ -172,6 +172,9 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name, message->client_addr = 0; message->client_proto = 0; message->client_helo = 0; + message->sasl_method = 0; + message->sasl_username = 0; + message->sasl_sender = 0; qmgr_rcpt_list_init(&message->rcpt_list); return (message); } @@ -525,6 +528,27 @@ static int qmgr_message_read(QMGR_MESSAGE *message) myfree(message->client_helo); message->client_helo = mystrdup(value); } + if (strcmp(name, MAIL_ATTR_SASL_METHOD) == 0) { + if (message->sasl_method == 0) + message->sasl_method = mystrdup(value); + else + msg_warn("%s: ignoring multiple %s attribute: %s", + message->queue_id, MAIL_ATTR_SASL_METHOD, value); + } + if (strcmp(name, MAIL_ATTR_SASL_USERNAME) == 0) { + if (message->sasl_username == 0) + message->sasl_username = mystrdup(value); + else + msg_warn("%s: ignoring multiple %s attribute: %s", + message->queue_id, MAIL_ATTR_SASL_USERNAME, value); + } + if (strcmp(name, MAIL_ATTR_SASL_SENDER) == 0) { + if (message->sasl_sender == 0) + message->sasl_sender = mystrdup(value); + else + msg_warn("%s: ignoring multiple %s attribute: %s", + message->queue_id, MAIL_ATTR_SASL_SENDER, value); + } /* Optional tracing flags. */ else if (strcmp(name, MAIL_ATTR_TRACE_FLAGS) == 0) { message->tflags = DEL_REQ_TRACE_FLAGS(atoi(value)); @@ -598,6 +622,12 @@ static int qmgr_message_read(QMGR_MESSAGE *message) message->client_proto = mystrdup(""); if (message->client_helo == 0) message->client_helo = mystrdup(""); + if (message->sasl_method == 0) + message->sasl_method = mystrdup(""); + if (message->sasl_username == 0) + message->sasl_username = mystrdup(""); + if (message->sasl_sender == 0) + message->sasl_sender = mystrdup(""); /* * Clean up. @@ -1072,6 +1102,12 @@ void qmgr_message_free(QMGR_MESSAGE *message) myfree(message->client_proto); if (message->client_helo) myfree(message->client_helo); + if (message->sasl_method) + myfree(message->sasl_method); + if (message->sasl_username) + myfree(message->sasl_username); + if (message->sasl_sender) + myfree(message->sasl_sender); qmgr_rcpt_list_free(&message->rcpt_list); qmgr_message_count--; myfree((char *) message); diff --git a/postfix/src/pipe/pipe.c b/postfix/src/pipe/pipe.c index 1b7217726..3eb2d4a2d 100644 --- a/postfix/src/pipe/pipe.c +++ b/postfix/src/pipe/pipe.c @@ -125,7 +125,11 @@ /* .sp /* In the command argument vector, the following macros are recognized /* and replaced with corresponding information from the Postfix queue -/* manager delivery request: +/* manager delivery request. +/* .sp +/* In addition to the form ${\fIname\fR}, the forms $\fIname\fR and +/* $(\fIname\fR) are also recognized. Specify \fB$$\fR where a single +/* \fB$\fR is wanted. /* .RS /* .IP \fB${\fBextension\fR}\fR /* This macro expands to the extension part of a recipient address. @@ -157,6 +161,23 @@ /* .sp /* This information is modified by the \fBhqu\fR flags for quoting /* and case folding. +/* .IP \fB${\fBsasl_method\fR}\fR +/* This macro expands to the SASL authentication mechanism used +/* during the reception of the message. An empty string is passed +/* if the message has been received without SASL authentication. +/* .sp +/* This is available in Postfix 2.2 and later. +/* .IP \fB${\fBsasl_sender\fR}\fR +/* This macro expands to the SASL sender name (i.e. the original +/* submitter as per RFC 2554) used during the reception of the message. +/* .sp +/* This is available in Postfix 2.2 and later. +/* .IP \fB${\fBsasl_username\fR}\fR +/* This macro expands to the SASL user name used during the reception +/* of the message. An empty string is passed if the message has been +/* received without SASL authentication. +/* .sp +/* This is available in Postfix 2.2 and later. /* .IP \fB${\fBsender\fR}\fR /* This macro expands to the envelope sender address. /* .sp @@ -174,10 +195,6 @@ /* .sp /* This information is modified by the \fBu\fR flag for case folding. /* .RE -/* .PP -/* In addition to the form ${\fIname\fR}, the forms $\fIname\fR and -/* $(\fIname\fR) are also recognized. Specify \fB$$\fR where a single -/* \fB$\fR is wanted. /* DIAGNOSTICS /* Command exit status codes are expected to /* follow the conventions defined in <\fBsysexits.h\fR>. @@ -341,6 +358,9 @@ #define PIPE_DICT_EXTENSION "extension" /* key */ #define PIPE_DICT_MAILBOX "mailbox" /* key */ #define PIPE_DICT_SIZE "size" /* key */ +#define PIPE_DICT_SASL_METHOD "sasl_method" /* key */ +#define PIPE_DICT_SASL_USERNAME "sasl_username" /* key */ +#define PIPE_DICT_SASL_SENDER "sasl_sender" /* key */ /* * Flags used to pass back the type of special parameter found by @@ -422,6 +442,9 @@ static int parse_callback(int type, VSTRING *buf, char *context) PIPE_DICT_EXTENSION, PIPE_FLAG_EXTENSION, PIPE_DICT_MAILBOX, PIPE_FLAG_MAILBOX, PIPE_DICT_SIZE, 0, + PIPE_DICT_SASL_METHOD, 0, + PIPE_DICT_SASL_USERNAME, 0, + PIPE_DICT_SASL_SENDER, 0, 0, 0, }; struct cmd_flags *p; @@ -970,6 +993,12 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv) dict_update(PIPE_DICT_TABLE, PIPE_DICT_NEXTHOP, request->nexthop); vstring_sprintf(buf, "%ld", (long) request->data_size); dict_update(PIPE_DICT_TABLE, PIPE_DICT_SIZE, STR(buf)); + dict_update(PIPE_DICT_TABLE, PIPE_DICT_SASL_METHOD, + request->sasl_method); + dict_update(PIPE_DICT_TABLE, PIPE_DICT_SASL_USERNAME, + request->sasl_username); + dict_update(PIPE_DICT_TABLE, PIPE_DICT_SASL_SENDER, + request->sasl_sender); vstring_free(buf); if ((expanded_argv = expand_argv(service, attr.command, diff --git a/postfix/src/postfix/postfix.c b/postfix/src/postfix/postfix.c index 910d001b1..24ed673a3 100644 --- a/postfix/src/postfix/postfix.c +++ b/postfix/src/postfix/postfix.c @@ -157,7 +157,8 @@ /* sendmail(1), Sendmail compatibility interface /* /* Postfix configuration: -/* postconf(5), Postfix configuration parameters +/* master(5), Postfix master.cf file syntax +/* postconf(5), Postfix main.cf file syntax /* /* Table-driven mechanisms: /* access(5), Postfix SMTP access control table diff --git a/postfix/src/postsuper/postsuper.c b/postfix/src/postsuper/postsuper.c index af0afef5a..7c5a21179 100644 --- a/postfix/src/postsuper/postsuper.c +++ b/postfix/src/postsuper/postsuper.c @@ -92,7 +92,7 @@ /* .sp /* Note: use "\fBpostsuper -r\fR" to release mail that was kept on /* hold for a significant fraction of \fB$maximal_queue_lifetime\fR -/* or \fB$bounce_queue_lifetime\fR or longer. +/* or \fB$bounce_queue_lifetime\fR, or longer. /* .sp /* Specify \fB-H ALL\fR to release all mail that is "on hold". /* As a safety measure, the word \fBALL\fR must be specified in upper diff --git a/postfix/src/qmgr/qmgr.h b/postfix/src/qmgr/qmgr.h index 45178f621..612625bcf 100644 --- a/postfix/src/qmgr/qmgr.h +++ b/postfix/src/qmgr/qmgr.h @@ -283,6 +283,9 @@ struct QMGR_MESSAGE { char *client_addr; /* client address */ char *client_proto; /* client protocol */ char *client_helo; /* helo parameter */ + char *sasl_method; /* SASL method */ + char *sasl_username; /* SASL user name */ + char *sasl_sender; /* SASL sender */ QMGR_RCPT_LIST rcpt_list; /* complete addresses */ int rcpt_count; /* used recipient slots */ int rcpt_limit; /* maximum read in-core */ diff --git a/postfix/src/qmgr/qmgr_deliver.c b/postfix/src/qmgr/qmgr_deliver.c index 178f93d5e..3064e540a 100644 --- a/postfix/src/qmgr/qmgr_deliver.c +++ b/postfix/src/qmgr/qmgr_deliver.c @@ -166,6 +166,9 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream) ATTR_TYPE_STR, MAIL_ATTR_CLIENT_ADDR, message->client_addr, ATTR_TYPE_STR, MAIL_ATTR_PROTO_NAME, message->client_proto, ATTR_TYPE_STR, MAIL_ATTR_HELO_NAME, message->client_helo, + ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD, message->sasl_method, + ATTR_TYPE_STR, MAIL_ATTR_SASL_USERNAME, message->sasl_username, + ATTR_TYPE_STR, MAIL_ATTR_SASL_SENDER, message->sasl_sender, ATTR_TYPE_END); if (sender_buf != 0) vstring_free(sender_buf); diff --git a/postfix/src/qmgr/qmgr_message.c b/postfix/src/qmgr/qmgr_message.c index 724cbd1ab..132a738a2 100644 --- a/postfix/src/qmgr/qmgr_message.c +++ b/postfix/src/qmgr/qmgr_message.c @@ -182,6 +182,9 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name, message->client_addr = 0; message->client_proto = 0; message->client_helo = 0; + message->sasl_method = 0; + message->sasl_username = 0; + message->sasl_sender = 0; qmgr_rcpt_list_init(&message->rcpt_list); message->rcpt_count = 0; message->rcpt_limit = var_qmgr_msg_rcpt_limit; @@ -560,6 +563,27 @@ static int qmgr_message_read(QMGR_MESSAGE *message) myfree(message->client_helo); message->client_helo = mystrdup(value); } + if (strcmp(name, MAIL_ATTR_SASL_METHOD) == 0) { + if (message->sasl_method == 0) + message->sasl_method = mystrdup(value); + else + msg_warn("%s: ignoring multiple %s attribute: %s", + message->queue_id, MAIL_ATTR_SASL_METHOD, value); + } + if (strcmp(name, MAIL_ATTR_SASL_USERNAME) == 0) { + if (message->sasl_username == 0) + message->sasl_username = mystrdup(value); + else + msg_warn("%s: ignoring multiple %s attribute: %s", + message->queue_id, MAIL_ATTR_SASL_USERNAME, value); + } + if (strcmp(name, MAIL_ATTR_SASL_SENDER) == 0) { + if (message->sasl_sender == 0) + message->sasl_sender = mystrdup(value); + else + msg_warn("%s: ignoring multiple %s attribute: %s", + message->queue_id, MAIL_ATTR_SASL_SENDER, value); + } /* Optional tracing flags. */ else if (strcmp(name, MAIL_ATTR_TRACE_FLAGS) == 0) { message->tflags = DEL_REQ_TRACE_FLAGS(atoi(value)); @@ -633,6 +657,12 @@ static int qmgr_message_read(QMGR_MESSAGE *message) message->client_proto = mystrdup(""); if (message->client_helo == 0) message->client_helo = mystrdup(""); + if (message->sasl_method == 0) + message->sasl_method = mystrdup(""); + if (message->sasl_username == 0) + message->sasl_username = mystrdup(""); + if (message->sasl_sender == 0) + message->sasl_sender = mystrdup(""); /* * Clean up. @@ -1178,6 +1208,12 @@ void qmgr_message_free(QMGR_MESSAGE *message) myfree(message->client_proto); if (message->client_helo) myfree(message->client_helo); + if (message->sasl_method) + myfree(message->sasl_method); + if (message->sasl_username) + myfree(message->sasl_username); + if (message->sasl_sender) + myfree(message->sasl_sender); qmgr_rcpt_list_free(&message->rcpt_list); qmgr_message_count--; myfree((char *) message); diff --git a/postfix/src/sendmail/sendmail.c b/postfix/src/sendmail/sendmail.c index 1e94712d0..c1aa4aed3 100644 --- a/postfix/src/sendmail/sendmail.c +++ b/postfix/src/sendmail/sendmail.c @@ -240,9 +240,8 @@ /* .IP "\fBauthorized_mailq_users (static:anyone)\fR" /* List of users who are authorized to view the queue. /* .IP "\fBauthorized_submit_users (static:anyone)\fR" -/* List of users who are authorized to submit mail with the -/* sendmail(1) command (and with the privileged postdrop(1) -/* helper command). +/* List of users who are authorized to submit mail with the sendmail(1) +/* command (and with the privileged postdrop(1) helper command). /* RESOURCE AND RATE CONTROLS /* .ad /* .fi @@ -655,7 +654,10 @@ static void enqueue(const int flags, const char *encoding, const char *sender, */ rec_fputs(dst, REC_TYPE_MESG, ""); if (DEL_REQ_TRACE_ONLY(flags) != 0) { - rec_fprintf(dst, REC_TYPE_NORM, "From: %s", saved_sender); + if (flags & SM_FLAG_XRCPT) + msg_fatal_status(EX_USAGE, "-t option cannot be used with -bv"); + if (*saved_sender) + rec_fprintf(dst, REC_TYPE_NORM, "From: %s", saved_sender); rec_fprintf(dst, REC_TYPE_NORM, "Subject: probe"); if (recipients) { rec_fprintf(dst, REC_TYPE_NORM, "To:"); diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 4591d678b..c34aebdd2 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -305,16 +305,26 @@ /* The maximal number of lines in the Postfix SMTP server command history /* before it is flushed upon receipt of EHLO, RSET, or end of DATA. /* .PP -/* Not available in Postfix version 2.1: +/* The per SMTP client connection count and request rate limits are +/* implemented in co-operation with the anvil(8) service, and +/* are available in Postfix version 2.2 and later. /* .IP "\fBsmtpd_client_connection_count_limit (50)\fR" -/* How many simultaneous connections any SMTP client is allowed to -/* make to the SMTP service. +/* How many simultaneous connections any client is allowed to +/* make to this service. /* .IP "\fBsmtpd_client_connection_rate_limit (0)\fR" /* The maximal number of connection attempts any client is allowed to /* make to this service per time unit. -/* .IP "\fBsmtpd_client_connection_limit_exceptions ($mynetworks)\fR" -/* Clients that are excluded from connection count or connection rate -/* restrictions. +/* .IP "\fBsmtpd_client_message_rate_limit (0)\fR" +/* The maximal number of message delivery requests that any client is +/* allowed to make to this service per time unit, regardless of whether +/* or not Postfix actually accepts those messages. +/* .IP "\fBsmtpd_client_recipient_rate_limit (0)\fR" +/* The maximal number of recipient addresses that any client is allowed +/* to send to this service per time unit, regardless of whether or not +/* Postfix actually accepts those recipients. +/* .IP "\fBsmtpd_client_event_limit_exceptions ($mynetworks)\fR" +/* Clients that are excluded from connection count, connection rate, +/* message rate or recipient rate restrictions. /* TARPIT CONTROLS /* .ad /* .fi @@ -553,6 +563,7 @@ /* The mail system name that is prepended to the process name in syslog /* records, so that "smtpd" becomes, for example, "postfix/smtpd". /* SEE ALSO +/* anvil(8), client count and request rate management /* cleanup(8), message canonicalization /* trivial-rewrite(8), address resolver /* verify(8), address verification service @@ -758,6 +769,8 @@ bool var_smtpd_rej_unl_rcpt; #ifdef SNAPSHOT int var_smtpd_crate_limit; int var_smtpd_cconn_limit; +int var_smtpd_cmail_limit; +int var_smtpd_crcpt_limit; char *var_smtpd_hoggers; #endif @@ -1030,14 +1043,28 @@ static void mail_open_stream(SMTPD_STATE *state) state->queue_id = mystrdup(state->dest->id); /* - * Record the time of arrival, the sender envelope address, some session - * information, and some additional attributes. + * Record the time of arrival, the SASL-related stuff if applicable, the + * sender envelope address, some session information, and some additional + * attributes. */ if (SMTPD_STAND_ALONE(state) == 0) { rec_fprintf(state->cleanup, REC_TYPE_TIME, "%ld", state->time); if (*var_filter_xport) rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", var_filter_xport); } +#ifdef USE_SASL_AUTH + if (var_smtpd_sasl_enable) { + if (state->sasl_method) + rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s", + MAIL_ATTR_SASL_METHOD, state->sasl_method); + if (state->sasl_username) + rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s", + MAIL_ATTR_SASL_USERNAME, state->sasl_username); + if (state->sasl_sender) + rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s", + MAIL_ATTR_SASL_SENDER, state->sasl_sender); + } +#endif rec_fputs(state->cleanup, REC_TYPE_FROM, state->sender); if (state->encoding != 0) rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s", @@ -1187,6 +1214,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) int narg; char *arg; char *verp_delims = 0; + int rate; state->encoding = 0; @@ -1217,6 +1245,28 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) smtpd_chat_reply(state, "501 Syntax: MAIL FROM:

    "); return (-1); } + + /* + * XXX The client event count/rate control must be consistent in its use + * of client address information in connect and disconnect events. For + * now we exclude xclient authorized hosts from event count/rate control. + */ +#ifdef SNAPSHOT + if (SMTPD_STAND_ALONE(state) == 0 + && !xclient_allowed + && anvil_clnt + && var_smtpd_cmail_limit > 0 + && !namadr_list_match(hogger_list, state->name, state->addr) + && anvil_clnt_mail(anvil_clnt, state->service, state->addr, + &rate) == ANVIL_STAT_OK + && rate > var_smtpd_cmail_limit) { + smtpd_chat_reply(state, "421 %s Error: too much mail from %s", + var_myhostname, state->addr); + msg_warn("Message delivery request rate limit exceeded: %d from %s for service %s", + rate, state->namaddr, state->service); + return (-1); + } +#endif if (argv[2].tokval == SMTPD_TOK_ERROR) { state->error_mask |= MAIL_ERROR_PROTOCOL; smtpd_chat_reply(state, "501 Bad sender address syntax"); @@ -1383,6 +1433,7 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) char *err; int narg; char *arg; + int rate; /* * Sanity checks. @@ -1404,6 +1455,28 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) smtpd_chat_reply(state, "501 Syntax: RCPT TO:
    "); return (-1); } + + /* + * XXX The client event count/rate control must be consistent in its use + * of client address information in connect and disconnect events. For + * now we exclude xclient authorized hosts from event count/rate control. + */ +#ifdef SNAPSHOT + if (SMTPD_STAND_ALONE(state) == 0 + && !xclient_allowed + && anvil_clnt + && var_smtpd_crcpt_limit > 0 + && !namadr_list_match(hogger_list, state->name, state->addr) + && anvil_clnt_rcpt(anvil_clnt, state->service, state->addr, + &rate) == ANVIL_STAT_OK + && rate > var_smtpd_crcpt_limit) { + smtpd_chat_reply(state, "421 %s Error: too many recipients from %s", + var_myhostname, state->addr); + msg_warn("Recipient address rate limit exceeded: %d from %s for service %s", + rate, state->namaddr, state->service); + return (-1); + } +#endif if (argv[2].tokval == SMTPD_TOK_ERROR) { state->error_mask |= MAIL_ERROR_PROTOCOL; smtpd_chat_reply(state, "501 Bad recipient address syntax"); @@ -2409,6 +2482,11 @@ static void smtpd_proto(SMTPD_STATE *state, const char *service) * its use of client address information in connect and disconnect * events. For now we exclude xclient authorized hosts from * connection count/rate control. + * + * XXX Must send connect/disconnect events to the anvil server even when + * this service is not connection count or rate limited, otherwise it + * will discard client message or recipient rate information too + * early or too late. */ #ifdef SNAPSHOT if (SMTPD_STAND_ALONE(state) == 0 @@ -2420,14 +2498,14 @@ static void smtpd_proto(SMTPD_STATE *state, const char *service) if (var_smtpd_cconn_limit > 0 && count > var_smtpd_cconn_limit) { smtpd_chat_reply(state, "421 %s Error: too many connections from %s", var_myhostname, state->addr); - msg_warn("Too many connections: %d from %s for service %s", + msg_warn("Connection concurrency limit exceeded: %d from %s for service %s", count, state->namaddr, service); break; } if (var_smtpd_crate_limit > 0 && crate > var_smtpd_crate_limit) { smtpd_chat_reply(state, "421 %s Error: too many connections from %s", var_myhostname, state->addr); - msg_warn("Too frequent connections: %d from %s for service %s", + msg_warn("Connection rate limit exceeded: %d from %s for service %s", crate, state->namaddr, service); break; } @@ -2505,6 +2583,11 @@ static void smtpd_proto(SMTPD_STATE *state, const char *service) * use of client address information in connect and disconnect events. * For now we exclude xclient authorized hosts from connection count/rate * control. + * + * XXX Must send connect/disconnect events to the anvil server even when + * this service is not connection count or rate limited, otherwise it + * will discard client message or recipient rate information too early or + * too late. */ #ifdef SNAPSHOT if (SMTPD_STAND_ALONE(state) == 0 @@ -2561,7 +2644,7 @@ static void smtpd_service(VSTREAM *stream, char *service, char **argv) * take a while. This is why I always run a local name server on critical * machines. */ - smtpd_state_init(&state, stream); + smtpd_state_init(&state, stream, service); msg_info("connect from %s[%s]", state.name, state.addr); /* @@ -2674,7 +2757,8 @@ static void post_jail_init(char *unused_name, char **unused_argv) * Connection rate management. */ #ifdef SNAPSHOT - if (var_smtpd_crate_limit || var_smtpd_cconn_limit) + if (var_smtpd_crate_limit || var_smtpd_cconn_limit + || var_smtpd_cmail_limit || var_smtpd_crcpt_limit) anvil_clnt = anvil_clnt_create(); #endif } @@ -2712,6 +2796,8 @@ int main(int argc, char **argv) #ifdef SNAPSHOT VAR_SMTPD_CRATE_LIMIT, DEF_SMTPD_CRATE_LIMIT, &var_smtpd_crate_limit, 0, 0, VAR_SMTPD_CCONN_LIMIT, DEF_SMTPD_CCONN_LIMIT, &var_smtpd_cconn_limit, 0, 0, + VAR_SMTPD_CMAIL_LIMIT, DEF_SMTPD_CMAIL_LIMIT, &var_smtpd_cmail_limit, 0, 0, + VAR_SMTPD_CRCPT_LIMIT, DEF_SMTPD_CRCPT_LIMIT, &var_smtpd_crcpt_limit, 0, 0, #endif 0, }; diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h index 396deeedb..ffe0c9c70 100644 --- a/postfix/src/smtpd/smtpd.h +++ b/postfix/src/smtpd/smtpd.h @@ -59,6 +59,7 @@ typedef struct SMTPD_STATE { int err; /* cleanup server/queue file errors */ VSTREAM *client; /* SMTP client handle */ VSTRING *buffer; /* SMTP client buffer */ + char *service; /* for event rate control */ time_t time; /* start of MAIL FROM transaction */ char *name; /* client hostname */ char *addr; /* client host address string */ @@ -149,7 +150,7 @@ typedef struct SMTPD_STATE { (SMTPD_STATE_XFORWARD_NAME | SMTPD_STATE_XFORWARD_ADDR \ | SMTPD_STATE_XFORWARD_PROTO | SMTPD_STATE_XFORWARD_HELO) -extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *); +extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *, const char *); extern void smtpd_state_reset(SMTPD_STATE *); /* diff --git a/postfix/src/smtpd/smtpd_state.c b/postfix/src/smtpd/smtpd_state.c index 003f42fba..5989df75e 100644 --- a/postfix/src/smtpd/smtpd_state.c +++ b/postfix/src/smtpd/smtpd_state.c @@ -6,9 +6,10 @@ /* SYNOPSIS /* #include "smtpd.h" /* -/* void smtpd_state_init(state, stream) +/* void smtpd_state_init(state, stream, service) /* SMTPD_STATE *state; /* VSTREAM *stream; +/* const char *service; /* /* void smtpd_state_reset(state) /* SMTPD_STATE *state; @@ -62,7 +63,8 @@ /* smtpd_state_init - initialize after connection establishment */ -void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream) +void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream, + const char *service) { /* @@ -71,6 +73,7 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream) */ state->err = CLEANUP_STAT_OK; state->client = stream; + state->service = mystrdup(service); state->buffer = vstring_alloc(100); state->error_count = 0; state->error_mask = 0; @@ -145,6 +148,8 @@ void smtpd_state_reset(SMTPD_STATE *state) * filled in. The other fields are taken care of by their own * "destructor" functions. */ + if (state->service) + myfree(state->service); if (state->buffer) vstring_free(state->buffer); if (state->protocol) diff --git a/postfix/src/util/sys_defs.h b/postfix/src/util/sys_defs.h index 37a3598bb..26272666d 100644 --- a/postfix/src/util/sys_defs.h +++ b/postfix/src/util/sys_defs.h @@ -240,6 +240,7 @@ extern int opterr; /* XXX use */ #ifdef SUNOS4 #define SUPPORTED #include +#include #define UNSAFE_CTYPE #define fpos_t long #define MISSING_SETENV -- 2.47.3