BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.sbin / sendmail / src / readcf.c
index 5f2e6f8..bd2bad7 100644 (file)
@@ -1,6 +1,42 @@
-# include "sendmail.h"
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)readcf.c   5.22 (Berkeley) 3/12/91";
+#endif /* not lint */
 
 
-SCCSID(@(#)readcf.c    4.12            %G%);
+# include "sendmail.h"
 
 /*
 **  READCF -- read control file.
 
 /*
 **  READCF -- read control file.
@@ -24,10 +60,8 @@ SCCSID(@(#)readcf.c  4.12            %G%);
 **             Sn              Use rewriting set n.
 **             Rlhs rhs        Rewrite addresses that match lhs to
 **                             be rhs.
 **             Sn              Use rewriting set n.
 **             Rlhs rhs        Rewrite addresses that match lhs to
 **                             be rhs.
-**             Mn p f s r a    Define mailer.  n - internal name,
-**                             p - pathname, f - flags, s - rewriting
-**                             ruleset for sender, s - rewriting ruleset
-**                             for recipients, a - argument vector.
+**             Mn arg=val...   Define mailer.  n is the internal name.
+**                             Args specify mailer parameters.
 **             Oxvalue         Set option x to value.
 **             Pname=value     Set precedence name to value.
 **
 **             Oxvalue         Set option x to value.
 **             Pname=value     Set precedence name to value.
 **
@@ -78,7 +112,7 @@ readcf(cfname)
                        if (p[1] == '$')
                        {
                                /* actual dollar sign.... */
                        if (p[1] == '$')
                        {
                                /* actual dollar sign.... */
-                               strcpy(p, p + 1);
+                               (void) strcpy(p, p + 1);
                                continue;
                        }
 
                                continue;
                        }
 
@@ -198,7 +232,7 @@ readcf(cfname)
                        break;
 
                  case 'O':             /* set option */
                        break;
 
                  case 'O':             /* set option */
-                       setoption(buf[1], &buf[2], FALSE);
+                       setoption(buf[1], &buf[2], TRUE, FALSE);
                        break;
 
                  case 'P':             /* set precedence */
                        break;
 
                  case 'P':             /* set precedence */
@@ -290,7 +324,7 @@ fileclass(class, filename, fmt)
        char *filename;
        char *fmt;
 {
        char *filename;
        char *fmt;
 {
-       register FILE *f;
+       FILE *f;
        char buf[MAXLINE];
 
        f = fopen(filename, "r");
        char buf[MAXLINE];
 
        f = fopen(filename, "r");
@@ -303,12 +337,42 @@ fileclass(class, filename, fmt)
        while (fgets(buf, sizeof buf, f) != NULL)
        {
                register STAB *s;
        while (fgets(buf, sizeof buf, f) != NULL)
        {
                register STAB *s;
+               register char *p;
+# ifdef SCANF
                char wordbuf[MAXNAME+1];
 
                if (sscanf(buf, fmt, wordbuf) != 1)
                        continue;
                char wordbuf[MAXNAME+1];
 
                if (sscanf(buf, fmt, wordbuf) != 1)
                        continue;
-               s = stab(wordbuf, ST_CLASS, ST_ENTER);
-               setbitn(class, s->s_class);
+               p = wordbuf;
+# else SCANF
+               p = buf;
+# endif SCANF
+
+               /*
+               **  Break up the match into words.
+               */
+
+               while (*p != '\0')
+               {
+                       register char *q;
+
+                       /* strip leading spaces */
+                       while (isspace(*p))
+                               p++;
+                       if (*p == '\0')
+                               break;
+
+                       /* find the end of the word */
+                       q = p;
+                       while (*p != '\0' && !isspace(*p))
+                               p++;
+                       if (*p != '\0')
+                               *p++ = '\0';
+
+                       /* enter the word in the symbol table */
+                       s = stab(q, ST_CLASS, ST_ENTER);
+                       setbitn(class, s->s_class);
+               }
        }
 
        (void) fclose(f);
        }
 
        (void) fclose(f);
@@ -555,8 +619,6 @@ makeargv(p)
 **             prints rewrite rules.
 */
 
 **             prints rewrite rules.
 */
 
-# ifdef DEBUG
-
 printrules()
 {
        register struct rewrite *rwp;
 printrules()
 {
        register struct rewrite *rwp;
@@ -578,13 +640,15 @@ printrules()
        }
 }
 
        }
 }
 
-# endif DEBUG
 \f/*
 **  SETOPTION -- set global processing option
 **
 **     Parameters:
 **             opt -- option name.
 **             val -- option value (as a text string).
 \f/*
 **  SETOPTION -- set global processing option
 **
 **     Parameters:
 **             opt -- option name.
 **             val -- option value (as a text string).
+**             safe -- set if this came from a configuration file.
+**                     Some options (if set from the command line) will
+**                     reset the user id to avoid security problems.
 **             sticky -- if set, don't let other setoptions override
 **                     this value.
 **
 **             sticky -- if set, don't let other setoptions override
 **                     this value.
 **
@@ -596,12 +660,12 @@ printrules()
 */
 
 static BITMAP  StickyOpt;              /* set if option is stuck */
 */
 
 static BITMAP  StickyOpt;              /* set if option is stuck */
-extern char    *WizWord;               /* the stored wizard password */
 extern char    *NetName;               /* name of home (local) network */
 
 extern char    *NetName;               /* name of home (local) network */
 
-setoption(opt, val, sticky)
+setoption(opt, val, safe, sticky)
        char opt;
        char *val;
        char opt;
        char *val;
+       bool safe;
        bool sticky;
 {
        extern bool atobool();
        bool sticky;
 {
        extern bool atobool();
@@ -611,10 +675,8 @@ setoption(opt, val, sticky)
        extern bool trusteduser();
        extern char *username();
 
        extern bool trusteduser();
        extern char *username();
 
-# ifdef DEBUG
        if (tTd(37, 1))
                printf("setoption %c=%s", opt, val);
        if (tTd(37, 1))
                printf("setoption %c=%s", opt, val);
-# endif DEBUG
 
        /*
        **  See if this option is preset for us.
 
        /*
        **  See if this option is preset for us.
@@ -622,17 +684,33 @@ setoption(opt, val, sticky)
 
        if (bitnset(opt, StickyOpt))
        {
 
        if (bitnset(opt, StickyOpt))
        {
-# ifdef DEBUG
                if (tTd(37, 1))
                        printf(" (ignored)\n");
                if (tTd(37, 1))
                        printf(" (ignored)\n");
-# endif DEBUG
                return;
        }
 
                return;
        }
 
-#ifdef DEBUG
-       if (tTd(37, 1))
+       /*
+       **  Check to see if this option can be specified by this user.
+       */
+
+       if (!safe && getuid() == 0)
+               safe = TRUE;
+       if (!safe && index("deiLmorsv", opt) == NULL)
+       {
+               if (opt != 'M' || (val[0] != 'r' && val[0] != 's'))
+               {
+                       if (tTd(37, 1))
+                               printf(" (unsafe)");
+                       if (getuid() != geteuid())
+                       {
+                               printf("(Resetting uid)\n");
+                               (void) setgid(getgid());
+                               (void) setuid(getuid());
+                       }
+               }
+       }
+       else if (tTd(37, 1))
                printf("\n");
                printf("\n");
-#endif DEBUG
 
        switch (opt)
        {
 
        switch (opt)
        {
@@ -660,6 +738,10 @@ setoption(opt, val, sticky)
                NoConnect = atobool(val);
                break;
 
                NoConnect = atobool(val);
                break;
 
+         case 'C':             /* checkpoint after N connections */
+               CheckPointLimit = atoi(val);
+               break;
+
          case 'd':             /* delivery mode */
                switch (*val)
                {
          case 'd':             /* delivery mode */
                switch (*val)
                {
@@ -723,10 +805,18 @@ setoption(opt, val, sticky)
                        HelpFile = newstr(val);
                break;
 
                        HelpFile = newstr(val);
                break;
 
+         case 'I':             /* use internet domain name server */
+               UseNameServer = atobool(val);
+               break;
+
          case 'i':             /* ignore dot lines in message */
                IgnrDot = atobool(val);
                break;
 
          case 'i':             /* ignore dot lines in message */
                IgnrDot = atobool(val);
                break;
 
+         case 'k':             /* checkpoint every N addresses */
+               CheckpointInterval = atoi(val);
+               break;
+
          case 'L':             /* log level */
                LogLevel = atoi(val);
                break;
          case 'L':             /* log level */
                LogLevel = atoi(val);
                break;
@@ -740,6 +830,10 @@ setoption(opt, val, sticky)
                MeToo = atobool(val);
                break;
 
                MeToo = atobool(val);
                break;
 
+         case 'n':             /* validate RHS in newaliases */
+               CheckAliases = atobool(val);
+               break;
+
 # ifdef DAEMON
          case 'N':             /* home (local?) network name */
                NetName = newstr(val);
 # ifdef DAEMON
          case 'N':             /* home (local?) network name */
                NetName = newstr(val);
@@ -753,6 +847,14 @@ setoption(opt, val, sticky)
                        CurEnv->e_flags &= ~EF_OLDSTYLE;
                break;
 
                        CurEnv->e_flags &= ~EF_OLDSTYLE;
                break;
 
+         case 'P':             /* postmaster copy address for returned mail */
+               PostMasterCopy = newstr(val);
+               break;
+
+         case 'q':             /* slope of queue only function */
+               QueueFactor = atoi(val);
+               break;
+
          case 'Q':             /* queue directory */
                if (val[0] == '\0')
                        QueueDir = "mqueue";
          case 'Q':             /* queue directory */
                if (val[0] == '\0')
                        QueueDir = "mqueue";
@@ -777,33 +879,20 @@ setoption(opt, val, sticky)
 
          case 'T':             /* queue timeout */
                TimeOut = convtime(val);
 
          case 'T':             /* queue timeout */
                TimeOut = convtime(val);
-               break;
+               /*FALLTHROUGH*/
 
          case 't':             /* time zone name */
 
          case 't':             /* time zone name */
-# ifdef V6
-               StdTimezone = newstr(val);
-               DstTimezone = index(StdTimeZone, ',');
-               if (DstTimezone == NULL)
-                       syserr("bad time zone spec");
-               else
-                       *DstTimezone++ = '\0';
-# endif V6
                break;
 
          case 'u':             /* set default uid */
                DefUid = atoi(val);
                break;
 
          case 'u':             /* set default uid */
                DefUid = atoi(val);
+               setdefuser();
                break;
 
          case 'v':             /* run in verbose mode */
                Verbose = atobool(val);
                break;
 
                break;
 
          case 'v':             /* run in verbose mode */
                Verbose = atobool(val);
                break;
 
-# ifdef DEBUG
-         case 'W':             /* set the wizards password */
-               WizWord = newstr(val);
-               break;
-# endif DEBUG
-
          case 'x':             /* load avg at which to auto-queue msgs */
                QueueLA = atoi(val);
                break;
          case 'x':             /* load avg at which to auto-queue msgs */
                QueueLA = atoi(val);
                break;
@@ -812,6 +901,22 @@ setoption(opt, val, sticky)
                RefuseLA = atoi(val);
                break;
 
                RefuseLA = atoi(val);
                break;
 
+         case 'y':             /* work recipient factor */
+               WkRecipFact = atoi(val);
+               break;
+
+         case 'Y':             /* fork jobs during queue runs */
+               ForkQueueRuns = atobool(val);
+               break;
+
+         case 'z':             /* work message class factor */
+               WkClassFact = atoi(val);
+               break;
+
+         case 'Z':             /* work time factor */
+               WkTimeFact = atoi(val);
+               break;
+
          default:
                break;
        }
          default:
                break;
        }