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