1 /* 2 * Copyright (c) 1998-2003 Proofpoint, Inc. and its suppliers. 3 * All rights reserved. 4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5 * Copyright (c) 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * By using this file, you agree to the terms and conditions set 9 * forth in the LICENSE file which can be found at the top level of 10 * the sendmail distribution. 11 * 12 */ 13 14 #include <sendmail.h> 15 16 SM_RCSID("@(#)$Id: alias.c,v 8.221 2013-11-22 20:51:54 ca Exp $") 17 18 #include <sm/sendmail.h> 19 20 #define SEPARATOR ':' 21 # define ALIAS_SPEC_SEPARATORS " ,/:" 22 23 static MAP *AliasFileMap = NULL; /* the actual aliases.files map */ 24 static int NAliasFileMaps; /* the number of entries in AliasFileMap */ 25 26 static char *aliaslookup __P((char *, int *, char *)); 27 28 /* 29 ** ALIAS -- Compute aliases. 30 ** 31 ** Scans the alias file for an alias for the given address. 32 ** If found, it arranges to deliver to the alias list instead. 33 ** Uses libdbm database if -DDBM. 34 ** 35 ** Parameters: 36 ** a -- address to alias. 37 ** sendq -- a pointer to the head of the send queue 38 ** to put the aliases in. 39 ** aliaslevel -- the current alias nesting depth. 40 ** e -- the current envelope. 41 ** 42 ** Returns: 43 ** none 44 ** 45 ** Side Effects: 46 ** Aliases found are expanded. 47 ** 48 ** Deficiencies: 49 ** It should complain about names that are aliased to 50 ** nothing. 51 */ 52 53 void 54 alias(a, sendq, aliaslevel, e) 55 register ADDRESS *a; 56 ADDRESS **sendq; 57 int aliaslevel; 58 register ENVELOPE *e; 59 { 60 register char *p; 61 char *owner; 62 auto int status = EX_OK; 63 char obuf[MAXNAME_I + 7]; 64 65 if (tTd(27, 1)) 66 sm_dprintf("alias(%s)\n", a->q_user); 67 68 /* don't realias already aliased names */ 69 if (!QS_IS_OK(a->q_state)) 70 return; 71 72 if (NoAlias) 73 return; 74 75 e->e_to = a->q_paddr; 76 77 /* 78 ** Look up this name. 79 ** 80 ** If the map was unavailable, we will queue this message 81 ** until the map becomes available; otherwise, we could 82 ** bounce messages inappropriately. 83 */ 84 85 #if _FFR_REDIRECTEMPTY 86 /* 87 ** envelope <> can't be sent to mailing lists, only owner- 88 ** send spam of this type to owner- of the list 89 ** ---- to stop spam from going to mailing lists! 90 */ 91 92 if (e->e_sender != NULL && *e->e_sender == '\0') 93 { 94 /* Look for owner of alias */ 95 (void) sm_strlcpyn(obuf, sizeof(obuf), 2, "owner-", a->q_user); 96 if (aliaslookup(obuf, &status, a->q_host) != NULL) 97 { 98 if (LogLevel > 8) 99 sm_syslog(LOG_WARNING, e->e_id, 100 "possible spam from <> to list: %s, redirected to %s\n", 101 a->q_user, obuf); 102 a->q_user = sm_rpool_strdup_x(e->e_rpool, obuf); 103 } 104 } 105 #endif /* _FFR_REDIRECTEMPTY */ 106 107 p = aliaslookup(a->q_user, &status, a->q_host); 108 if (status == EX_TEMPFAIL || status == EX_UNAVAILABLE) 109 { 110 a->q_state = QS_QUEUEUP; 111 if (e->e_message == NULL) 112 e->e_message = sm_rpool_strdup_x(e->e_rpool, 113 "alias database unavailable"); 114 115 /* XXX msg only per recipient? */ 116 if (a->q_message == NULL) 117 a->q_message = "alias database unavailable"; 118 return; 119 } 120 if (p == NULL) 121 return; 122 123 /* 124 ** Match on Alias. 125 ** Deliver to the target list. 126 */ 127 128 if (tTd(27, 1)) 129 sm_dprintf("%s (%s, %s) aliased to %s\n", 130 a->q_paddr, a->q_host, a->q_user, p); 131 if (bitset(EF_VRFYONLY, e->e_flags)) 132 { 133 a->q_state = QS_VERIFIED; 134 return; 135 } 136 message("aliased to %s", shortenstring(p, MAXSHORTSTR)); 137 if (LogLevel > 10) 138 sm_syslog(LOG_INFO, e->e_id, 139 "alias %.100s => %s", 140 a->q_paddr, shortenstring(p, MAXSHORTSTR)); 141 a->q_flags &= ~QSELFREF; 142 if (tTd(27, 5)) 143 { 144 sm_dprintf("alias: QS_EXPANDED "); 145 printaddr(sm_debug_file(), a, false); 146 } 147 a->q_state = QS_EXPANDED; 148 149 /* 150 ** Always deliver aliased items as the default user. 151 ** Setting q_gid to 0 forces deliver() to use DefUser 152 ** instead of the alias name for the call to initgroups(). 153 */ 154 155 a->q_uid = DefUid; 156 a->q_gid = 0; 157 a->q_fullname = NULL; 158 a->q_flags |= QGOODUID|QALIAS; 159 160 (void) sendtolist(p, a, sendq, aliaslevel + 1, e); 161 162 if (bitset(QSELFREF, a->q_flags) && QS_IS_EXPANDED(a->q_state)) 163 a->q_state = QS_OK; 164 165 /* 166 ** Look for owner of alias 167 */ 168 169 if (strncmp(a->q_user, "owner-", 6) == 0 || 170 strlen(a->q_user) > sizeof(obuf) - 7) 171 (void) sm_strlcpy(obuf, "owner-owner", sizeof(obuf)); 172 else 173 (void) sm_strlcpyn(obuf, sizeof(obuf), 2, "owner-", a->q_user); 174 owner = aliaslookup(obuf, &status, a->q_host); 175 if (owner == NULL) 176 return; 177 178 /* reflect owner into envelope sender */ 179 if (strpbrk(owner, ",:/|\"") != NULL) 180 owner = obuf; 181 a->q_owner = sm_rpool_strdup_x(e->e_rpool, owner); 182 183 /* announce delivery to this alias; NORECEIPT bit set later */ 184 if (e->e_xfp != NULL) 185 (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, 186 "Message delivered to mailing list %s\n", 187 a->q_paddr); 188 e->e_flags |= EF_SENDRECEIPT; 189 a->q_flags |= QDELIVERED|QEXPANDED; 190 } 191 192 /* 193 ** ALIASLOOKUP -- look up a name in the alias file. 194 ** 195 ** Parameters: 196 ** name -- the name to look up [i] 197 ** pstat -- a pointer to a place to put the status. 198 ** av -- argument for %1 expansion. 199 ** 200 ** Returns: 201 ** the value of name. 202 ** NULL if unknown. 203 ** 204 ** Warnings: 205 ** The return value will be trashed across calls. 206 */ 207 208 static char * 209 aliaslookup(name, pstat, av) 210 char *name; 211 int *pstat; 212 char *av; 213 { 214 static MAP *map = NULL; 215 char *res; 216 #if _FFR_ALIAS_DETAIL 217 int i; 218 char *argv[4]; 219 #else 220 # define argv NULL 221 #endif 222 #if _FFR_8BITENVADDR 223 char buf[MAXNAME]; /* EAI:ok */ 224 #endif 225 226 if (map == NULL) 227 { 228 STAB *s = stab("aliases", ST_MAP, ST_FIND); 229 230 if (s == NULL) 231 return NULL; 232 map = &s->s_map; 233 } 234 DYNOPENMAP(map); 235 236 /* special case POstMastER -- always use lower case */ 237 if (SM_STRCASEEQ(name, "postmaster")) 238 name = "postmaster"; 239 #if _FFR_8BITENVADDR 240 (void) dequote_internal_chars(name, buf, sizeof(buf)); 241 /* check length? */ 242 name = buf; 243 #endif /* _FFR_8BITENVADDR */ 244 245 #if _FFR_ALIAS_DETAIL 246 i = 0; 247 argv[i++] = name; 248 argv[i++] = av; 249 250 /* XXX '+' is hardwired here as delimiter! */ 251 if (av != NULL && *av == '+') 252 argv[i++] = av + 1; 253 argv[i++] = NULL; 254 #endif /* _FFR_ALIAS_DETAIL */ 255 res = (*map->map_class->map_lookup)(map, name, argv, pstat); 256 #if _FFR_8BITENVADDR 257 /* map_lookup() does a map_rewrite(), so no quoting here */ 258 #endif 259 return res; 260 } 261 262 /* 263 ** SETALIAS -- set up an alias map 264 ** 265 ** Called when reading configuration file. 266 ** 267 ** Parameters: 268 ** spec -- the alias specification 269 ** 270 ** Returns: 271 ** none. 272 */ 273 274 void 275 setalias(spec) 276 char *spec; 277 { 278 register char *p; 279 register MAP *map; 280 char *class; 281 STAB *s; 282 283 if (tTd(27, 8)) 284 sm_dprintf("setalias(%s)\n", spec); 285 286 for (p = spec; p != NULL; ) 287 { 288 char buf[50]; 289 290 while (SM_ISSPACE(*p)) 291 p++; 292 if (*p == '\0') 293 break; 294 spec = p; 295 296 if (NAliasFileMaps >= MAXMAPSTACK) 297 { 298 syserr("Too many alias databases defined, %d max", 299 MAXMAPSTACK); 300 return; 301 } 302 if (AliasFileMap == NULL) 303 { 304 (void) sm_strlcpy(buf, "aliases.files sequence", 305 sizeof(buf)); 306 AliasFileMap = makemapentry(buf); 307 if (AliasFileMap == NULL) 308 { 309 syserr("setalias: cannot create aliases.files map"); 310 return; 311 } 312 } 313 (void) sm_snprintf(buf, sizeof(buf), "Alias%d", NAliasFileMaps); 314 s = stab(buf, ST_MAP, ST_ENTER); 315 map = &s->s_map; 316 memset(map, '\0', sizeof(*map)); 317 map->map_mname = s->s_name; 318 p = strpbrk(p, ALIAS_SPEC_SEPARATORS); 319 if (p != NULL && *p == SEPARATOR) 320 { 321 /* map name */ 322 *p++ = '\0'; 323 class = spec; 324 spec = p; 325 } 326 else 327 { 328 class = "implicit"; 329 map->map_mflags = MF_INCLNULL; 330 } 331 332 /* find end of spec */ 333 if (p != NULL) 334 { 335 bool quoted = false; 336 337 for (; *p != '\0'; p++) 338 { 339 /* 340 ** Don't break into a quoted string. 341 ** Needed for ldap maps which use 342 ** commas in their specifications. 343 */ 344 345 if (*p == '"') 346 quoted = !quoted; 347 else if (*p == ',' && !quoted) 348 break; 349 } 350 351 /* No more alias specifications follow */ 352 if (*p == '\0') 353 p = NULL; 354 } 355 if (p != NULL) 356 *p++ = '\0'; 357 358 if (tTd(27, 20)) 359 sm_dprintf(" map %s:%s %s\n", class, s->s_name, spec); 360 361 /* look up class */ 362 s = stab(class, ST_MAPCLASS, ST_FIND); 363 if (s == NULL) 364 { 365 syserr("setalias: unknown alias class %s", class); 366 } 367 else if (!bitset(MCF_ALIASOK, s->s_mapclass.map_cflags)) 368 { 369 syserr("setalias: map class %s can't handle aliases", 370 class); 371 } 372 else 373 { 374 map->map_class = &s->s_mapclass; 375 map->map_mflags |= MF_ALIAS; 376 if (map->map_class->map_parse(map, spec)) 377 { 378 map->map_mflags |= MF_VALID; 379 AliasFileMap->map_stack[NAliasFileMaps++] = map; 380 } 381 } 382 } 383 } 384 /* 385 ** ALIASWAIT -- wait for distinguished @:@ token to appear. 386 ** 387 ** This can decide to reopen or rebuild the alias file 388 ** 389 ** Parameters: 390 ** map -- a pointer to the map descriptor for this alias file. 391 ** ext -- the filename extension (e.g., ".db") for the 392 ** database file. 393 ** isopen -- if set, the database is already open, and we 394 ** should check for validity; otherwise, we are 395 ** just checking to see if it should be created. 396 ** 397 ** Returns: 398 ** true -- if the database is open when we return. 399 ** false -- if the database is closed when we return. 400 */ 401 402 bool 403 aliaswait(map, ext, isopen) 404 MAP *map; 405 char *ext; 406 bool isopen; 407 { 408 bool attimeout = false; 409 time_t mtime; 410 struct stat stb; 411 char buf[MAXPATHLEN]; 412 413 if (tTd(27, 3)) 414 sm_dprintf("aliaswait(%s:%s)\n", 415 map->map_class->map_cname, map->map_file); 416 if (bitset(MF_ALIASWAIT, map->map_mflags)) 417 return isopen; 418 map->map_mflags |= MF_ALIASWAIT; 419 420 if (SafeAlias > 0) 421 { 422 auto int st; 423 unsigned int sleeptime = 2; 424 unsigned int loopcount = 0; /* only used for debugging */ 425 time_t toolong = curtime() + SafeAlias; 426 427 while (isopen && 428 map->map_class->map_lookup(map, "@", NULL, &st) == NULL) 429 { 430 if (curtime() > toolong) 431 { 432 /* we timed out */ 433 attimeout = true; 434 break; 435 } 436 437 /* 438 ** Close and re-open the alias database in case 439 ** the one is mv'ed instead of cp'ed in. 440 */ 441 442 if (tTd(27, 2)) 443 { 444 loopcount++; 445 sm_dprintf("aliaswait: sleeping for %u seconds (loopcount = %u)\n", 446 sleeptime, loopcount); 447 } 448 449 map->map_mflags |= MF_CLOSING; 450 map->map_class->map_close(map); 451 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING); 452 (void) sleep(sleeptime); 453 sleeptime *= 2; 454 if (sleeptime > 60) 455 sleeptime = 60; 456 isopen = map->map_class->map_open(map, O_RDONLY); 457 } 458 } 459 460 /* see if we need to go into auto-rebuild mode */ 461 if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags)) 462 { 463 if (tTd(27, 3)) 464 sm_dprintf("aliaswait: not rebuildable\n"); 465 map->map_mflags &= ~MF_ALIASWAIT; 466 return isopen; 467 } 468 if (stat(map->map_file, &stb) < 0) 469 { 470 if (tTd(27, 3)) 471 sm_dprintf("aliaswait: no source file\n"); 472 map->map_mflags &= ~MF_ALIASWAIT; 473 return isopen; 474 } 475 mtime = stb.st_mtime; 476 if (sm_strlcpyn(buf, sizeof(buf), 2, 477 map->map_file, ext == NULL ? "" : ext) >= sizeof(buf)) 478 { 479 if (LogLevel > 3) 480 sm_syslog(LOG_INFO, NOQID, 481 "alias database %s%s name too long", 482 map->map_file, ext == NULL ? "" : ext); 483 message("alias database %s%s name too long", 484 map->map_file, ext == NULL ? "" : ext); 485 } 486 487 if (stat(buf, &stb) < 0 || stb.st_mtime < mtime || attimeout) 488 { 489 if (LogLevel > 3) 490 sm_syslog(LOG_INFO, NOQID, 491 "alias database %s out of date", buf); 492 message("Warning: alias database %s out of date", buf); 493 } 494 map->map_mflags &= ~MF_ALIASWAIT; 495 return isopen; 496 } 497 /* 498 ** REBUILDALIASES -- rebuild the alias database. 499 ** 500 ** Parameters: 501 ** map -- the database to rebuild. 502 ** automatic -- set if this was automatically generated. 503 ** 504 ** Returns: 505 ** true if successful; false otherwise. 506 ** 507 ** Side Effects: 508 ** Reads the text version of the database, builds the 509 ** DBM or DB version. 510 */ 511 512 bool 513 rebuildaliases(map, automatic) 514 register MAP *map; 515 bool automatic; 516 { 517 SM_FILE_T *af; 518 bool nolock = false; 519 bool success = false; 520 long sff = SFF_OPENASROOT|SFF_REGONLY|SFF_NOLOCK; 521 sigfunc_t oldsigint, oldsigquit; 522 #ifdef SIGTSTP 523 sigfunc_t oldsigtstp; 524 #endif 525 526 if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags)) 527 return false; 528 529 if (!bitnset(DBS_LINKEDALIASFILEINWRITABLEDIR, DontBlameSendmail)) 530 sff |= SFF_NOWLINK; 531 if (!bitnset(DBS_GROUPWRITABLEALIASFILE, DontBlameSendmail)) 532 sff |= SFF_NOGWFILES; 533 if (!bitnset(DBS_WORLDWRITABLEALIASFILE, DontBlameSendmail)) 534 sff |= SFF_NOWWFILES; 535 536 /* try to lock the source file */ 537 if ((af = safefopen(map->map_file, O_RDWR, 0, sff)) == NULL) 538 { 539 struct stat stb; 540 541 if ((errno != EACCES && errno != EROFS) || automatic || 542 (af = safefopen(map->map_file, O_RDONLY, 0, sff)) == NULL) 543 { 544 int saveerr = errno; 545 546 if (tTd(27, 1)) 547 sm_dprintf("Can't open %s: %s\n", 548 map->map_file, sm_errstring(saveerr)); 549 if (!automatic && !bitset(MF_OPTIONAL, map->map_mflags)) 550 message("newaliases: cannot open %s: %s", 551 map->map_file, sm_errstring(saveerr)); 552 errno = 0; 553 return false; 554 } 555 nolock = true; 556 if (tTd(27, 1) || 557 fstat(sm_io_getinfo(af, SM_IO_WHAT_FD, NULL), &stb) < 0 || 558 bitset(S_IWUSR|S_IWGRP|S_IWOTH, stb.st_mode)) 559 message("warning: cannot lock %s: %s", 560 map->map_file, sm_errstring(errno)); 561 } 562 563 /* see if someone else is rebuilding the alias file */ 564 if (!nolock && 565 !lockfile(sm_io_getinfo(af, SM_IO_WHAT_FD, NULL), map->map_file, 566 NULL, LOCK_EX|LOCK_NB)) 567 { 568 /* yes, they are -- wait until done */ 569 message("Alias file %s is locked (maybe being rebuilt)", 570 map->map_file); 571 if (OpMode != MD_INITALIAS) 572 { 573 /* wait for other rebuild to complete */ 574 (void) lockfile(sm_io_getinfo(af, SM_IO_WHAT_FD, NULL), 575 map->map_file, NULL, LOCK_EX); 576 } 577 (void) sm_io_close(af, SM_TIME_DEFAULT); 578 errno = 0; 579 return false; 580 } 581 582 oldsigint = sm_signal(SIGINT, SIG_IGN); 583 oldsigquit = sm_signal(SIGQUIT, SIG_IGN); 584 #ifdef SIGTSTP 585 oldsigtstp = sm_signal(SIGTSTP, SIG_IGN); 586 #endif 587 588 if (map->map_class->map_open(map, O_RDWR)) 589 { 590 if (LogLevel > 7) 591 { 592 sm_syslog(LOG_NOTICE, NOQID, 593 "alias database %s %srebuilt by %s", 594 map->map_file, automatic ? "auto" : "", 595 username()); 596 } 597 map->map_mflags |= MF_OPEN|MF_WRITABLE; 598 map->map_pid = CurrentPid; 599 readaliases(map, af, !automatic, true); 600 success = true; 601 } 602 else 603 { 604 if (tTd(27, 1)) 605 sm_dprintf("Can't create database for %s: %s\n", 606 map->map_file, sm_errstring(errno)); 607 if (!automatic) 608 syserr("Cannot create database for alias file %s", 609 map->map_file); 610 } 611 612 /* close the file, thus releasing locks */ 613 (void) sm_io_close(af, SM_TIME_DEFAULT); 614 615 /* add distinguished entries and close the database */ 616 if (bitset(MF_OPEN, map->map_mflags)) 617 { 618 #if _FFR_TESTS 619 if (tTd(78, 101)) 620 { 621 int sl; 622 623 sl = tTdlevel(78) - 100; 624 sm_dprintf("rebuildaliases: sleep=%d\n", sl); 625 sleep(sl); 626 } 627 #endif 628 map->map_mflags |= MF_CLOSING; 629 map->map_class->map_close(map); 630 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING); 631 } 632 633 /* restore the old signals */ 634 (void) sm_signal(SIGINT, oldsigint); 635 (void) sm_signal(SIGQUIT, oldsigquit); 636 #ifdef SIGTSTP 637 (void) sm_signal(SIGTSTP, oldsigtstp); 638 #endif 639 return success; 640 } 641 /* 642 ** READALIASES -- read and process the alias file. 643 ** 644 ** This routine implements the part of initaliases that occurs 645 ** when we are not going to use the DBM stuff. 646 ** 647 ** Parameters: 648 ** map -- the alias database descriptor. 649 ** af -- file to read the aliases from. 650 ** announcestats -- announce statistics regarding number of 651 ** aliases, longest alias, etc. 652 ** logstats -- lot the same info. 653 ** 654 ** Returns: 655 ** none. 656 ** 657 ** Side Effects: 658 ** Reads aliasfile into the symbol table. 659 ** Optionally, builds the .dir & .pag files. 660 */ 661 662 void 663 readaliases(map, af, announcestats, logstats) 664 register MAP *map; 665 SM_FILE_T *af; 666 bool announcestats; 667 bool logstats; 668 { 669 register char *p; 670 char *rhs; 671 bool skipping; 672 long naliases, bytes, longest; 673 ADDRESS al, bl; 674 char lbuf[BUFSIZ]; 675 char *line; 676 #if _FFR_8BITENVADDR 677 char lhsbuf[MAXNAME]; /* EAI:ok */ 678 char rhsbuf[BUFSIZ]; 679 int len; 680 #endif 681 682 /* 683 ** Read and interpret lines 684 */ 685 686 FileName = map->map_file; 687 LineNumber = 0; 688 naliases = bytes = longest = 0; 689 skipping = false; 690 line = NULL; 691 while (sm_io_fgets(af, SM_TIME_DEFAULT, lbuf, sizeof(lbuf)) >= 0) 692 { 693 int lhssize, rhssize; 694 int c; 695 696 LineNumber++; 697 #if _FFR_8BITENVADDR 698 if (line != lbuf) 699 SM_FREE(line); 700 len = 0; 701 line = quote_internal_chars(lbuf, NULL, &len, NULL); 702 #else 703 line = lbuf; 704 #endif 705 p = strchr(line, '\n'); 706 707 /* XXX what if line="a\\" ? */ 708 while (p != NULL && p > line && p[-1] == '\\') 709 { 710 p--; 711 if (sm_io_fgets(af, SM_TIME_DEFAULT, p, 712 SPACELEFT(line, p)) < 0) 713 break; 714 LineNumber++; 715 p = strchr(p, '\n'); 716 } 717 if (p != NULL) 718 *p = '\0'; 719 else if (!sm_io_eof(af)) 720 { 721 errno = 0; 722 syserr("554 5.3.0 alias line too long"); 723 724 /* flush to end of line */ 725 while ((c = sm_io_getc(af, SM_TIME_DEFAULT)) != 726 SM_IO_EOF && c != '\n') 727 continue; 728 729 /* skip any continuation lines */ 730 skipping = true; 731 continue; 732 } 733 switch (line[0]) 734 { 735 case '#': 736 case '\0': 737 skipping = false; 738 continue; 739 740 case ' ': 741 case '\t': 742 if (!skipping) 743 syserr("554 5.3.5 Non-continuation line starts with space"); 744 skipping = true; 745 continue; 746 } 747 skipping = false; 748 749 /* 750 ** Process the LHS 751 ** Find the colon separator, and parse the address. 752 ** It should resolve to a local name -- this will 753 ** be checked later (we want to optionally do 754 ** parsing of the RHS first to maximize error 755 ** detection). 756 */ 757 758 for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++) 759 continue; 760 if (*p++ != ':') 761 { 762 syserr("554 5.3.5 missing colon"); 763 continue; 764 } 765 /* XXX line must be [i] */ 766 if (parseaddr(line, &al, RF_COPYALL, ':', NULL, CurEnv, true) 767 == NULL) 768 { 769 syserr("554 5.3.5 %.40s... illegal alias name", line); 770 continue; 771 } 772 773 /* 774 ** Process the RHS. 775 ** 'al' is the internal form of the LHS address. 776 ** 'p' points to the text of the RHS. 777 */ 778 779 while (SM_ISSPACE(*p)) 780 p++; 781 rhs = p; 782 for (;;) 783 { 784 register char *nlp; 785 786 nlp = &p[strlen(p)]; 787 if (nlp > p && nlp[-1] == '\n') 788 *--nlp = '\0'; 789 790 if (CheckAliases) 791 { 792 /* do parsing & compression of addresses */ 793 while (*p != '\0') 794 { 795 auto char *delimptr; 796 797 while ((SM_ISSPACE(*p)) || *p == ',') 798 p++; 799 if (*p == '\0') 800 break; 801 /* XXX p must be [i] */ 802 if (parseaddr(p, &bl, RF_COPYNONE, ',', 803 &delimptr, CurEnv, true) 804 == NULL) 805 usrerr("553 5.3.5 %s... bad address", p); 806 p = delimptr; 807 } 808 } 809 else 810 { 811 p = nlp; 812 } 813 814 /* see if there should be a continuation line */ 815 c = sm_io_getc(af, SM_TIME_DEFAULT); 816 if (!sm_io_eof(af)) 817 (void) sm_io_ungetc(af, SM_TIME_DEFAULT, c); 818 if (c != ' ' && c != '\t') 819 break; 820 821 /* read continuation line */ 822 if (sm_io_fgets(af, SM_TIME_DEFAULT, p, 823 sizeof(line) - (p-line)) < 0) 824 break; 825 LineNumber++; 826 827 /* check for line overflow */ 828 if (strchr(p, '\n') == NULL && !sm_io_eof(af)) 829 { 830 usrerr("554 5.3.5 alias too long"); 831 while ((c = sm_io_getc(af, SM_TIME_DEFAULT)) 832 != SM_IO_EOF && c != '\n') 833 continue; 834 skipping = true; 835 break; 836 } 837 } 838 839 if (skipping) 840 continue; 841 842 if (!bitnset(M_ALIASABLE, al.q_mailer->m_flags)) 843 { 844 syserr("554 5.3.5 %s... cannot alias non-local names", 845 al.q_paddr); 846 continue; 847 } 848 849 /* 850 ** Insert alias into symbol table or database file. 851 ** 852 ** Special case pOStmaStER -- always make it lower case. 853 */ 854 855 if (SM_STRCASEEQ(al.q_user, "postmaster")) 856 makelower_a(&al.q_user, CurEnv->e_rpool); 857 858 lhssize = strlen(al.q_user); 859 rhssize = strlen(rhs); 860 if (rhssize > 0) 861 { 862 /* is RHS empty (just spaces)? */ 863 p = rhs; 864 while (SM_ISSPACE(*p)) 865 p++; 866 } 867 if (rhssize == 0 || *p == '\0') 868 { 869 syserr("554 5.3.5 %.40s... missing value for alias", 870 line); 871 872 } 873 else 874 { 875 #if _FFR_8BITENVADDR 876 dequote_internal_chars(al.q_user, lhsbuf, sizeof(lhsbuf)); 877 dequote_internal_chars(rhs, rhsbuf, sizeof(rhsbuf)); 878 map->map_class->map_store(map, lhsbuf, rhsbuf); 879 #else 880 map->map_class->map_store(map, al.q_user, rhs); 881 #endif 882 883 /* statistics */ 884 naliases++; 885 bytes += lhssize + rhssize; 886 if (rhssize > longest) 887 longest = rhssize; 888 } 889 } 890 891 CurEnv->e_to = NULL; 892 FileName = NULL; 893 if (Verbose || announcestats) 894 message("%s: %ld aliases, longest %ld bytes, %ld bytes total", 895 map->map_file, naliases, longest, bytes); 896 if (LogLevel > 7 && logstats) 897 sm_syslog(LOG_INFO, NOQID, 898 "%s: %ld aliases, longest %ld bytes, %ld bytes total", 899 map->map_file, naliases, longest, bytes); 900 } 901 /* 902 ** FORWARD -- Try to forward mail 903 ** 904 ** This is similar but not identical to aliasing. 905 ** 906 ** Parameters: 907 ** user -- the name of the user who's mail we would like 908 ** to forward to. It must have been verified -- 909 ** i.e., the q_home field must have been filled in. 910 ** sendq -- a pointer to the head of the send queue to 911 ** put this user's aliases in. 912 ** aliaslevel -- the current alias nesting depth. 913 ** e -- the current envelope. 914 ** 915 ** Returns: 916 ** none. 917 ** 918 ** Side Effects: 919 ** New names are added to send queues. 920 */ 921 922 void 923 forward(user, sendq, aliaslevel, e) 924 ADDRESS *user; 925 ADDRESS **sendq; 926 int aliaslevel; 927 register ENVELOPE *e; 928 { 929 char *pp; 930 char *ep; 931 bool got_transient; 932 933 if (tTd(27, 1)) 934 sm_dprintf("forward(%s)\n", user->q_paddr); 935 936 if (!bitnset(M_HASPWENT, user->q_mailer->m_flags) || 937 !QS_IS_OK(user->q_state)) 938 return; 939 if (ForwardPath != NULL && *ForwardPath == '\0') 940 return; 941 if (user->q_home == NULL) 942 { 943 syserr("554 5.3.0 forward: no home"); 944 user->q_home = "/no/such/directory"; 945 } 946 947 /* good address -- look for .forward file in home */ 948 macdefine(&e->e_macro, A_PERM, 'z', user->q_home); 949 macdefine(&e->e_macro, A_PERM, 'u', user->q_user); 950 macdefine(&e->e_macro, A_PERM, 'h', user->q_host); 951 if (ForwardPath == NULL) 952 ForwardPath = newstr("\201z/.forward"); 953 954 got_transient = false; 955 for (pp = ForwardPath; pp != NULL; pp = ep) 956 { 957 int err; 958 char buf[MAXPATHLEN]; 959 struct stat st; 960 961 ep = strchr(pp, SEPARATOR); 962 if (ep != NULL) 963 *ep = '\0'; 964 expand(pp, buf, sizeof(buf), e); 965 if (ep != NULL) 966 *ep++ = SEPARATOR; 967 if (buf[0] == '\0') 968 continue; 969 if (tTd(27, 3)) 970 sm_dprintf("forward: trying %s\n", buf); 971 972 err = include(buf, true, user, sendq, aliaslevel, e); 973 if (err == 0) 974 break; 975 else if (transienterror(err)) 976 { 977 /* we may have to suspend this message */ 978 got_transient = true; 979 if (tTd(27, 2)) 980 sm_dprintf("forward: transient error on %s\n", 981 buf); 982 if (LogLevel > 2) 983 { 984 char *curhost = CurHostName; 985 986 CurHostName = NULL; 987 sm_syslog(LOG_ERR, e->e_id, 988 "forward %s: transient error: %s", 989 buf, sm_errstring(err)); 990 CurHostName = curhost; 991 } 992 993 } 994 else 995 { 996 switch (err) 997 { 998 case ENOENT: 999 break; 1000 1001 case E_SM_WWDIR: 1002 case E_SM_GWDIR: 1003 /* check if it even exists */ 1004 if (stat(buf, &st) < 0 && errno == ENOENT) 1005 { 1006 if (bitnset(DBS_DONTWARNFORWARDFILEINUNSAFEDIRPATH, 1007 DontBlameSendmail)) 1008 break; 1009 } 1010 /* FALLTHROUGH */ 1011 1012 #if _FFR_FORWARD_SYSERR 1013 case E_SM_NOSLINK: 1014 case E_SM_NOHLINK: 1015 case E_SM_REGONLY: 1016 case E_SM_ISEXEC: 1017 case E_SM_WWFILE: 1018 case E_SM_GWFILE: 1019 syserr("forward: %s: %s", buf, sm_errstring(err)); 1020 break; 1021 #endif /* _FFR_FORWARD_SYSERR */ 1022 1023 default: 1024 if (LogLevel > (RunAsUid == 0 ? 2 : 10)) 1025 sm_syslog(LOG_WARNING, e->e_id, 1026 "forward %s: %s", buf, 1027 sm_errstring(err)); 1028 if (Verbose) 1029 message("forward: %s: %s", 1030 buf, sm_errstring(err)); 1031 break; 1032 } 1033 } 1034 } 1035 if (pp == NULL && got_transient) 1036 { 1037 /* 1038 ** There was no successful .forward open and at least one 1039 ** transient open. We have to defer this address for 1040 ** further delivery. 1041 */ 1042 1043 message("transient .forward open error: message queued"); 1044 user->q_state = QS_QUEUEUP; 1045 return; 1046 } 1047 } 1048