clean up implementation if you don't have getusershell(3) in libc
authorEric Allman <eric@ucbvax.Berkeley.EDU>
Sun, 26 Dec 1993 22:07:57 +0000 (14:07 -0800)
committerEric Allman <eric@ucbvax.Berkeley.EDU>
Sun, 26 Dec 1993 22:07:57 +0000 (14:07 -0800)
SCCS-vsn: usr.sbin/sendmail/src/READ_ME 8.43
SCCS-vsn: usr.sbin/sendmail/src/recipient.c 8.33
SCCS-vsn: usr.sbin/sendmail/src/conf.h 8.69
SCCS-vsn: usr.sbin/sendmail/src/conf.c 8.56
SCCS-vsn: usr.sbin/sendmail/src/sendmail.h 8.37

usr/src/usr.sbin/sendmail/src/READ_ME
usr/src/usr.sbin/sendmail/src/conf.c
usr/src/usr.sbin/sendmail/src/conf.h
usr/src/usr.sbin/sendmail/src/recipient.c
usr/src/usr.sbin/sendmail/src/sendmail.h

index de1c8af..cb965b4 100644 (file)
@@ -4,7 +4,7 @@
 #
 # %sccs.include.redist.sh%
 #
 #
 # %sccs.include.redist.sh%
 #
-#      @(#)READ_ME     8.42 (Berkeley) %G%
+#      @(#)READ_ME     8.43 (Berkeley) %G%
 #
 
 This directory contains the source files for sendmail.
 #
 
 This directory contains the source files for sendmail.
@@ -185,15 +185,13 @@ NEEDVPRINTF       Define this if your standard C library does not define
                vprintf(3).  Note that the resulting fake implementation
                is not very elegant and may not even work on some
                architectures.
                vprintf(3).  Note that the resulting fake implementation
                is not very elegant and may not even work on some
                architectures.
-NEEDGETUSERSHELL
-               Define this to 1 if you do not have getusershell(3) in
-               your standard C library.  This will cause inclusion of
-               a getusershell implementation that looks in /etc/shells
-               (no NIS-style support) and defaults to /bin/sh and
-               /bin/csh if that file does not exist.  You can #define
-               this to 0 to force it to believe that getusershell(3)
-               does exist in the C library (for example, for SVR4
-               systems that have BSD extensions, such as Solaris 2.x).
+HASGETUSERSHELL        Define this to 1 if you have getusershell(3) in your
+               standard C library.  If this is not defined, or is defined
+               to be 0, sendmail will scan the /etc/shells file (no
+               NIS-style support, defaults to /bin/sh and /bin/csh if
+               that file does not exist) to get a list of unrestricted
+               user shells.  This is used to determine whether users
+               are allowed to forward their mail to a program or a file.
 GIDSET_T       The type of entries in a gidset passed as the second
                argument to getgroups(2).  Historically this has been an
                int, so this is the default, but some systems (such as
 GIDSET_T       The type of entries in a gidset passed as the second
                argument to getgroups(2).  Historically this has been an
                int, so this is the default, but some systems (such as
@@ -680,4 +678,4 @@ version.c   The version number and information about this
 
 Eric Allman
 
 
 Eric Allman
 
-(Version 8.42, last update %G% 10:11:59)
+(Version 8.43, last update %G% 06:07:47)
index abf9c71..7be8439 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)conf.c     8.55 (Berkeley) %G%";
+static char sccsid[] = "@(#)conf.c     8.56 (Berkeley) %G%";
 #endif /* not lint */
 
 # include "sendmail.h"
 #endif /* not lint */
 
 # include "sendmail.h"
@@ -1344,150 +1344,75 @@ vsprintf(s, fmt, ap)
 
 #endif
 \f/*
 
 #endif
 \f/*
-**  {GET,SET,END}USERSHELL -- getusershell(3) implementation
+**  usershellok -- tell if a user's shell is ok for unrestricted use
 **
 **
-**     Grabbed from 4.4BSD source tree.
+**     Parameters:
+**             shell -- the user's shell from /etc/passwd
+**
+**     Returns:
+**             TRUE -- if it is ok to use this for unrestricted access.
+**             FALSE -- if the shell is restricted.
 */
 
 */
 
-#if NEEDGETUSERSHELL
-
-/*
- * Copyright (c) 1985, 1993
- *     The 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.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getusershell.c     8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * Local shells should NOT be added here.  They should be added in
- * /etc/shells.
- */
-
+#ifndef _PATH_SHELLS
+# define _PATH_SHELLS  "/etc/shells"
+#endif
 #ifndef _PATH_BSHELL
 # define _PATH_BSHELL  "/bin/sh"
 #endif
 #ifndef _PATH_CSHELL
 # define _PATH_CSHELL  "/bin/csh"
 #endif
 #ifndef _PATH_BSHELL
 # define _PATH_BSHELL  "/bin/sh"
 #endif
 #ifndef _PATH_CSHELL
 # define _PATH_CSHELL  "/bin/csh"
 #endif
-#ifndef _PATH_SHELLS
-# define _PATH_SHELLS  "/etc/shells"
-#endif
-
-static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
-static char **curshell, **shells, *strings;
-static char **initshells __P((void));
-
-/*
- * Get a list of shells from _PATH_SHELLS, if it exists.
- */
-char *
-getusershell()
-{
-       char *ret;
-
-       if (curshell == NULL)
-               curshell = initshells();
-       ret = *curshell;
-       if (ret != NULL)
-               curshell++;
-       return (ret);
-}
 
 
-void
-endusershell()
+bool
+usershellok(shell)
+       char *shell;
 {
 {
-       if (shells != NULL)
-               free(shells);
-       shells = NULL;
-       if (strings != NULL)
-               free(strings);
-       strings = NULL;
-       curshell = NULL;
-}
+#if HASGETUSERSHELL
+       register char *p;
+       extern char *getusershell();
 
 
-void
-setusershell()
-{
-       curshell = initshells();
-}
+       setusershell();
+       while ((p = getusershell()) != NULL)
+               if (strcmp(p, shell) == 0)
+                       break;
+       endusershell();
+       return p != NULL;
+#else
+       register FILE *shellf;
+       char buf[MAXLINE];
 
 
-static char **
-initshells()
-{
-       register char **sp, *cp;
-       register FILE *fp;
-       struct stat statb;
-
-       if (shells != NULL)
-               free(shells);
-       shells = NULL;
-       if (strings != NULL)
-               free(strings);
-       strings = NULL;
-       if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
-               return (okshells);
-       if (fstat(fileno(fp), &statb) == -1) {
-               (void)fclose(fp);
-               return (okshells);
-       }
-       if ((strings = malloc((u_int)statb.st_size)) == NULL) {
-               (void)fclose(fp);
-               return (okshells);
-       }
-       shells = calloc((unsigned)statb.st_size / 3, sizeof (char *));
-       if (shells == NULL) {
-               (void)fclose(fp);
-               free(strings);
-               strings = NULL;
-               return (okshells);
+       shellf = fopen(_PATH_SHELLS, "r");
+       if (shellf == NULL)
+       {
+               /* no /etc/shells; see if it is one of the std shells */
+               return (strcmp(shell, _PATH_CSHELL) == 0 ||
+                       strcmp(shell, _PATH_BSHELL) == 0);
        }
        }
-       sp = shells;
-       cp = strings;
-       while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
-               while (*cp != '#' && *cp != '/' && *cp != '\0')
-                       cp++;
-               if (*cp == '#' || *cp == '\0')
+
+       while (fgets(buf, sizeof buf, shellf) != NULL)
+       {
+               register char *p, *q;
+
+               p = buf;
+               while (*p != '\0' && *p != '#' && *p != '/')
+                       p++;
+               if (*p == '#' || *p == '\0')
                        continue;
                        continue;
-               *sp++ = cp;
-               while (!isspace(*cp) && *cp != '#' && *cp != '\0')
-                       cp++;
-               *cp++ = '\0';
+               q = p;
+               while (*p != '\0' && *p != '#' && !isspace(*p))
+                       p++;
+               *p = '\0';
+               if (strcmp(shell, q) == 0)
+               {
+                       fclose(shellf);
+                       return TRUE;
+               }
        }
        }
-       *sp = NULL;
-       (void)fclose(fp);
-       return (shells);
-}
+       fclose(shellf);
+       return FALSE;
 #endif
 #endif
+}
 \f/*
 **  FREESPACE -- see how much free space is on the queue filesystem
 **
 \f/*
 **  FREESPACE -- see how much free space is on the queue filesystem
 **
index efc4749..5fe8094 100644 (file)
@@ -5,7 +5,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)conf.h      8.68 (Berkeley) %G%
+ *     @(#)conf.h      8.69 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
 # define HASINITGROUPS 1       /* has initgroups(3) call */
 # define HASSTATFS     1       /* has the statfs(2) syscall */
 # define HASUNAME      1       /* use System V uname(2) system call */
 # define HASINITGROUPS 1       /* has initgroups(3) call */
 # define HASSTATFS     1       /* has the statfs(2) syscall */
 # define HASUNAME      1       /* use System V uname(2) system call */
-# define NEEDGETUSERSHELL 1    /* needs getusershell(3) implementation */
+# define HASGETUSERSHELL 0     /* does not have getusershell(3) call */
 # define FORK          fork    /* no vfork primitive available */
 # undef  SETPROCTITLE          /* setproctitle confuses AIX */
 # endif
 # define FORK          fork    /* no vfork primitive available */
 # undef  SETPROCTITLE          /* setproctitle confuses AIX */
 # endif
 # define HASSETREUID   1       /* has setreuid(2) call */
 # define HASINITGROUPS 1       /* has initgroups(3) call */
 # define HASSTATFS     1       /* has the statfs(2) syscall */
 # define HASSETREUID   1       /* has setreuid(2) call */
 # define HASINITGROUPS 1       /* has initgroups(3) call */
 # define HASSTATFS     1       /* has the statfs(2) syscall */
-# define NEEDGETUSERSHELL 1    /* needs getusershell(3) implementation */
+# define HASGETUSERSHELL 0     /* does not have getusershell(3) call */
 # define FORK          fork    /* no vfork primitive available */
 # define WAITUNION     1       /* use "union wait" as wait argument type */
 # define setpgid       BSDsetpgrp
 # define FORK          fork    /* no vfork primitive available */
 # define WAITUNION     1       /* use "union wait" as wait argument type */
 # define setpgid       BSDsetpgrp
 # define LA_TYPE       LA_INT
 # define HASINITGROUPS 1       /* has initgroups(3) call */
 # define HASUNAME      1       /* use System V uname(2) system call */
 # define LA_TYPE       LA_INT
 # define HASINITGROUPS 1       /* has initgroups(3) call */
 # define HASUNAME      1       /* use System V uname(2) system call */
-# define NEEDGETUSERSHELL 0    /* libc has getusershell(3) */
+# define HASGETUSERSHELL 1     /* DOES have getusershell(3) call in libc */
 
 # ifdef SOLARIS_2_3
 #  define SOLARIS
 
 # ifdef SOLARIS_2_3
 #  define SOLARIS
@@ -249,7 +249,7 @@ extern long dgux_inet_addr();
 # define HASUNSETENV   1       /* has unsetenv(3) call */
 # define HASINITGROUPS 1       /* has initgroups(3) call */
 # define HASFLOCK      1       /* has flock(2) call */
 # define HASUNSETENV   1       /* has unsetenv(3) call */
 # define HASINITGROUPS 1       /* has initgroups(3) call */
 # define HASFLOCK      1       /* has flock(2) call */
-# define NEEDGETUSERSHELL 1    /* needs getusershell(3) implementation */
+# define HASGETUSERSHELL 0     /* does not have getusershell(3) call */
 # ifdef vax
 #  define LA_TYPE      LA_FLOAT
 # else
 # ifdef vax
 #  define LA_TYPE      LA_FLOAT
 # else
@@ -555,7 +555,7 @@ extern void         *malloc();
 # define HASSTATFS     1       /* has the statfs(2) syscall */
 # define HASSETVBUF    1       /* we have setvbuf(3) in libc */
 # define HASINITGROUPS 1       /* has initgroups(3) call */
 # define HASSTATFS     1       /* has the statfs(2) syscall */
 # define HASSETVBUF    1       /* we have setvbuf(3) in libc */
 # define HASINITGROUPS 1       /* has initgroups(3) call */
-# define NEEDGETUSERSHELL 1    /* needs getusershell(3) implementation ??? */
+# define HASGETUSERSHELL 0     /* does not have getusershell(3) call */
 # define SYS5SIGNALS   1       /* SysV signal semantics -- reset on each sig */
 # define SYS5SETPGRP   1       /* use System V setpgrp(2) syscall */
 # define FORK          fork    /* no vfork(2) primitive available */
 # define SYS5SIGNALS   1       /* SysV signal semantics -- reset on each sig */
 # define SYS5SETPGRP   1       /* use System V setpgrp(2) syscall */
 # define FORK          fork    /* no vfork(2) primitive available */
@@ -643,8 +643,8 @@ typedef int         pid_t;
 #ifdef __svr4__
 # define SYSTEM5       1
 # define HASSETREUID   1       /* has seteuid(2) call & working saved uids */
 #ifdef __svr4__
 # define SYSTEM5       1
 # define HASSETREUID   1       /* has seteuid(2) call & working saved uids */
-# ifndef NEEDGETUSERSHELL
-#  define NEEDGETUSERSHELL 1   /* needs getusershell(3) implementation ??? */
+# ifndef HASGETUSERSHELL
+#  define HASGETUSERSHELL 0    /* does not have getusershell(3) call */
 # endif
 # define setreuid(r, e)        seteuid(e)
 
 # endif
 # define setreuid(r, e)        seteuid(e)
 
@@ -717,8 +717,8 @@ typedef int         pid_t;
 # define IDENTPROTO    1       /* use IDENT proto (RFC 1413) */
 #endif
 
 # define IDENTPROTO    1       /* use IDENT proto (RFC 1413) */
 #endif
 
-#ifndef NEEDGETUSERSHELL
-# define NEEDGETUSERSHELL 0    /* libc has getusershell(3) */
+#ifndef HASGETUSERSHELL
+# define HASGETUSERSHELL 1     /* libc has getusershell(3) call */
 #endif
 
 
 #endif
 
 
index fcad467..e7f7714 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)recipient.c        8.32 (Berkeley) %G%";
+static char sccsid[] = "@(#)recipient.c        8.33 (Berkeley) %G%";
 #endif /* not lint */
 
 # include "sendmail.h"
 #endif /* not lint */
 
 # include "sendmail.h"
@@ -474,17 +474,10 @@ recipient(a, sendq, e)
                        buildfname(pw->pw_gecos, pw->pw_name, nbuf);
                        if (nbuf[0] != '\0')
                                a->q_fullname = newstr(nbuf);
                        buildfname(pw->pw_gecos, pw->pw_name, nbuf);
                        if (nbuf[0] != '\0')
                                a->q_fullname = newstr(nbuf);
-                       if (pw->pw_shell != NULL && pw->pw_shell[0] != '\0')
+                       if (pw->pw_shell != NULL && pw->pw_shell[0] != '\0' &&
+                           !usershellok(pw->pw_shell))
                        {
                        {
-                               extern char *getusershell();
-
-                               setusershell();
-                               while ((p = getusershell()) != NULL)
-                                       if (strcmp(p, pw->pw_shell) == 0)
-                                               break;
-                               endusershell();
-                               if (p == NULL)
-                                       a->q_flags |= QBOGUSSHELL;
+                               a->q_flags |= QBOGUSSHELL;
                        }
                        if (!quoted)
                                forward(a, sendq, e);
                        }
                        if (!quoted)
                                forward(a, sendq, e);
index e5dac92..4f616f6 100644 (file)
@@ -5,7 +5,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)sendmail.h  8.36 (Berkeley) %G%
+ *     @(#)sendmail.h  8.37 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -15,7 +15,7 @@
 # ifdef _DEFINE
 # define EXTERN
 # ifndef lint
 # ifdef _DEFINE
 # define EXTERN
 # ifndef lint
-static char SmailSccsId[] =    "@(#)sendmail.h 8.36            %G%";
+static char SmailSccsId[] =    "@(#)sendmail.h 8.37            %G%";
 # endif
 # else /*  _DEFINE */
 # define EXTERN extern
 # endif
 # else /*  _DEFINE */
 # define EXTERN extern
@@ -936,6 +936,7 @@ extern void         openxscript __P((ENVELOPE *));
 extern void            closexscript __P((ENVELOPE *));
 extern sigfunc_t       setsignal __P((int, sigfunc_t));
 extern char            *shortenstring __P((char *, int));
 extern void            closexscript __P((ENVELOPE *));
 extern sigfunc_t       setsignal __P((int, sigfunc_t));
 extern char            *shortenstring __P((char *, int));
+extern bool            usershellok __P((char *));
 
 /* ellipsis is a different case though */
 #ifdef __STDC__
 
 /* ellipsis is a different case though */
 #ifdef __STDC__