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