Subject: Postfix 19990906 Patch05: defer logfile lossage

From: [email-masked] (Wietse Venema)
Date: Thu, 23 Sep 1999 13:18:58 -0400 (EDT)

Patch 04 (for a problem introduced with Postfix 19990906) causes
trouble with bounces for bad address syntax or for recipients in
the relocated map.

The patch below corrects the problem. The patch appears to be large
but compared to postfix-19990906-pl03 it only moves three lines of
source code from one source file to another one.

A fully-patched version, Postfix-19990906-pl05 will be distributed
from ftp://ftp.porcupine.org/postfix-release/official and mirrors.

Credits to Dick Porter @ acm.org for diagnosing the problem.

	Wietse

*** ./global/mail_version.h-	Wed Sep 22 20:13:18 1999
--- ./global/mail_version.h	Thu Sep 23 12:45:31 1999
***************
*** 15,21 ****
    * Version of this program.
    */
  #define VAR_MAIL_VERSION	"mail_version"
! #define DEF_MAIL_VERSION	"Postfix-19990906-pl04"
  extern char *var_mail_version;
  
  /* LICENSE
--- 15,21 ----
    * Version of this program.
    */
  #define VAR_MAIL_VERSION	"mail_version"
! #define DEF_MAIL_VERSION	"Postfix-19990906-pl05"
  extern char *var_mail_version;
  
  /* LICENSE
*** ./qmgr/qmgr_active.c-	Wed Sep 22 20:12:21 1999
--- ./qmgr/qmgr_active.c	Thu Sep 23 12:41:06 1999
***************
*** 221,240 ****
      } else {
  
  	/*
- 	 * Reset the defer log. Leave the bounce log alone; if it is still
- 	 * around, something did not send it previously.
- 	 */
- 	if (mail_queue_remove(MAIL_QUEUE_DEFER, queue_id) && errno != ENOENT)
- 	    msg_fatal("%s: %s: remove %s %s: %m", myname,
- 		      queue_id, MAIL_QUEUE_DEFER, queue_id);
- 
- 	/*
- 	 * Resolve recipient destinations and assign transports. This will
- 	 * also defer or bounce recipients.
- 	 */
- 	qmgr_message_route(message);
- 
- 	/*
  	 * Special case if all recipients were already delivered. Send any
  	 * bounces and clean up. Or, when all recipients were bounced or
  	 * deferred, go look for more.
--- 221,226 ----
***************
*** 310,321 ****
  	    qmgr_active_corrupt(message->queue_id);
  	    qmgr_message_free(message);
  	} else {
- 
- 	    /*
- 	     * Resolve recipient destinations and assign transports. This
- 	     * will also defer or bounce recipients.
- 	     */
- 	    qmgr_message_route(message);
  
  	    /*
  	     * Special case if all recipients were already delivered. Send
--- 296,301 ----
*** ./qmgr/qmgr_message.c-	Wed Sep 22 20:12:21 1999
--- ./qmgr/qmgr_message.c	Thu Sep 23 12:45:11 1999
***************
*** 20,28 ****
  /*	void	qmgr_message_free(message)
  /*	QMGR_MESSAGE *message;
  /*
- /*	void	qmgr_message_route(message)
- /*	QMGR_MESSAGE *message;
- /*
  /*	void	qmgr_message_update_warn(message)
  /*	QMGR_MESSAGE *message;
  /* DESCRIPTION
--- 20,25 ----
***************
*** 44,50 ****
  /*	of recipients read from a queue file is limited by the global
  /*	var_qmgr_rcpt_limit configuration parameter. When the limit
  /*	is reached, the \fIrcpt_offset\fR structure member is set to
! /*	the position where the read was terminated.
  /*
  /*	qmgr_message_realloc() resumes reading recipients from the queue
  /*	file, and updates the recipient list and \fIrcpt_offset\fR message
--- 41,50 ----
  /*	of recipients read from a queue file is limited by the global
  /*	var_qmgr_rcpt_limit configuration parameter. When the limit
  /*	is reached, the \fIrcpt_offset\fR structure member is set to
! /*	the position where the read was terminated. Recipients are
! /*	run through the resolver, and are assigned to destination
! /*	queues. Recipients that cannot be assigned are deferred or
! /*	bounced. Mail that has bounced twice is silently absorbed.
  /*
  /*	qmgr_message_realloc() resumes reading recipients from the queue
  /*	file, and updates the recipient list and \fIrcpt_offset\fR message
***************
*** 55,65 ****
  /*	the resources available for reuse. It is an error to destroy
  /*	a message structure that is still referenced by queue entry structures.
  /*
- /*	qmgr_message_route() runs message recipients through the resolver,
- /*	and assigns them to destination queues. Recipients that cannot be
- /*	assigned are deferred or bounced. Mail that has bounced twice is
- /*	silently absorbed.
- /*
  /*	qmgr_message_update_warn() takes a closed message, opens it, updates
  /*	the warning field, and closes it again.
  /* DIAGNOSTICS
--- 55,60 ----
***************
*** 705,710 ****
--- 700,720 ----
  	qmgr_message_free(message);
  	return (0);
      } else {
+ 
+ 	/*
+ 	 * Reset the defer log. This code should not be here, but we must
+ 	 * reset the defer log *after* acquiring the exclusive lock on the
+ 	 * queue file and *before* resolving new recipients. Since all those
+ 	 * operations are encapsulated so nicely by this routine, the defer
+ 	 * log reset has to be done here as well.
+ 	 */
+ 	if (mail_queue_remove(MAIL_QUEUE_DEFER, queue_id) && errno != ENOENT)
+ 	    msg_fatal("%s: %s: remove %s %s: %m", myname,
+ 		      queue_id, MAIL_QUEUE_DEFER, queue_id);
+ 	qmgr_message_sort(message);
+ 	qmgr_message_resolve(message);
+ 	qmgr_message_sort(message);
+ 	qmgr_message_assign(message);
  	qmgr_message_close(message);
  	return (message);
      }
***************
*** 737,753 ****
  	qmgr_message_close(message);
  	return (0);
      } else {
  	qmgr_message_close(message);
  	return (message);
      }
- }
- 
- /* qmgr_message_route - route recipients to transports */
- 
- void    qmgr_message_route(QMGR_MESSAGE *message)
- {
-     qmgr_message_sort(message);
-     qmgr_message_resolve(message);
-     qmgr_message_sort(message);
-     qmgr_message_assign(message);
  }
--- 747,757 ----
  	qmgr_message_close(message);
  	return (0);
      } else {
+ 	qmgr_message_sort(message);
+ 	qmgr_message_resolve(message);
+ 	qmgr_message_sort(message);
+ 	qmgr_message_assign(message);
  	qmgr_message_close(message);
  	return (message);
      }
  }
*** ./qmgr/qmgr.h-	Wed Sep 22 20:12:21 1999
--- ./qmgr/qmgr.h	Thu Sep 23 12:47:44 1999
***************
*** 245,251 ****
  extern void qmgr_message_update_warn(QMGR_MESSAGE *);
  extern QMGR_MESSAGE *qmgr_message_alloc(const char *, const char *, int);
  extern QMGR_MESSAGE *qmgr_message_realloc(QMGR_MESSAGE *);
- extern void qmgr_message_route(QMGR_MESSAGE *);
  
   /*
    * qmgr_defer.c
--- 245,250 ----
*** ./HISTORY-	Wed Sep 22 20:37:16 1999
--- ./HISTORY	Thu Sep 23 12:46:58 1999
***************
*** 3068,3070 ****
--- 3068,3076 ----
  	would not show why mail is delayed, and that delayed mail
  	could be sent back with recipients missing from the error
  	report. Reported by Giulio Orsero @ tiscalinet.it.
+ 
+ 19990922
+ 
+ 	Bugfix: the above bugfix broke bounces of mail with bad
+ 	address syntax and relocated users. Problem diagnosed by
+ 	Dick Porter @ acm.org.

----- End of forwarded message from Wietse Venema -----