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