Remove tm.h and xm.h handling, as it wasn't used. Use nm.h only when needed.
[dragonfly.git] / contrib / sendmail-8.14 / sendmail / alias.c
blob3eae4baf4bbf59b4b9952c8838cee04a48d976f8
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.
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.
14 #include <sendmail.h>
16 SM_RCSID("@(#)$Id: alias.c,v 8.219 2006/10/24 18:04:09 ca Exp $")
18 #define SEPARATOR ':'
19 # define ALIAS_SPEC_SEPARATORS " ,/:"
21 static MAP *AliasFileMap = NULL; /* the actual aliases.files map */
22 static int NAliasFileMaps; /* the number of entries in AliasFileMap */
24 static char *aliaslookup __P((char *, int *, char *));
27 ** ALIAS -- Compute aliases.
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.
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.
40 ** Returns:
41 ** none
43 ** Side Effects:
44 ** Aliases found are expanded.
46 ** Deficiencies:
47 ** It should complain about names that are aliased to
48 ** nothing.
51 void
52 alias(a, sendq, aliaslevel, e)
53 register ADDRESS *a;
54 ADDRESS **sendq;
55 int aliaslevel;
56 register ENVELOPE *e;
58 register char *p;
59 char *owner;
60 auto int status = EX_OK;
61 char obuf[MAXNAME + 7];
63 if (tTd(27, 1))
64 sm_dprintf("alias(%s)\n", a->q_user);
66 /* don't realias already aliased names */
67 if (!QS_IS_OK(a->q_state))
68 return;
70 if (NoAlias)
71 return;
73 e->e_to = a->q_paddr;
76 ** Look up this name.
78 ** If the map was unavailable, we will queue this message
79 ** until the map becomes available; otherwise, we could
80 ** bounce messages inappropriately.
83 #if _FFR_REDIRECTEMPTY
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!
90 if (e->e_sender != NULL && *e->e_sender == '\0')
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)
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);
103 #endif /* _FFR_REDIRECTEMPTY */
105 p = aliaslookup(a->q_user, &status, a->q_host);
106 if (status == EX_TEMPFAIL || status == EX_UNAVAILABLE)
108 a->q_state = QS_QUEUEUP;
109 if (e->e_message == NULL)
110 e->e_message = sm_rpool_strdup_x(e->e_rpool,
111 "alias database unavailable");
113 /* XXX msg only per recipient? */
114 if (a->q_message == NULL)
115 a->q_message = "alias database unavailable";
116 return;
118 if (p == NULL)
119 return;
122 ** Match on Alias.
123 ** Deliver to the target list.
126 if (tTd(27, 1))
127 sm_dprintf("%s (%s, %s) aliased to %s\n",
128 a->q_paddr, a->q_host, a->q_user, p);
129 if (bitset(EF_VRFYONLY, e->e_flags))
131 a->q_state = QS_VERIFIED;
132 return;
134 message("aliased to %s", shortenstring(p, MAXSHORTSTR));
135 if (LogLevel > 10)
136 sm_syslog(LOG_INFO, e->e_id,
137 "alias %.100s => %s",
138 a->q_paddr, shortenstring(p, MAXSHORTSTR));
139 a->q_flags &= ~QSELFREF;
140 if (tTd(27, 5))
142 sm_dprintf("alias: QS_EXPANDED ");
143 printaddr(sm_debug_file(), a, false);
145 a->q_state = QS_EXPANDED;
148 ** Always deliver aliased items as the default user.
149 ** Setting q_gid to 0 forces deliver() to use DefUser
150 ** instead of the alias name for the call to initgroups().
153 a->q_uid = DefUid;
154 a->q_gid = 0;
155 a->q_fullname = NULL;
156 a->q_flags |= QGOODUID|QALIAS;
158 (void) sendtolist(p, a, sendq, aliaslevel + 1, e);
160 if (bitset(QSELFREF, a->q_flags) && QS_IS_EXPANDED(a->q_state))
161 a->q_state = QS_OK;
164 ** Look for owner of alias
167 if (strncmp(a->q_user, "owner-", 6) == 0 ||
168 strlen(a->q_user) > sizeof(obuf) - 7)
169 (void) sm_strlcpy(obuf, "owner-owner", sizeof(obuf));
170 else
171 (void) sm_strlcpyn(obuf, sizeof(obuf), 2, "owner-", a->q_user);
172 owner = aliaslookup(obuf, &status, a->q_host);
173 if (owner == NULL)
174 return;
176 /* reflect owner into envelope sender */
177 if (strpbrk(owner, ",:/|\"") != NULL)
178 owner = obuf;
179 a->q_owner = sm_rpool_strdup_x(e->e_rpool, owner);
181 /* announce delivery to this alias; NORECEIPT bit set later */
182 if (e->e_xfp != NULL)
183 (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT,
184 "Message delivered to mailing list %s\n",
185 a->q_paddr);
186 e->e_flags |= EF_SENDRECEIPT;
187 a->q_flags |= QDELIVERED|QEXPANDED;
190 ** ALIASLOOKUP -- look up a name in the alias file.
192 ** Parameters:
193 ** name -- the name to look up.
194 ** pstat -- a pointer to a place to put the status.
195 ** av -- argument for %1 expansion.
197 ** Returns:
198 ** the value of name.
199 ** NULL if unknown.
201 ** Side Effects:
202 ** none.
204 ** Warnings:
205 ** The return value will be trashed across calls.
208 static char *
209 aliaslookup(name, pstat, av)
210 char *name;
211 int *pstat;
212 char *av;
214 static MAP *map = NULL;
215 #if _FFR_ALIAS_DETAIL
216 int i;
217 char *argv[4];
218 #endif /* _FFR_ALIAS_DETAIL */
220 if (map == NULL)
222 STAB *s = stab("aliases", ST_MAP, ST_FIND);
224 if (s == NULL)
225 return NULL;
226 map = &s->s_map;
228 DYNOPENMAP(map);
230 /* special case POstMastER -- always use lower case */
231 if (sm_strcasecmp(name, "postmaster") == 0)
232 name = "postmaster";
234 #if _FFR_ALIAS_DETAIL
235 i = 0;
236 argv[i++] = name;
237 argv[i++] = av;
239 /* XXX '+' is hardwired here as delimiter! */
240 if (av != NULL && *av == '+')
241 argv[i++] = av + 1;
242 argv[i++] = NULL;
243 return (*map->map_class->map_lookup)(map, name, argv, pstat);
244 #else /* _FFR_ALIAS_DETAIL */
245 return (*map->map_class->map_lookup)(map, name, NULL, pstat);
246 #endif /* _FFR_ALIAS_DETAIL */
249 ** SETALIAS -- set up an alias map
251 ** Called when reading configuration file.
253 ** Parameters:
254 ** spec -- the alias specification
256 ** Returns:
257 ** none.
260 void
261 setalias(spec)
262 char *spec;
264 register char *p;
265 register MAP *map;
266 char *class;
267 STAB *s;
269 if (tTd(27, 8))
270 sm_dprintf("setalias(%s)\n", spec);
272 for (p = spec; p != NULL; )
274 char buf[50];
276 while (isascii(*p) && isspace(*p))
277 p++;
278 if (*p == '\0')
279 break;
280 spec = p;
282 if (NAliasFileMaps >= MAXMAPSTACK)
284 syserr("Too many alias databases defined, %d max",
285 MAXMAPSTACK);
286 return;
288 if (AliasFileMap == NULL)
290 (void) sm_strlcpy(buf, "aliases.files sequence",
291 sizeof(buf));
292 AliasFileMap = makemapentry(buf);
293 if (AliasFileMap == NULL)
295 syserr("setalias: cannot create aliases.files map");
296 return;
299 (void) sm_snprintf(buf, sizeof(buf), "Alias%d", NAliasFileMaps);
300 s = stab(buf, ST_MAP, ST_ENTER);
301 map = &s->s_map;
302 memset(map, '\0', sizeof(*map));
303 map->map_mname = s->s_name;
304 p = strpbrk(p, ALIAS_SPEC_SEPARATORS);
305 if (p != NULL && *p == SEPARATOR)
307 /* map name */
308 *p++ = '\0';
309 class = spec;
310 spec = p;
312 else
314 class = "implicit";
315 map->map_mflags = MF_INCLNULL;
318 /* find end of spec */
319 if (p != NULL)
321 bool quoted = false;
323 for (; *p != '\0'; p++)
326 ** Don't break into a quoted string.
327 ** Needed for ldap maps which use
328 ** commas in their specifications.
331 if (*p == '"')
332 quoted = !quoted;
333 else if (*p == ',' && !quoted)
334 break;
337 /* No more alias specifications follow */
338 if (*p == '\0')
339 p = NULL;
341 if (p != NULL)
342 *p++ = '\0';
344 if (tTd(27, 20))
345 sm_dprintf(" map %s:%s %s\n", class, s->s_name, spec);
347 /* look up class */
348 s = stab(class, ST_MAPCLASS, ST_FIND);
349 if (s == NULL)
351 syserr("setalias: unknown alias class %s", class);
353 else if (!bitset(MCF_ALIASOK, s->s_mapclass.map_cflags))
355 syserr("setalias: map class %s can't handle aliases",
356 class);
358 else
360 map->map_class = &s->s_mapclass;
361 map->map_mflags |= MF_ALIAS;
362 if (map->map_class->map_parse(map, spec))
364 map->map_mflags |= MF_VALID;
365 AliasFileMap->map_stack[NAliasFileMaps++] = map;
371 ** ALIASWAIT -- wait for distinguished @:@ token to appear.
373 ** This can decide to reopen or rebuild the alias file
375 ** Parameters:
376 ** map -- a pointer to the map descriptor for this alias file.
377 ** ext -- the filename extension (e.g., ".db") for the
378 ** database file.
379 ** isopen -- if set, the database is already open, and we
380 ** should check for validity; otherwise, we are
381 ** just checking to see if it should be created.
383 ** Returns:
384 ** true -- if the database is open when we return.
385 ** false -- if the database is closed when we return.
388 bool
389 aliaswait(map, ext, isopen)
390 MAP *map;
391 char *ext;
392 bool isopen;
394 bool attimeout = false;
395 time_t mtime;
396 struct stat stb;
397 char buf[MAXPATHLEN];
399 if (tTd(27, 3))
400 sm_dprintf("aliaswait(%s:%s)\n",
401 map->map_class->map_cname, map->map_file);
402 if (bitset(MF_ALIASWAIT, map->map_mflags))
403 return isopen;
404 map->map_mflags |= MF_ALIASWAIT;
406 if (SafeAlias > 0)
408 auto int st;
409 unsigned int sleeptime = 2;
410 unsigned int loopcount = 0; /* only used for debugging */
411 time_t toolong = curtime() + SafeAlias;
413 while (isopen &&
414 map->map_class->map_lookup(map, "@", NULL, &st) == NULL)
416 if (curtime() > toolong)
418 /* we timed out */
419 attimeout = true;
420 break;
424 ** Close and re-open the alias database in case
425 ** the one is mv'ed instead of cp'ed in.
428 if (tTd(27, 2))
430 loopcount++;
431 sm_dprintf("aliaswait: sleeping for %u seconds (loopcount = %u)\n",
432 sleeptime, loopcount);
435 map->map_mflags |= MF_CLOSING;
436 map->map_class->map_close(map);
437 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
438 (void) sleep(sleeptime);
439 sleeptime *= 2;
440 if (sleeptime > 60)
441 sleeptime = 60;
442 isopen = map->map_class->map_open(map, O_RDONLY);
446 /* see if we need to go into auto-rebuild mode */
447 if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags))
449 if (tTd(27, 3))
450 sm_dprintf("aliaswait: not rebuildable\n");
451 map->map_mflags &= ~MF_ALIASWAIT;
452 return isopen;
454 if (stat(map->map_file, &stb) < 0)
456 if (tTd(27, 3))
457 sm_dprintf("aliaswait: no source file\n");
458 map->map_mflags &= ~MF_ALIASWAIT;
459 return isopen;
461 mtime = stb.st_mtime;
462 if (sm_strlcpyn(buf, sizeof(buf), 2,
463 map->map_file, ext == NULL ? "" : ext) >= sizeof(buf))
465 if (LogLevel > 3)
466 sm_syslog(LOG_INFO, NOQID,
467 "alias database %s%s name too long",
468 map->map_file, ext == NULL ? "" : ext);
469 message("alias database %s%s name too long",
470 map->map_file, ext == NULL ? "" : ext);
473 if (stat(buf, &stb) < 0 || stb.st_mtime < mtime || attimeout)
475 if (LogLevel > 3)
476 sm_syslog(LOG_INFO, NOQID,
477 "alias database %s out of date", buf);
478 message("Warning: alias database %s out of date", buf);
480 map->map_mflags &= ~MF_ALIASWAIT;
481 return isopen;
484 ** REBUILDALIASES -- rebuild the alias database.
486 ** Parameters:
487 ** map -- the database to rebuild.
488 ** automatic -- set if this was automatically generated.
490 ** Returns:
491 ** true if successful; false otherwise.
493 ** Side Effects:
494 ** Reads the text version of the database, builds the
495 ** DBM or DB version.
498 bool
499 rebuildaliases(map, automatic)
500 register MAP *map;
501 bool automatic;
503 SM_FILE_T *af;
504 bool nolock = false;
505 bool success = false;
506 long sff = SFF_OPENASROOT|SFF_REGONLY|SFF_NOLOCK;
507 sigfunc_t oldsigint, oldsigquit;
508 #ifdef SIGTSTP
509 sigfunc_t oldsigtstp;
510 #endif /* SIGTSTP */
512 if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags))
513 return false;
515 if (!bitnset(DBS_LINKEDALIASFILEINWRITABLEDIR, DontBlameSendmail))
516 sff |= SFF_NOWLINK;
517 if (!bitnset(DBS_GROUPWRITABLEALIASFILE, DontBlameSendmail))
518 sff |= SFF_NOGWFILES;
519 if (!bitnset(DBS_WORLDWRITABLEALIASFILE, DontBlameSendmail))
520 sff |= SFF_NOWWFILES;
522 /* try to lock the source file */
523 if ((af = safefopen(map->map_file, O_RDWR, 0, sff)) == NULL)
525 struct stat stb;
527 if ((errno != EACCES && errno != EROFS) || automatic ||
528 (af = safefopen(map->map_file, O_RDONLY, 0, sff)) == NULL)
530 int saveerr = errno;
532 if (tTd(27, 1))
533 sm_dprintf("Can't open %s: %s\n",
534 map->map_file, sm_errstring(saveerr));
535 if (!automatic && !bitset(MF_OPTIONAL, map->map_mflags))
536 message("newaliases: cannot open %s: %s",
537 map->map_file, sm_errstring(saveerr));
538 errno = 0;
539 return false;
541 nolock = true;
542 if (tTd(27, 1) ||
543 fstat(sm_io_getinfo(af, SM_IO_WHAT_FD, NULL), &stb) < 0 ||
544 bitset(S_IWUSR|S_IWGRP|S_IWOTH, stb.st_mode))
545 message("warning: cannot lock %s: %s",
546 map->map_file, sm_errstring(errno));
549 /* see if someone else is rebuilding the alias file */
550 if (!nolock &&
551 !lockfile(sm_io_getinfo(af, SM_IO_WHAT_FD, NULL), map->map_file,
552 NULL, LOCK_EX|LOCK_NB))
554 /* yes, they are -- wait until done */
555 message("Alias file %s is locked (maybe being rebuilt)",
556 map->map_file);
557 if (OpMode != MD_INITALIAS)
559 /* wait for other rebuild to complete */
560 (void) lockfile(sm_io_getinfo(af, SM_IO_WHAT_FD, NULL),
561 map->map_file, NULL, LOCK_EX);
563 (void) sm_io_close(af, SM_TIME_DEFAULT);
564 errno = 0;
565 return false;
568 oldsigint = sm_signal(SIGINT, SIG_IGN);
569 oldsigquit = sm_signal(SIGQUIT, SIG_IGN);
570 #ifdef SIGTSTP
571 oldsigtstp = sm_signal(SIGTSTP, SIG_IGN);
572 #endif /* SIGTSTP */
574 if (map->map_class->map_open(map, O_RDWR))
576 if (LogLevel > 7)
578 sm_syslog(LOG_NOTICE, NOQID,
579 "alias database %s %srebuilt by %s",
580 map->map_file, automatic ? "auto" : "",
581 username());
583 map->map_mflags |= MF_OPEN|MF_WRITABLE;
584 map->map_pid = CurrentPid;
585 readaliases(map, af, !automatic, true);
586 success = true;
588 else
590 if (tTd(27, 1))
591 sm_dprintf("Can't create database for %s: %s\n",
592 map->map_file, sm_errstring(errno));
593 if (!automatic)
594 syserr("Cannot create database for alias file %s",
595 map->map_file);
598 /* close the file, thus releasing locks */
599 (void) sm_io_close(af, SM_TIME_DEFAULT);
601 /* add distinguished entries and close the database */
602 if (bitset(MF_OPEN, map->map_mflags))
604 map->map_mflags |= MF_CLOSING;
605 map->map_class->map_close(map);
606 map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
609 /* restore the old signals */
610 (void) sm_signal(SIGINT, oldsigint);
611 (void) sm_signal(SIGQUIT, oldsigquit);
612 #ifdef SIGTSTP
613 (void) sm_signal(SIGTSTP, oldsigtstp);
614 #endif /* SIGTSTP */
615 return success;
618 ** READALIASES -- read and process the alias file.
620 ** This routine implements the part of initaliases that occurs
621 ** when we are not going to use the DBM stuff.
623 ** Parameters:
624 ** map -- the alias database descriptor.
625 ** af -- file to read the aliases from.
626 ** announcestats -- announce statistics regarding number of
627 ** aliases, longest alias, etc.
628 ** logstats -- lot the same info.
630 ** Returns:
631 ** none.
633 ** Side Effects:
634 ** Reads aliasfile into the symbol table.
635 ** Optionally, builds the .dir & .pag files.
638 void
639 readaliases(map, af, announcestats, logstats)
640 register MAP *map;
641 SM_FILE_T *af;
642 bool announcestats;
643 bool logstats;
645 register char *p;
646 char *rhs;
647 bool skipping;
648 long naliases, bytes, longest;
649 ADDRESS al, bl;
650 char line[BUFSIZ];
653 ** Read and interpret lines
656 FileName = map->map_file;
657 LineNumber = 0;
658 naliases = bytes = longest = 0;
659 skipping = false;
660 while (sm_io_fgets(af, SM_TIME_DEFAULT, line, sizeof(line)) != NULL)
662 int lhssize, rhssize;
663 int c;
665 LineNumber++;
666 p = strchr(line, '\n');
668 /* XXX what if line="a\\" ? */
669 while (p != NULL && p > line && p[-1] == '\\')
671 p--;
672 if (sm_io_fgets(af, SM_TIME_DEFAULT, p,
673 SPACELEFT(line, p)) == NULL)
674 break;
675 LineNumber++;
676 p = strchr(p, '\n');
678 if (p != NULL)
679 *p = '\0';
680 else if (!sm_io_eof(af))
682 errno = 0;
683 syserr("554 5.3.0 alias line too long");
685 /* flush to end of line */
686 while ((c = sm_io_getc(af, SM_TIME_DEFAULT)) !=
687 SM_IO_EOF && c != '\n')
688 continue;
690 /* skip any continuation lines */
691 skipping = true;
692 continue;
694 switch (line[0])
696 case '#':
697 case '\0':
698 skipping = false;
699 continue;
701 case ' ':
702 case '\t':
703 if (!skipping)
704 syserr("554 5.3.5 Non-continuation line starts with space");
705 skipping = true;
706 continue;
708 skipping = false;
711 ** Process the LHS
712 ** Find the colon separator, and parse the address.
713 ** It should resolve to a local name -- this will
714 ** be checked later (we want to optionally do
715 ** parsing of the RHS first to maximize error
716 ** detection).
719 for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++)
720 continue;
721 if (*p++ != ':')
723 syserr("554 5.3.5 missing colon");
724 continue;
726 if (parseaddr(line, &al, RF_COPYALL, ':', NULL, CurEnv, true)
727 == NULL)
729 syserr("554 5.3.5 %.40s... illegal alias name", line);
730 continue;
734 ** Process the RHS.
735 ** 'al' is the internal form of the LHS address.
736 ** 'p' points to the text of the RHS.
739 while (isascii(*p) && isspace(*p))
740 p++;
741 rhs = p;
742 for (;;)
744 register char *nlp;
746 nlp = &p[strlen(p)];
747 if (nlp > p && nlp[-1] == '\n')
748 *--nlp = '\0';
750 if (CheckAliases)
752 /* do parsing & compression of addresses */
753 while (*p != '\0')
755 auto char *delimptr;
757 while ((isascii(*p) && isspace(*p)) ||
758 *p == ',')
759 p++;
760 if (*p == '\0')
761 break;
762 if (parseaddr(p, &bl, RF_COPYNONE, ',',
763 &delimptr, CurEnv, true)
764 == NULL)
765 usrerr("553 5.3.5 %s... bad address", p);
766 p = delimptr;
769 else
771 p = nlp;
774 /* see if there should be a continuation line */
775 c = sm_io_getc(af, SM_TIME_DEFAULT);
776 if (!sm_io_eof(af))
777 (void) sm_io_ungetc(af, SM_TIME_DEFAULT, c);
778 if (c != ' ' && c != '\t')
779 break;
781 /* read continuation line */
782 if (sm_io_fgets(af, SM_TIME_DEFAULT, p,
783 sizeof(line) - (p-line)) == NULL)
784 break;
785 LineNumber++;
787 /* check for line overflow */
788 if (strchr(p, '\n') == NULL && !sm_io_eof(af))
790 usrerr("554 5.3.5 alias too long");
791 while ((c = sm_io_getc(af, SM_TIME_DEFAULT))
792 != SM_IO_EOF && c != '\n')
793 continue;
794 skipping = true;
795 break;
799 if (skipping)
800 continue;
802 if (!bitnset(M_ALIASABLE, al.q_mailer->m_flags))
804 syserr("554 5.3.5 %s... cannot alias non-local names",
805 al.q_paddr);
806 continue;
810 ** Insert alias into symbol table or database file.
812 ** Special case pOStmaStER -- always make it lower case.
815 if (sm_strcasecmp(al.q_user, "postmaster") == 0)
816 makelower(al.q_user);
818 lhssize = strlen(al.q_user);
819 rhssize = strlen(rhs);
820 if (rhssize > 0)
822 /* is RHS empty (just spaces)? */
823 p = rhs;
824 while (isascii(*p) && isspace(*p))
825 p++;
827 if (rhssize == 0 || *p == '\0')
829 syserr("554 5.3.5 %.40s... missing value for alias",
830 line);
833 else
835 map->map_class->map_store(map, al.q_user, rhs);
837 /* statistics */
838 naliases++;
839 bytes += lhssize + rhssize;
840 if (rhssize > longest)
841 longest = rhssize;
844 #if 0
846 ** address strings are now stored in the envelope rpool,
847 ** and therefore cannot be freed.
849 if (al.q_paddr != NULL)
850 sm_free(al.q_paddr); /* disabled */
851 if (al.q_host != NULL)
852 sm_free(al.q_host); /* disabled */
853 if (al.q_user != NULL)
854 sm_free(al.q_user); /* disabled */
855 #endif /* 0 */
858 CurEnv->e_to = NULL;
859 FileName = NULL;
860 if (Verbose || announcestats)
861 message("%s: %ld aliases, longest %ld bytes, %ld bytes total",
862 map->map_file, naliases, longest, bytes);
863 if (LogLevel > 7 && logstats)
864 sm_syslog(LOG_INFO, NOQID,
865 "%s: %ld aliases, longest %ld bytes, %ld bytes total",
866 map->map_file, naliases, longest, bytes);
869 ** FORWARD -- Try to forward mail
871 ** This is similar but not identical to aliasing.
873 ** Parameters:
874 ** user -- the name of the user who's mail we would like
875 ** to forward to. It must have been verified --
876 ** i.e., the q_home field must have been filled
877 ** in.
878 ** sendq -- a pointer to the head of the send queue to
879 ** put this user's aliases in.
880 ** aliaslevel -- the current alias nesting depth.
881 ** e -- the current envelope.
883 ** Returns:
884 ** none.
886 ** Side Effects:
887 ** New names are added to send queues.
890 void
891 forward(user, sendq, aliaslevel, e)
892 ADDRESS *user;
893 ADDRESS **sendq;
894 int aliaslevel;
895 register ENVELOPE *e;
897 char *pp;
898 char *ep;
899 bool got_transient;
901 if (tTd(27, 1))
902 sm_dprintf("forward(%s)\n", user->q_paddr);
904 if (!bitnset(M_HASPWENT, user->q_mailer->m_flags) ||
905 !QS_IS_OK(user->q_state))
906 return;
907 if (ForwardPath != NULL && *ForwardPath == '\0')
908 return;
909 if (user->q_home == NULL)
911 syserr("554 5.3.0 forward: no home");
912 user->q_home = "/no/such/directory";
915 /* good address -- look for .forward file in home */
916 macdefine(&e->e_macro, A_PERM, 'z', user->q_home);
917 macdefine(&e->e_macro, A_PERM, 'u', user->q_user);
918 macdefine(&e->e_macro, A_PERM, 'h', user->q_host);
919 if (ForwardPath == NULL)
920 ForwardPath = newstr("\201z/.forward");
922 got_transient = false;
923 for (pp = ForwardPath; pp != NULL; pp = ep)
925 int err;
926 char buf[MAXPATHLEN];
927 struct stat st;
929 ep = strchr(pp, SEPARATOR);
930 if (ep != NULL)
931 *ep = '\0';
932 expand(pp, buf, sizeof(buf), e);
933 if (ep != NULL)
934 *ep++ = SEPARATOR;
935 if (buf[0] == '\0')
936 continue;
937 if (tTd(27, 3))
938 sm_dprintf("forward: trying %s\n", buf);
940 err = include(buf, true, user, sendq, aliaslevel, e);
941 if (err == 0)
942 break;
943 else if (transienterror(err))
945 /* we may have to suspend this message */
946 got_transient = true;
947 if (tTd(27, 2))
948 sm_dprintf("forward: transient error on %s\n",
949 buf);
950 if (LogLevel > 2)
952 char *curhost = CurHostName;
954 CurHostName = NULL;
955 sm_syslog(LOG_ERR, e->e_id,
956 "forward %s: transient error: %s",
957 buf, sm_errstring(err));
958 CurHostName = curhost;
962 else
964 switch (err)
966 case ENOENT:
967 break;
969 case E_SM_WWDIR:
970 case E_SM_GWDIR:
971 /* check if it even exists */
972 if (stat(buf, &st) < 0 && errno == ENOENT)
974 if (bitnset(DBS_DONTWARNFORWARDFILEINUNSAFEDIRPATH,
975 DontBlameSendmail))
976 break;
978 /* FALLTHROUGH */
980 #if _FFR_FORWARD_SYSERR
981 case E_SM_NOSLINK:
982 case E_SM_NOHLINK:
983 case E_SM_REGONLY:
984 case E_SM_ISEXEC:
985 case E_SM_WWFILE:
986 case E_SM_GWFILE:
987 syserr("forward: %s: %s", buf, sm_errstring(err));
988 break;
989 #endif /* _FFR_FORWARD_SYSERR */
991 default:
992 if (LogLevel > (RunAsUid == 0 ? 2 : 10))
993 sm_syslog(LOG_WARNING, e->e_id,
994 "forward %s: %s", buf,
995 sm_errstring(err));
996 if (Verbose)
997 message("forward: %s: %s",
998 buf, sm_errstring(err));
999 break;
1003 if (pp == NULL && got_transient)
1006 ** There was no successful .forward open and at least one
1007 ** transient open. We have to defer this address for
1008 ** further delivery.
1011 message("transient .forward open error: message queued");
1012 user->q_state = QS_QUEUEUP;
1013 return;