2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
10 * Copyright (c) 1985 Regents of the University of California.
11 * All rights reserved. The Berkeley software License Agreement
12 * specifies the terms and conditions for redistribution.
15 #pragma ident "%Z%%M% %I% %E% SMI"
18 #include <sys/types.h>
19 #include <sys/param.h>
29 #define SHELLS "/etc/shells"
32 * Do not add local shells here. They should be added in /etc/shells
34 * Do not add restricted shells:
35 * Shells returned by getusershell traditionally allow:
36 * - users to change away from (i.e., if you have an rksh in
37 * getusershell(), then users can change their shell to ksh)
38 * - by default, ftp in is allowed only for shells returned by
39 * getusershell(); since FTP has no restrictions on directory
40 * movement, adding rksh to getusershell() would defeat that
43 const char *okshells
[] = {
74 static char **shells
, *strings
;
75 static char **curshell
;
76 static char **initshells(void);
79 * Get a list of shells from SHELLS, if it exists.
87 curshell
= initshells();
99 (void) free((char *)shells
);
102 (void) free(strings
);
111 curshell
= initshells();
122 (void) free((char *)shells
);
125 (void) free(strings
);
127 if ((fp
= fopen(SHELLS
, "rF")) == (FILE *)0)
128 return ((char **)okshells
);
130 * The +1 in the malloc() below is needed to handle the final
131 * fgets() NULL terminator. From fgets(3S):
133 * char *fgets(char *s, int n, FILE *stream);
135 * The fgets() function reads characters from the stream into
136 * the array pointed to by s, until n-1 characters are read, or
137 * a newline character is read and transferred to s, or an end-
138 * of-file condition is encountered. The string is then termi-
139 * nated with a null character.
141 if ((fstat(fileno(fp
), &statb
) == -1) || (statb
.st_size
> LONG_MAX
) ||
142 ((strings
= malloc((size_t)statb
.st_size
+ 1)) == NULL
)) {
144 return ((char **)okshells
);
146 shells
= calloc((size_t)statb
.st_size
/ 3, sizeof (char *));
147 if (shells
== NULL
) {
149 (void) free(strings
);
151 return ((char **)okshells
);
155 while (fgets(cp
, MAXPATHLEN
+ 1, fp
) != NULL
) {
156 while (*cp
!= '#' && *cp
!= '/' && *cp
!= '\0')
158 if (*cp
== '#' || *cp
== '\0')
161 while (!isspace(*cp
) && *cp
!= '#' && *cp
!= '\0')