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