more cleanup for DSN drafts
[unix-history] / usr / src / usr.sbin / sendmail / src / alias.c
index c4a308e..8f9df51 100644 (file)
@@ -10,7 +10,7 @@
 # include <pwd.h>
 
 #ifndef lint
 # include <pwd.h>
 
 #ifndef lint
-static char sccsid[] = "@(#)alias.c    8.25 (Berkeley) %G%";
+static char sccsid[] = "@(#)alias.c    8.40 (Berkeley) %G%";
 #endif /* not lint */
 
 
 #endif /* not lint */
 
 
@@ -27,6 +27,7 @@ int   NAliasDBs;                      /* number of alias databases */
 **             a -- address to alias.
 **             sendq -- a pointer to the head of the send queue
 **                     to put the aliases in.
 **             a -- address to alias.
 **             sendq -- a pointer to the head of the send queue
 **                     to put the aliases in.
+**             aliaslevel -- the current alias nesting depth.
 **             e -- the current envelope.
 **
 **     Returns:
 **             e -- the current envelope.
 **
 **     Returns:
@@ -40,9 +41,11 @@ int  NAliasDBs;                      /* number of alias databases */
 **                     nothing.
 */
 
 **                     nothing.
 */
 
-alias(a, sendq, e)
+void
+alias(a, sendq, aliaslevel, e)
        register ADDRESS *a;
        ADDRESS **sendq;
        register ADDRESS *a;
        ADDRESS **sendq;
+       int aliaslevel;
        register ENVELOPE *e;
 {
        register char *p;
        register ENVELOPE *e;
 {
        register char *p;
@@ -53,7 +56,7 @@ alias(a, sendq, e)
        extern char *aliaslookup();
 
        if (tTd(27, 1))
        extern char *aliaslookup();
 
        if (tTd(27, 1))
-               printf("alias(%s)\n", a->q_paddr);
+               printf("alias(%s)\n", a->q_user);
 
        /* don't realias already aliased names */
        if (bitset(QDONTSEND|QBADADDR|QVERIFIED, a->q_flags))
 
        /* don't realias already aliased names */
        if (bitset(QDONTSEND|QBADADDR|QVERIFIED, a->q_flags))
@@ -94,18 +97,15 @@ alias(a, sendq, e)
                        a->q_paddr, p);
 #endif
        a->q_flags &= ~QSELFREF;
                        a->q_paddr, p);
 #endif
        a->q_flags &= ~QSELFREF;
-       AliasLevel++;
-       a->q_child = sendto(p, 1, a, 0);
-       AliasLevel--;
-       if (!bitset(QSELFREF, a->q_flags))
+       if (tTd(27, 5))
        {
        {
-               if (tTd(27, 5))
-               {
-                       printf("alias: QDONTSEND ");
-                       printaddr(a, FALSE);
-               }
-               a->q_flags |= QDONTSEND;
+               printf("alias: QDONTSEND ");
+               printaddr(a, FALSE);
        }
        }
+       a->q_flags |= QDONTSEND;
+       naliases = sendtolist(p, a, sendq, aliaslevel + 1, e);
+       if (bitset(QSELFREF, a->q_flags))
+               a->q_flags &= ~QDONTSEND;
 
        /*
        **  Look for owner of alias
 
        /*
        **  Look for owner of alias
@@ -129,11 +129,10 @@ alias(a, sendq, e)
 
        /* announce delivery to this alias; NORECEIPT bit set later */
        if (e->e_xfp != NULL)
 
        /* announce delivery to this alias; NORECEIPT bit set later */
        if (e->e_xfp != NULL)
-       {
                fprintf(e->e_xfp, "Message delivered to mailing list %s\n",
                        a->q_paddr);
                fprintf(e->e_xfp, "Message delivered to mailing list %s\n",
                        a->q_paddr);
-               e->e_flags |= EF_SENDRECEIPT;
-       }
+       e->e_flags |= EF_SENDRECEIPT;
+       a->q_flags |= QREPORT|QEXPLODED;
 }
 \f/*
 **  ALIASLOOKUP -- look up a name in the alias file.
 }
 \f/*
 **  ALIASLOOKUP -- look up a name in the alias file.
@@ -186,6 +185,7 @@ aliaslookup(name, e)
 **             none.
 */
 
 **             none.
 */
 
+void
 setalias(spec)
        char *spec;
 {
 setalias(spec)
        char *spec;
 {
@@ -193,30 +193,47 @@ setalias(spec)
        register MAP *map;
        char *class;
        STAB *s;
        register MAP *map;
        char *class;
        STAB *s;
+       static bool first_unqual = TRUE;
 
        if (tTd(27, 8))
                printf("setalias(%s)\n", spec);
 
        for (p = spec; p != NULL; )
        {
 
        if (tTd(27, 8))
                printf("setalias(%s)\n", spec);
 
        for (p = spec; p != NULL; )
        {
-               char aname[50];
-
                while (isspace(*p))
                        p++;
                if (*p == '\0')
                        break;
                spec = p;
 
                while (isspace(*p))
                        p++;
                if (*p == '\0')
                        break;
                spec = p;
 
-               if (NAliasDBs >= MAXALIASDB)
+               /*
+               **  Treat simple filename specially -- this is the file name
+               **  for the files implementation, not necessarily in order.
+               */
+
+               if (spec[0] == '/' && first_unqual)
                {
                {
-                       syserr("Too many alias databases defined, %d max", MAXALIASDB);
-                       return;
+                       s = stab("aliases.files", ST_MAP, ST_ENTER);
+                       map = &s->s_map;
+                       first_unqual = FALSE;
+               }
+               else
+               {
+                       char aname[50];
+
+                       if (NAliasDBs >= MAXALIASDB)
+                       {
+                               syserr("Too many alias databases defined, %d max",
+                                       MAXALIASDB);
+                               return;
+                       }
+                       (void) sprintf(aname, "Alias%d", NAliasDBs);
+                       s = stab(aname, ST_MAP, ST_ENTER);
+                       map = &s->s_map;
+                       AliasDB[NAliasDBs] = map;
                }
                }
-               (void) sprintf(aname, "Alias%d", NAliasDBs);
-               s = stab(aname, ST_MAP, ST_ENTER);
-               map = &s->s_map;
-               AliasDB[NAliasDBs] = map;
                bzero(map, sizeof *map);
                bzero(map, sizeof *map);
+               map->map_mname = s->s_name;
 
                p = strpbrk(p, " ,/:");
                if (p != NULL && *p == ':')
 
                p = strpbrk(p, " ,/:");
                if (p != NULL && *p == ':')
@@ -238,6 +255,9 @@ setalias(spec)
                if (p != NULL)
                        *p++ = '\0';
 
                if (p != NULL)
                        *p++ = '\0';
 
+               if (tTd(27, 20))
+                       printf("  map %s:%s %s\n", class, s->s_name, spec);
+
                /* look up class */
                s = stab(class, ST_MAPCLASS, ST_FIND);
                if (s == NULL)
                /* look up class */
                s = stab(class, ST_MAPCLASS, ST_FIND);
                if (s == NULL)
@@ -256,7 +276,8 @@ setalias(spec)
                        if (map->map_class->map_parse(map, spec))
                        {
                                map->map_mflags |= MF_VALID|MF_ALIAS;
                        if (map->map_class->map_parse(map, spec))
                        {
                                map->map_mflags |= MF_VALID|MF_ALIAS;
-                               NAliasDBs++;
+                               if (AliasDB[NAliasDBs] == map)
+                                       NAliasDBs++;
                        }
                }
        }
                        }
                }
        }
@@ -288,7 +309,7 @@ aliaswait(map, ext, isopen)
        bool attimeout = FALSE;
        time_t mtime;
        struct stat stb;
        bool attimeout = FALSE;
        time_t mtime;
        struct stat stb;
-       char buf[MAXNAME];
+       char buf[MAXNAME + 1];
 
        if (tTd(27, 3))
                printf("aliaswait(%s:%s)\n",
 
        if (tTd(27, 3))
                printf("aliaswait(%s:%s)\n",
@@ -355,11 +376,16 @@ aliaswait(map, ext, isopen)
                /* database is out of date */
                if (AutoRebuild && stb.st_ino != 0 && stb.st_uid == geteuid())
                {
                /* database is out of date */
                if (AutoRebuild && stb.st_ino != 0 && stb.st_uid == geteuid())
                {
+                       bool oldSuprErrs;
+
                        message("auto-rebuilding alias database %s", buf);
                        message("auto-rebuilding alias database %s", buf);
+                       oldSuprErrs = SuprErrs;
+                       SuprErrs = TRUE;
                        if (isopen)
                                map->map_class->map_close(map);
                        rebuildaliases(map, TRUE);
                        isopen = map->map_class->map_open(map, O_RDONLY);
                        if (isopen)
                                map->map_class->map_close(map);
                        rebuildaliases(map, TRUE);
                        isopen = map->map_class->map_open(map, O_RDONLY);
+                       SuprErrs = oldSuprErrs;
                }
                else
                {
                }
                else
                {
@@ -389,13 +415,17 @@ aliaswait(map, ext, isopen)
 **             DBM or DB version.
 */
 
 **             DBM or DB version.
 */
 
+void
 rebuildaliases(map, automatic)
        register MAP *map;
        bool automatic;
 {
        FILE *af;
        bool nolock = FALSE;
 rebuildaliases(map, automatic)
        register MAP *map;
        bool automatic;
 {
        FILE *af;
        bool nolock = FALSE;
-       sigfunc_t oldsigint;
+       sigfunc_t oldsigint, oldsigquit;
+#ifdef SIGTSTP
+       sigfunc_t oldsigtstp;
+#endif
 
        if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags))
                return;
 
        if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags))
                return;
@@ -411,7 +441,7 @@ rebuildaliases(map, automatic)
                        if (tTd(27, 1))
                                printf("Can't open %s: %s\n",
                                        map->map_file, errstring(saveerr));
                        if (tTd(27, 1))
                                printf("Can't open %s: %s\n",
                                        map->map_file, errstring(saveerr));
-                       if (!automatic)
+                       if (!automatic && !bitset(MF_OPTIONAL, map->map_mflags))
                                message("newaliases: cannot open %s: %s",
                                        map->map_file, errstring(saveerr));
                        errno = 0;
                                message("newaliases: cannot open %s: %s",
                                        map->map_file, errstring(saveerr));
                        errno = 0;
@@ -440,7 +470,13 @@ rebuildaliases(map, automatic)
                return;
        }
 
                return;
        }
 
+       /* avoid denial-of-service attacks */
+       resetlimits();
        oldsigint = setsignal(SIGINT, SIG_IGN);
        oldsigint = setsignal(SIGINT, SIG_IGN);
+       oldsigquit = setsignal(SIGQUIT, SIG_IGN);
+#ifdef SIGTSTP
+       oldsigtstp = setsignal(SIGTSTP, SIG_IGN);
+#endif
 
        if (map->map_class->map_open(map, O_RDWR))
        {
 
        if (map->map_class->map_open(map, O_RDWR))
        {
@@ -453,7 +489,7 @@ rebuildaliases(map, automatic)
                }
 #endif /* LOG */
                map->map_mflags |= MF_OPEN|MF_WRITABLE;
                }
 #endif /* LOG */
                map->map_mflags |= MF_OPEN|MF_WRITABLE;
-               readaliases(map, af, automatic);
+               readaliases(map, af, !automatic, TRUE);
        }
        else
        {
        }
        else
        {
@@ -472,8 +508,12 @@ rebuildaliases(map, automatic)
        if (bitset(MF_OPEN, map->map_mflags))
                map->map_class->map_close(map);
 
        if (bitset(MF_OPEN, map->map_mflags))
                map->map_class->map_close(map);
 
-       /* restore the old signal */
+       /* restore the old signals */
        (void) setsignal(SIGINT, oldsigint);
        (void) setsignal(SIGINT, oldsigint);
+       (void) setsignal(SIGQUIT, oldsigquit);
+#ifdef SIGTSTP
+       (void) setsignal(SIGTSTP, oldsigtstp);
+#endif
 }
 \f/*
 **  READALIASES -- read and process the alias file.
 }
 \f/*
 **  READALIASES -- read and process the alias file.
@@ -484,7 +524,9 @@ rebuildaliases(map, automatic)
 **     Parameters:
 **             map -- the alias database descriptor.
 **             af -- file to read the aliases from.
 **     Parameters:
 **             map -- the alias database descriptor.
 **             af -- file to read the aliases from.
-**             automatic -- set if this was an automatic rebuild.
+**             announcestats -- anounce statistics regarding number of
+**                     aliases, longest alias, etc.
+**             logstats -- lot the same info.
 **
 **     Returns:
 **             none.
 **
 **     Returns:
 **             none.
@@ -494,10 +536,12 @@ rebuildaliases(map, automatic)
 **             Optionally, builds the .dir & .pag files.
 */
 
 **             Optionally, builds the .dir & .pag files.
 */
 
-readaliases(map, af, automatic)
+void
+readaliases(map, af, announcestats, logstats)
        register MAP *map;
        FILE *af;
        register MAP *map;
        FILE *af;
-       int automatic;
+       bool announcestats;
+       bool logstats;
 {
        register char *p;
        char *lhs;
 {
        register char *p;
        char *lhs;
@@ -695,11 +739,11 @@ readaliases(map, af, automatic)
 
        CurEnv->e_to = NULL;
        FileName = NULL;
 
        CurEnv->e_to = NULL;
        FileName = NULL;
-       if (Verbose || !automatic)
+       if (Verbose || announcestats)
                message("%s: %d aliases, longest %d bytes, %d bytes total",
                        map->map_file, naliases, longest, bytes);
 # ifdef LOG
                message("%s: %d aliases, longest %d bytes, %d bytes total",
                        map->map_file, naliases, longest, bytes);
 # ifdef LOG
-       if (LogLevel > 7)
+       if (LogLevel > 7 && logstats)
                syslog(LOG_INFO, "%s: %d aliases, longest %d bytes, %d bytes total",
                        map->map_file, naliases, longest, bytes);
 # endif /* LOG */
                syslog(LOG_INFO, "%s: %d aliases, longest %d bytes, %d bytes total",
                        map->map_file, naliases, longest, bytes);
 # endif /* LOG */
@@ -716,6 +760,8 @@ readaliases(map, af, automatic)
 **                     in.
 **             sendq -- a pointer to the head of the send queue to
 **                     put this user's aliases in.
 **                     in.
 **             sendq -- a pointer to the head of the send queue to
 **                     put this user's aliases in.
+**             aliaslevel -- the current alias nesting depth.
+**             e -- the current envelope.
 **
 **     Returns:
 **             none.
 **
 **     Returns:
 **             none.
@@ -724,9 +770,11 @@ readaliases(map, af, automatic)
 **             New names are added to send queues.
 */
 
 **             New names are added to send queues.
 */
 
-forward(user, sendq, e)
+void
+forward(user, sendq, aliaslevel, e)
        ADDRESS *user;
        ADDRESS **sendq;
        ADDRESS *user;
        ADDRESS **sendq;
+       int aliaslevel;
        register ENVELOPE *e;
 {
        char *pp;
        register ENVELOPE *e;
 {
        char *pp;
@@ -735,7 +783,8 @@ forward(user, sendq, e)
        if (tTd(27, 1))
                printf("forward(%s)\n", user->q_paddr);
 
        if (tTd(27, 1))
                printf("forward(%s)\n", user->q_paddr);
 
-       if (user->q_mailer != LocalMailer || bitset(QBADADDR, user->q_flags))
+       if (!bitnset(M_HASPWENT, user->q_mailer->m_flags) ||
+           bitset(QBADADDR, user->q_flags))
                return;
        if (user->q_home == NULL)
        {
                return;
        if (user->q_home == NULL)
        {
@@ -754,17 +803,18 @@ forward(user, sendq, e)
        {
                int err;
                char buf[MAXPATHLEN+1];
        {
                int err;
                char buf[MAXPATHLEN+1];
+               extern int include();
 
                ep = strchr(pp, ':');
                if (ep != NULL)
                        *ep = '\0';
 
                ep = strchr(pp, ':');
                if (ep != NULL)
                        *ep = '\0';
-               expand(pp, buf, &buf[sizeof buf - 1], e);
+               expand(pp, buf, sizeof buf, e);
                if (ep != NULL)
                        *ep++ = ':';
                if (tTd(27, 3))
                        printf("forward: trying %s\n", buf);
 
                if (ep != NULL)
                        *ep++ = ':';
                if (tTd(27, 3))
                        printf("forward: trying %s\n", buf);
 
-               err = include(buf, TRUE, user, sendq, e);
+               err = include(buf, TRUE, user, sendq, aliaslevel, e);
                if (err == 0)
                        break;
                else if (transienterror(err))
                if (err == 0)
                        break;
                else if (transienterror(err))