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#ifdef HAVE_CONFIG_H 3155682Smarkm#include <config.h> 3255682Smarkm#endif 3355682Smarkm 34178825SdfrRCSID("$Id: getusershell.c 21005 2007-06-08 01:54:35Z lha $"); 3555682Smarkm 3655682Smarkm#ifndef HAVE_GETUSERSHELL 3755682Smarkm 3855682Smarkm#include <stdio.h> 3955682Smarkm#include <stdlib.h> 4072445Sassar#include <string.h> 41178825Sdfr#include <ctype.h> 4255682Smarkm#ifdef HAVE_PATHS_H 4355682Smarkm#include <paths.h> 4455682Smarkm#endif 4555682Smarkm#ifdef HAVE_SYS_TYPES_H 4655682Smarkm#include <sys/types.h> 4755682Smarkm#endif 4855682Smarkm#ifdef HAVE_SYS_STAT_H 4955682Smarkm#include <sys/stat.h> 5055682Smarkm#endif 5155682Smarkm#ifdef HAVE_SYS_PARAM_H 5255682Smarkm#include <sys/param.h> 5355682Smarkm#endif 5455682Smarkm 5572445Sassar#ifdef HAVE_USERSEC_H 5672445Sassarstruct aud_rec; 5772445Sassar#include <usersec.h> 5872445Sassar#endif 5972445Sassar#ifdef HAVE_USERCONF_H 6072445Sassar#include <userconf.h> 6172445Sassar#endif 62178825Sdfr#include "roken.h" 6372445Sassar 6455682Smarkm#ifndef _PATH_SHELLS 6555682Smarkm#define _PATH_SHELLS "/etc/shells" 6655682Smarkm#endif 6755682Smarkm 6855682Smarkm#ifndef _PATH_BSHELL 6955682Smarkm#define _PATH_BSHELL "/bin/sh" 7055682Smarkm#endif 7155682Smarkm 7255682Smarkm#ifndef _PATH_CSHELL 7355682Smarkm#define _PATH_CSHELL "/bin/csh" 7455682Smarkm#endif 7555682Smarkm 7655682Smarkm/* 7755682Smarkm * Local shells should NOT be added here. They should be added in 7855682Smarkm * /etc/shells. 7955682Smarkm */ 8055682Smarkm 8155682Smarkmstatic char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; 8255682Smarkmstatic char **curshell, **shells, *strings; 8355682Smarkmstatic char **initshells (void); 8455682Smarkm 8555682Smarkm/* 8655682Smarkm * Get a list of shells from _PATH_SHELLS, if it exists. 8755682Smarkm */ 88178825Sdfrchar * ROKEN_LIB_FUNCTION 8955682Smarkmgetusershell() 9055682Smarkm{ 9172445Sassar char *ret; 9255682Smarkm 9372445Sassar if (curshell == NULL) 9472445Sassar curshell = initshells(); 9572445Sassar ret = *curshell; 9672445Sassar if (ret != NULL) 9772445Sassar curshell++; 9872445Sassar return (ret); 9955682Smarkm} 10055682Smarkm 101178825Sdfrvoid ROKEN_LIB_FUNCTION 10255682Smarkmendusershell() 10355682Smarkm{ 10472445Sassar if (shells != NULL) 10572445Sassar free(shells); 10672445Sassar shells = NULL; 10772445Sassar if (strings != NULL) 10872445Sassar free(strings); 10972445Sassar strings = NULL; 11072445Sassar curshell = NULL; 11155682Smarkm} 11255682Smarkm 113178825Sdfrvoid ROKEN_LIB_FUNCTION 11455682Smarkmsetusershell() 11555682Smarkm{ 11672445Sassar curshell = initshells(); 11755682Smarkm} 11855682Smarkm 11955682Smarkmstatic char ** 12055682Smarkminitshells() 12155682Smarkm{ 12272445Sassar char **sp, *cp; 12372445Sassar#ifdef HAVE_GETCONFATTR 12472445Sassar char *tmp; 12572445Sassar int nsh; 12672445Sassar#else 12772445Sassar FILE *fp; 12872445Sassar#endif 12972445Sassar struct stat statb; 13055682Smarkm 13172445Sassar free(shells); 13272445Sassar shells = NULL; 13372445Sassar free(strings); 13472445Sassar strings = NULL; 13572445Sassar#ifdef HAVE_GETCONFATTR 13672445Sassar if(getconfattr(SC_SYS_LOGIN, SC_SHELLS, &tmp, SEC_LIST) != 0) 13772445Sassar return okshells; 13872445Sassar 13972445Sassar for(cp = tmp, nsh = 0; *cp; cp += strlen(cp) + 1, nsh++); 14072445Sassar 14172445Sassar shells = calloc(nsh + 1, sizeof(*shells)); 14272445Sassar if(shells == NULL) 14372445Sassar return okshells; 14472445Sassar 14572445Sassar strings = malloc(cp - tmp); 14672445Sassar if(strings == NULL) { 14772445Sassar free(shells); 14855682Smarkm shells = NULL; 14972445Sassar return okshells; 15072445Sassar } 15172445Sassar memcpy(strings, tmp, cp - tmp); 15272445Sassar for(sp = shells, cp = strings; *cp; cp += strlen(cp) + 1, sp++) 15372445Sassar *sp = cp; 15472445Sassar#else 15572445Sassar if ((fp = fopen(_PATH_SHELLS, "r")) == NULL) 15672445Sassar return (okshells); 15772445Sassar if (fstat(fileno(fp), &statb) == -1) { 15872445Sassar fclose(fp); 15972445Sassar return (okshells); 16072445Sassar } 16172445Sassar if ((strings = malloc((u_int)statb.st_size)) == NULL) { 16272445Sassar fclose(fp); 16372445Sassar return (okshells); 16472445Sassar } 16572445Sassar shells = calloc((unsigned)statb.st_size / 3, sizeof (char *)); 16672445Sassar if (shells == NULL) { 16772445Sassar fclose(fp); 16872445Sassar free(strings); 16955682Smarkm strings = NULL; 17072445Sassar return (okshells); 17172445Sassar } 17272445Sassar sp = shells; 17372445Sassar cp = strings; 17472445Sassar while (fgets(cp, MaxPathLen + 1, fp) != NULL) { 17572445Sassar while (*cp != '#' && *cp != '/' && *cp != '\0') 17672445Sassar cp++; 17772445Sassar if (*cp == '#' || *cp == '\0') 17872445Sassar continue; 17972445Sassar *sp++ = cp; 180178825Sdfr while (!isspace((unsigned char)*cp) && *cp != '#' && *cp != '\0') 18172445Sassar cp++; 18272445Sassar *cp++ = '\0'; 18372445Sassar } 18472445Sassar fclose(fp); 18572445Sassar#endif 18672445Sassar *sp = NULL; 18772445Sassar return (shells); 18855682Smarkm} 18955682Smarkm#endif /* HAVE_GETUSERSHELL */ 190