BSD 4_4 release
[unix-history] / usr / src / usr.sbin / sendmail / src / main.c
index 8aa34ff..5027aeb 100644 (file)
@@ -1,25 +1,50 @@
 /*
  * Copyright (c) 1983 Eric P. Allman
 /*
  * Copyright (c) 1983 Eric P. Allman
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1988, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * %sccs.include.redist.c%
+ * 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
  */
 
 #ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1988 Regents of the University of California.\n\
- All rights reserved.\n";
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
      The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)main.c     6.51 (Berkeley) %G%";
+static char sccsid[] = "@(#)main.c     8.1 (Berkeley) 6/7/93";
 #endif /* not lint */
 
 #define        _DEFINE
 
 #include "sendmail.h"
 #endif /* not lint */
 
 #define        _DEFINE
 
 #include "sendmail.h"
-#include <sys/stat.h>
 #include <signal.h>
 #include <sgtty.h>
 #ifdef NAMED_BIND
 #include <signal.h>
 #include <sgtty.h>
 #ifdef NAMED_BIND
@@ -73,6 +98,7 @@ ADDRESS               NullAddress =   /* a null address */
                { "", "", NULL, "" };
 char           *UserEnviron[MAXUSERENVIRON + 1];
                                /* saved user environment */
                { "", "", NULL, "" };
 char           *UserEnviron[MAXUSERENVIRON + 1];
                                /* saved user environment */
+char           RealUserName[256];      /* the actual user id on this host */
 
 /*
 **  Pointers for setproctitle.
 
 /*
 **  Pointers for setproctitle.
@@ -104,7 +130,6 @@ main(argc, argv, envp)
        register char *p;
        register char *q;
        char **av;
        register char *p;
        register char *q;
        char **av;
-       char *locname;
        extern int finis();
        extern char Version[];
        char *ep, *from;
        extern int finis();
        extern char Version[];
        char *ep, *from;
@@ -120,17 +145,15 @@ main(argc, argv, envp)
        char *argv0 = argv[0];
        struct passwd *pw;
        struct stat stb;
        char *argv0 = argv[0];
        struct passwd *pw;
        struct stat stb;
-       char realuser[256];
        char jbuf[MAXHOSTNAMELEN];      /* holds MyHostName */
        extern int DtableSize;
        extern int optind;
        extern time_t convtime();
        extern putheader(), putbody();
        char jbuf[MAXHOSTNAMELEN];      /* holds MyHostName */
        extern int DtableSize;
        extern int optind;
        extern time_t convtime();
        extern putheader(), putbody();
-       extern ENVELOPE *newenvelope();
        extern void intsig();
        extern char **myhostname();
        extern char *arpadate();
        extern void intsig();
        extern char **myhostname();
        extern char *arpadate();
-       extern char *getrealhostname();
+       extern char *getauthinfo();
        extern char *optarg;
        extern char **environ;
 
        extern char *optarg;
        extern char **environ;
 
@@ -146,8 +169,6 @@ main(argc, argv, envp)
                abort();
        }
        reenter = TRUE;
                abort();
        }
        reenter = TRUE;
-       extern ADDRESS *recipient();
-       bool canrename;
 
 #ifndef SYS5TZ
        /* enforce use of kernel-supplied time zone information */
 
 #ifndef SYS5TZ
        /* enforce use of kernel-supplied time zone information */
@@ -192,8 +213,8 @@ main(argc, argv, envp)
        BlankEnvelope.e_putbody = putbody;
        BlankEnvelope.e_xfp = NULL;
        STRUCTCOPY(NullAddress, BlankEnvelope.e_from);
        BlankEnvelope.e_putbody = putbody;
        BlankEnvelope.e_xfp = NULL;
        STRUCTCOPY(NullAddress, BlankEnvelope.e_from);
-       STRUCTCOPY(BlankEnvelope, MainEnvelope);
-       CurEnv = &MainEnvelope;
+       CurEnv = &BlankEnvelope;
+       STRUCTCOPY(NullAddress, MainEnvelope.e_from);
 
        /*
        **  Set default values for variables.
 
        /*
        **  Set default values for variables.
@@ -207,9 +228,9 @@ main(argc, argv, envp)
 
        pw = getpwuid(RealUid);
        if (pw != NULL)
 
        pw = getpwuid(RealUid);
        if (pw != NULL)
-               (void) strcpy(realuser, pw->pw_name);
+               (void) strcpy(RealUserName, pw->pw_name);
        else
        else
-               (void) sprintf(realuser, "Unknown UID %d", RealUid);
+               (void) sprintf(RealUserName, "Unknown UID %d", RealUid);
 
        /* Handle any non-getoptable constructions. */
        obsolete(argv);
 
        /* Handle any non-getoptable constructions. */
        obsolete(argv);
@@ -223,9 +244,9 @@ main(argc, argv, envp)
        */
        nothaw = FALSE;
 #ifdef __osf__
        */
        nothaw = FALSE;
 #ifdef __osf__
-#define OPTIONS                "b:C:cd:e:F:f:h:Iimno:p:q:r:sTtvx"
+#define OPTIONS                "B:b:C:cd:e:F:f:h:Iimno:p:q:r:sTtvx"
 #else
 #else
-#define OPTIONS                "b:C:cd:e:F:f:h:Iimno:p:q:r:sTtv"
+#define OPTIONS                "B:b:C:cd:e:F:f:h:Iimno:p:q:r:sTtv"
 #endif
        while ((j = getopt(argc, argv, OPTIONS)) != EOF)
        {
 #endif
        while ((j = getopt(argc, argv, OPTIONS)) != EOF)
        {
@@ -299,6 +320,11 @@ main(argc, argv, envp)
        OpMode = MD_DELIVER;
        FullName = getenv("NAME");
 
        OpMode = MD_DELIVER;
        FullName = getenv("NAME");
 
+#ifdef NAMED_BIND
+       if (tTd(8, 8))
+               _res.options |= RES_DEBUG;
+#endif
+
        errno = 0;
        from = NULL;
 
        errno = 0;
        from = NULL;
 
@@ -316,7 +342,6 @@ main(argc, argv, envp)
        if (jbuf[0] != '\0')
        {
                struct  utsname utsname;
        if (jbuf[0] != '\0')
        {
                struct  utsname utsname;
-               extern char *strchr();
 
                if (tTd(0, 4))
                        printf("canonical name: %s\n", jbuf);
 
                if (tTd(0, 4))
                        printf("canonical name: %s\n", jbuf);
@@ -360,11 +385,8 @@ main(argc, argv, envp)
        **  Find our real host name for future logging.
        */
 
        **  Find our real host name for future logging.
        */
 
-       p = getrealhostname(STDIN_FILENO);
-       if (p != NULL)
-               RealHostName = newstr(p);
-       else
-               RealHostName = "localhost";
+       p = getauthinfo(STDIN_FILENO);
+       define('_', p, CurEnv);
 
        /*
        ** Crack argv.
 
        /*
        ** Crack argv.
@@ -432,11 +454,15 @@ main(argc, argv, envp)
                        }
                        break;
 
                        }
                        break;
 
+                 case 'B':     /* body type */
+                       CurEnv->e_bodytype = newstr(optarg);
+                       break;
+
                  case 'C':     /* select configuration file (already done) */
                        if (getuid() != 0)
                                auth_warning(CurEnv,
                                        "Processed by %s with -C %s",
                  case 'C':     /* select configuration file (already done) */
                        if (getuid() != 0)
                                auth_warning(CurEnv,
                                        "Processed by %s with -C %s",
-                                       realuser, optarg);
+                                       RealUserName, optarg);
                        break;
 
                  case 'd':     /* debugging -- redo in case frozen */
                        break;
 
                  case 'd':     /* debugging -- redo in case frozen */
@@ -454,10 +480,10 @@ main(argc, argv, envp)
                                break;
                        }
                        from = newstr(optarg);
                                break;
                        }
                        from = newstr(optarg);
-                       if (strcmp(realuser, from) != 0)
+                       if (strcmp(RealUserName, from) != 0)
                                auth_warning(CurEnv,
                                        "%s set sender to %s using -%c",
                                auth_warning(CurEnv,
                                        "%s set sender to %s using -%c",
-                                       realuser, from, j);
+                                       RealUserName, from, j);
                        break;
 
                  case 'F':     /* set full name */
                        break;
 
                  case 'F':     /* set full name */
@@ -561,11 +587,6 @@ main(argc, argv, envp)
        }
        av += optind;
 
        }
        av += optind;
 
-#ifdef NAMED_BIND
-       if (tTd(8, 8))
-               _res.options |= RES_DEBUG;
-#endif
-
        /*
        **  Do basic initialization.
        **      Read system control file.
        /*
        **  Do basic initialization.
        **      Read system control file.
@@ -636,7 +657,7 @@ main(argc, argv, envp)
                if (RealUid != 0)
                        auth_warning(CurEnv,
                                "%s owned process doing -bs",
                if (RealUid != 0)
                        auth_warning(CurEnv,
                                "%s owned process doing -bs",
-                               realuser);
+                               RealUserName);
                break;
        }
 
                break;
        }
 
@@ -710,7 +731,7 @@ main(argc, argv, envp)
 
          case MD_INITALIAS:
                /* initialize alias database */
 
          case MD_INITALIAS:
                /* initialize alias database */
-               initaliases(AliasFile, TRUE, CurEnv);
+               initmaps(TRUE, CurEnv);
                exit(EX_OK);
 
          case MD_DAEMON:
                exit(EX_OK);
 
          case MD_DAEMON:
@@ -719,7 +740,7 @@ main(argc, argv, envp)
 
          default:
                /* open the alias database */
 
          default:
                /* open the alias database */
-               initaliases(AliasFile, FALSE, CurEnv);
+               initmaps(FALSE, CurEnv);
                break;
        }
 
                break;
        }
 
@@ -812,7 +833,6 @@ main(argc, argv, envp)
                                continue;
                        do
                        {
                                continue;
                        do
                        {
-                               extern char **prescan();
                                char pvpbuf[PSBUFSIZE];
 
                                pvp = prescan(++p, ',', pvpbuf, &delimptr);
                                char pvpbuf[PSBUFSIZE];
 
                                pvp = prescan(++p, ',', pvpbuf, &delimptr);
@@ -821,7 +841,12 @@ main(argc, argv, envp)
                                p = q;
                                while (*p != '\0')
                                {
                                p = q;
                                while (*p != '\0')
                                {
-                                       rewrite(pvp, atoi(p));
+                                       int stat;
+
+                                       stat = rewrite(pvp, atoi(p), CurEnv);
+                                       if (stat != EX_OK)
+                                               printf("== Ruleset %s status %d\n",
+                                                       p, stat);
                                        while (*p != '\0' && *p++ != ',')
                                                continue;
                                }
                                        while (*p != '\0' && *p++ != ',')
                                                continue;
                                }
@@ -872,15 +897,16 @@ main(argc, argv, envp)
                        strcat(dtype, "+SMTP");
                if (QueueIntvl != 0)
                {
                        strcat(dtype, "+SMTP");
                if (QueueIntvl != 0)
                {
-                       extern char *pintvl();
-
                        strcat(dtype, "+queueing@");
                        strcat(dtype, pintvl(QueueIntvl, TRUE));
                }
                if (tTd(0, 1))
                        strcat(dtype, "+debugging");
 
                        strcat(dtype, "+queueing@");
                        strcat(dtype, pintvl(QueueIntvl, TRUE));
                }
                if (tTd(0, 1))
                        strcat(dtype, "+debugging");
 
-               syslog(LOG_INFO, "starting daemon: %s", dtype + 1);
+               syslog(LOG_INFO, "starting daemon (%s): %s", Version, dtype + 1);
+#ifdef XLA
+               xla_create_file();
+#endif
 
 # ifdef QUEUE
                if (queuemode)
 
 # ifdef QUEUE
                if (queuemode)
@@ -897,8 +923,15 @@ main(argc, argv, envp)
                getrequests();
 
                /* at this point we are in a child: reset state */
                getrequests();
 
                /* at this point we are in a child: reset state */
-               OpMode = MD_SMTP;
                (void) newenvelope(CurEnv, CurEnv);
                (void) newenvelope(CurEnv, CurEnv);
+
+               /*
+               **  Get authentication data
+               */
+
+               p = getauthinfo(fileno(InChannel));
+               define('_', p, CurEnv);
+
 #endif /* DAEMON */
        }
        
 #endif /* DAEMON */
        }
        
@@ -916,13 +949,19 @@ main(argc, argv, envp)
        **  Do basic system initialization and set the sender
        */
 
        **  Do basic system initialization and set the sender
        */
 
-# ifndef SYSTEM5
        /* make sendmail immune from process group signals */
        /* make sendmail immune from process group signals */
+# ifdef _POSIX_JOB_CONTROL
+       (void) setpgid(0, getpid());
+# else
+# ifndef SYSTEM5
        (void) setpgrp(0, getpid());
        (void) setpgrp(0, getpid());
+# endif
 # endif
 
        initsys(CurEnv);
        setsender(from, CurEnv, NULL, FALSE);
 # endif
 
        initsys(CurEnv);
        setsender(from, CurEnv, NULL, FALSE);
+       if (macvalue('s', CurEnv) == NULL)
+               define('s', RealHostName, CurEnv);
 
        if (*av == NULL && !GrabTo)
        {
 
        if (*av == NULL && !GrabTo)
        {
@@ -934,7 +973,10 @@ main(argc, argv, envp)
                finis();
        }
        if (OpMode == MD_VERIFY)
                finis();
        }
        if (OpMode == MD_VERIFY)
+       {
                CurEnv->e_sendmode = SM_VERIFY;
                CurEnv->e_sendmode = SM_VERIFY;
+               CurEnv->e_errormode = EM_QUIET;
+       }
 
        /*
        **  Scan argv and deliver the message to everyone.
 
        /*
        **  Scan argv and deliver the message to everyone.
@@ -977,7 +1019,8 @@ main(argc, argv, envp)
        sendall(CurEnv, SM_DEFAULT);
 
        /*
        sendall(CurEnv, SM_DEFAULT);
 
        /*
-       ** All done.
+       **  All done.
+       **      Don't send return error message if in VERIFY mode.
        */
 
        finis();
        */
 
        finis();
@@ -1010,6 +1053,11 @@ finis()
        /* post statistics */
        poststats(StatFile);
 
        /* post statistics */
        poststats(StatFile);
 
+# ifdef XLA
+       /* clean up extended load average stuff */
+       xla_all_end();
+# endif
+
        /* and exit */
 # ifdef LOG
        if (LogLevel > 78)
        /* and exit */
 # ifdef LOG
        if (LogLevel > 78)
@@ -1040,6 +1088,9 @@ intsig()
 {
        FileName = NULL;
        unlockqueue(CurEnv);
 {
        FileName = NULL;
        unlockqueue(CurEnv);
+#ifdef XLA
+       xla_all_end();
+#endif
        exit(EX_OK);
 }
 \f/*
        exit(EX_OK);
 }
 \f/*
@@ -1067,15 +1118,17 @@ struct metamac  MetaMacros[] =
        /* these are RHS metasymbols */
        '#', CANONNET,          '@', CANONHOST,         ':', CANONUSER,
        '>', CALLSUBR,
        /* these are RHS metasymbols */
        '#', CANONNET,          '@', CANONHOST,         ':', CANONUSER,
        '>', CALLSUBR,
-       '{', MATCHLOOKUP,               '}', MATCHELOOKUP,
 
        /* the conditional operations */
        '?', CONDIF,            '|', CONDELSE,          '.', CONDFI,
 
 
        /* the conditional operations */
        '?', CONDIF,            '|', CONDELSE,          '.', CONDFI,
 
-       /* and finally the hostname lookup characters */
+       /* the hostname lookup characters */
        '[', HOSTBEGIN,         ']', HOSTEND,
        '(', LOOKUPBEGIN,       ')', LOOKUPEND,
 
        '[', HOSTBEGIN,         ']', HOSTEND,
        '(', LOOKUPBEGIN,       ')', LOOKUPEND,
 
+       /* miscellaneous control characters */
+       '&', MACRODEXPAND,
+
        '\0'
 };
 
        '\0'
 };
 
@@ -1203,7 +1256,6 @@ thaw(freezefile, binfile)
        extern char edata, end;
        extern char Version[];
        extern char **myhostname();
        extern char edata, end;
        extern char Version[];
        extern char **myhostname();
-       extern char *macvalue();
        extern BRK_TYPE brk();
 
        if (freezefile == NULL)
        extern BRK_TYPE brk();
 
        if (freezefile == NULL)
@@ -1353,11 +1405,7 @@ disconnect(fulldrop, e)
        /* drop our controlling TTY completely if possible */
        if (fulldrop)
        {
        /* drop our controlling TTY completely if possible */
        if (fulldrop)
        {
-#ifdef SYSTEM5
-               (void) setpgrp();
-#else
                (void) setsid();
                (void) setsid();
-#endif
 #ifdef TIOCNOTTY
                fd = open("/dev/tty", 2);
                if (fd >= 0)
 #ifdef TIOCNOTTY
                fd = open("/dev/tty", 2);
                if (fd >= 0)
@@ -1384,7 +1432,7 @@ obsolete(argv)
 {
        char *ap;
 
 {
        char *ap;
 
-       while (ap = *++argv)
+       while ((ap = *++argv) != NULL)
        {
                /* Return if "--" or not an option of any form. */
                if (ap[0] != '-' || ap[1] == '-')
        {
                /* Return if "--" or not an option of any form. */
                if (ap[0] != '-' || ap[1] == '-')
@@ -1426,11 +1474,11 @@ obsolete(argv)
 
 void
 #ifdef __STDC__
 
 void
 #ifdef __STDC__
-auth_warning(register ENVELOPE *e, char *msg, ...)
+auth_warning(register ENVELOPE *e, const char *msg, ...)
 #else
 auth_warning(e, msg, va_alist)
        register ENVELOPE *e;
 #else
 auth_warning(e, msg, va_alist)
        register ENVELOPE *e;
-       char *msg;
+       const char *msg;
        va_dcl
 #endif
 {
        va_dcl
 #endif
 {
@@ -1451,6 +1499,6 @@ auth_warning(e, msg, va_alist)
                VA_START(msg);
                vsprintf(p, msg, ap);
                VA_END;
                VA_START(msg);
                vsprintf(p, msg, ap);
                VA_END;
-               addheader("x-authentication-warning", buf, e);
+               addheader("X-Authentication-Warning", buf, e);
        }
 }
        }
 }