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