1 /* 2 * Copyright (c) 1983, 1995 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[] = "@(#)recipient.c 8.96 (Berkeley) 06/15/95"; 11 #endif /* not lint */ 12 13 # include "sendmail.h" 14 15 /* 16 ** SENDTOLIST -- Designate a send list. 17 ** 18 ** The parameter is a comma-separated list of people to send to. 19 ** This routine arranges to send to all of them. 20 ** 21 ** Parameters: 22 ** list -- the send list. 23 ** ctladdr -- the address template for the person to 24 ** send to -- effective uid/gid are important. 25 ** This is typically the alias that caused this 26 ** expansion. 27 ** sendq -- a pointer to the head of a queue to put 28 ** these people into. 29 ** aliaslevel -- the current alias nesting depth -- to 30 ** diagnose loops. 31 ** e -- the envelope in which to add these recipients. 32 ** 33 ** Returns: 34 ** The number of addresses actually on the list. 35 ** 36 ** Side Effects: 37 ** none. 38 */ 39 40 #define MAXRCRSN 10 /* maximum levels of alias recursion */ 41 42 /* q_flags bits inherited from ctladdr */ 43 #define QINHERITEDBITS (QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY|QHASNOTIFY) 44 45 int 46 sendtolist(list, ctladdr, sendq, aliaslevel, e) 47 char *list; 48 ADDRESS *ctladdr; 49 ADDRESS **sendq; 50 int aliaslevel; 51 register ENVELOPE *e; 52 { 53 register char *p; 54 register ADDRESS *al; /* list of addresses to send to */ 55 bool firstone; /* set on first address sent */ 56 char delimiter; /* the address delimiter */ 57 int naddrs; 58 int i; 59 char *oldto = e->e_to; 60 char *bufp; 61 char buf[MAXNAME + 1]; 62 63 if (list == NULL) 64 { 65 syserr("sendtolist: null list"); 66 return 0; 67 } 68 69 if (tTd(25, 1)) 70 { 71 printf("sendto: %s\n ctladdr=", list); 72 printaddr(ctladdr, FALSE); 73 } 74 75 /* heuristic to determine old versus new style addresses */ 76 if (ctladdr == NULL && 77 (strchr(list, ',') != NULL || strchr(list, ';') != NULL || 78 strchr(list, '<') != NULL || strchr(list, '(') != NULL)) 79 e->e_flags &= ~EF_OLDSTYLE; 80 delimiter = ' '; 81 if (!bitset(EF_OLDSTYLE, e->e_flags) || ctladdr != NULL) 82 delimiter = ','; 83 84 firstone = TRUE; 85 al = NULL; 86 naddrs = 0; 87 88 /* make sure we have enough space to copy the string */ 89 i = strlen(list) + 1; 90 if (i <= sizeof buf) 91 bufp = buf; 92 else 93 bufp = xalloc(i); 94 strcpy(bufp, denlstring(list, FALSE, TRUE)); 95 96 for (p = bufp; *p != '\0'; ) 97 { 98 auto char *delimptr; 99 register ADDRESS *a; 100 101 /* parse the address */ 102 while ((isascii(*p) && isspace(*p)) || *p == ',') 103 p++; 104 a = parseaddr(p, NULLADDR, RF_COPYALL, delimiter, &delimptr, e); 105 p = delimptr; 106 if (a == NULL) 107 continue; 108 a->q_next = al; 109 a->q_alias = ctladdr; 110 111 /* arrange to inherit attributes from parent */ 112 if (ctladdr != NULL) 113 { 114 ADDRESS *b; 115 extern ADDRESS *self_reference(); 116 117 /* self reference test */ 118 if (sameaddr(ctladdr, a)) 119 { 120 if (tTd(27, 5)) 121 { 122 printf("sendtolist: QSELFREF "); 123 printaddr(ctladdr, FALSE); 124 } 125 ctladdr->q_flags |= QSELFREF; 126 } 127 128 /* check for address loops */ 129 b = self_reference(a, e); 130 if (b != NULL) 131 { 132 b->q_flags |= QSELFREF; 133 if (tTd(27, 5)) 134 { 135 printf("sendtolist: QSELFREF "); 136 printaddr(b, FALSE); 137 } 138 if (a != b) 139 { 140 if (tTd(27, 5)) 141 { 142 printf("sendtolist: QDONTSEND "); 143 printaddr(a, FALSE); 144 } 145 a->q_flags |= QDONTSEND; 146 continue; 147 } 148 } 149 150 /* full name */ 151 if (a->q_fullname == NULL) 152 a->q_fullname = ctladdr->q_fullname; 153 154 /* various flag bits */ 155 a->q_flags &= ~QINHERITEDBITS; 156 a->q_flags |= ctladdr->q_flags & QINHERITEDBITS; 157 158 /* original recipient information */ 159 a->q_orcpt = ctladdr->q_orcpt; 160 } 161 162 al = a; 163 firstone = FALSE; 164 } 165 166 /* arrange to send to everyone on the local send list */ 167 while (al != NULL) 168 { 169 register ADDRESS *a = al; 170 171 al = a->q_next; 172 a = recipient(a, sendq, aliaslevel, e); 173 naddrs++; 174 } 175 176 e->e_to = oldto; 177 if (bufp != buf) 178 free(bufp); 179 return (naddrs); 180 } 181 /* 182 ** RECIPIENT -- Designate a message recipient 183 ** 184 ** Saves the named person for future mailing. 185 ** 186 ** Parameters: 187 ** a -- the (preparsed) address header for the recipient. 188 ** sendq -- a pointer to the head of a queue to put the 189 ** recipient in. Duplicate supression is done 190 ** in this queue. 191 ** aliaslevel -- the current alias nesting depth. 192 ** e -- the current envelope. 193 ** 194 ** Returns: 195 ** The actual address in the queue. This will be "a" if 196 ** the address is not a duplicate, else the original address. 197 ** 198 ** Side Effects: 199 ** none. 200 */ 201 202 ADDRESS * 203 recipient(a, sendq, aliaslevel, e) 204 register ADDRESS *a; 205 register ADDRESS **sendq; 206 int aliaslevel; 207 register ENVELOPE *e; 208 { 209 register ADDRESS *q; 210 ADDRESS **pq; 211 register struct mailer *m; 212 register char *p; 213 bool quoted = FALSE; /* set if the addr has a quote bit */ 214 int findusercount = 0; 215 bool initialdontsend = bitset(QDONTSEND, a->q_flags); 216 int i; 217 char *buf; 218 char buf0[MAXNAME + 1]; /* unquoted image of the user name */ 219 extern int safefile(); 220 221 e->e_to = a->q_paddr; 222 m = a->q_mailer; 223 errno = 0; 224 if (aliaslevel == 0) 225 a->q_flags |= QPRIMARY; 226 if (tTd(26, 1)) 227 { 228 printf("\nrecipient (%d): ", aliaslevel); 229 printaddr(a, FALSE); 230 } 231 232 /* if this is primary, add it to the original recipient list */ 233 if (a->q_alias == NULL) 234 { 235 if (e->e_origrcpt == NULL) 236 e->e_origrcpt = a->q_paddr; 237 else if (e->e_origrcpt != a->q_paddr) 238 e->e_origrcpt = ""; 239 } 240 241 /* break aliasing loops */ 242 if (aliaslevel > MAXRCRSN) 243 { 244 a->q_status = "5.4.6"; 245 usrerr("554 aliasing/forwarding loop broken (%d aliases deep; %d max", 246 aliaslevel, MAXRCRSN); 247 return (a); 248 } 249 250 /* 251 ** Finish setting up address structure. 252 */ 253 254 /* get unquoted user for file, program or user.name check */ 255 i = strlen(a->q_user); 256 if (i >= sizeof buf0) 257 buf = xalloc(i + 1); 258 else 259 buf = buf0; 260 (void) strcpy(buf, a->q_user); 261 for (p = buf; *p != '\0' && !quoted; p++) 262 { 263 if (*p == '\\') 264 quoted = TRUE; 265 } 266 stripquotes(buf); 267 268 /* check for direct mailing to restricted mailers */ 269 if (m == ProgMailer) 270 { 271 if (a->q_alias == NULL) 272 { 273 a->q_flags |= QBADADDR; 274 a->q_status = "5.7.1"; 275 usrerr("550 Cannot mail directly to programs"); 276 } 277 else if (bitset(QBOGUSSHELL, a->q_alias->q_flags)) 278 { 279 a->q_flags |= QBADADDR; 280 a->q_status = "5.7.1"; 281 usrerr("550 User %s@%s doesn't have a valid shell for mailing to programs", 282 a->q_alias->q_ruser, MyHostName); 283 } 284 else if (bitset(QUNSAFEADDR, a->q_alias->q_flags)) 285 { 286 a->q_flags |= QBADADDR; 287 a->q_status = "5.7.1"; 288 usrerr("550 Address %s is unsafe for mailing to programs", 289 a->q_alias->q_paddr); 290 } 291 } 292 293 /* 294 ** Look up this person in the recipient list. 295 ** If they are there already, return, otherwise continue. 296 ** If the list is empty, just add it. Notice the cute 297 ** hack to make from addresses suppress things correctly: 298 ** the QDONTSEND bit will be set in the send list. 299 ** [Please note: the emphasis is on "hack."] 300 */ 301 302 for (pq = sendq; (q = *pq) != NULL; pq = &q->q_next) 303 { 304 if (sameaddr(q, a)) 305 { 306 if (tTd(26, 1)) 307 { 308 printf("%s in sendq: ", a->q_paddr); 309 printaddr(q, FALSE); 310 } 311 if (!bitset(QPRIMARY, q->q_flags)) 312 { 313 if (!bitset(QDONTSEND, a->q_flags)) 314 message("duplicate suppressed"); 315 q->q_flags |= a->q_flags; 316 } 317 else if (bitset(QSELFREF, q->q_flags)) 318 q->q_flags |= a->q_flags & ~QDONTSEND; 319 a = q; 320 goto done; 321 } 322 } 323 324 /* add address on list */ 325 *pq = a; 326 a->q_next = NULL; 327 328 /* 329 ** Alias the name and handle special mailer types. 330 */ 331 332 trylocaluser: 333 if (tTd(29, 7)) 334 printf("at trylocaluser %s\n", a->q_user); 335 336 if (bitset(QDONTSEND|QBADADDR|QVERIFIED, a->q_flags)) 337 goto testselfdestruct; 338 339 if (m == InclMailer) 340 { 341 a->q_flags |= QDONTSEND; 342 if (a->q_alias == NULL) 343 { 344 a->q_flags |= QBADADDR; 345 a->q_status = "5.7.1"; 346 usrerr("550 Cannot mail directly to :include:s"); 347 } 348 else 349 { 350 int ret; 351 352 message("including file %s", a->q_user); 353 ret = include(a->q_user, FALSE, a, sendq, aliaslevel, e); 354 if (transienterror(ret)) 355 { 356 #ifdef LOG 357 if (LogLevel > 2) 358 syslog(LOG_ERR, "%s: include %s: transient error: %s", 359 e->e_id == NULL ? "NOQUEUE" : e->e_id, 360 a->q_user, errstring(ret)); 361 #endif 362 a->q_flags |= QQUEUEUP; 363 a->q_flags &= ~QDONTSEND; 364 usrerr("451 Cannot open %s: %s", 365 a->q_user, errstring(ret)); 366 } 367 else if (ret != 0) 368 { 369 a->q_flags |= QBADADDR; 370 a->q_status = "5.2.4"; 371 usrerr("550 Cannot open %s: %s", 372 a->q_user, errstring(ret)); 373 } 374 } 375 } 376 else if (m == FileMailer) 377 { 378 extern bool writable(); 379 380 /* check if writable or creatable */ 381 if (a->q_alias == NULL) 382 { 383 a->q_flags |= QBADADDR; 384 a->q_status = "5.7.1"; 385 usrerr("550 Cannot mail directly to files"); 386 } 387 else if (bitset(QBOGUSSHELL, a->q_alias->q_flags)) 388 { 389 a->q_flags |= QBADADDR; 390 a->q_status = "5.7.1"; 391 usrerr("550 User %s@%s doesn't have a valid shell for mailing to files", 392 a->q_alias->q_ruser, MyHostName); 393 } 394 else if (bitset(QUNSAFEADDR, a->q_alias->q_flags)) 395 { 396 a->q_flags |= QBADADDR; 397 a->q_status = "5.7.1"; 398 usrerr("550 Address %s is unsafe for mailing to files", 399 a->q_alias->q_paddr); 400 } 401 else if (!writable(buf, getctladdr(a), SFF_CREAT)) 402 { 403 a->q_flags |= QBADADDR; 404 giveresponse(EX_CANTCREAT, m, NULL, a->q_alias, 405 (time_t) 0, e); 406 } 407 } 408 409 /* try aliasing */ 410 if (!quoted && !bitset(QDONTSEND, a->q_flags) && 411 bitnset(M_ALIASABLE, m->m_flags)) 412 alias(a, sendq, aliaslevel, e); 413 414 # if USERDB 415 /* if not aliased, look it up in the user database */ 416 if (!bitset(QDONTSEND|QNOTREMOTE|QVERIFIED, a->q_flags) && 417 bitnset(M_CHECKUDB, m->m_flags)) 418 { 419 extern int udbexpand(); 420 421 if (udbexpand(a, sendq, aliaslevel, e) == EX_TEMPFAIL) 422 { 423 a->q_flags |= QQUEUEUP; 424 if (e->e_message == NULL) 425 e->e_message = newstr("Deferred: user database error"); 426 # ifdef LOG 427 if (LogLevel > 8) 428 syslog(LOG_INFO, "%s: deferred: udbexpand: %s", 429 e->e_id == NULL ? "NOQUEUE" : e->e_id, 430 errstring(errno)); 431 # endif 432 message("queued (user database error): %s", 433 errstring(errno)); 434 e->e_nrcpts++; 435 goto testselfdestruct; 436 } 437 } 438 # endif 439 440 /* 441 ** If we have a level two config file, then pass the name through 442 ** Ruleset 5 before sending it off. Ruleset 5 has the right 443 ** to send rewrite it to another mailer. This gives us a hook 444 ** after local aliasing has been done. 445 */ 446 447 if (tTd(29, 5)) 448 { 449 printf("recipient: testing local? cl=%d, rr5=%x\n\t", 450 ConfigLevel, RewriteRules[5]); 451 printaddr(a, FALSE); 452 } 453 if (!bitset(QNOTREMOTE|QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags) && 454 ConfigLevel >= 2 && RewriteRules[5] != NULL && 455 bitnset(M_TRYRULESET5, m->m_flags)) 456 { 457 maplocaluser(a, sendq, aliaslevel + 1, e); 458 } 459 460 /* 461 ** If it didn't get rewritten to another mailer, go ahead 462 ** and deliver it. 463 */ 464 465 if (!bitset(QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags) && 466 bitnset(M_HASPWENT, m->m_flags)) 467 { 468 auto bool fuzzy; 469 register struct passwd *pw; 470 extern struct passwd *finduser(); 471 472 /* warning -- finduser may trash buf */ 473 pw = finduser(buf, &fuzzy); 474 if (pw == NULL) 475 { 476 a->q_flags |= QBADADDR; 477 a->q_status = "5.1.1"; 478 giveresponse(EX_NOUSER, m, NULL, a->q_alias, 479 (time_t) 0, e); 480 } 481 else 482 { 483 char nbuf[MAXNAME + 1]; 484 485 if (fuzzy) 486 { 487 /* name was a fuzzy match */ 488 a->q_user = newstr(pw->pw_name); 489 if (findusercount++ > 3) 490 { 491 a->q_flags |= QBADADDR; 492 a->q_status = "5.4.6"; 493 usrerr("554 aliasing/forwarding loop for %s broken", 494 pw->pw_name); 495 goto done; 496 } 497 498 /* see if it aliases */ 499 (void) strcpy(buf, pw->pw_name); 500 goto trylocaluser; 501 } 502 if (strcmp(pw->pw_dir, "/") == 0) 503 a->q_home = ""; 504 else 505 a->q_home = newstr(pw->pw_dir); 506 a->q_uid = pw->pw_uid; 507 a->q_gid = pw->pw_gid; 508 a->q_ruser = newstr(pw->pw_name); 509 a->q_flags |= QGOODUID; 510 buildfname(pw->pw_gecos, pw->pw_name, nbuf); 511 if (nbuf[0] != '\0') 512 a->q_fullname = newstr(nbuf); 513 if (!usershellok(pw->pw_name, pw->pw_shell)) 514 { 515 a->q_flags |= QBOGUSSHELL; 516 } 517 if (bitset(EF_VRFYONLY, e->e_flags)) 518 { 519 /* don't do any more now */ 520 a->q_flags |= QVERIFIED; 521 } 522 else if (!quoted) 523 forward(a, sendq, aliaslevel, e); 524 } 525 } 526 if (!bitset(QDONTSEND, a->q_flags)) 527 e->e_nrcpts++; 528 529 testselfdestruct: 530 a->q_flags |= QTHISPASS; 531 if (tTd(26, 8)) 532 { 533 printf("testselfdestruct: "); 534 printaddr(a, FALSE); 535 if (tTd(26, 10)) 536 { 537 printf("SENDQ:\n"); 538 printaddr(*sendq, TRUE); 539 printf("----\n"); 540 } 541 } 542 if (a->q_alias == NULL && a != &e->e_from && 543 bitset(QDONTSEND, a->q_flags)) 544 { 545 for (q = *sendq; q != NULL; q = q->q_next) 546 { 547 if (!bitset(QDONTSEND, q->q_flags) && 548 bitset(QTHISPASS, q->q_flags)) 549 break; 550 } 551 if (q == NULL) 552 { 553 a->q_flags |= QBADADDR; 554 a->q_status = "5.4.6"; 555 usrerr("554 aliasing/forwarding loop broken"); 556 } 557 } 558 559 done: 560 a->q_flags |= QTHISPASS; 561 if (buf != buf0) 562 free(buf); 563 564 /* 565 ** If we are at the top level, check to see if this has 566 ** expanded to exactly one address. If so, it can inherit 567 ** the primaryness of the address. 568 ** 569 ** While we're at it, clear the QTHISPASS bits. 570 */ 571 572 if (aliaslevel == 0) 573 { 574 int nrcpts = 0; 575 ADDRESS *only; 576 577 for (q = *sendq; q != NULL; q = q->q_next) 578 { 579 if (bitset(QTHISPASS, q->q_flags) && 580 !bitset(QDONTSEND|QBADADDR, q->q_flags)) 581 { 582 nrcpts++; 583 only = q; 584 } 585 q->q_flags &= ~QTHISPASS; 586 } 587 if (nrcpts == 1) 588 { 589 /* check to see if this actually got a new owner */ 590 q = only; 591 while ((q = q->q_alias) != NULL) 592 { 593 if (q->q_owner != NULL) 594 break; 595 } 596 if (q == NULL) 597 only->q_flags |= QPRIMARY; 598 } 599 else if (!initialdontsend && nrcpts > 0) 600 { 601 /* arrange for return receipt */ 602 e->e_flags |= EF_SENDRECEIPT; 603 a->q_flags |= QEXPANDED; 604 if (e->e_xfp != NULL) 605 fprintf(e->e_xfp, 606 "%s... expanded to multiple addresses\n", 607 a->q_paddr); 608 } 609 } 610 611 return (a); 612 } 613 /* 614 ** FINDUSER -- find the password entry for a user. 615 ** 616 ** This looks a lot like getpwnam, except that it may want to 617 ** do some fancier pattern matching in /etc/passwd. 618 ** 619 ** This routine contains most of the time of many sendmail runs. 620 ** It deserves to be optimized. 621 ** 622 ** Parameters: 623 ** name -- the name to match against. 624 ** fuzzyp -- an outarg that is set to TRUE if this entry 625 ** was found using the fuzzy matching algorithm; 626 ** set to FALSE otherwise. 627 ** 628 ** Returns: 629 ** A pointer to a pw struct. 630 ** NULL if name is unknown or ambiguous. 631 ** 632 ** Side Effects: 633 ** may modify name. 634 */ 635 636 struct passwd * 637 finduser(name, fuzzyp) 638 char *name; 639 bool *fuzzyp; 640 { 641 register struct passwd *pw; 642 register char *p; 643 644 if (tTd(29, 4)) 645 printf("finduser(%s): ", name); 646 647 *fuzzyp = FALSE; 648 649 #ifdef HESIOD 650 /* DEC Hesiod getpwnam accepts numeric strings -- short circuit it */ 651 for (p = name; *p != '\0'; p++) 652 if (!isascii(*p) || !isdigit(*p)) 653 break; 654 if (*p == '\0') 655 { 656 if (tTd(29, 4)) 657 printf("failed (numeric input)\n"); 658 return NULL; 659 } 660 #endif 661 662 /* look up this login name using fast path */ 663 if ((pw = sm_getpwnam(name)) != NULL) 664 { 665 if (tTd(29, 4)) 666 printf("found (non-fuzzy)\n"); 667 return (pw); 668 } 669 670 #if MATCHGECOS 671 /* see if fuzzy matching allowed */ 672 if (!MatchGecos) 673 { 674 if (tTd(29, 4)) 675 printf("not found (fuzzy disabled)\n"); 676 return NULL; 677 } 678 679 /* search for a matching full name instead */ 680 for (p = name; *p != '\0'; p++) 681 { 682 if (*p == (SpaceSub & 0177) || *p == '_') 683 *p = ' '; 684 } 685 (void) setpwent(); 686 while ((pw = getpwent()) != NULL) 687 { 688 char buf[MAXNAME + 1]; 689 690 buildfname(pw->pw_gecos, pw->pw_name, buf); 691 if (strchr(buf, ' ') != NULL && !strcasecmp(buf, name)) 692 { 693 if (tTd(29, 4)) 694 printf("fuzzy matches %s\n", pw->pw_name); 695 message("sending to login name %s", pw->pw_name); 696 *fuzzyp = TRUE; 697 return (pw); 698 } 699 } 700 if (tTd(29, 4)) 701 printf("no fuzzy match found\n"); 702 #else 703 if (tTd(29, 4)) 704 printf("not found (fuzzy disabled)\n"); 705 #endif 706 return (NULL); 707 } 708 /* 709 ** WRITABLE -- predicate returning if the file is writable. 710 ** 711 ** This routine must duplicate the algorithm in sys/fio.c. 712 ** Unfortunately, we cannot use the access call since we 713 ** won't necessarily be the real uid when we try to 714 ** actually open the file. 715 ** 716 ** Notice that ANY file with ANY execute bit is automatically 717 ** not writable. This is also enforced by mailfile. 718 ** 719 ** Parameters: 720 ** filename -- the file name to check. 721 ** ctladdr -- the controlling address for this file. 722 ** flags -- SFF_* flags to control the function. 723 ** 724 ** Returns: 725 ** TRUE -- if we will be able to write this file. 726 ** FALSE -- if we cannot write this file. 727 ** 728 ** Side Effects: 729 ** none. 730 */ 731 732 bool 733 writable(filename, ctladdr, flags) 734 char *filename; 735 ADDRESS *ctladdr; 736 int flags; 737 { 738 uid_t euid; 739 gid_t egid; 740 char *uname; 741 742 if (tTd(29, 5)) 743 printf("writable(%s, 0x%x)\n", filename, flags); 744 745 #ifdef SUID_ROOT_FILES_OK 746 /* really ought to be passed down -- and not a good idea */ 747 flags |= SFF_ROOTOK; 748 #endif 749 750 /* 751 ** File does exist -- check that it is writable. 752 */ 753 754 if (ctladdr != NULL && geteuid() == 0) 755 { 756 euid = ctladdr->q_uid; 757 egid = ctladdr->q_gid; 758 uname = ctladdr->q_user; 759 } 760 else if (bitset(SFF_RUNASREALUID, flags)) 761 { 762 euid = RealUid; 763 egid = RealGid; 764 uname = RealUserName; 765 } 766 else if (FileMailer != NULL) 767 { 768 euid = FileMailer->m_uid; 769 egid = FileMailer->m_gid; 770 uname = NULL; 771 } 772 else 773 { 774 euid = egid = 0; 775 uname = NULL; 776 } 777 if (euid == 0) 778 { 779 euid = DefUid; 780 uname = DefUser; 781 } 782 if (egid == 0) 783 egid = DefGid; 784 if (geteuid() == 0) 785 flags |= SFF_SETUIDOK; 786 787 errno = safefile(filename, euid, egid, uname, flags, S_IWRITE, NULL); 788 return errno == 0; 789 } 790 /* 791 ** INCLUDE -- handle :include: specification. 792 ** 793 ** Parameters: 794 ** fname -- filename to include. 795 ** forwarding -- if TRUE, we are reading a .forward file. 796 ** if FALSE, it's a :include: file. 797 ** ctladdr -- address template to use to fill in these 798 ** addresses -- effective user/group id are 799 ** the important things. 800 ** sendq -- a pointer to the head of the send queue 801 ** to put these addresses in. 802 ** aliaslevel -- the alias nesting depth. 803 ** e -- the current envelope. 804 ** 805 ** Returns: 806 ** open error status 807 ** 808 ** Side Effects: 809 ** reads the :include: file and sends to everyone 810 ** listed in that file. 811 ** 812 ** Security Note: 813 ** If you have restricted chown (that is, you can't 814 ** give a file away), it is reasonable to allow programs 815 ** and files called from this :include: file to be to be 816 ** run as the owner of the :include: file. This is bogus 817 ** if there is any chance of someone giving away a file. 818 ** We assume that pre-POSIX systems can give away files. 819 ** 820 ** There is an additional restriction that if you 821 ** forward to a :include: file, it will not take on 822 ** the ownership of the :include: file. This may not 823 ** be necessary, but shouldn't hurt. 824 */ 825 826 static jmp_buf CtxIncludeTimeout; 827 static void includetimeout(); 828 829 int 830 include(fname, forwarding, ctladdr, sendq, aliaslevel, e) 831 char *fname; 832 bool forwarding; 833 ADDRESS *ctladdr; 834 ADDRESS **sendq; 835 int aliaslevel; 836 ENVELOPE *e; 837 { 838 FILE *fp = NULL; 839 char *oldto = e->e_to; 840 char *oldfilename = FileName; 841 int oldlinenumber = LineNumber; 842 register EVENT *ev = NULL; 843 int nincludes; 844 register ADDRESS *ca; 845 uid_t saveduid, uid; 846 gid_t savedgid, gid; 847 char *uname; 848 int rval = 0; 849 int sfflags = SFF_REGONLY; 850 struct stat st; 851 char buf[MAXLINE]; 852 #ifdef _POSIX_CHOWN_RESTRICTED 853 # if _POSIX_CHOWN_RESTRICTED == -1 854 # define safechown FALSE 855 # else 856 # define safechown TRUE 857 # endif 858 #else 859 # ifdef _PC_CHOWN_RESTRICTED 860 bool safechown; 861 # else 862 # ifdef BSD 863 # define safechown TRUE 864 # else 865 # define safechown FALSE 866 # endif 867 # endif 868 #endif 869 extern bool chownsafe(); 870 871 if (tTd(27, 2)) 872 printf("include(%s)\n", fname); 873 if (tTd(27, 4)) 874 printf(" ruid=%d euid=%d\n", getuid(), geteuid()); 875 if (tTd(27, 14)) 876 { 877 printf("ctladdr "); 878 printaddr(ctladdr, FALSE); 879 } 880 881 if (tTd(27, 9)) 882 printf("include: old uid = %d/%d\n", getuid(), geteuid()); 883 884 if (forwarding) 885 sfflags |= SFF_MUSTOWN|SFF_ROOTOK|SFF_NOSLINK; 886 887 ca = getctladdr(ctladdr); 888 if (ca == NULL) 889 { 890 uid = DefUid; 891 gid = DefGid; 892 uname = DefUser; 893 } 894 else 895 { 896 uid = ca->q_uid; 897 gid = ca->q_gid; 898 uname = ca->q_user; 899 } 900 #if HASSETREUID || USESETEUID 901 saveduid = geteuid(); 902 savedgid = getegid(); 903 if (saveduid == 0) 904 { 905 initgroups(uname, gid); 906 if (uid != 0) 907 { 908 # if USESETEUID 909 if (seteuid(uid) < 0) 910 syserr("seteuid(%d) failure (real=%d, eff=%d)", 911 uid, getuid(), geteuid()); 912 # else 913 if (setreuid(0, uid) < 0) 914 syserr("setreuid(0, %d) failure (real=%d, eff=%d)", 915 uid, getuid(), geteuid()); 916 # endif 917 else 918 sfflags |= SFF_NOPATHCHECK; 919 } 920 } 921 #endif 922 923 if (tTd(27, 9)) 924 printf("include: new uid = %d/%d\n", getuid(), geteuid()); 925 926 /* 927 ** If home directory is remote mounted but server is down, 928 ** this can hang or give errors; use a timeout to avoid this 929 */ 930 931 if (setjmp(CtxIncludeTimeout) != 0) 932 { 933 ctladdr->q_flags |= QQUEUEUP; 934 errno = 0; 935 936 /* return pseudo-error code */ 937 rval = EOPENTIMEOUT; 938 goto resetuid; 939 } 940 if (TimeOuts.to_fileopen > 0) 941 ev = setevent(TimeOuts.to_fileopen, includetimeout, 0); 942 else 943 ev = NULL; 944 945 /* the input file must be marked safe */ 946 rval = safefile(fname, uid, gid, uname, sfflags, S_IREAD, NULL); 947 if (rval != 0) 948 { 949 /* don't use this :include: file */ 950 if (tTd(27, 4)) 951 printf("include: not safe (uid=%d): %s\n", 952 uid, errstring(rval)); 953 } 954 else 955 { 956 fp = fopen(fname, "r"); 957 if (fp == NULL) 958 { 959 rval = errno; 960 if (tTd(27, 4)) 961 printf("include: open: %s\n", errstring(rval)); 962 } 963 } 964 if (ev != NULL) 965 clrevent(ev); 966 967 resetuid: 968 969 #if HASSETREUID || USESETEUID 970 if (saveduid == 0) 971 { 972 if (uid != 0) 973 { 974 # if USESETEUID 975 if (seteuid(0) < 0) 976 syserr("seteuid(0) failure (real=%d, eff=%d)", 977 getuid(), geteuid()); 978 # else 979 if (setreuid(-1, 0) < 0) 980 syserr("setreuid(-1, 0) failure (real=%d, eff=%d)", 981 getuid(), geteuid()); 982 if (setreuid(RealUid, 0) < 0) 983 syserr("setreuid(%d, 0) failure (real=%d, eff=%d)", 984 RealUid, getuid(), geteuid()); 985 # endif 986 } 987 setgid(savedgid); 988 } 989 #endif 990 991 if (tTd(27, 9)) 992 printf("include: reset uid = %d/%d\n", getuid(), geteuid()); 993 994 if (rval == EOPENTIMEOUT) 995 usrerr("451 open timeout on %s", fname); 996 997 if (fp == NULL) 998 return rval; 999 1000 if (fstat(fileno(fp), &st) < 0) 1001 { 1002 rval = errno; 1003 syserr("Cannot fstat %s!", fname); 1004 return rval; 1005 } 1006 1007 #ifndef safechown 1008 safechown = chownsafe(fileno(fp)); 1009 #endif 1010 if (ca == NULL && safechown) 1011 { 1012 ctladdr->q_uid = st.st_uid; 1013 ctladdr->q_gid = st.st_gid; 1014 ctladdr->q_flags |= QGOODUID; 1015 } 1016 if (ca != NULL && ca->q_uid == st.st_uid) 1017 { 1018 /* optimization -- avoid getpwuid if we already have info */ 1019 ctladdr->q_flags |= ca->q_flags & QBOGUSSHELL; 1020 ctladdr->q_ruser = ca->q_ruser; 1021 } 1022 else 1023 { 1024 register struct passwd *pw; 1025 1026 pw = sm_getpwuid(st.st_uid); 1027 if (pw == NULL) 1028 ctladdr->q_flags |= QBOGUSSHELL; 1029 else 1030 { 1031 char *sh; 1032 1033 ctladdr->q_ruser = newstr(pw->pw_name); 1034 if (safechown) 1035 sh = pw->pw_shell; 1036 else 1037 sh = "/SENDMAIL/ANY/SHELL/"; 1038 if (!usershellok(pw->pw_name, sh)) 1039 { 1040 if (safechown) 1041 ctladdr->q_flags |= QBOGUSSHELL; 1042 else 1043 ctladdr->q_flags |= QUNSAFEADDR; 1044 } 1045 } 1046 } 1047 1048 if (bitset(EF_VRFYONLY, e->e_flags)) 1049 { 1050 /* don't do any more now */ 1051 ctladdr->q_flags |= QVERIFIED; 1052 e->e_nrcpts++; 1053 xfclose(fp, "include", fname); 1054 return rval; 1055 } 1056 1057 /* 1058 ** Check to see if some bad guy can write this file 1059 ** 1060 ** This should really do something clever with group 1061 ** permissions; currently we just view world writable 1062 ** as unsafe. Also, we don't check for writable 1063 ** directories in the path. We've got to leave 1064 ** something for the local sysad to do. 1065 */ 1066 1067 if (bitset(S_IWOTH, st.st_mode)) 1068 ctladdr->q_flags |= QUNSAFEADDR; 1069 1070 /* read the file -- each line is a comma-separated list. */ 1071 FileName = fname; 1072 LineNumber = 0; 1073 ctladdr->q_flags &= ~QSELFREF; 1074 nincludes = 0; 1075 while (fgets(buf, sizeof buf, fp) != NULL) 1076 { 1077 register char *p = strchr(buf, '\n'); 1078 1079 LineNumber++; 1080 if (p != NULL) 1081 *p = '\0'; 1082 if (buf[0] == '#' || buf[0] == '\0') 1083 continue; 1084 1085 /* <sp>#@# introduces a comment anywhere */ 1086 /* for Japanese character sets */ 1087 for (p = buf; (p = strchr(++p, '#')) != NULL; ) 1088 { 1089 if (p[1] == '@' && p[2] == '#' && 1090 isascii(p[-1]) && isspace(p[-1]) && 1091 (p[3] == '\0' || (isascii(p[3]) && isspace(p[3])))) 1092 { 1093 p[-1] = '\0'; 1094 break; 1095 } 1096 } 1097 if (buf[0] == '\0') 1098 continue; 1099 1100 e->e_to = NULL; 1101 message("%s to %s", 1102 forwarding ? "forwarding" : "sending", buf); 1103 #ifdef LOG 1104 if (forwarding && LogLevel > 9) 1105 syslog(LOG_INFO, "%s: forward %s => %s", 1106 e->e_id == NULL ? "NOQUEUE" : e->e_id, 1107 oldto, buf); 1108 #endif 1109 1110 nincludes += sendtolist(buf, ctladdr, sendq, aliaslevel + 1, e); 1111 } 1112 1113 if (ferror(fp) && tTd(27, 3)) 1114 printf("include: read error: %s\n", errstring(errno)); 1115 if (nincludes > 0 && !bitset(QSELFREF, ctladdr->q_flags)) 1116 { 1117 if (tTd(27, 5)) 1118 { 1119 printf("include: QDONTSEND "); 1120 printaddr(ctladdr, FALSE); 1121 } 1122 ctladdr->q_flags |= QDONTSEND; 1123 } 1124 1125 (void) xfclose(fp, "include", fname); 1126 FileName = oldfilename; 1127 LineNumber = oldlinenumber; 1128 e->e_to = oldto; 1129 return rval; 1130 } 1131 1132 static void 1133 includetimeout() 1134 { 1135 longjmp(CtxIncludeTimeout, 1); 1136 } 1137 /* 1138 ** SENDTOARGV -- send to an argument vector. 1139 ** 1140 ** Parameters: 1141 ** argv -- argument vector to send to. 1142 ** e -- the current envelope. 1143 ** 1144 ** Returns: 1145 ** none. 1146 ** 1147 ** Side Effects: 1148 ** puts all addresses on the argument vector onto the 1149 ** send queue. 1150 */ 1151 1152 void 1153 sendtoargv(argv, e) 1154 register char **argv; 1155 register ENVELOPE *e; 1156 { 1157 register char *p; 1158 1159 while ((p = *argv++) != NULL) 1160 { 1161 (void) sendtolist(p, NULLADDR, &e->e_sendqueue, 0, e); 1162 } 1163 } 1164 /* 1165 ** GETCTLADDR -- get controlling address from an address header. 1166 ** 1167 ** If none, get one corresponding to the effective userid. 1168 ** 1169 ** Parameters: 1170 ** a -- the address to find the controller of. 1171 ** 1172 ** Returns: 1173 ** the controlling address. 1174 ** 1175 ** Side Effects: 1176 ** none. 1177 */ 1178 1179 ADDRESS * 1180 getctladdr(a) 1181 register ADDRESS *a; 1182 { 1183 while (a != NULL && !bitset(QGOODUID, a->q_flags)) 1184 a = a->q_alias; 1185 return (a); 1186 } 1187 /* 1188 ** SELF_REFERENCE -- check to see if an address references itself 1189 ** 1190 ** The check is done through a chain of aliases. If it is part of 1191 ** a loop, break the loop at the "best" address, that is, the one 1192 ** that exists as a real user. 1193 ** 1194 ** This is to handle the case of: 1195 ** awc: Andrew.Chang 1196 ** Andrew.Chang: awc@mail.server 1197 ** which is a problem only on mail.server. 1198 ** 1199 ** Parameters: 1200 ** a -- the address to check. 1201 ** e -- the current envelope. 1202 ** 1203 ** Returns: 1204 ** The address that should be retained. 1205 */ 1206 1207 ADDRESS * 1208 self_reference(a, e) 1209 ADDRESS *a; 1210 ENVELOPE *e; 1211 { 1212 ADDRESS *b; /* top entry in self ref loop */ 1213 ADDRESS *c; /* entry that point to a real mail box */ 1214 1215 if (tTd(27, 1)) 1216 printf("self_reference(%s)\n", a->q_paddr); 1217 1218 for (b = a->q_alias; b != NULL; b = b->q_alias) 1219 { 1220 if (sameaddr(a, b)) 1221 break; 1222 } 1223 1224 if (b == NULL) 1225 { 1226 if (tTd(27, 1)) 1227 printf("\t... no self ref\n"); 1228 return NULL; 1229 } 1230 1231 /* 1232 ** Pick the first address that resolved to a real mail box 1233 ** i.e has a pw entry. The returned value will be marked 1234 ** QSELFREF in recipient(), which in turn will disable alias() 1235 ** from marking it QDONTSEND, which mean it will be used 1236 ** as a deliverable address. 1237 ** 1238 ** The 2 key thing to note here are: 1239 ** 1) we are in a recursive call sequence: 1240 ** alias->sentolist->recipient->alias 1241 ** 2) normally, when we return back to alias(), the address 1242 ** will be marked QDONTSEND, since alias() assumes the 1243 ** expanded form will be used instead of the current address. 1244 ** This behaviour is turned off if the address is marked 1245 ** QSELFREF We set QSELFREF when we return to recipient(). 1246 */ 1247 1248 c = a; 1249 while (c != NULL) 1250 { 1251 if (bitnset(M_HASPWENT, c->q_mailer->m_flags)) 1252 { 1253 if (tTd(27, 2)) 1254 printf("\t... getpwnam(%s)... ", c->q_user); 1255 if (sm_getpwnam(c->q_user) != NULL) 1256 { 1257 if (tTd(27, 2)) 1258 printf("found\n"); 1259 1260 /* ought to cache results here */ 1261 if (sameaddr(b, c)) 1262 return b; 1263 else 1264 return c; 1265 } 1266 if (tTd(27, 2)) 1267 printf("failed\n"); 1268 } 1269 c = c->q_alias; 1270 } 1271 1272 if (tTd(27, 1)) 1273 printf("\t... cannot break loop for \"%s\"\n", a->q_paddr); 1274 1275 return NULL; 1276 } 1277