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