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.88 (Berkeley) 05/23/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 (!bitset(QDONTSEND, a->q_flags) && bitnset(M_ALIASABLE, m->m_flags)) 411 alias(a, sendq, aliaslevel, e); 412 413 # ifdef USERDB 414 /* if not aliased, look it up in the user database */ 415 if (!bitset(QDONTSEND|QNOTREMOTE|QVERIFIED, a->q_flags) && 416 bitnset(M_CHECKUDB, m->m_flags)) 417 { 418 extern int udbexpand(); 419 420 if (udbexpand(a, sendq, aliaslevel, e) == EX_TEMPFAIL) 421 { 422 a->q_flags |= QQUEUEUP; 423 if (e->e_message == NULL) 424 e->e_message = newstr("Deferred: user database error"); 425 # ifdef LOG 426 if (LogLevel > 8) 427 syslog(LOG_INFO, "%s: deferred: udbexpand: %s", 428 e->e_id == NULL ? "NOQUEUE" : e->e_id, 429 errstring(errno)); 430 # endif 431 message("queued (user database error): %s", 432 errstring(errno)); 433 e->e_nrcpts++; 434 goto testselfdestruct; 435 } 436 } 437 # endif 438 439 /* 440 ** If we have a level two config file, then pass the name through 441 ** Ruleset 5 before sending it off. Ruleset 5 has the right 442 ** to send rewrite it to another mailer. This gives us a hook 443 ** after local aliasing has been done. 444 */ 445 446 if (tTd(29, 5)) 447 { 448 printf("recipient: testing local? cl=%d, rr5=%x\n\t", 449 ConfigLevel, RewriteRules[5]); 450 printaddr(a, FALSE); 451 } 452 if (!bitset(QNOTREMOTE|QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags) && 453 ConfigLevel >= 2 && RewriteRules[5] != NULL && 454 bitnset(M_TRYRULESET5, m->m_flags)) 455 { 456 maplocaluser(a, sendq, aliaslevel + 1, e); 457 } 458 459 /* 460 ** If it didn't get rewritten to another mailer, go ahead 461 ** and deliver it. 462 */ 463 464 if (!bitset(QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags) && 465 bitnset(M_HASPWENT, m->m_flags)) 466 { 467 auto bool fuzzy; 468 register struct passwd *pw; 469 extern struct passwd *finduser(); 470 471 /* warning -- finduser may trash buf */ 472 pw = finduser(buf, &fuzzy); 473 if (pw == NULL) 474 { 475 a->q_flags |= QBADADDR; 476 a->q_status = "5.1.1"; 477 giveresponse(EX_NOUSER, m, NULL, a->q_alias, 478 (time_t) 0, e); 479 } 480 else 481 { 482 char nbuf[MAXNAME + 1]; 483 484 if (fuzzy) 485 { 486 /* name was a fuzzy match */ 487 a->q_user = newstr(pw->pw_name); 488 if (findusercount++ > 3) 489 { 490 a->q_flags |= QBADADDR; 491 a->q_status = "5.4.6"; 492 usrerr("554 aliasing/forwarding loop for %s broken", 493 pw->pw_name); 494 goto done; 495 } 496 497 /* see if it aliases */ 498 (void) strcpy(buf, pw->pw_name); 499 goto trylocaluser; 500 } 501 if (strcmp(pw->pw_dir, "/") == 0) 502 a->q_home = ""; 503 else 504 a->q_home = newstr(pw->pw_dir); 505 a->q_uid = pw->pw_uid; 506 a->q_gid = pw->pw_gid; 507 a->q_ruser = newstr(pw->pw_name); 508 a->q_flags |= QGOODUID; 509 buildfname(pw->pw_gecos, pw->pw_name, nbuf); 510 if (nbuf[0] != '\0') 511 a->q_fullname = newstr(nbuf); 512 if (pw->pw_shell != NULL && pw->pw_shell[0] != '\0' && 513 !usershellok(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|QBADADDR, 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 #ifdef 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 int bits; 741 register char *p; 742 char *uname; 743 744 if (tTd(29, 5)) 745 printf("writable(%s, 0x%x)\n", filename, flags); 746 747 #ifdef SUID_ROOT_FILES_OK 748 /* really ought to be passed down -- and not a good idea */ 749 flags |= SFF_ROOTOK; 750 #endif 751 752 /* 753 ** File does exist -- check that it is writable. 754 */ 755 756 if (ctladdr != NULL && geteuid() == 0) 757 { 758 euid = ctladdr->q_uid; 759 egid = ctladdr->q_gid; 760 uname = ctladdr->q_user; 761 } 762 else if (bitset(SFF_RUNASREALUID, flags)) 763 { 764 extern char RealUserName[]; 765 766 euid = RealUid; 767 egid = RealGid; 768 uname = RealUserName; 769 } 770 else if (FileMailer != NULL) 771 { 772 euid = FileMailer->m_uid; 773 egid = FileMailer->m_gid; 774 } 775 else 776 { 777 euid = egid = 0; 778 } 779 if (euid == 0) 780 { 781 euid = DefUid; 782 uname = DefUser; 783 } 784 if (egid == 0) 785 egid = DefGid; 786 if (geteuid() == 0) 787 flags |= SFF_SETUIDOK; 788 789 errno = safefile(filename, euid, egid, uname, flags, S_IWRITE, NULL); 790 return errno == 0; 791 } 792 /* 793 ** INCLUDE -- handle :include: specification. 794 ** 795 ** Parameters: 796 ** fname -- filename to include. 797 ** forwarding -- if TRUE, we are reading a .forward file. 798 ** if FALSE, it's a :include: file. 799 ** ctladdr -- address template to use to fill in these 800 ** addresses -- effective user/group id are 801 ** the important things. 802 ** sendq -- a pointer to the head of the send queue 803 ** to put these addresses in. 804 ** aliaslevel -- the alias nesting depth. 805 ** e -- the current envelope. 806 ** 807 ** Returns: 808 ** open error status 809 ** 810 ** Side Effects: 811 ** reads the :include: file and sends to everyone 812 ** listed in that file. 813 ** 814 ** Security Note: 815 ** If you have restricted chown (that is, you can't 816 ** give a file away), it is reasonable to allow programs 817 ** and files called from this :include: file to be to be 818 ** run as the owner of the :include: file. This is bogus 819 ** if there is any chance of someone giving away a file. 820 ** We assume that pre-POSIX systems can give away files. 821 ** 822 ** There is an additional restriction that if you 823 ** forward to a :include: file, it will not take on 824 ** the ownership of the :include: file. This may not 825 ** be necessary, but shouldn't hurt. 826 */ 827 828 static jmp_buf CtxIncludeTimeout; 829 static void includetimeout(); 830 831 int 832 include(fname, forwarding, ctladdr, sendq, aliaslevel, e) 833 char *fname; 834 bool forwarding; 835 ADDRESS *ctladdr; 836 ADDRESS **sendq; 837 int aliaslevel; 838 ENVELOPE *e; 839 { 840 FILE *fp = NULL; 841 char *oldto = e->e_to; 842 char *oldfilename = FileName; 843 int oldlinenumber = LineNumber; 844 register EVENT *ev = NULL; 845 int nincludes; 846 register ADDRESS *ca; 847 uid_t saveduid, uid; 848 gid_t savedgid, gid; 849 char *uname; 850 int rval = 0; 851 int sfflags = SFF_REGONLY; 852 struct stat st; 853 char buf[MAXLINE]; 854 #ifdef _POSIX_CHOWN_RESTRICTED 855 # if _POSIX_CHOWN_RESTRICTED == -1 856 # define safechown FALSE 857 # else 858 # define safechown TRUE 859 # endif 860 #else 861 # ifdef _PC_CHOWN_RESTRICTED 862 bool safechown; 863 # else 864 # ifdef BSD 865 # define safechown TRUE 866 # else 867 # define safechown FALSE 868 # endif 869 # endif 870 #endif 871 extern bool chownsafe(); 872 873 if (tTd(27, 2)) 874 printf("include(%s)\n", fname); 875 if (tTd(27, 4)) 876 printf(" ruid=%d euid=%d\n", getuid(), geteuid()); 877 if (tTd(27, 14)) 878 { 879 printf("ctladdr "); 880 printaddr(ctladdr, FALSE); 881 } 882 883 if (tTd(27, 9)) 884 printf("include: old uid = %d/%d\n", getuid(), geteuid()); 885 886 if (forwarding) 887 sfflags |= SFF_MUSTOWN|SFF_ROOTOK|SFF_NOSLINK; 888 889 ca = getctladdr(ctladdr); 890 if (ca == NULL) 891 { 892 uid = DefUid; 893 gid = DefGid; 894 uname = DefUser; 895 } 896 else 897 { 898 uid = ca->q_uid; 899 gid = ca->q_gid; 900 uname = ca->q_user; 901 } 902 #ifdef HASSETREUID 903 saveduid = geteuid(); 904 savedgid = getegid(); 905 if (saveduid == 0) 906 { 907 initgroups(uname, gid); 908 if (uid != 0) 909 { 910 if (setreuid(0, uid) < 0) 911 syserr("setreuid(0, %d) failure (real=%d, eff=%d)", 912 uid, getuid(), geteuid()); 913 else 914 sfflags |= SFF_NOPATHCHECK; 915 } 916 } 917 #endif 918 919 if (tTd(27, 9)) 920 printf("include: new uid = %d/%d\n", getuid(), geteuid()); 921 922 /* 923 ** If home directory is remote mounted but server is down, 924 ** this can hang or give errors; use a timeout to avoid this 925 */ 926 927 if (setjmp(CtxIncludeTimeout) != 0) 928 { 929 ctladdr->q_flags |= QQUEUEUP; 930 errno = 0; 931 932 /* return pseudo-error code */ 933 rval = EOPENTIMEOUT; 934 goto resetuid; 935 } 936 if (TimeOuts.to_fileopen > 0) 937 ev = setevent(TimeOuts.to_fileopen, includetimeout, 0); 938 else 939 ev = NULL; 940 941 /* the input file must be marked safe */ 942 rval = safefile(fname, uid, gid, uname, sfflags, S_IREAD, NULL); 943 if (rval != 0) 944 { 945 /* don't use this :include: file */ 946 if (tTd(27, 4)) 947 printf("include: not safe (uid=%d): %s\n", 948 uid, errstring(rval)); 949 } 950 else 951 { 952 fp = fopen(fname, "r"); 953 if (fp == NULL) 954 { 955 rval = errno; 956 if (tTd(27, 4)) 957 printf("include: open: %s\n", errstring(rval)); 958 } 959 } 960 if (ev != NULL) 961 clrevent(ev); 962 963 resetuid: 964 965 #ifdef HASSETREUID 966 if (saveduid == 0) 967 { 968 if (uid != 0) 969 { 970 if (setreuid(-1, 0) < 0) 971 syserr("setreuid(-1, 0) failure (real=%d, eff=%d)", 972 getuid(), geteuid()); 973 if (setreuid(RealUid, 0) < 0) 974 syserr("setreuid(%d, 0) failure (real=%d, eff=%d)", 975 RealUid, getuid(), geteuid()); 976 } 977 setgid(savedgid); 978 } 979 #endif 980 981 if (tTd(27, 9)) 982 printf("include: reset uid = %d/%d\n", getuid(), geteuid()); 983 984 if (rval == EOPENTIMEOUT) 985 usrerr("451 open timeout on %s", fname); 986 987 if (fp == NULL) 988 return rval; 989 990 if (fstat(fileno(fp), &st) < 0) 991 { 992 rval = errno; 993 syserr("Cannot fstat %s!", fname); 994 return rval; 995 } 996 997 #ifndef safechown 998 safechown = chownsafe(fileno(fp)); 999 #endif 1000 if (ca == NULL && safechown) 1001 { 1002 ctladdr->q_uid = st.st_uid; 1003 ctladdr->q_gid = st.st_gid; 1004 ctladdr->q_flags |= QGOODUID; 1005 } 1006 if (ca != NULL && ca->q_uid == st.st_uid) 1007 { 1008 /* optimization -- avoid getpwuid if we already have info */ 1009 ctladdr->q_flags |= ca->q_flags & QBOGUSSHELL; 1010 ctladdr->q_ruser = ca->q_ruser; 1011 } 1012 else 1013 { 1014 register struct passwd *pw; 1015 1016 pw = sm_getpwuid(st.st_uid); 1017 if (pw == NULL) 1018 ctladdr->q_flags |= QBOGUSSHELL; 1019 else 1020 { 1021 char *sh; 1022 1023 ctladdr->q_ruser = newstr(pw->pw_name); 1024 if (safechown) 1025 sh = pw->pw_shell; 1026 else 1027 sh = "/SENDMAIL/ANY/SHELL/"; 1028 if (!usershellok(sh)) 1029 { 1030 if (safechown) 1031 ctladdr->q_flags |= QBOGUSSHELL; 1032 else 1033 ctladdr->q_flags |= QUNSAFEADDR; 1034 } 1035 } 1036 } 1037 1038 if (bitset(EF_VRFYONLY, e->e_flags)) 1039 { 1040 /* don't do any more now */ 1041 ctladdr->q_flags |= QVERIFIED; 1042 e->e_nrcpts++; 1043 xfclose(fp, "include", fname); 1044 return rval; 1045 } 1046 1047 /* 1048 ** Check to see if some bad guy can write this file 1049 ** 1050 ** This should really do something clever with group 1051 ** permissions; currently we just view world writable 1052 ** as unsafe. Also, we don't check for writable 1053 ** directories in the path. We've got to leave 1054 ** something for the local sysad to do. 1055 */ 1056 1057 if (bitset(S_IWOTH, st.st_mode)) 1058 ctladdr->q_flags |= QUNSAFEADDR; 1059 1060 /* read the file -- each line is a comma-separated list. */ 1061 FileName = fname; 1062 LineNumber = 0; 1063 ctladdr->q_flags &= ~QSELFREF; 1064 nincludes = 0; 1065 while (fgets(buf, sizeof buf, fp) != NULL) 1066 { 1067 register char *p = strchr(buf, '\n'); 1068 1069 LineNumber++; 1070 if (p != NULL) 1071 *p = '\0'; 1072 if (buf[0] == '#' || buf[0] == '\0') 1073 continue; 1074 1075 /* <sp>#@# introduces a comment anywhere */ 1076 /* for Japanese character sets */ 1077 for (p = buf; (p = strchr(++p, '#')) != NULL; ) 1078 { 1079 if (p[1] == '@' && p[2] == '#' && 1080 isascii(p[-1]) && isspace(p[-1]) && 1081 isascii(p[3]) && isspace(p[3])) 1082 { 1083 p[-1] = '\0'; 1084 break; 1085 } 1086 } 1087 if (buf[0] == '\0') 1088 continue; 1089 1090 e->e_to = NULL; 1091 message("%s to %s", 1092 forwarding ? "forwarding" : "sending", buf); 1093 #ifdef LOG 1094 if (forwarding && LogLevel > 9) 1095 syslog(LOG_INFO, "%s: forward %s => %s", 1096 e->e_id == NULL ? "NOQUEUE" : e->e_id, 1097 oldto, buf); 1098 #endif 1099 1100 nincludes += sendtolist(buf, ctladdr, sendq, aliaslevel + 1, e); 1101 } 1102 1103 if (ferror(fp) && tTd(27, 3)) 1104 printf("include: read error: %s\n", errstring(errno)); 1105 if (nincludes > 0 && !bitset(QSELFREF, ctladdr->q_flags)) 1106 { 1107 if (tTd(27, 5)) 1108 { 1109 printf("include: QDONTSEND "); 1110 printaddr(ctladdr, FALSE); 1111 } 1112 ctladdr->q_flags |= QDONTSEND; 1113 } 1114 1115 (void) xfclose(fp, "include", fname); 1116 FileName = oldfilename; 1117 LineNumber = oldlinenumber; 1118 e->e_to = oldto; 1119 return rval; 1120 } 1121 1122 static void 1123 includetimeout() 1124 { 1125 longjmp(CtxIncludeTimeout, 1); 1126 } 1127 /* 1128 ** SENDTOARGV -- send to an argument vector. 1129 ** 1130 ** Parameters: 1131 ** argv -- argument vector to send to. 1132 ** e -- the current envelope. 1133 ** 1134 ** Returns: 1135 ** none. 1136 ** 1137 ** Side Effects: 1138 ** puts all addresses on the argument vector onto the 1139 ** send queue. 1140 */ 1141 1142 sendtoargv(argv, e) 1143 register char **argv; 1144 register ENVELOPE *e; 1145 { 1146 register char *p; 1147 1148 while ((p = *argv++) != NULL) 1149 { 1150 (void) sendtolist(p, NULLADDR, &e->e_sendqueue, 0, e); 1151 } 1152 } 1153 /* 1154 ** GETCTLADDR -- get controlling address from an address header. 1155 ** 1156 ** If none, get one corresponding to the effective userid. 1157 ** 1158 ** Parameters: 1159 ** a -- the address to find the controller of. 1160 ** 1161 ** Returns: 1162 ** the controlling address. 1163 ** 1164 ** Side Effects: 1165 ** none. 1166 */ 1167 1168 ADDRESS * 1169 getctladdr(a) 1170 register ADDRESS *a; 1171 { 1172 while (a != NULL && !bitset(QGOODUID, a->q_flags)) 1173 a = a->q_alias; 1174 return (a); 1175 } 1176 /* 1177 ** SELF_REFERENCE -- check to see if an address references itself 1178 ** 1179 ** The check is done through a chain of aliases. If it is part of 1180 ** a loop, break the loop at the "best" address, that is, the one 1181 ** that exists as a real user. 1182 ** 1183 ** This is to handle the case of: 1184 ** awc: Andrew.Chang 1185 ** Andrew.Chang: awc@mail.server 1186 ** which is a problem only on mail.server. 1187 ** 1188 ** Parameters: 1189 ** a -- the address to check. 1190 ** e -- the current envelope. 1191 ** 1192 ** Returns: 1193 ** The address that should be retained. 1194 */ 1195 1196 ADDRESS * 1197 self_reference(a, e) 1198 ADDRESS *a; 1199 ENVELOPE *e; 1200 { 1201 ADDRESS *b; /* top entry in self ref loop */ 1202 ADDRESS *c; /* entry that point to a real mail box */ 1203 1204 if (tTd(27, 1)) 1205 printf("self_reference(%s)\n", a->q_paddr); 1206 1207 for (b = a->q_alias; b != NULL; b = b->q_alias) 1208 { 1209 if (sameaddr(a, b)) 1210 break; 1211 } 1212 1213 if (b == NULL) 1214 { 1215 if (tTd(27, 1)) 1216 printf("\t... no self ref\n"); 1217 return NULL; 1218 } 1219 1220 /* 1221 ** Pick the first address that resolved to a real mail box 1222 ** i.e has a pw entry. The returned value will be marked 1223 ** QSELFREF in recipient(), which in turn will disable alias() 1224 ** from marking it QDONTSEND, which mean it will be used 1225 ** as a deliverable address. 1226 ** 1227 ** The 2 key thing to note here are: 1228 ** 1) we are in a recursive call sequence: 1229 ** alias->sentolist->recipient->alias 1230 ** 2) normally, when we return back to alias(), the address 1231 ** will be marked QDONTSEND, since alias() assumes the 1232 ** expanded form will be used instead of the current address. 1233 ** This behaviour is turned off if the address is marked 1234 ** QSELFREF We set QSELFREF when we return to recipient(). 1235 */ 1236 1237 c = a; 1238 while (c != NULL) 1239 { 1240 if (bitnset(M_HASPWENT, c->q_mailer->m_flags)) 1241 { 1242 if (tTd(27, 2)) 1243 printf("\t... getpwnam(%s)... ", c->q_user); 1244 if (sm_getpwnam(c->q_user) != NULL) 1245 { 1246 if (tTd(27, 2)) 1247 printf("found\n"); 1248 1249 /* ought to cache results here */ 1250 if (sameaddr(b, c)) 1251 return b; 1252 else 1253 return c; 1254 } 1255 if (tTd(27, 2)) 1256 printf("failed\n"); 1257 } 1258 c = c->q_alias; 1259 } 1260 1261 if (tTd(27, 1)) 1262 printf("\t... cannot break loop for \"%s\"\n", a->q_paddr); 1263 1264 return NULL; 1265 } 1266