1 /* 2 * Copyright (c) 1983 Eric P. Allman 3 * Copyright (c) 1988, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * %sccs.include.redist.c% 7 */ 8 9 #ifndef lint 10 static char sccsid[] = "@(#)envelope.c 8.2 (Berkeley) 07/11/93"; 11 #endif /* not lint */ 12 13 #include "sendmail.h" 14 #include <sys/time.h> 15 #include <pwd.h> 16 17 /* 18 ** NEWENVELOPE -- allocate a new envelope 19 ** 20 ** Supports inheritance. 21 ** 22 ** Parameters: 23 ** e -- the new envelope to fill in. 24 ** parent -- the envelope to be the parent of e. 25 ** 26 ** Returns: 27 ** e. 28 ** 29 ** Side Effects: 30 ** none. 31 */ 32 33 ENVELOPE * 34 newenvelope(e, parent) 35 register ENVELOPE *e; 36 register ENVELOPE *parent; 37 { 38 extern putheader(), putbody(); 39 extern ENVELOPE BlankEnvelope; 40 41 if (e == parent && e->e_parent != NULL) 42 parent = e->e_parent; 43 clearenvelope(e, TRUE); 44 if (e == CurEnv) 45 bcopy((char *) &NullAddress, (char *) &e->e_from, sizeof e->e_from); 46 else 47 bcopy((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from); 48 e->e_parent = parent; 49 e->e_ctime = curtime(); 50 if (parent != NULL) 51 e->e_msgpriority = parent->e_msgsize; 52 e->e_puthdr = putheader; 53 e->e_putbody = putbody; 54 if (CurEnv->e_xfp != NULL) 55 (void) fflush(CurEnv->e_xfp); 56 57 return (e); 58 } 59 /* 60 ** DROPENVELOPE -- deallocate an envelope. 61 ** 62 ** Parameters: 63 ** e -- the envelope to deallocate. 64 ** 65 ** Returns: 66 ** none. 67 ** 68 ** Side Effects: 69 ** housekeeping necessary to dispose of an envelope. 70 ** Unlocks this queue file. 71 */ 72 73 void 74 dropenvelope(e) 75 register ENVELOPE *e; 76 { 77 bool queueit = FALSE; 78 register ADDRESS *q; 79 char *id = e->e_id; 80 char buf[MAXLINE]; 81 82 if (tTd(50, 1)) 83 { 84 printf("dropenvelope %x: id=", e); 85 xputs(e->e_id); 86 printf(", flags=%o\n", e->e_flags); 87 if (tTd(50, 10)) 88 { 89 printf("sendq="); 90 printaddr(e->e_sendqueue, TRUE); 91 } 92 } 93 94 /* we must have an id to remove disk files */ 95 if (id == NULL) 96 return; 97 98 #ifdef LOG 99 if (LogLevel > 84) 100 syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=%o, pid=%d", 101 id, e->e_flags, getpid()); 102 #endif /* LOG */ 103 104 /* post statistics */ 105 poststats(StatFile); 106 107 /* 108 ** Extract state information from dregs of send list. 109 */ 110 111 for (q = e->e_sendqueue; q != NULL; q = q->q_next) 112 { 113 if (bitset(QQUEUEUP, q->q_flags)) 114 queueit = TRUE; 115 } 116 117 /* 118 ** See if the message timed out. 119 */ 120 121 if (!queueit) 122 /* nothing to do */ ; 123 else if (curtime() > e->e_ctime + TimeOuts.to_q_return) 124 { 125 if (!bitset(EF_TIMEOUT, e->e_flags)) 126 { 127 (void) sprintf(buf, "Cannot send message for %s", 128 pintvl(TimeOuts.to_q_return, FALSE)); 129 if (e->e_message != NULL) 130 free(e->e_message); 131 e->e_message = newstr(buf); 132 message(buf); 133 } 134 e->e_flags |= EF_TIMEOUT|EF_CLRQUEUE; 135 fprintf(e->e_xfp, "421 Message timed out\n"); 136 } 137 else if (TimeOuts.to_q_warning > 0 && 138 curtime() > e->e_ctime + TimeOuts.to_q_warning) 139 { 140 if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && 141 e->e_class >= 0 && 142 strcmp(e->e_from.q_paddr, "<>") != 0) 143 { 144 (void) sprintf(buf, 145 "warning: cannot send message for %s", 146 pintvl(TimeOuts.to_q_warning, FALSE)); 147 if (e->e_message != NULL) 148 free(e->e_message); 149 e->e_message = newstr(buf); 150 message(buf); 151 e->e_flags |= EF_WARNING|EF_TIMEOUT; 152 } 153 fprintf(e->e_xfp, 154 "Warning: message still undelivered after %s\n", 155 pintvl(TimeOuts.to_q_warning, FALSE)); 156 fprintf(e->e_xfp, "Will keep trying until message is %s old\n", 157 pintvl(TimeOuts.to_q_return, FALSE)); 158 } 159 160 /* 161 ** Send back return receipts as requested. 162 */ 163 164 if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags)) 165 { 166 auto ADDRESS *rlist = NULL; 167 168 (void) sendtolist(e->e_receiptto, (ADDRESS *) NULL, &rlist, e); 169 (void) returntosender("Return receipt", rlist, FALSE, e); 170 } 171 172 /* 173 ** Arrange to send error messages if there are fatal errors. 174 */ 175 176 if (bitset(EF_FATALERRS|EF_TIMEOUT, e->e_flags) && 177 e->e_errormode != EM_QUIET) 178 savemail(e); 179 180 /* 181 ** Instantiate or deinstantiate the queue. 182 */ 183 184 if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) || 185 bitset(EF_CLRQUEUE, e->e_flags)) 186 { 187 if (tTd(50, 2)) 188 printf("Dropping envelope\n"); 189 if (e->e_df != NULL) 190 xunlink(e->e_df); 191 xunlink(queuename(e, 'q')); 192 } 193 else if (queueit || !bitset(EF_INQUEUE, e->e_flags)) 194 { 195 #ifdef QUEUE 196 queueup(e, FALSE, FALSE); 197 #else /* QUEUE */ 198 syserr("554 dropenvelope: queueup"); 199 #endif /* QUEUE */ 200 } 201 202 /* now unlock the job */ 203 closexscript(e); 204 unlockqueue(e); 205 206 /* make sure that this envelope is marked unused */ 207 if (e->e_dfp != NULL) 208 (void) xfclose(e->e_dfp, "dropenvelope", e->e_df); 209 e->e_dfp = NULL; 210 e->e_id = e->e_df = NULL; 211 212 #ifdef LOG 213 if (LogLevel > 74) 214 syslog(LOG_INFO, "%s: done", id); 215 #endif /* LOG */ 216 } 217 /* 218 ** CLEARENVELOPE -- clear an envelope without unlocking 219 ** 220 ** This is normally used by a child process to get a clean 221 ** envelope without disturbing the parent. 222 ** 223 ** Parameters: 224 ** e -- the envelope to clear. 225 ** fullclear - if set, the current envelope is total 226 ** garbage and should be ignored; otherwise, 227 ** release any resources it may indicate. 228 ** 229 ** Returns: 230 ** none. 231 ** 232 ** Side Effects: 233 ** Closes files associated with the envelope. 234 ** Marks the envelope as unallocated. 235 */ 236 237 void 238 clearenvelope(e, fullclear) 239 register ENVELOPE *e; 240 bool fullclear; 241 { 242 register HDR *bh; 243 register HDR **nhp; 244 extern ENVELOPE BlankEnvelope; 245 246 if (!fullclear) 247 { 248 /* clear out any file information */ 249 if (e->e_xfp != NULL) 250 (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id); 251 if (e->e_dfp != NULL) 252 (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_df); 253 e->e_xfp = e->e_dfp = NULL; 254 } 255 256 /* now clear out the data */ 257 STRUCTCOPY(BlankEnvelope, *e); 258 if (Verbose) 259 e->e_sendmode = SM_DELIVER; 260 bh = BlankEnvelope.e_header; 261 nhp = &e->e_header; 262 while (bh != NULL) 263 { 264 *nhp = (HDR *) xalloc(sizeof *bh); 265 bcopy((char *) bh, (char *) *nhp, sizeof *bh); 266 bh = bh->h_link; 267 nhp = &(*nhp)->h_link; 268 } 269 } 270 /* 271 ** INITSYS -- initialize instantiation of system 272 ** 273 ** In Daemon mode, this is done in the child. 274 ** 275 ** Parameters: 276 ** none. 277 ** 278 ** Returns: 279 ** none. 280 ** 281 ** Side Effects: 282 ** Initializes the system macros, some global variables, 283 ** etc. In particular, the current time in various 284 ** forms is set. 285 */ 286 287 void 288 initsys(e) 289 register ENVELOPE *e; 290 { 291 static char cbuf[5]; /* holds hop count */ 292 static char pbuf[10]; /* holds pid */ 293 #ifdef TTYNAME 294 static char ybuf[60]; /* holds tty id */ 295 register char *p; 296 #endif /* TTYNAME */ 297 extern char *ttyname(); 298 extern void settime(); 299 extern char Version[]; 300 301 /* 302 ** Give this envelope a reality. 303 ** I.e., an id, a transcript, and a creation time. 304 */ 305 306 openxscript(e); 307 e->e_ctime = curtime(); 308 309 /* 310 ** Set OutChannel to something useful if stdout isn't it. 311 ** This arranges that any extra stuff the mailer produces 312 ** gets sent back to the user on error (because it is 313 ** tucked away in the transcript). 314 */ 315 316 if (OpMode == MD_DAEMON && !bitset(EF_QUEUERUN, e->e_flags) && 317 e->e_xfp != NULL) 318 OutChannel = e->e_xfp; 319 320 /* 321 ** Set up some basic system macros. 322 */ 323 324 /* process id */ 325 (void) sprintf(pbuf, "%d", getpid()); 326 define('p', pbuf, e); 327 328 /* hop count */ 329 (void) sprintf(cbuf, "%d", e->e_hopcount); 330 define('c', cbuf, e); 331 332 /* time as integer, unix time, arpa time */ 333 settime(e); 334 335 #ifdef TTYNAME 336 /* tty name */ 337 if (macvalue('y', e) == NULL) 338 { 339 p = ttyname(2); 340 if (p != NULL) 341 { 342 if (strrchr(p, '/') != NULL) 343 p = strrchr(p, '/') + 1; 344 (void) strcpy(ybuf, p); 345 define('y', ybuf, e); 346 } 347 } 348 #endif /* TTYNAME */ 349 } 350 /* 351 ** SETTIME -- set the current time. 352 ** 353 ** Parameters: 354 ** none. 355 ** 356 ** Returns: 357 ** none. 358 ** 359 ** Side Effects: 360 ** Sets the various time macros -- $a, $b, $d, $t. 361 */ 362 363 void 364 settime(e) 365 register ENVELOPE *e; 366 { 367 register char *p; 368 auto time_t now; 369 static char tbuf[20]; /* holds "current" time */ 370 static char dbuf[30]; /* holds ctime(tbuf) */ 371 register struct tm *tm; 372 extern char *arpadate(); 373 extern struct tm *gmtime(); 374 375 now = curtime(); 376 tm = gmtime(&now); 377 (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, 378 tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min); 379 define('t', tbuf, e); 380 (void) strcpy(dbuf, ctime(&now)); 381 p = strchr(dbuf, '\n'); 382 if (p != NULL) 383 *p = '\0'; 384 define('d', dbuf, e); 385 p = newstr(arpadate(dbuf)); 386 if (macvalue('a', e) == NULL) 387 define('a', p, e); 388 define('b', p, e); 389 } 390 /* 391 ** OPENXSCRIPT -- Open transcript file 392 ** 393 ** Creates a transcript file for possible eventual mailing or 394 ** sending back. 395 ** 396 ** Parameters: 397 ** e -- the envelope to create the transcript in/for. 398 ** 399 ** Returns: 400 ** none 401 ** 402 ** Side Effects: 403 ** Creates the transcript file. 404 */ 405 406 #ifndef O_APPEND 407 #define O_APPEND 0 408 #endif 409 410 void 411 openxscript(e) 412 register ENVELOPE *e; 413 { 414 register char *p; 415 int fd; 416 417 if (e->e_xfp != NULL) 418 return; 419 p = queuename(e, 'x'); 420 fd = open(p, O_WRONLY|O_CREAT|O_APPEND, 0644); 421 if (fd < 0) 422 { 423 syserr("Can't create transcript file %s", p); 424 fd = open("/dev/null", O_WRONLY, 0644); 425 if (fd < 0) 426 syserr("!Can't open /dev/null"); 427 } 428 e->e_xfp = fdopen(fd, "w"); 429 } 430 /* 431 ** CLOSEXSCRIPT -- close the transcript file. 432 ** 433 ** Parameters: 434 ** e -- the envelope containing the transcript to close. 435 ** 436 ** Returns: 437 ** none. 438 ** 439 ** Side Effects: 440 ** none. 441 */ 442 443 void 444 closexscript(e) 445 register ENVELOPE *e; 446 { 447 if (e->e_xfp == NULL) 448 return; 449 (void) xfclose(e->e_xfp, "closexscript", e->e_id); 450 e->e_xfp = NULL; 451 } 452 /* 453 ** SETSENDER -- set the person who this message is from 454 ** 455 ** Under certain circumstances allow the user to say who 456 ** s/he is (using -f or -r). These are: 457 ** 1. The user's uid is zero (root). 458 ** 2. The user's login name is in an approved list (typically 459 ** from a network server). 460 ** 3. The address the user is trying to claim has a 461 ** "!" character in it (since #2 doesn't do it for 462 ** us if we are dialing out for UUCP). 463 ** A better check to replace #3 would be if the 464 ** effective uid is "UUCP" -- this would require me 465 ** to rewrite getpwent to "grab" uucp as it went by, 466 ** make getname more nasty, do another passwd file 467 ** scan, or compile the UID of "UUCP" into the code, 468 ** all of which are reprehensible. 469 ** 470 ** Assuming all of these fail, we figure out something 471 ** ourselves. 472 ** 473 ** Parameters: 474 ** from -- the person we would like to believe this message 475 ** is from, as specified on the command line. 476 ** e -- the envelope in which we would like the sender set. 477 ** delimptr -- if non-NULL, set to the location of the 478 ** trailing delimiter. 479 ** internal -- set if this address is coming from an internal 480 ** source such as an owner alias. 481 ** 482 ** Returns: 483 ** none. 484 ** 485 ** Side Effects: 486 ** sets sendmail's notion of who the from person is. 487 */ 488 489 void 490 setsender(from, e, delimptr, internal) 491 char *from; 492 register ENVELOPE *e; 493 char **delimptr; 494 bool internal; 495 { 496 register char **pvp; 497 char *realname = NULL; 498 register struct passwd *pw; 499 char delimchar; 500 char buf[MAXNAME]; 501 char pvpbuf[PSBUFSIZE]; 502 extern struct passwd *getpwnam(); 503 extern char *FullName; 504 505 if (tTd(45, 1)) 506 printf("setsender(%s)\n", from == NULL ? "" : from); 507 508 /* 509 ** Figure out the real user executing us. 510 ** Username can return errno != 0 on non-errors. 511 */ 512 513 if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP) 514 realname = from; 515 if (realname == NULL || realname[0] == '\0') 516 realname = username(); 517 518 if (ConfigLevel < 2) 519 SuprErrs = TRUE; 520 521 delimchar = internal ? '\0' : ' '; 522 if (from == NULL || 523 parseaddr(from, &e->e_from, 1, delimchar, delimptr, e) == NULL) 524 { 525 /* log garbage addresses for traceback */ 526 # ifdef LOG 527 if (from != NULL && LogLevel > 2) 528 { 529 char *p; 530 char ebuf[MAXNAME * 2 + 2]; 531 532 p = macvalue('_', e); 533 if (p == NULL) 534 { 535 char *host = RealHostName; 536 if (host == NULL) 537 host = MyHostName; 538 (void) sprintf(ebuf, "%s@%s", realname, host); 539 p = ebuf; 540 } 541 syslog(LOG_NOTICE, 542 "from=%s unparseable, received from %s", 543 from, p); 544 } 545 # endif /* LOG */ 546 if (from != NULL) 547 SuprErrs = TRUE; 548 if (from == realname || 549 parseaddr(from = newstr(realname), &e->e_from, 1, ' ', NULL, e) == NULL) 550 { 551 SuprErrs = TRUE; 552 if (parseaddr("postmaster", &e->e_from, 1, ' ', NULL, e) == NULL) 553 syserr("553 setsender: can't even parse postmaster!"); 554 } 555 } 556 else 557 FromFlag = TRUE; 558 e->e_from.q_flags |= QDONTSEND; 559 if (tTd(45, 5)) 560 { 561 printf("setsender: QDONTSEND "); 562 printaddr(&e->e_from, FALSE); 563 } 564 SuprErrs = FALSE; 565 566 pvp = NULL; 567 if (e->e_from.q_mailer == LocalMailer) 568 { 569 # ifdef USERDB 570 register char *p; 571 extern char *udbsender(); 572 # endif 573 574 if (!internal) 575 { 576 /* if the user has given fullname already, don't redefine */ 577 if (FullName == NULL) 578 FullName = macvalue('x', e); 579 if (FullName != NULL && FullName[0] == '\0') 580 FullName = NULL; 581 582 # ifdef USERDB 583 p = udbsender(from); 584 585 if (p != NULL) 586 { 587 /* 588 ** We have an alternate address for the sender 589 */ 590 591 pvp = prescan(p, '\0', pvpbuf, NULL); 592 } 593 # endif /* USERDB */ 594 } 595 596 if ((pw = getpwnam(e->e_from.q_user)) != NULL) 597 { 598 /* 599 ** Process passwd file entry. 600 */ 601 602 603 /* extract home directory */ 604 e->e_from.q_home = newstr(pw->pw_dir); 605 define('z', e->e_from.q_home, e); 606 607 /* extract user and group id */ 608 e->e_from.q_uid = pw->pw_uid; 609 e->e_from.q_gid = pw->pw_gid; 610 611 /* extract full name from passwd file */ 612 if (FullName == NULL && pw->pw_gecos != NULL && 613 strcmp(pw->pw_name, e->e_from.q_user) == 0 && 614 !internal) 615 { 616 buildfname(pw->pw_gecos, e->e_from.q_user, buf); 617 if (buf[0] != '\0') 618 FullName = newstr(buf); 619 } 620 } 621 if (FullName != NULL && !internal) 622 define('x', FullName, e); 623 } 624 else if (!internal) 625 { 626 if (e->e_from.q_home == NULL) 627 e->e_from.q_home = getenv("HOME"); 628 e->e_from.q_uid = getuid(); 629 e->e_from.q_gid = getgid(); 630 } 631 632 /* 633 ** Rewrite the from person to dispose of possible implicit 634 ** links in the net. 635 */ 636 637 if (pvp == NULL) 638 pvp = prescan(from, '\0', pvpbuf, NULL); 639 if (pvp == NULL) 640 { 641 /* don't need to give error -- prescan did that already */ 642 # ifdef LOG 643 if (LogLevel > 2) 644 syslog(LOG_NOTICE, "cannot prescan from (%s)", from); 645 # endif 646 finis(); 647 } 648 (void) rewrite(pvp, 3, e); 649 (void) rewrite(pvp, 1, e); 650 (void) rewrite(pvp, 4, e); 651 cataddr(pvp, NULL, buf, sizeof buf, '\0'); 652 e->e_sender = newstr(buf); 653 define('f', e->e_sender, e); 654 655 /* save the domain spec if this mailer wants it */ 656 if (!internal && e->e_from.q_mailer != NULL && 657 bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags)) 658 { 659 extern char **copyplist(); 660 661 while (*pvp != NULL && strcmp(*pvp, "@") != 0) 662 pvp++; 663 if (*pvp != NULL) 664 e->e_fromdomain = copyplist(pvp, TRUE); 665 } 666 } 667