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 54struct 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 79static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; 80static char **curshell, **shells, *strings; 81static char **initshells (void); 82 83/* 84 * Get a list of shells from _PATH_SHELLS, if it exists. 85 */ 86ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL 87getusershell() 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 99ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 100endusershell() 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 111ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 112setusershell() 113{ 114 curshell = initshells(); 115} 116 117static char ** 118initshells() 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