1 /* 2 * Copyright (c) 1983 Eric P. Allman 3 * Copyright (c) 1988 Regents of the University of California. 4 * All rights reserved. 5 * 6 * %sccs.include.redist.c% 7 */ 8 9 #ifndef lint 10 static char sccsid[] = "@(#)recipient.c 6.40 (Berkeley) 05/01/93"; 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 40 41 sendtolist(list, ctladdr, sendq, e) 42 char *list; 43 ADDRESS *ctladdr; 44 ADDRESS **sendq; 45 register ENVELOPE *e; 46 { 47 register char *p; 48 register ADDRESS *al; /* list of addresses to send to */ 49 bool firstone; /* set on first address sent */ 50 char delimiter; /* the address delimiter */ 51 int naddrs; 52 53 if (tTd(25, 1)) 54 { 55 printf("sendto: %s\n ctladdr=", list); 56 printaddr(ctladdr, FALSE); 57 } 58 59 /* heuristic to determine old versus new style addresses */ 60 if (ctladdr == NULL && 61 (strchr(list, ',') != NULL || strchr(list, ';') != NULL || 62 strchr(list, '<') != NULL || strchr(list, '(') != NULL)) 63 e->e_flags &= ~EF_OLDSTYLE; 64 delimiter = ' '; 65 if (!bitset(EF_OLDSTYLE, e->e_flags) || ctladdr != NULL) 66 delimiter = ','; 67 68 firstone = TRUE; 69 al = NULL; 70 naddrs = 0; 71 72 for (p = list; *p != '\0'; ) 73 { 74 auto char *delimptr; 75 register ADDRESS *a; 76 77 /* parse the address */ 78 while ((isascii(*p) && isspace(*p)) || *p == ',') 79 p++; 80 a = parseaddr(p, (ADDRESS *) NULL, 1, delimiter, &delimptr, e); 81 p = delimptr; 82 if (a == NULL) 83 continue; 84 a->q_next = al; 85 a->q_alias = ctladdr; 86 87 /* see if this should be marked as a primary address */ 88 if (ctladdr == NULL || 89 (firstone && *p == '\0' && bitset(QPRIMARY, ctladdr->q_flags))) 90 a->q_flags |= QPRIMARY; 91 92 if (ctladdr != NULL && sameaddr(ctladdr, a)) 93 ctladdr->q_flags |= QSELFREF; 94 al = a; 95 firstone = FALSE; 96 } 97 98 /* arrange to send to everyone on the local send list */ 99 while (al != NULL) 100 { 101 register ADDRESS *a = al; 102 extern ADDRESS *recipient(); 103 104 al = a->q_next; 105 a = recipient(a, sendq, e); 106 107 /* arrange to inherit full name */ 108 if (a->q_fullname == NULL && ctladdr != NULL) 109 a->q_fullname = ctladdr->q_fullname; 110 naddrs++; 111 } 112 113 e->e_to = NULL; 114 return (naddrs); 115 } 116 /* 117 ** RECIPIENT -- Designate a message recipient 118 ** 119 ** Saves the named person for future mailing. 120 ** 121 ** Parameters: 122 ** a -- the (preparsed) address header for the recipient. 123 ** sendq -- a pointer to the head of a queue to put the 124 ** recipient in. Duplicate supression is done 125 ** in this queue. 126 ** e -- the current envelope. 127 ** 128 ** Returns: 129 ** The actual address in the queue. This will be "a" if 130 ** the address is not a duplicate, else the original address. 131 ** 132 ** Side Effects: 133 ** none. 134 */ 135 136 extern ADDRESS *getctladdr(); 137 138 ADDRESS * 139 recipient(a, sendq, e) 140 register ADDRESS *a; 141 register ADDRESS **sendq; 142 register ENVELOPE *e; 143 { 144 register ADDRESS *q; 145 ADDRESS **pq; 146 register struct mailer *m; 147 register char *p; 148 bool quoted = FALSE; /* set if the addr has a quote bit */ 149 int findusercount = 0; 150 char buf[MAXNAME]; /* unquoted image of the user name */ 151 extern int safefile(); 152 153 e->e_to = a->q_paddr; 154 m = a->q_mailer; 155 errno = 0; 156 if (tTd(26, 1)) 157 { 158 printf("\nrecipient: "); 159 printaddr(a, FALSE); 160 } 161 162 /* break aliasing loops */ 163 if (AliasLevel > MAXRCRSN) 164 { 165 usrerr("554 aliasing/forwarding loop broken"); 166 return (a); 167 } 168 169 /* 170 ** Finish setting up address structure. 171 */ 172 173 /* set the queue timeout */ 174 a->q_timeout = TimeOuts.to_q_return; 175 176 /* get unquoted user for file, program or user.name check */ 177 (void) strcpy(buf, a->q_user); 178 for (p = buf; *p != '\0' && !quoted; p++) 179 { 180 if (*p == '\\') 181 quoted = TRUE; 182 } 183 stripquotes(buf); 184 185 /* check for direct mailing to restricted mailers */ 186 if (a->q_alias == NULL && m == ProgMailer && 187 !bitset(EF_QUEUERUN, e->e_flags)) 188 { 189 a->q_flags |= QBADADDR; 190 usrerr("550 Cannot mail directly to programs", m->m_name); 191 } 192 193 /* 194 ** Look up this person in the recipient list. 195 ** If they are there already, return, otherwise continue. 196 ** If the list is empty, just add it. Notice the cute 197 ** hack to make from addresses suppress things correctly: 198 ** the QDONTSEND bit will be set in the send list. 199 ** [Please note: the emphasis is on "hack."] 200 */ 201 202 for (pq = sendq; (q = *pq) != NULL; pq = &q->q_next) 203 { 204 if (sameaddr(q, a)) 205 { 206 if (tTd(26, 1)) 207 { 208 printf("%s in sendq: ", a->q_paddr); 209 printaddr(q, FALSE); 210 } 211 if (!bitset(QPRIMARY, q->q_flags)) 212 { 213 if (!bitset(QDONTSEND, a->q_flags)) 214 message("duplicate suppressed"); 215 q->q_flags |= a->q_flags; 216 } 217 return (q); 218 } 219 } 220 221 /* add address on list */ 222 *pq = a; 223 a->q_next = NULL; 224 225 /* 226 ** Alias the name and handle special mailer types. 227 */ 228 229 trylocaluser: 230 if (tTd(29, 7)) 231 printf("at trylocaluser %s\n", a->q_user); 232 233 if (bitset(QDONTSEND|QBADADDR|QVERIFIED, a->q_flags)) 234 return (a); 235 236 if (m == InclMailer) 237 { 238 a->q_flags |= QDONTSEND; 239 if (a->q_alias == NULL && !bitset(EF_QUEUERUN, e->e_flags)) 240 { 241 a->q_flags |= QBADADDR; 242 usrerr("550 Cannot mail directly to :include:s"); 243 } 244 else 245 { 246 int ret; 247 248 message("including file %s", a->q_user); 249 ret = include(a->q_user, FALSE, a, sendq, e); 250 if (transienterror(ret)) 251 { 252 #ifdef LOG 253 if (LogLevel > 2) 254 syslog(LOG_ERR, "%s: include %s: transient error: %e", 255 e->e_id, a->q_user, errstring(ret)); 256 #endif 257 a->q_flags |= QQUEUEUP|QDONTSEND; 258 usrerr("451 Cannot open %s: %s", 259 a->q_user, errstring(ret)); 260 } 261 else if (ret != 0) 262 { 263 usrerr("550 Cannot open %s: %s", 264 a->q_user, errstring(ret)); 265 a->q_flags |= QBADADDR; 266 } 267 } 268 } 269 else if (m == FileMailer) 270 { 271 struct stat stb; 272 extern bool writable(); 273 274 p = strrchr(buf, '/'); 275 /* check if writable or creatable */ 276 if (a->q_alias == NULL && !bitset(EF_QUEUERUN, e->e_flags)) 277 { 278 a->q_flags |= QBADADDR; 279 usrerr("550 Cannot mail directly to files"); 280 } 281 else if ((stat(buf, &stb) >= 0) ? (!writable(&stb)) : 282 (*p = '\0', safefile(buf, getruid(), S_IWRITE|S_IEXEC) != 0)) 283 { 284 a->q_flags |= QBADADDR; 285 giveresponse(EX_CANTCREAT, m, NULL, e); 286 } 287 } 288 289 if (m != LocalMailer) 290 { 291 if (!bitset(QDONTSEND, a->q_flags)) 292 e->e_nrcpts++; 293 return (a); 294 } 295 296 /* try aliasing */ 297 alias(a, sendq, e); 298 299 # ifdef USERDB 300 /* if not aliased, look it up in the user database */ 301 if (!bitset(QDONTSEND|QNOTREMOTE|QVERIFIED, a->q_flags)) 302 { 303 extern int udbexpand(); 304 extern int errno; 305 306 if (udbexpand(a, sendq, e) == EX_TEMPFAIL) 307 { 308 a->q_flags |= QQUEUEUP|QDONTSEND; 309 if (e->e_message == NULL) 310 e->e_message = newstr("Deferred: user database error"); 311 # ifdef LOG 312 if (LogLevel > 8) 313 syslog(LOG_INFO, "%s: deferred: udbexpand: %s", 314 e->e_id, errstring(errno)); 315 # endif 316 message("queued (user database error): %s", 317 errstring(errno)); 318 e->e_nrcpts++; 319 return (a); 320 } 321 } 322 # endif 323 324 /* if it was an alias or a UDB expansion, just return now */ 325 if (bitset(QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags)) 326 return (a); 327 328 /* 329 ** If we have a level two config file, then pass the name through 330 ** Ruleset 5 before sending it off. Ruleset 5 has the right 331 ** to send rewrite it to another mailer. This gives us a hook 332 ** after local aliasing has been done. 333 */ 334 335 if (tTd(29, 5)) 336 { 337 printf("recipient: testing local? cl=%d, rr5=%x\n\t", 338 ConfigLevel, RewriteRules[5]); 339 printaddr(a, FALSE); 340 } 341 if (!bitset(QNOTREMOTE, a->q_flags) && ConfigLevel >= 2 && 342 RewriteRules[5] != NULL) 343 { 344 maplocaluser(a, sendq, e); 345 } 346 347 /* 348 ** If it didn't get rewritten to another mailer, go ahead 349 ** and deliver it. 350 */ 351 352 if (!bitset(QDONTSEND|QQUEUEUP, a->q_flags)) 353 { 354 auto bool fuzzy; 355 register struct passwd *pw; 356 extern struct passwd *finduser(); 357 358 /* warning -- finduser may trash buf */ 359 pw = finduser(buf, &fuzzy); 360 if (pw == NULL) 361 { 362 a->q_flags |= QBADADDR; 363 giveresponse(EX_NOUSER, m, NULL, e); 364 } 365 else 366 { 367 char nbuf[MAXNAME]; 368 369 if (fuzzy) 370 { 371 /* name was a fuzzy match */ 372 a->q_user = newstr(pw->pw_name); 373 if (findusercount++ > 3) 374 { 375 a->q_flags |= QBADADDR; 376 usrerr("554 aliasing/forwarding loop for %s broken", 377 pw->pw_name); 378 return (a); 379 } 380 381 /* see if it aliases */ 382 (void) strcpy(buf, pw->pw_name); 383 goto trylocaluser; 384 } 385 a->q_home = newstr(pw->pw_dir); 386 a->q_uid = pw->pw_uid; 387 a->q_gid = pw->pw_gid; 388 a->q_ruser = newstr(pw->pw_name); 389 a->q_flags |= QGOODUID; 390 buildfname(pw->pw_gecos, pw->pw_name, nbuf); 391 if (nbuf[0] != '\0') 392 a->q_fullname = newstr(nbuf); 393 if (!quoted) 394 forward(a, sendq, e); 395 } 396 } 397 if (!bitset(QDONTSEND, a->q_flags)) 398 e->e_nrcpts++; 399 return (a); 400 } 401 /* 402 ** FINDUSER -- find the password entry for a user. 403 ** 404 ** This looks a lot like getpwnam, except that it may want to 405 ** do some fancier pattern matching in /etc/passwd. 406 ** 407 ** This routine contains most of the time of many sendmail runs. 408 ** It deserves to be optimized. 409 ** 410 ** Parameters: 411 ** name -- the name to match against. 412 ** fuzzyp -- an outarg that is set to TRUE if this entry 413 ** was found using the fuzzy matching algorithm; 414 ** set to FALSE otherwise. 415 ** 416 ** Returns: 417 ** A pointer to a pw struct. 418 ** NULL if name is unknown or ambiguous. 419 ** 420 ** Side Effects: 421 ** may modify name. 422 */ 423 424 struct passwd * 425 finduser(name, fuzzyp) 426 char *name; 427 bool *fuzzyp; 428 { 429 register struct passwd *pw; 430 register char *p; 431 extern struct passwd *getpwent(); 432 extern struct passwd *getpwnam(); 433 434 if (tTd(29, 4)) 435 printf("finduser(%s): ", name); 436 437 *fuzzyp = FALSE; 438 439 /* look up this login name using fast path */ 440 if ((pw = getpwnam(name)) != NULL) 441 { 442 if (tTd(29, 4)) 443 printf("found (non-fuzzy)\n"); 444 return (pw); 445 } 446 447 #ifdef MATCHGECOS 448 /* see if fuzzy matching allowed */ 449 if (!MatchGecos) 450 { 451 if (tTd(29, 4)) 452 printf("not found (fuzzy disabled)\n"); 453 return NULL; 454 } 455 456 /* search for a matching full name instead */ 457 for (p = name; *p != '\0'; p++) 458 { 459 if (*p == (SpaceSub & 0177) || *p == '_') 460 *p = ' '; 461 } 462 (void) setpwent(); 463 while ((pw = getpwent()) != NULL) 464 { 465 char buf[MAXNAME]; 466 467 buildfname(pw->pw_gecos, pw->pw_name, buf); 468 if (strchr(buf, ' ') != NULL && !strcasecmp(buf, name)) 469 { 470 if (tTd(29, 4)) 471 printf("fuzzy matches %s\n", pw->pw_name); 472 message("sending to login name %s", pw->pw_name); 473 *fuzzyp = TRUE; 474 return (pw); 475 } 476 } 477 if (tTd(29, 4)) 478 printf("no fuzzy match found\n"); 479 #else 480 if (tTd(29, 4)) 481 printf("not found (fuzzy disabled)\n"); 482 #endif 483 return (NULL); 484 } 485 /* 486 ** WRITABLE -- predicate returning if the file is writable. 487 ** 488 ** This routine must duplicate the algorithm in sys/fio.c. 489 ** Unfortunately, we cannot use the access call since we 490 ** won't necessarily be the real uid when we try to 491 ** actually open the file. 492 ** 493 ** Notice that ANY file with ANY execute bit is automatically 494 ** not writable. This is also enforced by mailfile. 495 ** 496 ** Parameters: 497 ** s -- pointer to a stat struct for the file. 498 ** 499 ** Returns: 500 ** TRUE -- if we will be able to write this file. 501 ** FALSE -- if we cannot write this file. 502 ** 503 ** Side Effects: 504 ** none. 505 */ 506 507 bool 508 writable(s) 509 register struct stat *s; 510 { 511 uid_t euid; 512 gid_t egid; 513 int bits; 514 515 if (bitset(0111, s->st_mode)) 516 return (FALSE); 517 euid = getruid(); 518 egid = getrgid(); 519 if (geteuid() == 0) 520 { 521 if (bitset(S_ISUID, s->st_mode)) 522 euid = s->st_uid; 523 if (bitset(S_ISGID, s->st_mode)) 524 egid = s->st_gid; 525 } 526 527 if (euid == 0) 528 return (TRUE); 529 bits = S_IWRITE; 530 if (euid != s->st_uid) 531 { 532 bits >>= 3; 533 if (egid != s->st_gid) 534 bits >>= 3; 535 } 536 return ((s->st_mode & bits) != 0); 537 } 538 /* 539 ** INCLUDE -- handle :include: specification. 540 ** 541 ** Parameters: 542 ** fname -- filename to include. 543 ** forwarding -- if TRUE, we are reading a .forward file. 544 ** if FALSE, it's a :include: file. 545 ** ctladdr -- address template to use to fill in these 546 ** addresses -- effective user/group id are 547 ** the important things. 548 ** sendq -- a pointer to the head of the send queue 549 ** to put these addresses in. 550 ** 551 ** Returns: 552 ** open error status 553 ** 554 ** Side Effects: 555 ** reads the :include: file and sends to everyone 556 ** listed in that file. 557 */ 558 559 static jmp_buf CtxIncludeTimeout; 560 561 int 562 include(fname, forwarding, ctladdr, sendq, e) 563 char *fname; 564 bool forwarding; 565 ADDRESS *ctladdr; 566 ADDRESS **sendq; 567 ENVELOPE *e; 568 { 569 register FILE *fp; 570 char *oldto = e->e_to; 571 char *oldfilename = FileName; 572 int oldlinenumber = LineNumber; 573 register EVENT *ev = NULL; 574 int nincludes; 575 int ret; 576 char buf[MAXLINE]; 577 static int includetimeout(); 578 579 if (tTd(27, 2)) 580 printf("include(%s)\n", fname); 581 582 /* 583 ** If home directory is remote mounted but server is down, 584 ** this can hang or give errors; use a timeout to avoid this 585 */ 586 587 if (setjmp(CtxIncludeTimeout) != 0) 588 { 589 ctladdr->q_flags |= QQUEUEUP|QDONTSEND; 590 errno = 0; 591 usrerr("451 open timeout on %s", fname); 592 return ETIMEDOUT; 593 } 594 ev = setevent((time_t) 60, includetimeout, 0); 595 596 /* if forwarding, the input file must be marked safe */ 597 if (forwarding && (ret = safefile(fname, ctladdr->q_uid, S_IREAD)) != 0) 598 { 599 /* don't use this .forward file */ 600 clrevent(ev); 601 if (tTd(27, 4)) 602 printf("include: not safe (uid=%d): %s\n", 603 ctladdr->q_uid, errstring(ret)); 604 return ret; 605 } 606 607 fp = fopen(fname, "r"); 608 if (fp == NULL) 609 { 610 int ret = errno; 611 612 clrevent(ev); 613 return ret; 614 } 615 616 if (getctladdr(ctladdr) == NULL) 617 { 618 struct stat st; 619 620 if (fstat(fileno(fp), &st) < 0) 621 { 622 int ret = errno; 623 624 clrevent(ev); 625 syserr("Cannot fstat %s!", fname); 626 return ret; 627 } 628 ctladdr->q_uid = st.st_uid; 629 ctladdr->q_gid = st.st_gid; 630 ctladdr->q_flags |= QGOODUID; 631 } 632 633 clrevent(ev); 634 635 if (bitset(EF_VRFYONLY, e->e_flags)) 636 { 637 /* don't do any more now */ 638 ctladdr->q_flags |= QVERIFIED; 639 e->e_nrcpts++; 640 xfclose(fp, "include", fname); 641 return 0; 642 } 643 644 /* read the file -- each line is a comma-separated list. */ 645 FileName = fname; 646 LineNumber = 0; 647 ctladdr->q_flags &= ~QSELFREF; 648 nincludes = 0; 649 while (fgets(buf, sizeof buf, fp) != NULL) 650 { 651 register char *p = strchr(buf, '\n'); 652 653 LineNumber++; 654 if (p != NULL) 655 *p = '\0'; 656 if (buf[0] == '#' || buf[0] == '\0') 657 continue; 658 e->e_to = NULL; 659 message("%s to %s", 660 forwarding ? "forwarding" : "sending", buf); 661 #ifdef LOG 662 if (forwarding && LogLevel > 9) 663 syslog(LOG_INFO, "%s: forward %s => %s", 664 e->e_id, oldto, buf); 665 #endif 666 667 AliasLevel++; 668 nincludes += sendtolist(buf, ctladdr, sendq, e); 669 AliasLevel--; 670 } 671 if (nincludes > 0 && !bitset(QSELFREF, ctladdr->q_flags)) 672 { 673 if (tTd(27, 5)) 674 { 675 printf("include: QDONTSEND "); 676 printaddr(ctladdr, FALSE); 677 } 678 ctladdr->q_flags |= QDONTSEND; 679 } 680 681 (void) xfclose(fp, "include", fname); 682 FileName = oldfilename; 683 LineNumber = oldlinenumber; 684 return 0; 685 } 686 687 static 688 includetimeout() 689 { 690 longjmp(CtxIncludeTimeout, 1); 691 } 692 /* 693 ** SENDTOARGV -- send to an argument vector. 694 ** 695 ** Parameters: 696 ** argv -- argument vector to send to. 697 ** e -- the current envelope. 698 ** 699 ** Returns: 700 ** none. 701 ** 702 ** Side Effects: 703 ** puts all addresses on the argument vector onto the 704 ** send queue. 705 */ 706 707 sendtoargv(argv, e) 708 register char **argv; 709 register ENVELOPE *e; 710 { 711 register char *p; 712 713 while ((p = *argv++) != NULL) 714 { 715 (void) sendtolist(p, (ADDRESS *) NULL, &e->e_sendqueue, e); 716 } 717 } 718 /* 719 ** GETCTLADDR -- get controlling address from an address header. 720 ** 721 ** If none, get one corresponding to the effective userid. 722 ** 723 ** Parameters: 724 ** a -- the address to find the controller of. 725 ** 726 ** Returns: 727 ** the controlling address. 728 ** 729 ** Side Effects: 730 ** none. 731 */ 732 733 ADDRESS * 734 getctladdr(a) 735 register ADDRESS *a; 736 { 737 while (a != NULL && !bitset(QGOODUID, a->q_flags)) 738 a = a->q_alias; 739 return (a); 740 } 741