1 /*++
2 /* NAME
3 /*	qmgr_message 3
4 /* SUMMARY
5 /*	in-core message structures
6 /* SYNOPSIS
7 /*	#include "qmgr.h"
8 /*
9 /*	int	qmgr_message_count;
10 /*	int	qmgr_recipient_count;
11 /*	int	qmgr_vrfy_pend_count;
12 /*
13 /*	QMGR_MESSAGE *qmgr_message_alloc(class, name, qflags, mode)
14 /*	const char *class;
15 /*	const char *name;
16 /*	int	qflags;
17 /*	mode_t	mode;
18 /*
19 /*	QMGR_MESSAGE *qmgr_message_realloc(message)
20 /*	QMGR_MESSAGE *message;
21 /*
22 /*	void	qmgr_message_free(message)
23 /*	QMGR_MESSAGE *message;
24 /*
25 /*	void	qmgr_message_update_warn(message)
26 /*	QMGR_MESSAGE *message;
27 /*
28 /*	void	qmgr_message_kill_record(message, offset)
29 /*	QMGR_MESSAGE *message;
30 /*	long	offset;
31 /* DESCRIPTION
32 /*	This module performs en-gross operations on queue messages.
33 /*
34 /*	qmgr_message_count is a global counter for the total number
35 /*	of in-core message structures (i.e. the total size of the
36 /*	`active' message queue).
37 /*
38 /*	qmgr_recipient_count is a global counter for the total number
39 /*	of in-core recipient structures (i.e. the sum of all recipients
40 /*	in all in-core message structures).
41 /*
42 /*	qmgr_vrfy_pend_count is a global counter for the total
43 /*	number of in-core message structures that are associated
44 /*	with an address verification request. Requests that exceed
45 /*	the address_verify_pending_limit are deferred immediately.
46 /*	This is a backup mechanism for a more refined enforcement
47 /*	mechanism in the verify(8) daemon.
48 /*
49 /*	qmgr_message_alloc() creates an in-core message structure
50 /*	with sender and recipient information taken from the named queue
51 /*	file. A null result means the queue file could not be read or
52 /*	that the queue file contained incorrect information. A result
53 /*	QMGR_MESSAGE_LOCKED means delivery must be deferred. The number
54 /*	of recipients read from a queue file is limited by the global
55 /*	var_qmgr_rcpt_limit configuration parameter. When the limit
56 /*	is reached, the \fIrcpt_offset\fR structure member is set to
57 /*	the position where the read was terminated. Recipients are
58 /*	run through the resolver, and are assigned to destination
59 /*	queues. Recipients that cannot be assigned are deferred or
60 /*	bounced. Mail that has bounced twice is silently absorbed.
61 /*	A non-zero mode means change the queue file permissions.
62 /*
63 /*	qmgr_message_realloc() resumes reading recipients from the queue
64 /*	file, and updates the recipient list and \fIrcpt_offset\fR message
65 /*	structure members. A null result means that the file could not be
66 /*	read or that the file contained incorrect information.
67 /*
68 /*	qmgr_message_free() destroys an in-core message structure and makes
69 /*	the resources available for reuse. It is an error to destroy
70 /*	a message structure that is still referenced by queue entry structures.
71 /*
72 /*	qmgr_message_update_warn() takes a closed message, opens it, updates
73 /*	the warning field, and closes it again.
74 /*
75 /*	qmgr_message_kill_record() takes a closed message, opens it, updates
76 /*	the record type at the given offset to "killed", and closes the file.
77 /*	A killed envelope record is ignored. Killed records are not allowed
78 /*	inside the message content.
79 /* DIAGNOSTICS
80 /*	Warnings: malformed message file. Fatal errors: out of memory.
81 /* SEE ALSO
82 /*	envelope(3) message envelope parser
83 /* LICENSE
84 /* .ad
85 /* .fi
86 /*	The Secure Mailer license must be distributed with this software.
87 /* AUTHOR(S)
88 /*	Wietse Venema
89 /*	IBM T.J. Watson Research
90 /*	P.O. Box 704
91 /*	Yorktown Heights, NY 10598, USA
92 /*
93 /*	Wietse Venema
94 /*	Google, Inc.
95 /*	111 8th Avenue
96 /*	New York, NY 10011, USA
97 /*--*/
98 
99 /* System library. */
100 
101 #include <sys_defs.h>
102 #include <sys/stat.h>
103 #include <stdlib.h>
104 #include <stdio.h>			/* sscanf() */
105 #include <fcntl.h>
106 #include <errno.h>
107 #include <unistd.h>
108 #include <string.h>
109 #include <ctype.h>
110 
111 /* Utility library. */
112 
113 #include <msg.h>
114 #include <mymalloc.h>
115 #include <vstring.h>
116 #include <vstream.h>
117 #include <split_at.h>
118 #include <valid_hostname.h>
119 #include <argv.h>
120 #include <stringops.h>
121 #include <myflock.h>
122 
123 /* Global library. */
124 
125 #include <dict.h>
126 #include <mail_queue.h>
127 #include <mail_params.h>
128 #include <canon_addr.h>
129 #include <record.h>
130 #include <rec_type.h>
131 #include <sent.h>
132 #include <deliver_completed.h>
133 #include <opened.h>
134 #include <verp_sender.h>
135 #include <mail_proto.h>
136 #include <qmgr_user.h>
137 #include <split_addr.h>
138 #include <dsn_mask.h>
139 #include <rec_attr_map.h>
140 
141 /* Client stubs. */
142 
143 #include <rewrite_clnt.h>
144 #include <resolve_clnt.h>
145 
146 /* Application-specific. */
147 
148 #include "qmgr.h"
149 
150 int     qmgr_message_count;
151 int     qmgr_recipient_count;
152 int     qmgr_vrfy_pend_count;
153 
154 /* qmgr_message_create - create in-core message structure */
155 
qmgr_message_create(const char * queue_name,const char * queue_id,int qflags)156 static QMGR_MESSAGE *qmgr_message_create(const char *queue_name,
157 				           const char *queue_id, int qflags)
158 {
159     QMGR_MESSAGE *message;
160 
161     message = (QMGR_MESSAGE *) mymalloc(sizeof(QMGR_MESSAGE));
162     qmgr_message_count++;
163     message->flags = 0;
164     message->qflags = qflags;
165     message->tflags = 0;
166     message->tflags_offset = 0;
167     message->rflags = QMGR_READ_FLAG_DEFAULT;
168     message->fp = 0;
169     message->refcount = 0;
170     message->single_rcpt = 0;
171     message->arrival_time.tv_sec = message->arrival_time.tv_usec = 0;
172     message->create_time = 0;
173     GETTIMEOFDAY(&message->active_time);
174     message->data_offset = 0;
175     message->queue_id = mystrdup(queue_id);
176     message->queue_name = mystrdup(queue_name);
177     message->encoding = 0;
178     message->sender = 0;
179     message->dsn_envid = 0;
180     message->dsn_ret = 0;
181     message->smtputf8 = 0;
182     message->filter_xport = 0;
183     message->inspect_xport = 0;
184     message->redirect_addr = 0;
185     message->data_size = 0;
186     message->cont_length = 0;
187     message->warn_offset = 0;
188     message->warn_time = 0;
189     message->rcpt_offset = 0;
190     message->verp_delims = 0;
191     message->client_name = 0;
192     message->client_addr = 0;
193     message->client_port = 0;
194     message->client_proto = 0;
195     message->client_helo = 0;
196     message->sasl_method = 0;
197     message->sasl_username = 0;
198     message->sasl_sender = 0;
199     message->log_ident = 0;
200     message->rewrite_context = 0;
201     recipient_list_init(&message->rcpt_list, RCPT_LIST_INIT_QUEUE);
202     return (message);
203 }
204 
205 /* qmgr_message_close - close queue file */
206 
qmgr_message_close(QMGR_MESSAGE * message)207 static void qmgr_message_close(QMGR_MESSAGE *message)
208 {
209     vstream_fclose(message->fp);
210     message->fp = 0;
211 }
212 
213 /* qmgr_message_open - open queue file */
214 
qmgr_message_open(QMGR_MESSAGE * message)215 static int qmgr_message_open(QMGR_MESSAGE *message)
216 {
217 
218     /*
219      * Sanity check.
220      */
221     if (message->fp)
222 	msg_panic("%s: queue file is open", message->queue_id);
223 
224     /*
225      * Open this queue file. Skip files that we cannot open. Back off when
226      * the system appears to be running out of resources.
227      */
228     if ((message->fp = mail_queue_open(message->queue_name,
229 				       message->queue_id,
230 				       O_RDWR, 0)) == 0) {
231 	if (errno != ENOENT)
232 	    msg_fatal("open %s %s: %m", message->queue_name, message->queue_id);
233 	msg_warn("open %s %s: %m", message->queue_name, message->queue_id);
234 	return (-1);
235     }
236     return (0);
237 }
238 
239 /* qmgr_message_oldstyle_scan - support for Postfix < 1.0 queue files */
240 
qmgr_message_oldstyle_scan(QMGR_MESSAGE * message)241 static void qmgr_message_oldstyle_scan(QMGR_MESSAGE *message)
242 {
243     VSTRING *buf;
244     long    orig_offset, extra_offset;
245     int     rec_type;
246     char   *start;
247 
248     /*
249      * Initialize. No early returns or we have a memory leak.
250      */
251     buf = vstring_alloc(100);
252     if ((orig_offset = vstream_ftell(message->fp)) < 0)
253 	msg_fatal("vstream_ftell %s: %m", VSTREAM_PATH(message->fp));
254 
255     /*
256      * Rewind to the very beginning to make sure we see all records.
257      */
258     if (vstream_fseek(message->fp, 0, SEEK_SET) < 0)
259 	msg_fatal("seek file %s: %m", VSTREAM_PATH(message->fp));
260 
261     /*
262      * Scan through the old style queue file. Count the total number of
263      * recipients and find the data/extra sections offsets. Note that the new
264      * queue files require that data_size equals extra_offset - data_offset,
265      * so we set data_size to this as well and ignore the size record itself
266      * completely.
267      */
268     for (;;) {
269 	rec_type = rec_get(message->fp, buf, 0);
270 	if (rec_type <= 0)
271 	    /* Report missing end record later. */
272 	    break;
273 	start = vstring_str(buf);
274 	if (msg_verbose > 1)
275 	    msg_info("old-style scan record %c %s", rec_type, start);
276 	if (rec_type == REC_TYPE_END)
277 	    break;
278 	if (rec_type == REC_TYPE_MESG) {
279 	    if (message->data_offset == 0) {
280 		if ((message->data_offset = vstream_ftell(message->fp)) < 0)
281 		    msg_fatal("vstream_ftell %s: %m", VSTREAM_PATH(message->fp));
282 		if ((extra_offset = atol(start)) <= message->data_offset)
283 		    msg_fatal("bad extra offset %s file %s",
284 			      start, VSTREAM_PATH(message->fp));
285 		if (vstream_fseek(message->fp, extra_offset, SEEK_SET) < 0)
286 		    msg_fatal("seek file %s: %m", VSTREAM_PATH(message->fp));
287 		message->data_size = extra_offset - message->data_offset;
288 	    }
289 	    continue;
290 	}
291     }
292 
293     /*
294      * Clean up.
295      */
296     if (vstream_fseek(message->fp, orig_offset, SEEK_SET) < 0)
297 	msg_fatal("seek file %s: %m", VSTREAM_PATH(message->fp));
298     vstring_free(buf);
299 
300     /*
301      * Sanity checks. Verify that all required information was found,
302      * including the queue file end marker.
303      */
304     if (message->data_offset == 0 || rec_type != REC_TYPE_END)
305 	msg_fatal("%s: envelope records out of order", message->queue_id);
306 }
307 
308 /* qmgr_message_read - read envelope records */
309 
qmgr_message_read(QMGR_MESSAGE * message)310 static int qmgr_message_read(QMGR_MESSAGE *message)
311 {
312     VSTRING *buf;
313     int     rec_type;
314     long    curr_offset;
315     long    save_offset = message->rcpt_offset;	/* save a flag */
316     char   *start;
317     int     nrcpt = 0;
318     const char *error_text;
319     char   *name;
320     char   *value;
321     char   *orig_rcpt = 0;
322     int     count;
323     int     dsn_notify = 0;
324     char   *dsn_orcpt = 0;
325     int     n;
326     int     have_log_client_attr = 0;
327 
328     /*
329      * Initialize. No early returns or we have a memory leak.
330      */
331     buf = vstring_alloc(100);
332 
333     /*
334      * If we re-open this file, skip over on-file recipient records that we
335      * already looked at, and refill the in-core recipient address list.
336      */
337     if (message->rcpt_offset) {
338 	if (message->rcpt_list.len)
339 	    msg_panic("%s: recipient list not empty on recipient reload",
340 		      message->queue_id);
341 	if (vstream_fseek(message->fp, message->rcpt_offset, SEEK_SET) < 0)
342 	    msg_fatal("seek file %s: %m", VSTREAM_PATH(message->fp));
343 	message->rcpt_offset = 0;
344     }
345 
346     /*
347      * Read envelope records. XXX Rely on the front-end programs to enforce
348      * record size limits. Read up to var_qmgr_rcpt_limit recipients from the
349      * queue file, to protect against memory exhaustion. Recipient records
350      * may appear before or after the message content, so we keep reading
351      * from the queue file until we have enough recipients (rcpt_offset != 0)
352      * and until we know all the non-recipient information.
353      *
354      * When reading recipients from queue file, stop reading when we reach a
355      * per-message in-core recipient limit rather than a global in-core
356      * recipient limit. Use the global recipient limit only in order to stop
357      * opening queue files. The purpose is to achieve equal delay for
358      * messages with recipient counts up to var_qmgr_rcpt_limit recipients.
359      *
360      * If we would read recipients up to a global recipient limit, the average
361      * number of in-core recipients per message would asymptotically approach
362      * (global recipient limit)/(active queue size limit), which gives equal
363      * delay per recipient rather than equal delay per message.
364      *
365      * On the first open, we must examine all non-recipient records.
366      *
367      * Optimization: when we know that recipient records are not mixed with
368      * non-recipient records, as is typical with mailing list mail, then we
369      * can avoid having to examine all the queue file records before we can
370      * start deliveries. This avoids some file system thrashing with huge
371      * mailing lists.
372      */
373     for (;;) {
374 	if ((curr_offset = vstream_ftell(message->fp)) < 0)
375 	    msg_fatal("vstream_ftell %s: %m", VSTREAM_PATH(message->fp));
376 	if (curr_offset == message->data_offset && curr_offset > 0) {
377 	    if (vstream_fseek(message->fp, message->data_size, SEEK_CUR) < 0)
378 		msg_fatal("seek file %s: %m", VSTREAM_PATH(message->fp));
379 	    curr_offset += message->data_size;
380 	}
381 	rec_type = rec_get_raw(message->fp, buf, 0, REC_FLAG_NONE);
382 	start = vstring_str(buf);
383 	if (msg_verbose > 1)
384 	    msg_info("record %c %s", rec_type, start);
385 	if (rec_type == REC_TYPE_PTR) {
386 	    if ((rec_type = rec_goto(message->fp, start)) == REC_TYPE_ERROR)
387 		break;
388 	    /* Need to update curr_offset after pointer jump. */
389 	    continue;
390 	}
391 	if (rec_type <= 0) {
392 	    msg_warn("%s: message rejected: missing end record",
393 		     message->queue_id);
394 	    break;
395 	}
396 	if (rec_type == REC_TYPE_END) {
397 	    message->rflags |= QMGR_READ_FLAG_SEEN_ALL_NON_RCPT;
398 	    break;
399 	}
400 
401 	/*
402 	 * Map named attributes to pseudo record types, so that we don't have
403 	 * to pollute the queue file with records that are incompatible with
404 	 * past Postfix versions. Preferably, people should be able to back
405 	 * out from an upgrade without losing mail.
406 	 */
407 	if (rec_type == REC_TYPE_ATTR) {
408 	    if ((error_text = split_nameval(start, &name, &value)) != 0) {
409 		msg_warn("%s: ignoring bad attribute: %s: %.200s",
410 			 message->queue_id, error_text, start);
411 		rec_type = REC_TYPE_ERROR;
412 		break;
413 	    }
414 	    if ((n = rec_attr_map(name)) != 0) {
415 		start = value;
416 		rec_type = n;
417 	    }
418 	}
419 
420 	/*
421 	 * Process recipient records.
422 	 */
423 	if (rec_type == REC_TYPE_RCPT) {
424 	    /* See also below for code setting orig_rcpt etc. */
425 #define FUDGE(x)	((x) * (var_qmgr_fudge / 100.0))
426 	    if (message->rcpt_offset == 0) {
427 		recipient_list_add(&message->rcpt_list, curr_offset,
428 				   dsn_orcpt ? dsn_orcpt : "",
429 				   dsn_notify ? dsn_notify : 0,
430 				   orig_rcpt ? orig_rcpt : "", start);
431 		if (dsn_orcpt) {
432 		    myfree(dsn_orcpt);
433 		    dsn_orcpt = 0;
434 		}
435 		if (orig_rcpt) {
436 		    myfree(orig_rcpt);
437 		    orig_rcpt = 0;
438 		}
439 		if (dsn_notify)
440 		    dsn_notify = 0;
441 		if (message->rcpt_list.len >= FUDGE(var_qmgr_rcpt_limit)) {
442 		    if ((message->rcpt_offset = vstream_ftell(message->fp)) < 0)
443 			msg_fatal("vstream_ftell %s: %m",
444 				  VSTREAM_PATH(message->fp));
445 		    if (message->rflags & QMGR_READ_FLAG_SEEN_ALL_NON_RCPT)
446 			/* We already examined all non-recipient records. */
447 			break;
448 		    if (message->rflags & QMGR_READ_FLAG_MIXED_RCPT_OTHER)
449 			/* Examine all remaining non-recipient records. */
450 			continue;
451 		    /* Optimizations for "pure recipient" record sections. */
452 		    if (curr_offset > message->data_offset) {
453 			/* We already examined all non-recipient records. */
454 			message->rflags |= QMGR_READ_FLAG_SEEN_ALL_NON_RCPT;
455 			break;
456 		    }
457 		    /* Examine non-recipient records in extracted segment. */
458 		    if (vstream_fseek(message->fp, message->data_offset
459 				      + message->data_size, SEEK_SET) < 0)
460 			msg_fatal("seek file %s: %m", VSTREAM_PATH(message->fp));
461 		    continue;
462 		}
463 	    }
464 	    continue;
465 	}
466 	if (rec_type == REC_TYPE_DONE || rec_type == REC_TYPE_DRCP) {
467 	    if (message->rcpt_offset == 0) {
468 		if (dsn_orcpt) {
469 		    myfree(dsn_orcpt);
470 		    dsn_orcpt = 0;
471 		}
472 		if (orig_rcpt) {
473 		    myfree(orig_rcpt);
474 		    orig_rcpt = 0;
475 		}
476 		if (dsn_notify)
477 		    dsn_notify = 0;
478 	    }
479 	    continue;
480 	}
481 	if (rec_type == REC_TYPE_DSN_ORCPT) {
482 	    /* See also above for code clearing dsn_orcpt. */
483 	    if (dsn_orcpt != 0) {
484 		msg_warn("%s: ignoring out-of-order DSN original recipient address <%.200s>",
485 			 message->queue_id, dsn_orcpt);
486 		myfree(dsn_orcpt);
487 		dsn_orcpt = 0;
488 	    }
489 	    if (message->rcpt_offset == 0)
490 		dsn_orcpt = mystrdup(start);
491 	    continue;
492 	}
493 	if (rec_type == REC_TYPE_DSN_NOTIFY) {
494 	    /* See also above for code clearing dsn_notify. */
495 	    if (dsn_notify != 0) {
496 		msg_warn("%s: ignoring out-of-order DSN notify flags <%d>",
497 			 message->queue_id, dsn_notify);
498 		dsn_notify = 0;
499 	    }
500 	    if (message->rcpt_offset == 0) {
501 		if (!alldig(start) || (n = atoi(start)) == 0 || !DSN_NOTIFY_OK(n))
502 		    msg_warn("%s: ignoring malformed DSN notify flags <%.200s>",
503 			     message->queue_id, start);
504 		else
505 		    dsn_notify = n;
506 		continue;
507 	    }
508 	}
509 	if (rec_type == REC_TYPE_ORCP) {
510 	    /* See also above for code clearing orig_rcpt. */
511 	    if (orig_rcpt != 0) {
512 		msg_warn("%s: ignoring out-of-order original recipient <%.200s>",
513 			 message->queue_id, orig_rcpt);
514 		myfree(orig_rcpt);
515 		orig_rcpt = 0;
516 	    }
517 	    if (message->rcpt_offset == 0)
518 		orig_rcpt = mystrdup(start);
519 	    continue;
520 	}
521 
522 	/*
523 	 * Process non-recipient records.
524 	 */
525 	if (message->rflags & QMGR_READ_FLAG_SEEN_ALL_NON_RCPT)
526 	    /* We already examined all non-recipient records. */
527 	    continue;
528 	if (rec_type == REC_TYPE_SIZE) {
529 	    if (message->data_offset == 0) {
530 		if ((count = sscanf(start, "%ld %ld %d %d %ld %d",
531 				 &message->data_size, &message->data_offset,
532 				    &nrcpt, &message->rflags,
533 				    &message->cont_length,
534 				    &message->smtputf8)) >= 3) {
535 		    /* Postfix >= 1.0 (a.k.a. 20010228). */
536 		    if (message->data_offset <= 0 || message->data_size <= 0) {
537 			msg_warn("%s: invalid size record: %.100s",
538 				 message->queue_id, start);
539 			rec_type = REC_TYPE_ERROR;
540 			break;
541 		    }
542 		    if (message->rflags & ~QMGR_READ_FLAG_USER) {
543 			msg_warn("%s: invalid flags in size record: %.100s",
544 				 message->queue_id, start);
545 			rec_type = REC_TYPE_ERROR;
546 			break;
547 		    }
548 		} else if (count == 1) {
549 		    /* Postfix < 1.0 (a.k.a. 20010228). */
550 		    qmgr_message_oldstyle_scan(message);
551 		} else {
552 		    /* Can't happen. */
553 		    msg_warn("%s: message rejected: weird size record",
554 			     message->queue_id);
555 		    rec_type = REC_TYPE_ERROR;
556 		    break;
557 		}
558 	    }
559 	    /* Postfix < 2.4 compatibility. */
560 	    if (message->cont_length == 0) {
561 		message->cont_length = message->data_size;
562 	    } else if (message->cont_length < 0) {
563 		msg_warn("%s: invalid size record: %.100s",
564 			 message->queue_id, start);
565 		rec_type = REC_TYPE_ERROR;
566 		break;
567 	    }
568 	    continue;
569 	}
570 	if (rec_type == REC_TYPE_TIME) {
571 	    if (message->arrival_time.tv_sec == 0)
572 		REC_TYPE_TIME_SCAN(start, message->arrival_time);
573 	    continue;
574 	}
575 	if (rec_type == REC_TYPE_CTIME) {
576 	    if (message->create_time == 0)
577 		message->create_time = atol(start);
578 	    continue;
579 	}
580 	if (rec_type == REC_TYPE_FILT) {
581 	    if (message->filter_xport != 0)
582 		myfree(message->filter_xport);
583 	    message->filter_xport = mystrdup(start);
584 	    continue;
585 	}
586 	if (rec_type == REC_TYPE_INSP) {
587 	    if (message->inspect_xport != 0)
588 		myfree(message->inspect_xport);
589 	    message->inspect_xport = mystrdup(start);
590 	    continue;
591 	}
592 	if (rec_type == REC_TYPE_RDR) {
593 	    if (message->redirect_addr != 0)
594 		myfree(message->redirect_addr);
595 	    message->redirect_addr = mystrdup(start);
596 	    continue;
597 	}
598 	if (rec_type == REC_TYPE_FROM) {
599 	    if (message->sender == 0) {
600 		message->sender = mystrdup(start);
601 		opened(message->queue_id, message->sender,
602 		       message->cont_length, nrcpt,
603 		       "queue %s", message->queue_name);
604 	    }
605 	    continue;
606 	}
607 	if (rec_type == REC_TYPE_DSN_ENVID) {
608 	    /* Allow Milter override. */
609 	    if (message->dsn_envid != 0)
610 		myfree(message->dsn_envid);
611 	    message->dsn_envid = mystrdup(start);
612 	}
613 	if (rec_type == REC_TYPE_DSN_RET) {
614 	    /* Allow Milter override. */
615 	    if (!alldig(start) || (n = atoi(start)) == 0 || !DSN_RET_OK(n))
616 		msg_warn("%s: ignoring malformed DSN RET flags in queue file record:%.100s",
617 			 message->queue_id, start);
618 	    else
619 		message->dsn_ret = n;
620 	}
621 	if (rec_type == REC_TYPE_ATTR) {
622 	    /* Allow extra segment to override envelope segment info. */
623 	    if (strcmp(name, MAIL_ATTR_ENCODING) == 0) {
624 		if (message->encoding != 0)
625 		    myfree(message->encoding);
626 		message->encoding = mystrdup(value);
627 	    }
628 
629 	    /*
630 	     * Backwards compatibility. Before Postfix 2.3, the logging
631 	     * attributes were called client_name, etc. Now they are called
632 	     * log_client_name. etc., and client_name is used for the actual
633 	     * client information. To support old queue files, we accept both
634 	     * names for the purpose of logging; the new name overrides the
635 	     * old one.
636 	     *
637 	     * XXX Do not use the "legacy" client_name etc. attribute values for
638 	     * initializing the logging attributes, when this file already
639 	     * contains the "modern" log_client_name etc. logging attributes.
640 	     * Otherwise, logging attributes that are not present in the
641 	     * queue file would be set with information from the real client.
642 	     */
643 	    else if (strcmp(name, MAIL_ATTR_ACT_CLIENT_NAME) == 0) {
644 		if (have_log_client_attr == 0 && message->client_name == 0)
645 		    message->client_name = mystrdup(value);
646 	    } else if (strcmp(name, MAIL_ATTR_ACT_CLIENT_ADDR) == 0) {
647 		if (have_log_client_attr == 0 && message->client_addr == 0)
648 		    message->client_addr = mystrdup(value);
649 	    } else if (strcmp(name, MAIL_ATTR_ACT_CLIENT_PORT) == 0) {
650 		if (have_log_client_attr == 0 && message->client_port == 0)
651 		    message->client_port = mystrdup(value);
652 	    } else if (strcmp(name, MAIL_ATTR_ACT_PROTO_NAME) == 0) {
653 		if (have_log_client_attr == 0 && message->client_proto == 0)
654 		    message->client_proto = mystrdup(value);
655 	    } else if (strcmp(name, MAIL_ATTR_ACT_HELO_NAME) == 0) {
656 		if (have_log_client_attr == 0 && message->client_helo == 0)
657 		    message->client_helo = mystrdup(value);
658 	    }
659 	    /* Original client attributes. */
660 	    else if (strcmp(name, MAIL_ATTR_LOG_CLIENT_NAME) == 0) {
661 		if (message->client_name != 0)
662 		    myfree(message->client_name);
663 		message->client_name = mystrdup(value);
664 		have_log_client_attr = 1;
665 	    } else if (strcmp(name, MAIL_ATTR_LOG_CLIENT_ADDR) == 0) {
666 		if (message->client_addr != 0)
667 		    myfree(message->client_addr);
668 		message->client_addr = mystrdup(value);
669 		have_log_client_attr = 1;
670 	    } else if (strcmp(name, MAIL_ATTR_LOG_CLIENT_PORT) == 0) {
671 		if (message->client_port != 0)
672 		    myfree(message->client_port);
673 		message->client_port = mystrdup(value);
674 		have_log_client_attr = 1;
675 	    } else if (strcmp(name, MAIL_ATTR_LOG_PROTO_NAME) == 0) {
676 		if (message->client_proto != 0)
677 		    myfree(message->client_proto);
678 		message->client_proto = mystrdup(value);
679 		have_log_client_attr = 1;
680 	    } else if (strcmp(name, MAIL_ATTR_LOG_HELO_NAME) == 0) {
681 		if (message->client_helo != 0)
682 		    myfree(message->client_helo);
683 		message->client_helo = mystrdup(value);
684 		have_log_client_attr = 1;
685 	    } else if (strcmp(name, MAIL_ATTR_SASL_METHOD) == 0) {
686 		if (message->sasl_method == 0)
687 		    message->sasl_method = mystrdup(value);
688 		else
689 		    msg_warn("%s: ignoring multiple %s attribute: %s",
690 			   message->queue_id, MAIL_ATTR_SASL_METHOD, value);
691 	    } else if (strcmp(name, MAIL_ATTR_SASL_USERNAME) == 0) {
692 		if (message->sasl_username == 0)
693 		    message->sasl_username = mystrdup(value);
694 		else
695 		    msg_warn("%s: ignoring multiple %s attribute: %s",
696 			 message->queue_id, MAIL_ATTR_SASL_USERNAME, value);
697 	    } else if (strcmp(name, MAIL_ATTR_SASL_SENDER) == 0) {
698 		if (message->sasl_sender == 0)
699 		    message->sasl_sender = mystrdup(value);
700 		else
701 		    msg_warn("%s: ignoring multiple %s attribute: %s",
702 			   message->queue_id, MAIL_ATTR_SASL_SENDER, value);
703 	    } else if (strcmp(name, MAIL_ATTR_LOG_IDENT) == 0) {
704 		if (message->log_ident == 0)
705 		    message->log_ident = mystrdup(value);
706 		else
707 		    msg_warn("%s: ignoring multiple %s attribute: %s",
708 			     message->queue_id, MAIL_ATTR_LOG_IDENT, value);
709 	    } else if (strcmp(name, MAIL_ATTR_RWR_CONTEXT) == 0) {
710 		if (message->rewrite_context == 0)
711 		    message->rewrite_context = mystrdup(value);
712 		else
713 		    msg_warn("%s: ignoring multiple %s attribute: %s",
714 			   message->queue_id, MAIL_ATTR_RWR_CONTEXT, value);
715 	    }
716 
717 	    /*
718 	     * Optional tracing flags (verify, sendmail -v, sendmail -bv).
719 	     * This record is killed after a trace logfile report is sent and
720 	     * after the logfile is deleted.
721 	     */
722 	    else if (strcmp(name, MAIL_ATTR_TRACE_FLAGS) == 0) {
723 		if (message->tflags == 0) {
724 		    message->tflags = DEL_REQ_TRACE_FLAGS(atoi(value));
725 		    if (message->tflags == DEL_REQ_FLAG_RECORD)
726 			message->tflags_offset = curr_offset;
727 		    else
728 			message->tflags_offset = 0;
729 		    if ((message->tflags & DEL_REQ_FLAG_MTA_VRFY) != 0)
730 			qmgr_vrfy_pend_count++;
731 		}
732 	    }
733 	    continue;
734 	}
735 	if (rec_type == REC_TYPE_WARN) {
736 	    if (message->warn_offset == 0) {
737 		message->warn_offset = curr_offset;
738 		REC_TYPE_WARN_SCAN(start, message->warn_time);
739 	    }
740 	    continue;
741 	}
742 	if (rec_type == REC_TYPE_VERP) {
743 	    if (message->verp_delims == 0) {
744 		if (message->sender == 0 || message->sender[0] == 0) {
745 		    msg_warn("%s: ignoring VERP request for null sender",
746 			     message->queue_id);
747 		} else if (verp_delims_verify(start) != 0) {
748 		    msg_warn("%s: ignoring bad VERP request: \"%.100s\"",
749 			     message->queue_id, start);
750 		} else {
751 		    if (msg_verbose)
752 			msg_info("%s: enabling VERP for sender \"%.100s\"",
753 				 message->queue_id, message->sender);
754 		    message->single_rcpt = 1;
755 		    message->verp_delims = mystrdup(start);
756 		}
757 	    }
758 	    continue;
759 	}
760     }
761 
762     /*
763      * Grr.
764      */
765     if (dsn_orcpt != 0) {
766 	if (rec_type > 0)
767 	    msg_warn("%s: ignoring out-of-order DSN original recipient <%.200s>",
768 		     message->queue_id, dsn_orcpt);
769 	myfree(dsn_orcpt);
770     }
771     if (orig_rcpt != 0) {
772 	if (rec_type > 0)
773 	    msg_warn("%s: ignoring out-of-order original recipient <%.200s>",
774 		     message->queue_id, orig_rcpt);
775 	myfree(orig_rcpt);
776     }
777 
778     /*
779      * After sending a "delayed" warning, request sender notification when
780      * message delivery is completed. While "mail delayed" notifications are
781      * bad enough because they multiply the amount of email traffic, "delay
782      * cleared" notifications are even worse because they come in a sudden
783      * burst when the queue drains after a network outage.
784      */
785     if (var_dsn_delay_cleared && message->warn_time < 0)
786 	message->tflags |= DEL_REQ_FLAG_REC_DLY_SENT;
787 
788     /*
789      * Avoid clumsiness elsewhere in the program. When sending data across an
790      * IPC channel, sending an empty string is more convenient than sending a
791      * null pointer.
792      */
793     if (message->dsn_envid == 0)
794 	message->dsn_envid = mystrdup("");
795     if (message->encoding == 0)
796 	message->encoding = mystrdup(MAIL_ATTR_ENC_NONE);
797     if (message->client_name == 0)
798 	message->client_name = mystrdup("");
799     if (message->client_addr == 0)
800 	message->client_addr = mystrdup("");
801     if (message->client_port == 0)
802 	message->client_port = mystrdup("");
803     if (message->client_proto == 0)
804 	message->client_proto = mystrdup("");
805     if (message->client_helo == 0)
806 	message->client_helo = mystrdup("");
807     if (message->sasl_method == 0)
808 	message->sasl_method = mystrdup("");
809     if (message->sasl_username == 0)
810 	message->sasl_username = mystrdup("");
811     if (message->sasl_sender == 0)
812 	message->sasl_sender = mystrdup("");
813     if (message->log_ident == 0)
814 	message->log_ident = mystrdup("");
815     if (message->rewrite_context == 0)
816 	message->rewrite_context = mystrdup(MAIL_ATTR_RWR_LOCAL);
817     /* Postfix < 2.3 compatibility. */
818     if (message->create_time == 0)
819 	message->create_time = message->arrival_time.tv_sec;
820 
821     /*
822      * Clean up.
823      */
824     vstring_free(buf);
825 
826     /*
827      * Sanity checks. Verify that all required information was found,
828      * including the queue file end marker.
829      */
830     if (rec_type <= 0) {
831 	/* Already logged warning. */
832     } else if (message->arrival_time.tv_sec == 0) {
833 	msg_warn("%s: message rejected: missing arrival time record",
834 		 message->queue_id);
835     } else if (message->sender == 0) {
836 	msg_warn("%s: message rejected: missing sender record",
837 		 message->queue_id);
838     } else if (message->data_offset == 0) {
839 	msg_warn("%s: message rejected: missing size record",
840 		 message->queue_id);
841     } else {
842 	return (0);
843     }
844     message->rcpt_offset = save_offset;		/* restore flag */
845     return (-1);
846 }
847 
848 /* qmgr_message_update_warn - update the time of next delay warning */
849 
qmgr_message_update_warn(QMGR_MESSAGE * message)850 void    qmgr_message_update_warn(QMGR_MESSAGE *message)
851 {
852 
853     /*
854      * After the "mail delayed" warning, optionally send a "delay cleared"
855      * notification.
856      */
857     if (qmgr_message_open(message)
858 	|| vstream_fseek(message->fp, message->warn_offset, SEEK_SET) < 0
859 	|| rec_fprintf(message->fp, REC_TYPE_WARN, REC_TYPE_WARN_FORMAT,
860 		       REC_TYPE_WARN_ARG(-1)) < 0
861 	|| vstream_fflush(message->fp))
862 	msg_fatal("update queue file %s: %m", VSTREAM_PATH(message->fp));
863     qmgr_message_close(message);
864 }
865 
866 /* qmgr_message_kill_record - mark one message record as killed */
867 
qmgr_message_kill_record(QMGR_MESSAGE * message,long offset)868 void    qmgr_message_kill_record(QMGR_MESSAGE *message, long offset)
869 {
870     if (offset <= 0)
871 	msg_panic("qmgr_message_kill_record: bad offset 0x%lx", offset);
872     if (qmgr_message_open(message)
873 	|| rec_put_type(message->fp, REC_TYPE_KILL, offset) < 0
874 	|| vstream_fflush(message->fp))
875 	msg_fatal("update queue file %s: %m", VSTREAM_PATH(message->fp));
876     qmgr_message_close(message);
877 }
878 
879 /* qmgr_message_sort_compare - compare recipient information */
880 
qmgr_message_sort_compare(const void * p1,const void * p2)881 static int qmgr_message_sort_compare(const void *p1, const void *p2)
882 {
883     RECIPIENT *rcpt1 = (RECIPIENT *) p1;
884     RECIPIENT *rcpt2 = (RECIPIENT *) p2;
885     QMGR_QUEUE *queue1;
886     QMGR_QUEUE *queue2;
887     char   *at1;
888     char   *at2;
889     int     result;
890 
891     /*
892      * Compare most significant to least significant recipient attributes.
893      * The comparison function must be transitive, so NULL values need to be
894      * assigned an ordinal (we set NULL last).
895      */
896 
897     queue1 = rcpt1->u.queue;
898     queue2 = rcpt2->u.queue;
899     if (queue1 != 0 && queue2 == 0)
900 	return (-1);
901     if (queue1 == 0 && queue2 != 0)
902 	return (1);
903     if (queue1 != 0 && queue2 != 0) {
904 
905 	/*
906 	 * Compare message transport.
907 	 */
908 	if ((result = strcmp(queue1->transport->name,
909 			     queue2->transport->name)) != 0)
910 	    return (result);
911 
912 	/*
913 	 * Compare queue name (nexthop or recipient@nexthop).
914 	 */
915 	if ((result = strcmp(queue1->name, queue2->name)) != 0)
916 	    return (result);
917     }
918 
919     /*
920      * Compare recipient domain.
921      */
922     at1 = strrchr(rcpt1->address, '@');
923     at2 = strrchr(rcpt2->address, '@');
924     if (at1 == 0 && at2 != 0)
925 	return (1);
926     if (at1 != 0 && at2 == 0)
927 	return (-1);
928     if (at1 != 0 && at2 != 0
929 	&& (result = strcasecmp_utf8(at1, at2)) != 0)
930 	return (result);
931 
932     /*
933      * Compare recipient address.
934      */
935     return (strcasecmp_utf8(rcpt1->address, rcpt2->address));
936 }
937 
938 /* qmgr_message_sort - sort message recipient addresses by domain */
939 
qmgr_message_sort(QMGR_MESSAGE * message)940 static void qmgr_message_sort(QMGR_MESSAGE *message)
941 {
942     qsort((void *) message->rcpt_list.info, message->rcpt_list.len,
943 	  sizeof(message->rcpt_list.info[0]), qmgr_message_sort_compare);
944     if (msg_verbose) {
945 	RECIPIENT_LIST list = message->rcpt_list;
946 	RECIPIENT *rcpt;
947 
948 	msg_info("start sorted recipient list");
949 	for (rcpt = list.info; rcpt < list.info + list.len; rcpt++)
950 	    msg_info("qmgr_message_sort: %s", rcpt->address);
951 	msg_info("end sorted recipient list");
952     }
953 }
954 
955 /* qmgr_resolve_one - resolve or skip one recipient */
956 
qmgr_resolve_one(QMGR_MESSAGE * message,RECIPIENT * recipient,const char * addr,RESOLVE_REPLY * reply)957 static int qmgr_resolve_one(QMGR_MESSAGE *message, RECIPIENT *recipient,
958 			            const char *addr, RESOLVE_REPLY *reply)
959 {
960 #define QMGR_REDIRECT(rp, tp, np) do { \
961 	(rp)->flags = 0; \
962 	vstring_strcpy((rp)->transport, (tp)); \
963 	vstring_strcpy((rp)->nexthop, (np)); \
964     } while (0)
965 
966     if ((message->tflags & DEL_REQ_FLAG_MTA_VRFY) == 0)
967 	resolve_clnt_query_from(message->sender, addr, reply);
968     else
969 	resolve_clnt_verify_from(message->sender, addr, reply);
970     if (reply->flags & RESOLVE_FLAG_FAIL) {
971 	QMGR_REDIRECT(reply, MAIL_SERVICE_RETRY,
972 		      "4.3.0 address resolver failure");
973 	return (0);
974     } else if (reply->flags & RESOLVE_FLAG_ERROR) {
975 	QMGR_REDIRECT(reply, MAIL_SERVICE_ERROR,
976 		      "5.1.3 bad address syntax");
977 	return (0);
978     } else {
979 	return (0);
980     }
981 }
982 
983 /* qmgr_message_resolve - resolve recipients */
984 
qmgr_message_resolve(QMGR_MESSAGE * message)985 static void qmgr_message_resolve(QMGR_MESSAGE *message)
986 {
987     static ARGV *defer_xport_argv;
988     RECIPIENT_LIST list = message->rcpt_list;
989     RECIPIENT *recipient;
990     QMGR_TRANSPORT *transport = 0;
991     QMGR_QUEUE *queue = 0;
992     RESOLVE_REPLY reply;
993     VSTRING *queue_name;
994     char   *at;
995     char  **cpp;
996     char   *nexthop;
997     ssize_t len;
998     int     status;
999     DSN     dsn;
1000     MSG_STATS stats;
1001     DSN    *saved_dsn;
1002 
1003 #define STREQ(x,y)	(strcmp(x,y) == 0)
1004 #define STR		vstring_str
1005 #define LEN		VSTRING_LEN
1006 
1007     resolve_clnt_init(&reply);
1008     queue_name = vstring_alloc(1);
1009     for (recipient = list.info; recipient < list.info + list.len; recipient++) {
1010 
1011 	/*
1012 	 * Redirect overrides all else. But only once (per entire message).
1013 	 * For consistency with the remainder of Postfix, rewrite the address
1014 	 * to canonical form before resolving it.
1015 	 */
1016 	if (message->redirect_addr) {
1017 	    if (recipient > list.info) {
1018 		recipient->u.queue = 0;
1019 		continue;
1020 	    }
1021 	    message->rcpt_offset = 0;
1022 	    rewrite_clnt_internal(REWRITE_CANON, message->redirect_addr,
1023 				  reply.recipient);
1024 	    RECIPIENT_UPDATE(recipient->address, STR(reply.recipient));
1025 	    if (qmgr_resolve_one(message, recipient,
1026 				 recipient->address, &reply) < 0)
1027 		continue;
1028 	    if (!STREQ(recipient->address, STR(reply.recipient)))
1029 		RECIPIENT_UPDATE(recipient->address, STR(reply.recipient));
1030 	}
1031 
1032 	/*
1033 	 * Content filtering overrides the address resolver.
1034 	 *
1035 	 * XXX Bypass content_filter inspection for user-generated probes
1036 	 * (sendmail -bv). MTA-generated probes never have the "please filter
1037 	 * me" bits turned on, but we handle them here anyway for the sake of
1038 	 * future proofing.
1039 	 */
1040 #define FILTER_WITHOUT_NEXTHOP(filter, next) \
1041 	(((next) = split_at((filter), ':')) == 0 || *(next) == 0)
1042 
1043 #define RCPT_WITHOUT_DOMAIN(rcpt, next) \
1044 	((next = strrchr(rcpt, '@')) == 0 || *++(next) == 0)
1045 
1046 	else if (message->filter_xport
1047 		 && (message->tflags & DEL_REQ_TRACE_ONLY_MASK) == 0) {
1048 	    reply.flags = 0;
1049 	    vstring_strcpy(reply.transport, message->filter_xport);
1050 	    if (FILTER_WITHOUT_NEXTHOP(STR(reply.transport), nexthop)
1051 		&& *(nexthop = var_def_filter_nexthop) == 0
1052 		&& RCPT_WITHOUT_DOMAIN(recipient->address, nexthop))
1053 		nexthop = var_myhostname;
1054 	    vstring_strcpy(reply.nexthop, nexthop);
1055 	    vstring_strcpy(reply.recipient, recipient->address);
1056 	}
1057 
1058 	/*
1059 	 * Resolve the destination to (transport, nexthop, address). The
1060 	 * result address may differ from the one specified by the sender.
1061 	 */
1062 	else {
1063 	    if (qmgr_resolve_one(message, recipient,
1064 				 recipient->address, &reply) < 0)
1065 		continue;
1066 	    if (!STREQ(recipient->address, STR(reply.recipient)))
1067 		RECIPIENT_UPDATE(recipient->address, STR(reply.recipient));
1068 	}
1069 
1070 	/*
1071 	 * Bounce null recipients. This should never happen, but is most
1072 	 * likely the result of a fault in a different program, so aborting
1073 	 * the queue manager process does not help.
1074 	 */
1075 	if (recipient->address[0] == 0) {
1076 	    QMGR_REDIRECT(&reply, MAIL_SERVICE_ERROR,
1077 			  "5.1.3 null recipient address");
1078 	}
1079 
1080 	/*
1081 	 * Redirect a forced-to-expire message without defer log to the retry
1082 	 * service, so that its defer log will contain an appropriate reason.
1083 	 * Do not redirect such a message to the error service, because if
1084 	 * that request fails, a defer log would be created with reason
1085 	 * "bounce or trace service failure" which would make no sense. Note
1086 	 * that if the bounce service fails to create a defer log, the
1087 	 * message will be returned as undeliverable anyway, because it is
1088 	 * expired.
1089 	 */
1090 	if ((message->qflags & QMGR_FORCE_EXPIRE) != 0) {
1091 	    QMGR_REDIRECT(&reply, MAIL_SERVICE_RETRY,
1092 			  "4.7.0 message is administratively expired");
1093 	}
1094 
1095 	/*
1096 	 * Discard mail to the local double bounce address here, so this
1097 	 * system can run without a local delivery agent. They'd still have
1098 	 * to configure something for mail directed to the local postmaster,
1099 	 * though, but that is an RFC requirement anyway.
1100 	 *
1101 	 * XXX This lookup should be done in the resolver, and the mail should
1102 	 * be directed to a general-purpose null delivery agent.
1103 	 */
1104 	if (reply.flags & RESOLVE_CLASS_LOCAL) {
1105 	    at = strrchr(STR(reply.recipient), '@');
1106 	    len = (at ? (at - STR(reply.recipient))
1107 		   : strlen(STR(reply.recipient)));
1108 	    if (strncasecmp_utf8(STR(reply.recipient),
1109 				 var_double_bounce_sender, len) == 0
1110 		&& !var_double_bounce_sender[len]) {
1111 		status = sent(message->tflags, message->queue_id,
1112 			      QMGR_MSG_STATS(&stats, message), recipient,
1113 			      "none", DSN_SIMPLE(&dsn, "2.0.0",
1114 			"undeliverable postmaster notification discarded"));
1115 		if (status == 0) {
1116 		    deliver_completed(message->fp, recipient->offset);
1117 #if 0
1118 		    /* It's the default verification probe sender address. */
1119 		    msg_warn("%s: undeliverable postmaster notification discarded",
1120 			     message->queue_id);
1121 #endif
1122 		} else
1123 		    message->flags |= status;
1124 		continue;
1125 	    }
1126 	}
1127 
1128 	/*
1129 	 * Optionally defer deliveries over specific transports, unless the
1130 	 * restriction is lifted temporarily.
1131 	 */
1132 	if (*var_defer_xports && (message->qflags & QMGR_FLUSH_DFXP) == 0) {
1133 	    if (defer_xport_argv == 0)
1134 		defer_xport_argv = argv_split(var_defer_xports, CHARS_COMMA_SP);
1135 	    for (cpp = defer_xport_argv->argv; *cpp; cpp++)
1136 		if (strcmp(*cpp, STR(reply.transport)) == 0)
1137 		    break;
1138 	    if (*cpp) {
1139 		QMGR_REDIRECT(&reply, MAIL_SERVICE_RETRY,
1140 			      "4.3.2 deferred transport");
1141 	    }
1142 	}
1143 
1144 	/*
1145 	 * Safety: defer excess address verification requests.
1146 	 */
1147 	if ((message->tflags & DEL_REQ_FLAG_MTA_VRFY) != 0
1148 	    && qmgr_vrfy_pend_count > var_vrfy_pend_limit)
1149 	    QMGR_REDIRECT(&reply, MAIL_SERVICE_RETRY,
1150 			  "4.3.2 Too many address verification requests");
1151 
1152 	/*
1153 	 * Look up or instantiate the proper transport.
1154 	 */
1155 	if (transport == 0 || !STREQ(transport->name, STR(reply.transport))) {
1156 	    if ((transport = qmgr_transport_find(STR(reply.transport))) == 0)
1157 		transport = qmgr_transport_create(STR(reply.transport));
1158 	    queue = 0;
1159 	}
1160 
1161 	/*
1162 	 * This message is being flushed. If need-be unthrottle the
1163 	 * transport.
1164 	 */
1165 	if ((message->qflags & QMGR_FLUSH_EACH) != 0
1166 	    && QMGR_TRANSPORT_THROTTLED(transport))
1167 	    qmgr_transport_unthrottle(transport);
1168 
1169 	/*
1170 	 * This transport is dead. Defer delivery to this recipient.
1171 	 */
1172 	if (QMGR_TRANSPORT_THROTTLED(transport)) {
1173 	    saved_dsn = transport->dsn;
1174 	    if ((transport = qmgr_error_transport(MAIL_SERVICE_RETRY)) != 0) {
1175 		nexthop = qmgr_error_nexthop(saved_dsn);
1176 		vstring_strcpy(reply.nexthop, nexthop);
1177 		myfree(nexthop);
1178 		queue = 0;
1179 	    } else {
1180 		qmgr_defer_recipient(message, recipient, saved_dsn);
1181 		continue;
1182 	    }
1183 	}
1184 
1185 	/*
1186 	 * The nexthop destination provides the default name for the
1187 	 * per-destination queue. When the delivery agent accepts only one
1188 	 * recipient per delivery, give each recipient its own queue, so that
1189 	 * deliveries to different recipients of the same message can happen
1190 	 * in parallel, and so that we can enforce per-recipient concurrency
1191 	 * limits and prevent one recipient from tying up all the delivery
1192 	 * agent resources. We use recipient@nexthop as queue name rather
1193 	 * than the actual recipient domain name, so that one recipient in
1194 	 * multiple equivalent domains cannot evade the per-recipient
1195 	 * concurrency limit. Split the address on the recipient delimiter if
1196 	 * one is defined, so that extended addresses don't get extra
1197 	 * delivery slots.
1198 	 *
1199 	 * Fold the result to lower case so that we don't have multiple queues
1200 	 * for the same name.
1201 	 *
1202 	 * Important! All recipients in a queue must have the same nexthop
1203 	 * value. It is OK to have multiple queues with the same nexthop
1204 	 * value, but only when those queues are named after recipients.
1205 	 *
1206 	 * The single-recipient code below was written for local(8) like
1207 	 * delivery agents, and assumes that all domains that deliver to the
1208 	 * same (transport + nexthop) are aliases for $nexthop. Delivery
1209 	 * concurrency is changed from per-domain into per-recipient, by
1210 	 * changing the queue name from nexthop into localpart@nexthop.
1211 	 *
1212 	 * XXX This assumption is incorrect when different destinations share
1213 	 * the same (transport + nexthop). In reality, such transports are
1214 	 * rarely configured to use single-recipient deliveries. The fix is
1215 	 * to decouple the per-destination recipient limit from the
1216 	 * per-destination concurrency.
1217 	 */
1218 	vstring_strcpy(queue_name, STR(reply.nexthop));
1219 	if (strcmp(transport->name, MAIL_SERVICE_ERROR) != 0
1220 	    && strcmp(transport->name, MAIL_SERVICE_RETRY) != 0
1221 	    && transport->recipient_limit == 1) {
1222 	    /* Copy the recipient localpart. */
1223 	    at = strrchr(STR(reply.recipient), '@');
1224 	    len = (at ? (at - STR(reply.recipient))
1225 		   : strlen(STR(reply.recipient)));
1226 	    vstring_strncpy(queue_name, STR(reply.recipient), len);
1227 	    /* Remove the address extension from the recipient localpart. */
1228 	    if (*var_rcpt_delim && split_addr(STR(queue_name), var_rcpt_delim))
1229 		vstring_truncate(queue_name, strlen(STR(queue_name)));
1230 	    /* Assume the recipient domain is equivalent to nexthop. */
1231 	    vstring_sprintf_append(queue_name, "@%s", STR(reply.nexthop));
1232 	}
1233 	lowercase(STR(queue_name));
1234 
1235 	/*
1236 	 * This transport is alive. Find or instantiate a queue for this
1237 	 * recipient.
1238 	 */
1239 	if (queue == 0 || !STREQ(queue->name, STR(queue_name))) {
1240 	    if ((queue = qmgr_queue_find(transport, STR(queue_name))) == 0)
1241 		queue = qmgr_queue_create(transport, STR(queue_name),
1242 					  STR(reply.nexthop));
1243 	}
1244 
1245 	/*
1246 	 * This message is being flushed. If need-be unthrottle the queue.
1247 	 */
1248 	if ((message->qflags & QMGR_FLUSH_EACH) != 0
1249 	    && QMGR_QUEUE_THROTTLED(queue))
1250 	    qmgr_queue_unthrottle(queue);
1251 
1252 	/*
1253 	 * This queue is dead. Defer delivery to this recipient.
1254 	 */
1255 	if (QMGR_QUEUE_THROTTLED(queue)) {
1256 	    saved_dsn = queue->dsn;
1257 	    if ((queue = qmgr_error_queue(MAIL_SERVICE_RETRY, saved_dsn)) == 0) {
1258 		qmgr_defer_recipient(message, recipient, saved_dsn);
1259 		continue;
1260 	    }
1261 	}
1262 
1263 	/*
1264 	 * This queue is alive. Bind this recipient to this queue instance.
1265 	 */
1266 	recipient->u.queue = queue;
1267     }
1268     resolve_clnt_free(&reply);
1269     vstring_free(queue_name);
1270 }
1271 
1272 /* qmgr_message_assign - assign recipients to specific delivery requests */
1273 
qmgr_message_assign(QMGR_MESSAGE * message)1274 static void qmgr_message_assign(QMGR_MESSAGE *message)
1275 {
1276     RECIPIENT_LIST list = message->rcpt_list;
1277     RECIPIENT *recipient;
1278     QMGR_ENTRY *entry = 0;
1279     QMGR_QUEUE *queue;
1280 
1281     /*
1282      * Try to bundle as many recipients in a delivery request as we can. When
1283      * the recipient resolves to the same site and transport as the previous
1284      * recipient, do not create a new queue entry, just move that recipient
1285      * to the recipient list of the existing queue entry. All this provided
1286      * that we do not exceed the transport-specific limit on the number of
1287      * recipients per transaction. Skip recipients with a dead transport or
1288      * destination.
1289      */
1290 #define LIMIT_OK(limit, count) ((limit) == 0 || ((count) < (limit)))
1291 
1292     for (recipient = list.info; recipient < list.info + list.len; recipient++) {
1293 	if ((queue = recipient->u.queue) != 0) {
1294 	    if (message->single_rcpt || entry == 0 || entry->queue != queue
1295 		|| !LIMIT_OK(entry->queue->transport->recipient_limit,
1296 			     entry->rcpt_list.len)) {
1297 		entry = qmgr_entry_create(queue, message);
1298 	    }
1299 	    recipient_list_add(&entry->rcpt_list, recipient->offset,
1300 			       recipient->dsn_orcpt, recipient->dsn_notify,
1301 			       recipient->orig_addr, recipient->address);
1302 	    qmgr_recipient_count++;
1303 	}
1304     }
1305     recipient_list_free(&message->rcpt_list);
1306     recipient_list_init(&message->rcpt_list, RCPT_LIST_INIT_QUEUE);
1307 }
1308 
1309 /* qmgr_message_free - release memory for in-core message structure */
1310 
qmgr_message_free(QMGR_MESSAGE * message)1311 void    qmgr_message_free(QMGR_MESSAGE *message)
1312 {
1313     if (message->refcount != 0)
1314 	msg_panic("qmgr_message_free: reference len: %d", message->refcount);
1315     if (message->fp)
1316 	msg_panic("qmgr_message_free: queue file is open");
1317     myfree(message->queue_id);
1318     myfree(message->queue_name);
1319     if (message->dsn_envid)
1320 	myfree(message->dsn_envid);
1321     if (message->encoding)
1322 	myfree(message->encoding);
1323     if (message->sender)
1324 	myfree(message->sender);
1325     if (message->verp_delims)
1326 	myfree(message->verp_delims);
1327     if (message->filter_xport)
1328 	myfree(message->filter_xport);
1329     if (message->inspect_xport)
1330 	myfree(message->inspect_xport);
1331     if (message->redirect_addr)
1332 	myfree(message->redirect_addr);
1333     if (message->client_name)
1334 	myfree(message->client_name);
1335     if (message->client_addr)
1336 	myfree(message->client_addr);
1337     if (message->client_port)
1338 	myfree(message->client_port);
1339     if (message->client_proto)
1340 	myfree(message->client_proto);
1341     if (message->client_helo)
1342 	myfree(message->client_helo);
1343     if (message->sasl_method)
1344 	myfree(message->sasl_method);
1345     if (message->sasl_username)
1346 	myfree(message->sasl_username);
1347     if (message->sasl_sender)
1348 	myfree(message->sasl_sender);
1349     if (message->log_ident)
1350 	myfree(message->log_ident);
1351     if (message->rewrite_context)
1352 	myfree(message->rewrite_context);
1353     recipient_list_free(&message->rcpt_list);
1354     qmgr_message_count--;
1355     if ((message->tflags & DEL_REQ_FLAG_MTA_VRFY) != 0)
1356 	qmgr_vrfy_pend_count--;
1357     myfree((void *) message);
1358 }
1359 
1360 /* qmgr_message_alloc - create in-core message structure */
1361 
qmgr_message_alloc(const char * queue_name,const char * queue_id,int qflags,mode_t mode)1362 QMGR_MESSAGE *qmgr_message_alloc(const char *queue_name, const char *queue_id,
1363 				         int qflags, mode_t mode)
1364 {
1365     const char *myname = "qmgr_message_alloc";
1366     QMGR_MESSAGE *message;
1367     struct stat st;
1368 
1369     if (msg_verbose)
1370 	msg_info("%s: %s %s", myname, queue_name, queue_id);
1371 
1372     /*
1373      * Create an in-core message structure.
1374      */
1375     message = qmgr_message_create(queue_name, queue_id, qflags);
1376 
1377     /*
1378      * Extract message envelope information: time of arrival, sender address,
1379      * recipient addresses. Skip files with malformed envelope information.
1380      */
1381 #define QMGR_LOCK_MODE (MYFLOCK_OP_EXCLUSIVE | MYFLOCK_OP_NOWAIT)
1382 
1383     if (qmgr_message_open(message) < 0) {
1384 	qmgr_message_free(message);
1385 	return (0);
1386     }
1387     if (myflock(vstream_fileno(message->fp), INTERNAL_LOCK, QMGR_LOCK_MODE) < 0) {
1388 	msg_info("%s: skipped, still being delivered", queue_id);
1389 	qmgr_message_close(message);
1390 	qmgr_message_free(message);
1391 	return (QMGR_MESSAGE_LOCKED);
1392     }
1393     if (qmgr_message_read(message) < 0) {
1394 	qmgr_message_close(message);
1395 	qmgr_message_free(message);
1396 	return (0);
1397     } else {
1398 
1399 	/*
1400 	 * We have validated the queue file content, so it is safe to modify
1401 	 * the file properties now.
1402 	 */
1403 	if (mode != 0 && fchmod(vstream_fileno(message->fp), mode) < 0)
1404 	    msg_fatal("fchmod %s: %m", VSTREAM_PATH(message->fp));
1405 
1406 	/*
1407 	 * If this message is forced to expire, use the existing defer
1408 	 * logfile records and do not assign any deliveries, leaving the
1409 	 * refcount at zero. If this message is forced to expire, but no
1410 	 * defer logfile records are available, assign deliveries to the
1411 	 * retry transport so that the sender will still find out what
1412 	 * recipients are affected and why. Either way, do not assign normal
1413 	 * deliveries because that would be undesirable especially with mail
1414 	 * that was expired in the 'hold' queue.
1415 	 */
1416 	if ((message->qflags & QMGR_FORCE_EXPIRE) != 0
1417 	    && stat(mail_queue_path((VSTRING *) 0, MAIL_QUEUE_DEFER,
1418 				    queue_id), &st) == 0 && st.st_size > 0) {
1419 	    /* Use this defer log; don't assign deliveries (refcount == 0). */
1420 	    message->flags = 1;			/* simplify downstream code */
1421 	    qmgr_message_close(message);
1422 	    return (message);
1423 	}
1424 
1425 	/*
1426 	 * Reset the defer log. This code should not be here, but we must
1427 	 * reset the defer log *after* acquiring the exclusive lock on the
1428 	 * queue file and *before* resolving new recipients. Since all those
1429 	 * operations are encapsulated so nicely by this routine, the defer
1430 	 * log reset has to be done here as well.
1431 	 *
1432 	 * Note: it is safe to remove the defer logfile from a previous queue
1433 	 * run of this queue file, because the defer log contains information
1434 	 * about recipients that still exist in this queue file.
1435 	 */
1436 	if (mail_queue_remove(MAIL_QUEUE_DEFER, queue_id) && errno != ENOENT)
1437 	    msg_fatal("%s: %s: remove %s %s: %m", myname,
1438 		      queue_id, MAIL_QUEUE_DEFER, queue_id);
1439 	qmgr_message_sort(message);
1440 	qmgr_message_resolve(message);
1441 	qmgr_message_sort(message);
1442 	qmgr_message_assign(message);
1443 	qmgr_message_close(message);
1444 	return (message);
1445     }
1446 }
1447 
1448 /* qmgr_message_realloc - refresh in-core message structure */
1449 
qmgr_message_realloc(QMGR_MESSAGE * message)1450 QMGR_MESSAGE *qmgr_message_realloc(QMGR_MESSAGE *message)
1451 {
1452     const char *myname = "qmgr_message_realloc";
1453 
1454     /*
1455      * Sanity checks.
1456      */
1457     if (message->rcpt_offset <= 0)
1458 	msg_panic("%s: invalid offset: %ld", myname, message->rcpt_offset);
1459     if (msg_verbose)
1460 	msg_info("%s: %s %s offset %ld", myname, message->queue_name,
1461 		 message->queue_id, message->rcpt_offset);
1462 
1463     /*
1464      * Extract recipient addresses. Skip files with malformed envelope
1465      * information.
1466      */
1467     if (qmgr_message_open(message) < 0)
1468 	return (0);
1469     if (qmgr_message_read(message) < 0) {
1470 	qmgr_message_close(message);
1471 	return (0);
1472     } else {
1473 	qmgr_message_sort(message);
1474 	qmgr_message_resolve(message);
1475 	qmgr_message_sort(message);
1476 	qmgr_message_assign(message);
1477 	qmgr_message_close(message);
1478 	return (message);
1479     }
1480 }
1481