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.86 (Berkeley) 05/19/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 (!quoted) 518 forward(a, sendq, aliaslevel, e); 519 } 520 } 521 if (!bitset(QDONTSEND, a->q_flags)) 522 e->e_nrcpts++; 523 524 testselfdestruct: 525 a->q_flags |= QTHISPASS; 526 if (tTd(26, 8)) 527 { 528 printf("testselfdestruct: "); 529 printaddr(a, FALSE); 530 if (tTd(26, 10)) 531 { 532 printf("SENDQ:\n"); 533 printaddr(*sendq, TRUE); 534 printf("----\n"); 535 } 536 } 537 if (a->q_alias == NULL && a != &e->e_from && 538 bitset(QDONTSEND, a->q_flags)) 539 { 540 for (q = *sendq; q != NULL; q = q->q_next) 541 { 542 if (!bitset(QDONTSEND|QBADADDR, q->q_flags) && 543 bitset(QTHISPASS, q->q_flags)) 544 break; 545 } 546 if (q == NULL) 547 { 548 a->q_flags |= QBADADDR; 549 a->q_status = "5.4.6"; 550 usrerr("554 aliasing/forwarding loop broken"); 551 } 552 } 553 554 done: 555 a->q_flags |= QTHISPASS; 556 if (buf != buf0) 557 free(buf); 558 559 /* 560 ** If we are at the top level, check to see if this has 561 ** expanded to exactly one address. If so, it can inherit 562 ** the primaryness of the address. 563 ** 564 ** While we're at it, clear the QTHISPASS bits. 565 */ 566 567 if (aliaslevel == 0) 568 { 569 int nrcpts = 0; 570 ADDRESS *only; 571 572 for (q = *sendq; q != NULL; q = q->q_next) 573 { 574 if (bitset(QTHISPASS, q->q_flags) && 575 !bitset(QDONTSEND|QBADADDR, q->q_flags)) 576 { 577 nrcpts++; 578 only = q; 579 } 580 q->q_flags &= ~QTHISPASS; 581 } 582 if (nrcpts == 1) 583 { 584 /* check to see if this actually got a new owner */ 585 q = only; 586 while ((q = q->q_alias) != NULL) 587 { 588 if (q->q_owner != NULL) 589 break; 590 } 591 if (q == NULL) 592 only->q_flags |= QPRIMARY; 593 } 594 else if (!initialdontsend && nrcpts > 0) 595 { 596 /* arrange for return receipt */ 597 e->e_flags |= EF_SENDRECEIPT; 598 a->q_flags |= QEXPANDED; 599 if (e->e_xfp != NULL) 600 fprintf(e->e_xfp, 601 "%s... expanded to multiple addresses\n", 602 a->q_paddr); 603 } 604 } 605 606 return (a); 607 } 608 /* 609 ** FINDUSER -- find the password entry for a user. 610 ** 611 ** This looks a lot like getpwnam, except that it may want to 612 ** do some fancier pattern matching in /etc/passwd. 613 ** 614 ** This routine contains most of the time of many sendmail runs. 615 ** It deserves to be optimized. 616 ** 617 ** Parameters: 618 ** name -- the name to match against. 619 ** fuzzyp -- an outarg that is set to TRUE if this entry 620 ** was found using the fuzzy matching algorithm; 621 ** set to FALSE otherwise. 622 ** 623 ** Returns: 624 ** A pointer to a pw struct. 625 ** NULL if name is unknown or ambiguous. 626 ** 627 ** Side Effects: 628 ** may modify name. 629 */ 630 631 struct passwd * 632 finduser(name, fuzzyp) 633 char *name; 634 bool *fuzzyp; 635 { 636 register struct passwd *pw; 637 register char *p; 638 639 if (tTd(29, 4)) 640 printf("finduser(%s): ", name); 641 642 *fuzzyp = FALSE; 643 644 #ifdef HESIOD 645 /* DEC Hesiod getpwnam accepts numeric strings -- short circuit it */ 646 for (p = name; *p != '\0'; p++) 647 if (!isascii(*p) || !isdigit(*p)) 648 break; 649 if (*p == '\0') 650 { 651 if (tTd(29, 4)) 652 printf("failed (numeric input)\n"); 653 return NULL; 654 } 655 #endif 656 657 /* look up this login name using fast path */ 658 if ((pw = sm_getpwnam(name)) != NULL) 659 { 660 if (tTd(29, 4)) 661 printf("found (non-fuzzy)\n"); 662 return (pw); 663 } 664 665 #ifdef MATCHGECOS 666 /* see if fuzzy matching allowed */ 667 if (!MatchGecos) 668 { 669 if (tTd(29, 4)) 670 printf("not found (fuzzy disabled)\n"); 671 return NULL; 672 } 673 674 /* search for a matching full name instead */ 675 for (p = name; *p != '\0'; p++) 676 { 677 if (*p == (SpaceSub & 0177) || *p == '_') 678 *p = ' '; 679 } 680 (void) setpwent(); 681 while ((pw = getpwent()) != NULL) 682 { 683 char buf[MAXNAME + 1]; 684 685 buildfname(pw->pw_gecos, pw->pw_name, buf); 686 if (strchr(buf, ' ') != NULL && !strcasecmp(buf, name)) 687 { 688 if (tTd(29, 4)) 689 printf("fuzzy matches %s\n", pw->pw_name); 690 message("sending to login name %s", pw->pw_name); 691 *fuzzyp = TRUE; 692 return (pw); 693 } 694 } 695 if (tTd(29, 4)) 696 printf("no fuzzy match found\n"); 697 #else 698 if (tTd(29, 4)) 699 printf("not found (fuzzy disabled)\n"); 700 #endif 701 return (NULL); 702 } 703 /* 704 ** WRITABLE -- predicate returning if the file is writable. 705 ** 706 ** This routine must duplicate the algorithm in sys/fio.c. 707 ** Unfortunately, we cannot use the access call since we 708 ** won't necessarily be the real uid when we try to 709 ** actually open the file. 710 ** 711 ** Notice that ANY file with ANY execute bit is automatically 712 ** not writable. This is also enforced by mailfile. 713 ** 714 ** Parameters: 715 ** filename -- the file name to check. 716 ** ctladdr -- the controlling address for this file. 717 ** flags -- SFF_* flags to control the function. 718 ** 719 ** Returns: 720 ** TRUE -- if we will be able to write this file. 721 ** FALSE -- if we cannot write this file. 722 ** 723 ** Side Effects: 724 ** none. 725 */ 726 727 bool 728 writable(filename, ctladdr, flags) 729 char *filename; 730 ADDRESS *ctladdr; 731 int flags; 732 { 733 uid_t euid; 734 gid_t egid; 735 int bits; 736 register char *p; 737 char *uname; 738 739 if (tTd(29, 5)) 740 printf("writable(%s, 0x%x)\n", filename, flags); 741 742 #ifdef SUID_ROOT_FILES_OK 743 /* really ought to be passed down -- and not a good idea */ 744 flags |= SFF_ROOTOK; 745 #endif 746 747 /* 748 ** File does exist -- check that it is writable. 749 */ 750 751 if (ctladdr != NULL && geteuid() == 0) 752 { 753 euid = ctladdr->q_uid; 754 egid = ctladdr->q_gid; 755 uname = ctladdr->q_user; 756 } 757 else if (bitset(SFF_RUNASREALUID, flags)) 758 { 759 extern char RealUserName[]; 760 761 euid = RealUid; 762 egid = RealGid; 763 uname = RealUserName; 764 } 765 else if (FileMailer != NULL) 766 { 767 euid = FileMailer->m_uid; 768 egid = FileMailer->m_gid; 769 } 770 else 771 { 772 euid = egid = 0; 773 } 774 if (euid == 0) 775 { 776 euid = DefUid; 777 uname = DefUser; 778 } 779 if (egid == 0) 780 egid = DefGid; 781 if (geteuid() == 0) 782 flags |= SFF_SETUIDOK; 783 784 errno = safefile(filename, euid, egid, uname, flags, S_IWRITE, NULL); 785 return errno == 0; 786 } 787 /* 788 ** INCLUDE -- handle :include: specification. 789 ** 790 ** Parameters: 791 ** fname -- filename to include. 792 ** forwarding -- if TRUE, we are reading a .forward file. 793 ** if FALSE, it's a :include: file. 794 ** ctladdr -- address template to use to fill in these 795 ** addresses -- effective user/group id are 796 ** the important things. 797 ** sendq -- a pointer to the head of the send queue 798 ** to put these addresses in. 799 ** aliaslevel -- the alias nesting depth. 800 ** e -- the current envelope. 801 ** 802 ** Returns: 803 ** open error status 804 ** 805 ** Side Effects: 806 ** reads the :include: file and sends to everyone 807 ** listed in that file. 808 ** 809 ** Security Note: 810 ** If you have restricted chown (that is, you can't 811 ** give a file away), it is reasonable to allow programs 812 ** and files called from this :include: file to be to be 813 ** run as the owner of the :include: file. This is bogus 814 ** if there is any chance of someone giving away a file. 815 ** We assume that pre-POSIX systems can give away files. 816 ** 817 ** There is an additional restriction that if you 818 ** forward to a :include: file, it will not take on 819 ** the ownership of the :include: file. This may not 820 ** be necessary, but shouldn't hurt. 821 */ 822 823 static jmp_buf CtxIncludeTimeout; 824 static void includetimeout(); 825 826 int 827 include(fname, forwarding, ctladdr, sendq, aliaslevel, e) 828 char *fname; 829 bool forwarding; 830 ADDRESS *ctladdr; 831 ADDRESS **sendq; 832 int aliaslevel; 833 ENVELOPE *e; 834 { 835 FILE *fp = NULL; 836 char *oldto = e->e_to; 837 char *oldfilename = FileName; 838 int oldlinenumber = LineNumber; 839 register EVENT *ev = NULL; 840 int nincludes; 841 register ADDRESS *ca; 842 uid_t saveduid, uid; 843 gid_t savedgid, gid; 844 char *uname; 845 int rval = 0; 846 int sfflags = SFF_REGONLY; 847 struct stat st; 848 char buf[MAXLINE]; 849 #ifdef _POSIX_CHOWN_RESTRICTED 850 # if _POSIX_CHOWN_RESTRICTED == -1 851 # define safechown FALSE 852 # else 853 # define safechown TRUE 854 # endif 855 #else 856 # ifdef _PC_CHOWN_RESTRICTED 857 bool safechown; 858 # else 859 # ifdef BSD 860 # define safechown TRUE 861 # else 862 # define safechown FALSE 863 # endif 864 # endif 865 #endif 866 extern bool chownsafe(); 867 868 if (tTd(27, 2)) 869 printf("include(%s)\n", fname); 870 if (tTd(27, 4)) 871 printf(" ruid=%d euid=%d\n", getuid(), geteuid()); 872 if (tTd(27, 14)) 873 { 874 printf("ctladdr "); 875 printaddr(ctladdr, FALSE); 876 } 877 878 if (tTd(27, 9)) 879 printf("include: old uid = %d/%d\n", getuid(), geteuid()); 880 881 if (forwarding) 882 sfflags |= SFF_MUSTOWN|SFF_ROOTOK|SFF_NOSLINK; 883 884 ca = getctladdr(ctladdr); 885 if (ca == NULL) 886 { 887 uid = DefUid; 888 gid = DefGid; 889 uname = DefUser; 890 } 891 else 892 { 893 uid = ca->q_uid; 894 gid = ca->q_gid; 895 uname = ca->q_user; 896 } 897 #ifdef HASSETREUID 898 saveduid = geteuid(); 899 savedgid = getegid(); 900 if (saveduid == 0) 901 { 902 initgroups(uname, gid); 903 if (uid != 0) 904 { 905 if (setreuid(0, uid) < 0) 906 syserr("setreuid(0, %d) failure (real=%d, eff=%d)", 907 uid, getuid(), geteuid()); 908 else 909 sfflags |= SFF_NOPATHCHECK; 910 } 911 } 912 #endif 913 914 if (tTd(27, 9)) 915 printf("include: new uid = %d/%d\n", getuid(), geteuid()); 916 917 /* 918 ** If home directory is remote mounted but server is down, 919 ** this can hang or give errors; use a timeout to avoid this 920 */ 921 922 if (setjmp(CtxIncludeTimeout) != 0) 923 { 924 ctladdr->q_flags |= QQUEUEUP; 925 errno = 0; 926 927 /* return pseudo-error code */ 928 rval = EOPENTIMEOUT; 929 goto resetuid; 930 } 931 if (TimeOuts.to_fileopen > 0) 932 ev = setevent(TimeOuts.to_fileopen, includetimeout, 0); 933 else 934 ev = NULL; 935 936 /* the input file must be marked safe */ 937 rval = safefile(fname, uid, gid, uname, sfflags, S_IREAD, NULL); 938 if (rval != 0) 939 { 940 /* don't use this :include: file */ 941 if (tTd(27, 4)) 942 printf("include: not safe (uid=%d): %s\n", 943 uid, errstring(rval)); 944 } 945 else 946 { 947 fp = fopen(fname, "r"); 948 if (fp == NULL) 949 { 950 rval = errno; 951 if (tTd(27, 4)) 952 printf("include: open: %s\n", errstring(rval)); 953 } 954 } 955 if (ev != NULL) 956 clrevent(ev); 957 958 resetuid: 959 960 #ifdef HASSETREUID 961 if (saveduid == 0) 962 { 963 if (uid != 0) 964 { 965 if (setreuid(-1, 0) < 0) 966 syserr("setreuid(-1, 0) failure (real=%d, eff=%d)", 967 getuid(), geteuid()); 968 if (setreuid(RealUid, 0) < 0) 969 syserr("setreuid(%d, 0) failure (real=%d, eff=%d)", 970 RealUid, getuid(), geteuid()); 971 } 972 setgid(savedgid); 973 } 974 #endif 975 976 if (tTd(27, 9)) 977 printf("include: reset uid = %d/%d\n", getuid(), geteuid()); 978 979 if (rval == EOPENTIMEOUT) 980 usrerr("451 open timeout on %s", fname); 981 982 if (fp == NULL) 983 return rval; 984 985 if (fstat(fileno(fp), &st) < 0) 986 { 987 rval = errno; 988 syserr("Cannot fstat %s!", fname); 989 return rval; 990 } 991 992 #ifndef safechown 993 safechown = chownsafe(fileno(fp)); 994 #endif 995 if (ca == NULL && safechown) 996 { 997 ctladdr->q_uid = st.st_uid; 998 ctladdr->q_gid = st.st_gid; 999 ctladdr->q_flags |= QGOODUID; 1000 } 1001 if (ca != NULL && ca->q_uid == st.st_uid) 1002 { 1003 /* optimization -- avoid getpwuid if we already have info */ 1004 ctladdr->q_flags |= ca->q_flags & QBOGUSSHELL; 1005 ctladdr->q_ruser = ca->q_ruser; 1006 } 1007 else 1008 { 1009 register struct passwd *pw; 1010 1011 pw = sm_getpwuid(st.st_uid); 1012 if (pw == NULL) 1013 ctladdr->q_flags |= QBOGUSSHELL; 1014 else 1015 { 1016 char *sh; 1017 1018 ctladdr->q_ruser = newstr(pw->pw_name); 1019 if (safechown) 1020 sh = pw->pw_shell; 1021 else 1022 sh = "/SENDMAIL/ANY/SHELL/"; 1023 if (!usershellok(sh)) 1024 { 1025 if (safechown) 1026 ctladdr->q_flags |= QBOGUSSHELL; 1027 else 1028 ctladdr->q_flags |= QUNSAFEADDR; 1029 } 1030 } 1031 } 1032 1033 if (bitset(EF_VRFYONLY, e->e_flags)) 1034 { 1035 /* don't do any more now */ 1036 ctladdr->q_flags |= QVERIFIED; 1037 e->e_nrcpts++; 1038 xfclose(fp, "include", fname); 1039 return rval; 1040 } 1041 1042 /* 1043 ** Check to see if some bad guy can write this file 1044 ** 1045 ** This should really do something clever with group 1046 ** permissions; currently we just view world writable 1047 ** as unsafe. Also, we don't check for writable 1048 ** directories in the path. We've got to leave 1049 ** something for the local sysad to do. 1050 */ 1051 1052 if (bitset(S_IWOTH, st.st_mode)) 1053 ctladdr->q_flags |= QUNSAFEADDR; 1054 1055 /* read the file -- each line is a comma-separated list. */ 1056 FileName = fname; 1057 LineNumber = 0; 1058 ctladdr->q_flags &= ~QSELFREF; 1059 nincludes = 0; 1060 while (fgets(buf, sizeof buf, fp) != NULL) 1061 { 1062 register char *p = strchr(buf, '\n'); 1063 1064 LineNumber++; 1065 if (p != NULL) 1066 *p = '\0'; 1067 if (buf[0] == '#' || buf[0] == '\0') 1068 continue; 1069 1070 /* <sp>#@# introduces a comment anywhere */ 1071 /* for Japanese character sets */ 1072 for (p = buf; (p = strchr(++p, '#')) != NULL; ) 1073 { 1074 if (p[1] == '@' && p[2] == '#' && 1075 isascii(p[-1]) && isspace(p[-1]) && 1076 isascii(p[3]) && isspace(p[3])) 1077 { 1078 p[-1] = '\0'; 1079 break; 1080 } 1081 } 1082 if (buf[0] == '\0') 1083 continue; 1084 1085 e->e_to = NULL; 1086 message("%s to %s", 1087 forwarding ? "forwarding" : "sending", buf); 1088 #ifdef LOG 1089 if (forwarding && LogLevel > 9) 1090 syslog(LOG_INFO, "%s: forward %s => %s", 1091 e->e_id == NULL ? "NOQUEUE" : e->e_id, 1092 oldto, buf); 1093 #endif 1094 1095 nincludes += sendtolist(buf, ctladdr, sendq, aliaslevel + 1, e); 1096 } 1097 1098 if (ferror(fp) && tTd(27, 3)) 1099 printf("include: read error: %s\n", errstring(errno)); 1100 if (nincludes > 0 && !bitset(QSELFREF, ctladdr->q_flags)) 1101 { 1102 if (tTd(27, 5)) 1103 { 1104 printf("include: QDONTSEND "); 1105 printaddr(ctladdr, FALSE); 1106 } 1107 ctladdr->q_flags |= QDONTSEND; 1108 } 1109 1110 (void) xfclose(fp, "include", fname); 1111 FileName = oldfilename; 1112 LineNumber = oldlinenumber; 1113 e->e_to = oldto; 1114 return rval; 1115 } 1116 1117 static void 1118 includetimeout() 1119 { 1120 longjmp(CtxIncludeTimeout, 1); 1121 } 1122 /* 1123 ** SENDTOARGV -- send to an argument vector. 1124 ** 1125 ** Parameters: 1126 ** argv -- argument vector to send to. 1127 ** e -- the current envelope. 1128 ** 1129 ** Returns: 1130 ** none. 1131 ** 1132 ** Side Effects: 1133 ** puts all addresses on the argument vector onto the 1134 ** send queue. 1135 */ 1136 1137 sendtoargv(argv, e) 1138 register char **argv; 1139 register ENVELOPE *e; 1140 { 1141 register char *p; 1142 1143 while ((p = *argv++) != NULL) 1144 { 1145 (void) sendtolist(p, NULLADDR, &e->e_sendqueue, 0, e); 1146 } 1147 } 1148 /* 1149 ** GETCTLADDR -- get controlling address from an address header. 1150 ** 1151 ** If none, get one corresponding to the effective userid. 1152 ** 1153 ** Parameters: 1154 ** a -- the address to find the controller of. 1155 ** 1156 ** Returns: 1157 ** the controlling address. 1158 ** 1159 ** Side Effects: 1160 ** none. 1161 */ 1162 1163 ADDRESS * 1164 getctladdr(a) 1165 register ADDRESS *a; 1166 { 1167 while (a != NULL && !bitset(QGOODUID, a->q_flags)) 1168 a = a->q_alias; 1169 return (a); 1170 } 1171 /* 1172 ** SELF_REFERENCE -- check to see if an address references itself 1173 ** 1174 ** The check is done through a chain of aliases. If it is part of 1175 ** a loop, break the loop at the "best" address, that is, the one 1176 ** that exists as a real user. 1177 ** 1178 ** This is to handle the case of: 1179 ** awc: Andrew.Chang 1180 ** Andrew.Chang: awc@mail.server 1181 ** which is a problem only on mail.server. 1182 ** 1183 ** Parameters: 1184 ** a -- the address to check. 1185 ** e -- the current envelope. 1186 ** 1187 ** Returns: 1188 ** The address that should be retained. 1189 */ 1190 1191 ADDRESS * 1192 self_reference(a, e) 1193 ADDRESS *a; 1194 ENVELOPE *e; 1195 { 1196 ADDRESS *b; /* top entry in self ref loop */ 1197 ADDRESS *c; /* entry that point to a real mail box */ 1198 1199 if (tTd(27, 1)) 1200 printf("self_reference(%s)\n", a->q_paddr); 1201 1202 for (b = a->q_alias; b != NULL; b = b->q_alias) 1203 { 1204 if (sameaddr(a, b)) 1205 break; 1206 } 1207 1208 if (b == NULL) 1209 { 1210 if (tTd(27, 1)) 1211 printf("\t... no self ref\n"); 1212 return NULL; 1213 } 1214 1215 /* 1216 ** Pick the first address that resolved to a real mail box 1217 ** i.e has a pw entry. The returned value will be marked 1218 ** QSELFREF in recipient(), which in turn will disable alias() 1219 ** from marking it QDONTSEND, which mean it will be used 1220 ** as a deliverable address. 1221 ** 1222 ** The 2 key thing to note here are: 1223 ** 1) we are in a recursive call sequence: 1224 ** alias->sentolist->recipient->alias 1225 ** 2) normally, when we return back to alias(), the address 1226 ** will be marked QDONTSEND, since alias() assumes the 1227 ** expanded form will be used instead of the current address. 1228 ** This behaviour is turned off if the address is marked 1229 ** QSELFREF We set QSELFREF when we return to recipient(). 1230 */ 1231 1232 c = a; 1233 while (c != NULL) 1234 { 1235 if (bitnset(M_HASPWENT, c->q_mailer->m_flags)) 1236 { 1237 if (tTd(27, 2)) 1238 printf("\t... getpwnam(%s)... ", c->q_user); 1239 if (sm_getpwnam(c->q_user) != NULL) 1240 { 1241 if (tTd(27, 2)) 1242 printf("found\n"); 1243 1244 /* ought to cache results here */ 1245 return c; 1246 } 1247 if (tTd(27, 2)) 1248 printf("failed\n"); 1249 } 1250 c = c->q_alias; 1251 } 1252 1253 if (tTd(27, 1)) 1254 printf("\t... cannot break loop for \"%s\"\n", a->q_paddr); 1255 1256 return NULL; 1257 } 1258