From: Wietse Venema Date: Thu, 5 Jun 2003 05:00:00 +0000 (-0500) Subject: postfix-2.0.11-20030605 X-Git-Tag: v2.1-RC1-20040331~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f8ab70fed887183393c48f1b9de401845c214942;p=thirdparty%2Fpostfix.git postfix-2.0.11-20030605 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 88bf11709..d59c39046 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -8106,6 +8106,8 @@ Apologies for any names omitted. 2003052[3-9] + Cleanup: qmgr_fudge_factor is gone. + Cleanup: rewrote the queue file record processing loops in cleanup and in [n]qmgr. This code had deteriorated a lot as the result of small changes over the years. This change @@ -8143,6 +8145,27 @@ Apologies for any names omitted. Compatibility: allow <@site,@site:address> route addresses in SMTP commands. File: smtpd/smtpd.c. +20030605 + + Cleanup: input checks moved from the pickup daemon to the + postdrop mail submission command; this is to prepare for + mail submission from postdrop->cleanup without going through + the maildrop directory. Files: pickup/pickup.c, + postdrop/postdrop.c. + + Bugfix: the "dead host" backoff timer in the MySQL client + didn't work. Fix by Leandro Santi. File: util/dict_mysql.c. + + Bugfix: same problem in the PostgreSQL client. File: + util/dict_pgsql.c. + + Workaround: turned off non-blocking write to pipe because + too many systems give a weird write() result. File: + global/pipe_command.c. + + Cleanup: added support for vstream_fseek(.., .., SEEK_END). + File: util/vstream.c. + Open problems: Low: smtp-source may block when sending large test messages. diff --git a/postfix/README_FILES/VIRTUAL_README b/postfix/README_FILES/VIRTUAL_README index 5c9df7613..3a4220e12 100644 --- a/postfix/README_FILES/VIRTUAL_README +++ b/postfix/README_FILES/VIRTUAL_README @@ -24,7 +24,7 @@ It looks up the user mailbox location, uid and gid via separate maps, and the mailbox location map can specify either mailbox or maildir delivery (controlled by trailing slash on mailbox name). -The agent allows but ignores user+foo address extensions, does not +The agent does support user+foo address extensions, but does not support 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 @@ -83,7 +83,8 @@ virtual_mailbox_maps In a lookup table, specify a left-hand side of @domain.tld to match any user in the specified domain that does not have her own user@domain.tld entry. While searching a lookup table, an - address extension (user+foo@domain.tld) is ignored. + extended address (user+foo@domain.tld) is searched before the + bare address (user@domain.tld). If a recipient is not found the mail is returned to the sender. diff --git a/postfix/html/virtual.8.html b/postfix/html/virtual.8.html index c36f4e313..550e4712d 100644 --- a/postfix/html/virtual.8.html +++ b/postfix/html/virtual.8.html @@ -24,7 +24,8 @@ VIRTUAL(8) VIRTUAL(8) The mailbox location is controlled by the virtual_mail- box_base and virtual_mailbox_maps configuration parameters (see below). The virtual_mailbox_maps table is indexed by - the full recipient address. + the recipient address as described under TABLE SEARCH + ORDER below. The mailbox pathname is constructed as follows: @@ -33,51 +34,78 @@ VIRTUAL(8) VIRTUAL(8) where recipient is the full recipient address. UNIX MAILBOX FORMAT - When the mailbox location does not end in /, the message - is delivered in UNIX mailbox format. This format stores + When the mailbox location does not end in /, the message + is delivered in UNIX mailbox format. This format stores multiple messages in one textfile. - The virtual delivery agent prepends a "From sender - time_stamp" envelope header to each message, prepends a - Delivered-To: message header with the envelope recipient + The virtual delivery agent prepends a "From sender + time_stamp" envelope header to each message, prepends a + Delivered-To: message header with the envelope recipient address, prepends an X-Original-To: header with the recip- - ient address as given to Postfix, prepends a Return-Path: - message header with the envelope sender address, prepends + ient address as given to Postfix, prepends a Return-Path: + message header with the envelope sender address, prepends a > character to lines beginning with "From ", and appends an empty line. - The mailbox is locked for exclusive access while delivery + The mailbox is locked for exclusive access while delivery is in progress. In case of problems, an attempt is made to truncate the mailbox to its original length. QMAIL MAILDIR FORMAT When the mailbox location ends in /, the message is deliv- - ered in qmail maildir format. This format stores one mes- + ered in qmail maildir format. This format stores one mes- sage per file. The virtual delivery agent daemon prepends a Delivered-To: - message header with the final envelope recipient address, + message header with the final envelope recipient address, prepends an X-Original-To: header with the recipient - address as given to Postfix, and prepends a Return-Path: + address as given to Postfix, and prepends a Return-Path: message header with the envelope sender address. - By definition, maildir format does not require file lock- + By definition, maildir format does not require file lock- ing during mail delivery or retrieval. MAILBOX OWNERSHIP - Mailbox ownership is controlled by the virtual_uid_maps + Mailbox ownership is controlled by the virtual_uid_maps and virtual_gid_maps lookup tables, which are indexed with - the full recipient address. Each table provides a string + the full recipient address. Each table provides a string with the numerical user and group ID, respectively. The virtual_minimum_uid parameter imposes a lower bound on numerical user ID values that may be specified in any vir- tual_uid_maps. +TABLE SEARCH ORDER + Normally, a lookup table is specified as a text file that + serves as input to the postmap(1) command. The result, an + indexed file in dbm or db format, is used for fast search- + ing by the mail system. + + The canonical search order is as follows. The search stops + upon the first successful lookup. + + o When the recipient has an optional address exten- + sion the user+extension@domain.tld address is + looked up first. + + o The user@domain.tld address, without address exten- + sion, is looked up next. + + o Finally, the recipient @domain is looked up. + + When the table is provided via other means such as NIS, + LDAP or SQL, the same lookups are done as for ordinary + indexed files. + + Alternatively, a table can be provided as a regular- + expression map where patterns are given as regular expres- + sions. In that case, only the full recipient address is + given to the regular-expression map. + SECURITY The virtual delivery agent is not security sensitive, pro- - vided that the lookup tables with recipient user/group ID - information are adequately protected. This program is not + vided that the lookup tables with recipient user/group ID + information are adequately protected. This program is not designed to run chrooted. STANDARDS @@ -88,16 +116,19 @@ VIRTUAL(8) VIRTUAL(8) recipient is over disk quota. In all other cases, mail for an existing recipient is deferred and a warning is logged. - 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 afterwards. - Depending on the setting of the notify_classes parameter, - the postmaster is notified of bounces and of other trou- + Depending on the setting of the notify_classes parameter, + the postmaster is notified of bounces and of other trou- ble. BUGS - This delivery agent silently ignores address extensions. + This delivery agent supports address extensions in email + addresses and in lookup table keys, but does not propagate + address extension information to the result of table + lookup. Postfix should have lookup tables that can return multiple result attributes. In order to avoid the inconvenience of @@ -152,110 +183,109 @@ VIRTUAL(8) VIRTUAL(8) virtual_minimum_uid Specifies a minimum uid that will be accepted as a - return from a virtual_owner_maps or vir- - tual_uid_maps lookup. Returned values less than - this will be rejected, and the message will be - deferred. + return from a virtual_uid_maps lookup. Returned + values less than this will be rejected, and the + message will be deferred. virtual_uid_maps Recipients are looked up in these maps to determine - the user ID to be used when writing to the target + the user ID to be used when writing to the target mailbox. - While searching a lookup table, an address exten- + While searching a lookup table, an address exten- sion (user+foo@domain.tld) is ignored. - In a lookup table, specify a left-hand side of - @domain.tld to match any user in the specified - domain that does not have a specific + In a lookup table, specify a left-hand side of + @domain.tld to match any user in the specified + domain that does not have a specific user@domain.tld entry. - For security reasons, regular expression maps are - allowed but regular expression substitution of $1 + For security reasons, regular expression maps are + allowed but regular expression substitution of $1 etc. is disallowed, because that would open a secu- rity hole. - For security reasons, proxied table lookup is not + For security reasons, proxied table lookup is not allowed, because that would open a security hole. virtual_gid_maps Recipients are looked up in these maps to determine - the group ID to be used when writing to the target + the group ID to be used when writing to the target mailbox. - While searching a lookup table, an address exten- + While searching a lookup table, an address exten- sion (user+foo@domain.tld) is ignored. - In a lookup table, specify a left-hand side of - @domain.tld to match any user in the specified - domain that does not have a specific + In a lookup table, specify a left-hand side of + @domain.tld to match any user in the specified + domain that does not have a specific user@domain.tld entry. - For security reasons, regular expression maps are - allowed but regular expression substitution of $1 + For security reasons, regular expression maps are + allowed but regular expression substitution of $1 etc. is disallowed, because that would open a secu- rity hole. - For security reasons, proxied table lookup is not + For security reasons, proxied table lookup is not allowed, because that would open a security hole. Locking controls virtual_mailbox_lock - How to lock UNIX-style mailboxes: one or more of - flock, fcntl or dotlock. The dotlock method - requires that the recipient UID or GID has write + How to lock UNIX-style mailboxes: one or more of + flock, fcntl or dotlock. The dotlock method + requires that the recipient UID or GID has write access to the parent directory of the mailbox file. - This setting is ignored with maildir style deliv- + This setting is ignored with maildir style deliv- ery, because such deliveries are safe without explicit locks. - Use the command postconf -l to find out what lock- + Use the command postconf -l to find out what lock- ing methods are available on your system. deliver_lock_attempts - Limit the number of attempts to acquire an exclu- + Limit the number of attempts to acquire an exclu- sive lock on a UNIX-style mailbox file. deliver_lock_delay Time (default: seconds) between successive attempts - to acquire an exclusive lock on a UNIX-style mail- - box file. The actual delay is slightly randomized. + to acquire an exclusive lock on a UNIX-style mail- + box file. The actual delay is slightly randomized. stale_lock_time - Limit the time after which a stale lockfile is - removed (applicable to UNIX-style mailboxes only). + Limit the time after which a stale lockfile is + removed (applicable to UNIX-style mailboxes only). Resource controls virtual_destination_concurrency_limit Limit the number of parallel deliveries to the same domain via the virtual delivery agent. The default limit is taken from the default_destination_concur- - rency_limit parameter. The limit is enforced by + rency_limit parameter. The limit is enforced by the Postfix queue manager. virtual_destination_recipient_limit Limit the number of recipients per message delivery - via the virtual delivery agent. The default limit - is taken from the default_destination_recipi- - ent_limit parameter. The limit is enforced by the + via the virtual delivery agent. The default limit + is taken from the default_destination_recipi- + ent_limit parameter. The limit is enforced by the Postfix queue manager. virtual_mailbox_limit - The maximal size in bytes of a mailbox or maildir + The maximal size in bytes of a mailbox or maildir file. Set to zero to disable the limit. HISTORY - This agent was originally based on the Postfix local + This agent was originally based on the Postfix local delivery agent. Modifications mainly consisted of removing - code that either was not applicable or that was not safe - in this context: aliases, ~user/.forward files, delivery + code that either was not applicable or that was not safe + in this context: aliases, ~user/.forward files, delivery to "|command" or to /file/name. - The Delivered-To: header appears in the qmail system by + The Delivered-To: header appears in the qmail system by Daniel Bernstein. - The maildir structure appears in the qmail system by + The maildir structure appears in the qmail system by Daniel Bernstein. SEE ALSO @@ -266,7 +296,7 @@ VIRTUAL(8) VIRTUAL(8) qmgr(8) queue manager LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/man/man8/virtual.8 b/postfix/man/man8/virtual.8 index ea1335517..04708e798 100644 --- a/postfix/man/man8/virtual.8 +++ b/postfix/man/man8/virtual.8 @@ -28,8 +28,8 @@ configured via virtual_alias maps or via similar lookup mechanisms. .fi The mailbox location is controlled by the \fBvirtual_mailbox_base\fR and \fBvirtual_mailbox_maps\fR configuration parameters (see below). -The \fBvirtual_mailbox_maps\fR table is indexed by the full recipient -address. +The \fBvirtual_mailbox_maps\fR table is indexed by the recipient +address as described under TABLE SEARCH ORDER below. The mailbox pathname is constructed as follows: @@ -88,6 +88,34 @@ a string with the numerical user and group ID, respectively. The \fBvirtual_minimum_uid\fR parameter imposes a lower bound on numerical user ID values that may be specified in any \fBvirtual_uid_maps\fR. +.SH TABLE SEARCH ORDER +.na +.nf +.ad +.fi +Normally, a lookup table is specified as a text file that +serves as input to the \fBpostmap\fR(1) command. The result, an +indexed file in \fBdbm\fR or \fBdb\fR format, is used for fast +searching by the mail system. + +The canonical search order is as follows. The search stops +upon the first successful lookup. +.IP \(bu +When the recipient has an optional address extension the +\fIuser+extension@domain.tld\fR address is looked up first. +.IP \(bu +The \fIuser@domain.tld\fR address, without address extension, +is looked up next. +.IP \(bu +Finally, the recipient \fI@domain\fR is looked up. +.PP +When the table is provided via other means such as NIS, LDAP +or SQL, the same lookups are done as for ordinary indexed files. + +Alternatively, a table can be provided as a regular-expression +map where patterns are given as regular expressions. In that case, +only the full recipient address is given to the regular-expression +map. .SH SECURITY .na .nf @@ -116,7 +144,9 @@ the postmaster is notified of bounces and of other trouble. .SH BUGS .ad .fi -This delivery agent silently ignores address extensions. +This delivery agent supports address extensions in email +addresses and in lookup table keys, but does not propagate +address extension information to the result of table lookup. Postfix should have lookup tables that can return multiple result attributes. In order to avoid the inconvenience of maintaining @@ -166,7 +196,7 @@ delivery agent. This uses the same syntax as the \fBmydestination\fR configuration parameter. .IP \fBvirtual_minimum_uid\fR Specifies a minimum uid that will be accepted as a return from -a \fBvirtual_owner_maps\fR or \fBvirtual_uid_maps\fR lookup. +a \fBvirtual_uid_maps\fR lookup. Returned values less than this will be rejected, and the message will be deferred. .IP \fBvirtual_uid_maps\fR diff --git a/postfix/src/cleanup/Makefile.in b/postfix/src/cleanup/Makefile.in index ef995fb26..994c381b7 100644 --- a/postfix/src/cleanup/Makefile.in +++ b/postfix/src/cleanup/Makefile.in @@ -193,17 +193,14 @@ cleanup_envelope.o: ../../include/record.h cleanup_envelope.o: ../../include/rec_type.h cleanup_envelope.o: ../../include/cleanup_user.h cleanup_envelope.o: ../../include/qmgr_user.h -cleanup_envelope.o: ../../include/tok822.h -cleanup_envelope.o: ../../include/resolve_clnt.h cleanup_envelope.o: ../../include/mail_params.h -cleanup_envelope.o: ../../include/ext_prop.h -cleanup_envelope.o: ../../include/mail_addr.h -cleanup_envelope.o: ../../include/canon_addr.h cleanup_envelope.o: ../../include/verp_sender.h cleanup_envelope.o: cleanup.h cleanup_envelope.o: ../../include/argv.h cleanup_envelope.o: ../../include/maps.h cleanup_envelope.o: ../../include/dict.h +cleanup_envelope.o: ../../include/tok822.h +cleanup_envelope.o: ../../include/resolve_clnt.h cleanup_envelope.o: ../../include/been_here.h cleanup_envelope.o: ../../include/mail_stream.h cleanup_envelope.o: ../../include/mail_conf.h @@ -218,7 +215,6 @@ cleanup_extracted.o: ../../include/msg.h cleanup_extracted.o: ../../include/vstring.h cleanup_extracted.o: ../../include/vbuf.h cleanup_extracted.o: ../../include/vstream.h -cleanup_extracted.o: ../../include/argv.h cleanup_extracted.o: ../../include/mymalloc.h cleanup_extracted.o: ../../include/nvtable.h cleanup_extracted.o: ../../include/htable.h @@ -227,11 +223,11 @@ cleanup_extracted.o: ../../include/qmgr_user.h cleanup_extracted.o: ../../include/record.h cleanup_extracted.o: ../../include/rec_type.h cleanup_extracted.o: ../../include/mail_params.h -cleanup_extracted.o: ../../include/ext_prop.h cleanup_extracted.o: ../../include/mail_proto.h cleanup_extracted.o: ../../include/iostuff.h cleanup_extracted.o: ../../include/attr.h cleanup_extracted.o: cleanup.h +cleanup_extracted.o: ../../include/argv.h cleanup_extracted.o: ../../include/maps.h cleanup_extracted.o: ../../include/dict.h cleanup_extracted.o: ../../include/tok822.h diff --git a/postfix/src/cleanup/cleanup_envelope.c b/postfix/src/cleanup/cleanup_envelope.c index 8026e6fa3..31f7765ca 100644 --- a/postfix/src/cleanup/cleanup_envelope.c +++ b/postfix/src/cleanup/cleanup_envelope.c @@ -64,11 +64,7 @@ #include #include #include -#include #include -#include -#include -#include #include /* Application-specific. */ @@ -160,11 +156,6 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, */ if ((state->flags & CLEANUP_FLAG_INRCPT) == 0 && strchr(REC_TYPE_ENV_RECIPIENT, type) != 0) { - if ((state->flags & CLEANUP_FLAG_WARN_SEEN) == 0 - && var_delay_warn_time > 0) { - cleanup_out_format(state, REC_TYPE_WARN, REC_TYPE_WARN_FORMAT, - (long) var_delay_warn_time); - } if (state->sender == 0) { msg_warn("%s: message rejected: missing sender envelope record", state->queue_id); @@ -177,11 +168,16 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, state->errs |= CLEANUP_STAT_BAD; return; } + if ((state->flags & CLEANUP_FLAG_WARN_SEEN) == 0 + && var_delay_warn_time > 0) { + cleanup_out_format(state, REC_TYPE_WARN, REC_TYPE_WARN_FORMAT, + (long) state->time + var_delay_warn_time); + } state->flags |= CLEANUP_FLAG_INRCPT; } /* - * Regular initial envelope record processing. + * Initial envelope recipient record processing. */ if (type == REC_TYPE_RCPT) { if (state->sender == 0) { /* protect showq */ @@ -215,8 +211,17 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, state->orig_rcpt = mystrdup(buf); return; } - if (type != REC_TYPE_MESG && (state->flags & CLEANUP_FLAG_INRCPT)) - /* Tell qmgr that recipients are mixed with other information. */ + if (type == REC_TYPE_MESG) { + state->action = cleanup_message; + state->flags &= ~CLEANUP_FLAG_INRCPT; + return; + } + + /* + * Initial envelope non-recipient record processing. + */ + if (state->flags & CLEANUP_FLAG_INRCPT) + /* Tell qmgr that recipient records are mixed with other information. */ state->qmgr_opts |= QMGR_READ_FLAG_MIXED_RCPT_OTHER; if (type == REC_TYPE_SIZE) /* Use our own SIZE record instead. */ @@ -277,11 +282,8 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, myfree(sbuf); cleanup_out(state, type, buf, len); return; - } - if (type != REC_TYPE_MESG) { + } else { cleanup_out(state, type, buf, len); return; } - state->action = cleanup_message; - state->flags &= ~CLEANUP_FLAG_INRCPT; } diff --git a/postfix/src/cleanup/cleanup_extracted.c b/postfix/src/cleanup/cleanup_extracted.c index e072e86b6..097abcef5 100644 --- a/postfix/src/cleanup/cleanup_extracted.c +++ b/postfix/src/cleanup/cleanup_extracted.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -61,7 +60,6 @@ #include #include #include -#include #include /* Application-specific. */ @@ -71,6 +69,7 @@ #define STR(x) vstring_str(x) static void cleanup_extracted_process(CLEANUP_STATE *, int, const char *, int); +static void cleanup_extracted_finish(CLEANUP_STATE *); /* cleanup_extracted - initialize extracted segment */ @@ -95,7 +94,6 @@ void cleanup_extracted(CLEANUP_STATE *state, int type, void cleanup_extracted_process(CLEANUP_STATE *state, int type, const char *buf, int len) { - const char myname[] = "cleanup_extracted_process"; const char *encoding; const char generated_by_cleanup[] = { REC_TYPE_FILT, REC_TYPE_RDR, REC_TYPE_ATTR, @@ -114,8 +112,8 @@ void cleanup_extracted_process(CLEANUP_STATE *state, int type, } /* - * At the end of the non-recipient records, emit optional information - * from header/body content. + * On the transition from non-recipient records to recipient records, + * emit optional information from header/body content. */ if ((state->flags & CLEANUP_FLAG_INRCPT) == 0 && strchr(REC_TYPE_EXT_RECIPIENT, type) != 0) { @@ -126,11 +124,15 @@ void cleanup_extracted_process(CLEANUP_STATE *state, int type, if ((encoding = nvtable_find(state->attr, MAIL_ATTR_ENCODING)) != 0) cleanup_out_format(state, REC_TYPE_ATTR, "%s=%s", MAIL_ATTR_ENCODING, encoding); + if (state->return_receipt) + cleanup_out_string(state, REC_TYPE_RRTO, state->return_receipt); + if (state->errors_to) + cleanup_out_string(state, REC_TYPE_ERTO, state->errors_to); state->flags |= CLEANUP_FLAG_INRCPT; } /* - * Regular extracted envelope record processing. + * Extracted envelope recipient record processing. */ if (type == REC_TYPE_RCPT) { if (state->sender == 0) { /* protect showq */ @@ -164,20 +166,34 @@ void cleanup_extracted_process(CLEANUP_STATE *state, int type, state->orig_rcpt = mystrdup(buf); return; } - if (type != REC_TYPE_END && (state->flags & CLEANUP_FLAG_INRCPT)) - /* Tell qmgr that recipients are mixed with other information. */ + if (type == REC_TYPE_END) { + state->flags &= ~CLEANUP_FLAG_INRCPT; + state->flags |= CLEANUP_FLAG_END_SEEN; + cleanup_extracted_finish(state); + return; + } + + /* + * Extracted envelope non-recipient record processing. + */ + if (state->flags & CLEANUP_FLAG_INRCPT) + /* Tell qmgr that recipient records are mixed with other information. */ state->qmgr_opts |= QMGR_READ_FLAG_MIXED_RCPT_OTHER; if (strchr(generated_by_cleanup, type) != 0) { /* Use our own header/body info instead. */ return; - } - if (type != REC_TYPE_END) { + } else { /* Pass on other non-recipient record. */ cleanup_out(state, type, buf, len); return; } - state->flags &= ~CLEANUP_FLAG_INRCPT; - state->flags |= CLEANUP_FLAG_END_SEEN; +} + +/* cleanup_extracted_finish - process one extracted envelope record */ + +void cleanup_extracted_finish(CLEANUP_STATE *state) +{ + const char myname[] = "cleanup_extracted_finish"; /* * On the way out, add the optional automatic BCC recipient. diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 8154eeaf0..31de9eae7 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,10 +20,10 @@ * Patches change the patchlevel and the release date. Snapshots change the * release date only, unless they include the same bugfix as a patch release. */ -#define MAIL_RELEASE_DATE "20030531" +#define MAIL_RELEASE_DATE "20030605" #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "2.0.10-" MAIL_RELEASE_DATE +#define DEF_MAIL_VERSION "2.0.11-" MAIL_RELEASE_DATE extern char *var_mail_version; /* diff --git a/postfix/src/global/pipe_command.c b/postfix/src/global/pipe_command.c index 550f87c3c..322747b8a 100644 --- a/postfix/src/global/pipe_command.c +++ b/postfix/src/global/pipe_command.c @@ -380,13 +380,13 @@ int pipe_command(VSTREAM *src, VSTRING *why,...) * Turn on non-blocking writes to the child process so that we can enforce * timeouts after partial writes. * - * XXX This breaks on IRIX where select reports that a pipe is writable - * while write transfers zero bytes. + * XXX Too much trouble with different systems returning weird write() + * results when a pipe is writable. */ if (pipe(cmd_in_pipe) < 0 || pipe(cmd_out_pipe) < 0) msg_fatal("%s: pipe: %m", myname); non_blocking(cmd_out_pipe[1], NON_BLOCKING); -#ifndef BROKEN_WRITE_SELECT_ON_NON_BLOCKING_PIPE +#if 0 non_blocking(cmd_in_pipe[1], NON_BLOCKING); #endif diff --git a/postfix/src/global/rec_type.h b/postfix/src/global/rec_type.h index 70aef24c9..5bb910952 100644 --- a/postfix/src/global/rec_type.h +++ b/postfix/src/global/rec_type.h @@ -82,6 +82,13 @@ #define REC_TYPE_CONTENT "XLN" #define REC_TYPE_EXTRACT "EDROPreAFIL>" + /* + * The subset of inputs that the postdrop command allows. + */ +#define REC_TYPE_POST_ENVELOPE "MFSRVA" +#define REC_TYPE_POST_CONTENT "XLN" +#define REC_TYPE_POST_EXTRACT "ERA" + /* * The record at the beginning of the envelope segment specifies the message * content size, data offset, recipient count, and processing flags. These @@ -94,14 +101,6 @@ #define REC_TYPE_SIZE_CAST3 long #define REC_TYPE_SIZE_CAST4 long - /* - * The record at the beginning of the message content records specifies the - * position of the next record group. This is the format of the position - * field. It is a fixed-width field so it can be updated in place. - */ -#define REC_TYPE_MESG_FORMAT "%15ld" /* message length format */ -#define REC_TYPE_MESG_CAST long - /* * The warn record specifies when the next warning that the message was * deferred should be sent. It is updated in place by qmgr, so changing diff --git a/postfix/src/nqmgr/qmgr_message.c b/postfix/src/nqmgr/qmgr_message.c index d252cff69..eb45a9c39 100644 --- a/postfix/src/nqmgr/qmgr_message.c +++ b/postfix/src/nqmgr/qmgr_message.c @@ -216,7 +216,6 @@ static void qmgr_message_oldstyle_scan(QMGR_MESSAGE *message) { VSTRING *buf; long orig_offset, - curr_offset, extra_offset; int rec_type; char *start; @@ -243,8 +242,6 @@ static void qmgr_message_oldstyle_scan(QMGR_MESSAGE *message) */ message->rcpt_unread = 0; for (;;) { - if ((curr_offset = vstream_ftell(message->fp)) < 0) - msg_fatal("vstream_ftell %s: %m", VSTREAM_PATH(message->fp)); rec_type = rec_get(message->fp, buf, 0); if (rec_type <= 0) /* Report missing end record later. */ @@ -344,7 +341,7 @@ static int qmgr_message_read(QMGR_MESSAGE *message) * queue file, to protect against memory exhaustion. Recipient records * may appear before or after the message content, so we keep reading * from the queue file until we have enough recipients (rcpt_offset != 0) - * and until we know all the non-recipient extracted segment information. + * and until we know all the non-recipient information. * * Note that the total recipient count record is accurate only for fresh * queue files. After some of the recipients are marked as done and the @@ -358,8 +355,8 @@ static int qmgr_message_read(QMGR_MESSAGE *message) * XXX We know how to skip over large numbers of recipient records in the * initial envelope segment but we haven't yet implemented code to skip * over large numbers of recipient records in the extracted envelope - * segment. This is not a problem as long as only "sendmail -t" produces - * extracted segment recipients. + * segment. This is not a problem as long as extracted segment recipients + * are not mixed with non-recipient information (sendmail -t, qmqpd). */ for (;;) { if ((curr_offset = vstream_ftell(message->fp)) < 0) diff --git a/postfix/src/pickup/pickup.c b/postfix/src/pickup/pickup.c index a7ac88035..b4b116ef6 100644 --- a/postfix/src/pickup/pickup.c +++ b/postfix/src/pickup/pickup.c @@ -87,7 +87,6 @@ #include #include #include -#include /* Global library. */ @@ -154,9 +153,6 @@ static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info, { int type; int check_first = (*expected == REC_TYPE_CONTENT[0]); - const char *error_text; - char *attr_name; - char *attr_value; /* * Limit the input record size. All front-end programs should protect the @@ -181,44 +177,17 @@ static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info, if (type == REC_TYPE_FROM) if (info->sender == 0) info->sender = mystrdup(vstring_str(buf)); - if (type == REC_TYPE_ORCP) - if (info->st.st_uid != var_owner_uid) { - msg_warn("uid=%ld: ignoring original recipient record: %.200s", - (long) info->st.st_uid, vstring_str(buf)); - continue; - } if (type == REC_TYPE_TIME) /* Use our own arrival time record instead. */ continue; - if (type == REC_TYPE_ATTR) { - if ((error_text = split_nameval(vstring_str(buf), &attr_name, - &attr_value)) != 0) { - msg_warn("uid=%ld: malformed attribute record: %s: %.200s", - (long) info->st.st_uid, error_text, vstring_str(buf)); - continue; - } -#define STREQ(x,y) (strcmp(x,y) == 0) - - if ((STREQ(attr_name, MAIL_ATTR_ENCODING) - && (STREQ(attr_value, MAIL_ATTR_ENC_7BIT) - || STREQ(attr_value, MAIL_ATTR_ENC_8BIT) - || STREQ(attr_value, MAIL_ATTR_ENC_NONE))) - || STREQ(attr_name, MAIL_ATTR_TRACE_FLAGS)) { /* XXX */ - rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s", - attr_name, attr_value); - } else if (info->st.st_uid != var_owner_uid) { - msg_warn("uid=%ld: ignoring attribute record: %.200s=%.200s", - (long) info->st.st_uid, attr_name, attr_value); - } - continue; - } /* * XXX Force an empty record when the queue file content begins with * whitespace, so that it won't be considered as being part of our * own Received: header. What an ugly Kluge. */ - if (check_first && *expected == REC_TYPE_CONTENT[0]) { + if (check_first + && (type == REC_TYPE_NORM || type == REC_TYPE_CONT)) { check_first = 0; if (VSTRING_LEN(buf) > 0 && IS_SPACE_TAB(vstring_str(buf)[0])) rec_put(cleanup, REC_TYPE_NORM, "", 0); diff --git a/postfix/src/postdrop/postdrop.c b/postfix/src/postdrop/postdrop.c index 141702406..f8397cee0 100644 --- a/postfix/src/postdrop/postdrop.c +++ b/postfix/src/postdrop/postdrop.c @@ -97,6 +97,7 @@ #include #include #include +#include /* Global library. */ @@ -178,11 +179,14 @@ int main(int argc, char **argv) MAIL_STREAM *dst; int rec_type; static char *segment_info[] = { - REC_TYPE_ENVELOPE, REC_TYPE_CONTENT, REC_TYPE_EXTRACT, + REC_TYPE_POST_ENVELOPE, REC_TYPE_POST_CONTENT, REC_TYPE_POST_EXTRACT, "" }; char **expected; uid_t uid = getuid(); ARGV *import_env; + const char *error_text; + char *attr_name; + char *attr_value; /* * Be consistent with file permissions. @@ -297,6 +301,9 @@ int main(int argc, char **argv) * * If something goes wrong, slurp up the input before responding to the * client, otherwise the client will give up after detecting SIGPIPE. + * + * Allow attribute records if the attribute specifies the MIME body type + * (sendmail -B). */ vstream_control(VSTREAM_IN, VSTREAM_CTL_PATH, "stdin", VSTREAM_CTL_END); buf = vstring_alloc(100); @@ -319,6 +326,28 @@ int main(int argc, char **argv) msg_fatal("uid=%ld: unexpected record type: %d", (long) uid, rec_type); if (rec_type == **expected) expected++; + if (rec_type == REC_TYPE_ATTR) { + if ((error_text = split_nameval(vstring_str(buf), &attr_name, + &attr_value)) != 0) { + msg_warn("uid=%ld: ignoring malformed record: %s: %.200s", + (long) uid, error_text, vstring_str(buf)); + continue; + } +#define STREQ(x,y) (strcmp(x,y) == 0) + + if ((STREQ(attr_name, MAIL_ATTR_ENCODING) + && (STREQ(attr_value, MAIL_ATTR_ENC_7BIT) + || STREQ(attr_value, MAIL_ATTR_ENC_8BIT) + || STREQ(attr_value, MAIL_ATTR_ENC_NONE))) + || STREQ(attr_name, MAIL_ATTR_TRACE_FLAGS)) { /* XXX */ + rec_fprintf(dst->stream, REC_TYPE_ATTR, "%s=%s", + attr_name, attr_value); + } else { + msg_warn("uid=%ld: ignoring attribute record: %.200s=%.200s", + (long) uid, attr_name, attr_value); + } + continue; + } if (REC_PUT_BUF(dst->stream, rec_type, buf) < 0) { while ((rec_type = rec_get(VSTREAM_IN, buf, var_line_limit)) > 0 && rec_type != REC_TYPE_END) diff --git a/postfix/src/qmgr/qmgr_message.c b/postfix/src/qmgr/qmgr_message.c index 918ea599a..ab0ad3b64 100644 --- a/postfix/src/qmgr/qmgr_message.c +++ b/postfix/src/qmgr/qmgr_message.c @@ -202,7 +202,6 @@ static void qmgr_message_oldstyle_scan(QMGR_MESSAGE *message) { VSTRING *buf; long orig_offset, - curr_offset, extra_offset; int rec_type; char *start; @@ -228,8 +227,6 @@ static void qmgr_message_oldstyle_scan(QMGR_MESSAGE *message) * completely. */ for (;;) { - if ((curr_offset = vstream_ftell(message->fp)) < 0) - msg_fatal("vstream_ftell %s: %m", VSTREAM_PATH(message->fp)); rec_type = rec_get(message->fp, buf, 0); if (rec_type <= 0) /* Report missing end record later. */ @@ -309,7 +306,7 @@ static int qmgr_message_read(QMGR_MESSAGE *message) * queue file, to protect against memory exhaustion. Recipient records * may appear before or after the message content, so we keep reading * from the queue file until we have enough recipients (rcpt_offset != 0) - * and until we know all the non-recipient extracted segment information. + * and until we know all the non-recipient information. * * When reading recipients from queue file, stop reading when we reach a * per-message in-core recipient limit rather than a global in-core @@ -327,8 +324,8 @@ static int qmgr_message_read(QMGR_MESSAGE *message) * XXX We know how to skip over large numbers of recipient records in the * initial envelope segment but we haven't yet implemented code to skip * over large numbers of recipient records in the extracted envelope - * segment. This is not a problem as long as only "sendmail -t" produces - * extracted segment recipients. + * segment. This is not a problem as long as extracted segment recipients + * are not mixed with non-recipient information (sendmail -t, qmqpd). */ for (;;) { if ((curr_offset = vstream_ftell(message->fp)) < 0) diff --git a/postfix/src/sendmail/sendmail.c b/postfix/src/sendmail/sendmail.c index ddd82369e..6b9ec6262 100644 --- a/postfix/src/sendmail/sendmail.c +++ b/postfix/src/sendmail/sendmail.c @@ -561,7 +561,7 @@ static void enqueue(const int flags, const char *encoding, const char *sender, * delivered intact via SMTP. Strip leading From_ lines. For the benefit * of UUCP environments, also get rid of leading >>>From_ lines. */ - rec_fprintf(dst, REC_TYPE_MESG, REC_TYPE_MESG_FORMAT, 0L); + rec_fputs(dst, REC_TYPE_MESG, ""); if (DEL_REQ_TRACE_ONLY(flags) != 0) { rec_fprintf(dst, REC_TYPE_NORM, "Subject: probe"); if (recipients) { diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 91a864aee..af022047c 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -816,7 +816,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) verp_delims = arg + VERP_CMD_LEN + 1; if (verp_delims_verify(verp_delims) != 0) { state->error_mask |= MAIL_ERROR_PROTOCOL; - smtpd_chat_reply(state, "501 %s needs two characters from %s", + smtpd_chat_reply(state, "501 Error: %s needs two characters from %s", VERP_CMD, var_verp_filter); return (-1); } @@ -828,7 +828,8 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) } } if (verp_delims && argv[2].strval[0] == 0) { - smtpd_chat_reply(state, "503 Error: XVERP requires non-null sender"); + smtpd_chat_reply(state, "503 Error: %s requires non-null sender", + VERP_CMD); return (-1); } state->time = time((time_t *) 0); diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h index 334fe749a..a369b7e86 100644 --- a/postfix/src/smtpd/smtpd.h +++ b/postfix/src/smtpd/smtpd.h @@ -95,10 +95,6 @@ typedef struct SMTPD_STATE { int defer_if_permit_sender; /* force permit into warning */ int discard; /* discard message */ VSTRING *expand_buf; /* scratch space for $name expansion */ - int session_hold; /* per-session hold action */ - int session_discard; /* per-session discard_action */ - char *session_filter; /* per-session filter action */ - char *session_redirect; /* per-session redirect action */ } SMTPD_STATE; extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *); diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index fc14ab175..f3ef3fe4f 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -429,19 +429,6 @@ static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient); */ #define STR vstring_str #define CONST_STR(x) ((const char *) vstring_str(x)) -#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0) - - /* - * Safety. - */ -#define SAFE_STRDUP(dst, src) { \ - if (src) { \ - if (dst) { \ - myfree(dst); \ - } \ - dst = mystrdup(src); \ - } \ - } /* * If some decision can't be made due to a temporary error, then change @@ -1799,16 +1786,9 @@ static int check_table_result(SMTPD_STATE *state, const char *table, vstring_sprintf(error_text, "<%s>: %s triggers FILTER %s", reply_name, reply_class, cmd_text); log_whatsup(state, "filter", STR(error_text)); - /* This action must execute with every MAIL FROM command. */ - if (var_smtpd_delay_reject == 0 - && (STREQ(reply_class, SMTPD_NAME_CLIENT) - || STREQ(reply_class, SMTPD_NAME_HELO))) { - SAFE_STRDUP(state->session_filter, cmd_text); - } else { #ifndef TEST - rec_fprintf(state->dest->stream, REC_TYPE_FILT, "%s", cmd_text); + rec_fprintf(state->dest->stream, REC_TYPE_FILT, "%s", cmd_text); #endif - } return (SMTPD_CHECK_DUNNO); } } @@ -1827,17 +1807,10 @@ static int check_table_result(SMTPD_STATE *state, const char *table, vstring_sprintf(error_text, "<%s>: %s %s", reply_name, reply_class, *cmd_text ? cmd_text : "triggers HOLD action"); log_whatsup(state, "hold", STR(error_text)); - /* This action must execute with every MAIL FROM command. */ - if (var_smtpd_delay_reject == 0 - && (STREQ(reply_class, SMTPD_NAME_CLIENT) - || STREQ(reply_class, SMTPD_NAME_HELO))) { - state->session_hold = 1; - } else { #ifndef TEST - rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d", - CLEANUP_FLAG_HOLD); + rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d", + CLEANUP_FLAG_HOLD); #endif - } return (SMTPD_CHECK_DUNNO); } @@ -1854,18 +1827,11 @@ static int check_table_result(SMTPD_STATE *state, const char *table, vstring_sprintf(error_text, "<%s>: %s %s", reply_name, reply_class, *cmd_text ? cmd_text : "triggers DISCARD action"); log_whatsup(state, "discard", STR(error_text)); - /* This action must execute with every MAIL FROM command. */ - if (var_smtpd_delay_reject == 0 - && (STREQ(reply_class, SMTPD_NAME_CLIENT) - || STREQ(reply_class, SMTPD_NAME_HELO))) { - state->session_discard = 1; - } else { #ifndef TEST - rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d", - CLEANUP_FLAG_DISCARD); - state->discard = 1; + rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d", + CLEANUP_FLAG_DISCARD); + state->discard = 1; #endif - } return (SMTPD_CHECK_OK); } @@ -1888,16 +1854,9 @@ static int check_table_result(SMTPD_STATE *state, const char *table, vstring_sprintf(error_text, "<%s>: %s triggers REDIRECT %s", reply_name, reply_class, cmd_text); log_whatsup(state, "redirect", STR(error_text)); - /* This action must execute with every MAIL FROM command. */ - if (var_smtpd_delay_reject == 0 - && (STREQ(reply_class, SMTPD_NAME_CLIENT) - || STREQ(reply_class, SMTPD_NAME_HELO))) { - SAFE_STRDUP(state->session_redirect, cmd_text); - } else { #ifndef TEST - rec_fprintf(state->dest->stream, REC_TYPE_RDR, "%s", cmd_text); + rec_fprintf(state->dest->stream, REC_TYPE_RDR, "%s", cmd_text); #endif - } return (SMTPD_CHECK_DUNNO); } } @@ -2307,6 +2266,8 @@ static const char *smtpd_expand_addr(VSTRING *buf, const char *addr, /* * "sender_name" or "recipient_name". */ +#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0) + else if (STREQ(suffix, MAIL_ATTR_S_NAME)) { if (*addr) { if ((p = strrchr(addr, '@')) != 0) { @@ -3127,27 +3088,6 @@ char *smtpd_check_mail(SMTPD_STATE *state, char *sender) if (sender == 0) return (0); - /* - * Actions that were triggered during connect or HELO need to be repeated - * with each MAIL FROM command. - */ - if (var_smtpd_delay_reject == 0) { -#ifndef TEST - if (state->session_hold) - rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d", - CLEANUP_FLAG_HOLD); - if (state->session_discard) - rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d", - CLEANUP_FLAG_DISCARD); - if (state->session_redirect) - rec_fprintf(state->dest->stream, REC_TYPE_RDR, "%s", - state->session_redirect); - if (state->session_filter) - rec_fprintf(state->dest->stream, REC_TYPE_FILT, "%s", - state->session_filter); -#endif - } - /* * Minor kluge so that we can delegate work to the generic routine and so * that we can syslog the recipient with the reject messages. diff --git a/postfix/src/smtpd/smtpd_check.h b/postfix/src/smtpd/smtpd_check.h index 26573d334..302e26903 100644 --- a/postfix/src/smtpd/smtpd_check.h +++ b/postfix/src/smtpd/smtpd_check.h @@ -20,7 +20,6 @@ extern char *smtpd_check_size(SMTPD_STATE *, off_t); extern char *smtpd_check_rcpt(SMTPD_STATE *, char *); extern char *smtpd_check_etrn(SMTPD_STATE *, char *); extern char *smtpd_check_data(SMTPD_STATE *); -extern char *smtpd_check_dot(SMTPD_STATE *); /* LICENSE /* .ad diff --git a/postfix/src/smtpd/smtpd_state.c b/postfix/src/smtpd/smtpd_state.c index 599d53854..6475ae49b 100644 --- a/postfix/src/smtpd/smtpd_state.c +++ b/postfix/src/smtpd/smtpd_state.c @@ -99,10 +99,6 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream) state->defer_if_permit.reason = 0; state->discard = 0; state->expand_buf = 0; - state->session_hold = 0; - state->session_discard = 0; - state->session_filter = 0; - state->session_redirect = 0; #ifdef USE_SASL_AUTH if (SMTPD_STAND_ALONE(state)) @@ -141,10 +137,6 @@ void smtpd_state_reset(SMTPD_STATE *state) vstring_free(state->defer_if_reject.reason); if (state->expand_buf) vstring_free(state->expand_buf); - if (state->session_filter) - myfree(state->session_filter); - if (state->session_redirect) - myfree(state->session_redirect); #ifdef USE_SASL_AUTH if (var_smtpd_sasl_enable) diff --git a/postfix/src/util/dict_mysql.c b/postfix/src/util/dict_mysql.c index f778e928d..baecfb85b 100644 --- a/postfix/src/util/dict_mysql.c +++ b/postfix/src/util/dict_mysql.c @@ -127,6 +127,7 @@ typedef struct { static PLMYSQL *plmysql_init(char *hostnames[], int); static MYSQL_RES *plmysql_query(PLMYSQL *, const char *, char *, char *, char *); static void plmysql_dealloc(PLMYSQL *); +static void plmysql_close_host(HOST *); static void plmysql_down_host(HOST *); static void plmysql_connect_single(HOST *, char *, char *, char *); static int plmysql_ready_reconn(HOST *); @@ -246,7 +247,7 @@ static MYSQL_RES *plmysql_query(PLMYSQL *PLDB, if (msg_verbose) msg_info("dict_mysql: closing unnessary connection to %s", host->hostname); - plmysql_down_host(host); + plmysql_close_host(host); } /* try to connect for the first time if we don't have a result yet */ if (res == 0 && host->stat == STATUNTRIED) { @@ -331,18 +332,24 @@ static void plmysql_connect_single(HOST *host, char *dbname, char *username, cha myfree(hostname); } +/* plmysql_close_host - close an established MySQL connection */ +static void plmysql_close_host(HOST *host) +{ + mysql_close(host->db); + host->db = 0; + host->stat = STATUNTRIED; +} + /* - * plmysql_down_host - mark a HOST down update ts if marked down - * for the first time so that we'll know when to retry the connection + * plmysql_down_host - close a failed connection AND set a "stay away from + * this host" timer */ static void plmysql_down_host(HOST *host) { - if (host->stat != STATFAIL) { - host->ts = time((time_t *) 0) + RETRY_CONN_INTV; - host->stat = STATFAIL; - } mysql_close(host->db); host->db = 0; + host->ts = time((time_t *) 0) + RETRY_CONN_INTV; + host->stat = STATFAIL; } /********************************************************************** diff --git a/postfix/src/util/dict_pgsql.c b/postfix/src/util/dict_pgsql.c index 7968168e1..97289c045 100644 --- a/postfix/src/util/dict_pgsql.c +++ b/postfix/src/util/dict_pgsql.c @@ -139,6 +139,7 @@ typedef struct { static PLPGSQL *plpgsql_init(char *hostnames[], int); static PGSQL_RES *plpgsql_query(PLPGSQL *, const char *, char *, char *, char *); static void plpgsql_dealloc(PLPGSQL *); +static void plpgsql_close_host(HOST *); static void plpgsql_down_host(HOST *); static void plpgsql_connect_single(HOST *, char *, char *, char *); static const char *dict_pgsql_lookup(DICT *, const char *); @@ -380,7 +381,7 @@ static PGSQL_RES *plpgsql_query(PLPGSQL *PLDB, if (msg_verbose) msg_info("dict_pgsql: closing unnessary connection to %s", host->hostname); - plpgsql_down_host(host); + plpgsql_close_host(host); } /* try to connect for the first time if we don't have a result yet */ if (res == 0 && host->stat == STATUNTRIED) { @@ -461,18 +462,25 @@ static void plpgsql_connect_single(HOST *host, char *dbname, char *username, cha myfree(hostname); } +/* plpgsql_close_host - close an established PostgreSQL connection */ + +static void plpgsql_close_host(HOST *host) +{ + PQfinish(host->db); + host->db = 0; + host->stat = STATUNTRIED; +} + /* - * plpgsql_down_host - mark a HOST down update ts if marked down - * for the first time so that we'll know when to retry the connection + * plpgsql_down_host - close a failed connection AND set a "stay away from + * this host" timer. */ static void plpgsql_down_host(HOST *host) { - if (host->stat != STATFAIL) { - host->ts = time((time_t *) 0) + RETRY_CONN_INTV; - host->stat = STATFAIL; - } PQfinish(host->db); host->db = 0; + host->ts = time((time_t *) 0) + RETRY_CONN_INTV; + host->stat = STATFAIL; } /********************************************************************** diff --git a/postfix/src/util/non_blocking.c b/postfix/src/util/non_blocking.c index 08f0c8243..6427cd80f 100644 --- a/postfix/src/util/non_blocking.c +++ b/postfix/src/util/non_blocking.c @@ -44,7 +44,7 @@ #include "iostuff.h" /* Backwards compatibility */ -#ifdef FNDELAY +#ifndef O_NONBLOCK #define PATTERN FNDELAY #else #define PATTERN O_NONBLOCK diff --git a/postfix/src/util/vstream.c b/postfix/src/util/vstream.c index 90ee2c7fd..9366915c2 100644 --- a/postfix/src/util/vstream.c +++ b/postfix/src/util/vstream.c @@ -810,6 +810,8 @@ long vstream_fseek(VSTREAM *stream, long offset, int whence) if (bp->ptr > bp->data) { if (whence == SEEK_CUR) offset += (bp->ptr - bp->data); /* add unwritten data */ + else if (whence == SEEK_END) + bp->flags &= ~VSTREAM_FLAG_SEEK; if (VSTREAM_FFLUSH_SOME(stream)) return (-1); } @@ -818,6 +820,8 @@ long vstream_fseek(VSTREAM *stream, long offset, int whence) case VSTREAM_FLAG_READ: if (whence == SEEK_CUR) offset += bp->cnt; /* subtract unread data */ + else if (whence == SEEK_END) + bp->flags &= ~VSTREAM_FLAG_SEEK; case 0: VSTREAM_BUF_AT_END(bp); break; diff --git a/postfix/src/virtual/Makefile.in b/postfix/src/virtual/Makefile.in index 8c47cfe0d..7ab030855 100644 --- a/postfix/src/virtual/Makefile.in +++ b/postfix/src/virtual/Makefile.in @@ -87,7 +87,7 @@ mailbox.o: ../../include/deliver_request.h mailbox.o: ../../include/recipient_list.h mailbox.o: ../../include/sent.h mailbox.o: ../../include/mail_params.h -mailbox.o: ../../include/virtual8_maps.h +mailbox.o: ../../include/mail_addr_find.h mailbox.o: ../../include/maps.h mailbox.o: ../../include/dict.h mailbox.o: ../../include/argv.h @@ -163,7 +163,7 @@ virtual.o: ../../include/deliver_request.h virtual.o: ../../include/deliver_completed.h virtual.o: ../../include/mail_params.h virtual.o: ../../include/mail_conf.h -virtual.o: ../../include/virtual8_maps.h +virtual.o: ../../include/mail_addr_find.h virtual.o: ../../include/maps.h virtual.o: ../../include/mail_server.h virtual.o: virtual.h diff --git a/postfix/src/virtual/mailbox.c b/postfix/src/virtual/mailbox.c index 87a8e691f..afb61978b 100644 --- a/postfix/src/virtual/mailbox.c +++ b/postfix/src/virtual/mailbox.c @@ -60,7 +60,7 @@ #include #include #include -#include +#include #ifndef EDQUOT #define EDQUOT EFBIG @@ -182,7 +182,10 @@ int deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp) * Look up the mailbox location. Bounce if not found, defer in case of * trouble. */ - mailbox_res = virtual8_maps_find(virtual_mailbox_maps, state.msg_attr.user); +#define IGNORE_EXTENSION ((char **) 0) + + mailbox_res = mail_addr_find(virtual_mailbox_maps, state.msg_attr.user, + IGNORE_EXTENSION); if (mailbox_res == 0) { if (dict_errno == 0) return (NO); @@ -201,7 +204,8 @@ int deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp) /* * Look up the mailbox owner rights. Defer in case of trouble. */ - uid_res = virtual8_maps_find(virtual_uid_maps, state.msg_attr.user); + uid_res = mail_addr_find(virtual_uid_maps, state.msg_attr.user, + IGNORE_EXTENSION); if (uid_res == 0) { *statusp = defer_append(BOUNCE_FLAGS(state.request), BOUNCE_ATTR(state.msg_attr), @@ -221,7 +225,8 @@ int deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp) /* * Look up the mailbox group rights. Defer in case of trouble. */ - gid_res = virtual8_maps_find(virtual_gid_maps, state.msg_attr.user); + gid_res = mail_addr_find(virtual_gid_maps, state.msg_attr.user, + IGNORE_EXTENSION); if (gid_res == 0) { *statusp = defer_append(BOUNCE_FLAGS(state.request), BOUNCE_ATTR(state.msg_attr), diff --git a/postfix/src/virtual/virtual.c b/postfix/src/virtual/virtual.c index 3ae4bdc52..3a22ecd20 100644 --- a/postfix/src/virtual/virtual.c +++ b/postfix/src/virtual/virtual.c @@ -20,8 +20,8 @@ /* .fi /* The mailbox location is controlled by the \fBvirtual_mailbox_base\fR /* and \fBvirtual_mailbox_maps\fR configuration parameters (see below). -/* The \fBvirtual_mailbox_maps\fR table is indexed by the full recipient -/* address. +/* The \fBvirtual_mailbox_maps\fR table is indexed by the recipient +/* address as described under TABLE SEARCH ORDER below. /* /* The mailbox pathname is constructed as follows: /* @@ -74,6 +74,32 @@ /* The \fBvirtual_minimum_uid\fR parameter imposes a lower bound on /* numerical user ID values that may be specified in any /* \fBvirtual_uid_maps\fR. +/* TABLE SEARCH ORDER +/* .ad +/* .fi +/* Normally, a lookup table is specified as a text file that +/* serves as input to the \fBpostmap\fR(1) command. The result, an +/* indexed file in \fBdbm\fR or \fBdb\fR format, is used for fast +/* searching by the mail system. +/* +/* The canonical search order is as follows. The search stops +/* upon the first successful lookup. +/* .IP \(bu +/* When the recipient has an optional address extension the +/* \fIuser+extension@domain.tld\fR address is looked up first. +/* .IP \(bu +/* The \fIuser@domain.tld\fR address, without address extension, +/* is looked up next. +/* .IP \(bu +/* Finally, the recipient \fI@domain\fR is looked up. +/* .PP +/* When the table is provided via other means such as NIS, LDAP +/* or SQL, the same lookups are done as for ordinary indexed files. +/* +/* Alternatively, a table can be provided as a regular-expression +/* map where patterns are given as regular expressions. In that case, +/* only the full recipient address is given to the regular-expression +/* map. /* SECURITY /* .ad /* .fi @@ -94,7 +120,9 @@ /* Depending on the setting of the \fBnotify_classes\fR parameter, /* the postmaster is notified of bounces and of other trouble. /* BUGS -/* This delivery agent silently ignores address extensions. +/* This delivery agent supports address extensions in email +/* addresses and in lookup table keys, but does not propagate +/* address extension information to the result of table lookup. /* /* Postfix should have lookup tables that can return multiple result /* attributes. In order to avoid the inconvenience of maintaining @@ -142,7 +170,7 @@ /* configuration parameter. /* .IP \fBvirtual_minimum_uid\fR /* Specifies a minimum uid that will be accepted as a return from -/* a \fBvirtual_owner_maps\fR or \fBvirtual_uid_maps\fR lookup. +/* a \fBvirtual_uid_maps\fR lookup. /* Returned values less than this will be rejected, and the message /* will be deferred. /* .IP \fBvirtual_uid_maps\fR @@ -283,7 +311,7 @@ #include #include #include -#include +#include /* Single server skeleton. */ @@ -414,15 +442,15 @@ static void post_init(char *unused_name, char **unused_argv) set_eugid(var_owner_uid, var_owner_gid); virtual_mailbox_maps = - virtual8_maps_create(VAR_VIRT_MAILBOX_MAPS, var_virt_mailbox_maps, + maps_create(VAR_VIRT_MAILBOX_MAPS, var_virt_mailbox_maps, DICT_FLAG_LOCK | DICT_FLAG_PARANOID); virtual_uid_maps = - virtual8_maps_create(VAR_VIRT_UID_MAPS, var_virt_uid_maps, + maps_create(VAR_VIRT_UID_MAPS, var_virt_uid_maps, DICT_FLAG_LOCK | DICT_FLAG_PARANOID); virtual_gid_maps = - virtual8_maps_create(VAR_VIRT_GID_MAPS, var_virt_gid_maps, + maps_create(VAR_VIRT_GID_MAPS, var_virt_gid_maps, DICT_FLAG_LOCK | DICT_FLAG_PARANOID); virtual_mbox_lock_mask = mbox_lock_mask(var_virt_mailbox_lock);