1 # include <signal.h> 2 # include <errno.h> 3 # include "sendmail.h" 4 # include <sys/stat.h> 5 # ifdef LOG 6 # include <syslog.h> 7 # endif LOG 8 9 static char SccsId[] = "@(#)deliver.c 3.53 11/11/81"; 10 11 /* 12 ** DELIVER -- Deliver a message to a list of addresses. 13 ** 14 ** This routine delivers to everyone on the same host as the 15 ** user on the head of the list. It is clever about mailers 16 ** that don't handle multiple users. It is NOT guaranteed 17 ** that it will deliver to all these addresses however -- so 18 ** deliver should be called once for each address on the 19 ** list. 20 ** 21 ** Parameters: 22 ** firstto -- head of the address list to deliver to. 23 ** editfcn -- if non-NULL, we want to call this function 24 ** to output the letter (instead of just out- 25 ** putting it raw). 26 ** 27 ** Returns: 28 ** zero -- successfully delivered. 29 ** else -- some failure, see ExitStat for more info. 30 ** 31 ** Side Effects: 32 ** The standard input is passed off to someone. 33 */ 34 35 deliver(firstto, editfcn) 36 ADDRESS *firstto; 37 int (*editfcn)(); 38 { 39 char *host; /* host being sent to */ 40 char *user; /* user being sent to */ 41 char **pvp; 42 register char **mvp; 43 register char *p; 44 register struct mailer *m; /* mailer for this recipient */ 45 register int i; 46 extern putmessage(); 47 extern bool checkcompat(); 48 char *pv[MAXPV+1]; 49 char tobuf[MAXLINE]; /* text line of to people */ 50 char buf[MAXNAME]; 51 ADDRESS *ctladdr; 52 extern ADDRESS *getctladdr(); 53 char tfrombuf[MAXNAME]; /* translated from person */ 54 extern char **prescan(); 55 register ADDRESS *to = firstto; 56 bool clever = FALSE; /* running user smtp to this mailer */ 57 bool tempfail = FALSE; 58 59 errno = 0; 60 if (!ForceMail && bitset(QDONTSEND, to->q_flags)) 61 return (0); 62 63 # ifdef DEBUG 64 if (Debug) 65 printf("\n--deliver, mailer=%d, host=`%s', first user=`%s'\n", 66 to->q_mailer->m_mno, to->q_host, to->q_user); 67 # endif DEBUG 68 69 /* 70 ** Do initial argv setup. 71 ** Insert the mailer name. Notice that $x expansion is 72 ** NOT done on the mailer name. Then, if the mailer has 73 ** a picky -f flag, we insert it as appropriate. This 74 ** code does not check for 'pv' overflow; this places a 75 ** manifest lower limit of 4 for MAXPV. 76 */ 77 78 m = to->q_mailer; 79 host = to->q_host; 80 81 /* rewrite from address, using rewriting rules */ 82 (void) expand(m->m_from, buf, &buf[sizeof buf - 1]); 83 mvp = prescan(buf, '\0'); 84 if (mvp == NULL) 85 { 86 syserr("bad mailer from translate \"%s\"", buf); 87 return (EX_SOFTWARE); 88 } 89 rewrite(mvp, 2); 90 cataddr(mvp, tfrombuf, sizeof tfrombuf); 91 92 define('g', tfrombuf); /* translated sender address */ 93 define('h', host); /* to host */ 94 Errors = 0; 95 pvp = pv; 96 *pvp++ = m->m_argv[0]; 97 98 /* insert -f or -r flag as appropriate */ 99 if (bitset(M_FOPT|M_ROPT, m->m_flags) && FromFlag) 100 { 101 if (bitset(M_FOPT, m->m_flags)) 102 *pvp++ = "-f"; 103 else 104 *pvp++ = "-r"; 105 (void) expand("$g", buf, &buf[sizeof buf - 1]); 106 *pvp++ = newstr(buf); 107 } 108 109 /* 110 ** Append the other fixed parts of the argv. These run 111 ** up to the first entry containing "$u". There can only 112 ** be one of these, and there are only a few more slots 113 ** in the pv after it. 114 */ 115 116 for (mvp = m->m_argv; (p = *++mvp) != NULL; ) 117 { 118 while ((p = index(p, '$')) != NULL) 119 if (*++p == 'u') 120 break; 121 if (p != NULL) 122 break; 123 124 /* this entry is safe -- go ahead and process it */ 125 (void) expand(*mvp, buf, &buf[sizeof buf - 1]); 126 *pvp++ = newstr(buf); 127 if (pvp >= &pv[MAXPV - 3]) 128 { 129 syserr("Too many parameters to %s before $u", pv[0]); 130 return (-1); 131 } 132 } 133 134 if (*mvp == NULL) 135 { 136 /* running SMTP */ 137 clever = TRUE; 138 *pvp = NULL; 139 i = smtpinit(m, pv, (ADDRESS *) NULL); 140 giveresponse(i, TRUE, m); 141 if (i == EX_TEMPFAIL) 142 { 143 QueueUp = TRUE; 144 tempfail = TRUE; 145 } 146 } 147 148 /* 149 ** At this point *mvp points to the argument with $u. We 150 ** run through our address list and append all the addresses 151 ** we can. If we run out of space, do not fret! We can 152 ** always send another copy later. 153 */ 154 155 tobuf[0] = '\0'; 156 To = tobuf; 157 ctladdr = NULL; 158 for (; to != NULL; to = to->q_next) 159 { 160 /* avoid sending multiple recipients to dumb mailers */ 161 if (tobuf[0] != '\0' && !bitset(M_MUSER, m->m_flags)) 162 break; 163 164 /* if already sent or not for this host, don't send */ 165 if ((!ForceMail && bitset(QDONTSEND, to->q_flags)) || 166 strcmp(to->q_host, host) != 0) 167 continue; 168 169 /* compute effective uid/gid when sending */ 170 if (to->q_mailer == ProgMailer) 171 ctladdr = getctladdr(to); 172 173 user = to->q_user; 174 To = to->q_paddr; 175 to->q_flags |= QDONTSEND; 176 if (tempfail) 177 to->q_flags |= QQUEUEUP; 178 # ifdef DEBUG 179 if (Debug) 180 printf(" send to `%s'\n", user); 181 # endif DEBUG 182 183 /* 184 ** Check to see that these people are allowed to 185 ** talk to each other. 186 */ 187 188 if (!checkcompat(to)) 189 { 190 giveresponse(EX_UNAVAILABLE, TRUE, m); 191 continue; 192 } 193 194 /* 195 ** Strip quote bits from names if the mailer is dumb 196 ** about them. 197 */ 198 199 if (bitset(M_STRIPQ, m->m_flags)) 200 { 201 stripquotes(user, TRUE); 202 stripquotes(host, TRUE); 203 } 204 else 205 { 206 stripquotes(user, FALSE); 207 stripquotes(host, FALSE); 208 } 209 210 /* 211 ** If an error message has already been given, don't 212 ** bother to send to this address. 213 ** 214 ** >>>>>>>>>> This clause assumes that the local mailer 215 ** >> NOTE >> cannot do any further aliasing; that 216 ** >>>>>>>>>> function is subsumed by sendmail. 217 */ 218 219 if (bitset(QBADADDR, to->q_flags)) 220 continue; 221 222 /* save statistics.... */ 223 Stat.stat_nt[to->q_mailer->m_mno]++; 224 Stat.stat_bt[to->q_mailer->m_mno] += kbytes(MsgSize); 225 226 /* 227 ** See if this user name is "special". 228 ** If the user name has a slash in it, assume that this 229 ** is a file -- send it off without further ado. 230 ** Note that this means that editfcn's will not 231 ** be applied to the message. Also note that 232 ** this type of addresses is not processed along 233 ** with the others, so we fudge on the To person. 234 */ 235 236 if (m == LocalMailer) 237 { 238 if (index(user, '/') != NULL) 239 { 240 i = mailfile(user, getctladdr(to)); 241 giveresponse(i, TRUE, m); 242 continue; 243 } 244 } 245 246 /* 247 ** Address is verified -- add this user to mailer 248 ** argv, and add it to the print list of recipients. 249 */ 250 251 /* create list of users for error messages */ 252 if (tobuf[0] != '\0') 253 (void) strcat(tobuf, ","); 254 (void) strcat(tobuf, to->q_paddr); 255 define('u', user); /* to user */ 256 define('z', to->q_home); /* user's home */ 257 258 /* 259 ** Expand out this user into argument list or 260 ** send it to our SMTP server. 261 */ 262 263 if (clever) 264 { 265 i = smtpmrcp(to); 266 if (i == EX_TEMPFAIL) 267 { 268 QueueUp = TRUE; 269 to->q_flags |= QQUEUEUP; 270 } 271 else if (i != EX_OK) 272 { 273 to->q_flags |= QBADADDR; 274 giveresponse(i, TRUE, m); 275 } 276 } 277 else 278 { 279 (void) expand(*mvp, buf, &buf[sizeof buf - 1]); 280 *pvp++ = newstr(buf); 281 if (pvp >= &pv[MAXPV - 2]) 282 { 283 /* allow some space for trailing parms */ 284 break; 285 } 286 } 287 } 288 289 /* see if any addresses still exist */ 290 if (tobuf[0] == '\0') 291 { 292 if (clever) 293 smtpquit(pv[0]); 294 return (0); 295 } 296 297 /* print out messages as full list */ 298 To = tobuf; 299 300 /* 301 ** Fill out any parameters after the $u parameter. 302 */ 303 304 while (!clever && *++mvp != NULL) 305 { 306 (void) expand(*mvp, buf, &buf[sizeof buf - 1]); 307 *pvp++ = newstr(buf); 308 if (pvp >= &pv[MAXPV]) 309 syserr("deliver: pv overflow after $u for %s", pv[0]); 310 } 311 *pvp++ = NULL; 312 313 /* 314 ** Call the mailer. 315 ** The argument vector gets built, pipes 316 ** are created as necessary, and we fork & exec as 317 ** appropriate. 318 ** If we are running SMTP, we just need to clean up. 319 */ 320 321 if (editfcn == NULL) 322 editfcn = putmessage; 323 if (ctladdr == NULL) 324 ctladdr = &From; 325 if (clever) 326 { 327 i = smtpfinish(m, editfcn); 328 smtpquit(pv[0]); 329 } 330 else 331 i = sendoff(m, pv, editfcn, ctladdr); 332 333 /* 334 ** If we got a temporary failure, arrange to queue the 335 ** addressees. 336 */ 337 338 if (i == EX_TEMPFAIL) 339 { 340 QueueUp = TRUE; 341 for (to = firstto; to != NULL; to = to->q_next) 342 { 343 if (bitset(QBADADDR, to->q_flags)) 344 continue; 345 to->q_flags |= QQUEUEUP; 346 } 347 } 348 349 errno = 0; 350 return (i); 351 } 352 /* 353 ** DOFORK -- do a fork, retrying a couple of times on failure. 354 ** 355 ** This MUST be a macro, since after a vfork we are running 356 ** two processes on the same stack!!! 357 ** 358 ** Parameters: 359 ** none. 360 ** 361 ** Returns: 362 ** From a macro??? You've got to be kidding! 363 ** 364 ** Side Effects: 365 ** Modifies the ==> LOCAL <== variable 'pid', leaving: 366 ** pid of child in parent, zero in child. 367 ** -1 on unrecoverable error. 368 ** 369 ** Notes: 370 ** I'm awfully sorry this looks so awful. That's 371 ** vfork for you..... 372 */ 373 374 # define NFORKTRIES 5 375 # ifdef VFORK 376 # define XFORK vfork 377 # else VFORK 378 # define XFORK fork 379 # endif VFORK 380 381 # define DOFORK(fORKfN) \ 382 {\ 383 register int i;\ 384 \ 385 for (i = NFORKTRIES; i-- > 0; )\ 386 {\ 387 pid = fORKfN();\ 388 if (pid >= 0)\ 389 break;\ 390 sleep((unsigned) NFORKTRIES - i);\ 391 }\ 392 } 393 /* 394 ** DOFORK -- simple fork interface to DOFORK. 395 ** 396 ** Parameters: 397 ** none. 398 ** 399 ** Returns: 400 ** pid of child in parent. 401 ** zero in child. 402 ** -1 on error. 403 ** 404 ** Side Effects: 405 ** returns twice, once in parent and once in child. 406 */ 407 408 dofork() 409 { 410 register int pid; 411 412 DOFORK(fork); 413 return (pid); 414 } 415 /* 416 ** SENDOFF -- send off call to mailer & collect response. 417 ** 418 ** Parameters: 419 ** m -- mailer descriptor. 420 ** pvp -- parameter vector to send to it. 421 ** editfcn -- function to pipe it through. 422 ** ctladdr -- an address pointer controlling the 423 ** user/groupid etc. of the mailer. 424 ** 425 ** Returns: 426 ** exit status of mailer. 427 ** 428 ** Side Effects: 429 ** none. 430 */ 431 432 sendoff(m, pvp, editfcn, ctladdr) 433 struct mailer *m; 434 char **pvp; 435 int (*editfcn)(); 436 ADDRESS *ctladdr; 437 { 438 auto FILE *mfile; 439 auto FILE *rfile; 440 register int i; 441 extern putmessage(); 442 int pid; 443 444 /* 445 ** Create connection to mailer. 446 */ 447 448 pid = openmailer(m, pvp, ctladdr, FALSE, &mfile, &rfile); 449 if (pid < 0) 450 return (-1); 451 452 /* 453 ** Format and send message. 454 */ 455 456 (void) signal(SIGPIPE, SIG_IGN); 457 if (editfcn == NULL) 458 editfcn = putmessage; 459 460 (*editfcn)(mfile, m, FALSE); 461 (void) fclose(mfile); 462 463 i = endmailer(pid, pvp[0]); 464 giveresponse(i, TRUE, m); 465 return (i); 466 } 467 /* 468 ** ENDMAILER -- Wait for mailer to terminate. 469 ** 470 ** We should never get fatal errors (e.g., segmentation 471 ** violation), so we report those specially. For other 472 ** errors, we choose a status message (into statmsg), 473 ** and if it represents an error, we print it. 474 ** 475 ** Parameters: 476 ** pid -- pid of mailer. 477 ** name -- name of mailer (for error messages). 478 ** 479 ** Returns: 480 ** exit code of mailer. 481 ** 482 ** Side Effects: 483 ** none. 484 */ 485 486 endmailer(pid, name) 487 int pid; 488 char *name; 489 { 490 register int i; 491 auto int st; 492 493 while ((i = wait(&st)) > 0 && i != pid) 494 continue; 495 if (i < 0) 496 { 497 syserr("wait"); 498 return (-1); 499 } 500 if ((st & 0377) != 0) 501 { 502 syserr("%s: stat %o", name, st); 503 ExitStat = EX_UNAVAILABLE; 504 return (-1); 505 } 506 i = (st >> 8) & 0377; 507 return (i); 508 } 509 /* 510 ** OPENMAILER -- open connection to mailer. 511 ** 512 ** Parameters: 513 ** m -- mailer descriptor. 514 ** pvp -- parameter vector to pass to mailer. 515 ** ctladdr -- controlling address for user. 516 ** clever -- create a full duplex connection. 517 ** pmfile -- pointer to mfile (to mailer) connection. 518 ** prfile -- pointer to rfile (from mailer) connection. 519 ** 520 ** Returns: 521 ** pid of mailer. 522 ** -1 on error. 523 ** 524 ** Side Effects: 525 ** creates a mailer in a subprocess. 526 */ 527 528 openmailer(m, pvp, ctladdr, clever, pmfile, prfile) 529 struct mailer *m; 530 char **pvp; 531 ADDRESS *ctladdr; 532 bool clever; 533 FILE **pmfile; 534 FILE **prfile; 535 { 536 int pid; 537 int mpvect[2]; 538 int rpvect[2]; 539 FILE *mfile; 540 FILE *rfile; 541 extern FILE *fdopen(); 542 543 # ifdef DEBUG 544 if (Debug) 545 { 546 printf("openmailer:\n"); 547 printav(pvp); 548 } 549 # endif DEBUG 550 errno = 0; 551 552 /* create a pipe to shove the mail through */ 553 if (pipe(mpvect) < 0) 554 { 555 syserr("pipe (to mailer)"); 556 return (-1); 557 } 558 559 /* if this mailer speaks smtp, create a return pipe */ 560 if (clever && pipe(rpvect) < 0) 561 { 562 syserr("pipe (from mailer)"); 563 (void) close(mpvect[0]); 564 (void) close(mpvect[1]); 565 return (-1); 566 } 567 568 DOFORK(XFORK); 569 /* pid is set by DOFORK */ 570 if (pid < 0) 571 { 572 syserr("Cannot fork"); 573 (void) close(mpvect[0]); 574 (void) close(mpvect[1]); 575 if (clever) 576 { 577 (void) close(rpvect[0]); 578 (void) close(rpvect[1]); 579 } 580 return (-1); 581 } 582 else if (pid == 0) 583 { 584 /* child -- set up input & exec mailer */ 585 /* make diagnostic output be standard output */ 586 (void) signal(SIGINT, SIG_IGN); 587 (void) signal(SIGHUP, SIG_IGN); 588 (void) signal(SIGTERM, SIG_DFL); 589 590 /* arrange to filter standard & diag output of command */ 591 if (clever) 592 { 593 (void) close(rpvect[0]); 594 (void) close(1); 595 (void) dup(rpvect[1]); 596 (void) close(rpvect[1]); 597 } 598 else if (OutChannel != stdout) 599 { 600 (void) close(1); 601 (void) dup(fileno(OutChannel)); 602 } 603 (void) close(2); 604 (void) dup(1); 605 606 /* arrange to get standard input */ 607 (void) close(mpvect[1]); 608 (void) close(0); 609 if (dup(mpvect[0]) < 0) 610 { 611 syserr("Cannot dup to zero!"); 612 _exit(EX_OSERR); 613 } 614 (void) close(mpvect[0]); 615 if (!bitset(M_RESTR, m->m_flags)) 616 { 617 if (ctladdr->q_uid == 0) 618 { 619 extern int DefUid, DefGid; 620 621 (void) setgid(DefGid); 622 (void) setuid(DefUid); 623 } 624 else 625 { 626 (void) setgid(ctladdr->q_gid); 627 (void) setuid(ctladdr->q_uid); 628 } 629 } 630 # ifndef VFORK 631 /* 632 ** We have to be careful with vfork - we can't mung up the 633 ** memory but we don't want the mailer to inherit any extra 634 ** open files. Chances are the mailer won't 635 ** care about an extra file, but then again you never know. 636 ** Actually, we would like to close(fileno(pwf)), but it's 637 ** declared static so we can't. But if we fclose(pwf), which 638 ** is what endpwent does, it closes it in the parent too and 639 ** the next getpwnam will be slower. If you have a weird 640 ** mailer that chokes on the extra file you should do the 641 ** endpwent(). 642 ** 643 ** Similar comments apply to log. However, openlog is 644 ** clever enough to set the FIOCLEX mode on the file, 645 ** so it will be closed automatically on the exec. 646 */ 647 648 endpwent(); 649 # ifdef LOG 650 closelog(); 651 # endif LOG 652 # endif VFORK 653 execv(m->m_mailer, pvp); 654 /* syserr fails because log is closed */ 655 /* syserr("Cannot exec %s", m->m_mailer); */ 656 printf("Cannot exec '%s' errno=%d\n", m->m_mailer, errno); 657 (void) fflush(stdout); 658 _exit(EX_UNAVAILABLE); 659 } 660 661 /* 662 ** Set up return value. 663 */ 664 665 (void) close(mpvect[0]); 666 mfile = fdopen(mpvect[1], "w"); 667 if (clever) 668 { 669 (void) close(rpvect[1]); 670 rfile = fdopen(rpvect[0], "r"); 671 } 672 673 *pmfile = mfile; 674 *prfile = rfile; 675 676 return (pid); 677 } 678 /* 679 ** GIVERESPONSE -- Interpret an error response from a mailer 680 ** 681 ** Parameters: 682 ** stat -- the status code from the mailer (high byte 683 ** only; core dumps must have been taken care of 684 ** already). 685 ** force -- if set, force an error message output, even 686 ** if the mailer seems to like to print its own 687 ** messages. 688 ** m -- the mailer descriptor for this mailer. 689 ** 690 ** Returns: 691 ** none. 692 ** 693 ** Side Effects: 694 ** Errors may be incremented. 695 ** ExitStat may be set. 696 */ 697 698 giveresponse(stat, force, m) 699 int stat; 700 int force; 701 register struct mailer *m; 702 { 703 register char *statmsg; 704 extern char *SysExMsg[]; 705 register int i; 706 extern int N_SysEx; 707 char buf[30]; 708 709 /* 710 ** Compute status message from code. 711 */ 712 713 i = stat - EX__BASE; 714 if (i < 0 || i > N_SysEx) 715 statmsg = NULL; 716 else 717 statmsg = SysExMsg[i]; 718 if (stat == 0) 719 { 720 if (bitset(M_LOCAL, m->m_flags)) 721 statmsg = "delivered"; 722 else 723 statmsg = "queued"; 724 if (Verbose) 725 message(Arpa_Info, statmsg); 726 } 727 else if (stat == EX_TEMPFAIL) 728 { 729 if (Verbose) 730 message(Arpa_Info, "transmission deferred"); 731 } 732 else 733 { 734 Errors++; 735 if (statmsg == NULL && m->m_badstat != 0) 736 { 737 stat = m->m_badstat; 738 i = stat - EX__BASE; 739 # ifdef DEBUG 740 if (i < 0 || i >= N_SysEx) 741 syserr("Bad m_badstat %d", stat); 742 else 743 # endif DEBUG 744 statmsg = SysExMsg[i]; 745 } 746 if (statmsg == NULL) 747 usrerr("unknown mailer response %d", stat); 748 else if (force || !bitset(M_QUIET, m->m_flags) || Verbose) 749 usrerr("%s", statmsg); 750 } 751 752 /* 753 ** Final cleanup. 754 ** Log a record of the transaction. Compute the new 755 ** ExitStat -- if we already had an error, stick with 756 ** that. 757 */ 758 759 if (statmsg == NULL) 760 { 761 (void) sprintf(buf, "error %d", stat); 762 statmsg = buf; 763 } 764 765 # ifdef LOG 766 syslog(LOG_INFO, "%s->%s: %ld: %s", From.q_paddr, To, MsgSize, statmsg); 767 # endif LOG 768 if (stat != EX_TEMPFAIL) 769 setstat(stat); 770 } 771 /* 772 ** PUTMESSAGE -- output a message to the final mailer. 773 ** 774 ** This routine takes care of recreating the header from the 775 ** in-core copy, etc. 776 ** 777 ** Parameters: 778 ** fp -- file to output onto. 779 ** m -- a mailer descriptor. 780 ** xdot -- if set, hide lines beginning with dot. 781 ** 782 ** Returns: 783 ** none. 784 ** 785 ** Side Effects: 786 ** The message is written onto fp. 787 */ 788 789 putmessage(fp, m, xdot) 790 FILE *fp; 791 struct mailer *m; 792 bool xdot; 793 { 794 char buf[BUFSIZ]; 795 register HDR *h; 796 extern char *arpadate(); 797 bool anyheader = FALSE; 798 extern char *capitalize(); 799 extern char *hvalue(); 800 extern bool samefrom(); 801 char *of_line; 802 803 /* 804 ** Output "From" line unless supressed 805 */ 806 807 if (!bitset(M_NHDR, m->m_flags)) 808 { 809 (void) expand("$l", buf, &buf[sizeof buf - 1]); 810 fprintf(fp, "%s\n", buf); 811 } 812 813 /* 814 ** Output all header lines 815 */ 816 817 of_line = hvalue("original-from"); 818 for (h = Header; h != NULL; h = h->h_link) 819 { 820 register char *p; 821 char *origfrom = OrigFrom; 822 bool nooutput; 823 824 nooutput = FALSE; 825 if (bitset(H_CHECK|H_ACHECK, h->h_flags) && !bitset(h->h_mflags, m->m_flags)) 826 { 827 p = ")><("; /* can't happen (I hope) */ 828 nooutput = TRUE; 829 } 830 831 /* use From: line from message if generated is the same */ 832 if (strcmp(h->h_field, "from") == 0 && origfrom != NULL && 833 strcmp(m->m_from, "$f") == 0 && of_line == NULL) 834 { 835 p = origfrom; 836 origfrom = NULL; 837 } 838 else if (bitset(H_DEFAULT, h->h_flags)) 839 { 840 (void) expand(h->h_value, buf, &buf[sizeof buf]); 841 p = buf; 842 } 843 else 844 p = h->h_value; 845 if (p == NULL || *p == '\0') 846 continue; 847 848 /* hack, hack -- output Original-From field if different */ 849 if (strcmp(h->h_field, "from") == 0 && origfrom != NULL) 850 { 851 /* output new Original-From line if needed */ 852 if (of_line == NULL && !samefrom(p, origfrom)) 853 { 854 fprintf(fp, "Original-From: %s\n", origfrom); 855 anyheader = TRUE; 856 } 857 if (of_line != NULL && !nooutput && samefrom(p, of_line)) 858 { 859 /* delete Original-From: line if redundant */ 860 p = of_line; 861 of_line = NULL; 862 } 863 } 864 else if (strcmp(h->h_field, "original-from") == 0 && of_line == NULL) 865 nooutput = TRUE; 866 867 /* finally, output the header line */ 868 if (!nooutput) 869 { 870 fprintf(fp, "%s: %s\n", capitalize(h->h_field), p); 871 h->h_flags |= H_USED; 872 anyheader = TRUE; 873 } 874 } 875 if (anyheader) 876 fprintf(fp, "\n"); 877 878 /* 879 ** Output the body of the message 880 */ 881 882 if (TempFile != NULL) 883 { 884 rewind(TempFile); 885 while (!ferror(fp) && fgets(buf, sizeof buf, TempFile) != NULL) 886 fprintf(fp, "%s%s", xdot && buf[0] == '.' ? "." : "", buf); 887 888 if (ferror(TempFile)) 889 { 890 syserr("putmessage: read error"); 891 setstat(EX_IOERR); 892 } 893 } 894 895 (void) fflush(fp); 896 if (ferror(fp) && errno != EPIPE) 897 { 898 syserr("putmessage: write error"); 899 setstat(EX_IOERR); 900 } 901 errno = 0; 902 } 903 /* 904 ** SAMEFROM -- tell if two text addresses represent the same from address. 905 ** 906 ** Parameters: 907 ** ifrom -- internally generated form of from address. 908 ** efrom -- external form of from address. 909 ** 910 ** Returns: 911 ** TRUE -- if they convey the same info. 912 ** FALSE -- if any information has been lost. 913 ** 914 ** Side Effects: 915 ** none. 916 */ 917 918 bool 919 samefrom(ifrom, efrom) 920 char *ifrom; 921 char *efrom; 922 { 923 register char *p; 924 char buf[MAXNAME + 4]; 925 926 # ifdef DEBUG 927 if (Debug > 7) 928 printf("samefrom(%s,%s)-->", ifrom, efrom); 929 # endif DEBUG 930 if (strcmp(ifrom, efrom) == 0) 931 goto success; 932 p = index(ifrom, '@'); 933 if (p == NULL) 934 goto failure; 935 *p = '\0'; 936 strcpy(buf, ifrom); 937 strcat(buf, " at "); 938 *p++ = '@'; 939 strcat(buf, p); 940 if (strcmp(buf, efrom) == 0) 941 goto success; 942 943 failure: 944 # ifdef DEBUG 945 if (Debug > 7) 946 printf("FALSE\n"); 947 # endif DEBUG 948 return (FALSE); 949 950 success: 951 # ifdef DEBUG 952 if (Debug > 7) 953 printf("TRUE\n"); 954 # endif DEBUG 955 return (TRUE); 956 } 957 /* 958 ** MAILFILE -- Send a message to a file. 959 ** 960 ** If the file has the setuid/setgid bits set, but NO execute 961 ** bits, sendmail will try to become the owner of that file 962 ** rather than the real user. Obviously, this only works if 963 ** sendmail runs as root. 964 ** 965 ** Parameters: 966 ** filename -- the name of the file to send to. 967 ** ctladdr -- the controlling address header -- includes 968 ** the userid/groupid to be when sending. 969 ** 970 ** Returns: 971 ** The exit code associated with the operation. 972 ** 973 ** Side Effects: 974 ** none. 975 */ 976 977 mailfile(filename, ctladdr) 978 char *filename; 979 ADDRESS *ctladdr; 980 { 981 register FILE *f; 982 register int pid; 983 984 /* 985 ** Fork so we can change permissions here. 986 ** Note that we MUST use fork, not vfork, because of 987 ** the complications of calling subroutines, etc. 988 */ 989 990 DOFORK(fork); 991 992 if (pid < 0) 993 return (EX_OSERR); 994 else if (pid == 0) 995 { 996 /* child -- actually write to file */ 997 struct stat stb; 998 extern int DefUid, DefGid; 999 1000 (void) signal(SIGINT, SIG_DFL); 1001 (void) signal(SIGHUP, SIG_DFL); 1002 (void) signal(SIGTERM, SIG_DFL); 1003 umask(OldUmask); 1004 if (stat(filename, &stb) < 0) 1005 stb.st_mode = 0666; 1006 if (bitset(0111, stb.st_mode)) 1007 exit(EX_CANTCREAT); 1008 if (ctladdr == NULL) 1009 ctladdr = &From; 1010 if (!bitset(S_ISGID, stb.st_mode) || setgid(stb.st_gid) < 0) 1011 { 1012 if (ctladdr->q_uid == 0) 1013 (void) setgid(DefGid); 1014 else 1015 (void) setgid(ctladdr->q_gid); 1016 } 1017 if (!bitset(S_ISUID, stb.st_mode) || setuid(stb.st_uid) < 0) 1018 { 1019 if (ctladdr->q_uid == 0) 1020 (void) setuid(DefUid); 1021 else 1022 (void) setuid(ctladdr->q_uid); 1023 } 1024 f = fopen(filename, "a"); 1025 if (f == NULL) 1026 exit(EX_CANTCREAT); 1027 1028 putmessage(f, Mailer[1], FALSE); 1029 fputs("\n", f); 1030 (void) fclose(f); 1031 (void) fflush(stdout); 1032 1033 /* reset ISUID & ISGID bits */ 1034 (void) chmod(filename, (int) stb.st_mode); 1035 exit(EX_OK); 1036 /*NOTREACHED*/ 1037 } 1038 else 1039 { 1040 /* parent -- wait for exit status */ 1041 register int i; 1042 auto int stat; 1043 1044 while ((i = wait(&stat)) != pid) 1045 { 1046 if (i < 0) 1047 { 1048 stat = EX_OSERR << 8; 1049 break; 1050 } 1051 } 1052 if ((stat & 0377) != 0) 1053 stat = EX_UNAVAILABLE << 8; 1054 return ((stat >> 8) & 0377); 1055 } 1056 } 1057 /* 1058 ** SENDALL -- actually send all the messages. 1059 ** 1060 ** Parameters: 1061 ** verifyonly -- if set, only give verification messages. 1062 ** 1063 ** Returns: 1064 ** none. 1065 ** 1066 ** Side Effects: 1067 ** Scans the send lists and sends everything it finds. 1068 */ 1069 1070 sendall(verifyonly) 1071 bool verifyonly; 1072 { 1073 register int i; 1074 typedef int (*fnptr)(); 1075 1076 for (i = 0; Mailer[i] != NULL; i++) 1077 { 1078 ADDRESS *q; 1079 1080 for (q = Mailer[i]->m_sendq; q != NULL; q = q->q_next) 1081 { 1082 if (verifyonly) 1083 { 1084 To = q->q_paddr; 1085 if (!bitset(QDONTSEND|QBADADDR, q->q_flags)) 1086 { 1087 if (bitset(M_LOCAL, q->q_mailer->m_flags)) 1088 message(Arpa_Info, "deliverable"); 1089 else 1090 message(Arpa_Info, "queueable"); 1091 } 1092 } 1093 else 1094 (void) deliver(q, (fnptr) NULL); 1095 } 1096 } 1097 } 1098