155682Smarkm/* 255682Smarkm * Copyright (c) 1985, 1993 355682Smarkm * The Regents of the University of California. All rights reserved. 455682Smarkm * 555682Smarkm * Redistribution and use in source and binary forms, with or without 655682Smarkm * modification, are permitted provided that the following conditions 755682Smarkm * are met: 855682Smarkm * 1. Redistributions of source code must retain the above copyright 955682Smarkm * notice, this list of conditions and the following disclaimer. 1055682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer in the 1255682Smarkm * documentation and/or other materials provided with the distribution. 13178825Sdfr * 3. Neither the name of the University nor the names of its contributors 1455682Smarkm * may be used to endorse or promote products derived from this software 1555682Smarkm * without specific prior written permission. 1655682Smarkm * 1755682Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1855682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1955682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2055682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2155682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2255682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2355682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2455682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2555682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2655682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2755682Smarkm * SUCH DAMAGE. 2855682Smarkm */ 2955682Smarkm 3055682Smarkm#include <config.h> 3155682Smarkm 3255682Smarkm#ifndef HAVE_GETUSERSHELL 3355682Smarkm 3455682Smarkm#include <stdio.h> 3555682Smarkm#include <stdlib.h> 3672445Sassar#include <string.h> 37178825Sdfr#include <ctype.h> 3855682Smarkm#ifdef HAVE_PATHS_H 3955682Smarkm#include <paths.h> 4055682Smarkm#endif 4155682Smarkm#ifdef HAVE_SYS_TYPES_H 4255682Smarkm#include <sys/types.h> 4355682Smarkm#endif 4455682Smarkm#ifdef HAVE_SYS_STAT_H 4555682Smarkm#include <sys/stat.h> 4655682Smarkm#endif 4755682Smarkm#ifdef HAVE_SYS_PARAM_H 4855682Smarkm#include <sys/param.h> 4955682Smarkm#endif 5055682Smarkm 5172445Sassar#ifdef HAVE_USERSEC_H 5272445Sassarstruct aud_rec; 5372445Sassar#include <usersec.h> 5472445Sassar#endif 5572445Sassar#ifdef HAVE_USERCONF_H 5672445Sassar#include <userconf.h> 5772445Sassar#endif 58178825Sdfr#include "roken.h" 5972445Sassar 6055682Smarkm#ifndef _PATH_SHELLS 6155682Smarkm#define _PATH_SHELLS "/etc/shells" 6255682Smarkm#endif 6355682Smarkm 6455682Smarkm#ifndef _PATH_BSHELL 6555682Smarkm#define _PATH_BSHELL "/bin/sh" 6655682Smarkm#endif 6755682Smarkm 6855682Smarkm#ifndef _PATH_CSHELL 6955682Smarkm#define _PATH_CSHELL "/bin/csh" 7055682Smarkm#endif 7155682Smarkm 7255682Smarkm/* 7355682Smarkm * Local shells should NOT be added here. They should be added in 7455682Smarkm * /etc/shells. 7555682Smarkm */ 7655682Smarkm 7755682Smarkmstatic char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; 7855682Smarkmstatic char **curshell, **shells, *strings; 7955682Smarkmstatic char **initshells (void); 8055682Smarkm 8155682Smarkm/* 8255682Smarkm * Get a list of shells from _PATH_SHELLS, if it exists. 8355682Smarkm */ 84233294SstasROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL 8555682Smarkmgetusershell() 8655682Smarkm{ 8772445Sassar char *ret; 8855682Smarkm 8972445Sassar if (curshell == NULL) 9072445Sassar curshell = initshells(); 9172445Sassar ret = *curshell; 9272445Sassar if (ret != NULL) 9372445Sassar curshell++; 9472445Sassar return (ret); 9555682Smarkm} 9655682Smarkm 97233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 9855682Smarkmendusershell() 9955682Smarkm{ 10072445Sassar if (shells != NULL) 10172445Sassar free(shells); 10272445Sassar shells = NULL; 10372445Sassar if (strings != NULL) 10472445Sassar free(strings); 10572445Sassar strings = NULL; 10672445Sassar curshell = NULL; 10755682Smarkm} 10855682Smarkm 109233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL 11055682Smarkmsetusershell() 11155682Smarkm{ 11272445Sassar curshell = initshells(); 11355682Smarkm} 11455682Smarkm 11555682Smarkmstatic char ** 11655682Smarkminitshells() 11755682Smarkm{ 11872445Sassar char **sp, *cp; 11972445Sassar#ifdef HAVE_GETCONFATTR 12072445Sassar char *tmp; 12172445Sassar int nsh; 12272445Sassar#else 12372445Sassar FILE *fp; 12472445Sassar#endif 12572445Sassar struct stat statb; 12655682Smarkm 12772445Sassar free(shells); 12872445Sassar shells = NULL; 12972445Sassar free(strings); 13072445Sassar strings = NULL; 13172445Sassar#ifdef HAVE_GETCONFATTR 13272445Sassar if(getconfattr(SC_SYS_LOGIN, SC_SHELLS, &tmp, SEC_LIST) != 0) 13372445Sassar return okshells; 13472445Sassar 13572445Sassar for(cp = tmp, nsh = 0; *cp; cp += strlen(cp) + 1, nsh++); 13672445Sassar 13772445Sassar shells = calloc(nsh + 1, sizeof(*shells)); 13872445Sassar if(shells == NULL) 13972445Sassar return okshells; 14072445Sassar 14172445Sassar strings = malloc(cp - tmp); 14272445Sassar if(strings == NULL) { 14372445Sassar free(shells); 14455682Smarkm shells = NULL; 14572445Sassar return okshells; 14672445Sassar } 14772445Sassar memcpy(strings, tmp, cp - tmp); 14872445Sassar for(sp = shells, cp = strings; *cp; cp += strlen(cp) + 1, sp++) 14972445Sassar *sp = cp; 15072445Sassar#else 15172445Sassar if ((fp = fopen(_PATH_SHELLS, "r")) == NULL) 15272445Sassar return (okshells); 15372445Sassar if (fstat(fileno(fp), &statb) == -1) { 15472445Sassar fclose(fp); 15572445Sassar return (okshells); 15672445Sassar } 15772445Sassar if ((strings = malloc((u_int)statb.st_size)) == NULL) { 15872445Sassar fclose(fp); 15972445Sassar return (okshells); 16072445Sassar } 16172445Sassar shells = calloc((unsigned)statb.st_size / 3, sizeof (char *)); 16272445Sassar if (shells == NULL) { 16372445Sassar fclose(fp); 16472445Sassar free(strings); 16555682Smarkm strings = NULL; 16672445Sassar return (okshells); 16772445Sassar } 16872445Sassar sp = shells; 16972445Sassar cp = strings; 17072445Sassar while (fgets(cp, MaxPathLen + 1, fp) != NULL) { 17172445Sassar while (*cp != '#' && *cp != '/' && *cp != '\0') 17272445Sassar cp++; 17372445Sassar if (*cp == '#' || *cp == '\0') 17472445Sassar continue; 17572445Sassar *sp++ = cp; 176178825Sdfr while (!isspace((unsigned char)*cp) && *cp != '#' && *cp != '\0') 17772445Sassar cp++; 17872445Sassar *cp++ = '\0'; 17972445Sassar } 18072445Sassar fclose(fp); 18172445Sassar#endif 18272445Sassar *sp = NULL; 18372445Sassar return (shells); 18455682Smarkm} 18555682Smarkm#endif /* HAVE_GETUSERSHELL */ 186