1 # include <signal.h> 2 # include <errno.h> 3 # include <sys/types.h> 4 # include <sys/stat.h> 5 # include "sendmail.h" 6 # ifdef LOG 7 # include <syslog.h> 8 # endif LOG 9 10 static char SccsId[] = "@(#)deliver.c 3.36 09/07/81"; 11 12 /* 13 ** DELIVER -- Deliver a message to a list of addresses. 14 ** 15 ** This routine delivers to everyone on the same host as the 16 ** user on the head of the list. It is clever about mailers 17 ** that don't handle multiple users. It is NOT guaranteed 18 ** that it will deliver to all these addresses however -- so 19 ** deliver should be called once for each address on the 20 ** list. 21 ** 22 ** Parameters: 23 ** to -- head of the address list to deliver to. 24 ** editfcn -- if non-NULL, we want to call this function 25 ** to output the letter (instead of just out- 26 ** putting it raw). 27 ** 28 ** Returns: 29 ** zero -- successfully delivered. 30 ** else -- some failure, see ExitStat for more info. 31 ** 32 ** Side Effects: 33 ** The standard input is passed off to someone. 34 */ 35 36 deliver(to, editfcn) 37 ADDRESS *to; 38 int (*editfcn)(); 39 { 40 char *host; 41 char *user; 42 char **pvp; 43 register char **mvp; 44 register char *p; 45 register struct mailer *m; 46 register int i; 47 extern putmessage(); 48 extern bool checkcompat(); 49 char *pv[MAXPV+1]; 50 char tobuf[MAXLINE]; 51 char buf[MAXNAME]; 52 bool firstone; 53 54 if (!ForceMail && bitset(QDONTSEND, to->q_flags)) 55 return (0); 56 57 # ifdef DEBUG 58 if (Debug) 59 printf("\n--deliver, mailer=%d, host=`%s', first user=`%s'\n", 60 to->q_mailer, to->q_host, to->q_user); 61 # endif DEBUG 62 63 /* 64 ** Do initial argv setup. 65 ** Insert the mailer name. Notice that $x expansion is 66 ** NOT done on the mailer name. Then, if the mailer has 67 ** a picky -f flag, we insert it as appropriate. This 68 ** code does not check for 'pv' overflow; this places a 69 ** manifest lower limit of 4 for MAXPV. 70 */ 71 72 m = Mailer[to->q_mailer]; 73 host = to->q_host; 74 define('g', m->m_from); /* translated from address */ 75 define('h', host); /* to host */ 76 Errors = 0; 77 errno = 0; 78 pvp = pv; 79 *pvp++ = m->m_argv[0]; 80 81 /* insert -f or -r flag as appropriate */ 82 if (bitset(M_FOPT|M_ROPT, m->m_flags) && FromFlag) 83 { 84 if (bitset(M_FOPT, m->m_flags)) 85 *pvp++ = "-f"; 86 else 87 *pvp++ = "-r"; 88 (void) expand("$g", buf, &buf[sizeof buf - 1]); 89 *pvp++ = newstr(buf); 90 } 91 92 /* 93 ** Append the other fixed parts of the argv. These run 94 ** up to the first entry containing "$u". There can only 95 ** be one of these, and there are only a few more slots 96 ** in the pv after it. 97 */ 98 99 for (mvp = m->m_argv; (p = *++mvp) != NULL; ) 100 { 101 while ((p = index(p, '$')) != NULL) 102 if (*++p == 'u') 103 break; 104 if (p != NULL) 105 break; 106 107 /* this entry is safe -- go ahead and process it */ 108 (void) expand(*mvp, buf, &buf[sizeof buf - 1]); 109 *pvp++ = newstr(buf); 110 if (pvp >= &pv[MAXPV - 3]) 111 { 112 syserr("Too many parameters to %s before $u", pv[0]); 113 return (-1); 114 } 115 } 116 if (*mvp == NULL) 117 syserr("No $u in mailer argv for %s", pv[0]); 118 119 /* 120 ** At this point *mvp points to the argument with $u. We 121 ** run through our address list and append all the addresses 122 ** we can. If we run out of space, do not fret! We can 123 ** always send another copy later. 124 */ 125 126 tobuf[0] = '\0'; 127 firstone = TRUE; 128 To = tobuf; 129 for (; to != NULL; to = to->q_next) 130 { 131 /* avoid sending multiple recipients to dumb mailers */ 132 if (!firstone && !bitset(M_MUSER, m->m_flags)) 133 break; 134 135 /* if already sent or not for this host, don't send */ 136 if ((!ForceMail && bitset(QDONTSEND, to->q_flags)) || 137 strcmp(to->q_host, host) != 0) 138 continue; 139 user = to->q_user; 140 To = to->q_paddr; 141 to->q_flags |= QDONTSEND; 142 # ifdef DEBUG 143 if (Debug) 144 printf(" send to `%s'\n", user); 145 # endif DEBUG 146 147 /* 148 ** Check to see that these people are allowed to 149 ** talk to each other. 150 */ 151 152 if (!checkcompat(to)) 153 { 154 giveresponse(EX_UNAVAILABLE, TRUE, m); 155 continue; 156 } 157 158 /* 159 ** Strip quote bits from names if the mailer is dumb 160 ** about them. 161 */ 162 163 if (bitset(M_STRIPQ, m->m_flags)) 164 { 165 stripquotes(user, TRUE); 166 stripquotes(host, TRUE); 167 } 168 else 169 { 170 stripquotes(user, FALSE); 171 stripquotes(host, FALSE); 172 } 173 174 /* 175 ** If an error message has already been given, don't 176 ** bother to send to this address. 177 ** 178 ** >>>>>>>>>> This clause assumes that the local mailer 179 ** >> NOTE >> cannot do any further aliasing; that 180 ** >>>>>>>>>> function is subsumed by sendmail. 181 */ 182 183 if (bitset(QBADADDR, to->q_flags)) 184 continue; 185 186 /* save statistics.... */ 187 Stat.stat_nt[to->q_mailer]++; 188 Stat.stat_bt[to->q_mailer] += kbytes(MsgSize); 189 190 /* 191 ** See if this user name is "special". 192 ** If the user name has a slash in it, assume that this 193 ** is a file -- send it off without further ado. 194 ** Note that this means that editfcn's will not 195 ** be applied to the message. Also note that 196 ** this type of addresses is not processed along 197 ** with the others, so we fudge on the To person. 198 */ 199 200 if (m == Mailer[MN_LOCAL]) 201 { 202 if (index(user, '/') != NULL) 203 { 204 i = mailfile(user); 205 giveresponse(i, TRUE, m); 206 continue; 207 } 208 } 209 210 /* 211 ** Address is verified -- add this user to mailer 212 ** argv, and add it to the print list of recipients. 213 */ 214 215 /* create list of users for error messages */ 216 if (tobuf[0] != '\0') 217 (void) strcat(tobuf, ","); 218 (void) strcat(tobuf, to->q_paddr); 219 define('u', user); /* to user */ 220 define('z', to->q_home); /* user's home */ 221 222 /* expand out this user */ 223 (void) expand(*mvp, buf, &buf[sizeof buf - 1]); 224 *pvp++ = newstr(buf); 225 if (pvp >= &pv[MAXPV - 2]) 226 { 227 /* allow some space for trailing parms */ 228 break; 229 } 230 } 231 232 /* see if any addresses still exist */ 233 if (tobuf[0] == '\0') 234 return (0); 235 236 /* print out messages as full list */ 237 To = tobuf; 238 239 /* 240 ** Fill out any parameters after the $u parameter. 241 */ 242 243 while (*++mvp != NULL) 244 { 245 (void) expand(*mvp, buf, &buf[sizeof buf - 1]); 246 *pvp++ = newstr(buf); 247 if (pvp >= &pv[MAXPV]) 248 syserr("deliver: pv overflow after $u for %s", pv[0]); 249 } 250 *pvp++ = NULL; 251 252 /* 253 ** Call the mailer. 254 ** The argument vector gets built, pipes 255 ** are created as necessary, and we fork & exec as 256 ** appropriate. 257 */ 258 259 if (editfcn == NULL) 260 editfcn = putmessage; 261 i = sendoff(m, pv, editfcn); 262 263 return (i); 264 } 265 /* 266 ** DOFORK -- do a fork, retrying a couple of times on failure. 267 ** 268 ** This MUST be a macro, since after a vfork we are running 269 ** two processes on the same stack!!! 270 ** 271 ** Parameters: 272 ** none. 273 ** 274 ** Returns: 275 ** From a macro??? You've got to be kidding! 276 ** 277 ** Side Effects: 278 ** Modifies the ==> LOCAL <== variable 'pid', leaving: 279 ** pid of child in parent, zero in child. 280 ** -1 on unrecoverable error. 281 ** 282 ** Notes: 283 ** I'm awfully sorry this looks so awful. That's 284 ** vfork for you..... 285 */ 286 287 # define NFORKTRIES 5 288 # ifdef VFORK 289 # define XFORK vfork 290 # else VFORK 291 # define XFORK fork 292 # endif VFORK 293 294 # define DOFORK(fORKfN) \ 295 {\ 296 register int i;\ 297 \ 298 for (i = NFORKTRIES; i-- > 0; )\ 299 {\ 300 pid = fORKfN();\ 301 if (pid >= 0)\ 302 break;\ 303 sleep((unsigned) NFORKTRIES - i);\ 304 }\ 305 } 306 /* 307 ** SENDOFF -- send off call to mailer & collect response. 308 ** 309 ** Parameters: 310 ** m -- mailer descriptor. 311 ** pvp -- parameter vector to send to it. 312 ** editfcn -- function to pipe it through. 313 ** 314 ** Returns: 315 ** exit status of mailer. 316 ** 317 ** Side Effects: 318 ** none. 319 */ 320 321 sendoff(m, pvp, editfcn) 322 struct mailer *m; 323 char **pvp; 324 int (*editfcn)(); 325 { 326 auto int st; 327 register int i; 328 int pid; 329 int pvect[2]; 330 FILE *mfile; 331 extern putmessage(); 332 extern FILE *fdopen(); 333 334 # ifdef DEBUG 335 if (Debug) 336 { 337 printf("Sendoff:\n"); 338 printav(pvp); 339 } 340 # endif DEBUG 341 342 /* create a pipe to shove the mail through */ 343 if (pipe(pvect) < 0) 344 { 345 syserr("pipe"); 346 return (-1); 347 } 348 DOFORK(XFORK); 349 /* pid is set by DOFORK */ 350 if (pid < 0) 351 { 352 syserr("Cannot fork"); 353 (void) close(pvect[0]); 354 (void) close(pvect[1]); 355 return (-1); 356 } 357 else if (pid == 0) 358 { 359 /* child -- set up input & exec mailer */ 360 /* make diagnostic output be standard output */ 361 (void) signal(SIGINT, SIG_DFL); 362 (void) signal(SIGHUP, SIG_DFL); 363 (void) signal(SIGTERM, SIG_DFL); 364 (void) close(2); 365 (void) dup(1); 366 (void) close(0); 367 if (dup(pvect[0]) < 0) 368 { 369 syserr("Cannot dup to zero!"); 370 _exit(EX_OSERR); 371 } 372 (void) close(pvect[0]); 373 (void) close(pvect[1]); 374 if (!bitset(M_RESTR, m->m_flags)) 375 { 376 (void) setuid(getuid()); 377 (void) setgid(getgid()); 378 } 379 # ifndef VFORK 380 /* 381 ** We have to be careful with vfork - we can't mung up the 382 ** memory but we don't want the mailer to inherit any extra 383 ** open files. Chances are the mailer won't 384 ** care about an extra file, but then again you never know. 385 ** Actually, we would like to close(fileno(pwf)), but it's 386 ** declared static so we can't. But if we fclose(pwf), which 387 ** is what endpwent does, it closes it in the parent too and 388 ** the next getpwnam will be slower. If you have a weird 389 ** mailer that chokes on the extra file you should do the 390 ** endpwent(). 391 ** 392 ** Similar comments apply to log. However, openlog is 393 ** clever enough to set the FIOCLEX mode on the file, 394 ** so it will be closed automatically on the exec. 395 */ 396 397 endpwent(); 398 # ifdef LOG 399 closelog(); 400 # endif LOG 401 # endif VFORK 402 execv(m->m_mailer, pvp); 403 /* syserr fails because log is closed */ 404 /* syserr("Cannot exec %s", m->m_mailer); */ 405 printf("Cannot exec '%s' errno=%d\n", m->m_mailer, errno); 406 (void) fflush(stdout); 407 _exit(EX_UNAVAILABLE); 408 } 409 410 /* write out message to mailer */ 411 (void) close(pvect[0]); 412 (void) signal(SIGPIPE, SIG_IGN); 413 mfile = fdopen(pvect[1], "w"); 414 if (editfcn == NULL) 415 editfcn = putmessage; 416 (*editfcn)(mfile, m); 417 (void) fclose(mfile); 418 419 /* 420 ** Wait for child to die and report status. 421 ** We should never get fatal errors (e.g., segmentation 422 ** violation), so we report those specially. For other 423 ** errors, we choose a status message (into statmsg), 424 ** and if it represents an error, we print it. 425 */ 426 427 while ((i = wait(&st)) > 0 && i != pid) 428 continue; 429 if (i < 0) 430 { 431 syserr("wait"); 432 return (-1); 433 } 434 if ((st & 0377) != 0) 435 { 436 syserr("%s: stat %o", pvp[0], st); 437 ExitStat = EX_UNAVAILABLE; 438 return (-1); 439 } 440 i = (st >> 8) & 0377; 441 giveresponse(i, TRUE, m); 442 return (i); 443 } 444 /* 445 ** GIVERESPONSE -- Interpret an error response from a mailer 446 ** 447 ** Parameters: 448 ** stat -- the status code from the mailer (high byte 449 ** only; core dumps must have been taken care of 450 ** already). 451 ** force -- if set, force an error message output, even 452 ** if the mailer seems to like to print its own 453 ** messages. 454 ** m -- the mailer descriptor for this mailer. 455 ** 456 ** Returns: 457 ** none. 458 ** 459 ** Side Effects: 460 ** Errors may be incremented. 461 ** ExitStat may be set. 462 */ 463 464 giveresponse(stat, force, m) 465 int stat; 466 int force; 467 register struct mailer *m; 468 { 469 register char *statmsg; 470 extern char *SysExMsg[]; 471 register int i; 472 extern int N_SysEx; 473 char buf[30]; 474 475 /* 476 ** Compute status message from code. 477 */ 478 479 i = stat - EX__BASE; 480 if (i < 0 || i > N_SysEx) 481 statmsg = NULL; 482 else 483 statmsg = SysExMsg[i]; 484 if (stat == 0) 485 { 486 if (bitset(M_LOCAL, m->m_flags)) 487 statmsg = "delivered"; 488 else 489 statmsg = "queued"; 490 if (Verbose) 491 message(Arpa_Info, statmsg); 492 } 493 else 494 { 495 Errors++; 496 if (statmsg == NULL && m->m_badstat != 0) 497 { 498 stat = m->m_badstat; 499 i = stat - EX__BASE; 500 # ifdef DEBUG 501 if (i < 0 || i >= N_SysEx) 502 syserr("Bad m_badstat %d", stat); 503 else 504 # endif DEBUG 505 statmsg = SysExMsg[i]; 506 } 507 if (statmsg == NULL) 508 usrerr("unknown mailer response %d", stat); 509 else if (force || !bitset(M_QUIET, m->m_flags) || Verbose) 510 usrerr("%s", statmsg); 511 } 512 513 /* 514 ** Final cleanup. 515 ** Log a record of the transaction. Compute the new 516 ** ExitStat -- if we already had an error, stick with 517 ** that. 518 */ 519 520 if (statmsg == NULL) 521 { 522 (void) sprintf(buf, "error %d", stat); 523 statmsg = buf; 524 } 525 526 # ifdef LOG 527 syslog(LOG_INFO, "%s->%s: %ld: %s", From.q_paddr, To, MsgSize, statmsg); 528 # endif LOG 529 setstat(stat); 530 } 531 /* 532 ** PUTMESSAGE -- output a message to the final mailer. 533 ** 534 ** This routine takes care of recreating the header from the 535 ** in-core copy, etc. 536 ** 537 ** Parameters: 538 ** fp -- file to output onto. 539 ** m -- a mailer descriptor. 540 ** 541 ** Returns: 542 ** none. 543 ** 544 ** Side Effects: 545 ** The message is written onto fp. 546 */ 547 548 putmessage(fp, m) 549 FILE *fp; 550 struct mailer *m; 551 { 552 char buf[BUFSIZ]; 553 register int i; 554 register HDR *h; 555 extern char *arpadate(); 556 bool anyheader = FALSE; 557 extern char *capitalize(); 558 559 /* 560 ** Output "From" line unless supressed 561 */ 562 563 if (!bitset(M_NHDR, m->m_flags)) 564 { 565 (void) expand("$l", buf, &buf[sizeof buf - 1]); 566 fprintf(fp, "%s\n", buf); 567 } 568 569 /* 570 ** Output all header lines 571 */ 572 573 for (h = Header; h != NULL; h = h->h_link) 574 { 575 register char *p; 576 577 if (bitset(H_CHECK|H_ACHECK, h->h_flags) && !bitset(h->h_mflags, m->m_flags)) 578 { 579 p = ")><("; /* can't happen (I hope) */ 580 goto checkfrom; 581 } 582 if (bitset(H_DEFAULT, h->h_flags)) 583 { 584 (void) expand(h->h_value, buf, &buf[sizeof buf]); 585 p = buf; 586 } 587 else 588 p = h->h_value; 589 if (*p == '\0') 590 continue; 591 fprintf(fp, "%s: %s\n", capitalize(h->h_field), p); 592 h->h_flags |= H_USED; 593 anyheader = TRUE; 594 595 /* hack, hack -- output Original-From field if different */ 596 checkfrom: 597 if (strcmp(h->h_field, "from") == 0) 598 { 599 extern char *hvalue(); 600 char *ofrom = hvalue("original-from"); 601 602 if (ofrom != NULL && strcmp(p, ofrom) != 0) 603 fprintf(fp, "Original-From: %s\n", ofrom); 604 } 605 } 606 if (anyheader) 607 fprintf(fp, "\n"); 608 609 /* 610 ** Output the body of the message 611 */ 612 613 rewind(TempFile); 614 while (!ferror(fp) && (i = fread(buf, 1, BUFSIZ, TempFile)) > 0) 615 (void) fwrite(buf, 1, i, fp); 616 617 if (ferror(fp) && errno != EPIPE) 618 { 619 syserr("putmessage: write error"); 620 setstat(EX_IOERR); 621 } 622 errno = 0; 623 } 624 /* 625 ** MAILFILE -- Send a message to a file. 626 ** 627 ** If the file has the setuid/setgid bits set, but NO execute 628 ** bits, sendmail will try to become the owner of that file 629 ** rather than the real user. Obviously, this only works if 630 ** sendmail runs as root. 631 ** 632 ** Parameters: 633 ** filename -- the name of the file to send to. 634 ** 635 ** Returns: 636 ** The exit code associated with the operation. 637 ** 638 ** Side Effects: 639 ** none. 640 */ 641 642 mailfile(filename) 643 char *filename; 644 { 645 register FILE *f; 646 register int pid; 647 648 /* 649 ** Fork so we can change permissions here. 650 ** Note that we MUST use fork, not vfork, because of 651 ** the complications of calling subroutines, etc. 652 */ 653 654 DOFORK(fork); 655 656 if (pid < 0) 657 return (EX_OSERR); 658 else if (pid == 0) 659 { 660 /* child -- actually write to file */ 661 struct stat stb; 662 663 (void) signal(SIGINT, SIG_DFL); 664 (void) signal(SIGHUP, SIG_DFL); 665 (void) signal(SIGTERM, SIG_DFL); 666 umask(OldUmask); 667 if (stat(filename, &stb) < 0) 668 stb.st_mode = 0; 669 if (bitset(0111, stb.st_mode)) 670 exit(EX_CANTCREAT); 671 if (!bitset(S_ISGID, stb.st_mode) || setgid(stb.st_gid) < 0) 672 (void) setgid(getgid()); 673 if (!bitset(S_ISUID, stb.st_mode) || setuid(stb.st_uid) < 0) 674 (void) setuid(getuid()); 675 f = fopen(filename, "a"); 676 if (f == NULL) 677 exit(EX_CANTCREAT); 678 679 putmessage(f, Mailer[1]); 680 fputs("\n", f); 681 (void) fclose(f); 682 (void) fflush(stdout); 683 exit(EX_OK); 684 /*NOTREACHED*/ 685 } 686 else 687 { 688 /* parent -- wait for exit status */ 689 register int i; 690 auto int stat; 691 692 while ((i = wait(&stat)) != pid) 693 { 694 if (i < 0) 695 { 696 stat = EX_OSERR << 8; 697 break; 698 } 699 } 700 if ((stat & 0377) != 0) 701 stat = EX_UNAVAILABLE << 8; 702 return ((stat >> 8) & 0377); 703 } 704 } 705