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