]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.6-20080207
authorWietse Venema <wietse@porcupine.org>
Thu, 7 Feb 2008 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:33:56 +0000 (06:33 +0000)
20 files changed:
postfix/HISTORY
postfix/Makefile.in
postfix/RELEASE_NOTES
postfix/conf/post-install
postfix/conf/postfix-files
postfix/conf/postfix-script
postfix/html/postfix.1.html
postfix/man/man1/postfix.1
postfix/postfix-install
postfix/src/cleanup/cleanup.c
postfix/src/cleanup/cleanup.h
postfix/src/cleanup/cleanup_milter.c
postfix/src/cleanup/cleanup_state.c
postfix/src/global/cleanup_user.h
postfix/src/global/mail_version.h
postfix/src/milter/milter8.c
postfix/src/milter/test-milter.c
postfix/src/postfix/postfix.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_chat.c

index bc501244027ffeb54ce518efd68c1dd4eca2e0b9..4724653a93c01b4740f448788b9c9114fe3c0506 100644 (file)
@@ -14315,3 +14315,22 @@ Apologies for any names omitted.
        Workaround: pick up a missing data_directory setting from
        main.cf when "postfix start" is invoked with an obsolete
        postfix command. File: conf/post-install.
+
+20080207
+
+       Cleanup: soft_bounce support for multi-line Milter replies.
+       File: src/milter/milter8.c.
+
+       Cleanup: preserve multi-line format of header/body Milter
+       replies. Files: cleanup/cleanup_milter.c, smtpd/smtpd.c.
+
+       Cleanup: nicer multi-line support in the SMTP server.  File:
+       smtpd/smtpd_chat.c.
+
+       SAFETY: postfix-script, postfix-files and post-install are
+       moved away from /etc/postfix to $daemon_directory. There
+       were too many accidents where people clobbered these files
+       with versions from an older Postfix release and ended up
+       with an unusable Postfix setup.  Files: postfix-install,
+       Makefile.in, postfix/postfix.c, conf/postfix-files,
+       conf/postfix-script, conf/post-install.
index 5dadb462ced9e80279d00ddf46e6a44f33d75dd8..6e68539d05a5a197263e2604387cb6a09c84c557 100644 (file)
@@ -10,6 +10,7 @@ DIRS  = src/util src/global src/dns src/tls src/xsasl src/milter src/master \
        src/postsuper src/qmqpd src/spawn src/flush src/verify \
        src/virtual src/proxymap src/anvil src/scache src/discard src/tlsmgr
 MANDIRS        = proto man html
+LIBEXEC        = libexec/post-install libexec/postfix-files libexec/postfix-script
 
 default: update
 
@@ -28,6 +29,17 @@ update printfck tests root_tests:
         (set -e; echo "[$$i]"; cd $$i; $(MAKE) $(OPTS) $@ MAKELEVEL=) || exit 1; \
        done
 
+update: $(LIBEXEC)
+
+libexec/post-install: conf/post-install
+       ln -f $? $@
+
+libexec/postfix-files: conf/postfix-files
+       ln -f $? $@
+
+libexec/postfix-script: conf/postfix-script
+       ln -f $? $@
+
 manpages:
        set -e; for i in $(MANDIRS); do \
         (set -e; echo "[$$i]"; cd $$i; $(MAKE) -f Makefile.in $(OPTS) MAKELEVEL=) || exit 1; \
index 190b2fb498ff3058a2d7797ed360b3ecaa493502..fb9c93e08a6a7dbb620483e922cf8a5d449afe5c 100644 (file)
@@ -16,3 +16,13 @@ Incompatibility with Postfix 2.4 and earlier
 
 If you upgrade from Postfix 2.4 or earlier, read RELEASE_NOTES-2.5
 before proceeding.
+
+Incompatible changes with snapshot 20080207
+===========================================
+
+According to discussions on the mailing list, too many people are
+breaking newly installed Postfix by overwriting the new /etc/postfix
+files with versions from an older release, and end up with a broken
+configuration that cannot repair itself. For this reason, postfix-script,
+postfix-files and post-install are moved away from /etc/postfix to
+$daemon_directory.
index c09fdfa3255574277126645512c821cd7bb96b21..29e3d9616b5417fe11cc88c6015884e726d19068 100644 (file)
@@ -9,7 +9,7 @@
 # SUMMARY
 #      Postfix post-installation script
 # SYNOPSIS
-#      post-install [name=value] command ...
+#      postfix post-install [name=value] command ...
 # DESCRIPTION
 #      The post-install script performs the finishing touch of a Postfix
 #      installation, after the executable programs and configuration
 #      Arguments
 # .IP create-missing
 #      Create missing queue directories with ownerships and permissions
-#      according to the contents of $config_directory/postfix-files, using
+#      according to the contents of $daemon_directory/postfix-files, using
 #      the mail_owner and setgid_group parameter settings from the command
 #      line, process environment or from the installed main.cf file.
 #
 #      This is required at Postfix start-up time.
 # .IP set-permissions
 #      Set all file/directory ownerships and permissions according to the
-#      contents of $config_directory/postfix-files, using the mail_owner
+#      contents of $daemon_directory/postfix-files, using the mail_owner
 #      and setgid_group parameter settings from the command line, process
 #      environment or from the installed main.cf file. Implies create-missing.
 #
@@ -56,7 +56,7 @@
 #      settings after Postfix is already installed.
 # .IP upgrade-permissions
 #      Update ownership and permission of existing files/directories as
-#      specified in $config_directory/postfix-files, using the mail_owner
+#      specified in $daemon_directory/postfix-files, using the mail_owner
 #      and setgid_group parameter settings from the command line, process
 #      environment or from the installed main.cf file. Implies create-missing.
 #
@@ -90,7 +90,7 @@
 #      copy the configuration files from the primary Postfix instance to
 #      a secondary configuration directory and execute:
 #
-#      post-install config_directory=secondary-config-directory \e
+#      postfix post-install config_directory=secondary-config-directory \e
 # .in +4
 #              queue_directory=secondary-queue-directory \e
 # .br
 #      To upgrade a secondary Postfix installation on the same machine,
 #      execute:
 #
-#      post-install config_directory=secondary-config-directory \e
+#      postfix post-install config_directory=secondary-config-directory \e
 # .in +4
 #              upgrade-permissions upgrade-configuration
 # INSTALLATION PARAMETER INPUT METHODS
 #      postfix-install(1) Postfix primary installation script.
 # FILES
 #      $config_directory/main.cf, Postfix installation parameters.
-#      $config_directory/postfix-files, installation control file.
+#      $daemon_directory/postfix-files, installation control file.
 #      $config_directory/install.cf, obsolete configuration file.
 # LICENSE
 # .ad
@@ -258,8 +258,8 @@ test -d "$config_directory" || {
     exit 1
 }
 
-test -f $config_directory/postfix-files || {
-    echo $0: Error: $config_directory/postfix-files is not a file. 1>&2
+test -f $daemon_directory/postfix-files || {
+    echo $0: Error: $daemon_directory/postfix-files is not a file. 1>&2
     exit 1
 }
 
@@ -412,10 +412,10 @@ test -n "$override" && {
     || exit 1
 }
 
-# Use file/directory status information in $config_directory/postfix-files.
+# Use file/directory status information in $daemon_directory/postfix-files.
 
 test -n "$create" && {
-    exec <$config_directory/postfix-files || exit 1
+    exec <$daemon_directory/postfix-files || exit 1
     while IFS=: read path type owner group mode flags junk
     do
        IFS="$BACKUP_IFS"
@@ -429,7 +429,7 @@ test -n "$create" && {
        case $type in
        [hl]) continue;;
        [df]) ;;
-          *) echo unknown type $type for $path in $config_directory/postfix-files1>&2; exit 1;;
+          *) echo unknown type $type for $path in $daemon_directory/postfix-files1>&2; exit 1;;
        esac
        # Expand $name, and canonicalize null fields.
        for name in path owner group flags
index 9bd905f8cd16fe9863d94afc0d00a72cd6b3cddc..f3632a45dd67511656b05519349793f344f274d2 100644 (file)
@@ -62,6 +62,9 @@ $queue_directory/public:d:$mail_owner:$setgid_group:710:uc
 $queue_directory/pid:d:root:-:755:uc
 $queue_directory/saved:d:$mail_owner:-:700:ucr
 $queue_directory/trace:d:$mail_owner:-:700:ucr
+$daemon_directory/postfix-script:f:root:-:755
+$daemon_directory/postfix-files:f:root:-:644
+$daemon_directory/post-install:f:root:-:755
 $daemon_directory/anvil:f:root:-:755
 $daemon_directory/bounce:f:root:-:755
 $daemon_directory/cleanup:f:root:-:755
@@ -118,16 +121,16 @@ $config_directory/main.cf:f:root:-:644:p
 $config_directory/makedefs.out:f:root:-:644
 $config_directory/master.cf:f:root:-:644:p
 $config_directory/pcre_table:f:root:-:644:o
-$config_directory/postfix-files:f:root:-:644
+$config_directory/postfix-files:f:root:-:644:o
 $config_directory/regexp_table:f:root:-:644:o
 $config_directory/relocated:f:root:-:644:p
 $config_directory/tcp_table:f:root:-:644:o
 $config_directory/transport:f:root:-:644:p
 $config_directory/virtual:f:root:-:644:p
-$config_directory/postfix-script:f:root:-:755
+$config_directory/postfix-script:f:root:-:755:o
 $config_directory/postfix-script-sgid:f:root:-:755:o
 $config_directory/postfix-script-nosgid:f:root:-:755:o
-$config_directory/post-install:f:root:-:755
+$config_directory/post-install:f:root:-:755:o
 $manpage_directory/man1/mailq.1:f:root:-:644
 $manpage_directory/man1/newaliases.1:f:root:-:644
 $manpage_directory/man1/postalias.1:f:root:-:644
index 8c1efd789cdbf211b40e4d5b386221c66335ecc5..4635f865c5caf9cc86849927da345040d791595f 100644 (file)
@@ -94,12 +94,12 @@ start)
        then
                rm -f $queue_directory/quick-start
        else
-               $config_directory/postfix-script check-fatal || {
+               $daemon_directory/postfix-script check-fatal || {
                        $FATAL Postfix integrity check failed!
                        exit 1
                }
                # Foreground this so it can be stopped. All inodes are cached.
-               $config_directory/postfix-script check-warn
+               $daemon_directory/postfix-script check-warn
        fi
        $INFO starting the Postfix mail system
        $daemon_directory/master &
@@ -117,7 +117,7 @@ drain)
 
 quick-stop)
 
-       $config_directory/postfix-script stop
+       $daemon_directory/postfix-script stop
        touch $queue_directory/quick-start
        ;;
 
@@ -173,8 +173,8 @@ flush)
 
 check)
 
-       $config_directory/postfix-script check-fatal || exit 1
-       $config_directory/postfix-script check-warn
+       $daemon_directory/postfix-script check-fatal || exit 1
+       $daemon_directory/postfix-script check-warn
        exit 0
        ;;
 
@@ -192,7 +192,7 @@ status)
 check-fatal)
        # This command is NOT part of the public interface.
 
-       $SHELL $config_directory/post-install create-missing || {
+       $SHELL $daemon_directory/post-install create-missing || {
                $FATAL unable to create missing queue directories
                exit 1
        }
@@ -283,13 +283,13 @@ check-warn)
        ;;
 
 set-permissions|upgrade-configuration)
-       $config_directory/post-install create-missing "$@"
+       $daemon_directory/post-install create-missing "$@"
        ;;
 
 post-install)
        # Currently not part of the public interface.
        shift
-       $config_directory/post-install "$@"
+       $daemon_directory/post-install "$@"
        ;;
 
 /*)
index cd1f1e3decf144774f6abbb311ee523a7b4e6ef1..f31564ebfc351788a2d4705ac7059bbccc94cb48 100644 (file)
@@ -201,9 +201,9 @@ POSTFIX(1)                                                          POSTFIX(1)
 <b>FILES</b>
        /etc/postfix/<a href="postconf.5.html">main.cf</a>, Postfix configuration parameters
        /etc/postfix/<a href="master.5.html">master.cf</a>, Postfix daemon processes
-       /etc/postfix/postfix-files, file/directory permissions
-       /etc/postfix/postfix-script, administrative commands
-       /etc/postfix/post-install, post-installation configuration
+       $<a href="postconf.5.html#daemon_directory">daemon_directory</a>/postfix-files, file/directory permissions
+       $<a href="postconf.5.html#daemon_directory">daemon_directory</a>/postfix-script, administrative commands
+       $<a href="postconf.5.html#daemon_directory">daemon_directory</a>/post-install, post-installation configuration
 
 <b>SEE ALSO</b>
        Commands:
index 4d46606e9e73da50b45c4ee18080669a82a997ca..72918c6276784353c7095f417ffe4567abf015d4 100644 (file)
@@ -164,9 +164,9 @@ records, so that "smtpd" becomes, for example, "postfix/smtpd".
 .nf
 /etc/postfix/main.cf, Postfix configuration parameters
 /etc/postfix/master.cf, Postfix daemon processes
-/etc/postfix/postfix-files, file/directory permissions
-/etc/postfix/postfix-script, administrative commands
-/etc/postfix/post-install, post-installation configuration
+$daemon_directory/postfix-files, file/directory permissions
+$daemon_directory/postfix-script, administrative commands
+$daemon_directory/post-install, post-installation configuration
 .SH "SEE ALSO"
 .na
 .nf
index b8286a5d46d67ebad0c9cf91588b60827f59c965..f936b81a02bcd8f1c2d0b5ec36c89600752683d4 100644 (file)
 #      post-install(1) post-installation procedure
 # FILES
 #      $config_directory/main.cf, Postfix installation configuration.
-#      $config_directory/postfix-files, installation control file.
+#      $daemon_directory/postfix-files, installation control file.
 #      $config_directory/install.cf, obsolete configuration file.
 # LICENSE
 # .ad
@@ -586,7 +586,7 @@ fi
 
 # Install files, using information from the postfix-files file.
 
-exec < conf/postfix-files || exit 1
+exec < libexec/postfix-files || exit 1
 while IFS=: read path type owner group mode flags junk
 do
     IFS="$BACKUP_IFS"
@@ -682,7 +682,7 @@ do
            test "$readme_directory" = "no" ||
                compare_or_replace $mode "$owner" "$group" README_FILES/$file \
                    $README_DIRECTORY/$file || exit 1;;
-        *) echo $0: Error: unknown entry $path in conf/postfix-files 1>&2
+        *) echo $0: Error: unknown entry $path in libexec/postfix-files 1>&2
            exit 1;;
        esac) || exit 1
        continue;;
@@ -713,7 +713,7 @@ do
        ) || exit 1
        continue;;
 
-     *) echo $0: Error: unknown type $type for $path in conf/postfix-files 1>&2
+     *) echo $0: Error: unknown type $type for $path in libexec/postfix-files 1>&2
        exit 1;;
     esac
 
index 577aa0a032c5bef5c784c760e387f5d0e93eafb3..a281ed553a47148f441332de60d75507a801ce94 100644 (file)
@@ -491,8 +491,10 @@ static void cleanup_service(VSTREAM *src, char *unused_service, char **argv)
     status = cleanup_flush(state);             /* in case state is modified */
     attr_print(src, ATTR_FLAG_NONE,
               ATTR_TYPE_INT, MAIL_ATTR_STATUS, status,
-              ATTR_TYPE_STR, MAIL_ATTR_WHY, state->reason ?
-              state->reason : "",
+              ATTR_TYPE_STR, MAIL_ATTR_WHY,
+              (state->flags & CLEANUP_FLAG_SMTP_REPLY)
+              && state->smtp_reply ? state->smtp_reply :
+              state->reason ? state->reason : "",
               ATTR_TYPE_END);
     cleanup_free(state);
 
index 500d31f5c009f4964ae396a7a265b4cfe084b925..e56511453a4b92190a3a9ad6255d351ea38c9bbd 100644 (file)
@@ -78,6 +78,7 @@ typedef struct CLEANUP_STATE {
     off_t   append_hdr_pt_target;      /* target of above record */
     ssize_t rcpt_count;                        /* recipient count */
     char   *reason;                    /* failure reason */
+    char   *smtp_reply;                        /* failure reason, SMTP-style */
     NVTABLE *attr;                     /* queue file attribute list */
     MIME_STATE *mime_state;            /* MIME state engine */
     int     mime_errs;                 /* MIME error flags */
@@ -121,6 +122,29 @@ typedef struct CLEANUP_STATE {
 #define CLEANUP_FLAG_WARN_SEEN (1<<17) /* REC_TYPE_WARN record seen */
 #define CLEANUP_FLAG_END_SEEN  (1<<18) /* REC_TYPE_END record seen */
 
+ /*
+  * Milter replies.
+  */
+#define CLEANUP_MILTER_REASON(__state, __reason) do { \
+       if ((__state)->reason) \
+           myfree((__state)->reason); \
+       (__state)->reason = mystrdup(__reason); \
+       if ((__state)->smtp_reply) { \
+           myfree((__state)->smtp_reply); \
+           (__state)->smtp_reply = 0; \
+       } \
+    } while (0)
+
+#define CLEANUP_MILTER_SMTP_REPLY(__state, __smtp_reply) do { \
+       if ((__state)->reason) \
+           myfree((__state)->reason); \
+       (__state)->reason = mystrdup(__smtp_reply + 4); \
+       printable((__state)->reason, '_'); \
+       if ((__state)->smtp_reply) \
+           myfree((__state)->smtp_reply); \
+       (__state)->smtp_reply = mystrdup(__smtp_reply); \
+    } while (0)
+
  /*
   * Mappings.
   */
index 7a76c52efe8eb5d6e34b7457ba950ae573602a2f..7c5fc939325deccf2e8434fa5e23b8a9563aa780 100644 (file)
@@ -1402,25 +1402,17 @@ static const char *cleanup_milter_apply(CLEANUP_STATE *state, const char *event,
         * CLEANUP_STAT_CONT and CLEANUP_STAT_DEFER both update the reason
         * attribute, but CLEANUP_STAT_DEFER takes precedence. It terminates
         * queue record processing, and prevents bounces from being sent.
-        * 
-        * XXX Multi-line replies are messy, We should eliminate not only the
-        * CRLF, but also the SMTP status and the enhanced status code that
-        * follows.
         */
     case '4':
-       if (state->reason)
-           myfree(state->reason);
-       ret = state->reason = mystrdup(resp + 4);
-       printable(state->reason, '_');
+       CLEANUP_MILTER_SMTP_REPLY(state, resp);
+       ret = state->reason;
        state->errs |= CLEANUP_STAT_DEFER;
        action = "milter-reject";
        text = resp + 4;
        break;
     case '5':
-       if (state->reason)
-           myfree(state->reason);
-       ret = state->reason = mystrdup(resp + 4);
-       printable(state->reason, '_');
+       CLEANUP_MILTER_SMTP_REPLY(state, resp);
+       ret = state->reason;
        state->errs |= CLEANUP_STAT_CONT;
        action = "milter-reject";
        text = resp + 4;
@@ -1596,9 +1588,7 @@ void    cleanup_milter_emul_rcpt(CLEANUP_STATE *state,
        msg_warn("%s: milter configuration error: can't reject recipient "
                 "in non-smtpd(8) submission", state->queue_id);
        msg_warn("%s: deferring delivery of this message", state->queue_id);
-       if (state->reason)
-           myfree(state->reason);
-       state->reason = mystrdup("4.3.5 Server configuration error");
+       CLEANUP_MILTER_REASON(state, "4.3.5 Server configuration error");
        state->errs |= CLEANUP_STAT_DEFER;
     }
 }
index 9e584a66078bad8e5a1b93162603bd8eccd2bed7..ea8b13b1199faaecbb2e0d70f68de4e743d49e21 100644 (file)
@@ -97,6 +97,7 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src)
     state->append_hdr_pt_target = -1;
     state->rcpt_count = 0;
     state->reason = 0;
+    state->smtp_reply = 0;
     state->attr = nvtable_create(10);
     nvtable_update(state->attr, MAIL_ATTR_LOG_ORIGIN, MAIL_ATTR_ORG_LOCAL);
     state->mime_state = 0;
@@ -150,6 +151,8 @@ void    cleanup_state_free(CLEANUP_STATE *state)
     been_here_free(state->dups);
     if (state->reason)
        myfree(state->reason);
+    if (state->smtp_reply)
+       myfree(state->smtp_reply);
     nvtable_free(state->attr);
     if (state->mime_state)
        mime_state_free(state->mime_state);
index 9d399cde71e3585b3d437c04636e8c317dd83c46..e44f105ab5508cbfc25d7508de3098c7eb7eacc5 100644 (file)
@@ -22,6 +22,7 @@
 #define CLEANUP_FLAG_BCC_OK    (1<<4)  /* Ok to add auto-BCC addresses */
 #define CLEANUP_FLAG_MAP_OK    (1<<5)  /* Ok to map addresses */
 #define CLEANUP_FLAG_MILTER    (1<<6)  /* Enable Milter applications */
+#define CLEANUP_FLAG_SMTP_REPLY        (1<<7)  /* Enable SMTP reply */
 
 #define CLEANUP_FLAG_FILTER_ALL        (CLEANUP_FLAG_FILTER | CLEANUP_FLAG_MILTER)
  /*
index 67e334fff5e397ec6f5caabf152c4d76d40c5670..86acee7dc24c12de15c5e8a7e1a42e9029808b9b 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20080201"
+#define MAIL_RELEASE_DATE      "20080207"
 #define MAIL_VERSION_NUMBER    "2.6"
 
 #ifdef SNAPSHOT
index 238c1d10771e69a012685c25ec9d910cfc23f4ea..be79cd8bcd0b7260c71f24fbb88f30942ae79e68 100644 (file)
@@ -83,7 +83,7 @@
 
 /* Global library. */
 
-#include <mail_params.h>               /* var_line_limit */
+#include <mail_params.h>
 #include <mail_proto.h>
 #include <rec_type.h>
 #include <record.h>
@@ -1094,6 +1094,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
        char   *cp;
        char   *rp;
        char    ch;
+       char   *next;
 
        if (milter8_read_resp(milter, event, &cmd, &data_size) != 0)
            MILTER8_EVENT_BREAK(milter->def_reply);
@@ -1266,6 +1267,18 @@ static const char *milter8_event(MILTER8 *milter, int event,
                        break;
                }
            }
+           for (cp = STR(milter->buf); /* void */ ; cp = next) {
+               if (var_soft_bounce) {
+                   if (cp[0] == '5') {
+                       cp[0] = '4';
+                       if (cp[4] == '5')
+                           cp[4] = '4';
+                   }
+               }
+               if ((next = strstr(cp, "\r\n")) == 0)
+                   break;
+               next += 2;
+           }
            if (IN_CONNECT_EVENT(event)) {
 #ifdef LIBMILTER_AUTO_DISCONNECT
                milter8_close_stream(milter);
index cc65212da37a7bb187e048d5151555cca38b862b..23a0c37cba880a3cedb8f614e784b362892487b2 100644 (file)
@@ -151,8 +151,8 @@ static int test_reply(SMFICTX *ctx, int code)
     (void) fflush(stdout);             /* In case output redirected. */
 
     if (code == SMFIR_REPLYCODE) {
-       if (smfi_setreply(ctx, reply_code, reply_dsn, reply_message) == MI_FAILURE)
-           fprintf(stderr, "smfi_setreply failed\n");
+       if (smfi_setmlreply(ctx, reply_code, reply_dsn, reply_message, reply_message, (char *) 0) == MI_FAILURE)
+           fprintf(stderr, "smfi_setmlreply failed\n");
        printf("test_reply %s\n", reply_code);
        return (reply_code[0] == '4' ? SMFIS_TEMPFAIL : SMFIS_REJECT);
     } else {
index 13eb9a6817fe8ad08ba70d007e80dfe95790140b..3b9154ca1fb84a7cc5e1f8ae31ca5eb19d155283 100644 (file)
 /* FILES
 /*     /etc/postfix/main.cf, Postfix configuration parameters
 /*     /etc/postfix/master.cf, Postfix daemon processes
-/*     /etc/postfix/postfix-files, file/directory permissions
-/*     /etc/postfix/postfix-script, administrative commands
-/*     /etc/postfix/post-install, post-installation configuration
+/*     $daemon_directory/postfix-files, file/directory permissions
+/*     $daemon_directory/postfix-script, administrative commands
+/*     $daemon_directory/post-install, post-installation configuration
 /* SEE ALSO
 /*     Commands:
 /*     postalias(1), create/update/query alias database
@@ -466,7 +466,7 @@ int     main(int argc, char **argv)
     /*
      * Run the management script with as process name ourself.
      */
-    script = concatenate(var_config_dir, "/postfix-script", (char *) 0);
+    script = concatenate(var_daemon_dir, "/postfix-script", (char *) 0);
     execvp(script, argv + optind - 1);
     msg_fatal("%s: %m", script);
 }
index 7588ea913bf603448ae7ce3a70c2d199339c0c16..35d1cf045dc646d73889b4817b516fbdcc9378e7 100644 (file)
@@ -1633,7 +1633,8 @@ static int mail_open_stream(SMTPD_STATE *state)
 
        smtpd_check_rewrite(state);
        cleanup_flags = input_transp_cleanup(CLEANUP_FLAG_MASK_EXTERNAL,
-                                            smtpd_input_transp_mask);
+                                            smtpd_input_transp_mask)
+           | CLEANUP_FLAG_SMTP_REPLY;
        state->dest = mail_stream_service(MAIL_CLASS_PUBLIC,
                                          var_cleanup_service);
        if (state->dest == 0
@@ -2864,6 +2865,11 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
      * 
      * See also: qmqpd.c
      */
+#define IS_SMTP_REJECT(s) \
+       (((s)[0] == '4' || (s)[0] == '5') \
+        && ISDIGIT((s)[1]) && ISDIGIT((s)[2]) \
+        && ((s)[3] == '\0' || (s)[3] == ' ' || (s)[3] == '-'))
+
     if (state->err == CLEANUP_STAT_OK) {
        state->error_count = 0;
        state->error_mask = 0;
@@ -2873,6 +2879,9 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
                             "250 2.0.0 Ok: queued as %s", state->queue_id);
        else
            smtpd_chat_reply(state, "%s", STR(state->proxy_buffer));
+    } else if (why && IS_SMTP_REJECT(STR(why))) {
+       state->error_mask |= MAIL_ERROR_POLICY;
+       smtpd_chat_reply(state, "%s", STR(why));
     } else if ((state->err & CLEANUP_STAT_DEFER) != 0) {
        state->error_mask |= MAIL_ERROR_POLICY;
        detail = cleanup_stat_detail(CLEANUP_STAT_DEFER);
@@ -3766,7 +3775,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
      * we exclude xclient authorized hosts from event count/rate control.
      */
     if (var_smtpd_cntls_limit > 0
-       && (state->tls_context == 0 || state->tls_context->session_reused == 0)
+     && (state->tls_context == 0 || state->tls_context->session_reused == 0)
        && SMTPD_STAND_ALONE(state) == 0
        && !xclient_allowed
        && anvil_clnt
@@ -3779,7 +3788,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
                 rate, state->namaddr, state->service);
        if (state->tls_context)
            smtpd_chat_reply(state,
-                       "421 4.7.0 %s Error: too many new TLS sessions from %s",
+                   "421 4.7.0 %s Error: too many new TLS sessions from %s",
                             var_myhostname, state->namaddr);
        /* XXX Use regular return to signal end of session. */
        vstream_longjmp(state->client, SMTP_ERR_QUIET);
index 861192863efc32d7d6b63e3a3da19f6544467847..f7445d66c76ccff9af4f859f7a41d50e843caea9 100644 (file)
@@ -104,7 +104,8 @@ void    smtpd_chat_reset(SMTPD_STATE *state)
 
 /* smtp_chat_append - append record to SMTP transaction log */
 
-static void smtp_chat_append(SMTPD_STATE *state, char *direction)
+static void smtp_chat_append(SMTPD_STATE *state, char *direction,
+                                    const char *text)
 {
     char   *line;
 
@@ -113,7 +114,7 @@ static void smtp_chat_append(SMTPD_STATE *state, char *direction)
 
     if (state->history == 0)
        state->history = argv_alloc(10);
-    line = concatenate(direction, STR(state->buffer), (char *) 0);
+    line = concatenate(direction, text, (char *) 0);
     argv_add(state->history, line, (char *) 0);
     myfree(line);
 }
@@ -125,7 +126,7 @@ void    smtpd_chat_query(SMTPD_STATE *state)
     int     last_char;
 
     last_char = smtp_get(state->buffer, state->client, var_line_limit);
-    smtp_chat_append(state, "In:  ");
+    smtp_chat_append(state, "In:  ", STR(state->buffer));
     if (last_char != '\n')
        msg_warn("%s: request longer than %d: %.30s...",
                 state->namaddr, var_line_limit,
@@ -141,20 +142,9 @@ void    smtpd_chat_reply(SMTPD_STATE *state, const char *format,...)
 {
     va_list ap;
     int     delay = 0;
-
-    va_start(ap, format);
-    vstring_vsprintf(state->buffer, format, ap);
-    va_end(ap);
-    /* All 5xx replies must have a 5.xx.xx detail code. */
-    if (var_soft_bounce && STR(state->buffer)[0] == '5') {
-       STR(state->buffer)[0] = '4';
-       if (STR(state->buffer)[4] == '5')
-           STR(state->buffer)[4] = '4';
-    }
-    smtp_chat_append(state, "Out: ");
-
-    if (msg_verbose)
-       msg_info("> %s: %s", state->namaddr, STR(state->buffer));
+    char   *cp;
+    char   *next;
+    char   *end;
 
     /*
      * Slow down clients that make errors. Sleep-on-anything slows down
@@ -163,7 +153,34 @@ void    smtpd_chat_reply(SMTPD_STATE *state, const char *format,...)
     if (state->error_count >= var_smtpd_soft_erlim)
        sleep(delay = var_smtpd_err_sleep);
 
-    smtp_fputs(STR(state->buffer), LEN(state->buffer), state->client);
+    va_start(ap, format);
+    vstring_vsprintf(state->buffer, format, ap);
+    va_end(ap);
+    /* All 5xx replies must have a 5.xx.xx detail code. */
+    for (cp = STR(state->buffer), end = cp + strlen(STR(state->buffer));;) {
+       if (var_soft_bounce) {
+           if (cp[0] == '5') {
+               cp[0] = '4';
+               if (cp[4] == '5')
+                   cp[4] = '4';
+           }
+       }
+       /* This is why we use strlen() above instead of VSTRING_LEN(). */
+       if ((next = strstr(cp, "\r\n")) != 0) {
+           *next = 0;
+       } else {
+           next = end;
+       }
+       smtp_chat_append(state, "Out: ", cp);
+       if (msg_verbose)
+           msg_info("> %s: %s", state->namaddr, cp);
+
+       smtp_fputs(cp, next - cp, state->client);
+       if (next < end)
+           cp = next + 2;
+       else
+           break;
+    }
 
     /*
      * Flush unsent output if no I/O happened for a while. This avoids