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