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