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.89 (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 #if HASSETREUID || USESETEUID 903 saveduid = geteuid(); 904 savedgid = getegid(); 905 if (saveduid == 0) 906 { 907 initgroups(uname, gid); 908 if (uid != 0) 909 { 910 # if USESETEUID 911 if (seteuid(uid) < 0) 912 syserr("seteuid(%d) failure (real=%d, eff=%d)", 913 uid, getuid(), geteuid()); 914 # else 915 if (setreuid(0, uid) < 0) 916 syserr("setreuid(0, %d) failure (real=%d, eff=%d)", 917 uid, getuid(), geteuid()); 918 # endif 919 else 920 sfflags |= SFF_NOPATHCHECK; 921 } 922 } 923 #endif 924 925 if (tTd(27, 9)) 926 printf("include: new uid = %d/%d\n", getuid(), geteuid()); 927 928 /* 929 ** If home directory is remote mounted but server is down, 930 ** this can hang or give errors; use a timeout to avoid this 931 */ 932 933 if (setjmp(CtxIncludeTimeout) != 0) 934 { 935 ctladdr->q_flags |= QQUEUEUP; 936 errno = 0; 937 938 /* return pseudo-error code */ 939 rval = EOPENTIMEOUT; 940 goto resetuid; 941 } 942 if (TimeOuts.to_fileopen > 0) 943 ev = setevent(TimeOuts.to_fileopen, includetimeout, 0); 944 else 945 ev = NULL; 946 947 /* the input file must be marked safe */ 948 rval = safefile(fname, uid, gid, uname, sfflags, S_IREAD, NULL); 949 if (rval != 0) 950 { 951 /* don't use this :include: file */ 952 if (tTd(27, 4)) 953 printf("include: not safe (uid=%d): %s\n", 954 uid, errstring(rval)); 955 } 956 else 957 { 958 fp = fopen(fname, "r"); 959 if (fp == NULL) 960 { 961 rval = errno; 962 if (tTd(27, 4)) 963 printf("include: open: %s\n", errstring(rval)); 964 } 965 } 966 if (ev != NULL) 967 clrevent(ev); 968 969 resetuid: 970 971 #if HASSETREUID || USESETEUID 972 if (saveduid == 0) 973 { 974 if (uid != 0) 975 { 976 # if USESETEUID 977 if (seteuid(0) < 0) 978 syserr("seteuid(0) failure (real=%d, eff=%d)", 979 getuid(), geteuid()); 980 # else 981 if (setreuid(-1, 0) < 0) 982 syserr("setreuid(-1, 0) failure (real=%d, eff=%d)", 983 getuid(), geteuid()); 984 if (setreuid(RealUid, 0) < 0) 985 syserr("setreuid(%d, 0) failure (real=%d, eff=%d)", 986 RealUid, getuid(), geteuid()); 987 # endif 988 } 989 setgid(savedgid); 990 } 991 #endif 992 993 if (tTd(27, 9)) 994 printf("include: reset uid = %d/%d\n", getuid(), geteuid()); 995 996 if (rval == EOPENTIMEOUT) 997 usrerr("451 open timeout on %s", fname); 998 999 if (fp == NULL) 1000 return rval; 1001 1002 if (fstat(fileno(fp), &st) < 0) 1003 { 1004 rval = errno; 1005 syserr("Cannot fstat %s!", fname); 1006 return rval; 1007 } 1008 1009 #ifndef safechown 1010 safechown = chownsafe(fileno(fp)); 1011 #endif 1012 if (ca == NULL && safechown) 1013 { 1014 ctladdr->q_uid = st.st_uid; 1015 ctladdr->q_gid = st.st_gid; 1016 ctladdr->q_flags |= QGOODUID; 1017 } 1018 if (ca != NULL && ca->q_uid == st.st_uid) 1019 { 1020 /* optimization -- avoid getpwuid if we already have info */ 1021 ctladdr->q_flags |= ca->q_flags & QBOGUSSHELL; 1022 ctladdr->q_ruser = ca->q_ruser; 1023 } 1024 else 1025 { 1026 register struct passwd *pw; 1027 1028 pw = sm_getpwuid(st.st_uid); 1029 if (pw == NULL) 1030 ctladdr->q_flags |= QBOGUSSHELL; 1031 else 1032 { 1033 char *sh; 1034 1035 ctladdr->q_ruser = newstr(pw->pw_name); 1036 if (safechown) 1037 sh = pw->pw_shell; 1038 else 1039 sh = "/SENDMAIL/ANY/SHELL/"; 1040 if (!usershellok(sh)) 1041 { 1042 if (safechown) 1043 ctladdr->q_flags |= QBOGUSSHELL; 1044 else 1045 ctladdr->q_flags |= QUNSAFEADDR; 1046 } 1047 } 1048 } 1049 1050 if (bitset(EF_VRFYONLY, e->e_flags)) 1051 { 1052 /* don't do any more now */ 1053 ctladdr->q_flags |= QVERIFIED; 1054 e->e_nrcpts++; 1055 xfclose(fp, "include", fname); 1056 return rval; 1057 } 1058 1059 /* 1060 ** Check to see if some bad guy can write this file 1061 ** 1062 ** This should really do something clever with group 1063 ** permissions; currently we just view world writable 1064 ** as unsafe. Also, we don't check for writable 1065 ** directories in the path. We've got to leave 1066 ** something for the local sysad to do. 1067 */ 1068 1069 if (bitset(S_IWOTH, st.st_mode)) 1070 ctladdr->q_flags |= QUNSAFEADDR; 1071 1072 /* read the file -- each line is a comma-separated list. */ 1073 FileName = fname; 1074 LineNumber = 0; 1075 ctladdr->q_flags &= ~QSELFREF; 1076 nincludes = 0; 1077 while (fgets(buf, sizeof buf, fp) != NULL) 1078 { 1079 register char *p = strchr(buf, '\n'); 1080 1081 LineNumber++; 1082 if (p != NULL) 1083 *p = '\0'; 1084 if (buf[0] == '#' || buf[0] == '\0') 1085 continue; 1086 1087 /* <sp>#@# introduces a comment anywhere */ 1088 /* for Japanese character sets */ 1089 for (p = buf; (p = strchr(++p, '#')) != NULL; ) 1090 { 1091 if (p[1] == '@' && p[2] == '#' && 1092 isascii(p[-1]) && isspace(p[-1]) && 1093 isascii(p[3]) && isspace(p[3])) 1094 { 1095 p[-1] = '\0'; 1096 break; 1097 } 1098 } 1099 if (buf[0] == '\0') 1100 continue; 1101 1102 e->e_to = NULL; 1103 message("%s to %s", 1104 forwarding ? "forwarding" : "sending", buf); 1105 #ifdef LOG 1106 if (forwarding && LogLevel > 9) 1107 syslog(LOG_INFO, "%s: forward %s => %s", 1108 e->e_id == NULL ? "NOQUEUE" : e->e_id, 1109 oldto, buf); 1110 #endif 1111 1112 nincludes += sendtolist(buf, ctladdr, sendq, aliaslevel + 1, e); 1113 } 1114 1115 if (ferror(fp) && tTd(27, 3)) 1116 printf("include: read error: %s\n", errstring(errno)); 1117 if (nincludes > 0 && !bitset(QSELFREF, ctladdr->q_flags)) 1118 { 1119 if (tTd(27, 5)) 1120 { 1121 printf("include: QDONTSEND "); 1122 printaddr(ctladdr, FALSE); 1123 } 1124 ctladdr->q_flags |= QDONTSEND; 1125 } 1126 1127 (void) xfclose(fp, "include", fname); 1128 FileName = oldfilename; 1129 LineNumber = oldlinenumber; 1130 e->e_to = oldto; 1131 return rval; 1132 } 1133 1134 static void 1135 includetimeout() 1136 { 1137 longjmp(CtxIncludeTimeout, 1); 1138 } 1139 /* 1140 ** SENDTOARGV -- send to an argument vector. 1141 ** 1142 ** Parameters: 1143 ** argv -- argument vector to send to. 1144 ** e -- the current envelope. 1145 ** 1146 ** Returns: 1147 ** none. 1148 ** 1149 ** Side Effects: 1150 ** puts all addresses on the argument vector onto the 1151 ** send queue. 1152 */ 1153 1154 sendtoargv(argv, e) 1155 register char **argv; 1156 register ENVELOPE *e; 1157 { 1158 register char *p; 1159 1160 while ((p = *argv++) != NULL) 1161 { 1162 (void) sendtolist(p, NULLADDR, &e->e_sendqueue, 0, e); 1163 } 1164 } 1165 /* 1166 ** GETCTLADDR -- get controlling address from an address header. 1167 ** 1168 ** If none, get one corresponding to the effective userid. 1169 ** 1170 ** Parameters: 1171 ** a -- the address to find the controller of. 1172 ** 1173 ** Returns: 1174 ** the controlling address. 1175 ** 1176 ** Side Effects: 1177 ** none. 1178 */ 1179 1180 ADDRESS * 1181 getctladdr(a) 1182 register ADDRESS *a; 1183 { 1184 while (a != NULL && !bitset(QGOODUID, a->q_flags)) 1185 a = a->q_alias; 1186 return (a); 1187 } 1188 /* 1189 ** SELF_REFERENCE -- check to see if an address references itself 1190 ** 1191 ** The check is done through a chain of aliases. If it is part of 1192 ** a loop, break the loop at the "best" address, that is, the one 1193 ** that exists as a real user. 1194 ** 1195 ** This is to handle the case of: 1196 ** awc: Andrew.Chang 1197 ** Andrew.Chang: awc@mail.server 1198 ** which is a problem only on mail.server. 1199 ** 1200 ** Parameters: 1201 ** a -- the address to check. 1202 ** e -- the current envelope. 1203 ** 1204 ** Returns: 1205 ** The address that should be retained. 1206 */ 1207 1208 ADDRESS * 1209 self_reference(a, e) 1210 ADDRESS *a; 1211 ENVELOPE *e; 1212 { 1213 ADDRESS *b; /* top entry in self ref loop */ 1214 ADDRESS *c; /* entry that point to a real mail box */ 1215 1216 if (tTd(27, 1)) 1217 printf("self_reference(%s)\n", a->q_paddr); 1218 1219 for (b = a->q_alias; b != NULL; b = b->q_alias) 1220 { 1221 if (sameaddr(a, b)) 1222 break; 1223 } 1224 1225 if (b == NULL) 1226 { 1227 if (tTd(27, 1)) 1228 printf("\t... no self ref\n"); 1229 return NULL; 1230 } 1231 1232 /* 1233 ** Pick the first address that resolved to a real mail box 1234 ** i.e has a pw entry. The returned value will be marked 1235 ** QSELFREF in recipient(), which in turn will disable alias() 1236 ** from marking it QDONTSEND, which mean it will be used 1237 ** as a deliverable address. 1238 ** 1239 ** The 2 key thing to note here are: 1240 ** 1) we are in a recursive call sequence: 1241 ** alias->sentolist->recipient->alias 1242 ** 2) normally, when we return back to alias(), the address 1243 ** will be marked QDONTSEND, since alias() assumes the 1244 ** expanded form will be used instead of the current address. 1245 ** This behaviour is turned off if the address is marked 1246 ** QSELFREF We set QSELFREF when we return to recipient(). 1247 */ 1248 1249 c = a; 1250 while (c != NULL) 1251 { 1252 if (bitnset(M_HASPWENT, c->q_mailer->m_flags)) 1253 { 1254 if (tTd(27, 2)) 1255 printf("\t... getpwnam(%s)... ", c->q_user); 1256 if (sm_getpwnam(c->q_user) != NULL) 1257 { 1258 if (tTd(27, 2)) 1259 printf("found\n"); 1260 1261 /* ought to cache results here */ 1262 if (sameaddr(b, c)) 1263 return b; 1264 else 1265 return c; 1266 } 1267 if (tTd(27, 2)) 1268 printf("failed\n"); 1269 } 1270 c = c->q_alias; 1271 } 1272 1273 if (tTd(27, 1)) 1274 printf("\t... cannot break loop for \"%s\"\n", a->q_paddr); 1275 1276 return NULL; 1277 } 1278