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