2 * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.
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.
16 SM_RCSID("@(#)$Id: alias.c,v 8.219 2006/10/24 18:04:09 ca Exp $")
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.
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.
44 ** Aliases found are expanded.
47 ** It should complain about names that are aliased to
52 alias(a, sendq, aliaslevel, e)
60 auto int status = EX_OK;
61 char obuf[MAXNAME + 7];
64 sm_dprintf("alias(%s)\n", a->q_user);
66 /* don't realias already aliased names */
67 if (!QS_IS_OK(a->q_state))
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)
97 sm_syslog(LOG_WARNING, e->e_id,
98 "possible spam from <> to list: %s, redirected to %s\n",
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";
123 ** Deliver to the target list.
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;
134 message("aliased to %s", shortenstring(p, MAXSHORTSTR));
136 sm_syslog(LOG_INFO, e->e_id,
137 "alias %.100s => %s",
138 a->q_paddr, shortenstring(p, MAXSHORTSTR));
139 a->q_flags &= ~QSELFREF;
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().
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))
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));
171 (void) sm_strlcpyn(obuf, sizeof(obuf), 2, "owner-", a->q_user);
172 owner = aliaslookup(obuf, &status, a->q_host);
176 /* reflect owner into envelope sender */
177 if (strpbrk(owner, ",:/|\"") != NULL)
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",
186 e->e_flags |= EF_SENDRECEIPT;
187 a->q_flags |= QDELIVERED|QEXPANDED;
190 ** ALIASLOOKUP -- look up a name in the alias file.
193 ** name -- the name to look up.
194 ** pstat -- a pointer to a place to put the status.
195 ** av -- argument for %1 expansion.
198 ** the value of name.
205 ** The return value will be trashed across calls.
209 aliaslookup(name, pstat, av)
214 static MAP *map = NULL;
215 #if _FFR_ALIAS_DETAIL
218 #endif /* _FFR_ALIAS_DETAIL */
222 STAB *s = stab("aliases", ST_MAP, ST_FIND);
230 /* special case POstMastER -- always use lower case */
231 if (sm_strcasecmp(name, "postmaster") == 0)
234 #if _FFR_ALIAS_DETAIL
239 /* XXX '+' is hardwired here as delimiter! */
240 if (av != NULL && *av == '+')
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.
254 ** spec -- the alias specification
270 sm_dprintf("setalias(%s)\n", spec);
272 for (p = spec; p != NULL; )
276 while (isascii(*p) && isspace(*p))
282 if (NAliasFileMaps >= MAXMAPSTACK)
284 syserr("Too many alias databases defined, %d max",
288 if (AliasFileMap == NULL)
290 (void) sm_strlcpy(buf, "aliases.files sequence",
292 AliasFileMap = makemapentry(buf);
293 if (AliasFileMap == NULL)
295 syserr("setalias: cannot create aliases.files map");
299 (void) sm_snprintf(buf, sizeof(buf), "Alias%d", NAliasFileMaps);
300 s = stab(buf, ST_MAP, ST_ENTER);
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)
315 map->map_mflags = MF_INCLNULL;
318 /* find end of spec */
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.
333 else if (*p == ',' && !quoted)
337 /* No more alias specifications follow */
345 sm_dprintf(" map %s:%s %s\n", class, s->s_name, spec);
348 s = stab(class, ST_MAPCLASS, ST_FIND);
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",
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
376 ** map -- a pointer to the map descriptor for this alias file.
377 ** ext -- the filename extension (e.g., ".db") for the
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.
384 ** true -- if the database is open when we return.
385 ** false -- if the database is closed when we return.
389 aliaswait(map, ext, isopen)
394 bool attimeout = false;
397 char buf[MAXPATHLEN];
400 sm_dprintf("aliaswait(%s:%s)\n",
401 map->map_class->map_cname, map->map_file);
402 if (bitset(MF_ALIASWAIT, map->map_mflags))
404 map->map_mflags |= MF_ALIASWAIT;
409 unsigned int sleeptime = 2;
410 unsigned int loopcount = 0; /* only used for debugging */
411 time_t toolong = curtime() + SafeAlias;
414 map->map_class->map_lookup(map, "@", NULL, &st) == NULL)
416 if (curtime() > toolong)
424 ** Close and re-open the alias database in case
425 ** the one is mv'ed instead of cp'ed in.
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);
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))
450 sm_dprintf("aliaswait: not rebuildable\n");
451 map->map_mflags &= ~MF_ALIASWAIT;
454 if (stat(map->map_file, &stb) < 0)
457 sm_dprintf("aliaswait: no source file\n");
458 map->map_mflags &= ~MF_ALIASWAIT;
461 mtime = stb.st_mtime;
462 if (sm_strlcpyn(buf, sizeof(buf), 2,
463 map->map_file, ext == NULL ? "" : ext) >= sizeof(buf))
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)
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;
484 ** REBUILDALIASES -- rebuild the alias database.
487 ** map -- the database to rebuild.
488 ** automatic -- set if this was automatically generated.
491 ** true if successful; false otherwise.
494 ** Reads the text version of the database, builds the
495 ** DBM or DB version.
499 rebuildaliases(map, automatic)
505 bool success = false;
506 long sff = SFF_OPENASROOT|SFF_REGONLY|SFF_NOLOCK;
507 sigfunc_t oldsigint, oldsigquit;
509 sigfunc_t oldsigtstp;
512 if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags))
515 if (!bitnset(DBS_LINKEDALIASFILEINWRITABLEDIR, DontBlameSendmail))
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)
527 if ((errno != EACCES && errno != EROFS) || automatic ||
528 (af = safefopen(map->map_file, O_RDONLY, 0, sff)) == NULL)
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));
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 */
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)",
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);
568 oldsigint = sm_signal(SIGINT, SIG_IGN);
569 oldsigquit = sm_signal(SIGQUIT, SIG_IGN);
571 oldsigtstp = sm_signal(SIGTSTP, SIG_IGN);
574 if (map->map_class->map_open(map, O_RDWR))
578 sm_syslog(LOG_NOTICE, NOQID,
579 "alias database %s %srebuilt by %s",
580 map->map_file, automatic ? "auto" : "",
583 map->map_mflags |= MF_OPEN|MF_WRITABLE;
584 map->map_pid = CurrentPid;
585 readaliases(map, af, !automatic, true);
591 sm_dprintf("Can't create database for %s: %s\n",
592 map->map_file, sm_errstring(errno));
594 syserr("Cannot create database for alias file %s",
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);
613 (void) sm_signal(SIGTSTP, oldsigtstp);
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.
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.
634 ** Reads aliasfile into the symbol table.
635 ** Optionally, builds the .dir & .pag files.
639 readaliases(map, af, announcestats, logstats)
648 long naliases, bytes, longest;
653 ** Read and interpret lines
656 FileName = map->map_file;
658 naliases = bytes = longest = 0;
660 while (sm_io_fgets(af, SM_TIME_DEFAULT, line, sizeof(line)) != NULL)
662 int lhssize, rhssize;
666 p = strchr(line, '\n');
668 /* XXX what if line="a\\" ? */
669 while (p != NULL && p > line && p[-1] == '\\')
672 if (sm_io_fgets(af, SM_TIME_DEFAULT, p,
673 SPACELEFT(line, p)) == NULL)
680 else if (!sm_io_eof(af))
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')
690 /* skip any continuation lines */
704 syserr("554 5.3.5 Non-continuation line starts with space");
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
719 for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++)
723 syserr("554 5.3.5 missing colon");
726 if (parseaddr(line, &al, RF_COPYALL, ':', NULL, CurEnv, true)
729 syserr("554 5.3.5 %.40s... illegal alias name", line);
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))
747 if (nlp > p && nlp[-1] == '\n')
752 /* do parsing & compression of addresses */
757 while ((isascii(*p) && isspace(*p)) ||
762 if (parseaddr(p, &bl, RF_COPYNONE, ',',
763 &delimptr, CurEnv, true)
765 usrerr("553 5.3.5 %s... bad address", p);
774 /* see if there should be a continuation line */
775 c = sm_io_getc(af, SM_TIME_DEFAULT);
777 (void) sm_io_ungetc(af, SM_TIME_DEFAULT, c);
778 if (c != ' ' && c != '\t')
781 /* read continuation line */
782 if (sm_io_fgets(af, SM_TIME_DEFAULT, p,
783 sizeof(line) - (p-line)) == NULL)
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')
802 if (!bitnset(M_ALIASABLE, al.q_mailer->m_flags))
804 syserr("554 5.3.5 %s... cannot alias non-local names",
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);
822 /* is RHS empty (just spaces)? */
824 while (isascii(*p) && isspace(*p))
827 if (rhssize == 0 || *p == '\0')
829 syserr("554 5.3.5 %.40s... missing value for alias",
835 map->map_class->map_store(map, al.q_user, rhs);
839 bytes += lhssize + rhssize;
840 if (rhssize > longest)
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 */
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.
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
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.
887 ** New names are added to send queues.
891 forward(user, sendq, aliaslevel, e)
895 register ENVELOPE *e;
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))
907 if (ForwardPath != NULL && *ForwardPath == '\0')
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)
926 char buf[MAXPATHLEN];
929 ep = strchr(pp, SEPARATOR);
932 expand(pp, buf, sizeof(buf), e);
938 sm_dprintf("forward: trying %s\n", buf);
940 err = include(buf, true, user, sendq, aliaslevel, e);
943 else if (transienterror(err))
945 /* we may have to suspend this message */
946 got_transient = true;
948 sm_dprintf("forward: transient error on %s\n",
952 char *curhost = CurHostName;
955 sm_syslog(LOG_ERR, e->e_id,
956 "forward %s: transient error: %s",
957 buf, sm_errstring(err));
958 CurHostName = curhost;
971 /* check if it even exists */
972 if (stat(buf, &st) < 0 && errno == ENOENT)
974 if (bitnset(DBS_DONTWARNFORWARDFILEINUNSAFEDIRPATH,
980 #if _FFR_FORWARD_SYSERR
987 syserr("forward: %s: %s", buf, sm_errstring(err));
989 #endif /* _FFR_FORWARD_SYSERR */
992 if (LogLevel > (RunAsUid == 0 ? 2 : 10))
993 sm_syslog(LOG_WARNING, e->e_id,
994 "forward %s: %s", buf,
997 message("forward: %s: %s",
998 buf, sm_errstring(err));
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;