]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.0.8-20030416
authorWietse Venema <wietse@porcupine.org>
Wed, 16 Apr 2003 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:28:49 +0000 (06:28 +0000)
36 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/RELEASE_NOTES
postfix/conf/sample-misc.cf
postfix/html/cleanup.8.html
postfix/html/pickup.8.html
postfix/html/qmqpd.8.html
postfix/html/sendmail.1.html
postfix/html/smtpd.8.html
postfix/man/man1/sendmail.1
postfix/man/man8/cleanup.8
postfix/man/man8/pickup.8
postfix/man/man8/qmqpd.8
postfix/man/man8/smtpd.8
postfix/src/cleanup/Makefile.in
postfix/src/cleanup/cleanup.c
postfix/src/cleanup/cleanup.h
postfix/src/cleanup/cleanup_addr.c [new file with mode: 0644]
postfix/src/cleanup/cleanup_api.c
postfix/src/cleanup/cleanup_envelope.c
postfix/src/cleanup/cleanup_extracted.c
postfix/src/cleanup/cleanup_init.c
postfix/src/cleanup/cleanup_message.c
postfix/src/cleanup/cleanup_state.c
postfix/src/global/cleanup_strerror.c
postfix/src/global/cleanup_user.h
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/local/maildir.c
postfix/src/pickup/pickup.c
postfix/src/qmqpd/qmqpd.c
postfix/src/sendmail/sendmail.c
postfix/src/smtp/smtp_addr.c
postfix/src/smtp/smtp_proto.c
postfix/src/smtpd/smtpd.c
postfix/src/virtual/maildir.c

index cd42b54bb96e2aef0a8c7c463b812b9155ea4a07..e1dd7986dc37f49b2a412825c29f8413a1bc1651 100644 (file)
 -TSMTP_RESP
 -TSMTP_SESSION
 -TSMTP_STATE
+-TSM_STATE
 -TSOCKADDR_SIZE
 -TSPAWN_ATTR
 -TSTRING_LIST
index 6f05456013929ea107462f011120c7a92662b4f3..08dc03abfdabba406b37c2a82a0b64f23361cdc9 100644 (file)
@@ -7967,11 +7967,40 @@ Apologies for any names omitted.
        client sockets.  This puts less strain on local system
        resources.
 
-10030415
+20030415
 
        Cleanup: the file system clock drift detection code now
        runs only for incoming mail. File: global/mail_stream.c.
 
+20030416
+
+       Bugfix: missing output flush when message content did not
+       end in newline while converting 8-bit to 7-bit mail.  File:
+       smtp/smtp_proto.c.
+
+       Cleanup: auto-bcc recipients are now added in one place
+       (the cleanup server) instead of by individual front-end
+       servers (pickup, smtpd, qmqpd). This makes it easier to
+       add auto-bcc features that trigger on sender or recipient
+       addresses.
+
+       Cleanup: "sendmail -t" (recipients from headers) is now
+       implemented by the sendmail command instead of by the
+       cleanup server. This means that the extract_recipient_limit
+       configuration parameter is no longer needed.  Files:
+       sendmail/sendmail.c, cleanup/cleanup_message.c,
+       cleanup/cleanup_extracted.c.
+
+       Compatibility: "sendmail -t" (recipients from headers) now
+       accepts command-line recipients instead of complaining.
+       The extracted header recipients are added to the command-line
+       recipients.
+
+       Feature: sender/recipient_bcc_maps. These are indexed by
+       sender/recipient address and are examined when mail enters
+       from outside of Postfix. Files: cleanup/cleanup_addr.c.
+       cleanup/cleanup_envelope.c cleanup/cleanup_extracted.c.
+
 Open problems:
 
        Low: smtp-source may block when sending large test messages.
index 55fab1989fae4c20a1fccc630e87c4d7347bd3b2..2ea6bc9f4637fd8e7aba224e6ab62d8b39f33617 100644 (file)
@@ -22,7 +22,20 @@ snapshot release).  Patches change the patchlevel and the release
 date. Snapshots change only the release date, unless they include
 the same bugfixes as a patch release.
 
-Incompatible changes with Postfix snapshot 2.0.8-20040414
+Incompatible changes with Postfix snapshot 2.0.8-2004XXXX
+=========================================================
+
+"sendmail -t" no longer complains when recipients are given on the
+command line. Instead, it now adds recipients from headers to the
+command-line recipients.
+
+Major changes with Postfix snapshot 2.0.8-2004XXXX
+==================================================
+
+sender_bcc_maps and recipient_bcc_maps, after a reorganization
+of how auto-bcc recipients are added.
+
+Incompatible changes with Postfix snapshot 2.0.8-20040415
 =========================================================
 
 Too many people mess up their net/mask patterns, causing open
@@ -31,7 +44,7 @@ net/mask pattern with a non-zero host portion (for example,
 168.100.189.2/28), and suggest to specify the proper net/mask
 pattern instead (for example, 168.100.189.0/28).
 
-Major changes with Postfix snapshot 2.0.8-20040414
+Major changes with Postfix snapshot 2.0.8-20040415
 ==================================================
 
 PostgreSQL table lookups. Specify "pgsql:/file/name" where "/file/name"
index 0dca7c8e912cad15428090f2d251e448ecd9b676..1ec322d2001a01b886ddd28b11a4d87f784d535c 100644 (file)
@@ -406,6 +406,19 @@ recipient_delimiter =
 #propagate_unmatched_extensions = canonical, virtual, alias, forward, include
 #propagate_unmatched_extensions = canonical, virtual
 
+# The recipient_bcc_maps parameter specifies optional lookup tables
+# with automatic BCC recipients per recipient address.  Each table
+# entry should contain exactly one recipient address. The BCC address
+# is added when mail enters from outside of Postfix.
+# 
+# By default, this feature is disabled. 
+#
+# Specify the types and names of databases to use.  After change,
+# run "postmap /etc/postfix/relocated", then "postfix reload".
+#
+#recipient_bcc_maps = hash:/etc/postfix/recipient_bcc
+recipient_bcc_maps =
+
 # The relayhost parameter specifies the default host to send mail to
 # when no entry is matched in the optional transport(5) table. When
 # no relayhost is given, mail is routed directly to the destination.
@@ -453,6 +466,19 @@ relocated_maps =
 #
 resolve_dequoted_address = no
 
+# The sender_bcc_maps parameter specifies optional lookup tables with
+# automatic BCC recipients per sender address.  Each table entry
+# should contain exactly one recipient address. The BCC address is
+# added when mail enters from outside of Postfix.
+# 
+# By default, this feature is disabled. 
+#
+# Specify the types and names of databases to use.  After change,
+# run "postmap /etc/postfix/relocated", then "postfix reload".
+#
+#sender_bcc_maps = hash:/etc/postfix/sender_bcc
+sender_bcc_maps =
+
 # The syslog_facility parameter controls where Postfix logging is
 # sent by the syslog daemon. Specify a logging facility as defined
 # in syslog.conf(5). The default logging facility is "mail".
index 287181429191ae707f1d4b64846d1dc9b0f87d1a..d6a5eecda3897fe87627a9842640ad78dd80308a 100644 (file)
@@ -143,6 +143,16 @@ CLEANUP(8)                                             CLEANUP(8)
               Address to send a copy of each message that  enters
               the system.
 
+       <b>sender</b><i>_</i><b>bcc</b><i>_</i><b>maps</b>
+              Automatic  BCC  recipient  lookup table, indexed by
+              sender address.  The BCC address is added when  the
+              message enters the system.
+
+       <b>recipient</b><i>_</i><b>bcc</b><i>_</i><b>maps</b>
+              Automatic  BCC  recipient  lookup table, indexed by
+              recipient address.  The BCC address is  added  when
+              the message enters the system.
+
        <b>hopcount</b><i>_</i><b>limit</b>
               Limit the number of <b>Received:</b> message headers.
 
@@ -204,17 +214,13 @@ CLEANUP(8)                                             CLEANUP(8)
               when  the  message arrival rate exceeds the message
               delivery rate.
 
-       <b>extract</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
-              Limit the amount of recipients extracted from  mes-
-              sage headers.
-
        <b>virtual</b><i>_</i><b>alias</b><i>_</i><b>expansion</b><i>_</i><b>limit</b>
-              Limit  the  number of actual recipients produced by
-              virtual alias expansion from each original  recipi-
+              Limit the number of actual recipients  produced  by
+              virtual  alias expansion from each original recipi-
               ent.
 
        <b>virtual</b><i>_</i><b>alias</b><i>_</i><b>recursion</b><i>_</i><b>limit</b>
-              Limit  the  recursion depth of virtual alias expan-
+              Limit the recursion depth of virtual  alias  expan-
               sion.
 
 <b>SEE</b> <b>ALSO</b>
@@ -229,7 +235,7 @@ CLEANUP(8)                                             CLEANUP(8)
        /etc/postfix/virtual*, virtual mapping table
 
 <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 ba6056e8e9ee01458d6a32167edd7f719398834c..d30fa65447d91f7b8acf352d621419273e5d42ad 100644 (file)
@@ -52,10 +52,6 @@ PICKUP(8)                                               PICKUP(8)
               transport table.
 
 <b>Miscellaneous</b>
-       <b>always</b><i>_</i><b>bcc</b>
-              Address  to send a copy of each message that enters
-              the system.
-
        <b>queue</b><i>_</i><b>directory</b>
               Top-level directory of the Postfix queue.
 
@@ -66,7 +62,7 @@ PICKUP(8)                                               PICKUP(8)
        syslogd(8) system logging
 
 <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 9c99eb526e3b09ffbb2e8b801de76bb522ce6f9d..19d36f7ff70861bf70a9cf3fd8f0e1fe8b85453e 100644 (file)
@@ -44,19 +44,15 @@ QMQPD(8)                                                 QMQPD(8)
        command after a configuration change.
 
 <b>Miscellaneous</b>
-       <b>always</b><i>_</i><b>bcc</b>
-              Address to send a copy of each message that  enters
-              the system.
-
        <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
-              Increment  in  verbose  logging level when a remote
+              Increment in verbose logging level  when  a  remote
               host  matches  a  pattern  in  the  <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
               parameter.
 
        <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
-              List  of  domain or network patterns. When a remote
-              host matches a pattern, increase the  verbose  log-
-              ging   level   by   the  amount  specified  in  the
+              List of domain or network patterns. When  a  remote
+              host  matches  a pattern, increase the verbose log-
+              ging  level  by  the  amount   specified   in   the
               <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
 
        <b>hopcount</b><i>_</i><b>limit</b>
@@ -67,32 +63,32 @@ QMQPD(8)                                                 QMQPD(8)
               what clients are allowed to use the service.
 
        <b>qmqpd</b><i>_</i><b>timeout</b>
-              Limit  the  time  to  send a server response and to
+              Limit the time to send a  server  response  and  to
               receive a client request.
 
        <b>soft</b><i>_</i><b>bounce</b>
-              Change hard (D)  reject  responses  into  soft  (Z)
-              reject  responses.   This can be useful for testing
+              Change  hard  (D)  reject  responses  into soft (Z)
+              reject responses.  This can be useful  for  testing
               purposes.
 
 <b>Content</b> <b>inspection</b> <b>controls</b>
        <b>content</b><i>_</i><b>filter</b>
-              The name of a mail delivery transport that  filters
+              The  name of a mail delivery transport that filters
               mail and that either bounces mail or re-injects the
-              result back into Postfix.  This parameter uses  the
-              same  syntax  as  the  right-hand side of a Postfix
+              result  back into Postfix.  This parameter uses the
+              same syntax as the right-hand  side  of  a  Postfix
               transport table.
 
 <b>Resource</b> <b>controls</b>
        <b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
-              Limit the amount of memory in bytes  used  for  the
-              handling  of partial input lines, and the length of
-              sender and recipient addresses  that  are  received
+              Limit  the  amount  of memory in bytes used for the
+              handling of partial input lines, and the length  of
+              sender  and  recipient  addresses that are received
               from client.
 
        <b>message</b><i>_</i><b>size</b><i>_</i><b>limit</b>
               Limit the total size in bytes of a message, includ-
-              ing  on-disk  storage  for  sender  and   recipient
+              ing   on-disk  storage  for  sender  and  recipient
               address information.
 
 <b>Tarpitting</b>
@@ -107,7 +103,7 @@ QMQPD(8)                                                 QMQPD(8)
        syslogd(8) system logging
 
 <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 35a140fa8bbb88f4232ce92f87d5f2fde00ca1d9..a5804b223a346b2a3290e6e5564ca1ec6e467dda 100644 (file)
@@ -209,9 +209,9 @@ SENDMAIL(1)                                           SENDMAIL(1)
               This  command  is  not  implemented. Use the slower
               <b>sendmail</b> <b>-q</b> command instead.
 
-       <b>-t</b>     Extract  recipients  from  message  headers.   This
-              requires  that  no  recipients  be specified on the
-              command line.
+       <b>-t</b>     Extract recipients from message headers. These  are
+              added  to  any  recipients specified on the command
+              line.
 
        <b>-v</b>     Send an email report of all delivery attempts (mail
               delivery  always  happens  in the background). When
index c481f91551f609ed48817fc8a9a66c933c575a49..4aca9e81b79b890bb72f4d2ca008605ed0554608 100644 (file)
@@ -115,32 +115,28 @@ SMTPD(8)                                                 SMTPD(8)
               restriction.
 
 <b>Miscellaneous</b>
-       <b>always</b><i>_</i><b>bcc</b>
-              Address  to send a copy of each message that enters
-              the system.
-
        <b>authorized</b><i>_</i><b>verp</b><i>_</i><b>clients</b>
               Hostnames, domain names and/or addresses of clients
               that are authorized to use the XVERP extension.
 
        <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
-              Increment  in  verbose  logging level when a remote
+              Increment in verbose logging level  when  a  remote
               host  matches  a  pattern  in  the  <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
               parameter.
 
        <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
-              List  of  domain or network patterns. When a remote
-              host matches a pattern, increase the  verbose  log-
-              ging   level   by   the  amount  specified  in  the
+              List of domain or network patterns. When  a  remote
+              host  matches  a pattern, increase the verbose log-
+              ging  level  by  the  amount   specified   in   the
               <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
 
        <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b>
               The default VERP delimiter characters that are used
-              when   the   XVERP  command  is  specified  without
+              when  the  XVERP  command  is   specified   without
               explicit delimiters.
 
        <b>error</b><i>_</i><b>notice</b><i>_</i><b>recipient</b>
-              Recipient   of    protocol/policy/resource/software
+              Recipient    of   protocol/policy/resource/software
               error notices.
 
        <b>hopcount</b><i>_</i><b>limit</b>
@@ -149,18 +145,18 @@ SMTPD(8)                                                 SMTPD(8)
        <b>notify</b><i>_</i><b>classes</b>
               List of error classes. Of special interest are:
 
-              <b>policy</b> When  a  client  violates any policy, mail a
+              <b>policy</b> When a client violates any  policy,  mail  a
                      transcript of the entire SMTP session to the
                      postmaster.
 
               <b>protocol</b>
-                     When  a client violates the SMTP protocol or
+                     When a client violates the SMTP protocol  or
                      issues  an  unimplemented  command,  mail  a
                      transcript of the entire SMTP session to the
                      postmaster.
 
        <b>smtpd</b><i>_</i><b>banner</b>
-              Text that follows the <b>220</b> status code in  the  SMTP
+              Text  that  follows the <b>220</b> status code in the SMTP
               greeting banner.
 
        <b>smtpd</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>
@@ -168,57 +164,57 @@ SMTPD(8)                                                 SMTPD(8)
               expansion of rbl template responses and other text.
 
        <b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
-              Restrict  the  number  of  recipients that the SMTP
+              Restrict the number of  recipients  that  the  SMTP
               server accepts per message delivery.
 
        <b>smtpd</b><i>_</i><b>timeout</b>
-              Limit the time to send a  server  response  and  to
+              Limit  the  time  to  send a server response and to
               receive a client request.
 
        <b>soft</b><i>_</i><b>bounce</b>
-              Change  hard (5xx) reject responses into soft (4xx)
-              reject responses.  This can be useful  for  testing
+              Change hard (5xx) reject responses into soft  (4xx)
+              reject  responses.   This can be useful for testing
               purposes.
 
        <b>verp</b><i>_</i><b>delimiter</b><i>_</i><b>filter</b>
-              The  characters that Postfix accepts as VERP delim-
+              The characters that Postfix accepts as VERP  delim-
               iter characters.
 
 <b>Known</b> <b>versus</b> <b>unknown</b> <b>recipients</b>
        <b>show</b><i>_</i><b>user</b><i>_</i><b>unknown</b><i>_</i><b>table</b><i>_</i><b>name</b>
-              Whether or not to reveal  the  table  name  in  the
-              "User  unknown"  responses.  The extra detail makes
-              trouble shooting easier but also  reveals  informa-
+              Whether  or  not  to  reveal  the table name in the
+              "User unknown" responses. The  extra  detail  makes
+              trouble  shooting  easier but also reveals informa-
               tion that is nobody elses business.
 
        <b>unknown</b><i>_</i><b>local</b><i>_</i><b>recipient</b><i>_</i><b>reject</b><i>_</i><b>code</b>
               The response code when a client specifies a recipi-
-              ent  whose   domain   matches   <b>$mydestination</b>   or
+              ent   whose   domain   matches   <b>$mydestination</b>  or
               <b>$inet</b><i>_</i><b>interfaces</b>,  while  <b>$local</b><i>_</i><b>recipient</b><i>_</i><b>maps</b>  is
-              non-empty and does not list the  recipient  address
+              non-empty  and  does not list the recipient address
               or address local-part.
 
        <b>unknown</b><i>_</i><b>relay</b><i>_</i><b>recipient</b><i>_</i><b>reject</b><i>_</i><b>code</b>
               The response code when a client specifies a recipi-
               ent  whose  domain  matches  <b>$relay</b><i>_</i><b>domains</b>,  while
-              <b>$relay</b><i>_</i><b>recipient</b><i>_</i><b>maps</b>  is  non-empty  and  does not
+              <b>$relay</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> is  non-empty  and  does  not
               list the recipient address.
 
        <b>unknown</b><i>_</i><b>virtual</b><i>_</i><b>alias</b><i>_</i><b>reject</b><i>_</i><b>code</b>
               The response code when a client specifies a recipi-
-              ent  whose  domain  matches <b>$virtual</b><i>_</i><b>alias</b><i>_</i><b>domains</b>,
-              while  the  recipient  is  not  listed   in   <b>$vir-</b>
+              ent whose  domain  matches  <b>$virtual</b><i>_</i><b>alias</b><i>_</i><b>domains</b>,
+              while   the   recipient  is  not  listed  in  <b>$vir-</b>
               <b>tual</b><i>_</i><b>alias</b><i>_</i><b>maps</b>.
 
        <b>unknown</b><i>_</i><b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>reject</b><i>_</i><b>code</b>
               The response code when a client specifies a recipi-
-              ent whose domain matches  <b>$virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>,
+              ent  whose domain matches <b>$virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>,
               while the recipient is not listed in <b>$virtual</b><i>_</i><b>mail-</b>
               <b>box</b><i>_</i><b>maps</b>.
 
 <b>Resource</b> <b>controls</b>
        <b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
-              Limit the amount of memory in bytes  used  for  the
+              Limit  the  amount  of memory in bytes used for the
               handling of partial input lines.
 
        <b>message</b><i>_</i><b>size</b><i>_</i><b>limit</b>
@@ -226,8 +222,8 @@ SMTPD(8)                                                 SMTPD(8)
               ing on-disk storage for envelope information.
 
        <b>queue</b><i>_</i><b>minfree</b>
-              Minimal amount of free space in bytes in the  queue
-              file  system for the SMTP server to accept any mail
+              Minimal  amount of free space in bytes in the queue
+              file system for the SMTP server to accept any  mail
               at all.
 
        <b>smtpd</b><i>_</i><b>history</b><i>_</i><b>flush</b><i>_</i><b>threshold</b>
@@ -242,23 +238,23 @@ SMTPD(8)                                                 SMTPD(8)
 
        <b>smtpd</b><i>_</i><b>soft</b><i>_</i><b>error</b><i>_</i><b>limit</b>
               When an SMTP client has made this number of errors,
-              wait <i>error_count</i> seconds before responding  to  any
+              wait  <i>error_count</i>  seconds before responding to any
               client request.
 
        <b>smtpd</b><i>_</i><b>hard</b><i>_</i><b>error</b><i>_</i><b>limit</b>
-              Disconnect  after  a client has made this number of
+              Disconnect after a client has made this  number  of
               errors.
 
        <b>smtpd</b><i>_</i><b>junk</b><i>_</i><b>command</b><i>_</i><b>limit</b>
               Limit the number of times a client can issue a junk
-              command  such  as  NOOP,  VRFY, ETRN or RSET in one
-              SMTP session before it  is  penalized  with  tarpit
+              command such as NOOP, VRFY, ETRN  or  RSET  in  one
+              SMTP  session  before  it  is penalized with tarpit
               delays.
 
 <b>UCE</b> <b>control</b> <b>restrictions</b>
        <b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b>
-              List  of  Postfix features that use <i>domain.tld</i> pat-
-              terns  to  match  <i>sub.domain.tld</i>  (as  opposed   to
+              List of Postfix features that use  <i>domain.tld</i>  pat-
+              terns   to  match  <i>sub.domain.tld</i>  (as  opposed  to
               requiring <i>.domain.tld</i> patterns).
 
        <b>smtpd</b><i>_</i><b>client</b><i>_</i><b>restrictions</b>
@@ -266,19 +262,19 @@ SMTPD(8)                                                 SMTPD(8)
               tem.
 
        <b>smtpd</b><i>_</i><b>helo</b><i>_</i><b>required</b>
-              Require that clients introduce  themselves  at  the
+              Require  that  clients  introduce themselves at the
               beginning of an SMTP session.
 
        <b>smtpd</b><i>_</i><b>helo</b><i>_</i><b>restrictions</b>
-              Restrict  what client hostnames are allowed in <b>HELO</b>
+              Restrict what client hostnames are allowed in  <b>HELO</b>
               and <b>EHLO</b> commands.
 
        <b>smtpd</b><i>_</i><b>sender</b><i>_</i><b>restrictions</b>
-              Restrict what sender addresses are allowed in  <b>MAIL</b>
+              Restrict  what sender addresses are allowed in <b>MAIL</b>
               <b>FROM</b> commands.
 
        <b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>restrictions</b>
-              Restrict  what  recipient  addresses are allowed in
+              Restrict what recipient addresses  are  allowed  in
               <b>RCPT</b> <b>TO</b> commands.
 
        <b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
@@ -286,77 +282,77 @@ SMTPD(8)                                                 SMTPD(8)
               mands, and what clients may issue <b>ETRN</b> commands.
 
        <b>smtpd</b><i>_</i><b>data</b><i>_</i><b>restrictions</b>
-              Restrictions  on  the  <b>DATA</b> command. Currently, the
-              only  restriction  that   makes   sense   here   is
+              Restrictions on the <b>DATA</b>  command.  Currently,  the
+              only   restriction   that   makes   sense  here  is
               <b>reject</b><i>_</i><b>unauth</b><i>_</i><b>pipelining</b>.
 
        <b>allow</b><i>_</i><b>untrusted</b><i>_</i><b>routing</b>
-              Allow  untrusted  clients to specify addresses with
-              sender-specified routing.  Enabling this  opens  up
-              nasty  relay  loopholes involving trusted backup MX
+              Allow untrusted clients to specify  addresses  with
+              sender-specified  routing.   Enabling this opens up
+              nasty relay loopholes involving trusted  backup  MX
               hosts.
 
        <b>smtpd</b><i>_</i><b>restriction</b><i>_</i><b>classes</b>
-              Declares the name of zero or more  parameters  that
-              contain  a  list  of UCE restrictions. The names of
-              these parameters can then be used  instead  of  the
+              Declares  the  name of zero or more parameters that
+              contain a list of UCE restrictions.  The  names  of
+              these  parameters  can  then be used instead of the
               restriction lists that they represent.
 
        <b>smtpd</b><i>_</i><b>null</b><i>_</i><b>access</b><i>_</i><b>lookup</b><i>_</i><b>key</b>
-              The  lookup  key  to be used in SMTPD access tables
-              instead of the null sender address. A  null  sender
+              The lookup key to be used in  SMTPD  access  tables
+              instead  of  the null sender address. A null sender
               address cannot be looked up.
 
        <b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b> (deprecated)
-              List  of  DNS domains that publish the addresses of
+              List of DNS domains that publish the  addresses  of
               blacklisted hosts. This is used with the deprecated
               <b>reject</b><i>_</i><b>maps</b><i>_</i><b>rbl</b> restriction.
 
        <b>permit</b><i>_</i><b>mx</b><i>_</i><b>backup</b><i>_</i><b>networks</b>
-              Only  domains  whose  primary  MX  hosts  match the
-              listed  networks  are   eligible   for   the   <b>per-</b>
+              Only domains  whose  primary  MX  hosts  match  the
+              listed   networks   are   eligible   for  the  <b>per-</b>
               <b>mit</b><i>_</i><b>mx</b><i>_</i><b>backup</b> feature.
 
        <b>relay</b><i>_</i><b>domains</b>
-              Restrict  what  domains this mail system will relay
-              mail to. The domains are  routed  to  the  delivery
+              Restrict what domains this mail system  will  relay
+              mail  to.  The  domains  are routed to the delivery
               agent specified with the <b>relay</b><i>_</i><b>transport</b> setting.
 
 <b>UCE</b> <b>control</b> <b>responses</b>
        <b>access</b><i>_</i><b>map</b><i>_</i><b>reject</b><i>_</i><b>code</b>
-              Response  code  when  a  client  violates an access
+              Response code when  a  client  violates  an  access
               database restriction.
 
        <b>default</b><i>_</i><b>rbl</b><i>_</i><b>reply</b>
               Default template reply when a request is RBL black-
-              listed.   This template is used by the <b>reject</b><i>_</i><b>rbl</b><i>_</i><b>*</b>
-              and   <b>reject</b><i>_</i><b>rhsbl</b><i>_</i><b>*</b>   restrictions.   See    also:
+              listed.  This template is used by the  <b>reject</b><i>_</i><b>rbl</b><i>_</i><b>*</b>
+              and    <b>reject</b><i>_</i><b>rhsbl</b><i>_</i><b>*</b>   restrictions.   See   also:
               <b>rbl</b><i>_</i><b>reply</b><i>_</i><b>maps</b> and <b>smtpd</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>.
 
        <b>defer</b><i>_</i><b>code</b>
-              Response  code when a client request is rejected by
+              Response code when a client request is rejected  by
               the <b>defer</b> restriction.
 
        <b>invalid</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
-              Response  code   when   a   client   violates   the
+              Response   code   when   a   client   violates  the
               <b>reject</b><i>_</i><b>invalid</b><i>_</i><b>hostname</b> restriction.
 
        <b>maps</b><i>_</i><b>rbl</b><i>_</i><b>reject</b><i>_</i><b>code</b>
               Response code when a request is RBL blacklisted.
 
        <b>multi</b><i>_</i><b>recipient</b><i>_</i><b>bounce</b><i>_</i><b>reject</b><i>_</i><b>code</b>
-              Response  code  when  a  multi-recipient  bounce is
+              Response code  when  a  multi-recipient  bounce  is
               blocked.
 
        <b>rbl</b><i>_</i><b>reply</b><i>_</i><b>maps</b>
-              Table with template responses for  RBL  blacklisted
-              requests,  indexed  by  RBL domain name. These tem-
+              Table  with  template responses for RBL blacklisted
+              requests, indexed by RBL domain  name.  These  tem-
               plates   are   used   by   the   <b>reject</b><i>_</i><b>rbl</b><i>_</i><b>*</b>   and
-              <b>reject</b><i>_</i><b>rhsbl</b><i>_</i><b>*</b>      restrictions.     See     also:
+              <b>reject</b><i>_</i><b>rhsbl</b><i>_</i><b>*</b>     restrictions.     See      also:
               <b>default</b><i>_</i><b>rbl</b><i>_</i><b>reply</b> and <b>smtpd</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>.
 
        <b>reject</b><i>_</i><b>code</b>
-              Response code when  the  client  matches  a  <b>reject</b>
+              Response  code  when  the  client  matches a <b>reject</b>
               restriction.
 
        <b>relay</b><i>_</i><b>domains</b><i>_</i><b>reject</b><i>_</i><b>code</b>
@@ -364,7 +360,7 @@ SMTPD(8)                                                 SMTPD(8)
               mail relay policy.
 
        <b>unknown</b><i>_</i><b>address</b><i>_</i><b>reject</b><i>_</i><b>code</b>
-              Response  code   when   a   client   violates   the
+              Response   code   when   a   client   violates  the
               <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>address</b> restriction.
 
        <b>unknown</b><i>_</i><b>client</b><i>_</i><b>reject</b><i>_</i><b>code</b>
@@ -373,15 +369,15 @@ SMTPD(8)                                                 SMTPD(8)
               tion.
 
        <b>unknown</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
-              Response   code   when   a   client   violates  the
+              Response  code   when   a   client   violates   the
               <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>hostname</b> restriction.
 
        <b>unverified</b><i>_</i><b>sender</b><i>_</i><b>reject</b><i>_</i><b>code</b>
-              Response code when a sender address is known to  be
+              Response  code when a sender address is known to be
               undeliverable.
 
        <b>unverified</b><i>_</i><b>recipient</b><i>_</i><b>reject</b><i>_</i><b>code</b>
-              Response  code when a recipient address is known to
+              Response code when a recipient address is known  to
               be undeliverable.
 
 <b>SEE</b> <b>ALSO</b>
@@ -391,7 +387,7 @@ SMTPD(8)                                                 SMTPD(8)
        syslogd(8) system logging
 
 <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 6e7f76e6b79ae76d018cb8a592a63678b19d0b00..e7453eb8d26541716de2ff4ded93e428ea228daf 100644 (file)
@@ -175,8 +175,8 @@ service.
 This command is not implemented. Use the slower \fBsendmail -q\fR
 command instead.
 .IP \fB-t\fR
-Extract recipients from message headers. This requires that no
-recipients be specified on the command line.
+Extract recipients from message headers. These are added to any
+recipients specified on the command line.
 .IP \fB-v\fR
 Send an email report of all delivery attempts (mail delivery
 always happens in the background). When multiple \fB-v\fR
index fe4360d18780fec41c7118830a91c53b03efd773..fdadfa4a80a36291a540917f849b0daca2a33856 100644 (file)
@@ -130,6 +130,12 @@ from poorly written software.
 .fi
 .IP \fBalways_bcc\fR
 Address to send a copy of each message that enters the system.
+.IP \fBsender_bcc_maps\fR
+Automatic BCC recipient lookup table, indexed by sender address.
+The BCC address is added when the message enters the system.
+.IP \fBrecipient_bcc_maps\fR
+Automatic BCC recipient lookup table, indexed by recipient address.
+The BCC address is added when the message enters the system.
 .IP \fBhopcount_limit\fR
 Limit the number of \fBReceived:\fR message headers.
 .IP \fBundisclosed_recipients_header\fR
@@ -172,8 +178,6 @@ Limits the amount of memory in bytes used to process a message header.
 .IP \fBin_flow_delay\fR
 Amount of time to pause before accepting a message, when the
 message arrival rate exceeds the message delivery rate.
-.IP \fBextract_recipient_limit\fR
-Limit the amount of recipients extracted from message headers.
 .IP \fBvirtual_alias_expansion_limit\fR
 Limit the number of actual recipients produced by virtual alias
 expansion from each original recipient.
index 199e030558bae29e35ab951d740df613af57785d..92c98ae40bca90575e558d786ba37ae1b5a63dd4 100644 (file)
@@ -64,8 +64,6 @@ a Postfix transport table.
 .SH Miscellaneous
 .ad
 .fi
-.IP \fBalways_bcc\fR
-Address to send a copy of each message that enters the system.
 .IP \fBqueue_directory\fR
 Top-level directory of the Postfix queue.
 .SH SEE ALSO
index b608249fa84a23c47330f23302c57d5f3a5a0aba..e6308c794a64906214cb5fbf142c1cfdde62e996 100644 (file)
@@ -56,8 +56,6 @@ a configuration change.
 .SH Miscellaneous
 .ad
 .fi
-.IP \fBalways_bcc\fR
-Address to send a copy of each message that enters the system.
 .IP \fBdebug_peer_level\fR
 Increment in verbose logging level when a remote host matches a
 pattern in the \fBdebug_peer_list\fR parameter.
index 1b7d59fa3eb6988bfc78858a4b2c8e0f7c24e8f0..8646cd8bb203a15dcdc237119789b7136e5586eb 100644 (file)
@@ -114,8 +114,6 @@ anti-spoofing restriction.
 .SH Miscellaneous
 .ad
 .fi
-.IP \fBalways_bcc\fR
-Address to send a copy of each message that enters the system.
 .IP \fBauthorized_verp_clients\fR
 Hostnames, domain names and/or addresses of clients that are
 authorized to use the XVERP extension.
index 3a5110c1dfb4077d08ca4b196df131680ed2c146..d3d8832dbf79d989c57742237ac151b7b40a2872 100644 (file)
@@ -2,11 +2,13 @@ SHELL = /bin/sh
 SRCS   = cleanup.c cleanup_out.c cleanup_envelope.c cleanup_message.c \
        cleanup_extracted.c cleanup_state.c cleanup_rewrite.c \
        cleanup_map11.c cleanup_map1n.c cleanup_masquerade.c \
-       cleanup_out_recipient.c cleanup_init.c cleanup_api.c
+       cleanup_out_recipient.c cleanup_init.c cleanup_api.c \
+       cleanup_addr.c
 OBJS   = cleanup.o cleanup_out.o cleanup_envelope.o cleanup_message.o \
        cleanup_extracted.o cleanup_state.o cleanup_rewrite.o \
        cleanup_map11.o cleanup_map1n.o cleanup_masquerade.o \
-       cleanup_out_recipient.o cleanup_init.o cleanup_api.o
+       cleanup_out_recipient.o cleanup_init.o cleanup_api.o \
+       cleanup_addr.o
 HDRS   =
 TESTSRC        = 
 WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
@@ -113,6 +115,36 @@ cleanup.o: ../../include/header_opts.h
 cleanup.o: ../../include/string_list.h
 cleanup.o: ../../include/match_list.h
 cleanup.o: ../../include/match_ops.h
+cleanup_addr.o: cleanup_addr.c
+cleanup_addr.o: ../../include/sys_defs.h
+cleanup_addr.o: ../../include/msg.h
+cleanup_addr.o: ../../include/vstring.h
+cleanup_addr.o: ../../include/vbuf.h
+cleanup_addr.o: ../../include/vstream.h
+cleanup_addr.o: ../../include/mymalloc.h
+cleanup_addr.o: ../../include/stringops.h
+cleanup_addr.o: ../../include/rec_type.h
+cleanup_addr.o: ../../include/cleanup_user.h
+cleanup_addr.o: ../../include/mail_params.h
+cleanup_addr.o: ../../include/ext_prop.h
+cleanup_addr.o: ../../include/mail_addr.h
+cleanup_addr.o: ../../include/canon_addr.h
+cleanup_addr.o: cleanup.h
+cleanup_addr.o: ../../include/argv.h
+cleanup_addr.o: ../../include/nvtable.h
+cleanup_addr.o: ../../include/htable.h
+cleanup_addr.o: ../../include/maps.h
+cleanup_addr.o: ../../include/dict.h
+cleanup_addr.o: ../../include/tok822.h
+cleanup_addr.o: ../../include/resolve_clnt.h
+cleanup_addr.o: ../../include/been_here.h
+cleanup_addr.o: ../../include/mail_stream.h
+cleanup_addr.o: ../../include/mail_conf.h
+cleanup_addr.o: ../../include/mime_state.h
+cleanup_addr.o: ../../include/header_opts.h
+cleanup_addr.o: ../../include/string_list.h
+cleanup_addr.o: ../../include/match_list.h
+cleanup_addr.o: ../../include/match_ops.h
 cleanup_api.o: cleanup_api.c
 cleanup_api.o: ../../include/sys_defs.h
 cleanup_api.o: ../../include/msg.h
@@ -273,6 +305,7 @@ cleanup_map1n.o: ../../include/vstring.h
 cleanup_map1n.o: ../../include/vbuf.h
 cleanup_map1n.o: ../../include/dict.h
 cleanup_map1n.o: ../../include/vstream.h
+cleanup_map1n.o: ../../include/mail_params.h
 cleanup_map1n.o: ../../include/mail_addr_map.h
 cleanup_map1n.o: ../../include/maps.h
 cleanup_map1n.o: ../../include/cleanup_user.h
@@ -440,7 +473,6 @@ cleanup_state.o: ../../include/sys_defs.h
 cleanup_state.o: ../../include/mymalloc.h
 cleanup_state.o: ../../include/vstring.h
 cleanup_state.o: ../../include/vbuf.h
-cleanup_state.o: ../../include/argv.h
 cleanup_state.o: ../../include/htable.h
 cleanup_state.o: ../../include/been_here.h
 cleanup_state.o: ../../include/mail_params.h
@@ -448,6 +480,7 @@ cleanup_state.o: ../../include/mime_state.h
 cleanup_state.o: ../../include/header_opts.h
 cleanup_state.o: cleanup.h
 cleanup_state.o: ../../include/vstream.h
+cleanup_state.o: ../../include/argv.h
 cleanup_state.o: ../../include/nvtable.h
 cleanup_state.o: ../../include/maps.h
 cleanup_state.o: ../../include/dict.h
index 9ec0896fe838de5118e688627e3c5d08a37fe063..2b19a902e566764801e583aac28158d4a4571b14 100644 (file)
 /* .fi
 /* .IP \fBalways_bcc\fR
 /*     Address to send a copy of each message that enters the system.
+/* .IP \fBsender_bcc_maps\fR
+/*     Automatic BCC recipient lookup table, indexed by sender address.
+/*     The BCC address is added when the message enters the system.
+/* .IP \fBrecipient_bcc_maps\fR
+/*     Automatic BCC recipient lookup table, indexed by recipient address.
+/*     The BCC address is added when the message enters the system.
 /* .IP \fBhopcount_limit\fR
 /*     Limit the number of \fBReceived:\fR message headers.
 /* .IP \fBundisclosed_recipients_header\fR
 /* .IP \fBin_flow_delay\fR
 /*     Amount of time to pause before accepting a message, when the
 /*     message arrival rate exceeds the message delivery rate.
-/* .IP \fBextract_recipient_limit\fR
-/*     Limit the amount of recipients extracted from message headers.
 /* .IP \fBvirtual_alias_expansion_limit\fR
 /*     Limit the number of actual recipients produced by virtual alias
 /*     expansion from each original recipient.
index 8c6ee53456320554c957b713c5f3be15ddfd69fe..c1a1c2fab83e2b51af6c190b9728f70e18a99ab1 100644 (file)
@@ -52,12 +52,10 @@ typedef struct CLEANUP_STATE {
     int     err_mask;                  /* allowed badness */
     int     headers_seen;              /* which headers were seen */
     int     hop_count;                 /* count of received: headers */
-    ARGV   *recipients;                        /* recipients from regular headers */
-    ARGV   *resent_recip;              /* recipients from resent headers */
     char   *resent;                    /* any resent- header seen */
     BH_TABLE *dups;                    /* recipient dup filter */
     long    warn_time;                 /* cleanup_envelope.c */
-    void    (*action) (struct CLEANUP_STATE *, int, char *, int);
+    void    (*action) (struct CLEANUP_STATE *, int, const char *, int);
     off_t   mesg_offset;               /* start of message segment */
     off_t   data_offset;               /* start of message content */
     off_t   xtra_offset;               /* start of extra segment */
@@ -85,6 +83,8 @@ extern MAPS *cleanup_virt_alias_maps;
 extern ARGV *cleanup_masq_domains;
 extern STRING_LIST *cleanup_masq_exceptions;
 extern int cleanup_masq_flags;
+extern MAPS *cleanup_send_bcc_maps;
+extern MAPS *cleanup_rcpt_bcc_maps;
 
  /*
   * Address masquerading fine control.
@@ -143,17 +143,17 @@ extern void PRINTFLIKE(3, 4) cleanup_out_format(CLEANUP_STATE *, int, const char
  /*
   * cleanup_envelope.c
   */
-extern void cleanup_envelope(CLEANUP_STATE *, int, char *, int);
+extern void cleanup_envelope(CLEANUP_STATE *, int, const char *, int);
 
  /*
   * cleanup_message.c
   */
-extern void cleanup_message(CLEANUP_STATE *, int, char *, int);
+extern void cleanup_message(CLEANUP_STATE *, int, const char *, int);
 
  /*
   * cleanup_extracted.c
   */
-extern void cleanup_extracted(CLEANUP_STATE *, int, char *, int);
+extern void cleanup_extracted(CLEANUP_STATE *, int, const char *, int);
 
  /*
   * cleanup_rewrite.c
@@ -182,10 +182,17 @@ extern void cleanup_masquerade_internal(VSTRING *, ARGV *);
 extern void cleanup_masquerade_tree(TOK822 *, ARGV *);
 
  /*
-  * Cleanup_recipient.c
+  * cleanup_recipient.c
   */
 extern void cleanup_out_recipient(CLEANUP_STATE *, const char *, const char *);
 
+ /*
+  * cleanup_addr.c.
+  */
+extern void cleanup_addr_sender(CLEANUP_STATE *, const char *);
+extern void cleanup_addr_recipient(CLEANUP_STATE *, const char *);
+extern void cleanup_addr_bcc(CLEANUP_STATE *, const char *);
+
 /* LICENSE
 /* .ad
 /* .fi
diff --git a/postfix/src/cleanup/cleanup_addr.c b/postfix/src/cleanup/cleanup_addr.c
new file mode 100644 (file)
index 0000000..b52a27a
--- /dev/null
@@ -0,0 +1,165 @@
+/*++
+/* NAME
+/*     cleanup_addr 3
+/* SUMMARY
+/*     process envelope addresses
+/* SYNOPSIS
+/*     #include <cleanup.h>
+/*
+/*     void    cleanup_addr_sender(state, addr)
+/*     CLEANUP_STATE *state;
+/*     const char *addr;
+/*
+/*     void    cleanup_addr_recipient(state, addr)
+/*     CLEANUP_STATE *state;
+/*     const char *addr;
+/*
+/*     void    cleanup_addr_bcc(state, addr)
+/*     CLEANUP_STATE *state;
+/*     const char *addr;
+/* DESCRIPTION
+/*     This module processes envelope address records and writes the result
+/*     to the queue file. Processing includes address rewriting and
+/*     sender/recipient auto bcc address generation.
+/*
+/*     cleanup_addr_sender() process sender envelope information and updates
+/*     state->sender.
+/*
+/*     cleanup_addr_recipient() processes recipient envelope information
+/*     and updates state->recip.
+/*
+/*     cleanup_addr_bcc() processes recipient envelope information. This
+/*     is a separate function to avoid invoking cleanup_addr_recipient()
+/*     recursively.
+/*
+/*     Arguments:
+/* .IP state
+/*     Queue file and message processing state. This state is updated
+/*     as records are processed and as errors happen.
+/* .IP buf
+/*     Record content.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
+/* Utility library. */
+
+#include <msg.h>
+#include <vstring.h>
+#include <vstream.h>
+#include <mymalloc.h>
+#include <stringops.h>
+
+/* Global library. */
+
+#include <rec_type.h>
+#include <cleanup_user.h>
+#include <mail_params.h>
+#include <ext_prop.h>
+#include <mail_addr.h>
+#include <canon_addr.h>
+
+/* Application-specific. */
+
+#include "cleanup.h"
+
+#define STR    vstring_str
+
+/* cleanup_addr_sender - process envelope sender record */
+
+void    cleanup_addr_sender(CLEANUP_STATE *state, const char *buf)
+{
+    VSTRING *clean_addr = vstring_alloc(100);
+    const char *bcc;
+
+    cleanup_rewrite_internal(clean_addr, buf);
+    if (strncasecmp(STR(clean_addr), MAIL_ADDR_MAIL_DAEMON "@",
+                   sizeof(MAIL_ADDR_MAIL_DAEMON)) == 0) {
+       canon_addr_internal(state->temp1, MAIL_ADDR_MAIL_DAEMON);
+       if (strcasecmp(STR(clean_addr), STR(state->temp1)) == 0)
+           vstring_strcpy(clean_addr, "");
+    }
+    if (cleanup_send_canon_maps)
+       cleanup_map11_internal(state, clean_addr, cleanup_send_canon_maps,
+                              cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+    if (cleanup_comm_canon_maps)
+       cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
+                              cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+    if (cleanup_masq_domains
+       && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_FROM))
+       cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
+    CLEANUP_OUT_BUF(state, REC_TYPE_FROM, clean_addr);
+    if (state->sender == 0)
+       state->sender = mystrdup(STR(clean_addr));
+    if ((state->flags & CLEANUP_FLAG_BCC_OK)
+       && *STR(clean_addr)
+       && cleanup_send_bcc_maps
+       && (bcc = maps_find(cleanup_send_bcc_maps, STR(clean_addr), 0)) != 0)
+       cleanup_addr_bcc(state, bcc);
+    vstring_free(clean_addr);
+}
+
+/* cleanup_addr_recipient - process envelope recipient */
+
+void    cleanup_addr_recipient(CLEANUP_STATE *state, const char *buf)
+{
+    VSTRING *clean_addr = vstring_alloc(100);
+    const char *bcc;
+
+    cleanup_rewrite_internal(clean_addr, *buf ? buf : var_empty_addr);
+    if (cleanup_rcpt_canon_maps)
+       cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
+                              cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+    if (cleanup_comm_canon_maps)
+       cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
+                              cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+    if (cleanup_masq_domains
+       && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
+       cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
+    cleanup_out_recipient(state, state->orig_rcpt, STR(clean_addr));
+    if (state->recip == 0)
+       state->recip = mystrdup(STR(clean_addr));
+    if ((state->flags & CLEANUP_FLAG_BCC_OK)
+       && *STR(clean_addr)
+       && cleanup_rcpt_bcc_maps
+       && (bcc = maps_find(cleanup_rcpt_bcc_maps, STR(clean_addr), 0)) != 0)
+       cleanup_addr_bcc(state, bcc);
+    vstring_free(clean_addr);
+}
+
+/* cleanup_addr_bcc - process automatic BCC recipient */
+
+void    cleanup_addr_bcc(CLEANUP_STATE *state, const char *bcc)
+{
+    VSTRING *clean_addr = vstring_alloc(100);
+
+    cleanup_rewrite_internal(clean_addr, bcc);
+    if (cleanup_rcpt_canon_maps)
+       cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
+                              cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+    if (cleanup_comm_canon_maps)
+       cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
+                              cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
+    if (cleanup_masq_domains
+       && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
+       cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
+    cleanup_out_recipient(state, STR(clean_addr), STR(clean_addr));
+    vstring_free(clean_addr);
+}
index bb06cb1b6f5c142cb56a6d9e3baefff30f69f686..c0f749cd377d2f1a1ceb8d10a189c98249988b0f 100644 (file)
 /* .IP CLEANUP_FLAG_BOUNCE
 /*     The cleanup server is responsible for returning undeliverable
 /*     mail (too many hops, message too large) to the sender.
+/* .IP CLEANUP_FLAG_BCC_OK
+/*     It is OK to add automatic BCC recipient addresses.
 /* .IP CLEANUP_FLAG_FILTER
 /*     Enable header/body filtering. This should be enabled only with mail
 /*     that enters Postfix, not with locally forwarded mail or with bounce
 /*     messages.
-/* .IP CLEANUP_FLAG_EXTRACT
-/*     Extract recipients from message headers when no recipients are
-/*     provided in the message envelope records.
 /* .PP
 /*     CLEANUP_RECORD() is a macro that processes one message record,
 /*     that copies the result to the queue file, and that maintains a
@@ -171,7 +170,7 @@ void    cleanup_control(CLEANUP_STATE *state, int flags)
     if ((state->flags = flags) & CLEANUP_FLAG_BOUNCE) {
        state->err_mask = CLEANUP_STAT_MASK_INCOMPLETE;
     } else {
-       state->err_mask = ~CLEANUP_STAT_MASK_EXTRACT_RCPT;
+       state->err_mask = ~0;
     }
 }
 
@@ -183,13 +182,6 @@ int     cleanup_flush(CLEANUP_STATE *state)
     int     status;
     char   *encoding;
 
-    /*
-     * Ignore recipient extraction alarms if (a) we did (not need to) extract
-     * recipients, or (b) we did not examine all queue file records.
-     */
-    if (state->recip != 0 || CLEANUP_OUT_OK(state) == 0)
-       state->errs &= ~CLEANUP_STAT_MASK_EXTRACT_RCPT;
-
     /*
      * Raise these errors only if we examined all queue file records.
      */
index 77734a8b0af3ddb317b29ef27af4069f2ad2bc03..226a673d658e90ff2b35543f69d33dcb46e214a0 100644 (file)
@@ -9,8 +9,7 @@
 /*     void    cleanup_envelope(state, type, buf, len)
 /*     CLEANUP_STATE *state;
 /*     int     type;
-/*     char    *buf;
-/*     int     len;
+/*     const char *buf;
 /*     int     len;
 /* DESCRIPTION
 /*     This module processes envelope records and writes the result
 
 #define STR    vstring_str
 
-static void cleanup_envelope_process(CLEANUP_STATE *, int, char *, int);
+static void cleanup_envelope_process(CLEANUP_STATE *, int, const char *, int);
 
 /* cleanup_envelope - initialize message envelope */
 
-void    cleanup_envelope(CLEANUP_STATE *state, int type, char *str, int len)
+void    cleanup_envelope(CLEANUP_STATE *state, int type,
+                                const char *str, int len)
 {
 
     /*
@@ -104,13 +104,18 @@ void    cleanup_envelope(CLEANUP_STATE *state, int type, char *str, int len)
 
 /* cleanup_envelope_process - process one envelope record */
 
-static void cleanup_envelope_process(CLEANUP_STATE *state, int type, char *buf, int len)
+static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
+                                            const char *buf, int len)
 {
     char   *attr_name;
     char   *attr_value;
     const char *error_text;
     int     extra_flags;
 
+    /*
+     * On the transition from envelope segment to content segment, do some
+     * sanity checks and add some records.
+     */
     if (type == REC_TYPE_MESG) {
        if (state->sender == 0 || state->time == 0) {
            msg_warn("%s: missing sender or time envelope record",
@@ -158,31 +163,13 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, char *buf,
     } else if (type == REC_TYPE_FULL) {
        state->fullname = mystrdup(buf);
     } else if (type == REC_TYPE_FROM) {
-       VSTRING *clean_addr = vstring_alloc(100);
-
-       cleanup_rewrite_internal(clean_addr, buf);
-       if (strncasecmp(STR(clean_addr), MAIL_ADDR_MAIL_DAEMON "@",
-                       sizeof(MAIL_ADDR_MAIL_DAEMON)) == 0) {
-           canon_addr_internal(state->temp1, MAIL_ADDR_MAIL_DAEMON);
-           if (strcasecmp(STR(clean_addr), STR(state->temp1)) == 0)
-               vstring_strcpy(clean_addr, "");
+       if (state->sender != 0) {
+           msg_warn("%s: too many envelope sender records", state->queue_id);
+           state->errs |= CLEANUP_STAT_BAD;
+           return;
        }
-       if (cleanup_send_canon_maps)
-           cleanup_map11_internal(state, clean_addr, cleanup_send_canon_maps,
-                               cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
-       if (cleanup_comm_canon_maps)
-           cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
-                               cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
-       if (cleanup_masq_domains
-           && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_FROM))
-           cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
-       CLEANUP_OUT_BUF(state, type, clean_addr);
-       if (state->sender == 0)
-           state->sender = mystrdup(STR(clean_addr));
-       vstring_free(clean_addr);
+       cleanup_addr_sender(state, buf);
     } else if (type == REC_TYPE_RCPT) {
-       VSTRING *clean_addr = vstring_alloc(100);
-
        if (state->sender == 0) {               /* protect showq */
            msg_warn("%s: envelope recipient precedes sender",
                     state->queue_id);
@@ -191,20 +178,7 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, char *buf,
        }
        if (state->orig_rcpt == 0)
            state->orig_rcpt = mystrdup(buf);
-       cleanup_rewrite_internal(clean_addr, *buf ? buf : var_empty_addr);
-       if (cleanup_rcpt_canon_maps)
-           cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
-                               cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
-       if (cleanup_comm_canon_maps)
-           cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
-                               cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
-       if (cleanup_masq_domains
-           && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
-           cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
-       cleanup_out_recipient(state, state->orig_rcpt, STR(clean_addr));
-       if (state->recip == 0)
-           state->recip = mystrdup(STR(clean_addr));
-       vstring_free(clean_addr);
+       cleanup_addr_recipient(state, buf);
        myfree(state->orig_rcpt);
        state->orig_rcpt = 0;
     } else if (type == REC_TYPE_WARN) {
@@ -225,6 +199,8 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, char *buf,
            return;
        }
     } else if (type == REC_TYPE_ATTR) {
+       char   *sbuf;
+
        if (state->attr->used >= var_qattr_count_limit) {
            msg_warn("%s: queue file attribute count exceeds safety limit: %d",
                     state->queue_id, var_qattr_count_limit);
@@ -232,13 +208,16 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, char *buf,
            return;
        }
        cleanup_out(state, type, buf, len);
-       if ((error_text = split_nameval(buf, &attr_name, &attr_value)) != 0) {
+       sbuf = mystrdup(buf);
+       if ((error_text = split_nameval(sbuf, &attr_name, &attr_value)) != 0) {
            msg_warn("%s: malformed attribute: %s: %.100s",
                     state->queue_id, error_text, buf);
            state->errs |= CLEANUP_STAT_BAD;
+           myfree(sbuf);
            return;
        }
        nvtable_update(state->attr, attr_name, attr_value);
+       myfree(sbuf);
     } else if (type == REC_TYPE_ORCP) {
        state->orig_rcpt = mystrdup(buf);
     } else {
index 50b3d12edda3367cc223921fb85abc80884463aa..faad668a1f365f4a872eb856202c05250b313edf 100644 (file)
@@ -9,7 +9,7 @@
 /*     void    cleanup_extracted(state, type, buf, len)
 /*     CLEANUP_STATE *state;
 /*     int     type;
-/*     char    *buf;
+/*     const char *buf;
 /*     int     len;
 /* DESCRIPTION
 /*     This module processes message records with information extracted
 
 #define STR(x) vstring_str(x)
 
-static void cleanup_extracted_process(CLEANUP_STATE *, int, char *, int);
+static void cleanup_extracted_process(CLEANUP_STATE *, int, const char *, int);
 
 /* cleanup_extracted - initialize extracted segment */
 
-void    cleanup_extracted(CLEANUP_STATE *state, int type, char *buf, int len)
+void    cleanup_extracted(CLEANUP_STATE *state, int type,
+                                 const char *buf, int len)
 {
     const char *encoding;
 
@@ -128,12 +129,10 @@ void    cleanup_extracted(CLEANUP_STATE *state, int type, char *buf, int len)
 
 /* cleanup_extracted_process - process extracted segment */
 
-static void cleanup_extracted_process(CLEANUP_STATE *state, int type, char *buf, int len)
+static void cleanup_extracted_process(CLEANUP_STATE *state, int type,
+                                             const char *buf, int len)
 {
     char   *myname = "cleanup_extracted_process";
-    VSTRING *clean_addr;
-    ARGV   *rcpt;
-    char  **cpp;
 
     /*
      * Weird condition for consistency with cleanup_envelope.c
@@ -148,23 +147,9 @@ static void cleanup_extracted_process(CLEANUP_STATE *state, int type, char *buf,
        }
     }
     if (type == REC_TYPE_RCPT) {
-       clean_addr = vstring_alloc(100);
        if (state->orig_rcpt == 0)
            state->orig_rcpt = mystrdup(buf);
-       cleanup_rewrite_internal(clean_addr, *buf ? buf : var_empty_addr);
-       if (cleanup_rcpt_canon_maps)
-           cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
-                               cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
-       if (cleanup_comm_canon_maps)
-           cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
-                               cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
-       if (cleanup_masq_domains
-           && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT))
-           cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
-       cleanup_out_recipient(state, state->orig_rcpt, STR(clean_addr));
-       if (state->recip == 0)
-           state->recip = mystrdup(STR(clean_addr));
-       vstring_free(clean_addr);
+       cleanup_addr_recipient(state, buf);
        myfree(state->orig_rcpt);
        state->orig_rcpt = 0;
        return;
@@ -177,52 +162,11 @@ static void cleanup_extracted_process(CLEANUP_STATE *state, int type, char *buf,
     }
 
     /*
-     * Optionally account for missing recipient envelope records.
-     * 
-     * Don't extract recipients when some header was too long. We have
-     * incomplete information.
-     * 
-     * XXX Code duplication from cleanup_envelope.c. This should be in one
-     * place.
+     * On the way out, add the optional automatic BCC recipient.
      */
-    if (state->recip == 0 && (state->errs & CLEANUP_STAT_HOVFL) == 0) {
-       rcpt = (state->resent[0] ? state->resent_recip : state->recipients);
-       if (rcpt->argc >= var_extra_rcpt_limit) {
-           state->errs |= CLEANUP_STAT_ROVFL;
-       } else {
-           clean_addr = vstring_alloc(100);
-           if (*var_always_bcc && rcpt->argv[0]) {
-               cleanup_rewrite_internal(clean_addr, var_always_bcc);
-               if (cleanup_rcpt_canon_maps)
-                   cleanup_map11_internal(state, clean_addr, cleanup_rcpt_canon_maps,
-                               cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
-               if (cleanup_comm_canon_maps)
-                   cleanup_map11_internal(state, clean_addr, cleanup_comm_canon_maps,
-                               cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
-               argv_add(rcpt, STR(clean_addr), (char *) 0);
-           }
-           argv_terminate(rcpt);
-
-           /*
-            * Recipients extracted from message headers already have
-            * undergone recipient address rewriting (see cleanup_message.c),
-            * but still may need address masquerading.
-            */
-           for (cpp = rcpt->argv; CLEANUP_OUT_OK(state) && *cpp; cpp++) {
-               if (cleanup_masq_domains
-                   && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT)) {
-                   vstring_strcpy(clean_addr, *cpp);
-                   cleanup_masquerade_internal(clean_addr, cleanup_masq_domains);
-                   cleanup_out_recipient(state, STR(clean_addr),
-                                         STR(clean_addr));     /* XXX */
-               } else
-                   cleanup_out_recipient(state, *cpp, *cpp);   /* XXX */
-           }
-           if (rcpt->argv[0])
-               state->recip = mystrdup(rcpt->argv[0]);
-           vstring_free(clean_addr);
-       }
-    }
+    if ((state->flags & CLEANUP_FLAG_BCC_OK)
+       && state->recip != 0 && *var_always_bcc)
+       cleanup_addr_bcc(state, var_always_bcc);
 
     /*
      * Terminate the extracted segment.
index 5c8a5765809fa64796215243fa2053b54ec0b1bf..dcd1dfbf09fb3ac470f3d4b2636de2d3b262bc15 100644 (file)
@@ -106,18 +106,18 @@ char   *var_empty_addr;                   /* destination of bounced bounces */
 int     var_delay_warn_time;           /* delay that triggers warning */
 char   *var_prop_extension;            /* propagate unmatched extension */
 char   *var_always_bcc;                        /* big brother */
-int     var_extra_rcpt_limit;          /* recipient extract limit */
 char   *var_rcpt_witheld;              /* recipients not disclosed */
 char   *var_masq_classes;              /* what to masquerade */
 int     var_qattr_count_limit;         /* named attribute limit */
 int     var_virt_recur_limit;          /* maximum virtual alias recursion */
 int     var_virt_expan_limit;          /* maximum virtual alias expansion */
 int     var_body_check_len;            /* when to stop body scan */
+char   *var_send_bcc_maps;             /* sender auto-bcc maps */
+char   *var_rcpt_bcc_maps;             /* recipient auto-bcc maps */
 
 CONFIG_INT_TABLE cleanup_int_table[] = {
     VAR_HOPCOUNT_LIMIT, DEF_HOPCOUNT_LIMIT, &var_hopcount_limit, 1, 0,
     VAR_DUP_FILTER_LIMIT, DEF_DUP_FILTER_LIMIT, &var_dup_filter_limit, 0, 0,
-    VAR_EXTRA_RCPT_LIMIT, DEF_EXTRA_RCPT_LIMIT, &var_extra_rcpt_limit, 0, 0,
     VAR_QATTR_COUNT_LIMIT, DEF_QATTR_COUNT_LIMIT, &var_qattr_count_limit, 1, 0,
     VAR_VIRT_RECUR_LIMIT, DEF_VIRT_RECUR_LIMIT, &var_virt_recur_limit, 1, 0,
     VAR_VIRT_EXPAN_LIMIT, DEF_VIRT_EXPAN_LIMIT, &var_virt_expan_limit, 1, 0,
@@ -146,6 +146,8 @@ CONFIG_STR_TABLE cleanup_str_table[] = {
     VAR_ALWAYS_BCC, DEF_ALWAYS_BCC, &var_always_bcc, 0, 0,
     VAR_RCPT_WITHELD, DEF_RCPT_WITHELD, &var_rcpt_witheld, 1, 0,
     VAR_MASQ_CLASSES, DEF_MASQ_CLASSES, &var_masq_classes, 0, 0,
+    VAR_SEND_BCC_MAPS, DEF_SEND_BCC_MAPS, &var_send_bcc_maps, 0, 0,
+    VAR_RCPT_BCC_MAPS, DEF_RCPT_BCC_MAPS, &var_rcpt_bcc_maps, 0, 0,
     0,
 };
 
@@ -163,6 +165,8 @@ MAPS   *cleanup_virt_alias_maps;
 ARGV   *cleanup_masq_domains;
 STRING_LIST *cleanup_masq_exceptions;
 int     cleanup_masq_flags;
+MAPS   *cleanup_send_bcc_maps;
+MAPS   *cleanup_rcpt_bcc_maps;
 
  /*
   * Address extension propagation restrictions.
@@ -224,6 +228,14 @@ void    cleanup_pre_jail(char *unused_name, char **unused_argv)
     if (*var_masq_classes)
        cleanup_masq_flags = name_mask(VAR_MASQ_CLASSES, masq_class_table,
                                       var_masq_classes);
+    if (*var_send_bcc_maps)
+       cleanup_send_bcc_maps =
+           maps_create(VAR_SEND_BCC_MAPS, var_send_bcc_maps,
+                       DICT_FLAG_LOCK);
+    if (*var_rcpt_bcc_maps)
+       cleanup_rcpt_bcc_maps =
+           maps_create(VAR_RCPT_BCC_MAPS, var_rcpt_bcc_maps,
+                       DICT_FLAG_LOCK);
 }
 
 /* cleanup_post_jail - initialize after entering the chroot jail */
index 28ac89b10d861fc6c1c20bb76561e0abc9b75bf2..72a562703c53a238c89e3dac261a7770b9b8ae19 100644 (file)
@@ -9,7 +9,7 @@
 /*     void    cleanup_message(state, type, buf, len)
 /*     CLEANUP_STATE *state;
 /*     int     type;
-/*     char    *buf;
+/*     const char *buf;
 /*     int     len;
 /* DESCRIPTION
 /*     This module processes message content records and copies the
@@ -213,7 +213,6 @@ static void cleanup_rewrite_recip(CLEANUP_STATE *state, HEADER_OPTS *hdr_opts,
     TOK822 *tree;
     TOK822 **addr_list;
     TOK822 **tpp;
-    ARGV   *rcpt;
 
     if (msg_verbose)
        msg_info("rewrite_recip: %s", hdr_opts->name);
@@ -236,18 +235,6 @@ static void cleanup_rewrite_recip(CLEANUP_STATE *state, HEADER_OPTS *hdr_opts,
            cleanup_map11_tree(state, *tpp, cleanup_comm_canon_maps,
                               cleanup_ext_prop_mask & EXT_PROP_CANONICAL);
 
-       /*
-        * Extract envelope recipients after recipient address rewriting but
-        * before address masquerading.
-        */
-       if (state->recip == 0 && (hdr_opts->flags & HDR_OPT_EXTRACT) != 0) {
-           rcpt = (hdr_opts->flags & HDR_OPT_RR) ?
-               state->resent_recip : state->recipients;
-           if (rcpt->argc < var_extra_rcpt_limit) {
-               tok822_internalize(state->temp1, tpp[0]->head, TOK822_STR_DEFL);
-               argv_add(rcpt, vstring_str(state->temp1), (char *) 0);
-           }
-       }
        if (cleanup_masq_domains
            && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_HDR_RCPT))
            cleanup_masquerade_tree(*tpp, cleanup_masq_domains);
@@ -269,7 +256,7 @@ static void cleanup_act_log(CLEANUP_STATE *state,
     const char *attr;
 
     if ((attr = nvtable_find(state->attr, MAIL_ATTR_ORIGIN)) == 0)
-       attr="unknown";
+       attr = "unknown";
     vstring_sprintf(state->temp1, "%s: %s: %s %.200s from %s;",
                    state->queue_id, action, class, content, attr);
     if (state->sender)
@@ -595,13 +582,6 @@ static void cleanup_header_done_callback(void *context)
 
     if ((state->headers_seen & VISIBLE_RCPT) == 0)
        cleanup_out_format(state, REC_TYPE_NORM, "%s", var_rcpt_witheld);
-
-    /*
-     * Header buffer overflow is an unrecoverable error only if we extract
-     * recipients from the main message headers.
-     */
-    if (state->mime_errs & MIME_ERR_TRUNC_HEADER)
-       state->errs |= CLEANUP_STAT_HOVFL;
 }
 
 /* cleanup_body_callback - output one body record */
@@ -635,7 +615,7 @@ static void cleanup_body_callback(void *context, int type,
 /* cleanup_message_headerbody - process message content, header and body */
 
 static void cleanup_message_headerbody(CLEANUP_STATE *state, int type,
-                                              char *buf, int len)
+                                              const char *buf, int len)
 {
     char   *myname = "cleanup_message_headerbody";
 
@@ -696,7 +676,7 @@ static void cleanup_mime_error_callback(void *context, int err_code,
 
 /* cleanup_message - initialize message content segment */
 
-void    cleanup_message(CLEANUP_STATE *state, int type, char *buf, int len)
+void    cleanup_message(CLEANUP_STATE *state, int type, const char *buf, int len)
 {
     char   *myname = "cleanup_message";
     int     mime_options;
@@ -717,7 +697,7 @@ void    cleanup_message(CLEANUP_STATE *state, int type, char *buf, int len)
      * special processing of Content-Type: headers, and thus, causes all text
      * after the primary headers to be treated as the message body.
      */
-    mime_options = MIME_OPT_REPORT_TRUNC_HEADER;
+    mime_options = 0;
     if (var_disable_mime_input) {
        mime_options |= MIME_OPT_DISABLE_MIME;
     } else {
index 2f17fd050a183d95bba9309e08704f3ec5ee1a61..f10d50c3d20d6bc097305a50bf1a4b95ef8fd605 100644 (file)
@@ -37,7 +37,6 @@
 
 #include <mymalloc.h>
 #include <vstring.h>
-#include <argv.h>
 #include <htable.h>
 
 /* Global library. */
@@ -76,8 +75,6 @@ CLEANUP_STATE *cleanup_state_alloc(void)
     state->err_mask = 0;
     state->headers_seen = 0;
     state->hop_count = 0;
-    state->recipients = argv_alloc(2);
-    state->resent_recip = argv_alloc(2);
     state->resent = "";
     state->dups = been_here_init(var_dup_filter_limit, BH_FLAG_FOLD);
     state->warn_time = 0;
@@ -118,8 +115,6 @@ void    cleanup_state_free(CLEANUP_STATE *state)
        myfree(state->return_receipt);
     if (state->errors_to)
        myfree(state->errors_to);
-    argv_free(state->recipients);
-    argv_free(state->resent_recip);
     if (state->queue_name)
        myfree(state->queue_name);
     if (state->queue_id)
index 144b74e7226530f8664a17390551db6900c9511b..489093ed94e2e9cb367d099e611be3d980c5703e 100644 (file)
@@ -49,8 +49,6 @@ struct cleanup_stat_map {
 
 static struct cleanup_stat_map cleanup_stat_map[] = {
     CLEANUP_STAT_BAD, "Internal protocol error",
-    CLEANUP_STAT_HOVFL, "Message header too long",
-    CLEANUP_STAT_ROVFL, "Too many extracted recipients",
     CLEANUP_STAT_RCPT, "No recipients specified",
     CLEANUP_STAT_HOPS, "Too many hops",
     CLEANUP_STAT_SIZE, "Message file too big",
index 44a4a506a31963409de74c99b03da7560c7aefd3..ce4af58514d7b83c39477416346281d61b347cd5 100644 (file)
@@ -19,6 +19,7 @@
 #define CLEANUP_FLAG_FILTER    (1<<1)  /* Enable content filter */
 #define CLEANUP_FLAG_HOLD      (1<<2)  /* Place message on hold */
 #define CLEANUP_FLAG_DISCARD   (1<<3)  /* Discard message silently */
+#define CLEANUP_FLAG_BCC_OK    (1<<4)  /* Ok to add auto-BCC addresses */
 
  /*
   * These are set on the fly while processing SMTP envelopes or message
 #define CLEANUP_STAT_SIZE      (1<<2)  /* Message file too big */
 #define CLEANUP_STAT_CONT      (1<<3)  /* Message content rejected */
 #define CLEANUP_STAT_HOPS      (1<<4)  /* Too many hops */
-#define CLEANUP_STAT_SYN       (1<<5)  /* Bad address syntax */
 #define CLEANUP_STAT_RCPT      (1<<6)  /* No recipients found */
-#define CLEANUP_STAT_HOVFL     (1<<7)  /* Header overflow */
-#define CLEANUP_STAT_ROVFL     (1<<8)  /* Recipient overflow */
 
  /*
   * These are set when we can't bounce even if we were asked to.
 #define CLEANUP_STAT_MASK_INCOMPLETE \
        (CLEANUP_STAT_BAD | CLEANUP_STAT_WRITE | CLEANUP_STAT_SIZE)
 
- /*
-  * These are relevant for extracting recipients from headers.
-  */
-#define CLEANUP_STAT_MASK_EXTRACT_RCPT \
-       (CLEANUP_STAT_HOVFL | CLEANUP_STAT_ROVFL | CLEANUP_STAT_RCPT)
-
 extern const char *cleanup_strerror(unsigned);
 
 /* LICENSE
index e4cb9ce1b6e80dc0e7315c37fcfcc6bda5232eaa..67cc4ea05c8795e665a7746d811a268c44862421 100644 (file)
@@ -324,6 +324,14 @@ extern char *var_send_canon_maps;
 #define DEF_RCPT_CANON_MAPS    ""
 extern char *var_rcpt_canon_maps;
 
+#define VAR_SEND_BCC_MAPS      "sender_bcc_maps"
+#define DEF_SEND_BCC_MAPS      ""
+extern char *var_send_bcc_maps;
+
+#define VAR_RCPT_BCC_MAPS      "recipient_bcc_maps"
+#define DEF_RCPT_BCC_MAPS      ""
+extern char *var_rcpt_bcc_maps;
+
 #define VAR_TRANSPORT_MAPS     "transport_maps"
 #define DEF_TRANSPORT_MAPS     ""
 extern char *var_transport_maps;
@@ -1015,10 +1023,6 @@ extern int var_header_limit;
 #define DEF_TOKEN_LIMIT                10240
 extern int var_token_limit;
 
-#define VAR_EXTRA_RCPT_LIMIT   "extract_recipient_limit"
-#define DEF_EXTRA_RCPT_LIMIT   10240
-extern int var_extra_rcpt_limit;
-
 #define VAR_VIRT_RECUR_LIMIT   "virtual_alias_recursion_limit"
 #define DEF_VIRT_RECUR_LIMIT   1000
 extern int var_virt_recur_limit;
index f6665ddc13114d64e9f7776b495acea905719cd7..cff3dd02cd643549ec1b799441281ce99bd98fa6 100644 (file)
@@ -20,7 +20,7 @@
   * 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      "20030415"
+#define MAIL_RELEASE_DATE      "20030416"
 
 #define VAR_MAIL_VERSION       "mail_version"
 #define DEF_MAIL_VERSION       "2.0.8-" MAIL_RELEASE_DATE
index dca5193944e05b9b2eac03f350359f84570dd252..e2d20cb42dc47730c8d16d047b322ed5751cb279 100644 (file)
@@ -216,6 +216,11 @@ int     deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path)
                          defer_append : bounce_append)
            (BOUNCE_FLAGS(state.request), BOUNCE_ATTR(state.msg_attr),
             "maildir delivery failed: %s", vstring_str(why));
+       if (errno == EACCES) {
+           msg_warn("maildir access problem for UID/GID=%lu/%lu: %s",
+               (long) usr_attr.uid, (long) usr_attr.gid, vstring_str(why));
+           msg_warn("perhaps you need to create the maildirs in advance");
+       }
     } else {
        deliver_status = sent(BOUNCE_FLAGS(state.request),
                              SENT_ATTR(state.msg_attr),
index fd586072f45763713cef4ca8025497a1cd877aaf..6d51cec84b1a9b90f8d1a77f22cb07da5bb5e8f3 100644 (file)
@@ -48,8 +48,6 @@
 /* .SH Miscellaneous
 /* .ad
 /* .fi
-/* .IP \fBalways_bcc\fR
-/*     Address to send a copy of each message that enters the system.
 /* .IP \fBqueue_directory\fR
 /*     Top-level directory of the Postfix queue.
 /* SEE ALSO
 
 /* Application-specific. */
 
-char   *var_always_bcc;
 char   *var_filter_xport;
 
  /*
@@ -299,9 +296,6 @@ static int pickup_copy(VSTREAM *qfile, VSTREAM *cleanup,
      * Copy the message envelope segment. Allow only those records that we
      * expect to see in the envelope section. The envelope segment must
      * contain an envelope sender address.
-     * 
-     * If the segment contains a recipient address, include the optional
-     * always_bcc recipient.
      */
     if ((status = copy_segment(qfile, cleanup, info, buf, REC_TYPE_ENVELOPE)) != 0)
        return (status);
@@ -313,11 +307,6 @@ static int pickup_copy(VSTREAM *qfile, VSTREAM *cleanup,
     msg_info("%s: uid=%d from=<%s>", info->id,
             (int) info->st.st_uid, info->sender);
 
-    if (info->rcpt) {
-       if (*var_always_bcc)
-           rec_fputs(cleanup, REC_TYPE_RCPT, var_always_bcc);
-    }
-
     /*
      * Message content segment. Send a dummy message length. Prepend a
      * Received: header to the message contents. For tracing purposes,
@@ -408,7 +397,8 @@ static int pickup_file(PICKUP_INFO *info)
      * easier to implement the many possible error exits without forgetting
      * to close files, or to release memory.
      */
-#define PICKUP_CLEANUP_FLAGS   (CLEANUP_FLAG_BOUNCE | CLEANUP_FLAG_FILTER)
+#define PICKUP_CLEANUP_FLAGS \
+       (CLEANUP_FLAG_BOUNCE | CLEANUP_FLAG_FILTER | CLEANUP_FLAG_BCC_OK)
 
     cleanup = mail_connect_wait(MAIL_CLASS_PUBLIC, var_cleanup_service);
     if (attr_scan(cleanup, ATTR_FLAG_STRICT,
@@ -512,7 +502,6 @@ static void drop_privileges(char *unused_name, char **unused_argv)
 int     main(int argc, char **argv)
 {
     static CONFIG_STR_TABLE str_table[] = {
-       VAR_ALWAYS_BCC, DEF_ALWAYS_BCC, &var_always_bcc, 0, 0,
        VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0,
        0,
     };
index 4fe2cc8bda528767035e9f90ee3c8578206a250b..28cbbcd68947dfa8ca6bdd31ba38d6663c4cf17e 100644 (file)
@@ -42,8 +42,6 @@
 /* .SH Miscellaneous
 /* .ad
 /* .fi
-/* .IP \fBalways_bcc\fR
-/*     Address to send a copy of each message that enters the system.
 /* .IP \fBdebug_peer_level\fR
 /*     Increment in verbose logging level when a remote host matches a
 /*     pattern in the \fBdebug_peer_list\fR parameter.
   */
 int     var_qmqpd_timeout;
 int     var_qmqpd_err_sleep;
-char   *var_always_bcc;
 char   *var_filter_xport;
 char   *var_qmqpd_clients;
 
@@ -182,10 +179,12 @@ static void qmqpd_open_file(QMQPD_STATE *state)
     /*
      * Connect to the cleanup server. Log client name/address with queue ID.
      */
+#define QMQPD_CLEANUP_FLAGS (CLEANUP_FLAG_FILTER | CLEANUP_FLAG_BCC_OK)
+
     state->dest = mail_stream_service(MAIL_CLASS_PUBLIC, var_cleanup_service);
     if (state->dest == 0
        || attr_print(state->dest->stream, ATTR_FLAG_NONE,
-                     ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, CLEANUP_FLAG_FILTER,
+                     ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, QMQPD_CLEANUP_FLAGS,
                      ATTR_TYPE_END) != 0)
        msg_fatal("unable to connect to the %s %s service",
                  MAIL_CLASS_PUBLIC, var_cleanup_service);
@@ -295,14 +294,6 @@ static void qmqpd_copy_recipients(QMQPD_STATE *state)
        if (state->recipient == 0)
            state->recipient = mystrndup(STR(state->buf), LEN(state->buf));
     }
-
-    /*
-     * Append the optional recipient who is copied on all mail.
-     */
-    if (state->err == CLEANUP_STAT_OK
-       && *var_always_bcc
-       && rec_fputs(state->cleanup, REC_TYPE_RCPT, var_always_bcc) < 0)
-       state->err = CLEANUP_STAT_WRITE;
 }
 
 /* qmqpd_next_line - get line from buffer, return last char, newline, or -1 */
@@ -690,7 +681,6 @@ int     main(int argc, char **argv)
        0,
     };
     static CONFIG_STR_TABLE str_table[] = {
-       VAR_ALWAYS_BCC, DEF_ALWAYS_BCC, &var_always_bcc, 0, 0,
        VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0,
        VAR_QMQPD_CLIENTS, DEF_QMQPD_CLIENTS, &var_qmqpd_clients, 0, 0,
        0,
index 00785b831fc81f3c48bbe338484b3d3fdedff1cd..38e604c16ac2de2f081fa859f5845e46b6b6eef4 100644 (file)
 /*     This command is not implemented. Use the slower \fBsendmail -q\fR
 /*     command instead.
 /* .IP \fB-t\fR
-/*     Extract recipients from message headers. This requires that no
-/*     recipients be specified on the command line.
+/*     Extract recipients from message headers. These are added to any
+/*     recipients specified on the command line.
 /* .IP \fB-v\fR
 /*     Send an email report of all delivery attempts (mail delivery
 /*     always happens in the background). When multiple \fB-v\fR
 #include <stringops.h>
 #include <set_ugid.h>
 #include <connect.h>
+#include <split_at.h>
 
 /* Global library. */
 
 #include <mail_stream.h>
 #include <verp_sender.h>
 #include <deliver_request.h>
+#include <mime_state.h>
+#include <header_opts.h>
 
 /* Application-specific. */
 
   * Flag parade. Flags 8-15 are reserved for delivery request trace flags.
   */
 #define SM_FLAG_AEOF   (1<<0)          /* archaic EOF */
+#define SM_FLAG_XRCPT  (1<<1)          /* extract recipients from headers */
 
 #define SM_FLAG_DEFAULT        (SM_FLAG_AEOF)
 
   */
 char   *verp_delims;
 
+ /*
+  * Context for extracting recipients.
+  */
+typedef struct SM_STATE {
+    VSTREAM *dst;                      /* output stream */
+    ARGV   *recipients;                        /* recipients from regular headers */
+    ARGV   *resent_recip;              /* recipients from resent headers */
+    int     resent;                    /* resent flag */
+    const char *saved_sender;          /* for error messages */
+    uid_t   uid;                       /* for error messages */
+    VSTRING *temp;                     /* scratch buffer */
+} SM_STATE;
+
  /*
   * Silly little macros (SLMs).
   */
 #define STR    vstring_str
 
+/* output_text - output partial or complete text line */
+
+static void output_text(void *context, int rec_type, const char *buf, int len,
+                               off_t unused_offset)
+{
+    SM_STATE *state = (SM_STATE *) context;
+
+    if (rec_put(state->dst, rec_type, buf, len) < 0)
+       msg_fatal_status(EX_TEMPFAIL,
+                        "%s(%ld): error writing queue file: %m",
+                        state->saved_sender, (long) state->uid);
+}
+
+/* output_header - output one message header */
+
+static void output_header(void *context, int header_class,
+                                 HEADER_OPTS *header_info,
+                                 VSTRING *buf, off_t offset)
+{
+    SM_STATE *state = (SM_STATE *) context;
+    TOK822 *tree;
+    TOK822 **addr_list;
+    TOK822 **tpp;
+    ARGV   *rcpt;
+    char   *start;
+    char   *line;
+    char   *next_line;
+
+    /*
+     * Pipe the unmodified message header through the header line folding
+     * routine.
+     */
+    for (line = start = STR(buf); line; line = next_line) {
+       next_line = split_at(line, '\n');
+       output_text(context, REC_TYPE_NORM, line, next_line ?
+                   next_line - line - 1 : strlen(line), offset);
+    }
+
+    /*
+     * Parse the header line, and save copies of recipient addresses in the
+     * appropriate place.
+     */
+    if (header_class == MIME_HDR_PRIMARY
+       && header_info->flags & HDR_OPT_RECIP
+       && header_info->flags & HDR_OPT_EXTRACT
+       && (state->resent == 0 || (header_info->flags & HDR_OPT_RR))) {
+       if (header_info->flags & HDR_OPT_RR) {
+           rcpt = state->resent_recip;
+           if (state->resent == 0)
+               state->resent = 1;
+       } else
+           rcpt = state->recipients;
+       tree = tok822_parse(vstring_str(buf) + strlen(header_info->name) + 1);
+       addr_list = tok822_grep(tree, TOK822_ADDR);
+       for (tpp = addr_list; *tpp; tpp++) {
+           tok822_internalize(state->temp, tpp[0]->head, TOK822_STR_DEFL);
+           argv_add(rcpt, vstring_str(state->temp), (char *) 0);
+       }
+       myfree((char *) addr_list);
+       tok822_free_tree(tree);
+    }
+}
+
 /* enqueue - post one message */
 
 static void enqueue(const int flags, const char *encoding, const char *sender,
@@ -376,6 +456,9 @@ static void enqueue(const int flags, const char *encoding, const char *sender,
     int     status;
     int     naddr;
     int     prev_type;
+    MIME_STATE *mime_state = 0;
+    SM_STATE state;
+    int     mime_errs;
 
     /*
      * Initialize.
@@ -482,6 +565,31 @@ static void enqueue(const int flags, const char *encoding, const char *sender,
            }
        }
     } else {
+
+       /*
+        * Initialize the MIME processor and set up the callback context.
+        */
+       if (flags & SM_FLAG_XRCPT) {
+           state.dst = dst;
+           state.recipients = argv_alloc(2);
+           state.resent_recip = argv_alloc(2);
+           state.resent = 0;
+           state.saved_sender = saved_sender;
+           state.uid = uid;
+           state.temp = vstring_alloc(10);
+           mime_state = mime_state_alloc(MIME_OPT_DISABLE_MIME
+                                         | MIME_OPT_REPORT_TRUNC_HEADER,
+                                         output_header,
+                                         (MIME_STATE_ANY_END) 0,
+                                         output_text,
+                                         (MIME_STATE_ANY_END) 0,
+                                         (MIME_STATE_ERR_PRINT) 0,
+                                         (void *) &state);
+       }
+
+       /*
+        * Process header/body lines.
+        */
        skip_from_ = 1;
        strip_cr = STRIP_CR_DUNNO;
        for (prev_type = 0; (type = rec_streamlf_get(VSTREAM_IN, buf, var_line_limit))
@@ -506,18 +614,52 @@ static void enqueue(const int flags, const char *encoding, const char *sender,
            if ((flags & SM_FLAG_AEOF) && prev_type != REC_TYPE_CONT
                && VSTRING_LEN(buf) == 1 && *STR(buf) == '.')
                break;
-           if (REC_PUT_BUF(dst, type, buf) < 0)
-               msg_fatal_status(EX_TEMPFAIL,
-                                "%s(%ld): error writing queue file: %m",
-                                saved_sender, (long) uid);
+           if (mime_state) {
+               mime_errs = mime_state_update(mime_state, type, STR(buf),
+                                             VSTRING_LEN(buf));
+               if (mime_errs)
+                   msg_fatal_status(EX_DATAERR,
+                               "%s(%ld): unable to extract recipients: %s",
+                                    saved_sender, (long) uid,
+                                    mime_state_error(mime_errs));
+           } else {
+               if (REC_PUT_BUF(dst, type, buf) < 0)
+                   msg_fatal_status(EX_TEMPFAIL,
+                                    "%s(%ld): error writing queue file: %m",
+                                    saved_sender, (long) uid);
+           }
        }
     }
 
     /*
-     * Append an empty section for information extracted from message
-     * headers. Header parsing is done by the cleanup service.
+     * Finish up MIME processing.
+     */
+    if (mime_state) {
+       mime_errs = mime_state_update(mime_state, REC_TYPE_EOF, "", 0);
+       if (mime_errs)
+           msg_fatal_status(EX_DATAERR,
+                            "%s(%ld): unable to extract recipients: %s",
+                            saved_sender, (long) uid,
+                            mime_state_error(mime_errs));
+       mime_state = mime_state_free(mime_state);
+    }
+
+    /*
+     * Append recipient addresses that were extracted from message headers.
      */
     rec_fputs(dst, REC_TYPE_XTRA, "");
+    if (flags & SM_FLAG_XRCPT) {
+       for (cpp = state.resent ? state.resent_recip->argv :
+            state.recipients->argv; *cpp; cpp++) {
+           if (rec_put(dst, REC_TYPE_RCPT, *cpp, strlen(*cpp)) < 0)
+               msg_fatal_status(EX_TEMPFAIL,
+                                "%s(%ld): error writing queue file: %m",
+                                saved_sender, (long) uid);
+       }
+       argv_free(state.recipients);
+       argv_free(state.resent_recip);
+       vstring_free(state.temp);
+    }
 
     /*
      * Identify the end of the queue file.
@@ -563,7 +705,6 @@ int     main(int argc, char **argv)
     static char *full_name = 0;                /* sendmail -F */
     struct stat st;
     char   *slash;
-    int     extract_recipients = 0;    /* sendmail -t, almost */
     char   *sender = 0;                        /* sendmail -f */
     int     c;
     int     fd;
@@ -797,7 +938,7 @@ int     main(int argc, char **argv)
            }
            break;
        case 't':
-           extract_recipients = 1;
+           flags |= SM_FLAG_XRCPT;
            break;
        case 'v':
            msg_verbose++;
@@ -810,16 +951,12 @@ int     main(int argc, char **argv)
     /*
      * Look for conflicting options and arguments.
      */
-    if (extract_recipients && mode != SM_MODE_ENQUEUE)
+    if ((flags & SM_FLAG_XRCPT) && mode != SM_MODE_ENQUEUE)
        msg_fatal_status(EX_USAGE, "-t can be used only in delivery mode");
 
     if (site_to_flush && mode != SM_MODE_ENQUEUE)
        msg_fatal_status(EX_USAGE, "-qR can be used only in delivery mode");
 
-    if (extract_recipients && argv[OPTIND])
-       msg_fatal_status(EX_USAGE,
-                        "cannot handle command-line recipients with -t");
-
     /*
      * The -v option plays double duty. One requests verbose delivery, more
      * than one requests verbose logging.
index e5bc30e2d546b87178a3819280cfa77daef82d3d..9235fe50216a21976e2d36d083076c69ebeb516c 100644 (file)
@@ -347,6 +347,14 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why, int *found_myself)
      * preferred than myself. When no MX resource records exist, look up the
      * addresses listed for this name.
      * 
+     * According to RFC 974: "It is possible that the list of MXs in the
+     * response to the query will be empty.  This is a special case.  If the
+     * list is empty, mailers should treat it as if it contained one RR, an
+     * MX RR with a preference value of 0, and a host name of REMOTE.  (I.e.,
+     * REMOTE is its only MX).  In addition, the mailer should do no further
+     * processing on the list, but should attempt to deliver the message to
+     * REMOTE."
+     * 
      * Normally it is OK if an MX host cannot be found in the DNS; we'll just
      * use a backup one, and silently ignore the better MX host. However, if
      * the best backup that we can find in the DNS is the local machine, then
index 0ad53abeb9351a9e1a0ed1e284025ebba1322191..543d78b2a74911a4a0bb3b2daa75f22190a6e37c 100644 (file)
@@ -648,7 +648,7 @@ int     smtp_xfer(SMTP_STATE *state)
                                        request->queue_id, rcpt->orig_addr,
                                        rcpt->address, session->namaddr,
                                        request->arrival_time, "%s",
-                                       translit(resp->str, "\n", " ")) == 0) {
+                                    translit(resp->str, "\n", " ")) == 0) {
                                if (request->flags & DEL_REQ_FLAG_SUCCESS)
                                    deliver_completed(state->src, rcpt->offset);
                                rcpt->offset = 0;       /* in case deferred */
@@ -820,7 +820,8 @@ int     smtp_xfer(SMTP_STATE *state)
                                          vstring_str(state->scratch),
                                          VSTRING_LEN(state->scratch));
                    if (mime_errs) {
-                       smtp_mesg_fail(state, 554, "MIME 7-bit conversion failed: %s",
+                       smtp_mesg_fail(state, 554,
+                                      "MIME 7-bit conversion failed: %s",
                                       mime_state_error(mime_errs));
                        RETURN(0);
                    }
@@ -828,7 +829,16 @@ int     smtp_xfer(SMTP_STATE *state)
                prev_type = rec_type;
            }
 
-           if (prev_type == REC_TYPE_CONT)     /* missing newline at end */
+           if (state->mime_state) {
+               mime_errs =
+                   mime_state_update(state->mime_state, rec_type, "", 0);
+               if (mime_errs) {
+                   smtp_mesg_fail(state, 554,
+                                  "MIME 7-bit conversion failed: %s",
+                                  mime_state_error(mime_errs));
+                   RETURN(0);
+               }
+           } else if (prev_type == REC_TYPE_CONT)      /* missing newline */
                smtp_fputs("", 0, session->stream);
            if ((state->features & SMTP_FEATURE_MAYBEPIX) != 0
                && request->arrival_time < vstream_ftime(session->stream)
@@ -853,6 +863,5 @@ int     smtp_xfer(SMTP_STATE *state)
        send_state = next_state;
        send_rcpt = next_rcpt;
     }
-
     RETURN(0);
 }
index 7cf3ed70b98990b0753ae57e75dfd99bbbe4818f..96147559d6356699b7b70bcdeb5f79dc5eaec496 100644 (file)
 /* .SH Miscellaneous
 /* .ad
 /* .fi
-/* .IP \fBalways_bcc\fR
-/*     Address to send a copy of each message that enters the system.
 /* .IP \fBauthorized_verp_clients\fR
 /*     Hostnames, domain names and/or addresses of clients that are
 /*     authorized to use the XVERP extension.
@@ -411,7 +409,6 @@ int     var_reject_code;
 int     var_defer_code;
 int     var_smtpd_err_sleep;
 int     var_non_fqdn_code;
-char   *var_always_bcc;
 char   *var_error_rcpt;
 int     var_smtpd_delay_reject;
 char   *var_rest_classes;
@@ -600,12 +597,14 @@ static void mail_open_stream(SMTPD_STATE *state)
      * If running from the master or from inetd, connect to the cleanup
      * service.
      */
+#define SMTPD_CLEANUP_FLAGS (CLEANUP_FLAG_FILTER | CLEANUP_FLAG_BCC_OK)
+
     if (SMTPD_STAND_ALONE(state) == 0) {
        state->dest = mail_stream_service(MAIL_CLASS_PUBLIC,
                                          var_cleanup_service);
        if (state->dest == 0
            || attr_print(state->dest->stream, ATTR_FLAG_NONE,
-                       ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, CLEANUP_FLAG_FILTER,
+                       ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, SMTPD_CLEANUP_FLAGS,
                          ATTR_TYPE_END) != 0)
            msg_fatal("unable to connect to the %s %s service",
                      MAIL_CLASS_PUBLIC, var_cleanup_service);
@@ -1028,8 +1027,6 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
      * segment, and prepend our own Received: header. If there is only one
      * recipient, list the recipient address.
      */
-    if (*var_always_bcc)
-       rec_fputs(state->cleanup, REC_TYPE_RCPT, var_always_bcc);
     rec_fputs(state->cleanup, REC_TYPE_MESG, "");
     rec_fprintf(state->cleanup, REC_TYPE_NORM,
                "Received: from %s (%s [%s])",
@@ -1694,7 +1691,6 @@ int     main(int argc, char **argv)
        VAR_DATA_CHECKS, DEF_DATA_CHECKS, &var_data_checks, 0, 0,
        VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains, 0, 0,
        VAR_RBL_REPLY_MAPS, DEF_RBL_REPLY_MAPS, &var_rbl_reply_maps, 0, 0,
-       VAR_ALWAYS_BCC, DEF_ALWAYS_BCC, &var_always_bcc, 0, 0,
        VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
        VAR_REST_CLASSES, DEF_REST_CLASSES, &var_rest_classes, 0, 0,
        VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0,
index b84c1fa7491f96b4e4787a5c732bd4fb5a12e07f..c51a4e7c51f0b7d0ab90b83228c2ef8e64e34a9c 100644 (file)
@@ -215,7 +215,11 @@ int     deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr)
                          bounce_append : defer_append)
            (BOUNCE_FLAGS(state.request), BOUNCE_ATTR(state.msg_attr),
             "maildir delivery failed: %s", vstring_str(why));
-
+       if (errno == EACCES) {
+           msg_warn("maildir access problem for UID/GID=%lu/%lu: %s",
+               (long) usr_attr.uid, (long) usr_attr.gid, vstring_str(why));
+           msg_warn("perhaps you need to create the maildirs in advance");
+       }
     } else {
        deliver_status = sent(BOUNCE_FLAGS(state.request),
                              SENT_ATTR(state.msg_attr),