alias.c
上传用户:xu_441
上传日期:2007-01-04
资源大小:1640k
文件大小:21k
源码类别:

Email客户端

开发平台:

Unix_Linux

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