From owner-freebsd-current Sun Jan 28 1:14:20 2001 Delivered-To: freebsd-current@freebsd.org Received: from smtp.wanadoo.nl (smtp.wanadoo.nl [194.134.193.6]) by hub.freebsd.org (Postfix) with ESMTP id 1E16237B69F for ; Sun, 28 Jan 2001 01:13:56 -0800 (PST) Received: from ams-gw.sohara.org (p021.vcu.wanadoo.nl [194.134.200.21]) by smtp.wanadoo.nl (8.9.3/8.9.3) with SMTP id KAA25391 for ; Sun, 28 Jan 2001 10:13:53 +0100 (MET) Date: Sun, 28 Jan 2001 10:13:49 +0100 From: "Steve O'Hara-Smith" To: current@freebsd.org Subject: /etc/shells #include syntax support patch Message-Id: <20010128101349.2c94539f.steveo@eircom.net> X-Mailer: Sylpheed version 0.4.9 (GTK+ 1.2.8; FreeBSD 4.2-STABLE; i386) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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 #include #include +#include /* * 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() { 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 majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message