1b528cefcSMark Murray /*
2b528cefcSMark Murray * Copyright (c) 1985, 1993
3b528cefcSMark Murray * The Regents of the University of California. All rights reserved.
4b528cefcSMark Murray *
5b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without
6b528cefcSMark Murray * modification, are permitted provided that the following conditions
7b528cefcSMark Murray * are met:
8b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright
9b528cefcSMark Murray * notice, this list of conditions and the following disclaimer.
10b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright
11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the
12b528cefcSMark Murray * documentation and/or other materials provided with the distribution.
13c19800e8SDoug Rabson * 3. Neither the name of the University nor the names of its contributors
14b528cefcSMark Murray * may be used to endorse or promote products derived from this software
15b528cefcSMark Murray * without specific prior written permission.
16b528cefcSMark Murray *
17b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27b528cefcSMark Murray * SUCH DAMAGE.
28b528cefcSMark Murray */
29b528cefcSMark Murray
30b528cefcSMark Murray #include <config.h>
31b528cefcSMark Murray
32b528cefcSMark Murray #ifndef HAVE_GETUSERSHELL
33b528cefcSMark Murray
34b528cefcSMark Murray #include <stdio.h>
35b528cefcSMark Murray #include <stdlib.h>
365e9cd1aeSAssar Westerlund #include <string.h>
37c19800e8SDoug Rabson #include <ctype.h>
38b528cefcSMark Murray #ifdef HAVE_PATHS_H
39b528cefcSMark Murray #include <paths.h>
40b528cefcSMark Murray #endif
41b528cefcSMark Murray #ifdef HAVE_SYS_TYPES_H
42b528cefcSMark Murray #include <sys/types.h>
43b528cefcSMark Murray #endif
44b528cefcSMark Murray #ifdef HAVE_SYS_STAT_H
45b528cefcSMark Murray #include <sys/stat.h>
46b528cefcSMark Murray #endif
47b528cefcSMark Murray #ifdef HAVE_SYS_PARAM_H
48b528cefcSMark Murray #include <sys/param.h>
49b528cefcSMark Murray #endif
50b528cefcSMark Murray
515e9cd1aeSAssar Westerlund #ifdef HAVE_USERSEC_H
525e9cd1aeSAssar Westerlund struct aud_rec;
535e9cd1aeSAssar Westerlund #include <usersec.h>
545e9cd1aeSAssar Westerlund #endif
555e9cd1aeSAssar Westerlund #ifdef HAVE_USERCONF_H
565e9cd1aeSAssar Westerlund #include <userconf.h>
575e9cd1aeSAssar Westerlund #endif
58c19800e8SDoug Rabson #include "roken.h"
595e9cd1aeSAssar Westerlund
60b528cefcSMark Murray #ifndef _PATH_SHELLS
61b528cefcSMark Murray #define _PATH_SHELLS "/etc/shells"
62b528cefcSMark Murray #endif
63b528cefcSMark Murray
64b528cefcSMark Murray #ifndef _PATH_BSHELL
65b528cefcSMark Murray #define _PATH_BSHELL "/bin/sh"
66b528cefcSMark Murray #endif
67b528cefcSMark Murray
68b528cefcSMark Murray #ifndef _PATH_CSHELL
69b528cefcSMark Murray #define _PATH_CSHELL "/bin/csh"
70b528cefcSMark Murray #endif
71b528cefcSMark Murray
72b528cefcSMark Murray /*
73b528cefcSMark Murray * Local shells should NOT be added here. They should be added in
74b528cefcSMark Murray * /etc/shells.
75b528cefcSMark Murray */
76b528cefcSMark Murray
77b528cefcSMark Murray static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
78b528cefcSMark Murray static char **curshell, **shells, *strings;
79b528cefcSMark Murray static char **initshells (void);
80b528cefcSMark Murray
81b528cefcSMark Murray /*
82b528cefcSMark Murray * Get a list of shells from _PATH_SHELLS, if it exists.
83b528cefcSMark Murray */
84*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL
getusershell()85b528cefcSMark Murray getusershell()
86b528cefcSMark Murray {
87b528cefcSMark Murray char *ret;
88b528cefcSMark Murray
89b528cefcSMark Murray if (curshell == NULL)
90b528cefcSMark Murray curshell = initshells();
91b528cefcSMark Murray ret = *curshell;
92b528cefcSMark Murray if (ret != NULL)
93b528cefcSMark Murray curshell++;
94b528cefcSMark Murray return (ret);
95b528cefcSMark Murray }
96b528cefcSMark Murray
97*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
endusershell()98b528cefcSMark Murray endusershell()
99b528cefcSMark Murray {
100b528cefcSMark Murray if (shells != NULL)
101b528cefcSMark Murray free(shells);
102b528cefcSMark Murray shells = NULL;
103b528cefcSMark Murray if (strings != NULL)
104b528cefcSMark Murray free(strings);
105b528cefcSMark Murray strings = NULL;
106b528cefcSMark Murray curshell = NULL;
107b528cefcSMark Murray }
108b528cefcSMark Murray
109*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
setusershell()110b528cefcSMark Murray setusershell()
111b528cefcSMark Murray {
112b528cefcSMark Murray curshell = initshells();
113b528cefcSMark Murray }
114b528cefcSMark Murray
115b528cefcSMark Murray static char **
initshells()116b528cefcSMark Murray initshells()
117b528cefcSMark Murray {
118b528cefcSMark Murray char **sp, *cp;
1195e9cd1aeSAssar Westerlund #ifdef HAVE_GETCONFATTR
1205e9cd1aeSAssar Westerlund char *tmp;
1215e9cd1aeSAssar Westerlund int nsh;
1225e9cd1aeSAssar Westerlund #else
123b528cefcSMark Murray FILE *fp;
1245e9cd1aeSAssar Westerlund #endif
125b528cefcSMark Murray struct stat statb;
126b528cefcSMark Murray
127b528cefcSMark Murray free(shells);
128b528cefcSMark Murray shells = NULL;
129b528cefcSMark Murray free(strings);
130b528cefcSMark Murray strings = NULL;
1315e9cd1aeSAssar Westerlund #ifdef HAVE_GETCONFATTR
1325e9cd1aeSAssar Westerlund if(getconfattr(SC_SYS_LOGIN, SC_SHELLS, &tmp, SEC_LIST) != 0)
1335e9cd1aeSAssar Westerlund return okshells;
1345e9cd1aeSAssar Westerlund
1355e9cd1aeSAssar Westerlund for(cp = tmp, nsh = 0; *cp; cp += strlen(cp) + 1, nsh++);
1365e9cd1aeSAssar Westerlund
1375e9cd1aeSAssar Westerlund shells = calloc(nsh + 1, sizeof(*shells));
1385e9cd1aeSAssar Westerlund if(shells == NULL)
1395e9cd1aeSAssar Westerlund return okshells;
1405e9cd1aeSAssar Westerlund
1415e9cd1aeSAssar Westerlund strings = malloc(cp - tmp);
1425e9cd1aeSAssar Westerlund if(strings == NULL) {
1435e9cd1aeSAssar Westerlund free(shells);
1445e9cd1aeSAssar Westerlund shells = NULL;
1455e9cd1aeSAssar Westerlund return okshells;
1465e9cd1aeSAssar Westerlund }
1475e9cd1aeSAssar Westerlund memcpy(strings, tmp, cp - tmp);
1485e9cd1aeSAssar Westerlund for(sp = shells, cp = strings; *cp; cp += strlen(cp) + 1, sp++)
1495e9cd1aeSAssar Westerlund *sp = cp;
1505e9cd1aeSAssar Westerlund #else
151b528cefcSMark Murray if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
152b528cefcSMark Murray return (okshells);
153b528cefcSMark Murray if (fstat(fileno(fp), &statb) == -1) {
154b528cefcSMark Murray fclose(fp);
155b528cefcSMark Murray return (okshells);
156b528cefcSMark Murray }
157b528cefcSMark Murray if ((strings = malloc((u_int)statb.st_size)) == NULL) {
158b528cefcSMark Murray fclose(fp);
159b528cefcSMark Murray return (okshells);
160b528cefcSMark Murray }
161b528cefcSMark Murray shells = calloc((unsigned)statb.st_size / 3, sizeof (char *));
162b528cefcSMark Murray if (shells == NULL) {
163b528cefcSMark Murray fclose(fp);
164b528cefcSMark Murray free(strings);
165b528cefcSMark Murray strings = NULL;
166b528cefcSMark Murray return (okshells);
167b528cefcSMark Murray }
168b528cefcSMark Murray sp = shells;
169b528cefcSMark Murray cp = strings;
170b528cefcSMark Murray while (fgets(cp, MaxPathLen + 1, fp) != NULL) {
171b528cefcSMark Murray while (*cp != '#' && *cp != '/' && *cp != '\0')
172b528cefcSMark Murray cp++;
173b528cefcSMark Murray if (*cp == '#' || *cp == '\0')
174b528cefcSMark Murray continue;
175b528cefcSMark Murray *sp++ = cp;
176c19800e8SDoug Rabson while (!isspace((unsigned char)*cp) && *cp != '#' && *cp != '\0')
177b528cefcSMark Murray cp++;
178b528cefcSMark Murray *cp++ = '\0';
179b528cefcSMark Murray }
180b528cefcSMark Murray fclose(fp);
1815e9cd1aeSAssar Westerlund #endif
1825e9cd1aeSAssar Westerlund *sp = NULL;
183b528cefcSMark Murray return (shells);
184b528cefcSMark Murray }
185b528cefcSMark Murray #endif /* HAVE_GETUSERSHELL */
186