]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-20011006
authorWietse Venema <wietse@porcupine.org>
Sat, 6 Oct 2001 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:27:26 +0000 (06:27 +0000)
36 files changed:
postfix/DEBUG_README
postfix/HISTORY
postfix/LINUX_README
postfix/RELEASE_NOTES
postfix/conf/main.cf
postfix/conf/sample-misc.cf
postfix/conf/sample-smtpd.cf
postfix/html/faq.html
postfix/html/flush.8.html
postfix/html/smtpd.8.html
postfix/html/uce.html
postfix/makedefs
postfix/man/man8/flush.8
postfix/man/man8/smtpd.8
postfix/src/bounce/bounce_notify_util.c
postfix/src/cleanup/Makefile.in
postfix/src/flush/flush.c
postfix/src/global/defer.c
postfix/src/global/flush_clnt.c
postfix/src/global/flush_clnt.h
postfix/src/global/mail_addr_map.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/global/split_addr.c
postfix/src/nqmgr/Makefile.in
postfix/src/postsuper/postsuper.c
postfix/src/qmgr/Makefile.in
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpstone/qmqp-source.c
postfix/src/smtpstone/smtp-sink.c
postfix/src/smtpstone/smtp-source.c
postfix/src/util/Makefile.in
postfix/src/util/cache.in [new file with mode: 0644]
postfix/src/util/mymalloc.c
postfix/src/util/vstream.c

index cd2593eb682e3974679857fcd37e98cd39e3c4c3..43b2b889ecac9837f96552919639e4a66a6ee601 100644 (file)
@@ -44,10 +44,15 @@ a lot of activity to be logged to the syslog daemon.
 Some systems allow you to inspect a running process with a system
 call tracer. For example:
 
-       # trace -p process-id
-       # strace -p process-id
-       # truss -p process-id
-       # ktrace -p process-id
+    # trace -p process-id (SunOS 4)
+    # strace -p process-id (Linux and many others)
+    # truss -p process-id (Solaris, FreeBSD)
+    # ktrace -p process-id (generic 4.4BSD)
+
+Even more informative are traces of system library calls. Examples:
+
+    # ltrace -p process-id (Linux, also ported to FreeBSD and BSD/OS)
+    # sotruss -p process-id (Solaris)
 
 See your system documentation for details.
 
index fdca8a3fa16c0f54d286ee95d14716c5dc2a3243..a0d8abad145050344eb7550063466eb04b28b41e 100644 (file)
@@ -1616,7 +1616,7 @@ Apologies for any names omitted.
        wrong place. Problem tackled with help of Chip Christian.
 
        Portability: reportedly, Solaris 2.5.1 can hang waiting
-       for a UNIX-domain connection to be accepted, to it gets
+       for a UNIX-domain connection to be accepted, so it gets
        the same workaround that was designed for LINUX. Problem
        reported by Scott Cotton.
 
@@ -5412,3 +5412,78 @@ Apologies for any names omitted.
        address masquerading. The default setting is backwards
        compatible: envelope_sender header_sender header_recipient.
        Files: cleanup/whatever.c.
+
+20010822
+
+       Code cleanup: the bounce daemon complained about data that
+       it was not going to send back anyway. Fix: stop reading
+       the original message when the bounce message reaches the
+       bounce message size limit. File: bounce/bounce_notify_util.c.
+
+20010826
+
+       Logging: postsuper now logs the queue ID when it requeues
+       a message, or when it deletes a message from the mail queue.
+       File: postsuper/postsuper.c.
+
+20010830
+
+       Safety: the SMTP server now sends a 4xx (try again later)
+       response when an UCE restriction is misconfigured, instead
+       of ignoring the bad restriction and possibly accepting mail
+       that it should not accept.   File: smtpd/smtpd_check.c.
+
+20010907
+
+       Workaround: the Postfix qmqp-source program produced mail
+       not ending in newline that qmail-qmqpd accepts but that
+       qmail-remote was unable to deliver.  Matthias Andree,
+       uni-dortmund.de. File: smtpstone/qmqp-source.c.
+
+20010910
+
+       Bugfix: smtp-sink broke when RCPT TO commands crossed a
+       network packet boundary. Problem reported by Matthias
+       Andree, uni-dortmund.de.  File: smtpstone/smtp-sink.c.
+
+20010917
+
+       Code cleanup: permit_mx_backup implements the old behavior
+       (accept mail if the local MTA is MX relay), and allows an
+       additional restriction via the permit_mx_backup_networks
+       parameter (accept mail only if the primary MX hosts match
+       the specified list of network blocks). This second restriction
+       is now entirely optional, for backwards compatiblity.
+
+       Bugfix: an address extension could be appended multiple
+       times to the result of a canonical or virtual map lookup.
+       File: global/mail_addr_map.c.  Fix by Victor Duchovni,
+       Morgan Stanley.
+
+       Bugfix: split_addr() would split an address even when there
+       was no data before the recipient delimiter. In combination
+       with the above bug, this could cause an address to grow
+       exponentially in size.  Problem reported by Victor Duchovni,
+       Morgan Stanley.  File:  global/split_addr.c.
+
+20010918
+
+       Bugfix: the mail_addr_map() fix was almost but not quite
+       right. It took two really clever people and several iterations
+       of email to really fix the mail_addr_map() problem.  Thanks
+       to Victor Duchovni and Liviu Daia.
+
+20011006
+
+       Cleanup: Postfix no longer flushes the whole deferred queue
+       after an ETRN request for a random domain name; the SMTP
+       server instead replies with "459 service unavailable".
+       Files:  smtpd/smtpd.c, global/flush_clnt.c, flush/flush.c.
+
+Open problems:
+
+       Minor: The $process_id_directory setting is not used anywhere
+       in Postfix. Problem reported by Michael Smith, texas.net.
+
+       Medium: address rewriting should be configurable for envelopes
+       and headers.
index 35a22a7a4266cc5df40dee714cf2409bd0b9c4d5..410cd7f08424467f8fd8356b15fa7038c77c465c 100644 (file)
@@ -1,16 +1,19 @@
 LINUX PORTABILITY
 =================
 
-On RedHat Linux 7.0, you must install the db3-devel RPM before you
+On RedHat Linux 7.0 you must install the db3-devel RPM before you
 can compile the Postfix source code.
 
+On RedHat Linux 7.1 procmail no longer has permission to write the
+mail spool directory. Workaround: chmod 1777 /var/spool/mail.
+
 LINUX SYSLOGD PERFORMANCE
 =========================
 
-LINUX syslogd uses synchronous writes by default, which is very
-expensive. For services such as mail it is recommended that you
-disable synchronous logfile writes by editing /etc/syslog.conf and
-by prepending a - to the logfile name:
+LINUX syslogd uses synchronous writes by default. Because of this,
+syslogd can actually use more system resources than Postfix.  To
+avoid such madness, disable synchronous mail logfile writes by
+editing /etc/syslog.conf and by prepending a - to the logfile name:
 
     mail.*                          -/var/log/mail.log
 
index b3d204f9fb80a0da1ce167a09a46b5473f977fa4..8f2adc18acc4e33fad39f653f6a8fca91ce125c3 100644 (file)
@@ -1,3 +1,17 @@
+Incompatible changes with snapshot-20011007
+===========================================
+
+Postfix no longer flushes the whole queue after an ETRN request
+for a random domain name. Requests for random domain names are now
+rejected instead.
+
+The permit_mx_backup feature has changed. It accepts mail when the
+local machine is listed in the DNS as MX relay host for the given
+destination. The optional permit_mx_backup_networks parameter can
+further require that the primary MX hosts for the given destinations
+match specific network blocks. This optional restriction is off by
+default.
+
 Incompatible changes with snapshot-20010808
 ===========================================
 
@@ -9,7 +23,8 @@ The permit_mx_backup feature has changed. It now accepts mail only
 when the primary MX hosts for the recipient match the networks that
 are specified with the new auth_mx_backup_networks configuration
 parameter.  Postfix refuses to accept mail when permit_mx_backup
-is used while auth_mx_backup_networks is not configured.
+is used while auth_mx_backup_networks is not configured. [This
+change was undone with a later release].
 
 The protocol between Postfix master and child processes has changed.
 You must stop and start Postfix in order to switch between Snapshot
index ccd3ddaf2a231249217276f36d06b7d23d638f27..a517fc830c635f7b29506194604fcbd53a7bf31e 100644 (file)
@@ -109,7 +109,7 @@ mail_owner = postfix
 # gateway, you should also include $mydomain. Do not specify the
 # names of domains that this machine is backup MX host for. Specify
 # those names via the relay_domains or permit_mx_backup settings for
-# the SMTP server (see sample-smtpd.cf.
+# the SMTP server (see sample-smtpd.cf).
 #
 # The local machine is always the final destination for mail addressed
 # to user@[the.net.work.address] of an interface that the mail system
index 16ca0d37f40022cd89610a8875d280ca3f5406a9..e1d23a60f8d72c16f9dcc6665f19e710b4c068a8 100644 (file)
@@ -175,7 +175,7 @@ max_use = 100
 # gateway, you should also include $mydomain. Do not specify the
 # names of domains that this machine is backup MX host for. Specify
 # those names via the relay_domains or permit_mx_backup settings for
-# the SMTP server (see sample-smtpd.cf.
+# the SMTP server (see sample-smtpd.cf).
 #
 # The local machine is always the final destination for mail addressed
 # to user@[the.net.work.address] of an interface that the mail system
index fc513f145776fa1d9c691969e332e70ecfeb9018..081bcb8b06c9e884c4612335b7f4d02409efd8ef 100644 (file)
@@ -282,8 +282,9 @@ smtpd_sender_restrictions =
 #      - to destinations matching $relay_domains or subdomain thereof,
 #        except for addresses with sender-specified routing.
 #   reject_unauth_pipelining: reject mail from improperly pipelining spamware
-#   permit_mx_backup: accept mail for sites whose primary MX hosts
-#       match the networks specified with auth_mx_backup_networks.
+#   permit_mx_backup: accept mail for sites that list me as MX host.
+#       Use the optional permit_mx_backup_networks parameter to also
+#      require that the primary MX hosts match a list of network blocks.
 #   reject_unknown_recipient_domain: reject domains without A or MX record.
 #   check_recipient_access maptype:mapname
 #   maptype:mapname: look up recipient address, parent domain, or localpart@.
@@ -310,20 +311,6 @@ smtpd_sender_restrictions =
 #
 smtpd_recipient_restrictions = permit_mynetworks,check_relay_domains
 
-# The auth_mx_backup_networks parameter specifies a list of networks 
-# for which the permit_mx_backup feature (see above) can be used.
-#
-# By default, auth_mx_backup_networks is empty and no networks are
-# authorized to use the permit_mx_backup feature.  You can specify
-# a complete class A network (X.0.0.0/8), a complete class B network
-# (X.X.0.0/16), and so on. If you want stricter control, specify a
-# list of network/mask patterns, where the mask specifies the number
-# of bits in the network part of a host address. You can also specify
-# the absolute pathname of a pattern file instead of listing the
-# patterns here.
-#
-auth_mx_backup_networks =
-
 #
 # ADDITIONAL UCE CONTROLS
 #
index 734337f5b69968aa94746ba389c626a5c0f66431..394cb330bafcd414f6a1f8eb4a3e57ee7eae0a82 100644 (file)
@@ -409,7 +409,7 @@ implements its own private mail database system. Not for beginners.
 <p>
 
 <li><a href="http://www.inter7.com/courierimap/">Courier-Imap</a>
-provides POP3, IMAP, POP3 and IMAP, and supports access over SSL.
+provides POP3 and IMAP, and supports access over SSL.
 This software supports the maildir-style mailbox format only
 (one message per file, same format as qmail).
 
@@ -1522,9 +1522,10 @@ reject when the destination is not local.
 
 <li> <a href="uce.html#permit_mx_backup">permit_mx_backup</a>:
 permit if the local system is listed as MX host for the recipient
-domain, provided that the primary MX host for the recipient domain
-is within the networks specified with <a
-href="uce.html#auth_mx_backup_networks">auth_mx_backup_networks</a>.
+domain. Use the optional <a
+href="#permit_mx_backup_networks">permit_mx_backup_networks</a>
+parameter to also require that the primary MX hosts match a list
+of network blocks.
 
 <li> Other UCE restrictions (e.g., SMTPD access maps) are not aware
 of sender-provided routing information.
index 3304cca1912eb857ed3655242ceec05aea9e79c7..dbd2fb0f0b54002fa4d65296dce43faf0fa8933e 100644 (file)
@@ -44,8 +44,8 @@ FLUSH(8)                                                 FLUSH(8)
               undeliverable it will be added back to the logfile.
 
               If the destination is not eligible for a fast flush
-              logfile,  this  request  triggers  delivery  of all
-              queued mail.
+              logfile,  this  request  is rejected (see below for
+              status codes).
 
        <b>TRIGGER</b><i>_</i><b>REQ</b><i>_</i><b>WAKEUP</b>
               This wakeup request from the master is an  alterna-
@@ -82,6 +82,11 @@ FLUSH(8)                                                 FLUSH(8)
        <b>FLUSH</b><i>_</i><b>STAT</b><i>_</i><b>FAIL</b>
               The request failed.
 
+       <b>FLUSH</b><i>_</i><b>STAT</b><i>_</i><b>DENY</b>
+              The  request  was  denied  because  the destination
+              domain is not eligible for fast flush  service,  or
+              because the fast flush service is disabled.
+
 <b>SECURITY</b>
        The  fast  flush server is not security-sensitive. It does
        not talk to the network, and it does  not  talk  to  local
index 80ad4a9ab9abfd34ccadddb15933fc96d1844333..923af8b0cd3f6479ef99dc50876434f308ba5992 100644 (file)
@@ -250,6 +250,11 @@ SMTPD(8)                                                 SMTPD(8)
               List of DNS domains that publish the  addresses  of
               blacklisted hosts.
 
+       <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>
+              <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 or networks this mail system
               will relay mail from or to.
index a7c5a609e111f8d5746e37101858a590e4aa0f80..f2cb60483d34fd7e361ffa201545d58dac90029d 100644 (file)
@@ -146,6 +146,14 @@ clients this system accepts SMTP connections from.
 
 <p>
 
+By default, this restriction is applied when the client sends the
+RCPT TO command. In order to have the restriction take effect
+as soon as possible, specify <b>smtpd_delay_reject = yes</b> in
+the Postfix <b>main.cf</b> configuration file. Doing so may cause
+unexpected results with poorly implemented client software.
+
+<p>
+
 <dl>
 
 <dt>Default:
@@ -280,6 +288,14 @@ The <b>smtpd_helo_restrictions</b> parameter restricts what hostnames
 clients may send with the <b>HELO</b> (<b>EHLO</b>) command.  Some
 UCE software can be stopped by being strict here.
 
+<p>
+
+By default, this restriction is applied when the client sends the
+RCPT TO command. In order to have the restriction take effect
+as soon as possible, specify <b>smtpd_delay_reject = yes</b> in
+the Postfix <b>main.cf</b> configuration file. Doing so may cause
+unexpected results with poorly implemented client software.
+
 <dl>
 
 <dt>Default:
@@ -443,6 +459,14 @@ addresses this system accepts in MAIL FROM commands.
 
 <p>
 
+By default, this restriction is applied when the client sends the
+RCPT TO command. In order to have the restriction take effect
+as soon as possible, specify <b>smtpd_delay_reject = yes</b> in
+the Postfix <b>main.cf</b> configuration file. Doing so may cause
+unexpected results with poorly implemented client software.
+
+<p>
+
 <dl>
 
 <dt> Default:
@@ -722,9 +746,7 @@ code for rejected requests (default:  <b>554</b>).
 <a name="permit_mx_backup">
 
 <dt> <b>permit_mx_backup</b> <dd> Permit the request when the local
-mail system is MX host for the resolved destination, provided that
-the primary MX host is within the networks specified with <a
-href="#auth_mx_backup_networks">auth_mx_backup_networks</a> parameter.
+mail system is MX host for the resolved destination. 
 This includes the case that the local mail system is the final
 destination.  However, the SMTP server will not forward mail with
 addresses that have sender-specified routing information (example:
@@ -732,9 +754,15 @@ addresses that have sender-specified routing information (example:
 
 <p>
 
+Use the optional <a href="#permit_mx_backup_networks">
+permit_mx_backup_networks</a> parameter to also require that the
+primary MX hosts match a list of network blocks.
+
+<p>
+
 Relevant configuration parameters:  <a
-href="#auth_mx_backup_networks">auth_mx_backup_networks</a>, <a
-href="basic.html#mydestination"> $mydestination</a>, <a
+href="#permit_mx_backup_networks">permit_mx_backup_networks</a>,
+<a href="basic.html#mydestination"> $mydestination</a>, <a
 href="basic.html#inet_interfaces"> $inet_interfaces</a>.
 
 <p>
@@ -969,13 +997,13 @@ to speed up deliveries.
 
 <dl>
 
-<a name="auth_mx_backup_networks">
+<a name="permit_mx_backup_networks">
 
-<dt> <b>auth_mx_backup_networks</b>
+<dt> <b>permit_mx_backup_networks</b>
 
-<dd>This parameter specifies the networks that are allowed to
-use the <a href="#permit_mx_backup">permit_mx_backup</a>
-relay control feature.
+<dd>Restrict the use of the <a href="#permit_mx_backup">
+permit_mx_backup</a> relay control feature to destinations whose
+primary MX hosts match a list of network blocks.
 
 <p>
 
@@ -983,11 +1011,11 @@ relay control feature.
 
 <dt>Default:
 
-<dd><b>auth_mx_backup_networks = </b>
+<dd><b>permit_mx_backup_networks = </b>
 
 <p>
 
-That is, no networks are authorized by default.
+That is, all networks are authorized by default.
 
 <p>
 
@@ -1000,7 +1028,7 @@ blocks in CIDR (network/mask) notation, for example:
 
 <dl>
 
-<dd> <b>auth_mx_backup_networks = 168.100.0.0/16</b>
+<dd> <b>permit_mx_backup_networks = 168.100.0.0/16</b>
 
 </dl>
 
index fc05109a3d7c1dc1d87114232df9fc05789ecd19..831e8ccd58303dc6de2eb9ba90b30e3c91ba1a00 100644 (file)
@@ -93,6 +93,8 @@ case "$SYSTEM.$RELEASE" in
                ;;
   OpenBSD.2*)  SYSTYPE=OPENBSD2
                ;;
+  OpenBSD.3*)  SYSTYPE=OPENBSD3
+               ;;
    NetBSD.1*)  SYSTYPE=NETBSD1
                ;;
    BSD/OS.2*)  SYSTYPE=BSDI2
index 57eb598cec113775966eb21cc143b9e3872751ff..f11f4854b5ef02d845ca28180d60c77599899736 100644 (file)
@@ -44,7 +44,7 @@ destination's logfile, and the logfile is truncated to zero length;
 if mail is undeliverable it will be added back to the logfile.
 .sp
 If the destination is not eligible for a fast flush logfile,
-this request triggers delivery of all queued mail.
+this request is rejected (see below for status codes).
 .IP \fBTRIGGER_REQ_WAKEUP\fR
 This wakeup request from the master is an alternative way to
 request \fBFLUSH_REQ_REFRESH\fR.
@@ -72,6 +72,10 @@ The flush server rejected the request (bad request name, bad
 request parameter value).
 .IP \fBFLUSH_STAT_FAIL\fR
 The request failed.
+.IP \fBFLUSH_STAT_DENY\fR
+The request was denied because the destination domain is not
+eligible for fast flush service, or because the fast flush
+service is disabled.
 .SH SECURITY
 .na
 .nf
index 736c299ece29be3325e22dc1a98bf50d45b264e7..b69bb213230858d8d2529dd695d56218335b9e6f 100644 (file)
@@ -209,6 +209,9 @@ then be used instead of the restriction lists that they represent.
 .IP \fBmaps_rbl_domains\fR
 List of DNS domains that publish the addresses of blacklisted
 hosts.
+.IP \fBpermit_mx_backup_networks\fR
+Only domains whose primary MX hosts match the listed networks
+are eligible for the \fBpermit_mx_backup\fR feature.
 .IP \fBrelay_domains\fR
 Restrict what domains or networks this mail system will relay
 mail from or to.
index efa68ce4988077f933288d4566a0e77af6ebe960..599d516f8c31d7bc0be403c3bb4ea98e1069ac08 100644 (file)
@@ -339,7 +339,7 @@ int     bounce_boilerplate(VSTREAM *bounce, BOUNCE_INFO *bounce_info)
                        "####################################################################");
        post_mail_fputs(bounce, "");
        post_mail_fprintf(bounce,
-                       "Your message could not be delivered for %.1f hours.",
+                     "Your message could not be delivered for %.1f hours.",
                          var_delay_warn_time / 3600.0);
        post_mail_fprintf(bounce,
                          "It will be retried until it is %.1f days old.",
@@ -478,7 +478,7 @@ int     bounce_recipient_dsn(VSTREAM *bounce, BOUNCE_INFO *bounce_info)
 #endif
     if (bounce_info->flush == 0)
        post_mail_fprintf(bounce, "Will-Retry-Until: %s",
-        mail_date(bounce_info->arrival_time + var_max_queue_time));
+                mail_date(bounce_info->arrival_time + var_max_queue_time));
     return (vstream_ferror(bounce));
 }
 
@@ -547,12 +547,16 @@ int     bounce_original(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
        if (var_bounce_limit == 0 || bounce_length < var_bounce_limit) {
            bounce_length += VSTRING_LEN(bounce_info->buf) + 2;
            status = (REC_PUT_BUF(bounce, rec_type, bounce_info->buf) != rec_type);
-       }
+       } else
+           break;
     }
 
     /*
      * Final MIME headers. These require -- at the end of the boundary
      * string.
+     * 
+     * XXX This should be a separate bounce_terminate() entry so we can be
+     * assured that the terminator will always be sent.
      */
     post_mail_fputs(bounce, "");
     post_mail_fprintf(bounce, "--%s--", bounce_info->mime_boundary);
index 75d74b513b34a76f00ef2153a157ffcd059a56c7..3ed1de67b0b8530bc3f448711ac537cf7a83a789 100644 (file)
@@ -75,7 +75,6 @@ cleanup.o: ../../include/iostuff.h
 cleanup.o: ../../include/mail_params.h
 cleanup.o: ../../include/record.h
 cleanup.o: ../../include/rec_type.h
-cleanup.o: ../../include/mail_flow.h
 cleanup.o: ../../include/mail_server.h
 cleanup.o: cleanup.h
 cleanup.o: ../../include/maps.h
@@ -154,6 +153,7 @@ cleanup_init.o: cleanup_init.c
 cleanup_init.o: ../../include/sys_defs.h
 cleanup_init.o: ../../include/msg.h
 cleanup_init.o: ../../include/iostuff.h
+cleanup_init.o: ../../include/name_mask.h
 cleanup_init.o: ../../include/mail_addr.h
 cleanup_init.o: ../../include/mail_params.h
 cleanup_init.o: ../../include/ext_prop.h
index c8c76c0d09a1b4c78b22d9909403092be35b786d..5fd7316c3fed99ecadebec9cf6556054f8b79ac1 100644 (file)
@@ -38,7 +38,7 @@
 /*     if mail is undeliverable it will be added back to the logfile.
 /* .sp
 /*     If the destination is not eligible for a fast flush logfile,
-/*     this request triggers delivery of all queued mail.
+/*     this request is rejected (see below for status codes).
 /* .IP \fBTRIGGER_REQ_WAKEUP\fR
 /*     This wakeup request from the master is an alternative way to
 /*     request \fBFLUSH_REQ_REFRESH\fR.
 /*     request parameter value).
 /* .IP \fBFLUSH_STAT_FAIL\fR
 /*     The request failed.
+/* .IP \fBFLUSH_STAT_DENY\fR
+/*     The request was denied because the destination domain is not
+/*     eligible for fast flush service, or because the fast flush
+/*     service is disabled.
 /* SECURITY
 /* .ad
 /* .fi
@@ -243,10 +247,10 @@ static int flush_add_service(const char *site, const char *queue_id)
        msg_info("%s: site %s queue_id %s", myname, site, queue_id);
 
     /*
-     * If this site is not eligible for logging, just ignore the request.
+     * If this site is not eligible for logging, deny the request.
      */
     if (flush_policy_ok(site) == 0)
-       return (FLUSH_STAT_OK);
+       return (FLUSH_STAT_DENY);
 
     /*
      * Map site to path and update log.
@@ -319,10 +323,10 @@ static int flush_send_service(const char *site)
        msg_info("%s: site %s", myname, site);
 
     /*
-     * If this site is not eligible for logging, deliver all queued mail.
+     * If this site is not eligible for logging, deny the request.
      */
     if (flush_policy_ok(site) == 0)
-       return (mail_flush_deferred());
+       return (FLUSH_STAT_DENY);
 
     /*
      * Map site name to path name and flush the log.
index 59cde38fa419d595b81c8fd2c4fca2d56b83db4a..934b289cba92284591ae1445fddd2cdda17bf80d 100644 (file)
@@ -158,8 +158,14 @@ int     vdefer_append(int flags, const char *id, const char *recipient,
      * bounce/defer daemon? Well, doing it here is more robust.
      */
     if ((rcpt_domain = strrchr(recipient, '@')) != 0 && *++rcpt_domain != 0)
-       if (flush_add(rcpt_domain, id) != FLUSH_STAT_OK)
+       switch (flush_add(rcpt_domain, id)) {
+       case FLUSH_STAT_OK:
+       case FLUSH_STAT_DENY:
+           break;
+       default:
            msg_warn("unable to talk to fast flush service");
+           break;
+       }
 
     return (-1);
 }
index 6de4b426de828459bdc77b94b6e386bd4eae305d..b8f92dd69e89ac586a38c010a51e5957446674e2 100644 (file)
@@ -46,6 +46,8 @@
 /* .IP MAIL_FLUSH_BAD
 /*     The "fast flush" server rejected the request (invalid request
 /*     parameter).
+/* .IP MAIL_FLUSH_DENY
+/*     The specified domain is not eligible for "fast flush" service.
 /* SEE ALSO
 /*     flush(8) Postfix fast flush cache manager
 /* LICENSE
@@ -95,7 +97,7 @@ int     flush_purge(void)
      * Don't bother the server if the service is turned off.
      */
     if (*var_fflush_domains == 0)
-       status = FLUSH_STAT_OK;
+       status = FLUSH_STAT_DENY;
     else
        status = mail_command_write(MAIL_CLASS_PRIVATE, MAIL_SERVICE_FLUSH,
                                    "%s", FLUSH_REQ_PURGE);
@@ -120,7 +122,7 @@ int     flush_refresh(void)
      * Don't bother the server if the service is turned off.
      */
     if (*var_fflush_domains == 0)
-       status = FLUSH_STAT_OK;
+       status = FLUSH_STAT_DENY;
     else
        status = mail_command_write(MAIL_CLASS_PRIVATE, MAIL_SERVICE_FLUSH,
                                    "%s", FLUSH_REQ_REFRESH);
@@ -145,7 +147,7 @@ int     flush_send(const char *site)
      * Don't bother the server if the service is turned off.
      */
     if (*var_fflush_domains == 0)
-       status = mail_flush_deferred();
+       status = FLUSH_STAT_DENY;
     else
        status = mail_command_write(MAIL_CLASS_PRIVATE, MAIL_SERVICE_FLUSH,
                                    "%s %s", FLUSH_REQ_SEND, site);
@@ -170,7 +172,7 @@ int     flush_add(const char *site, const char *queue_id)
      * Don't bother the server if the service is turned off.
      */
     if (*var_fflush_domains == 0)
-       status = FLUSH_STAT_OK;
+       status = FLUSH_STAT_DENY;
     else
        status = mail_command_write(MAIL_CLASS_PRIVATE, MAIL_SERVICE_FLUSH,
                                 "%s %s %s", FLUSH_REQ_ADD, site, queue_id);
index 47a88558a536a370ee1d9b223103ecc8dddda4a4..ee82a984cb4655de5e6e97aa4965a4be0770711b 100644 (file)
@@ -33,6 +33,7 @@ extern int flush_purge(void);
 #define FLUSH_STAT_FAIL                -1      /* request failed */
 #define FLUSH_STAT_OK          0       /* request executed */
 #define FLUSH_STAT_BAD         3       /* invalid parameter */
+#define FLUSH_STAT_DENY                4       /* request denied */
 
 
 /* LICENSE
index 5146eb080e3e4f2b513fb6d42d5a8cfdcb49c242..258ea8740c3c15ca64970038124c3951f9bd6809 100644 (file)
@@ -68,6 +68,7 @@
 /* Application-specific. */
 
 #define STR    vstring_str
+#define LEN    VSTRING_LEN
 
 /* mail_addr_map - map a canonical address */
 
@@ -88,7 +89,8 @@ ARGV   *mail_addr_map(MAPS *path, const char *address, int propagate)
     if ((string = mail_addr_find(path, address, &extension)) != 0) {
 
        /*
-        * Prepend the original user to @otherdomain.
+        * Prepend the original user to @otherdomain, but do not propagate
+        * the unmatched address extension.
         */
        if (*string == '@') {
            buffer = vstring_alloc(100);
@@ -96,6 +98,8 @@ ARGV   *mail_addr_map(MAPS *path, const char *address, int propagate)
                vstring_strncpy(buffer, address, ratsign - address);
            else
                vstring_strcpy(buffer, address);
+           if (extension)
+               vstring_truncate(buffer, LEN(buffer) - strlen(extension));
            vstring_strcat(buffer, string);
            string = STR(buffer);
        }
@@ -163,6 +167,15 @@ int     main(int argc, char **argv)
        msg_fatal("chdir %s: %m", var_queue_dir);
     path = maps_create(argv[0], argv[1], DICT_FLAG_LOCK);
     while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
+       msg_info("=== Address extension on, extension propagation on ===");
+       var_rcpt_delim = "+";
+       if ((result = mail_addr_map(path, STR(buffer), 1)) != 0)
+           argv_free(result);
+       msg_info("=== Address extension on, extension propagation off ===");
+       if ((result = mail_addr_map(path, STR(buffer), 0)) != 0)
+           argv_free(result);
+       msg_info("=== Address extension off ===");
+       var_rcpt_delim = "";
        if ((result = mail_addr_map(path, STR(buffer), 1)) != 0)
            argv_free(result);
     }
index 655ebd2606927205b7b5658b2aca0fe70607cb3a..36aef3c73d244e8e7291f81a23cbc5d5e886664e 100644 (file)
@@ -1122,9 +1122,9 @@ extern int var_relay_code;
 
 #define PERMIT_MX_BACKUP       "permit_mx_backup"
 
-#define VAR_AUTH_MX_NETWORKS   "auth_mx_backup_networks"
-#define DEF_AUTH_MX_NETWORKS   ""
-extern char *var_auth_mx_networks;
+#define VAR_PERM_MX_NETWORKS   "permit_mx_backup_networks"
+#define DEF_PERM_MX_NETWORKS   ""
+extern char *var_perm_mx_networks;
 
 #define VAR_ACCESS_MAP_CODE    "access_map_reject_code"
 #define DEF_ACCESS_MAP_CODE    554
index b088beb5ab913cba862afdd39e304ec763d82827..6ecf22dbea8afa78752ab41ccc5eb96bdaf8c8be 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-20010808"
+#define DEF_MAIL_VERSION       "Snapshot-20011006"
 extern char *var_mail_version;
 
 /* LICENSE
index 3b1fbb3b3e95fe90eca8d7b676cdc2602b770d0b..279ad4fb697cfa66f21c2c2844fc8e12a52fbe8f 100644 (file)
@@ -76,7 +76,8 @@ char   *split_addr(char *localpart, int delimiter)
     }
 
     /*
-     * Safe to split this address.
+     * Safe to split this address. Do not split the address if the result
+     * would have a null localpart.
      */
-    return (split_at(localpart, delimiter));
+    return (delimiter == *localpart ? 0 : split_at(localpart, delimiter));
 }
index 1d6b8024f6efa1fec65538e66fa5a7e51090d9a1..ddf61ea7373bedb64199b3587f42117aed0e96d9 100644 (file)
@@ -75,6 +75,7 @@ qmgr.o: ../../include/mail_conf.h
 qmgr.o: ../../include/mail_params.h
 qmgr.o: ../../include/mail_proto.h
 qmgr.o: ../../include/iostuff.h
+qmgr.o: ../../include/mail_flow.h
 qmgr.o: ../../include/master_proto.h
 qmgr.o: ../../include/mail_server.h
 qmgr.o: qmgr.h
index af43366915285a5983cbff9c220e40d4f8ed497e..5177125ace30f078415234125f146c04db1d63ba 100644 (file)
@@ -337,6 +337,7 @@ static int delete_one(const char **queue_names, const char *queue_id)
                postremove(mail_queue_path(log_path_buf, *log_qpp, queue_id));
            if (postremove(msg_path) == 0) {
                found = 1;
+               msg_info("%s: removed", queue_id);
                break;
            }                                   /* else: maybe lost a race */
        }
@@ -381,6 +382,7 @@ static int requeue_one(const char **queue_names, const char *queue_id)
                continue;
            (void) mail_queue_path(new_path_buf, MAIL_QUEUE_MAILDROP, queue_id);
            if (postrename(old_path, STR(new_path_buf)) == 0) {
+               msg_info("%s: requeued", queue_id);
                found = 1;
                break;
            }                                   /* else: maybe lost a race */
index ae85a5f2095de20e1e0b2ce60ad6f65084fe3763..eaddb56f53e7a1e8793d64dc6332bc1e5e3a3690 100644 (file)
@@ -73,6 +73,7 @@ qmgr.o: ../../include/mail_conf.h
 qmgr.o: ../../include/mail_params.h
 qmgr.o: ../../include/mail_proto.h
 qmgr.o: ../../include/iostuff.h
+qmgr.o: ../../include/mail_flow.h
 qmgr.o: ../../include/master_proto.h
 qmgr.o: ../../include/mail_server.h
 qmgr.o: qmgr.h
index 4e0eaefb10752dfb91d15c729a6d815ab9fe11cc..113a6c30ca2bd14366a4388de73fe5bbf38ef76d 100644 (file)
 /* .IP \fBmaps_rbl_domains\fR
 /*     List of DNS domains that publish the addresses of blacklisted
 /*     hosts.
+/* .IP \fBpermit_mx_backup_networks\fR
+/*     Only domains whose primary MX hosts match the listed networks
+/*     are eligible for the \fBpermit_mx_backup\fR feature.
 /* .IP \fBrelay_domains\fR
 /*     Restrict what domains or networks this mail system will relay
 /*     mail from or to.
@@ -356,7 +359,7 @@ char   *var_smtpd_sasl_opts;
 char   *var_smtpd_sasl_realm;
 char   *var_filter_xport;
 bool    var_broken_auth_clients;
-char   *var_auth_mx_networks;
+char   *var_perm_mx_networks;
 
  /*
   * Global state, for stand-alone mode queue file cleanup. When this is
@@ -1227,6 +1230,12 @@ static int etrn_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
     case FLUSH_STAT_OK:
        smtpd_chat_reply(state, "250 Queuing started");
        return (0);
+    case FLUSH_STAT_DENY:
+       msg_warn("reject: ETRN %.100s... from %s",
+                argv[1].strval, state->namaddr);
+       smtpd_chat_reply(state, "459 <%s>: service unavailable",
+                        argv[1].strval);
+       return (-1);
     case FLUSH_STAT_BAD:
        msg_warn("bad ETRN %.100s... from %s", argv[1].strval, state->namaddr);
        smtpd_chat_reply(state, "458 Unable to queue messages");
@@ -1591,7 +1600,7 @@ int     main(int argc, char **argv)
        VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0,
        VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 1, 0,
        VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0,
-       VAR_AUTH_MX_NETWORKS, DEF_AUTH_MX_NETWORKS, &var_auth_mx_networks, 0, 0,
+       VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks, 0, 0,
        0,
     };
 
index f29b7204c4974acdbd0064056ac6e08e6f7b472a..15d0e10e6ed33582b19eddef7ca3580d646023db 100644 (file)
@@ -337,7 +337,7 @@ static MAPS *relocated_maps;
   */
 static DOMAIN_LIST *relay_domains;
 static NAMADR_LIST *mynetworks;
-static NAMADR_LIST *auth_mx_networks;
+static NAMADR_LIST *perm_mx_networks;
 
  /*
   * Pre-parsed restriction lists.
@@ -506,7 +506,7 @@ void    smtpd_check_init(void)
      */
     mynetworks = namadr_list_init(var_mynetworks);
     relay_domains = domain_list_init(var_relay_domains);
-    auth_mx_networks = namadr_list_init(var_auth_mx_networks);
+    perm_mx_networks = namadr_list_init(var_perm_mx_networks);
 
     /*
      * Pre-parse and pre-open the recipient maps.
@@ -1058,7 +1058,7 @@ static int all_auth_mx_addr(char *host)
        if (msg_verbose)
            msg_info("%s: checking: %s", myname, inet_ntoa(addr));
 
-       if (!namadr_list_match(auth_mx_networks, host, inet_ntoa(addr))) {
+       if (!namadr_list_match(perm_mx_networks, host, inet_ntoa(addr))) {
 
            /*
             * Reject: at least one IP address is not listed in
@@ -1066,7 +1066,7 @@ static int all_auth_mx_addr(char *host)
             */
            if (msg_verbose)
                msg_info("%s: address %s does not match %s",
-                        myname, inet_ntoa(addr), VAR_AUTH_MX_NETWORKS);
+                        myname, inet_ntoa(addr), VAR_PERM_MX_NETWORKS);
            dns_rr_free(addr_list);
            return (NOPE);
        }
@@ -1116,137 +1116,92 @@ static int has_my_addr(const char *host)
     return (NOPE);
 }
 
-#if 0
-
-/* permit_mx_backup - permit use of me as MX backup for recipient domain */
+/* i_am_mx - is this machine listed as MX relay */
 
-static int permit_mx_backup(SMTPD_STATE *state, const char *recipient)
+static int i_am_mx(DNS_RR *mx_list)
 {
-    char   *myname = "permit_mx_backup";
-    const RESOLVE_REPLY *reply;
-    const char *domain;
-
-    DNS_RR *mx_list;
+    const char *myname = "permit_mx_backup";
     DNS_RR *mx;
-    int     dns_status;
-
-    if (msg_verbose)
-       msg_info("%s: %s", myname, recipient);
 
     /*
-     * Resolve the address.
+     * Compare hostnames first. Only if no name match is found, go through
+     * the trouble of host address lookups.
      */
-    reply = (const RESOLVE_REPLY *)
-       ctable_locate(smtpd_resolve_cache, recipient);
+    for (mx = mx_list; mx != 0; mx = mx->next) {
+       if (msg_verbose)
+           msg_info("%s: resolve hostname: %s", myname, (char *) mx->data);
+       if (resolve_local((char *) mx->data))
+           return (YUP);
+    }
 
     /*
-     * If the destination is local, it is acceptable, because we are
-     * supposedly MX for our own address.
+     * Argh. Do further DNS lookups and match interface addresses.
      */
-    if ((domain = strrchr(CONST_STR(reply->recipient), '@')) == 0)
-       return (SMTPD_CHECK_OK);
-    domain += 1;
-    if (resolve_local(domain)
-       || (*var_virtual_maps
-           && check_maps_find(state, recipient, virtual_maps, domain, 0))
-       || (*var_virt_mailbox_maps
-       && check_maps_find(state, recipient, virt_mailbox_maps, domain, 0)))
-       return (SMTPD_CHECK_OK);
-
-    if (msg_verbose)
-       msg_info("%s: not local: %s", myname, recipient);
+    for (mx = mx_list; mx != 0; mx = mx->next) {
+       if (msg_verbose)
+           msg_info("%s: address lookup: %s", myname, (char *) mx->data);
+       if (has_my_addr((char *) mx->data))
+           return (YUP);
+    }
 
     /*
-     * Skip source-routed mail (uncertain destination).
+     * This machine is not listed as MX relay.
      */
-    if (var_allow_untrust_route == 0 && (reply->flags & RESOLVE_FLAG_ROUTED))
-       return (SMTPD_CHECK_DUNNO);
+    if (msg_verbose)
+       msg_info("%s: I am not listed as MX relay", myname);
+    return (NOPE);
+}
 
-    /*
-     * Skip numerical forms that didn't match the local system.
-     */
-    if (domain[0] == '#'
-       || (domain[0] == '[' && domain[strlen(domain) - 1] == ']'))
-       return (SMTPD_CHECK_DUNNO);
+/* permit_mx_primary - authorize primary MX relays */
+
+static int permit_mx_primary(DNS_RR *mx_list)
+{
+    DNS_RR *mx;
+    int     best_pref;
+    int     status;
 
     /*
-     * Look up the list of MX host names for this domain. If no MX host is
-     * found, perhaps it is a CNAME for the local machine. Clients aren't
-     * supposed to send CNAMEs in SMTP commands, but it happens anyway. If we
-     * can't look up the destination, play safe and assume it is OK.
+     * Find the preference of the primary MX hosts.
      */
-    dns_status = dns_lookup(domain, T_MX, 0, &mx_list,
-                           (VSTRING *) 0, (VSTRING *) 0);
-    if (dns_status == DNS_NOTFOUND)
-       return (has_my_addr(domain) ? SMTPD_CHECK_OK : SMTPD_CHECK_DUNNO);
-    if (dns_status != DNS_OK)
-       return (SMTPD_CHECK_TRYAGAIN);
+    for (best_pref = 0xffff, mx = mx_list; mx != 0; mx = mx->next)
+       if (mx->pref < best_pref)
+           best_pref = mx->pref;
 
     /*
-     * First, see if we match any of the MX host names listed. Only if no
-     * name match is found, go through the trouble of host address lookups.
+     * See if each best MX host has all IP addresses in
+     * permit_mx_backup_networks.
      */
     for (mx = mx_list; mx != 0; mx = mx->next) {
-       if (msg_verbose)
-           msg_info("%s: resolve hostname: %s", myname, (char *) mx->data);
-       if (resolve_local((char *) mx->data)) {
-           dns_rr_free(mx_list);
-           return (SMTPD_CHECK_OK);
+       if (mx->pref != best_pref)
+           continue;
+       switch (status = all_auth_mx_addr((char *) mx->data)) {
+       case TRYAGAIN:
+       case NOPE:
+           return (status);
        }
     }
 
     /*
-     * Argh. Do further DNS lookups and match interface addresses.
+     * All IP addresses of the best MX hosts are within
+     * auth_mx_backup_networks.
      */
-    for (mx = mx_list; mx != 0; mx = mx->next) {
-       if (msg_verbose)
-           msg_info("%s: address lookup: %s", myname, (char *) mx->data);
-       if (has_my_addr((char *) mx->data)) {
-           dns_rr_free(mx_list);
-           return (SMTPD_CHECK_OK);
-       }
-    }
-    if (msg_verbose)
-       msg_info("%s: no match", myname);
-
-    dns_rr_free(mx_list);
-    return (SMTPD_CHECK_DUNNO);
+    return (YUP);
 }
 
-#endif
-
-/* permit_auth_mx_backup - relay for authorized networks */
+/* permit_mx_backup - permit use of me as MX backup for recipient domain */
 
-static int permit_auth_mx_backup(SMTPD_STATE *state, const char *recipient)
+static int permit_mx_backup(SMTPD_STATE *state, const char *recipient)
 {
-    char   *myname = "permit_auth_mx_backup";
+    char   *myname = "permit_mx_backup";
     const RESOLVE_REPLY *reply;
     const char *domain;
 
     DNS_RR *mx_list;
-    DNS_RR *mx;
     int     dns_status;
-    int     best_pref;
 
     if (msg_verbose)
        msg_info("%s: %s", myname, recipient);
 
-    /*
-     * Sanity check.
-     */
-    if (*var_auth_mx_networks == 0) {
-       msg_warn("The %s feature requires that you specify authorized networks",
-                PERMIT_MX_BACKUP);
-       msg_warn("via the %s configuration parameter. See examples",
-                VAR_AUTH_MX_NETWORKS);
-       msg_warn("in the %s/sample-smtpd.cf configuration file.",
-                var_config_dir);
-       longjmp(smtpd_check_buf, smtpd_check_reject(state, MAIL_ERROR_SOFTWARE,
-                                      "%d <%s>: Configuration error in %s",
-                                                   451, recipient,
-                                                   VAR_AUTH_MX_NETWORKS));
-    }
-
     /*
      * Resolve the address.
      */
@@ -1286,7 +1241,8 @@ static int permit_auth_mx_backup(SMTPD_STATE *state, const char *recipient)
     /*
      * Look up the list of MX host names for this domain. If no MX host is
      * found, perhaps it is a CNAME for the local machine. Clients aren't
-     * supposed to send CNAMEs in SMTP commands, but it happens anyway.
+     * supposed to send CNAMEs in SMTP commands, but it happens anyway. If we
+     * can't look up the destination, play safe and assume it is OK.
      */
     dns_status = dns_lookup(domain, T_MX, 0, &mx_list,
                            (VSTRING *) 0, (VSTRING *) 0);
@@ -1296,34 +1252,24 @@ static int permit_auth_mx_backup(SMTPD_STATE *state, const char *recipient)
        return (SMTPD_CHECK_TRYAGAIN);
 
     /*
-     * Find the preference of the primary MX hosts.
+     * First, see if we match any of the MX host names listed.
      */
-    for (best_pref = 0xffff, mx = mx_list; mx != 0; mx = mx->next)
-       if (mx->pref < best_pref)
-           best_pref = mx->pref;
+    if (!i_am_mx(mx_list)) {
+       dns_rr_free(mx_list);
+       return (SMTPD_CHECK_DUNNO);
+    }
 
     /*
-     * See if each best MX host has all IP addresses in
-     * auth_mx_backup_networks.
+     * Optionally, see if the primary MX hosts are in a restricted list of
+     * networks.
      */
-    for (mx = mx_list; mx != 0; mx = mx->next) {
-       if (mx->pref != best_pref)
-           continue;
-       switch (all_auth_mx_addr((char *) mx->data)) {
-       case NOPE:
-           dns_rr_free(mx_list);
-           return (SMTPD_CHECK_DUNNO);
-       case YUP:
-           continue;
-       case TRYAGAIN:
-           dns_rr_free(mx_list);
-           return (SMTPD_CHECK_TRYAGAIN);
-       }
+    if (*var_perm_mx_networks && !permit_mx_primary(mx_list)) {
+       dns_rr_free(mx_list);
+       return (SMTPD_CHECK_DUNNO);
     }
 
     /*
-     * All IP addresses of the best MX hosts are within
-     * auth_mx_backup_networks.
+     * The destination passed all requirements.
      */
     dns_rr_free(mx_list);
     return (SMTPD_CHECK_OK);
@@ -1491,7 +1437,8 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
                 table, value);
        msg_warn("do not specify lookup tables inside SMTPD access maps");
        msg_warn("define a restriction class and specify its name instead");
-       longjmp(smtpd_check_buf, -1);
+       longjmp(smtpd_check_buf, smtpd_check_reject(state, MAIL_ERROR_SOFTWARE,
+                                        "451 Server configuration error"));
     }
 
     /*
@@ -1500,7 +1447,8 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
     if (state->recursion++ > 100) {
        msg_warn("SMTPD access map %s entry %s causes unreasonable recursion",
                 table, value);
-       longjmp(smtpd_check_buf, -1);
+       longjmp(smtpd_check_buf, smtpd_check_reject(state, MAIL_ERROR_SOFTWARE,
+                                        "451 Server configuration error"));
     }
 
     /*
@@ -1826,7 +1774,8 @@ static int reject_maps_rbl(SMTPD_STATE *state)
 
 /* is_map_command - restriction has form: check_xxx_access type:name */
 
-static int is_map_command(const char *name, const char *command, char ***argp)
+static int is_map_command(SMTPD_STATE *state, const char *name,
+                         const char *command, char ***argp)
 {
 
     /*
@@ -1840,7 +1789,8 @@ static int is_map_command(const char *name, const char *command, char ***argp)
        return (0);
     } else if (*(*argp + 1) == 0 || strchr(*(*argp += 1), ':') == 0) {
        msg_warn("restriction %s requires maptype:mapname", command);
-       longjmp(smtpd_check_buf, -1);
+       longjmp(smtpd_check_buf, smtpd_check_reject(state, MAIL_ERROR_SOFTWARE,
+                                        "451 Server configuration error"));
     } else {
        return (1);
     }
@@ -1903,7 +1853,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
            status = reject_unknown_client(state);
        } else if (strcasecmp(name, PERMIT_MYNETWORKS) == 0) {
            status = permit_mynetworks(state);
-       } else if (is_map_command(name, CHECK_CLIENT_ACL, &cpp)) {
+       } else if (is_map_command(state, name, CHECK_CLIENT_ACL, &cpp)) {
            status = check_namadr_access(state, *cpp, state->name, state->addr,
                                         FULL, &found, state->namaddr,
                                         SMTPD_NAME_CLIENT, def_acl);
@@ -1914,7 +1864,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
        /*
         * HELO/EHLO parameter restrictions.
         */
-       else if (is_map_command(name, CHECK_HELO_ACL, &cpp)) {
+       else if (is_map_command(state, name, CHECK_HELO_ACL, &cpp)) {
            if (state->helo_name)
                status = check_domain_access(state, *cpp, state->helo_name,
                                             FULL, &found, state->helo_name,
@@ -1958,7 +1908,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
        /*
         * Sender mail address restrictions.
         */
-       else if (is_map_command(name, CHECK_SENDER_ACL, &cpp)) {
+       else if (is_map_command(state, name, CHECK_SENDER_ACL, &cpp)) {
            if (state->sender && *state->sender)
                status = check_mail_access(state, *cpp, state->sender,
                                           &found, state->sender,
@@ -1980,14 +1930,14 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
        /*
         * Recipient mail address restrictions.
         */
-       else if (is_map_command(name, CHECK_RECIP_ACL, &cpp)) {
+       else if (is_map_command(state, name, CHECK_RECIP_ACL, &cpp)) {
            if (state->recipient)
                status = check_mail_access(state, *cpp, state->recipient,
                                           &found, state->recipient,
                                           SMTPD_NAME_RECIPIENT, def_acl);
        } else if (strcasecmp(name, PERMIT_MX_BACKUP) == 0) {
            if (state->recipient)
-               status = permit_auth_mx_backup(state, state->recipient);
+               status = permit_mx_backup(state, state->recipient);
        } else if (strcasecmp(name, PERMIT_AUTH_DEST) == 0) {
            if (state->recipient)
                status = permit_auth_destination(state, state->recipient);
@@ -2020,7 +1970,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
        /*
         * ETRN domain name restrictions.
         */
-       else if (is_map_command(name, CHECK_ETRN_ACL, &cpp)) {
+       else if (is_map_command(state, name, CHECK_ETRN_ACL, &cpp)) {
            if (state->etrn_name)
                status = check_domain_access(state, *cpp, state->etrn_name,
                                             FULL, &found, state->etrn_name,
@@ -2040,7 +1990,8 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
         */
        else {
            msg_warn("unknown smtpd restriction: \"%s\"", name);
-           break;
+           longjmp(smtpd_check_buf, smtpd_check_reject(state,
+                   MAIL_ERROR_SOFTWARE, "451 Server configuration error"));
        }
        if (msg_verbose)
            msg_info("%s: name=%s status=%d", myname, name, status);
index a06ab7591b93a6495569d096a07908b069340f11..66fd33854e3e8b63a3a597263fb45112fbce2983 100644 (file)
@@ -549,6 +549,7 @@ int     main(int argc, char **argv)
            VSTRING_ADDCH(buffer, 'X');
        VSTRING_ADDCH(buffer, '\n');
     }
+    STR(buffer)[message_length - 1] = '\n';
     netstring_memcpy(message_buffer, STR(buffer), message_length);
 
     n = strlen(sender);
index 81aab916b360b249b3fb28f04b2cb1bc39e1f169..67c9d9f12fa35d135dcfbe02328fc95fdec44d5a 100644 (file)
@@ -77,6 +77,7 @@
 
 typedef struct SINK_STATE {
     VSTREAM *stream;
+    VSTRING *buffer;
     int     data_state;
     int     (*read) (struct SINK_STATE *);
     int     rcpts;
@@ -90,9 +91,8 @@ typedef struct SINK_STATE {
 #define ST_CR_LF_DOT_CR_LF     5
 
 static int var_tmout;
-static int var_max_line_length;
+static int var_max_line_length = 2048;
 static char *var_myhostname;
-static VSTRING *buffer;
 static int command_read(SINK_STATE *);
 static int data_read(SINK_STATE *);
 static void disconnect(SINK_STATE *);
@@ -197,11 +197,10 @@ static int data_read(SINK_STATE *state)
     struct data_trans *dp;
 
     /*
-     * We must avoid blocking I/O, so get out of here as soon as both the
-     * VSTREAM and kernel read buffers dry up.
+     * A read may result in EOF, but is never supposed to time out - a time
+     * out means that we were trying to read when no data was available.
      */
-    while (vstream_peek(state->stream) > 0
-          || peekfd(vstream_fileno(state->stream)) > 0) {
+    for (;;) {
        if ((ch = VSTREAM_GETC(state->stream)) == VSTREAM_EOF)
            return (-1);
        for (dp = data_trans; dp->state != state->data_state; dp++)
@@ -224,8 +223,17 @@ static int data_read(SINK_STATE *state)
                msg_info(".");
            dot_response(state);
            state->read = command_read;
+           state->data_state = ST_ANY;
            break;
        }
+
+       /*
+        * We must avoid blocking I/O, so get out of here as soon as both the
+        * VSTREAM and kernel read buffers dry up.
+        */
+       if (vstream_peek(state->stream) <= 0
+           && peekfd(vstream_fileno(state->stream)) <= 0)
+           return (0);
     }
     return (0);
 }
@@ -258,9 +266,74 @@ static int command_read(SINK_STATE *state)
 {
     char   *command;
     SINK_COMMAND *cmdp;
+    int     ch;
+    struct cmd_trans {
+       int     state;
+       int     want;
+       int     next_state;
+    };
+    static struct cmd_trans cmd_trans[] = {
+       ST_ANY, '\r', ST_CR,
+       ST_CR, '\n', ST_CR_LF,
+    };
+    struct cmd_trans *cp;
+
+    /*
+     * A read may result in EOF, but is never supposed to time out - a time
+     * out means that we were trying to read when no data was available.
+     */
+    for (;;) {
+       if ((ch = VSTREAM_GETC(state->stream)) == VSTREAM_EOF)
+           return (-1);
+
+       /*
+        * Sanity check. We don't want to store infinitely long commands.
+        */
+       if (VSTRING_LEN(state->buffer) >= var_max_line_length) {
+           msg_warn("command line too long");
+           return (-1);
+       }
+       VSTRING_ADDCH(state->buffer, ch);
+
+       /*
+        * Try to match the current character desired by the state machine.
+        * If that fails, try to restart the machine with a match for its
+        * first state.
+        */
+       for (cp = cmd_trans; cp->state != state->data_state; cp++)
+            /* void */ ;
+       if (ch == cp->want)
+           state->data_state = cp->next_state;
+       else if (ch == cmd_trans[0].want)
+           state->data_state = cmd_trans[0].next_state;
+       else
+           state->data_state = ST_ANY;
+       if (state->data_state == ST_CR_LF)
+           break;
+
+       /*
+        * We must avoid blocking I/O, so get out of here as soon as both the
+        * VSTREAM and kernel read buffers dry up.
+        */
+       if (vstream_peek(state->stream) <= 0
+           && peekfd(vstream_fileno(state->stream)) <= 0)
+           return (0);
+    }
 
-    smtp_get(buffer, state->stream, var_max_line_length);
-    if ((command = strtok(vstring_str(buffer), " \t")) == 0) {
+    /*
+     * Properly terminate the result, and reset the buffer write pointer for
+     * reading the next command. This is ugly, but not as ugly as trying to
+     * deal with all the early returns below.
+     */
+    vstring_truncate(state->buffer, VSTRING_LEN(state->buffer) - 2);
+    VSTRING_TERMINATE(state->buffer);
+    state->data_state = ST_ANY;
+    VSTRING_RESET(state->buffer);
+
+    /*
+     * Got a complete command line. Parse it.
+     */
+    if ((command = strtok(vstring_str(state->buffer), " \t")) == 0) {
        smtp_printf(state->stream, "500 Error: unknown command");
        return (0);
     }
@@ -321,6 +394,7 @@ static void disconnect(SINK_STATE *state)
 {
     event_disable_readwrite(vstream_fileno(state->stream));
     vstream_fclose(state->stream);
+    vstring_free(state->buffer);
     myfree((char *) state);
 }
 
@@ -350,8 +424,9 @@ static void connect_event(int unused_event, char *context)
        non_blocking(fd, NON_BLOCKING);
        state = (SINK_STATE *) mymalloc(sizeof(*state));
        state->stream = vstream_fdopen(fd, O_RDWR);
+       state->buffer = vstring_alloc(1024);
        state->read = command_read;
-       state->data_state = 0;
+       state->data_state = ST_ANY;
        smtp_timeout_setup(state->stream, var_tmout);
        smtp_printf(state->stream, "220 %s ESMTP", var_myhostname);
        event_enable_read(fd, read_event, (char *) state);
@@ -409,7 +484,6 @@ int     main(int argc, char **argv)
     /*
      * Initialize.
      */
-    buffer = vstring_alloc(1024);
     var_myhostname = "smtp-sink";
     if (strncmp(argv[optind], "unix:", 5) == 0) {
        sock = unix_listen(argv[optind] + 5, backlog, BLOCKING);
index 9e69fa122a7a06966023b2e3d10d722c7e24425a..be0dff0faa751df44237342d604e6535987d51d0 100644 (file)
@@ -52,6 +52,8 @@
 /* .IP "-w interval"
 /*     Wait a fixed time between messages.
 /*     Suspending one thread does not affect other delivery threads.
+/* BUGS
+/*     No SMTP command pipelining support.
 /* LICENSE
 /* .ad
 /* .fi
@@ -739,7 +741,7 @@ static void quit_done(int unused_event, char *context)
 
 static void usage(char *myname)
 {
-    msg_fatal("usage: %s -s sess -l msglen -m msgs -c -C count -d -f from -o -t to -R delay -v -w delay host[:port]", myname);
+    msg_fatal("usage: %s -s sess -l msglen -m msgs -c -C count -d -f from -o -t to -r rcptcount -R delay -v -w delay host[:port]", myname);
 }
 
 /* main - parse JCL and start the machine */
index 04fa8037a8275143f6aaff296e8e49a7782db331..dd2c9154273d78244401de05c83f57f835261f19 100644 (file)
@@ -200,87 +200,87 @@ fifo_rdonly_bug: fifo_rdonly_bug.c $(LIB)
 select_bug: select_bug.c $(LIB)
        $(CC) $(CFLAGS)  -o $@ $@.c $(LIB) $(SYSLIBS)
 
-translit: $(LIB)
+translit: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-fsspace: $(LIB)
+fsspace: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-exec_command: $(LIB)
+exec_command: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-make_dirs: $(LIB)
+make_dirs: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-mac_parse: $(LIB)
+mac_parse: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-vstream_popen: $(LIB)
+vstream_popen: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-fifo_trigger: $(LIB)
+fifo_trigger: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-doze: $(LIB)
+doze: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-mac_expand: $(LIB)
+mac_expand: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-watchdog: $(LIB)
+watchdog: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-unescape: $(LIB)
+unescape: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-hex_quote: $(LIB)
+hex_quote: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-name_mask: $(LIB)
+name_mask: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-rand_sleep: $(LIB)
+rand_sleep: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-sane_time: $(LIB)
+sane_time: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-ctable: $(LIB)
+ctable: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-inet_addr_list: $(LIB)
+inet_addr_list: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
diff --git a/postfix/src/util/cache.in b/postfix/src/util/cache.in
new file mode 100644 (file)
index 0000000..89974bd
--- /dev/null
@@ -0,0 +1,26 @@
+a
+1
+b
+2
+c
+3
+d
+4
+e
+5
+f
+6
+f
+e
+d
+c
+b
+a
+1
+b
+c
+d
+e
+f
+6
+f
index 04c1fb49ab032875197009374ef974aa62387115..36c7d684ec1d372177df742f5f9675ee00a87d38 100644 (file)
@@ -165,6 +165,8 @@ void    myfree(char *ptr)
 
 char   *mystrdup(const char *str)
 {
+    if (str == 0)
+       msg_panic("mystrdup: null pointer argument");
     return (strcpy(mymalloc(strlen(str) + 1), str));
 }
 
@@ -175,6 +177,8 @@ char   *mystrndup(const char *str, int len)
     char   *result;
     char   *cp;
 
+    if (str == 0)
+       msg_panic("mystrndup: null pointer argument");
     if ((cp = memchr(str, 0, len)) != 0)
        len = cp - str;
     result = memcpy(mymalloc(len + 1), str, len);
@@ -186,5 +190,7 @@ char   *mystrndup(const char *str, int len)
 
 char   *mymemdup(const char *ptr, int len)
 {
+    if (ptr == 0)
+       msg_panic("mymemdup: null pointer argument");
     return (memcpy(mymalloc(len), ptr, len));
 }
index c5bdbfdde1e54da65b6f48a58645d1bf39e72a1f..655bc0a3de6d5aa00ee181427a96545452ee8893 100644 (file)
@@ -97,7 +97,7 @@
 /*     int     vstream_setjmp(stream)
 /*     VSTREAM *stream;
 /*
-/*     void    longjmp(stream, val)
+/*     void    vstream_longjmp(stream, val)
 /*     VSTREAM *stream;
 /*     int     val;
 /*