]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.0.11-20030605
authorWietse Venema <wietse@porcupine.org>
Thu, 5 Jun 2003 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:28:55 +0000 (06:28 +0000)
27 files changed:
postfix/HISTORY
postfix/README_FILES/VIRTUAL_README
postfix/html/virtual.8.html
postfix/man/man8/virtual.8
postfix/src/cleanup/Makefile.in
postfix/src/cleanup/cleanup_envelope.c
postfix/src/cleanup/cleanup_extracted.c
postfix/src/global/mail_version.h
postfix/src/global/pipe_command.c
postfix/src/global/rec_type.h
postfix/src/nqmgr/qmgr_message.c
postfix/src/pickup/pickup.c
postfix/src/postdrop/postdrop.c
postfix/src/qmgr/qmgr_message.c
postfix/src/sendmail/sendmail.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd.h
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpd/smtpd_check.h
postfix/src/smtpd/smtpd_state.c
postfix/src/util/dict_mysql.c
postfix/src/util/dict_pgsql.c
postfix/src/util/non_blocking.c
postfix/src/util/vstream.c
postfix/src/virtual/Makefile.in
postfix/src/virtual/mailbox.c
postfix/src/virtual/virtual.c

index 88bf11709869d4e72f83e9c724acc4bd179e0a5a..d59c39046051be042f628463cee28beb3ff73a61 100644 (file)
@@ -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.
index 5c9df76137f60ee0644194f185ea345cda4c23a3..3a4220e1232ee5c3889abfd31e2e786657fc3dfc 100644 (file)
@@ -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.
 
index c36f4e3137dabe104ad7a530e1dc4757ab8a8c99..550e4712d2dfb1c3f7930c15ab189581affb1d0c 100644 (file)
@@ -24,7 +24,8 @@ VIRTUAL(8)                                             VIRTUAL(8)
        The  mailbox  location  is controlled by the <b>virtual</b><i>_</i><b>mail-</b>
        <b>box</b><i>_</i><b>base</b> and <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>maps</b> configuration parameters
        (see below).  The <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>maps</b> 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 <i>recipient</i> is the full recipient address.
 
 <b>UNIX</b> <b>MAILBOX</b> <b>FORMAT</b>
-       When the mailbox location does not end in <b>/</b>,  the  message
-       is  delivered in UNIX mailbox format.   This format stores
+       When  the  mailbox location does not end in <b>/</b>, the message
+       is delivered in UNIX mailbox format.   This format  stores
        multiple messages in one textfile.
 
-       The  <b>virtual</b>  delivery  agent  prepends  a  "<b>From</b>   <i>sender</i>
-       <i>time_stamp</i>"  envelope  header  to each message, prepends a
-       <b>Delivered-To:</b> message header with the  envelope  recipient
+       The   <b>virtual</b>  delivery  agent  prepends  a  "<b>From</b>  <i>sender</i>
+       <i>time_stamp</i>" envelope header to each  message,  prepends  a
+       <b>Delivered-To:</b>  message  header with the envelope recipient
        address, prepends an <b>X-Original-To:</b> header with the recip-
-       ient address as given to Postfix, prepends a  <b>Return-Path:</b>
-       message  header with the envelope sender address, prepends
+       ient  address as given to Postfix, prepends a <b>Return-Path:</b>
+       message header with the envelope sender address,  prepends
        a &gt; character to lines beginning with "<b>From</b> ", 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.
 
 <b>QMAIL</b> <b>MAILDIR</b> <b>FORMAT</b>
        When the mailbox location ends in <b>/</b>, the message is deliv-
-       ered in qmail <b>maildir</b> format. This format stores one  mes-
+       ered  in qmail <b>maildir</b> format. This format stores one mes-
        sage per file.
 
        The <b>virtual</b> delivery agent daemon prepends a <b>Delivered-To:</b>
-       message header with the final envelope recipient  address,
+       message  header with the final envelope recipient address,
        prepends  an  <b>X-Original-To:</b>  header  with  the  recipient
-       address as given to Postfix, and prepends  a  <b>Return-Path:</b>
+       address  as  given to Postfix, and prepends a <b>Return-Path:</b>
        message header with the envelope sender address.
 
-       By  definition, <b>maildir</b> format does not require file lock-
+       By definition, <b>maildir</b> format does not require file  lock-
        ing during mail delivery or retrieval.
 
 <b>MAILBOX</b> <b>OWNERSHIP</b>
-       Mailbox ownership is controlled  by  the  <b>virtual</b><i>_</i><b>uid</b><i>_</i><b>maps</b>
+       Mailbox  ownership  is  controlled by the <b>virtual</b><i>_</i><b>uid</b><i>_</i><b>maps</b>
        and <b>virtual</b><i>_</i><b>gid</b><i>_</i><b>maps</b> 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 <b>virtual</b><i>_</i><b>minimum</b><i>_</i><b>uid</b> parameter imposes a lower bound on
        numerical user ID values that may be specified in any <b>vir-</b>
        <b>tual</b><i>_</i><b>uid</b><i>_</i><b>maps</b>.
 
+<b>TABLE</b> <b>SEARCH</b> <b>ORDER</b>
+       Normally, a lookup table is specified as a text file  that
+       serves  as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command. The result, an
+       indexed file in <b>dbm</b> or <b>db</b> 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.
+
+       <b>o</b>      When the recipient has an optional  address  exten-
+              sion   the   <i>user+extension@domain.tld</i>  address  is
+              looked up first.
+
+       <b>o</b>      The <i>user@domain.tld</i> address, without address exten-
+              sion, is looked up next.
+
+       <b>o</b>      Finally, the recipient <i>@domain</i> 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.
+
 <b>SECURITY</b>
        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.
 
 <b>STANDARDS</b>
@@ -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 <b>syslogd</b>(8).  Cor-
-       rupted message files are marked so that the queue  manager
+       Problems and transactions are logged to <b>syslogd</b>(8).   Cor-
+       rupted  message files are marked so that the queue manager
        can move them to the <b>corrupt</b> queue afterwards.
 
-       Depending  on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
-       the postmaster is notified of bounces and of  other  trou-
+       Depending on the setting of the <b>notify</b><i>_</i><b>classes</b>  parameter,
+       the  postmaster  is notified of bounces and of other trou-
        ble.
 
 <b>BUGS</b>
-       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)
 
        <b>virtual</b><i>_</i><b>minimum</b><i>_</i><b>uid</b>
               Specifies  a minimum uid that will be accepted as a
-              return   from   a   <b>virtual</b><i>_</i><b>owner</b><i>_</i><b>maps</b>   or    <b>vir-</b>
-              <b>tual</b><i>_</i><b>uid</b><i>_</i><b>maps</b>  lookup.   Returned  values less than
-              this will be rejected,  and  the  message  will  be
-              deferred.
+              return from a  <b>virtual</b><i>_</i><b>uid</b><i>_</i><b>maps</b>  lookup.   Returned
+              values  less  than  this  will be rejected, and the
+              message will be deferred.
 
        <b>virtual</b><i>_</i><b>uid</b><i>_</i><b>maps</b>
               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 (<i>user+foo@domain.tld</i>) is ignored.
 
-              In a lookup table,  specify  a  left-hand  side  of
-              <i>@domain.tld</i>  to  match  any  user  in the specified
-              domain   that   does   not    have    a    specific
+              In  a  lookup  table,  specify  a left-hand side of
+              <i>@domain.tld</i> to match  any  user  in  the  specified
+              domain    that    does    not   have   a   specific
               <i>user@domain.tld</i> 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.
 
        <b>virtual</b><i>_</i><b>gid</b><i>_</i><b>maps</b>
               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 (<i>user+foo@domain.tld</i>) is ignored.
 
-              In a lookup table,  specify  a  left-hand  side  of
-              <i>@domain.tld</i>  to  match  any  user  in the specified
-              domain   that   does   not    have    a    specific
+              In  a  lookup  table,  specify  a left-hand side of
+              <i>@domain.tld</i> to match  any  user  in  the  specified
+              domain    that    does    not   have   a   specific
               <i>user@domain.tld</i> 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.
 
 <b>Locking</b> <b>controls</b>
        <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>lock</b>
-              How  to  lock  UNIX-style mailboxes: one or more of
-              <b>flock</b>,  <b>fcntl</b>  or  <b>dotlock</b>.  The   <b>dotlock</b>   method
-              requires  that  the  recipient UID or GID has write
+              How to lock UNIX-style mailboxes: one  or  more  of
+              <b>flock</b>,   <b>fcntl</b>   or  <b>dotlock</b>.  The  <b>dotlock</b>  method
+              requires that the recipient UID or  GID  has  write
               access to the parent directory of the mailbox file.
 
-              This  setting  is ignored with <b>maildir</b> style deliv-
+              This setting is ignored with <b>maildir</b>  style  deliv-
               ery,  because  such  deliveries  are  safe  without
               explicit locks.
 
-              Use  the command <b>postconf</b> <b>-l</b> to find out what lock-
+              Use the command <b>postconf</b> <b>-l</b> to find out what  lock-
               ing methods are available on your system.
 
        <b>deliver</b><i>_</i><b>lock</b><i>_</i><b>attempts</b>
-              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.
 
        <b>deliver</b><i>_</i><b>lock</b><i>_</i><b>delay</b>
               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.
 
        <b>stale</b><i>_</i><b>lock</b><i>_</i><b>time</b>
-              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).
 
 <b>Resource</b> <b>controls</b>
        <b>virtual</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
               Limit the number of parallel deliveries to the same
               domain via the <b>virtual</b> delivery agent.  The default
               limit is taken from the <b>default</b><i>_</i><b>destination</b><i>_</i><b>concur-</b>
-              <b>rency</b><i>_</i><b>limit</b>  parameter.   The  limit is enforced by
+              <b>rency</b><i>_</i><b>limit</b> parameter.  The limit  is  enforced  by
               the Postfix queue manager.
 
        <b>virtual</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
               Limit the number of recipients per message delivery
-              via  the <b>virtual</b> delivery agent.  The default limit
-              is  taken  from   the   <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipi-</b>
-              <b>ent</b><i>_</i><b>limit</b>  parameter.  The limit is enforced by the
+              via the <b>virtual</b> delivery agent.  The default  limit
+              is   taken   from  the  <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipi-</b>
+              <b>ent</b><i>_</i><b>limit</b> parameter.  The limit is enforced by  the
               Postfix queue manager.
 
        <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>limit</b>
-              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.
 
 <b>HISTORY</b>
-       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  <b>Delivered-To:</b>  header  appears in the <b>qmail</b> system by
+       The <b>Delivered-To:</b> header appears in the  <b>qmail</b>  system  by
        Daniel Bernstein.
 
-       The <b>maildir</b> structure  appears  in  the  <b>qmail</b>  system  by
+       The  <b>maildir</b>  structure  appears  in  the  <b>qmail</b> system by
        Daniel Bernstein.
 
 <b>SEE</b> <b>ALSO</b>
@@ -266,7 +296,7 @@ VIRTUAL(8)                                             VIRTUAL(8)
        <a href="qmgr.8.html">qmgr(8)</a> queue manager
 
 <b>LICENSE</b>
-       The  Secure  Mailer  license must be distributed with this
+       The Secure Mailer license must be  distributed  with  this
        software.
 
 <b>AUTHOR(S)</b>
index ea13355170c9480825b67e348d88c522f7a23efd..04708e798ec2a96ebfd2d8b7d99ab22eb6e17622 100644 (file)
@@ -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
index ef995fb26701e3712fea96997245509df1c4487f..994c381b7b1afc9814579d2cd856e78979c6e381 100644 (file)
@@ -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
index 8026e6fa3598934f2dcfff4944150dac98159623..31f7765ca9966381a9093c02e8c1fb688be8b102 100644 (file)
 #include <rec_type.h>
 #include <cleanup_user.h>
 #include <qmgr_user.h>
-#include <tok822.h>
 #include <mail_params.h>
-#include <ext_prop.h>
-#include <mail_addr.h>
-#include <canon_addr.h>
 #include <verp_sender.h>
 
 /* 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;
 }
index e072e86b6c0927e506cc55175738e318961f16ce..097abcef5e1597ceab1d36d66a680b8a77e45f19 100644 (file)
@@ -50,7 +50,6 @@
 #include <msg.h>
 #include <vstring.h>
 #include <vstream.h>
-#include <argv.h>
 #include <mymalloc.h>
 #include <nvtable.h>
 
@@ -61,7 +60,6 @@
 #include <record.h>
 #include <rec_type.h>
 #include <mail_params.h>
-#include <ext_prop.h>
 #include <mail_proto.h>
 
 /* 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.
index 8154eeaf00afaf6030d5455b413b998cf1c223fa..31de9eae712b045b1bc0b120d32df404c044eb52 100644 (file)
   * 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;
 
  /*
index 550f87c3c6db6c1d214bfaeea26a2a49e93822ba..322747b8a65e0d4dcdbce790dd80b3f33b0bcfbc 100644 (file)
@@ -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
 
index 70aef24c95b38c00881b46228ce8df288e2beaf0..5bb910952a9d970c5a47d0a07d1afb1ae19930a1 100644 (file)
 #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
 #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
index d252cff69907cf3a5d56ac9aac5d0fd79d3eddd3..eb45a9c399bae6df0ca6ab06b8396dde1af6da4b 100644 (file)
@@ -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)
index a7ac88035f94f40f916c56d77a7335ed7c0844ca..b4b116ef6b283258316987e944543c0fab186fca 100644 (file)
@@ -87,7 +87,6 @@
 #include <vstream.h>
 #include <set_ugid.h>
 #include <safe_open.h>
-#include <stringops.h>
 
 /* 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);
index 141702406f07c98b1c661bf36191b89e9d4b4903..f8397cee0c21d790343940a091ab999be47c585f 100644 (file)
@@ -97,6 +97,7 @@
 #include <msg_syslog.h>
 #include <argv.h>
 #include <iostuff.h>
+#include <stringops.h>
 
 /* 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)
index 918ea599adef2e5ba45c69d3ad19fba87572df75..ab0ad3b64a9749905a64d0ac1a6d1d2742fef368 100644 (file)
@@ -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)
index ddd82369ea0d26498a00260d220f33606888b7ff..6b9ec626260932716e26f24c6a9d405fc905abb6 100644 (file)
@@ -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) {
index 91a864aee41ca2f74dd83e2c7673b3f656824213..af022047c99fb0c62cdf832d43120e814aa58218 100644 (file)
@@ -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);
index 334fe749a7acd9f1da030ef54d226234e4cf5d2c..a369b7e8603abae1d5cbeb6925777f733d03c77f 100644 (file)
@@ -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 *);
index fc14ab1750958828938b37c7544ed04e83022e15..f3ef3fe4f1cb4003c50f8c5641adf3335d1619d1 100644 (file)
@@ -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.
index 26573d334ea414cf8f9de8ea9a62f9fe4732cc82..302e2690354b3fad5d65b6f1ef672a8b692590f9 100644 (file)
@@ -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
index 599d53854e2681c2a27bfd613f4100f60a09d0b2..6475ae49b05f220bcbd470511cd37ed5f1f8de76 100644 (file)
@@ -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)
index f778e928d082bb2876666a22fce22c5e5c5ee2be..baecfb85b12e8574d768877ba39f4973454b55ea 100644 (file)
@@ -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;
 }
 
 /**********************************************************************
index 7968168e183e83368bb1319de8c2baf040b50d08..97289c04533e10fb5b88c0a4778e46e2bac3f9dc 100644 (file)
@@ -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;
 }
 
 /**********************************************************************
index 08f0c8243287aad64a2fc50122db1f9e16a77f1b..6427cd80fc62b01c07d4cc5186a7c2d35ad7db5c 100644 (file)
@@ -44,7 +44,7 @@
 #include "iostuff.h"
 
 /* Backwards compatibility */
-#ifdef FNDELAY
+#ifndef O_NONBLOCK
 #define PATTERN        FNDELAY
 #else
 #define PATTERN        O_NONBLOCK
index 90ee2c7fdac24159ada396eeab9758f3e6e30743..9366915c2a7a100706389cbec5ad4ae646b5e65f 100644 (file)
@@ -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;
index 8c47cfe0d8e00f33a4ba1ca9d4248de61281dd3f..7ab0308559461bbce19a1977cb85ab26ebc4831b 100644 (file)
@@ -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
index 87a8e691f6a27b0430b3409ae6d3c26f429607d3..afb61978be2478f4c1ec68e3c4621a9991f61ed3 100644 (file)
@@ -60,7 +60,7 @@
 #include <defer.h>
 #include <sent.h>
 #include <mail_params.h>
-#include <virtual8_maps.h>
+#include <mail_addr_find.h>
 
 #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),
index 3ae4bdc521022a668d9b0982ece28ecbaec2c7bd..3a22ecd20f4960ffde6730d647c5a003e7ce3e53 100644 (file)
@@ -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:
 /*
 /*     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
 /*     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
 /*     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
 #include <mail_params.h>
 #include <mail_conf.h>
 #include <mail_params.h>
-#include <virtual8_maps.h>
+#include <mail_addr_find.h>
 
 /* 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);