Hi,

        Asbestos suit on, round two.

        The patch below changes getusershell to support a #include syntax
in /etc/shells. It is against RELENG_4 and may require a bit of fiddling
to apply to -current (because of nsdispatch()).

        Everything that I can find is using it (well adduser.perl has the
same support written in perl) including sendmail although I cannot see why
sendmail isn't using it's built in fallback code, but it isn't somewhere
I haven't found HASGETUSERSHELL is being set or assumed. I'm not looking
anymore.

        The changes are confined to adduser.perl, getusershell.c and shells.

        BTW: is there a reason for the avoidance of my in adduser.perl ?

Index: etc/shells
===================================================================
RCS file: /home/ncvs/src/etc/shells,v
retrieving revision 1.3.2.1
diff -u -r1.3.2.1 shells
--- etc/shells  2000/07/10 08:47:17     1.3.2.1
+++ etc/shells  2001/01/27 16:32:01
@@ -1,4 +1,4 @@
-# $FreeBSD: src/etc/shells,v 1.3.2.1 2000/07/10 08:47:17 obrien Exp $
+# $FreeBSD: src/etc/shells,v 1.3 1999/08/27 23:23:45 peter Exp $
 #
 # List of acceptable shells for chpass(1).
 # Ftpd will not allow users to connect who are not using
@@ -7,3 +7,4 @@
 /bin/sh
 /bin/csh
 /bin/tcsh
+#include /usr/local/etc/shells
Index: lib/libc/gen/getusershell.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/getusershell.c,v
retrieving revision 1.3
diff -u -r1.3 getusershell.c
--- lib/libc/gen/getusershell.c 1999/11/04 04:16:28     1.3
+++ lib/libc/gen/getusershell.c 2001/01/28 08:57:29
@@ -45,6 +45,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <paths.h>
+#include <string.h>
 
 /*
  * Local shells should NOT be added here.  They should be added in
@@ -52,8 +53,9 @@
  */
 
 static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
-static char **curshell, **shells, *strings;
+static char **curshell, **shells;
 static char **initshells __P((void));
+static int shellslots = 0;
 
 /*
  * Get a list of shells from _PATH_SHELLS, if it exists.
@@ -74,66 +76,87 @@
 void
 endusershell()
 {
-
-       if (shells != NULL)
+       char **sp;
+       if (shells != NULL) {
+               for (sp = shells; *sp; sp++) {
+                       free (*sp);
+               }
                free(shells);
+       }
        shells = NULL;
-       if (strings != NULL)
-               free(strings);
-       strings = NULL;
+       shellslots = 0;
        curshell = NULL;
 }
 
 void
 setusershell()
 {
-
        curshell = initshells();
 }
 
 static char **
-initshells()
+readshellfile (char *path)
 {
-       register char **sp, *cp;
        register FILE *fp;
-       struct stat statb;
+       static int sp;
+       register char *cp;
+       void *new;
+       char buf[MAXPATHLEN];
+       char *st;
+       int newslots;
 
-       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);
+       if (shellslots == 0) {
+               sp = 0;
        }
-       shells = calloc((unsigned)statb.st_size / 3, sizeof (char *));
-       if (shells == NULL) {
-               (void)fclose(fp);
-               free(strings);
-               strings = NULL;
-               return (okshells);
-       }
-       sp = shells;
-       cp = strings;
-       while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
+       if ((fp = fopen(path, "r")) == NULL)
+               return (NULL);
+       while (fgets(buf, MAXPATHLEN + 1, fp) != NULL) {
+               cp = buf;
                while (*cp != '#' && *cp != '/' && *cp != '\0')
                        cp++;
-               if (*cp == '#' || *cp == '\0')
+               if (*cp == '#' || *cp == '\0') {
+                       if (!strncmp (cp, "#include", 8)) {
+                               cp++;
+                               while (*cp != '#' && *cp != '/' && *cp != '\0')
+                                       cp++;
+                               if (*cp == '/') {
+                                       char *fn = cp;
+                                       while (!isspace((unsigned char)*cp) && *cp != 
+'#' && *cp != '\0')
+                                               cp++;
+                                       *cp++ = '\0';
+                                       readshellfile (fn);
+                               }
+                       }
                        continue;
-               *sp++ = cp;
+               }
+               if (sp >= (shellslots - 1)) {
+                       newslots = shellslots ? 2*shellslots : 8;
+                       new = realloc ((void *)shells, newslots * sizeof (char *));
+                       if (new == NULL) {
+                               shells[sp] = NULL;
+                               return shells;
+                       }
+                       shells = new;
+                       shellslots = newslots;
+               }
+               st = cp;
                while (!isspace((unsigned char)*cp) && *cp != '#' && *cp != '\0')
                        cp++;
                *cp++ = '\0';
+               shells[sp++] = strdup (st);
        }
-       *sp = NULL;
+       shells[sp] = NULL;
        (void)fclose(fp);
        return (shells);
+}
+
+static char **
+initshells()
+{
+       char **sp;
+       endusershell ();
+       if (!readshellfile (_PATH_SHELLS)) {
+               return (okshells);
+       }
+       return shells;
 }
Index: usr.sbin/adduser/adduser.perl
===================================================================
RCS file: /home/ncvs/src/usr.sbin/adduser/adduser.perl,v
retrieving revision 1.44
diff -u -r1.44 adduser.perl
--- usr.sbin/adduser/adduser.perl       1999/08/28 01:15:11     1.44
+++ usr.sbin/adduser/adduser.perl       2001/01/28 08:52:17
@@ -86,11 +86,26 @@
 
 # read shell database, see also: shells(5)
 sub shells_read {
-    local($sh);
     local($err) = 0;
+    shells_file_read ($etc_shells);
+
+    # Allow /nonexistent and /bin/date as a valid shell for system utils
+    push(@list, "/nonexistent");
+    push(@shellpref, "no") if !grep(/^no$/, @shellpref);
+    $shell{"no"} = "/nonexistent";
+
+    push(@list, "/bin/date");
+    push(@shellpref, "date") if !grep(/^date$/, @shellpref);
+    $shell{"date"} = "/bin/date";
+}
+
+sub shells_file_read {
+    my $shellsfile = shift;
+    local($sh);
+    local *S;
 
-    print "Check $etc_shells\n" if $verbose;
-    open(S, $etc_shells) || die "$etc_shells:$!\n";
+    print "Check $shellsfile\n" if $verbose;
+    open(S, $shellsfile) || die "$shellsfile:$!\n";
 
     while(<S>) {
        if (/^\s*\//) {
@@ -102,18 +117,10 @@
                warn "Shell: $sh not executable!\n";
                $err++;
            }
-       }
+       } elsif (/\#include\s+(\S+)/) {
+            shells_file_read ($1);
+        }
     }
-
-    # Allow /nonexistent and /bin/date as a valid shell for system utils
-    push(@list, "/nonexistent");
-    push(@shellpref, "no") if !grep(/^no$/, @shellpref);
-    $shell{"no"} = "/nonexistent";
-
-    push(@list, "/bin/date");
-    push(@shellpref, "date") if !grep(/^date$/, @shellpref);
-    $shell{"date"} = "/bin/date";
-
     return $err;
 }
 


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to