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