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