]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/heimdal/lib/roken/getusershell.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / crypto / heimdal / lib / roken / getusershell.c
1 /*
2  * Copyright (c) 1985, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33
34 RCSID("$Id: getusershell.c 21005 2007-06-08 01:54:35Z lha $");
35
36 #ifndef HAVE_GETUSERSHELL
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <ctype.h>
42 #ifdef HAVE_PATHS_H
43 #include <paths.h>
44 #endif
45 #ifdef HAVE_SYS_TYPES_H
46 #include <sys/types.h>
47 #endif
48 #ifdef HAVE_SYS_STAT_H
49 #include <sys/stat.h>
50 #endif
51 #ifdef HAVE_SYS_PARAM_H
52 #include <sys/param.h>
53 #endif
54
55 #ifdef HAVE_USERSEC_H
56 struct aud_rec;
57 #include <usersec.h>
58 #endif
59 #ifdef HAVE_USERCONF_H
60 #include <userconf.h>
61 #endif
62 #include "roken.h"
63
64 #ifndef _PATH_SHELLS
65 #define _PATH_SHELLS "/etc/shells"
66 #endif
67
68 #ifndef _PATH_BSHELL
69 #define _PATH_BSHELL "/bin/sh"
70 #endif
71
72 #ifndef _PATH_CSHELL
73 #define _PATH_CSHELL "/bin/csh"
74 #endif
75
76 /*
77  * Local shells should NOT be added here.  They should be added in
78  * /etc/shells.
79  */
80
81 static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
82 static char **curshell, **shells, *strings;
83 static char **initshells (void);
84
85 /*
86  * Get a list of shells from _PATH_SHELLS, if it exists.
87  */
88 char * ROKEN_LIB_FUNCTION
89 getusershell()
90 {
91     char *ret;
92
93     if (curshell == NULL)
94         curshell = initshells();
95     ret = *curshell;
96     if (ret != NULL)
97         curshell++;
98     return (ret);
99 }
100
101 void ROKEN_LIB_FUNCTION
102 endusershell()
103 {
104     if (shells != NULL)
105         free(shells);
106     shells = NULL;
107     if (strings != NULL)
108         free(strings);
109     strings = NULL;
110     curshell = NULL;
111 }
112
113 void ROKEN_LIB_FUNCTION
114 setusershell()
115 {
116     curshell = initshells();
117 }
118
119 static char **
120 initshells()
121 {
122     char **sp, *cp;
123 #ifdef HAVE_GETCONFATTR
124     char *tmp;
125     int nsh;
126 #else
127     FILE *fp;
128 #endif
129     struct stat statb;
130
131     free(shells);
132     shells = NULL;
133     free(strings);
134     strings = NULL;
135 #ifdef HAVE_GETCONFATTR
136     if(getconfattr(SC_SYS_LOGIN, SC_SHELLS, &tmp, SEC_LIST) != 0)
137         return okshells;
138
139     for(cp = tmp, nsh = 0; *cp; cp += strlen(cp) + 1, nsh++);
140
141     shells = calloc(nsh + 1, sizeof(*shells));
142     if(shells == NULL)
143         return okshells;
144
145     strings = malloc(cp - tmp);
146     if(strings == NULL) {
147         free(shells);
148         shells = NULL;
149         return okshells;
150     }
151     memcpy(strings, tmp, cp - tmp);
152     for(sp = shells, cp = strings; *cp; cp += strlen(cp) + 1, sp++)
153         *sp = cp;
154 #else
155     if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
156         return (okshells);
157     if (fstat(fileno(fp), &statb) == -1) {
158         fclose(fp);
159         return (okshells);
160     }
161     if ((strings = malloc((u_int)statb.st_size)) == NULL) {
162         fclose(fp);
163         return (okshells);
164     }
165     shells = calloc((unsigned)statb.st_size / 3, sizeof (char *));
166     if (shells == NULL) {
167         fclose(fp);
168         free(strings);
169         strings = NULL;
170         return (okshells);
171     }
172     sp = shells;
173     cp = strings;
174     while (fgets(cp, MaxPathLen + 1, fp) != NULL) {
175         while (*cp != '#' && *cp != '/' && *cp != '\0')
176             cp++;
177         if (*cp == '#' || *cp == '\0')
178             continue;
179         *sp++ = cp;
180         while (!isspace((unsigned char)*cp) && *cp != '#' && *cp != '\0')
181             cp++;
182         *cp++ = '\0';
183     }
184     fclose(fp);
185 #endif
186     *sp = NULL;
187     return (shells);
188 }
189 #endif /* HAVE_GETUSERSHELL */