1 /* 2 * Copyright (c) 1998-2001 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 1.1.1.7 2002/02/17 21:56:38 gshapiro 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 syslog(LOG_WARNING, 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[MAXNAME + 1]; 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 (void) sm_strlcpyn(buf, sizeof buf, 2, 462 map->map_file, ext == NULL ? "" : ext); 463 if (stat(buf, &stb) < 0 || stb.st_mtime < mtime || attimeout) 464 { 465 if (LogLevel > 3) 466 sm_syslog(LOG_INFO, NOQID, 467 "alias database %s out of date", buf); 468 message("Warning: alias database %s out of date", buf); 469 } 470 map->map_mflags &= ~MF_ALIASWAIT; 471 return isopen; 472 } 473 /* 474 ** REBUILDALIASES -- rebuild the alias database. 475 ** 476 ** Parameters: 477 ** map -- the database to rebuild. 478 ** automatic -- set if this was automatically generated. 479 ** 480 ** Returns: 481 ** true if successful; false otherwise. 482 ** 483 ** Side Effects: 484 ** Reads the text version of the database, builds the 485 ** DBM or DB version. 486 */ 487 488 bool 489 rebuildaliases(map, automatic) 490 register MAP *map; 491 bool automatic; 492 { 493 SM_FILE_T *af; 494 bool nolock = false; 495 bool success = false; 496 long sff = SFF_OPENASROOT|SFF_REGONLY|SFF_NOLOCK; 497 sigfunc_t oldsigint, oldsigquit; 498 #ifdef SIGTSTP 499 sigfunc_t oldsigtstp; 500 #endif /* SIGTSTP */ 501 502 if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags)) 503 return false; 504 505 if (!bitnset(DBS_LINKEDALIASFILEINWRITABLEDIR, DontBlameSendmail)) 506 sff |= SFF_NOWLINK; 507 if (!bitnset(DBS_GROUPWRITABLEALIASFILE, DontBlameSendmail)) 508 sff |= SFF_NOGWFILES; 509 if (!bitnset(DBS_WORLDWRITABLEALIASFILE, DontBlameSendmail)) 510 sff |= SFF_NOWWFILES; 511 512 /* try to lock the source file */ 513 if ((af = safefopen(map->map_file, O_RDWR, 0, sff)) == NULL) 514 { 515 struct stat stb; 516 517 if ((errno != EACCES && errno != EROFS) || automatic || 518 (af = safefopen(map->map_file, O_RDONLY, 0, sff)) == NULL) 519 { 520 int saveerr = errno; 521 522 if (tTd(27, 1)) 523 sm_dprintf("Can't open %s: %s\n", 524 map->map_file, sm_errstring(saveerr)); 525 if (!automatic && !bitset(MF_OPTIONAL, map->map_mflags)) 526 message("newaliases: cannot open %s: %s", 527 map->map_file, sm_errstring(saveerr)); 528 errno = 0; 529 return false; 530 } 531 nolock = true; 532 if (tTd(27, 1) || 533 fstat(sm_io_getinfo(af, SM_IO_WHAT_FD, NULL), &stb) < 0 || 534 bitset(S_IWUSR|S_IWGRP|S_IWOTH, stb.st_mode)) 535 message("warning: cannot lock %s: %s", 536 map->map_file, sm_errstring(errno)); 537 } 538 539 /* see if someone else is rebuilding the alias file */ 540 if (!nolock && 541 !lockfile(sm_io_getinfo(af, SM_IO_WHAT_FD, NULL), map->map_file, 542 NULL, LOCK_EX|LOCK_NB)) 543 { 544 /* yes, they are -- wait until done */ 545 message("Alias file %s is locked (maybe being rebuilt)", 546 map->map_file); 547 if (OpMode != MD_INITALIAS) 548 { 549 /* wait for other rebuild to complete */ 550 (void) lockfile(sm_io_getinfo(af, SM_IO_WHAT_FD, NULL), 551 map->map_file, NULL, LOCK_EX); 552 } 553 (void) sm_io_close(af, SM_TIME_DEFAULT); 554 errno = 0; 555 return false; 556 } 557 558 oldsigint = sm_signal(SIGINT, SIG_IGN); 559 oldsigquit = sm_signal(SIGQUIT, SIG_IGN); 560 #ifdef SIGTSTP 561 oldsigtstp = sm_signal(SIGTSTP, SIG_IGN); 562 #endif /* SIGTSTP */ 563 564 if (map->map_class->map_open(map, O_RDWR)) 565 { 566 if (LogLevel > 7) 567 { 568 sm_syslog(LOG_NOTICE, NOQID, 569 "alias database %s %srebuilt by %s", 570 map->map_file, automatic ? "auto" : "", 571 username()); 572 } 573 map->map_mflags |= MF_OPEN|MF_WRITABLE; 574 map->map_pid = CurrentPid; 575 readaliases(map, af, !automatic, true); 576 success = true; 577 } 578 else 579 { 580 if (tTd(27, 1)) 581 sm_dprintf("Can't create database for %s: %s\n", 582 map->map_file, sm_errstring(errno)); 583 if (!automatic) 584 syserr("Cannot create database for alias file %s", 585 map->map_file); 586 } 587 588 /* close the file, thus releasing locks */ 589 (void) sm_io_close(af, SM_TIME_DEFAULT); 590 591 /* add distinguished entries and close the database */ 592 if (bitset(MF_OPEN, map->map_mflags)) 593 { 594 map->map_mflags |= MF_CLOSING; 595 map->map_class->map_close(map); 596 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING); 597 } 598 599 /* restore the old signals */ 600 (void) sm_signal(SIGINT, oldsigint); 601 (void) sm_signal(SIGQUIT, oldsigquit); 602 #ifdef SIGTSTP 603 (void) sm_signal(SIGTSTP, oldsigtstp); 604 #endif /* SIGTSTP */ 605 return success; 606 } 607 /* 608 ** READALIASES -- read and process the alias file. 609 ** 610 ** This routine implements the part of initaliases that occurs 611 ** when we are not going to use the DBM stuff. 612 ** 613 ** Parameters: 614 ** map -- the alias database descriptor. 615 ** af -- file to read the aliases from. 616 ** announcestats -- announce statistics regarding number of 617 ** aliases, longest alias, etc. 618 ** logstats -- lot the same info. 619 ** 620 ** Returns: 621 ** none. 622 ** 623 ** Side Effects: 624 ** Reads aliasfile into the symbol table. 625 ** Optionally, builds the .dir & .pag files. 626 */ 627 628 void 629 readaliases(map, af, announcestats, logstats) 630 register MAP *map; 631 SM_FILE_T *af; 632 bool announcestats; 633 bool logstats; 634 { 635 register char *p; 636 char *rhs; 637 bool skipping; 638 long naliases, bytes, longest; 639 ADDRESS al, bl; 640 char line[BUFSIZ]; 641 642 /* 643 ** Read and interpret lines 644 */ 645 646 FileName = map->map_file; 647 LineNumber = 0; 648 naliases = bytes = longest = 0; 649 skipping = false; 650 while (sm_io_fgets(af, SM_TIME_DEFAULT, line, sizeof line) != NULL) 651 { 652 int lhssize, rhssize; 653 int c; 654 655 LineNumber++; 656 p = strchr(line, '\n'); 657 658 /* XXX what if line="a\\" ? */ 659 while (p != NULL && p > line && p[-1] == '\\') 660 { 661 p--; 662 if (sm_io_fgets(af, SM_TIME_DEFAULT, p, 663 SPACELEFT(line, p)) == NULL) 664 break; 665 LineNumber++; 666 p = strchr(p, '\n'); 667 } 668 if (p != NULL) 669 *p = '\0'; 670 else if (!sm_io_eof(af)) 671 { 672 errno = 0; 673 syserr("554 5.3.0 alias line too long"); 674 675 /* flush to end of line */ 676 while ((c = sm_io_getc(af, SM_TIME_DEFAULT)) != 677 SM_IO_EOF && c != '\n') 678 continue; 679 680 /* skip any continuation lines */ 681 skipping = true; 682 continue; 683 } 684 switch (line[0]) 685 { 686 case '#': 687 case '\0': 688 skipping = false; 689 continue; 690 691 case ' ': 692 case '\t': 693 if (!skipping) 694 syserr("554 5.3.5 Non-continuation line starts with space"); 695 skipping = true; 696 continue; 697 } 698 skipping = false; 699 700 /* 701 ** Process the LHS 702 ** Find the colon separator, and parse the address. 703 ** It should resolve to a local name -- this will 704 ** be checked later (we want to optionally do 705 ** parsing of the RHS first to maximize error 706 ** detection). 707 */ 708 709 for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++) 710 continue; 711 if (*p++ != ':') 712 { 713 syserr("554 5.3.5 missing colon"); 714 continue; 715 } 716 if (parseaddr(line, &al, RF_COPYALL, ':', NULL, CurEnv, true) 717 == NULL) 718 { 719 syserr("554 5.3.5 %.40s... illegal alias name", line); 720 continue; 721 } 722 723 /* 724 ** Process the RHS. 725 ** 'al' is the internal form of the LHS address. 726 ** 'p' points to the text of the RHS. 727 */ 728 729 while (isascii(*p) && isspace(*p)) 730 p++; 731 rhs = p; 732 for (;;) 733 { 734 register char *nlp; 735 736 nlp = &p[strlen(p)]; 737 if (nlp > p && nlp[-1] == '\n') 738 *--nlp = '\0'; 739 740 if (CheckAliases) 741 { 742 /* do parsing & compression of addresses */ 743 while (*p != '\0') 744 { 745 auto char *delimptr; 746 747 while ((isascii(*p) && isspace(*p)) || 748 *p == ',') 749 p++; 750 if (*p == '\0') 751 break; 752 if (parseaddr(p, &bl, RF_COPYNONE, ',', 753 &delimptr, CurEnv, true) 754 == NULL) 755 usrerr("553 5.3.5 %s... bad address", p); 756 p = delimptr; 757 } 758 } 759 else 760 { 761 p = nlp; 762 } 763 764 /* see if there should be a continuation line */ 765 c = sm_io_getc(af, SM_TIME_DEFAULT); 766 if (!sm_io_eof(af)) 767 (void) sm_io_ungetc(af, SM_TIME_DEFAULT, c); 768 if (c != ' ' && c != '\t') 769 break; 770 771 /* read continuation line */ 772 if (sm_io_fgets(af, SM_TIME_DEFAULT, p, 773 sizeof line - (p-line)) == NULL) 774 break; 775 LineNumber++; 776 777 /* check for line overflow */ 778 if (strchr(p, '\n') == NULL && !sm_io_eof(af)) 779 { 780 usrerr("554 5.3.5 alias too long"); 781 while ((c = sm_io_getc(af, SM_TIME_DEFAULT)) 782 != SM_IO_EOF && c != '\n') 783 continue; 784 skipping = true; 785 break; 786 } 787 } 788 789 if (skipping) 790 continue; 791 792 if (!bitnset(M_ALIASABLE, al.q_mailer->m_flags)) 793 { 794 syserr("554 5.3.5 %s... cannot alias non-local names", 795 al.q_paddr); 796 continue; 797 } 798 799 /* 800 ** Insert alias into symbol table or database file. 801 ** 802 ** Special case pOStmaStER -- always make it lower case. 803 */ 804 805 if (sm_strcasecmp(al.q_user, "postmaster") == 0) 806 makelower(al.q_user); 807 808 lhssize = strlen(al.q_user); 809 rhssize = strlen(rhs); 810 if (rhssize > 0) 811 { 812 /* is RHS empty (just spaces)? */ 813 p = rhs; 814 while (isascii(*p) && isspace(*p)) 815 p++; 816 } 817 if (rhssize == 0 || *p == '\0') 818 { 819 syserr("554 5.3.5 %.40s... missing value for alias", 820 line); 821 822 } 823 else 824 { 825 map->map_class->map_store(map, al.q_user, rhs); 826 827 /* statistics */ 828 naliases++; 829 bytes += lhssize + rhssize; 830 if (rhssize > longest) 831 longest = rhssize; 832 } 833 834 #if 0 835 /* 836 ** address strings are now stored in the envelope rpool, 837 ** and therefore cannot be freed. 838 */ 839 if (al.q_paddr != NULL) 840 sm_free(al.q_paddr); /* disabled */ 841 if (al.q_host != NULL) 842 sm_free(al.q_host); /* disabled */ 843 if (al.q_user != NULL) 844 sm_free(al.q_user); /* disabled */ 845 #endif /* 0 */ 846 } 847 848 CurEnv->e_to = NULL; 849 FileName = NULL; 850 if (Verbose || announcestats) 851 message("%s: %ld aliases, longest %ld bytes, %ld bytes total", 852 map->map_file, naliases, longest, bytes); 853 if (LogLevel > 7 && logstats) 854 sm_syslog(LOG_INFO, NOQID, 855 "%s: %ld aliases, longest %ld bytes, %ld bytes total", 856 map->map_file, naliases, longest, bytes); 857 } 858 /* 859 ** FORWARD -- Try to forward mail 860 ** 861 ** This is similar but not identical to aliasing. 862 ** 863 ** Parameters: 864 ** user -- the name of the user who's mail we would like 865 ** to forward to. It must have been verified -- 866 ** i.e., the q_home field must have been filled 867 ** in. 868 ** sendq -- a pointer to the head of the send queue to 869 ** put this user's aliases in. 870 ** aliaslevel -- the current alias nesting depth. 871 ** e -- the current envelope. 872 ** 873 ** Returns: 874 ** none. 875 ** 876 ** Side Effects: 877 ** New names are added to send queues. 878 */ 879 880 void 881 forward(user, sendq, aliaslevel, e) 882 ADDRESS *user; 883 ADDRESS **sendq; 884 int aliaslevel; 885 register ENVELOPE *e; 886 { 887 char *pp; 888 char *ep; 889 bool got_transient; 890 891 if (tTd(27, 1)) 892 sm_dprintf("forward(%s)\n", user->q_paddr); 893 894 if (!bitnset(M_HASPWENT, user->q_mailer->m_flags) || 895 !QS_IS_OK(user->q_state)) 896 return; 897 if (ForwardPath != NULL && *ForwardPath == '\0') 898 return; 899 if (user->q_home == NULL) 900 { 901 syserr("554 5.3.0 forward: no home"); 902 user->q_home = "/no/such/directory"; 903 } 904 905 /* good address -- look for .forward file in home */ 906 macdefine(&e->e_macro, A_PERM, 'z', user->q_home); 907 macdefine(&e->e_macro, A_PERM, 'u', user->q_user); 908 macdefine(&e->e_macro, A_PERM, 'h', user->q_host); 909 if (ForwardPath == NULL) 910 ForwardPath = newstr("\201z/.forward"); 911 912 got_transient = false; 913 for (pp = ForwardPath; pp != NULL; pp = ep) 914 { 915 int err; 916 char buf[MAXPATHLEN + 1]; 917 struct stat st; 918 919 ep = strchr(pp, SEPARATOR); 920 if (ep != NULL) 921 *ep = '\0'; 922 expand(pp, buf, sizeof buf, e); 923 if (ep != NULL) 924 *ep++ = SEPARATOR; 925 if (buf[0] == '\0') 926 continue; 927 if (tTd(27, 3)) 928 sm_dprintf("forward: trying %s\n", buf); 929 930 err = include(buf, true, user, sendq, aliaslevel, e); 931 if (err == 0) 932 break; 933 else if (transienterror(err)) 934 { 935 /* we may have to suspend this message */ 936 got_transient = true; 937 if (tTd(27, 2)) 938 sm_dprintf("forward: transient error on %s\n", 939 buf); 940 if (LogLevel > 2) 941 { 942 char *curhost = CurHostName; 943 944 CurHostName = NULL; 945 sm_syslog(LOG_ERR, e->e_id, 946 "forward %s: transient error: %s", 947 buf, sm_errstring(err)); 948 CurHostName = curhost; 949 } 950 951 } 952 else 953 { 954 switch (err) 955 { 956 case ENOENT: 957 break; 958 959 case E_SM_WWDIR: 960 case E_SM_GWDIR: 961 /* check if it even exists */ 962 if (stat(buf, &st) < 0 && errno == ENOENT) 963 { 964 if (bitnset(DBS_DONTWARNFORWARDFILEINUNSAFEDIRPATH, 965 DontBlameSendmail)) 966 break; 967 } 968 /* FALLTHROUGH */ 969 970 #if _FFR_FORWARD_SYSERR 971 case E_SM_NOSLINK: 972 case E_SM_NOHLINK: 973 case E_SM_REGONLY: 974 case E_SM_ISEXEC: 975 case E_SM_WWFILE: 976 case E_SM_GWFILE: 977 syserr("forward: %s: %s", buf, sm_errstring(err)); 978 break; 979 #endif /* _FFR_FORWARD_SYSERR */ 980 981 default: 982 if (LogLevel > (RunAsUid == 0 ? 2 : 10)) 983 sm_syslog(LOG_WARNING, e->e_id, 984 "forward %s: %s", buf, 985 sm_errstring(err)); 986 if (Verbose) 987 message("forward: %s: %s", 988 buf, sm_errstring(err)); 989 break; 990 } 991 } 992 } 993 if (pp == NULL && got_transient) 994 { 995 /* 996 ** There was no successful .forward open and at least one 997 ** transient open. We have to defer this address for 998 ** further delivery. 999 */ 1000 1001 message("transient .forward open error: message queued"); 1002 user->q_state = QS_QUEUEUP; 1003 return; 1004 } 1005 } 1006