diff --git a/postfix/0README b/postfix/0README index 01ac09a24..9023f6fd7 100644 --- a/postfix/0README +++ b/postfix/0README @@ -21,9 +21,7 @@ Purpose of the Postfix mail system ================================== Postfix aims to be an alternative to the widely-used sendmail -program. Sendmail is responsible for 70% of all e-mail delivered -on the Internet. With an estimated 100 million users, that's an -estimated 10 billion (10^10) messages daily. A stunning number. +program. Although IBM supported the Postfix development, it abstains from control over its evolution. The goal is to have Postfix installed @@ -71,15 +69,6 @@ you are welcome to send a postcard to: Roadmap of the Postfix source distribution ========================================== -Point your browser at html/index.html for Postfix documentation, -for manual pages, and for the unavoidable Postfix FAQ. Expect to -see updated versions on-line at http://www.postfix.org/ - -Point your MANPATH environment variable at the `man' directory (use -an absolute path) for UNIX-style on-line manual pages. These pages -are also available through the HTML interface, which allows you to -navigate faster. - The RELEASE_NOTES file describes new features, and lists incompatible changes with respect to previous Postfix versions. @@ -91,10 +80,17 @@ not yet implement, and how well it works with other software. The HISTORY file gives a detailed log of changes to the software. +Point your browser at html/index.html for Postfix documentation, +for manual pages, and for the unavoidable Postfix FAQ. Expect to +see updated versions on-line at http://www.postfix.org/ + +Point your MANPATH environment variable at the `man' directory (use +an absolute path) for UNIX-style on-line manual pages. These pages +are also available through the HTML interface, which allows you to +navigate faster. + The PORTING file discusses how to go about porting Postfix to other -UNIX platforms. Some people are looking into a port to Windows NT. -We'll see. This software uses every trick in the book that I learned -about UNIX. +UNIX platforms. The TODO file lists things that still need to be done. If you want to set your teeth into one of those problems, drop me a note at diff --git a/postfix/HISTORY b/postfix/HISTORY index 0ab32a6be..4613ef2c2 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -4856,7 +4856,7 @@ Apologies for any names omitted. 20010203 - Update: null candidate patch from Patrick Rak. Files: + Update: null candidate patch from Patrik Rak. Files: nqmgr/qmgr_entry.c nqmgr/qmgr_job.c nqmgr/qmgr_message.c. Cleanup: added one gruesome command to the postlink script @@ -4869,3 +4869,46 @@ Apologies for any names omitted. Laid the ground work for logging of table accesses. This will give more insight into how Postfix uses its lookup tables. User interface comes later. File: util/dict_debug.c. + +20010215 + + The showq output format assumes queue IDs of up to 10 + characters. It can be more with large file systems. + Workaround for 11 character queue IDs by Lamont Jones. + File: showq/showq.c. + +20010216 + + Bugfix: the pipe delivery agent expanded $size as if it + were a recipient, instead of expanding it as $nexthop or + as $sender. Reported by Michael Tokarev. File: pipe/pipe.c. + +20010221 + + Bugfix: poor LMTP performance for domains that are listed + in $mydestination, because Postfix would send one recipient + at a time, with multiple deliveries of recipients of the + same message in parallel; a similar problem could exist + with firewall relay hosts that forward mail for $mydestination + to an inside machine. This behavior is now changed to depend + on the transport-specific xxx_destination_recipient_limit + parameter. This also means that you can now get qmail behavior + for SMTP deliveries by setting smtp_destination_recipient_limit=1. + File: {qmgr,nqmgr}/qmgr_message.c. + + Workaround: Solaris socketpair() can fail with EINTR. Added + a sane_socketpair.c module that joins the ranks of the other + sane_whatever workarounds. Reported by Andrew McNamara. + File: util/sane_socketpair.[hc] + +20010222 + + Documentation: the default main.cf file has a prominent + warning that mynetworks should be properly configured in + order to reject unauthorized mail relay requests from + strangers. + + Documentation: the INSTALL document, section "mandatory + configuration file edits" has a section that explains that + mynetworks should be properly configured in order to reject + unauthorized mail relay requests from strangers. diff --git a/postfix/INSTALL b/postfix/INSTALL index 49cf95a8a..c56c93055 100644 --- a/postfix/INSTALL +++ b/postfix/INSTALL @@ -66,11 +66,13 @@ If your system is supported, it is one of Linux RedHat 4.x Linux RedHat 5.x Linux RedHat 6.x + Linux RedHat 7.x Linux Slackware 3.5 Linux Slackware 4.0 Linux Slackware 7.0 Linux SuSE 5.x Linux SuSE 6.x + Linux SuSE 7.x Mac OS X server NEXTSTEP 3.x NetBSD 1.x @@ -83,7 +85,7 @@ If your system is supported, it is one of Rhapsody 5.x SunOS 4.1.x SunOS 5.4..5.8 (Solaris 2.4..8) - Ultrix 4.x + Ultrix 4.x (well, that was long ago) or something closely resemblant. @@ -202,7 +204,8 @@ In order to install or upgrade Postfix: - Run the INSTALL.sh script as the super-user: - # sh INSTALL.sh + # make install (interactive version, first time install) + # make install 1 (i.e., send + multiple recipients per delivery), the per-transport destination + concurrency limit controls the number of simultaneous deliveries + to the same domain. This is the default behavior for all other + Postfix delivery agents. + +The default settings are: local_destination_recipient_limit = 1, +local_destination_concurrency_limit = 2. Other delivery transports +have default recipient limits (50) and have default per-destination +concurrency limits (10). Major changes with snapshot-20010202 ==================================== diff --git a/postfix/TODO b/postfix/TODO index 280c4c224..04708b4df 100644 --- a/postfix/TODO +++ b/postfix/TODO @@ -7,55 +7,30 @@ expanded via :include:). postconf -f filename -more general relocated feature - perhaps better to bounce recipients +get rid of the relocated feature - perhaps better to bounce recipients at the SMTP port. -use $mydomain when hostname is not FQDN. - -generic daemon that listens on fifo and runs command - make sendmail/smtpd/cleanup output directory/fifo configurable if postdrop scrutinizes input, skip the overhead in the pickup daemon. -luser relay - add a threshold to sendmail etc. stderr logging, so that class "info" messages don't go to stderr. -need a configurable mailbox locking method with system-specific -default, so people don't have to recompile just to turn of fcntl() -locks to work around SUN mailtool. - implement an UCE control to accept mail if the sender domain sender lists us as MX host (rafal wiosna). By the same token, implement a control to accept mail when the client hostname/parent domain lists us as their MX host. -with recipient delimiter enabled, append the unmatched recipient -of @virtual.domain patterns as extension to right-hand recipient, -for qmail-like virtual mapping. - received: headers should be generated by the cleanup daemon, and client attributes ("with", "from", etc.) should be passed along with the message. This guarantees that forwarded/aliased mail gets stamped with the queue ID. -trivial-rewrite etc.: after reload, close the listen socket and -wait until all clients disconnect. - -In qmgr_entry.c, turn off random walk by default. - toss double-bounce mail even when mail for the local machine is redirected to another box. See mail_addr_double_bounce(). -represent peer as object, not as name + addr arguments - -ignore sender: header when different from envelope? - -smtp client: optionally log every MX host contacted - remote showq access (cookie in maildrop or print some text to inform the user) @@ -63,48 +38,23 @@ defer: explain mail was bounced after N days multiple rewrite processes? -log relay address in addition to host. - gethostbyaddr() uses native name services, which can be slow. can we detect a client that ignores error responses? way to block inbound mail based on recipient suffix? -when client begins with non-SMTP data, log warning - -when non-SMTP follows ".", log warning. - -On linux syslogd needs -/file/name - can Postfix implement one switchboard instead of having all these little lookup tables? make canonical/virtual/etc. table lookup order configurable -allow /file/name or maptype_mapname in $mydestination - -make protocol errors soft errore? There are a lot of broken mailers -out there that sometimes croak and sometimes work. - -require @ in sender/rcpt (another restriction) - -figure out a way to pump recipients into qmgr before concurrency -starts to drop. - pass on client etc/ attributes along with message to delivery agent -pass on configurable info into external process environment - scrutinize file opens in delivery agents just like in qmgr (better: open the file and see if someone compromised the vmailer account and is racing against us). -cleanup: don't run out of memory with large amounts of bcc addresses - -cleanup: permit non-empty extra segment, so that mail posting -software can pass in bcc recipients. - suspend/resume signals + master status (suspended/running) in PID file. Maybe use FIFO instead. But, that means requests do not arrive when the master is stuck. @@ -134,24 +84,9 @@ access. trivial-rewrite: optionally, use DNS to fully qualify hostnames. -smtp: optionally deal with MX records containing an address instead -of a name. - pickup/cleanup/qmgr/local: add options record to control internal features such as canonical/virtual mapping, VERPs etcetera. -smtpd: when deciding if a destination is local, also look at the -virtual map. Perhaps we should move canonical and virtual lookups -back into the rewrite service, but under a different name, so they -do not get in the way if we do not want them. - -Queue manager: do not allocate queue slots when a destination -already has more than some threshold. This is to prevent a dead or -slow destination from filling up the queue manager's active queue, -preventing delivery to other destinations. However, such `fairness' -strategies should not cause Postfix to lose the benchmark race, so -we must be fair and smart at the same time :-) - Add hook for (domain, user database) support. This is needed if you have lots of real domains and can't afford a separate master.cf delivery agent entry for each domain. @@ -159,9 +94,6 @@ delivery agent entry for each domain. Add support for DBZ databases, using the code from INN. Reportedly, GDB handles large numbers of keys poorly. -Make the number of time bits in the queue ID configurable, or at -least a little larger. - Change the front-end to cleanup protocol so that the front-end sends the expected message size, and so that the cleanup service can report if there is enough space. This is useful only for the @@ -196,40 +128,11 @@ postfix-script: detect and/or build missing alias database. In order to do this we must extract the alias_maps parameter from the main.cf file, and create any missing files with the right ownerships. -SunOS 5.4 sendmail seems to include the null byte in alias keys -and values, like almost every UNIX system; SunOS 5.5 sendmail does -not include these nulls. Need to add support for SunOS 5.4. NIS -alias maps always include the null terminator... - implement the return-receipt-to notification service. -Implement real address rewriting. - -default alias for mail to non-existent users. How useful is this -when the postmaster already gets notices of mail that could not be -delivered by the local mail system? And how do we pass around the -original envelope recipient once it has been "aliased" to the -address for non-existent users? - -owner-default alias to capture all mailing list errors. Or perhaps -they should just set up the appropriate owner-foo aliases in their -alias database? - -make mail_params module the main config interface; no calls from -config.c to routines in mail_params.c - -resolve/rewrite clients should share connection - -postfix-script: make sure permissions of queue (and anything below) -are sane. - bounce/defer: provide attribute-value interface, for better logging (expanded-from etc.) and non-delivery reports. -Postfix-Options: header, to turn on qmail-like VERPs. But, these -must be accessible only for locally-posted mail (not mail that -arrives via UUCP). - Maintain per-client short-term host status, so we can slow down unreasonable clients @@ -248,27 +151,10 @@ True ETRN means kick the host out of the queue manager's "dead hosts" table & move mail from the "hold" queue for that site to the incoming queue. -Option to make a copy of all mail passing through the mail system. - -The message ID is built by concatenating the time of day in seconds -with the queue id. We must ensure that a queue id is unique for at -least one second, otherwise multiple messages will have the same -message ID. Queue ids will always collide after a while. The NFS -generation number for the queue file would be useful, but there is -no portable interface to get it, and we cannot depend on the system -having NFS support enabled. If a 1-microsecond resolution is -sufficient, we could compose the queue ID from the inode number -plus 6 decimal digits or 5 hex ones for the time in microseconds. -Or, use a smarter encoding with more bits per character. - postfix-script: make sure that each queue file matches its file id or we might lose mail. postfix-script: do database fixups as the unprivileged user -Put a version file in the conf directory or add option to vmail -control command to print the version (requires vmconf tool that -can query main.cf.). - Maintain a pool of pre-allocated queue files, to eliminate file creation and deletion overhead. diff --git a/postfix/VIRTUAL_README b/postfix/VIRTUAL_README index 00db8dd23..12005afb0 100644 --- a/postfix/VIRTUAL_README +++ b/postfix/VIRTUAL_README @@ -8,6 +8,10 @@ Purpose of this software You can use the virtual delivery agent for mailbox delivery of some or all domains that are handled by a machine. +This mechanism is different from virtual domains that are implemented +by translating each virtual address into a real local user. For +that, see the virtual(5) manual page. + This is what Andrew McNamara wrote when he made the virtual delivery agent available. @@ -16,12 +20,12 @@ It looks up the location, uid and gid of user mailboxes via separate maps, and the mailbox location map can specify either mailbox or maildir delivery (controlled by trailing slash on mailbox name). -The agent does not support aliases or .forwards (use the virtual -table instead), and therefore doesn't support file or program -aliases. This choice was made to simplify and streamline the code -(it allowed me to dispense with 70% of local's code - mostly the -bits that are a security headache) - if you need this functionality, -this agent isn't for you. +The agent does not support user+foo address extensions, aliases or +.forward files (use the virtual table instead), and therefore +doesn't support file or program aliases. This choice was made to +simplify and streamline the code (it allowed me to dispense with +70% of local's code - mostly the bits that are a security headache) +- if you need this functionality, this agent isn't for you. It also doesn't support writing to a common spool as root and then chowning the mailbox to the user - I felt this functionality didn't @@ -30,8 +34,7 @@ fit with my overall aims." [End of Andrew McNamara's words] The result is the most secure local delivery agent that you will -find with Postfix. All deliveries are done with the privileges of -the recipient. +find with Postfix. This delivery agent requires three different lookup tables in order to define its recipients. This is because Postfix table lookups @@ -61,7 +64,8 @@ virtual_mailbox_maps If a recipient is not found the mail is returned to the sender. - For security reasons, regexp maps are not allowed here. + For security reasons, regexp maps are not allowed here, because + their $1 etc. substitutions would open a security hole. The mail administrator is expected to create and chown recipient mailbox files or maildir directories ahead of time. @@ -77,14 +81,16 @@ virtual_uid_maps Recipients are looked up in this map to determine the UID (owner privileges) to be used when writing to the target mailbox. - For security reasons, regexp maps are not allowed here. + For security reasons, regexp maps are not allowed here, because + their $1 etc. substitutions would open a security hole. virtual_gid_maps Recipients are looked up in this map to determine the GID (group privileges) to be used when writing to the target mailbox. - For security reasons, regexp maps are not allowed here. + For security reasons, regexp maps are not allowed here, because + their $1 etc. substitutions would open a security hole. virtual_mailbox_lock @@ -107,8 +113,9 @@ Example 1: using the virtual delivery agent for all local mail ============================================================== This example does not use the Postfix local delivery agent at all. -With this configuration Postfix does no alias expansion, no .forward -file expansion, and no lookups of recipients in /etc/passwd. +With this configuration Postfix does no user+foo address extension, +no alias expansion, no .forward file expansion, and no lookups of +recipients in /etc/passwd. Instead of "hash" specify "dbm" or "btree", depending on your system type. The command "postconf -m" displays possible lookup table diff --git a/postfix/conf/main.cf b/postfix/conf/main.cf index 38ae9fcd8..b170c6c54 100644 --- a/postfix/conf/main.cf +++ b/postfix/conf/main.cf @@ -115,14 +115,67 @@ mail_owner = postfix # a name matches a lookup key. Continue long lines by starting the # next line with whitespace. # -# DO NOT LIST VIRTUAL DOMAINS HERE. LIST THEM IN THE VIRTUAL FILE -# INSTEAD. BE SURE TO READ THE ENTIRE VIRTUAL MANUAL PAGE. -# #mydestination = $myhostname, localhost.$mydomain #mydestination = $myhostname, localhost.$mydomain $mydomain #mydestination = $myhostname, localhost.$mydomain, $mydomain, # mail.$mydomain, www.$mydomain, ftp.$mydomain +# RELAY CONTROL + +# The mynetworks parameter specifies the list of networks that make +# up the local neighborhood. The list is used by the anti-UCE software +# to distinguish local clients from strangers. See permit_mynetworks +# and smtpd_recipient_restrictions in the file sample-smtpd.cf file. +# +# The default is a list of all networks attached to the machine: a +# complete class A network (X.0.0.0/8), a complete class B network +# (X.X.0.0/16), and so on. +# +# YOU MUST CHANGE THIS DEFAULT SETTING IF YOUR ADDRESS BLOCK IS PART +# OF A LARGER ADDRESS RANGE THAT IS OWNED BY YOUR PROVIDER - IT WOULD +# CAUSE POSTFIX TO RELAY MAIL FROM ALL THEIR CUSTOMERS. +# +# If you need stricter control than the default, specify a list of +# network/mask patterns, where the mask specifies the number of bits +# in the network part of a host address. +# +# You can also specify the absolute pathname of a pattern file instead +# of listing the patterns here. +# +#mynetworks = 168.100.189.0/28, 127.0.0.0/8 +#mynetworks = $config_directory/mynetworks + +# The relay_domains parameter restricts what clients this mail system +# will relay mail from, or what destinations this system will relay +# mail to. See the smtpd_recipient_restrictions restriction in the +# file sample-smtpd.cf for detailed information. +# +# By default, Postfix relays mail +# - from "trusted" clients whose IP address matches $mynetworks, +# - from "trusted" clients matching $relay_domains or subdomains thereof, +# - from untrusted clients to destinations that match $relay_domains +# or subdomains thereof, except addresses with sender-specified routing. +# The default relay_domains value is $mydestination. +# +# In addition to the above, the Postfix SMTP server by default accepts mail +# that Postfix is final destination for: +# - destinations that match $inet_interfaces, +# - destinations that match $mydestination +# - destinations that match $virtual_maps. +# These destinations do not need to be listed in $relay_domains. +# +# Specify a list of hosts or domains, /file/name patterns or type:name +# lookup tables, separated by commas and/or whitespace. Continue +# long lines by starting the next line with whitespace. A file name +# is replaced by its contents; a type:name table is matched when a +# (parent) domain appears as lookup key. +# +# NOTE: Postfix will not automatically forward mail for domains that +# list this system as their primary or backup MX host. See the +# permit_mx_backup restriction in the file sample-smtpd.cf. +# +#relay_domains = $mydestination + # INTERNET OR INTRANET # The relayhost parameter specifies the default host to send mail to @@ -322,53 +375,6 @@ mail_owner = postfix #header_checks = regexp:/etc/postfix/filename #header_checks = pcre:/etc/postfix/filename -# The relay_domains parameter restricts what clients this mail system -# will relay mail from, or what destinations this system will relay -# mail to. See the smtpd_recipient_restrictions restriction in the -# file sample-smtpd.cf. -# -# By default, Postfix relays mail -# - from trusted clients whose IP address matches $mynetworks, -# - from trusted clients matching $relay_domains or subdomains thereof, -# - from untrusted clients to destinations that match $relay_domains -# or subdomains thereof, except addresses with sender-specified routing. -# The default relay_domains value is $mydestination. -# -# In addition to the above, the Postfix SMTP server by default accepts mail -# that Postfix is final destination for: -# - destinations that match $inet_interfaces, -# - destinations that match $mydestination -# - destinations that match $virtual_maps. -# These destinations do not need to be listed in $relay_domains. -# -# Specify a list of hosts or domains, /file/name patterns or type:name -# lookup tables, separated by commas and/or whitespace. Continue -# long lines by starting the next line with whitespace. A file name -# is replaced by its contents; a type:name table is matched when a -# (parent) domain appears as lookup key. -# -# NOTE: Postfix will not automatically forward mail for domains that -# list this system as their primary or backup MX host. See the -# permit_mx_backup restriction in the file sample-smtpd.cf. -# -#relay_domains = $mydestination - -# The mynetworks parameter specifies the list of networks that are -# local to this machine. The list is used by the anti-UCE software -# to distinguish local clients from strangers. See permit_mynetworks -# and smtpd_recipient_restrictions in the file sample-smtpd.cf file. -# -# The default is a list of all networks attached to the machine: a -# complete class A network (X.0.0.0/8), a complete class B network -# (X.X.0.0/16), and so on. If you want stricter control, specify a -# list of network/mask patterns, where the mask specifies the number -# of bits in the network part of a host address. You can also specify -# the absolute pathname of a pattern file instead of listing the -# patterns here. -# -#mynetworks = 168.100.189.0/28, 127.0.0.0/8 -#mynetworks = $config_directory/mynetworks - # FAST ETRN SERVICE # # Postfix maintains per-destination logfiles with information about diff --git a/postfix/conf/postfix-script-nosgid b/postfix/conf/postfix-script-nosgid index 25235a208..d2374041a 100755 --- a/postfix/conf/postfix-script-nosgid +++ b/postfix/conf/postfix-script-nosgid @@ -145,7 +145,9 @@ reload) exit 1 } $INFO refreshing the Postfix mail system + $command_directory/postsuper active || exit 1 kill -HUP `sed 1q pid/master.pid` + $command_directory/postsuper & ;; flush) @@ -252,7 +254,8 @@ EOF # See if all queue files are in the right place. - $command_directory/postsuper || exit 1 + $command_directory/postsuper active + $command_directory/postsuper & find corrupt -type f -exec $WARN damaged message: {} \; diff --git a/postfix/conf/postfix-script-sgid b/postfix/conf/postfix-script-sgid index 2cf7f5c38..f86fdc3c9 100755 --- a/postfix/conf/postfix-script-sgid +++ b/postfix/conf/postfix-script-sgid @@ -145,7 +145,9 @@ reload) exit 1 } $INFO refreshing the Postfix mail system + $command_directory/postsuper active || exit 1 kill -HUP `sed 1q pid/master.pid` + $command_directory/postsuper & ;; flush) @@ -253,8 +255,8 @@ EOF # See if all queue files are in the right place. - - $command_directory/postsuper || exit 1 + $command_directory/postsuper active + $command_directory/postsuper & find corrupt -type f -exec $WARN damaged message: {} \; diff --git a/postfix/html/faq.html b/postfix/html/faq.html index e8919e7ca..6f2dc9829 100644 --- a/postfix/html/faq.html +++ b/postfix/html/faq.html @@ -26,6 +26,8 @@
How to set up Postfix on the firewall machine so that it relays -mail for my.domain to a gateway machine on the inside, and -so that it refuses mail for *.my.domain? The problem is that -the standard relay_domains -mail relaying restriction allows mail to *.my.domain when -you specify my.domain. +mail for domain.com to a gateway machine on the inside, and +so that it refuses mail for *.domain.com? The problem is that +the default relay_domains +mail relaying restriction allows mail to *.domain.com when +you specify domain.com.
+ +Specify explicit settings for smtpd_recipient_restrictions +and for mynetworks that allow +local systems to send mail anywhere, and that allow remote systems +to send mail only to user@domain.com.
/etc/postfix/main.cf: - mydestination = $myhostname, my.domain, localhost.my.domain - relay_domains = + myorigin = domain.com + mydestination = domain.com transport_maps = hash:/etc/postfix/transport + mynetworks = 12.34.56.0/24 + smtpd_recipient_restrictions = permit_mynetworks reject_unauth_destination /etc/postfix/transport: - my.domain smtp:inside-gateway.my.domain (forwards user@domain) - .my.domain smtp:inside-gateway.my.domain (forwards user@firewall) + domain.com smtp:inside-gateway.domain.com (forwards user@domain) /etc/postfix/master.cf: Comment out the local delivery agent @@ -806,6 +836,81 @@ delivery agent deals with undeliverable mail.
+Running hundreds of Postfix processes on FreeBSD
+ +With hundreds of Postfix processes, the kernel will eventually +run out of file handles; after that, it will run out of sockets. + ++ +To set kernel parameters at boot time, add the following lines to +the /boot/loader.conf file (this is specific to FreeBSD 4.x): + +
+ +
++ ++kern.ipc.maxsockets="5000" +kern.maxfiles="16384" +kern.maxfilesperproc="16384" +kern.ipc.nmbclusters="65536" +++ +To set kernel parameters at run time execute the following commands +as root (this is specific to FreeBSD 4.x): + +
+ +
++ ++# sysctl -w kern.ipc.maxsockets=5000 +# sysctl -w kern.maxfiles=16384 +# sysctl -w kern.maxfilesperproc=16384 +# sysctl -w kern.ipc.nmbclusters=65536 ++
+ +Running hundreds of Postfix processes on Linux
+ +When you increase the number of Postfix processes into the hundreds, +the kernel will eventually run out of file handles; after that it +is likely to run out of process slots. + ++ +To set parameters at boot time on Linux systems that have +/etc/sysctl.conf, add the following lines: + +
+ +
++ ++fs.file-max = 16384 +kernel.threads-max = 2048 +++ +To set kernel parameters at run time, execute the following +commands as root: + +
+ +
++ ++# echo 16384 > /proc/sys/fs/file-max +# echo 2048 > /proc/sys/kernel/threads-max ++
+Too much mail in the incoming queue
@@ -2398,7 +2503,7 @@ with Postfix and HylaFax. Here's the setup used:/etc/postfix/master.cf: - fax unix - n n - - pipe + fax unix - n n - 1 pipe flags= user=fax argv=/usr/bin/faxmail -d -n ${user} /etc/postfix/transport: @@ -2411,6 +2516,12 @@ with Postfix and HylaFax. Here's the setup used:+The process limit of 1 in the master.cf file is necessary +with fax software that cannot handle multiple requests at the same +time. It won't hurt otherwise. + +
+ The fax_destination_recipient_limit entry (by Simon, Mr. Simix) is necessary with fax software that can't have more than one destination on its command line. It won't hurt otherwise. @@ -2423,7 +2534,7 @@ types Postfix supports, use the command postconf -m.
-Note: be sure to not advertise fax.your.domain in the DNS... +Note: be sure to not advertise fax.your.domain in the DNS :-)
@@ -2461,9 +2572,9 @@ Postfix first.-Do not use the above command on a running Postfix system, because -it can delete files that belong to new mail that arrives while you -are deleting queue files. +Do not use the above find command on a running Postfix +system, because it can delete files that belong to new mail that +arrives while you are deleting queue files.
diff --git a/postfix/html/lmtp.8.html b/postfix/html/lmtp.8.html index c68540a97..653d5d8e4 100644 --- a/postfix/html/lmtp.8.html +++ b/postfix/html/lmtp.8.html @@ -29,21 +29,22 @@ LMTP(8) LMTP(8) specified in the Postfix transport(5) table, has the form: unix:pathname - Connect to the UNIX-domain server that is bound to - the specified pathname. If the process runs - chrooted, an absolute pathname is interpreted rela- - tive to the changed root directory. + Connect to the local UNIX-domain server that is + bound to the specified pathname. If the process + runs chrooted, an absolute pathname is interpreted + relative to the changed root directory. inet:host, inet:host:port (symbolic host) inet:[addr], inet:[addr]:port (numeric host) Connect to the specified IPV4 TCP port on the spec- - ified host. If no port is specified, connect to the - port defined as lmtp in services(4). If no such - service is found, the lmtp_tcp_port configuration - parameter (default value of 24) will be used. + ified local or remote host. If no port is speci- + fied, connect to the port defined as lmtp in ser- + vices(4). If no such service is found, the + lmtp_tcp_port configuration parameter (default + value of 24) will be used. - The LMTP client does not perform MX (mail + The LMTP client does not perform MX (mail exchanger) lookups since those are defined only for mail delivery via SMTP. @@ -52,13 +53,12 @@ LMTP(8) LMTP(8) SECURITY The LMTP client is moderately security-sensitive. It talks - to LMTP servers and to DNS servers on the network. The + to LMTP servers and to DNS servers on the network. The LMTP client can be run chrooted at fixed low privilege. STANDARDS RFC 821 (SMTP protocol) RFC 1651 (SMTP service extensions) - RFC 1870 (Message Size Declaration) @@ -71,60 +71,60 @@ LMTP(8) LMTP(8) LMTP(8) LMTP(8) + RFC 1870 (Message Size Declaration) RFC 2033 (LMTP protocol) RFC 2197 (Pipelining) RFC 2554 (AUTH command) DIAGNOSTICS - 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. - Depending on the setting of the notify_classes parameter, - the postmaster is notified of bounces, protocol problems, + Depending on the setting of the notify_classes parameter, + the postmaster is notified of bounces, protocol problems, and of other trouble. BUGS CONFIGURATION PARAMETERS - The following main.cf parameters are especially relevant - to this program. See the Postfix main.cf file for syntax - details and for default values. Use the postfix reload + The following main.cf parameters are especially relevant + to this program. See the Postfix main.cf file for syntax + details and for default values. Use the postfix reload command after a configuration change. Miscellaneous debug_peer_level - Verbose logging level increment for hosts that + Verbose logging level increment for hosts that match a pattern in the debug_peer_list parameter. debug_peer_list - List of domain or network patterns. When a remote - host matches a pattern, increase the verbose log- - ging level by the amount specified in the + List of domain or network patterns. When a remote + host matches a pattern, increase the verbose log- + ging level by the amount specified in the debug_peer_level parameter. error_notice_recipient - Recipient of protocol/policy/resource/software + Recipient of protocol/policy/resource/software error notices. notify_classes - When this parameter includes the protocol class, - send mail to the postmaster with transcripts of + When this parameter includes the protocol class, + send mail to the postmaster with transcripts of LMTP sessions with protocol errors. lmtp_skip_quit_response - Do not wait for the server response after sending + Do not wait for the server response after sending QUIT. lmtp_tcp_port - The TCP port to be used when connecting to a LMTP - server. Used as backup if the lmtp service is not + The TCP port to be used when connecting to a LMTP + server. Used as backup if the lmtp service is not found in services(4). Authentication controls lmtp_enable_sasl_auth - Enable per-session authentication as per RFC 2554 - (SASL). By default, Postfix is built without SASL - support. + Enable per-session authentication as per RFC 2554 + (SASL). By default, Postfix is built without SASL @@ -137,9 +137,11 @@ LMTP(8) LMTP(8) LMTP(8) LMTP(8) + support. + lmtp_sasl_password_maps Lookup tables with per-host or domain name:password - entries. No entry for a host means no attempt to + entries. No entry for a host means no attempt to authenticate. lmtp_sasl_security_options @@ -162,35 +164,33 @@ LMTP(8) LMTP(8) Resource controls lmtp_cache_connection - Should we cache the connection to the LMTP server? - The effectiveness of cached connections will be - determined by the number of LMTP servers in use, - and the concurrency limit specified for the LMTP + Should we cache the connection to the LMTP server? + The effectiveness of cached connections will be + determined by the number of LMTP servers in use, + and the concurrency limit specified for the LMTP client. Cached connections are closed under any of the following conditions: - o The LMTP client idle time limit is reached. - This limit is specified with the Postfix + o The LMTP client idle time limit is reached. + This limit is specified with the Postfix max_idle configuration parameter. - o A delivery request specifies a different + o A delivery request specifies a different destination than the one currently cached. o The per-process limit on the number of delivery requests is reached. This limit is - specified with the Postfix max_use configu- + specified with the Postfix max_use configu- ration parameter. - o Upon the onset of another delivery request, - the LMTP server associated with the current - session does not respond to the RSET com- + o Upon the onset of another delivery request, + the LMTP server associated with the current + session does not respond to the RSET com- mand. transport_destination_concurrency_limit Limit the number of parallel deliveries to the same - destination via this mail delivery transport. - transport is the name of the service as specified - in the master.cf file. The default limit is taken + destination via this mail delivery transport. @@ -203,59 +203,59 @@ LMTP(8) LMTP(8) LMTP(8) LMTP(8) - from the default_destination_concurrency_limit + transport is the name of the service as specified + in the master.cf file. The default limit is taken + from the default_destination_concurrency_limit parameter. transport_destination_recipient_limit Limit the number of recipients per message delivery - via this mail delivery transport. transport is the - name of the service as specified in the master.cf - file. The default limit is taken from the + via this mail delivery transport. transport is the + name of the service as specified in the master.cf + file. The default limit is taken from the default_destination_recipient_limit parameter. - This parameter becomes significant if the LMTP - client is used for local delivery. Some LMTP - servers can optimize delivery of the same message + This parameter becomes significant if the LMTP + client is used for local delivery. Some LMTP + servers can optimize delivery of the same message to multiple recipients. The default limit for local mail delivery is 1. Setting this parameter to 0 will lead to an - unbounded number of recipients per delivery. How- - ever, this could be risky since it may make the - machine vulnerable to running out of resources if - messages are encountered with an inordinate number - of recipients. Exercise care when setting this + unbounded number of recipients per delivery. How- + ever, this could be risky since it may make the + machine vulnerable to running out of resources if + messages are encountered with an inordinate number + of recipients. Exercise care when setting this parameter. Timeout controls - The default time unit is seconds; an explicit time unit - can be specified by appending a one-letter suffix to the - value: s (seconds), m (minutes), h (hours), d (days) or w + The default time unit is seconds; an explicit time unit + can be specified by appending a one-letter suffix to the + value: s (seconds), m (minutes), h (hours), d (days) or w (weeks). lmtp_connect_timeout Timeout for opening a connection to the LMTP - server. If no connection can be made within the + server. If no connection can be made within the deadline, the message is deferred. lmtp_lhlo_timeout - Timeout for sending the LHLO command, and for + Timeout for sending the LHLO command, and for receiving the server response. lmtp_mail_timeout - Timeout for sending the MAIL FROM command, and for + Timeout for sending the MAIL FROM command, and for receiving the server response. lmtp_rcpt_timeout - Timeout for sending the RCPT TO command, and for + Timeout for sending the RCPT TO command, and for receiving the server response. lmtp_data_init_timeout - Timeout for sending the DATA command, and for + Timeout for sending the DATA command, and for receiving the server response. - lmtp_data_xfer_timeout - Timeout for sending the message content. @@ -269,18 +269,21 @@ LMTP(8) LMTP(8) LMTP(8) LMTP(8) + lmtp_data_xfer_timeout + Timeout for sending the message content. + lmtp_data_done_timeout Timeout for sending the "." command, and for - receiving the server response. When no response is - received, a warning is logged that the mail may be + receiving the server response. When no response is + received, a warning is logged that the mail may be delivered multiple times. lmtp_rset_timeout - Timeout for sending the RSET command, and for + Timeout for sending the RSET command, and for receiving the server response. lmtp_quit_timeout - Timeout for sending the QUIT command, and for + Timeout for sending the QUIT command, and for receiving the server response. SEE ALSO @@ -293,7 +296,7 @@ LMTP(8) LMTP(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) @@ -323,9 +326,6 @@ LMTP(8) LMTP(8) - - - 5 diff --git a/postfix/html/local.8.html b/postfix/html/local.8.html index 36c800201..04aa4eb83 100644 --- a/postfix/html/local.8.html +++ b/postfix/html/local.8.html @@ -470,11 +470,13 @@ LOCAL(8) LOCAL(8) Security controls allow_mail_to_commands Restrict the usage of mail delivery to external - command. + command. Specify zero or more of: alias, forward, + include. allow_mail_to_files - Restrict the usage of mail delivery to external - file. + Restrict the usage of mail delivery to external + file. Specify zero or more of: alias, forward, + include. command_expansion_filter What characters are allowed to appear in $name @@ -522,8 +524,6 @@ LOCAL(8) LOCAL(8) - - 8 diff --git a/postfix/makedefs b/postfix/makedefs index d0cea5588..2f110f03f 100644 --- a/postfix/makedefs +++ b/postfix/makedefs @@ -218,7 +218,7 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543 RANLIB=echo SYSLIBS="-lresolv -lsocket -lnsl" ;; -Rhapsody.5*|Darwin.1.2*) +Rhapsody.5*|Darwin.1.*) SYSTYPE=RHAPSODY5 # Use the native compiler by default : ${CC=cc} diff --git a/postfix/man/man8/lmtp.8 b/postfix/man/man8/lmtp.8 index bca8c187c..0521d53e5 100644 --- a/postfix/man/man8/lmtp.8 +++ b/postfix/man/man8/lmtp.8 @@ -27,14 +27,14 @@ The LMTP client connects to the destination specified in the message delivery request. The destination, usually specified in the Postfix \fBtransport\fR(5) table, has the form: .IP \fBunix\fR:\fIpathname\fR -Connect to the UNIX-domain server that is bound to the specified +Connect to the local UNIX-domain server that is bound to the specified \fIpathname\fR. If the process runs chrooted, an absolute pathname is interpreted relative to the changed root directory. .IP "\fBinet\fR:\fIhost\fR, \fBinet\fB:\fIhost\fR:\fIport\fR (symbolic host)" .IP "\fBinet\fR:[\fIaddr\fR], \fBinet\fR:[\fIaddr\fR]:\fIport\fR (numeric host)" -Connect to the specified IPV4 TCP port on the specified host. If no -port is specified, connect to the port defined as \fBlmtp\fR in -\fBservices\fR(4). +Connect to the specified IPV4 TCP port on the specified local or +remote host. If no port is specified, connect to the port defined as +\fBlmtp\fR in \fBservices\fR(4). If no such service is found, the \fBlmtp_tcp_port\fR configuration parameter (default value of 24) will be used. diff --git a/postfix/man/man8/local.8 b/postfix/man/man8/local.8 index 8f3806515..db1f94677 100644 --- a/postfix/man/man8/local.8 +++ b/postfix/man/man8/local.8 @@ -384,8 +384,10 @@ Set to zero to disable the limit. .fi .IP \fBallow_mail_to_commands\fR Restrict the usage of mail delivery to external command. +Specify zero or more of: \fBalias\fR, \fBforward\fR, \fBinclude\fR. .IP \fBallow_mail_to_files\fR Restrict the usage of mail delivery to external file. +Specify zero or more of: \fBalias\fR, \fBforward\fR, \fBinclude\fR. .IP \fBcommand_expansion_filter\fR What characters are allowed to appear in $name expansions of mailbox_command. Illegal characters are replaced by underscores. diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 8cac93945..cf789375e 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -617,7 +617,7 @@ extern int var_debug_peer_level; * subdirectories, and how deep the forest is. */ #define VAR_HASH_QUEUE_NAMES "hash_queue_names" -#define DEF_HASH_QUEUE_NAMES "active,bounce,defer,flush" +#define DEF_HASH_QUEUE_NAMES "incoming,active,deferred,bounce,defer,flush" extern char *var_hash_queue_names; #define VAR_HASH_QUEUE_DEPTH "hash_queue_depth" @@ -1048,7 +1048,7 @@ extern int var_unk_client_code; #define REJECT_INVALID_HOSTNAME "reject_invalid_hostname" #define VAR_BAD_NAME_CODE "invalid_hostname_reject_code" -#define DEF_BAD_NAME_CODE 501 +#define DEF_BAD_NAME_CODE 501 /* SYNTAX */ extern int var_bad_name_code; #define REJECT_UNKNOWN_HOSTNAME "reject_unknown_hostname" @@ -1060,7 +1060,7 @@ extern int var_unk_name_code; #define REJECT_NON_FQDN_SENDER "reject_non_fqdn_sender" #define REJECT_NON_FQDN_RCPT "reject_non_fqdn_recipient" #define VAR_NON_FQDN_CODE "non_fqdn_reject_code" -#define DEF_NON_FQDN_CODE 504 +#define DEF_NON_FQDN_CODE 504 /* POLICY */ extern int var_non_fqdn_code; #define REJECT_UNKNOWN_SENDDOM "reject_unknown_sender_domain" @@ -1201,10 +1201,6 @@ extern char *var_virt_uid_maps; #define DEF_VIRT_GID_MAPS "" extern char *var_virt_gid_maps; -#define VAR_VIRT_USEDOTLOCK "virtual_usedotlock" -#define DEF_VIRT_USEDOTLOCK 0 -extern bool var_virt_usedotlock; - #define VAR_VIRT_MINUID "virtual_minimum_uid" #define DEF_VIRT_MINUID 100 extern int var_virt_minimum_uid; diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index a1c3a8171..7482f815e 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Snapshot-20010204" +#define DEF_MAIL_VERSION "Snapshot-20010222" extern char *var_mail_version; /* LICENSE diff --git a/postfix/src/lmtp/lmtp.c b/postfix/src/lmtp/lmtp.c index b9bc3c481..09572082a 100644 --- a/postfix/src/lmtp/lmtp.c +++ b/postfix/src/lmtp/lmtp.c @@ -21,14 +21,14 @@ /* delivery request. The destination, usually specified in the Postfix /* \fBtransport\fR(5) table, has the form: /* .IP \fBunix\fR:\fIpathname\fR -/* Connect to the UNIX-domain server that is bound to the specified +/* Connect to the local UNIX-domain server that is bound to the specified /* \fIpathname\fR. If the process runs chrooted, an absolute pathname /* is interpreted relative to the changed root directory. /* .IP "\fBinet\fR:\fIhost\fR, \fBinet\fB:\fIhost\fR:\fIport\fR (symbolic host)" /* .IP "\fBinet\fR:[\fIaddr\fR], \fBinet\fR:[\fIaddr\fR]:\fIport\fR (numeric host)" -/* Connect to the specified IPV4 TCP port on the specified host. If no -/* port is specified, connect to the port defined as \fBlmtp\fR in -/* \fBservices\fR(4). +/* Connect to the specified IPV4 TCP port on the specified local or +/* remote host. If no port is specified, connect to the port defined as +/* \fBlmtp\fR in \fBservices\fR(4). /* If no such service is found, the \fBlmtp_tcp_port\fR configuration /* parameter (default value of 24) will be used. /* diff --git a/postfix/src/local/local.c b/postfix/src/local/local.c index 068d61e08..1118acd18 100644 --- a/postfix/src/local/local.c +++ b/postfix/src/local/local.c @@ -356,8 +356,10 @@ /* .fi /* .IP \fBallow_mail_to_commands\fR /* Restrict the usage of mail delivery to external command. +/* Specify zero or more of: \fBalias\fR, \fBforward\fR, \fBinclude\fR. /* .IP \fBallow_mail_to_files\fR /* Restrict the usage of mail delivery to external file. +/* Specify zero or more of: \fBalias\fR, \fBforward\fR, \fBinclude\fR. /* .IP \fBcommand_expansion_filter\fR /* What characters are allowed to appear in $name expansions of /* mailbox_command. Illegal characters are replaced by underscores. @@ -637,7 +639,7 @@ static void pre_init(char *unused_name, char **unused_argv) * also affects delivery to command. * * A file size limit protects the machine against runaway software errors. - * It is not suitable to enfoce mail quota, because users can get around + * It is not suitable to enforce mail quota, because users can get around * mail quota by delivering to /file/name or to |command. * * We can't have mailbox size limit smaller than the message size limit, diff --git a/postfix/src/nqmgr/qmgr_deliver.c b/postfix/src/nqmgr/qmgr_deliver.c index b064210d6..8a06746ce 100644 --- a/postfix/src/nqmgr/qmgr_deliver.c +++ b/postfix/src/nqmgr/qmgr_deliver.c @@ -126,9 +126,10 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream) char *cp; /* - * With local delivery, the queue name is user@nexthop, so that we can - * implement per-recipient concurrency limits. The delivery agent - * protocol expects nexthop only. + * With mail transports that accept only one recipient per delivery, the + * queue name is user@nexthop, so that we can implement per-recipient + * concurrency limits. However, the delivery agent protocol expects + * nexthop only, so we must strip off the recipient local part. */ mail_print(stream, "%d %s %s %ld %ld %s %s %s %s %ld", message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT, diff --git a/postfix/src/nqmgr/qmgr_message.c b/postfix/src/nqmgr/qmgr_message.c index 45bb0f78a..ad19aebae 100644 --- a/postfix/src/nqmgr/qmgr_message.c +++ b/postfix/src/nqmgr/qmgr_message.c @@ -670,8 +670,11 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) /* * Queues are identified by the transport name and by the next-hop - * hostname. When the destination is local (no next hop), derive the - * queue name from the recipient name. XXX Should split the address + * hostname. When the delivery agent accepts only one recipient per + * delivery, give each recipient its own queue, so that deliveries to + * different recipients of the same message can happen in parallel. + * This also has the benefit that one bad recipient cannot interfere + * with deliveries to other recipients. XXX Should split the address * on the recipient delimiter if one is defined, but doing a proper * job requires knowledge of local aliases. Yuck! I don't want to * duplicate delivery-agent specific knowledge in the queue manager. @@ -679,23 +682,27 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) * queue name. Should have separate fields for queue name and for * destination. */ - if ((at = strrchr(STR(reply.recipient), '@')) == 0 - || resolve_local(at + 1)) { - len = (at != 0 ? (at - STR(reply.recipient)) - : strlen(STR(reply.recipient))); + at = strrchr(STR(reply.recipient), '@'); + len = (at ? (at - STR(reply.recipient)) : strlen(STR(reply.recipient))); + + if ((transport = qmgr_transport_find(STR(reply.transport))) == 0) + transport = qmgr_transport_create(STR(reply.transport)); + if (transport->recipient_limit == 1) { VSTRING_SPACE(reply.nexthop, len + 1); memmove(STR(reply.nexthop) + len + 1, STR(reply.nexthop), LEN(reply.nexthop) + 1); memcpy(STR(reply.nexthop), STR(reply.recipient), len); STR(reply.nexthop)[len] = '@'; lowercase(STR(reply.nexthop)); + } - /* - * Discard mail to the local double bounce address here, so this - * system can run without a local delivery agent. They'd still - * have to configure something for mail directed to the local - * postmaster, though, but that is an RFC requirement anyway. - */ + /* + * Discard mail to the local double bounce address here, so this + * system can run without a local delivery agent. They'd still have + * to configure something for mail directed to the local postmaster, + * though, but that is an RFC requirement anyway. + */ + if (at == 0 || resolve_local(at + 1)) { if (strncasecmp(STR(reply.recipient), var_double_bounce_sender, len) == 0 && !var_double_bounce_sender[len]) { diff --git a/postfix/src/pipe/pipe.c b/postfix/src/pipe/pipe.c index 60c1fb48e..ee9154c6d 100644 --- a/postfix/src/pipe/pipe.c +++ b/postfix/src/pipe/pipe.c @@ -291,8 +291,6 @@ static int parse_callback(int type, VSTRING *buf, char *context) *expand_flag |= PIPE_FLAG_EXTENSION; else if (strcmp(vstring_str(buf), PIPE_DICT_MAILBOX) == 0) *expand_flag |= PIPE_FLAG_MAILBOX; - else if (strcmp(vstring_str(buf), PIPE_DICT_SIZE) == 0) - *expand_flag |= PIPE_FLAG_SIZE; } return (0); } @@ -397,14 +395,6 @@ static ARGV *expand_argv(char **argv, RECIPIENT_LIST *rcpt_list, long data_size) dict_update(PIPE_DICT_TABLE, PIPE_DICT_MAILBOX, STR(buf)); } - /* - * This argument contains $size. - */ - if (expand_flag & PIPE_FLAG_SIZE) { - vstring_sprintf(buf, "%ld", data_size); - dict_update(PIPE_DICT_TABLE, PIPE_DICT_SIZE, STR(buf)); - } - /* * Done. */ @@ -698,6 +688,10 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv) dict_update(PIPE_DICT_TABLE, PIPE_DICT_SENDER, request->sender); dict_update(PIPE_DICT_TABLE, PIPE_DICT_NEXTHOP, request->nexthop); + buf = vstring_alloc(10); + vstring_sprintf(buf, "%ld", (long) request->data_size); + dict_update(PIPE_DICT_TABLE, PIPE_DICT_SIZE, STR(buf)); + vstring_free(buf); expanded_argv = expand_argv(attr.command, rcpt_list, request->data_size); export_env = argv_split(var_export_environ, ", \t\r\n"); diff --git a/postfix/src/qmgr/qmgr_deliver.c b/postfix/src/qmgr/qmgr_deliver.c index 003c4373e..1a605dd1f 100644 --- a/postfix/src/qmgr/qmgr_deliver.c +++ b/postfix/src/qmgr/qmgr_deliver.c @@ -121,9 +121,10 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream) char *cp; /* - * With local delivery, the queue name is user@nexthop, so that we can - * implement per-recipient concurrency limits. The delivery agent - * protocol expects nexthop only. + * With mail transports that accept only one recipient per delivery, the + * queue name is user@nexthop, so that we can implement per-recipient + * concurrency limits. However, the delivery agent protocol expects + * nexthop only, so we must strip off the recipient local part. */ mail_print(stream, "%d %s %s %ld %ld %s %s %s %s %ld", message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT, diff --git a/postfix/src/qmgr/qmgr_entry.c b/postfix/src/qmgr/qmgr_entry.c index 6e2fb3b2e..1d5c3afac 100644 --- a/postfix/src/qmgr/qmgr_entry.c +++ b/postfix/src/qmgr/qmgr_entry.c @@ -47,7 +47,7 @@ /* the queue file to the deferred queue; send bounce reports to the /* message originator (see qmgr_active_done()). /* -/* qmgr_entry_select() randomly selects one entry from the named +/* qmgr_entry_select() selects the next entry from the named /* per-site queue's `todo' list for actual delivery. The entry is /* moved to the queue's `busy' list: the list of messages being /* delivered. diff --git a/postfix/src/qmgr/qmgr_message.c b/postfix/src/qmgr/qmgr_message.c index 4f31a25b3..7ec5521d9 100644 --- a/postfix/src/qmgr/qmgr_message.c +++ b/postfix/src/qmgr/qmgr_message.c @@ -550,8 +550,11 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) /* * Queues are identified by the transport name and by the next-hop - * hostname. When the destination is local (no next hop), derive the - * queue name from the recipient name. XXX Should split the address + * hostname. When the delivery agent accepts only one recipient per + * delivery, give each recipient its own queue, so that deliveries to + * different recipients of the same message can happen in parallel. + * This also has the benefit that one bad recipient cannot interfere + * with deliveries to other recipients. XXX Should split the address * on the recipient delimiter if one is defined, but doing a proper * job requires knowledge of local aliases. Yuck! I don't want to * duplicate delivery-agent specific knowledge in the queue manager. @@ -559,23 +562,27 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) * queue name. Should have separate fields for queue name and for * destination. */ - if ((at = strrchr(STR(reply.recipient), '@')) == 0 - || resolve_local(at + 1)) { - len = (at != 0 ? (at - STR(reply.recipient)) - : strlen(STR(reply.recipient))); + at = strrchr(STR(reply.recipient), '@'); + len = (at ? (at - STR(reply.recipient)) : strlen(STR(reply.recipient))); + + if ((transport = qmgr_transport_find(STR(reply.transport))) == 0) + transport = qmgr_transport_create(STR(reply.transport)); + if (transport->recipient_limit == 1) { VSTRING_SPACE(reply.nexthop, len + 1); memmove(STR(reply.nexthop) + len + 1, STR(reply.nexthop), LEN(reply.nexthop) + 1); memcpy(STR(reply.nexthop), STR(reply.recipient), len); STR(reply.nexthop)[len] = '@'; lowercase(STR(reply.nexthop)); + } - /* - * Discard mail to the local double bounce address here, so this - * system can run without a local delivery agent. They'd still - * have to configure something for mail directed to the local - * postmaster, though, but that is an RFC requirement anyway. - */ + /* + * Discard mail to the local double bounce address here, so this + * system can run without a local delivery agent. They'd still have + * to configure something for mail directed to the local postmaster, + * though, but that is an RFC requirement anyway. + */ + if (at == 0 || resolve_local(at + 1)) { if (strncasecmp(STR(reply.recipient), var_double_bounce_sender, len) == 0 && !var_double_bounce_sender[len]) { diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in index 90dd044a2..f792599c2 100644 --- a/postfix/src/util/Makefile.in +++ b/postfix/src/util/Makefile.in @@ -22,7 +22,8 @@ SRCS = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \ stream_connect.c stream_trigger.c dict_regexp.c mac_expand.c \ clean_env.c watchdog.c spawn_command.c duplex_pipe.c sane_rename.c \ sane_link.c unescape.c timed_read.c timed_write.c dict_tcp.c \ - hex_quote.c dict_alloc.c rand_sleep.c sane_time.c dict_debug.c + hex_quote.c dict_alloc.c rand_sleep.c sane_time.c dict_debug.c \ + sane_socketpair.c OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \ close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \ dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \ @@ -46,7 +47,8 @@ OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \ stream_connect.o stream_trigger.o dict_regexp.o mac_expand.o \ clean_env.o watchdog.o spawn_command.o duplex_pipe.o sane_rename.o \ sane_link.o unescape.o timed_read.o timed_write.o dict_tcp.o \ - hex_quote.o dict_alloc.o rand_sleep.o sane_time.o dict_debug.o + hex_quote.o dict_alloc.o rand_sleep.o sane_time.o dict_debug.o \ + sane_socketpair.o HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \ dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \ dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \ @@ -62,7 +64,7 @@ HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \ vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h \ dict_unix.h dict_pcre.h dict_regexp.h mac_expand.h clean_env.h \ watchdog.h spawn_command.h sane_fsops.h dict_tcp.h hex_quote.h \ - sane_time.h + sane_time.h sane_socketpair.h TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \ stream_test.c dup2_pass_on_exec.c WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \ @@ -534,6 +536,7 @@ dup2_pass_on_exec.o: dup2_pass_on_exec.c duplex_pipe.o: duplex_pipe.c duplex_pipe.o: sys_defs.h duplex_pipe.o: iostuff.h +duplex_pipe.o: sane_socketpair.h environ.o: environ.c environ.o: sys_defs.h events.o: events.c @@ -840,6 +843,10 @@ sane_rename.o: sane_rename.c sane_rename.o: sys_defs.h sane_rename.o: msg.h sane_rename.o: sane_fsops.h +sane_socketpair.o: sane_socketpair.c +sane_socketpair.o: sys_defs.h +sane_socketpair.o: msg.h +sane_socketpair.o: sane_socketpair.h sane_time.o: sane_time.c sane_time.o: sys_defs.h sane_time.o: msg.h diff --git a/postfix/src/util/duplex_pipe.c b/postfix/src/util/duplex_pipe.c index 38017ed9e..04f23f6e5 100644 --- a/postfix/src/util/duplex_pipe.c +++ b/postfix/src/util/duplex_pipe.c @@ -34,6 +34,7 @@ /* Utility library. */ #include "iostuff.h" +#include "sane_socketpair.h" /* duplex_pipe - give me a duplex pipe or bust */ @@ -42,7 +43,7 @@ int duplex_pipe(int *fds) #ifdef HAS_DUPLEX_PIPE return (pipe(fds)); #else - return (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)); + return (sane_socketpair(AF_UNIX, SOCK_STREAM, 0, fds)); #endif } diff --git a/postfix/src/util/sane_socketpair.c b/postfix/src/util/sane_socketpair.c new file mode 100644 index 000000000..c1d3568d3 --- /dev/null +++ b/postfix/src/util/sane_socketpair.c @@ -0,0 +1,71 @@ +/*++ +/* NAME +/* sane_socketpair 3 +/* SUMMARY +/* sanitize socketpair() error returns +/* SYNOPSIS +/* #include+/* +/* int sane_socketpair(domain, type, protocol, result) +/* int domain; +/* int type; +/* int protocol; +/* int *result; +/* DESCRIPTION +/* sane_socketpair() implements the socketpair(2) socket call, and +/* skips over silly error results such as EINTR. +/* BUGS +/* Bizarre systems may have other harmless error results. Such +/* systems encourage programers to ignore error results, and +/* penalizes programmers who code defensively. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include "sys_defs.h" +#include +#include +#include + +/* Utility library. */ + +#include "msg.h" +#include "sane_socketpair.h" + +/* sane_socketpair - sanitize socketpair() error returns */ + +int sane_socketpair(int domain, int type, int protocol, int *result) +{ + static int socketpair_ok_errors[] = { + EINTR, + 0, + }; + int count; + int err; + int ret; + + /* + * Solaris socketpair() can fail with EINTR. + */ + while ((ret = socketpair(domain, type, protocol, result)) < 0) { + for (count = 0; /* void */ ; count++) { + if ((err = socketpair_ok_errors[count]) == 0) + return (ret); + if (errno == err) { + msg_warn("socketpair: %m (trying again)"); + sleep(1); + break; + } + } + } + return (ret); +} diff --git a/postfix/src/util/sane_socketpair.h b/postfix/src/util/sane_socketpair.h new file mode 100644 index 000000000..3c8e239a9 --- /dev/null +++ b/postfix/src/util/sane_socketpair.h @@ -0,0 +1,29 @@ +#ifndef _SANE_SOCKETPAIR_H_ +#define _SANE_SOCKETPAIR_H_ + +/*++ +/* NAME +/* sane_socketpair 3h +/* SUMMARY +/* sanitize socketpair() error returns +/* SYNOPSIS +/* #include +/* DESCRIPTION +/* .nf + + /* External interface. */ + +extern int sane_socketpair(int, int, int, int *); + +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +#endif