From 9f6c81ebcdacde034c6a7705f55f79a9b57cac95 Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Sun, 25 Jun 2000 00:00:00 +0000 Subject: [PATCH] snapshot-20000625 --- postfix/FILTER_README | 29 +++-- postfix/HISTORY | 63 +++++++++++ postfix/INSPECT_README | 181 +++++++++++++++++++++++++++++++ postfix/RELEASE_NOTES | 9 ++ postfix/base64/base64decode | Bin 0 -> 83319 bytes postfix/base64/base64encode | Bin 0 -> 83473 bytes postfix/cleanup/Makefile.in | 2 + postfix/conf/sample-ldap.cf | 56 +++++++++- postfix/global/deliver_pass.c | 3 +- postfix/global/deliver_request.c | 15 ++- postfix/global/deliver_request.h | 5 + postfix/global/header_opts.c | 8 +- postfix/global/header_opts.h | 1 + postfix/global/mail_copy.c | 2 +- postfix/global/mail_copy.h | 3 +- postfix/global/mail_params.h | 8 +- postfix/global/mail_version.h | 2 +- postfix/html/faq.html | 7 +- postfix/html/local.8.html | 32 +++--- postfix/html/pipe.8.html | 92 ++++++++-------- postfix/html/smtp.8.html | 24 ++-- postfix/lmtp/lmtp_proto.c | 3 +- postfix/local/dotforward.c | 32 +++++- postfix/local/local.c | 9 +- postfix/local/maildir.c | 4 +- postfix/local/recipient.c | 4 + postfix/makedefs | 2 +- postfix/man/man8/local.8 | 5 +- postfix/man/man8/pipe.8 | 9 +- postfix/man/man8/smtp.8 | 2 + postfix/pipe/pipe.c | 46 +++++++- postfix/qmgr/Makefile.in | 1 + postfix/qmgr/qmgr.h | 3 +- postfix/qmgr/qmgr_deliver.c | 4 +- postfix/qmgr/qmgr_message.c | 6 + postfix/smtp/smtp.c | 4 + postfix/smtp/smtp_proto.c | 3 +- postfix/smtp/smtp_unalias.c | 9 +- postfix/smtpd/smtpd.c | 7 +- postfix/smtpd/smtpd_state.c | 2 + postfix/util/dict_pcre.c | 2 - postfix/util/dict_regexp.c | 2 - postfix/util/vstream.c | 2 +- 43 files changed, 569 insertions(+), 134 deletions(-) create mode 100644 postfix/INSPECT_README create mode 100755 postfix/base64/base64decode create mode 100755 postfix/base64/base64encode diff --git a/postfix/FILTER_README b/postfix/FILTER_README index 7c2284566..c6a3a71c0 100644 --- a/postfix/FILTER_README +++ b/postfix/FILTER_README @@ -1,4 +1,8 @@ This is a very first implementation of Postfix content filtering. +A Postfix content filter re-injects filtered mail back into Postfix. +If all you want is content _inspection_, see the INSPECT_README +file instead. + It involves an incompatible change to queue file formats. Older Postfix versions will reject mail that needs to be content filtered, and will move the queue file to the "corrupt" mail queue subdirectory. @@ -76,18 +80,19 @@ content through run a third-party content filter program. If the mail cannot be captured to file, mail delivery is deferred by terminating with exit status 75 (EX_TEMPFAIL). If the content filter program finds a problem, the mail is bounced by terminating -the filter command with exit status 69 (EX_UNAVAILABLE). If the +the shell script with exit status 69 (EX_UNAVAILABLE). If the content is OK, it is given as input to Postfix sendmail, and the exit status of the filter command is whatever exit status Postfix sendmail produces. -The problem with content filterings like this is that they are not -very robust, because they do not talk a well-defined protocol with -Postfix. If the filter command aborts because of some memory -allocation problem, it will not produce a nice exit status as per -/usr/include/sysexits.h and mail will probably bounce. The same -lack of robustness is possible when the content filtering software -itself runs into a resource problem. +The problem with content filters like this is that they are not +very robust, because the software does not talk a well-defined +protocol with Postfix. If the filter shell script aborts because +the shell runs into some memory allocation problem, the script will +not produce a nice exit status as per /usr/include/sysexits.h and +mail will probably bounce. The same lack of robustness is possible +when the content filtering software itself runs into a resource +problem. I suggest that you play with this script for a while until you are satisfied with the results. Run it as root or as the filter user, @@ -159,7 +164,7 @@ When a queue file has content filtering information, the queue manager will deliver the mail to the specified content filtering regardless of its final destination. -The content filtering can be set up with the Postfix spawn service, +The content filter can be set up with the Postfix spawn service, which is the Postfix equivalent of inetd. For example, to instantiate up to 10 content filtering processes on demand: @@ -184,18 +189,18 @@ For now, it is left up to the Postfix users to come up with a PERL/SMTP framework for Postfix content filtering. If done well, it can be used with other mailers too, which is a nice spin-off. -The simplest content filtering just copies SMTP commands and data +The simplest content filter just copies SMTP commands and data between its inputs and outputs. If it has a problem, all it has to do is to reply to an input of `.' with `550 content rejected', and to disconnect its output side instead of sending `.'. -The job of the content filtering is to either bounce mail with a +The job of the content filter is to either bounce mail with a suitable diagnostic, or to feed the mail back into Postfix through a dedicated listener on port localhost 10026: /etc/postfix/master.cf: localhost:10026 inet n - n - 10 smtpd - -o content_filter= myhostname=localhost.domain.name + -o content_filter= -o myhostname=localhost.domain.name This is just another SMTP server. It is configured NOT to request content filtering for incoming mail, has the same process limit diff --git a/postfix/HISTORY b/postfix/HISTORY index 69089100b..7a478e983 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -4032,3 +4032,66 @@ Apologies for any names omitted. Renamed "content inspection" etc. to "content filtering" in anticipation of a new hook for content inspection that only inspects mail without re-injecting it into Postfix. + +20000601 + + Feature: limit the size of pipe mailer deliveries with the + size=nnn command-line attribute. Patch by Andrew McNamara. + +20000603 + + Bugfix: don't try to do SASL authentication when running + in stand-alone (sendmail -bs) mode. Fix by Liviu Daia. + + Bug: the unauthorized pipelining test fails with single + recipient mail when smtpd_delay_reject = yes. + +20000617 + + Bugfix: conf/sample-ldap.cf was no longer up to date with + reality. Patch by Lamont Jones, HP. + + Bugfix: the maildir delivery routine left temporary files + lying around after unsuccessful delivery (problem reported + by Brian Laughton @ Corp.Axxent.Ca). + +20000619 + + Workaround: if append_dot_mydomain=no, turn on parent domain + search in the Postfix SMTP client, so that mail does not + bounce. Files: smtp/smtp.c, smtp/smtp_unalias.c. + +20000621 + + AIX 4.x had POSIX regular expression support all the time + I was working on Postfix. Beter find out late than never. + +20000623 + + Bugfix: the SMTP server did not reset the so-called junk + command counter after successfull delivery (Mark Hoffman + @ wallst.com). File: smtpd/smtpd.c. + +20000625 + + Cleanup: remove Content-Length from incoming mail. The + sender has no authority over the format of mail as stored + by the receiving system. File: global/header_opts.h. + + Feature: rewrite Mail-Followup-To: as sender. Files: + global/header_opts.[hc]. + + Cleanup: rewrite Reply-To, Errors-To, Return-Receipt-To as + sender, so that address masquerading works as expected. + Files: global/header_opts.c. + + Feature: specify "test_home_directory = yes" to prevent + mail from being delivered to a user whose home directory + is not mounted. File: local/dotforward.c. + + Cleanup: the pipe deliver agent no longer appends a blank + line when the F flag (prepend From_ line) is specified. + Specify the B flag if you need that blank line. The local + delivery agent no longer appends a blank line to mail that + is delivered to external command. Files: pipe/pipe.c, + global/mail_copy.[hc]. diff --git a/postfix/INSPECT_README b/postfix/INSPECT_README new file mode 100644 index 000000000..2b91d3456 --- /dev/null +++ b/postfix/INSPECT_README @@ -0,0 +1,181 @@ +This is a very first implementation of Postfix content inspection. +A Postfix content inspector causes "bad" mail to be bounced. All +other mail is delivered normally. If you want content _inspection_, +which allows you to modify mail content or destination, see the +FILTER_README file instead. + +Content inspection involves an incompatible change to queue file +formats. Older Postfix versions will reject mail that needs to be +content inspected, and will move the queue file to the "corrupt" +mail queue subdirectory. + +This document describes two approaches to content inspection. + +Simple content inspection example +================================= + +The example is relatively simple to set up, but is resource intensive +because it runs a shell script for each message. + +With the shell script as shown you can lose a factor in Postfix +performance for each temporary file that is created and deleted in +the process of content inspection. The performance impact is less +for mail that is submitted or delivered locally, because such +deliveries are not as fast as SMTP transit mail. + +The example assumes that only mail received via SMTP needs to be +content inspected. + + .................................. + . Postfix . + ------smtpd \ /local----- + . -cleanup->queue- . + -----pickup / \smtp------ + . | . + . \pipe------>inspector + .................................. + +Create a dedicated local user account called "inspect". The user +will never log in, and can be given a "*" password and non-existent +shell and home. + +Create a directory /var/spool/inspect that is accessible only to +the "inspect" user. This is where the content inspection software +will store any temporary files. + +Define a content inspection entry in the Postfix master file: + + /etc/postfix/master.cf: + inspect unix - n n - - pipe + user=inspect argv=/some/where/inspect ${sender} ${recipient} + +The filter program can start out as a simple shell script like this: + + #!/bin/sh + + # Localize this + INSPECT_DIR=/var/spool/inspect + + # Exit codes from + EX_TEMPFAIL=75 + EX_UNAVAILABLE=69 + + cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; } + + # Clean up when done or when aborting. + trap "rm -f in.$$; exit" 0 1 2 3 15 + + cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; } + + # inspect queue- . + -----pickup / | \smtp------ + . v . + . smtp . + . | . + ......................|........... + | + v + ................. + . 10025 . + . inspection . + . . + ................. + +To enable content inspection in this manner, specify in main.cf a +new parameter: + + /etc/postfix/main.cf: + content_filter = smtp:localhost:10025 + +This causes Postfix to add one extra content inspection record to +each incoming mail message, with content smtp:localhost:10025. +You can use the same syntax as in the right-hand side of a Postfix +transport table. The content inspection records are added by the +smtpd and pickup servers. + +When a queue file has content inspection information, the queue +manager will deliver the mail to the specified content inspector +before attempting final delivery. + +The content filter can be set up with the Postfix spawn service, +which is the Postfix equivalent of inetd. For example, to instantiate +up to 10 content inspection processes on demand: + + /etc/postfix/master.cf: + localhost:10025 inet n n n - 10 spawn + user=inspect argv=/some/where/inspect + +"inspect" is a dedicated local user account. The user will never +log in, and can be given a "*" password and non-existent shell and +home. + +The spawn server is part of Postfix but is not installed by default. +Edit the top-level Makefile.in file, run "make makefiles", "make", +and "make install". The manual page isn't installed by default, +either. See the spawn.c source file. + +The /some/where/inspect command is most likely a PERL script. PERL +has modules that make talking SMTP easy. + +For now, it is left up to the Postfix users to come up with a +PERL/SMTP framework for Postfix content inspection. If done well, +it can be used with other mailers too, which is a nice spin-off. diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 514f443e8..ff73e4d12 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -1,3 +1,12 @@ +Incompatible changes with snapshot-20000625 +=========================================== + +The local delivery agent no longer appends a blank line to mail +that is delivered to external command. + +The pipe delivery agent no longer appends a blank line when the F +flag is specified. Specify the B flag if you need that blank line. + Incompatible changes with snapshot-20000531 =========================================== diff --git a/postfix/base64/base64decode b/postfix/base64/base64decode new file mode 100755 index 0000000000000000000000000000000000000000..67cbb9b3d08af9af693f4bb8d146c591411ea419 GIT binary patch literal 83319 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ⅈUe| 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 SyHZcvN1DNm+w#z475)!!jvQtH literal 0 HcmV?d00001 diff --git a/postfix/base64/base64encode b/postfix/base64/base64encode new file mode 100755 index 0000000000000000000000000000000000000000..8f1869c0dc268d7671d9a93ea95868d07aab7307 GIT binary patch literal 83473 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, request->queue_name, request->queue_id, request->data_offset, request->data_size, request->nexthop, request->sender, diff --git a/postfix/global/deliver_request.c b/postfix/global/deliver_request.c index ff361736e..a38f0368d 100644 --- a/postfix/global/deliver_request.c +++ b/postfix/global/deliver_request.c @@ -9,6 +9,7 @@ /* typedef struct DELIVER_REQUEST { /* .in +5 /* VSTREAM *fp; +/* int flags; /* char *queue_name; /* char *queue_id; /* long data_offset; @@ -40,6 +41,17 @@ /* A null result means that the client sent bad information or that /* it went away unexpectedly. /* +/* The \fBflags\fR structure member is the bit-wise OR of zero or more +/* of the following: +/* .IP \fBDEL_REQ_FLAG_SUCCESS\fR +/* Delete successful recipients from the queue file. +/* .IP \fBDEL_REQ_FLAG_BOUNCE\fR +/* Delete bounced recipients from the queue file. Currently, +/* this flag is considered to be "always on". +/* .PP +/* The \fBDEL_REQ_FLAG_DEFLT\fR constant provides a convenient shorthand +/* for the most common case: delete successful and bounced recipients. +/* /* The \fIhop_status\fR structure member must be updated /* by the caller when all delivery to the destination in /* \fInexthop\fR should be deferred. The value of the @@ -174,7 +186,8 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) * Extract the queue file name, data offset, and sender address. Abort * the conversation when they send bad information. */ - if (mail_scan(stream, "%s %s %ld %ld %s %s %s %s %ld", + if (mail_scan(stream, "%d %s %s %ld %ld %s %s %s %s %ld", + &request->flags, queue_name, queue_id, &request->data_offset, &request->data_size, nexthop, address, errors_to, return_receipt, &request->arrival_time) != 9) diff --git a/postfix/global/deliver_request.h b/postfix/global/deliver_request.h index 34ab16af9..2406085ff 100644 --- a/postfix/global/deliver_request.h +++ b/postfix/global/deliver_request.h @@ -27,6 +27,7 @@ */ typedef struct DELIVER_REQUEST { VSTREAM *fp; /* stream, shared lock */ + int flags; /* see below */ char *queue_name; /* message queue name */ char *queue_id; /* message queue id */ long data_offset; /* offset to message */ @@ -40,6 +41,10 @@ typedef struct DELIVER_REQUEST { char *hop_status; /* reason if unavailable */ } DELIVER_REQUEST; +#define DEL_REQ_FLAG_DEFLT (DEL_REQ_FLAG_SUCCESS | DEL_REQ_FLAG_BOUNCE) +#define DEL_REQ_FLAG_SUCCESS (1<<0) /* delete successful recipients */ +#define DEL_REQ_FLAG_BOUNCE (1<<1) /* unimplemented */ + typedef struct VSTREAM _deliver_vstream_; extern DELIVER_REQUEST *deliver_request_read(_deliver_vstream_ *); extern int deliver_request_done(_deliver_vstream_ *, DELIVER_REQUEST *, int); diff --git a/postfix/global/header_opts.c b/postfix/global/header_opts.c index e14e31f3c..f4d60544e 100644 --- a/postfix/global/header_opts.c +++ b/postfix/global/header_opts.c @@ -51,13 +51,15 @@ static HEADER_OPTS header_opts[] = { "Apparently-To", HDR_APPARENTLY_TO, HDR_OPT_RECIP, "Bcc", HDR_BCC, HDR_OPT_DROP | HDR_OPT_XRECIP, "Cc", HDR_CC, HDR_OPT_XRECIP, + "Content-Length", HDR_CONTENT_LENGTH, HDR_OPT_DROP, "Delivered-To", HDR_DELIVERED_TO, 0, "Date", HDR_DATE, 0, - "Errors-To", HDR_ERRORS_TO, HDR_OPT_RECIP, + "Errors-To", HDR_ERRORS_TO, HDR_OPT_SENDER, "From", HDR_FROM, HDR_OPT_SENDER, + "Mail-Followup-To", HDR_MAIL_FOLLOWUP_TO, HDR_OPT_SENDER, "Message-Id", HDR_MESSAGE_ID, 0, "Received", HDR_RECEIVED, 0, - "Reply-To", HDR_REPLY_TO, HDR_OPT_RECIP, + "Reply-To", HDR_REPLY_TO, HDR_OPT_SENDER, "Resent-Bcc", HDR_RESENT_BCC, HDR_OPT_DROP | HDR_OPT_XRECIP | HDR_OPT_RR, "Resent-Cc", HDR_RESENT_CC, HDR_OPT_XRECIP | HDR_OPT_RR, "Resent-Date", HDR_RESENT_DATE, HDR_OPT_RR, @@ -67,7 +69,7 @@ static HEADER_OPTS header_opts[] = { "Resent-Sender", HDR_RESENT_SENDER, HDR_OPT_SENDER | HDR_OPT_RR, "Resent-To", HDR_RESENT_TO, HDR_OPT_XRECIP | HDR_OPT_RR, "Return-Path", HDR_RETURN_PATH, HDR_OPT_DROP | HDR_OPT_SENDER, - "Return-Receipt-To", HDR_RETURN_RECEIPT_TO, HDR_OPT_RECIP, + "Return-Receipt-To", HDR_RETURN_RECEIPT_TO, HDR_OPT_SENDER, "Sender", HDR_SENDER, HDR_OPT_SENDER, "To", HDR_TO, HDR_OPT_XRECIP, }; diff --git a/postfix/global/header_opts.h b/postfix/global/header_opts.h index 27c44ddbe..b4e0b83dd 100644 --- a/postfix/global/header_opts.h +++ b/postfix/global/header_opts.h @@ -48,6 +48,7 @@ typedef struct { #define HDR_RETURN_RECEIPT_TO 23 #define HDR_SENDER 24 #define HDR_TO 25 +#define HDR_MAIL_FOLLOWUP_TO 26 /* * Header flags. diff --git a/postfix/global/mail_copy.c b/postfix/global/mail_copy.c index 912f1a7ee..c8fae4f5f 100644 --- a/postfix/global/mail_copy.c +++ b/postfix/global/mail_copy.c @@ -186,7 +186,7 @@ int mail_copy(const char *sender, const char *delivered, corrupt_error = mark_corrupt(src); if (prev_type != REC_TYPE_NORM) vstream_fputs(eol, dst); - if (flags & MAIL_COPY_FROM) + if (flags & MAIL_COPY_BLANK) vstream_fputs(eol, dst); } vstring_free(buf); diff --git a/postfix/global/mail_copy.h b/postfix/global/mail_copy.h index 2c0c743bb..2d8c6ae39 100644 --- a/postfix/global/mail_copy.h +++ b/postfix/global/mail_copy.h @@ -29,9 +29,10 @@ extern int mail_copy(const char *, const char *, VSTREAM *, VSTREAM *, #define MAIL_COPY_DELIVERED (1<<3) /* prepend Delivered-To: */ #define MAIL_COPY_RETURN_PATH (1<<4) /* prepend Return-Path: */ #define MAIL_COPY_DOT (1<<5) /* escape dots - needed for bsmtp */ +#define MAIL_COPY_BLANK (1<<6) /* append blank line */ #define MAIL_COPY_MBOX (MAIL_COPY_FROM | MAIL_COPY_QUOTE | \ MAIL_COPY_TOFILE | MAIL_COPY_DELIVERED | \ - MAIL_COPY_RETURN_PATH) + MAIL_COPY_RETURN_PATH | MAIL_COPY_BLANK) #define MAIL_COPY_NONE 0 /* all turned off */ /* LICENSE diff --git a/postfix/global/mail_params.h b/postfix/global/mail_params.h index 94d0dda9f..64e092926 100644 --- a/postfix/global/mail_params.h +++ b/postfix/global/mail_params.h @@ -381,10 +381,14 @@ extern char *var_fwd_exp_filter; #define DEF_DELIVER_HDR "command, file, forward" extern char *var_deliver_hdr; -#define VAR_EXP_OWN_ALIAS "expand_owner_alias" -#define DEF_EXP_OWN_ALIAS 0 +#define VAR_EXP_OWN_ALIAS "expand_owner_alias" +#define DEF_EXP_OWN_ALIAS 0 extern bool var_exp_own_alias; +#define VAR_STAT_HOME_DIR "test_home_directory" +#define DEF_STAT_HOME_DIR 0 +extern bool var_stat_home_dir; + /* * Queue manager: maximal size of the duplicate expansion filter. By * default, we do graceful degradation with huge mailing lists. diff --git a/postfix/global/mail_version.h b/postfix/global/mail_version.h index 5ab30414c..9d9f8ac88 100644 --- a/postfix/global/mail_version.h +++ b/postfix/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Snapshot-20000531" +#define DEF_MAIL_VERSION "Snapshot-20000625" extern char *var_mail_version; /* LICENSE diff --git a/postfix/html/faq.html b/postfix/html/faq.html index c8c95e19b..691b64e0f 100644 --- a/postfix/html/faq.html +++ b/postfix/html/faq.html @@ -1020,10 +1020,9 @@ types Postfix supports, use the command postconf -m.

diff --git a/postfix/html/local.8.html b/postfix/html/local.8.html index a4c1574d3..c2d7bfea6 100644 --- a/postfix/html/local.8.html +++ b/postfix/html/local.8.html @@ -216,7 +216,7 @@ LOCAL(8) LOCAL(8) lope header to each message, prepends an optional Deliv- ered-To: header with the recipient envelope address, prepends a Return-Path: header with the sender envelope - address, and appends an empty line. + address, and appends no empty line. EXTERNAL FILE DELIVERY The allow_mail_to_files configuration parameter restricts @@ -277,7 +277,7 @@ LOCAL(8) LOCAL(8) the default_privs configuration parameter. STANDARDS - RFC 822 (ARPA Internet Text Messages) + RFC 822 (ARPA Internet Text Messages) DIAGNOSTICS Problems and transactions are logged to syslogd(8). Cor- @@ -352,6 +352,10 @@ LOCAL(8) LOCAL(8) recipient_delimiter Separator between username and address extension. + test_home_directory + Require that a recipient's home directory is acces- + sible by the recipient before attempting delivery. + Mailbox delivery fallback_transport Message transport for recipients that are not found @@ -385,10 +389,6 @@ LOCAL(8) LOCAL(8) rides all other configuration parameters that con- trol mailbox delivery, including luser_relay. -Locking controls - deliver_lock_attempts - Limit the number of attempts to acquire an exclu- - sive lock on a mailbox or external file. @@ -401,6 +401,11 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) +Locking controls + deliver_lock_attempts + Limit the number of attempts to acquire an exclu- + sive lock on a mailbox or external file. + deliver_lock_delay Time in seconds between successive attempts to acquire an exclusive lock. @@ -449,11 +454,6 @@ LOCAL(8) LOCAL(8) Default rights for delivery to external file or command. - forward_expansion_filter - What characters are allowed to appear in $name - expansions of forward_path. Illegal characters are - replaced by underscores. - @@ -467,6 +467,11 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) + forward_expansion_filter + What characters are allowed to appear in $name + expansions of forward_path. Illegal characters are + replaced by underscores. + HISTORY The Delivered-To: header appears in the qmail system by Daniel Bernstein. @@ -513,11 +518,6 @@ LOCAL(8) LOCAL(8) - - - - - diff --git a/postfix/html/pipe.8.html b/postfix/html/pipe.8.html index eeed53567..0b02333e5 100644 --- a/postfix/html/pipe.8.html +++ b/postfix/html/pipe.8.html @@ -30,23 +30,28 @@ PIPE(8) PIPE(8) file at the end of a service definition. The syntax is as follows: - flags=FR.> (optional) + flags=BFR.> (optional) Optional message processing flags. By default, a message is copied unchanged. - F Prepend a "From sender time_stamp" envelope - header to the message content. This is + B Append a blank line at the end of each mes- + sage. This is required by some mail user + agents that recognize "From " lines only + when preceded by a blank line. + + F Prepend a "From sender time_stamp" envelope + header to the message content. This is expected by, for example, UUCP software. The - F flag also causes an empty line to be + F flag also causes an empty line to be appended to the message. - R Prepend a Return-Path: message header with + R Prepend a Return-Path: message header with the envelope sender address. - . Prepend . to lines starting with ".". This + . Prepend . to lines starting with ".". This is needed by, for example, BSMTP software. - > Prepend > to lines starting with "From ". + > Prepend > to lines starting with "From ". This is expected by, for example, UUCP soft- ware. @@ -54,11 +59,6 @@ PIPE(8) PIPE(8) user=username:groupname The external command is executed with the rights of - the specified username. The software refuses to - execute commands with root privileges, or with the - privileges of the mail system owner. If groupname - is specified, the corresponding group ID is used - instead of the group ID of username. @@ -71,12 +71,22 @@ PIPE(8) PIPE(8) PIPE(8) PIPE(8) + the specified username. The software refuses to + execute commands with root privileges, or with the + privileges of the mail system owner. If groupname + is specified, the corresponding group ID is used + instead of the group ID of username. + eol=string (default: \n) - The output record delimiter. Typically one would - use either \r\n or \n. The usual C-style backslash - escape sequences are recognized: \a \b \f \n \r \t + The output record delimiter. Typically one would + use either \r\n or \n. The usual C-style backslash + escape sequences are recognized: \a \b \f \n \r \t \v \octal and \\. + size=size_limit (optional) + Messages greater in size than this limit (in bytes) + will be bounced back to the sender. + argv=command... (required) The command to be executed. This must be specified as the last command attribute. The command is exe- @@ -115,16 +125,6 @@ PIPE(8) PIPE(8) tains ${recipient} expands into as many com- mand-line arguments as there are recipients. - ${sender} - This macro expands to the envelope sender - address. - - ${user} - This macro expands to the username part of a - 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 @@ -137,6 +137,16 @@ PIPE(8) PIPE(8) PIPE(8) PIPE(8) + ${sender} + This macro expands to the envelope sender + address. + + ${user} + This macro expands to the username part of a + 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 arguments as there are recipients. In addition to the form ${name}, the forms $name and @@ -180,17 +190,7 @@ PIPE(8) PIPE(8) enforced by the Postfix queue manager. transport_destination_recipient_limit - Limit the number of recipients per message deliv- - ery, for delivery via the named transport. The - default limit is taken from the default_destina- - tion_recipient_limit parameter. The limit is - enforced by the Postfix queue manager. - - transport_time_limit - Limit the time for delivery to external command, - for delivery via the named transport. The default - limit is taken from the command_time_limit parame- - ter. The limit is enforced by the Postfix queue + Limit the number of recipients per message @@ -203,6 +203,16 @@ PIPE(8) PIPE(8) PIPE(8) PIPE(8) + delivery, for delivery via the named transport. The + default limit is taken from the default_destina- + tion_recipient_limit parameter. The limit is + enforced by the Postfix queue manager. + + transport_time_limit + Limit the time for delivery to external command, + for delivery via the named transport. The default + limit is taken from the command_time_limit parame- + ter. The limit is enforced by the Postfix queue manager. SEE ALSO @@ -239,16 +249,6 @@ PIPE(8) PIPE(8) - - - - - - - - - - diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html index 05e2d06e6..1529182fb 100644 --- a/postfix/html/smtp.8.html +++ b/postfix/html/smtp.8.html @@ -75,6 +75,9 @@ SMTP(8) SMTP(8) command after a configuration change. Miscellaneous + append_dot_mydomain + Rewrite user@host to user@host.$mydomain. + best_mx_transport Name of the delivery transport to use when the local machine is the most-preferred mail exchanger @@ -123,9 +126,6 @@ SMTP(8) SMTP(8) smtp_always_send_ehlo Always send EHLO at the start of a connection. - smtp_skip_4xx_greeting - Skip servers that greet us with a 4xx status code. - 2 @@ -137,6 +137,9 @@ SMTP(8) SMTP(8) SMTP(8) SMTP(8) + smtp_skip_4xx_greeting + Skip servers that greet us with a 4xx status code. + smtp_skip_5xx_greeting Skip servers that greet us with a 5xx status code. @@ -188,9 +191,6 @@ SMTP(8) SMTP(8) ery. The default limit is taken from the default_destination_recipient_limit parameter. -Timeout controls - smtp_connect_timeout - Timeout in seconds for completing a TCP connection. @@ -203,6 +203,9 @@ SMTP(8) SMTP(8) SMTP(8) SMTP(8) +Timeout controls + smtp_connect_timeout + Timeout in seconds for completing a TCP connection. When no connection can be made within the deadline, the SMTP client tries the next address on the mail exchanger list. @@ -254,9 +257,6 @@ SMTP(8) SMTP(8) The Secure Mailer license must be distributed with this software. -AUTHOR(S) - Wietse Venema - IBM T.J. Watson Research @@ -269,6 +269,9 @@ SMTP(8) SMTP(8) SMTP(8) SMTP(8) +AUTHOR(S) + Wietse Venema + IBM T.J. Watson Research P.O. Box 704 Yorktown Heights, NY 10598, USA @@ -319,9 +322,6 @@ SMTP(8) SMTP(8) - - - diff --git a/postfix/lmtp/lmtp_proto.c b/postfix/lmtp/lmtp_proto.c index 440d521d4..ae16b0385 100644 --- a/postfix/lmtp/lmtp_proto.c +++ b/postfix/lmtp/lmtp_proto.c @@ -531,7 +531,8 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state) sent(request->queue_id, rcpt->address, session->namaddr, request->arrival_time, "%s", resp->str); - deliver_completed(state->src, rcpt->offset); + if (request->flags & DEL_REQ_FLAG_SUCCESS) + deliver_completed(state->src, rcpt->offset); rcpt->offset = 0; } } else { diff --git a/postfix/local/dotforward.c b/postfix/local/dotforward.c index e3131d3f8..12ae1241d 100644 --- a/postfix/local/dotforward.c +++ b/postfix/local/dotforward.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -78,6 +79,7 @@ #include #include #include +#include /* Application-specific. */ @@ -112,18 +114,36 @@ int deliver_dotforward(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp) if (msg_verbose) MSG_LOG_STATE(myname, state); + /* + * Skip non-existing users. The mailbox delivery routine will catch the + * error. + * + * Defer delivery to recipients whose home directory is not accessible. + * + * XXX This code should be one level up. The caller should pass the + * recipient's password file info along with the call. + * + * XXX This code should also be executed for \user deliveries that bypass + * aliasing and .forward processing. Said code is currently broken after + * a revision of the RFC822 address parser. + */ + if ((mypwd = mypwnam(state.msg_attr.user)) == 0) + return (NO); + if (var_stat_home_dir + && stat_as(mypwd->pw_dir, &st, mypwd->pw_uid, mypwd->pw_gid) < 0) { + *statusp = defer_append(BOUNCE_FLAG_KEEP, + BOUNCE_ATTR(state.msg_attr), + "cannot access %s home directory %s: %m", + mypwd->pw_name, mypwd->pw_dir); + return (YES); + } + /* * Skip this module if per-user forwarding is disabled. */ if (*var_forward_path == 0) return (NO); - /* - * Skip non-existing users. The mailbox delivery routine will catch the - * error. - */ - if ((mypwd = mypwnam(state.msg_attr.user)) == 0) - return (NO); /* * From here on no early returns or we have a memory leak. diff --git a/postfix/local/local.c b/postfix/local/local.c index 94bcb9799..fd2580194 100644 --- a/postfix/local/local.c +++ b/postfix/local/local.c @@ -173,7 +173,7 @@ /* optional \fBDelivered-To:\fR /* header with the recipient envelope address, prepends a /* \fBReturn-Path:\fR header with the sender envelope address, -/* and appends an empty line. +/* and appends no empty line. /* EXTERNAL FILE DELIVERY /* .ad /* .fi @@ -278,6 +278,9 @@ /* forwarding mail is not recommended. /* .IP \fBrecipient_delimiter\fR /* Separator between username and address extension. +/* .IP \fBtest_home_directory\fR +/* Require that a recipient's home directory is accessible by the +/* recipient before attempting delivery. /* .SH Mailbox delivery /* .ad /* .fi @@ -439,6 +442,7 @@ char *var_fwd_exp_filter; char *var_prop_extension; int var_exp_own_alias; char *var_deliver_hdr; +int var_stat_home_dir; int local_cmd_deliver_mask; int local_file_deliver_mask; @@ -500,7 +504,7 @@ static int local_deliver(DELIVER_REQUEST *rqst, char *service) state.msg_attr.recipient = rcpt->address; rcpt_stat = deliver_recipient(state, usr_attr); rcpt_stat |= forward_finish(state.msg_attr, rcpt_stat); - if (rcpt_stat == 0) + if (rcpt_stat == 0 && (rqst->flags & DEL_REQ_FLAG_SUCCESS)) deliver_completed(state.msg_attr.fp, rcpt->offset); been_here_free(state.dup_filter); msg_stat |= rcpt_stat; @@ -618,6 +622,7 @@ int main(int argc, char **argv) static CONFIG_BOOL_TABLE bool_table[] = { VAR_BIFF, DEF_BIFF, &var_biff, VAR_EXP_OWN_ALIAS, DEF_EXP_OWN_ALIAS, &var_exp_own_alias, + VAR_STAT_HOME_DIR, DEF_STAT_HOME_DIR, &var_stat_home_dir, 0, }; diff --git a/postfix/local/maildir.c b/postfix/local/maildir.c index 24f2ff8f4..01adc5b15 100644 --- a/postfix/local/maildir.c +++ b/postfix/local/maildir.c @@ -143,11 +143,11 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path) || sane_link(tmpfile, newfile) < 0)) { vstring_sprintf(why, "link to %s: %m", newfile); } else { - if (unlink(tmpfile) < 0) - msg_warn("remove %s: %m", tmpfile); status = 0; } } + if (unlink(tmpfile) < 0) + msg_warn("remove %s: %m", tmpfile); } set_eugid(var_owner_uid, var_owner_gid); diff --git a/postfix/local/recipient.c b/postfix/local/recipient.c index 3a6a2991f..4db844173 100644 --- a/postfix/local/recipient.c +++ b/postfix/local/recipient.c @@ -104,6 +104,10 @@ static int deliver_switch(LOCAL_STATE state, USER_ATTR usr_attr) /* * \user is special: it means don't do any alias or forward expansion. + * + * XXX This code currently does not work due to revision of the RFC822 + * address parser. \user should be permitted only in locally specified + * aliases, includes or forward files. */ if (state.msg_attr.recipient[0] == '\\') { state.msg_attr.recipient++, state.msg_attr.local++, state.msg_attr.user++; diff --git a/postfix/makedefs b/postfix/makedefs index 6a9503706..fe25dde9b 100644 --- a/postfix/makedefs +++ b/postfix/makedefs @@ -147,7 +147,7 @@ case "$SYSTEM.$RELEASE" in case "$CC" in cc|*/cc|xlc|*/xlc) OPT=; CCARGS="$CCARGS -w -blibpath:/usr/lib:/lib:/usr/local/lib";; esac - CCARGS="$CCARGS -D_ALL_SOURCE" + CCARGS="$CCARGS -D_ALL_SOURCE -DHAS_POSIX_REGEXP" ;; 3) SYSTYPE=AIX3 # How embarrassing... diff --git a/postfix/man/man8/local.8 b/postfix/man/man8/local.8 index da7665d53..b7489f5f8 100644 --- a/postfix/man/man8/local.8 +++ b/postfix/man/man8/local.8 @@ -187,7 +187,7 @@ envelope header to each message, prepends an optional \fBDelivered-To:\fR header with the recipient envelope address, prepends a \fBReturn-Path:\fR header with the sender envelope address, -and appends an empty line. +and appends no empty line. .SH EXTERNAL FILE DELIVERY .na .nf @@ -306,6 +306,9 @@ forwarding, delivery to command or file. Specify zero or more of: forwarding mail is not recommended. .IP \fBrecipient_delimiter\fR Separator between username and address extension. +.IP \fBtest_home_directory\fR +Require that a recipient's home directory is accessible by the +recipient before attempting delivery. .SH Mailbox delivery .ad .fi diff --git a/postfix/man/man8/pipe.8 b/postfix/man/man8/pipe.8 index 9676e8210..59b3cd028 100644 --- a/postfix/man/man8/pipe.8 +++ b/postfix/man/man8/pipe.8 @@ -30,10 +30,14 @@ to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate. .fi The external command attributes are given in the \fBmaster.cf\fR file at the end of a service definition. The syntax is as follows: -.IP "\fBflags=FR.>\fR (optional)" +.IP "\fBflags=BFR.>\fR (optional)" Optional message processing flags. By default, a message is copied unchanged. .RS +.IP \fBB\fR +Append a blank line at the end of each message. This is required +by some mail user agents that recognize "\fBFrom \fR" lines only +when preceded by a blank line. .IP \fBF\fR Prepend a "\fBFrom \fIsender time_stamp\fR" envelope header to the message content. @@ -62,6 +66,9 @@ The output record delimiter. Typically one would use either \fB\er\en\fR or \fB\en\fR. The usual C-style backslash escape sequences are recognized: \fB\ea \eb \ef \en \er \et \ev \e\fIoctal\fR and \fB\e\e\fR. +.IP "\fBsize\fR=\fIsize_limit\fR (optional)" +Messages greater in size than this limit (in bytes) will be bounced +back to the sender. .IP "\fBargv\fR=\fIcommand\fR... (required)" The command to be executed. This must be specified as the last command attribute. diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8 index bcf367a20..2942eb9ff 100644 --- a/postfix/man/man8/smtp.8 +++ b/postfix/man/man8/smtp.8 @@ -72,6 +72,8 @@ a configuration change. .SH Miscellaneous .ad .fi +.IP \fBappend_dot_mydomain\fR +Rewrite \fIuser\fR@\fIhost\fR to \fIuser\fR@\fIhost\fR.$\fBmydomain\fR. .IP \fBbest_mx_transport\fR Name of the delivery transport to use when the local machine is the most-preferred mail exchanger (by default, a mailer diff --git a/postfix/pipe/pipe.c b/postfix/pipe/pipe.c index 9102d4275..78c11a200 100644 --- a/postfix/pipe/pipe.c +++ b/postfix/pipe/pipe.c @@ -22,10 +22,14 @@ /* .fi /* The external command attributes are given in the \fBmaster.cf\fR /* file at the end of a service definition. The syntax is as follows: -/* .IP "\fBflags=FR.>\fR (optional)" +/* .IP "\fBflags=BFR.>\fR (optional)" /* Optional message processing flags. By default, a message is /* copied unchanged. /* .RS +/* .IP \fBB\fR +/* Append a blank line at the end of each message. This is required +/* by some mail user agents that recognize "\fBFrom \fR" lines only +/* when preceded by a blank line. /* .IP \fBF\fR /* Prepend a "\fBFrom \fIsender time_stamp\fR" envelope header to /* the message content. @@ -54,6 +58,9 @@ /* \fB\er\en\fR or \fB\en\fR. The usual C-style backslash escape /* sequences are recognized: \fB\ea \eb \ef \en \er \et \ev /* \e\fIoctal\fR and \fB\e\e\fR. +/* .IP "\fBsize\fR=\fIsize_limit\fR (optional)" +/* Messages greater in size than this limit (in bytes) will be bounced +/* back to the sender. /* .IP "\fBargv\fR=\fIcommand\fR... (required)" /* The command to be executed. This must be specified as the /* last command attribute. @@ -200,6 +207,7 @@ #include #include #include +#include /* Single server skeleton. */ @@ -255,6 +263,7 @@ typedef struct { gid_t gid; /* command privileges */ int flags; /* mail_copy() flags */ VSTRING *eol; /* output record delimiter */ + off_t size_limit; /* max size in bytes we will accept */ } PIPE_ATTR; /* parse_callback - callback for mac_parse() */ @@ -415,6 +424,7 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv) struct group *grp; char *user; /* user name */ char *group; /* group name */ + char *size; /* max message size */ char *cp; /* @@ -425,6 +435,7 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv) attr->command = 0; attr->flags = 0; attr->eol = vstring_strcpy(vstring_alloc(1), "\n"); + attr->size_limit = 0; /* * Iterate over the command-line attribute list. @@ -437,6 +448,9 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv) if (strncasecmp("flags=", *argv, sizeof("flags=") - 1) == 0) { for (cp = *argv + sizeof("flags=") - 1; *cp; cp++) { switch (*cp) { + case 'B': + attr->flags |= MAIL_COPY_BLANK; + break; case 'F': attr->flags |= MAIL_COPY_FROM; break; @@ -483,6 +497,15 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv) unescape(attr->eol, *argv + sizeof("eol=") - 1); } + /* + * size=max_message_size (in bytes) + */ + else if (strncasecmp("size=", *argv, sizeof("size=") - 1) == 0) { + size = *argv + sizeof("size=") - 1; + if ((attr->size_limit = off_cvt_string(size)) < 0) + msg_fatal("%s: bad size= value: %s", myname, size); + } + /* * argv=command... */ @@ -519,8 +542,9 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv) * Give the poor tester a clue of what is going on. */ if (msg_verbose) - msg_info("%s: uid %d, gid %d. flags %d", - myname, attr->uid, attr->gid, attr->flags); + msg_info("%s: uid %d, gid %d, flags %d, size %ld", + myname, attr->uid, attr->gid, attr->flags, + (long) attr->size_limit); } /* eval_command_status - do something with command completion status */ @@ -544,7 +568,8 @@ static int eval_command_status(int command_status, char *service, rcpt = request->rcpt_list.info + n; sent(request->queue_id, rcpt->address, service, request->arrival_time, "%s", request->nexthop); - deliver_completed(src, rcpt->offset); + if (request->flags & DEL_REQ_FLAG_SUCCESS) + deliver_completed(src, rcpt->offset); } break; case PIPE_STAT_BOUNCE: @@ -621,6 +646,19 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv) get_service_attr(&attr, argv); } + /* + * Check that this agent accepts messages this large. + */ + if (attr.size_limit != 0 && request->data_size > attr.size_limit) { + if (msg_verbose) + msg_info("%s: too big: size_limit = %ld, request->data_size = %ld", + myname, (long) attr.size_limit, request->data_size); + + deliver_status = eval_command_status(PIPE_STAT_BOUNCE, service, + request, request->fp, "message too large"); + return (deliver_status); + } + /* * Deliver. Set the nexthop and sender variables, and expand the command * argument vector. Recipients will be expanded on the fly. XXX Rewrite diff --git a/postfix/qmgr/Makefile.in b/postfix/qmgr/Makefile.in index 99ce9e6ef..a078dcaee 100644 --- a/postfix/qmgr/Makefile.in +++ b/postfix/qmgr/Makefile.in @@ -134,6 +134,7 @@ qmgr_deliver.o: ../include/mail_queue.h qmgr_deliver.o: ../include/mail_proto.h qmgr_deliver.o: ../include/recipient_list.h qmgr_deliver.o: ../include/mail_params.h +qmgr_deliver.o: ../include/deliver_request.h qmgr_deliver.o: qmgr.h qmgr_deliver.o: ../include/scan_dir.h qmgr_deliver.o: ../include/maps.h diff --git a/postfix/qmgr/qmgr.h b/postfix/qmgr/qmgr.h index 004fd1d91..44e6b4fb3 100644 --- a/postfix/qmgr/qmgr.h +++ b/postfix/qmgr/qmgr.h @@ -229,7 +229,8 @@ struct QMGR_MESSAGE { char *sender; /* complete address */ char *errors_to; /* error report address */ char *return_receipt; /* confirm receipt address */ - char *filter_xport; /* inspection transport */ + char *filter_xport; /* filtering transport */ + char *inspect_xport; /* inspecting transport */ long data_size; /* message content size */ long rcpt_offset; /* more recipients here */ QMGR_RCPT_LIST rcpt_list; /* complete addresses */ diff --git a/postfix/qmgr/qmgr_deliver.c b/postfix/qmgr/qmgr_deliver.c index 1ff2f350e..466d5360d 100644 --- a/postfix/qmgr/qmgr_deliver.c +++ b/postfix/qmgr/qmgr_deliver.c @@ -61,6 +61,7 @@ #include #include #include +#include /* Application-specific. */ @@ -117,7 +118,8 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream) QMGR_RCPT *recipient; QMGR_MESSAGE *message = entry->message; - mail_print(stream, "%s %s %ld %ld %s %s %s %s %ld", + mail_print(stream, "%d %s %s %ld %ld %s %s %s %s %ld", + message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT, message->queue_name, message->queue_id, message->data_offset, message->data_size, entry->queue->name, message->sender, diff --git a/postfix/qmgr/qmgr_message.c b/postfix/qmgr/qmgr_message.c index feb247806..7008cc7f3 100644 --- a/postfix/qmgr/qmgr_message.c +++ b/postfix/qmgr/qmgr_message.c @@ -145,6 +145,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name, message->errors_to = 0; message->return_receipt = 0; message->filter_xport = 0; + message->inspect_xport = 0; message->data_size = 0; message->warn_offset = 0; message->warn_time = 0; @@ -250,6 +251,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message) } else if (rec_type == REC_TYPE_FILT) { if (message->filter_xport == 0) message->filter_xport = mystrdup(start); + } else if (rec_type == REC_TYPE_INSP) { + if (message->inspect_xport == 0) + message->inspect_xport = mystrdup(start); } else if (rec_type == REC_TYPE_FROM) { if (message->sender == 0) { message->sender = mystrdup(start); @@ -706,6 +710,8 @@ void qmgr_message_free(QMGR_MESSAGE *message) myfree(message->return_receipt); if (message->filter_xport) myfree(message->filter_xport); + if (message->inspect_xport) + myfree(message->inspect_xport); qmgr_rcpt_list_free(&message->rcpt_list); qmgr_message_count--; myfree((char *) message); diff --git a/postfix/smtp/smtp.c b/postfix/smtp/smtp.c index d9d54357e..5a5b30b20 100644 --- a/postfix/smtp/smtp.c +++ b/postfix/smtp/smtp.c @@ -56,6 +56,8 @@ /* .SH Miscellaneous /* .ad /* .fi +/* .IP \fBappend_dot_mydomain\fR +/* Rewrite \fIuser\fR@\fIhost\fR to \fIuser\fR@\fIhost\fR.$\fBmydomain\fR. /* .IP \fBbest_mx_transport\fR /* Name of the delivery transport to use when the local machine /* is the most-preferred mail exchanger (by default, a mailer @@ -239,6 +241,7 @@ char *var_smtp_sasl_opts; char *var_smtp_sasl_passwd; bool var_smtp_sasl_enable; char *var_smtp_bind_addr; +bool var_append_dot_mydomain; /* * Global variables. smtp_errno is set by the address lookup routines and by @@ -408,6 +411,7 @@ int main(int argc, char **argv) VAR_SKIP_QUIT_RESP, DEF_SKIP_QUIT_RESP, &var_skip_quit_resp, VAR_SMTP_ALWAYS_EHLO, DEF_SMTP_ALWAYS_EHLO, &var_smtp_always_ehlo, VAR_SMTP_SASL_ENABLE, DEF_SMTP_SASL_ENABLE, &var_smtp_sasl_enable, + VAR_APP_DOT_MYDOMAIN, DEF_APP_DOT_MYDOMAIN, &var_append_dot_mydomain, 0, }; diff --git a/postfix/smtp/smtp_proto.c b/postfix/smtp/smtp_proto.c index 0d7b4f97b..5d562ccdb 100644 --- a/postfix/smtp/smtp_proto.c +++ b/postfix/smtp/smtp_proto.c @@ -533,7 +533,8 @@ int smtp_xfer(SMTP_STATE *state) session->namaddr, request->arrival_time, "%s", resp->str); - deliver_completed(state->src, rcpt->offset); + if (request->flags & DEL_REQ_FLAG_SUCCESS) + deliver_completed(state->src, rcpt->offset); rcpt->offset = 0; } } diff --git a/postfix/smtp/smtp_unalias.c b/postfix/smtp/smtp_unalias.c index 91cf6f989..f92fb2477 100644 --- a/postfix/smtp/smtp_unalias.c +++ b/postfix/smtp/smtp_unalias.c @@ -50,6 +50,10 @@ #include #include +/* Global library. */ + +#include + /* DNS library. */ #include @@ -73,8 +77,11 @@ const char *smtp_unalias_name(const char *name) * after servicing a limited number of requests, so there is no need to * prevent the cache from growing too large, or to expire old entries. */ - if (cache == 0) + if (cache == 0) { cache = htable_create(10); + if (var_append_dot_mydomain == 0) + smtp_unalias_flags |= RES_DNSRCH; + } /* * Look up the fqdn. If none is found use the query name instead, so that diff --git a/postfix/smtpd/smtpd.c b/postfix/smtpd/smtpd.c index e7fe2d31d..4d8701e4f 100644 --- a/postfix/smtpd/smtpd.c +++ b/postfix/smtpd/smtpd.c @@ -431,7 +431,7 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) smtpd_chat_reply(state, "250-SIZE"); smtpd_chat_reply(state, "250-ETRN"); #ifdef USE_SASL_AUTH - if (SMTPD_STAND_ALONE(state) == 0 && var_smtpd_sasl_enable) + if (var_smtpd_sasl_enable) smtpd_chat_reply(state, "250-AUTH %s", state->sasl_mechanism_list); #endif smtpd_chat_reply(state, "250 8BITMIME"); @@ -624,9 +624,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) if ((state->msg_size = off_cvt_string(arg + 5)) < 0) state->msg_size = 0; #ifdef USE_SASL_AUTH - } else if (SMTPD_STAND_ALONE(state) == 0 - && var_smtpd_sasl_enable - && strncasecmp(arg, "AUTH=", 5) == 0) { + } else if (var_smtpd_sasl_enable && strncasecmp(arg, "AUTH=", 5) == 0) { if ((err = smtpd_sasl_mail_opt(state, arg + 5)) != 0) { smtpd_chat_reply(state, "%s", err); return (-1); @@ -913,6 +911,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) if (state->err == CLEANUP_STAT_OK) { state->error_count = 0; state->error_mask = 0; + state->junk_cmds = 0; smtpd_chat_reply(state, "250 Ok: queued as %s", state->queue_id); } else if ((state->err & CLEANUP_STAT_BAD) != 0) { state->error_mask |= MAIL_ERROR_SOFTWARE; diff --git a/postfix/smtpd/smtpd_state.c b/postfix/smtpd/smtpd_state.c index 09b7b82ef..4e98a8f28 100644 --- a/postfix/smtpd/smtpd_state.c +++ b/postfix/smtpd/smtpd_state.c @@ -92,6 +92,8 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream) state->junk_cmds = 0; #ifdef USE_SASL_AUTH + if (SMTPD_STAND_ALONE(state)) + var_smtpd_sasl_enable = 0; if (var_smtpd_sasl_enable) smtpd_sasl_connect(state); #endif diff --git a/postfix/util/dict_pcre.c b/postfix/util/dict_pcre.c index ddaf39bdd..94d6fc67f 100644 --- a/postfix/util/dict_pcre.c +++ b/postfix/util/dict_pcre.c @@ -13,8 +13,6 @@ /* DESCRIPTION /* dict_pcre_open() opens the named file and compiles the contained /* regular expressions. -/* -/* The lookup interface will match only user@domain form addresses. /* SEE ALSO /* dict(3) generic dictionary manager /* AUTHOR(S) diff --git a/postfix/util/dict_regexp.c b/postfix/util/dict_regexp.c index 85ae9a49c..7f86f083d 100644 --- a/postfix/util/dict_regexp.c +++ b/postfix/util/dict_regexp.c @@ -13,8 +13,6 @@ /* DESCRIPTION /* dict_regexp_open() opens the named file and compiles the contained /* regular expressions. -/* -/* The lookup interface will match only user@domain form addresses. /* SEE ALSO /* dict(3) generic dictionary manager /* AUTHOR(S) diff --git a/postfix/util/vstream.c b/postfix/util/vstream.c index 1f582a458..e2ec94ddc 100644 --- a/postfix/util/vstream.c +++ b/postfix/util/vstream.c @@ -213,7 +213,7 @@ /* value arguments. /* .IP "VSTREAM_CTL_READ_FN (int (*)(int, void *, unsigned, int, void *))" /* The argument specifies an alternative for the timed_read(3) function, -/* for example, a read function that performs encryption. +/* for example, a read function that performs decryption. /* .IP "VSTREAM_CTL_WRITE_FN (int (*)(int, void *, unsigned, int, void *))" /* The argument specifies an alternative for the timed_write(3) function, /* for example, a write function that performs encryption.

N.B. Some non-Postfix software such as DRAC uses -btree files instead of hash files. In that case, -you will have to adjust the above check_client_access -restriction accordingly. +href="http://mail.cc.umanitoba.ca/drac/">DRAC uses btree +files instead of hash files. In that case, you will have +to adjust the above check_client_access restriction accordingly.