158f0484fSRodney W. Grimes /* 258f0484fSRodney W. Grimes * Copyright (c) 1985, 1993 358f0484fSRodney W. Grimes * The Regents of the University of California. All rights reserved. 458f0484fSRodney W. Grimes * 558f0484fSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 658f0484fSRodney W. Grimes * modification, are permitted provided that the following conditions 758f0484fSRodney W. Grimes * are met: 858f0484fSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 958f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 1058f0484fSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 1158f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 1258f0484fSRodney W. Grimes * documentation and/or other materials provided with the distribution. 13fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 1458f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software 1558f0484fSRodney W. Grimes * without specific prior written permission. 1658f0484fSRodney W. Grimes * 1758f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1858f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1958f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2058f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2158f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2258f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2358f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2458f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2558f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2658f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2758f0484fSRodney W. Grimes * SUCH DAMAGE. 2858f0484fSRodney W. Grimes */ 2958f0484fSRodney W. Grimes 3058f0484fSRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint) 31135b57f9SDavid E. O'Brien static char sccsid[] = "@(#)getusershell.c 8.1 (Berkeley) 6/4/93"; 3258f0484fSRodney W. Grimes #endif /* LIBC_SCCS and not lint */ 33b231cb39SDavid E. O'Brien /* $NetBSD: getusershell.c,v 1.17 1999/01/25 01:09:34 lukem Exp $ */ 34ec4c2e36SDavid E. O'Brien #include <sys/cdefs.h> 35135b57f9SDavid E. O'Brien __FBSDID("$FreeBSD$"); 3658f0484fSRodney W. Grimes 370030cba4SJacques Vidrine #include "namespace.h" 3858f0484fSRodney W. Grimes #include <sys/param.h> 3958f0484fSRodney W. Grimes #include <sys/file.h> 40248aee62SJacques Vidrine 4158f0484fSRodney W. Grimes #include <ctype.h> 42248aee62SJacques Vidrine #include <errno.h> 43248aee62SJacques Vidrine #include <nsswitch.h> 4458f0484fSRodney W. Grimes #include <paths.h> 45248aee62SJacques Vidrine #include <stdio.h> 46248aee62SJacques Vidrine #include <stdlib.h> 47248aee62SJacques Vidrine #include <string.h> 48248aee62SJacques Vidrine #include <stringlist.h> 49248aee62SJacques Vidrine #include <unistd.h> 50248aee62SJacques Vidrine 51248aee62SJacques Vidrine #ifdef HESIOD 52248aee62SJacques Vidrine #include <hesiod.h> 53248aee62SJacques Vidrine #endif 54248aee62SJacques Vidrine #ifdef YP 55248aee62SJacques Vidrine #include <rpc/rpc.h> 56248aee62SJacques Vidrine #include <rpcsvc/ypclnt.h> 57248aee62SJacques Vidrine #include <rpcsvc/yp_prot.h> 58248aee62SJacques Vidrine #endif 590030cba4SJacques Vidrine #include "un-namespace.h" 6058f0484fSRodney W. Grimes 61248aee62SJacques Vidrine static const char *const *curshell; 62248aee62SJacques Vidrine static StringList *sl; 63248aee62SJacques Vidrine 64b231cb39SDavid E. O'Brien static const char *const *initshells(void); 6558f0484fSRodney W. Grimes 6658f0484fSRodney W. Grimes /* 67248aee62SJacques Vidrine * Get a list of shells from "shells" nsswitch database 6858f0484fSRodney W. Grimes */ 6958f0484fSRodney W. Grimes char * 70248aee62SJacques Vidrine getusershell(void) 7158f0484fSRodney W. Grimes { 7258f0484fSRodney W. Grimes char *ret; 7358f0484fSRodney W. Grimes 7458f0484fSRodney W. Grimes if (curshell == NULL) 7558f0484fSRodney W. Grimes curshell = initshells(); 76248aee62SJacques Vidrine /*LINTED*/ 77248aee62SJacques Vidrine ret = (char *)*curshell; 7858f0484fSRodney W. Grimes if (ret != NULL) 7958f0484fSRodney W. Grimes curshell++; 8058f0484fSRodney W. Grimes return (ret); 8158f0484fSRodney W. Grimes } 8258f0484fSRodney W. Grimes 8358f0484fSRodney W. Grimes void 84248aee62SJacques Vidrine endusershell(void) 8558f0484fSRodney W. Grimes { 860d74f328SRobert Drehmel if (sl) { 87248aee62SJacques Vidrine sl_free(sl, 1); 88248aee62SJacques Vidrine sl = NULL; 890d74f328SRobert Drehmel } 9058f0484fSRodney W. Grimes curshell = NULL; 9158f0484fSRodney W. Grimes } 9258f0484fSRodney W. Grimes 9358f0484fSRodney W. Grimes void 94248aee62SJacques Vidrine setusershell(void) 9558f0484fSRodney W. Grimes { 9658f0484fSRodney W. Grimes 9758f0484fSRodney W. Grimes curshell = initshells(); 9858f0484fSRodney W. Grimes } 9958f0484fSRodney W. Grimes 10058f0484fSRodney W. Grimes 101b231cb39SDavid E. O'Brien static int _local_initshells(void *, void *, va_list); 102248aee62SJacques Vidrine 103248aee62SJacques Vidrine /*ARGSUSED*/ 104248aee62SJacques Vidrine static int 10555b6b759SCraig Rodrigues _local_initshells(void *rv, void *cb_data, va_list ap) 106248aee62SJacques Vidrine { 107248aee62SJacques Vidrine char *sp, *cp; 108248aee62SJacques Vidrine FILE *fp; 109248aee62SJacques Vidrine char line[MAXPATHLEN + 2]; 110248aee62SJacques Vidrine 111248aee62SJacques Vidrine if (sl) 112248aee62SJacques Vidrine sl_free(sl, 1); 113248aee62SJacques Vidrine sl = sl_init(); 114248aee62SJacques Vidrine 1151084b38bSJilles Tjoelker if ((fp = fopen(_PATH_SHELLS, "re")) == NULL) 116248aee62SJacques Vidrine return NS_UNAVAIL; 117248aee62SJacques Vidrine 118*b47e69e6SEd Maste while (fgets(line, MAXPATHLEN + 1, fp) != NULL) { 1190c0349bfSGarrett Wollman cp = line; 12058f0484fSRodney W. Grimes while (*cp != '#' && *cp != '/' && *cp != '\0') 12158f0484fSRodney W. Grimes cp++; 12258f0484fSRodney W. Grimes if (*cp == '#' || *cp == '\0') 12358f0484fSRodney W. Grimes continue; 124248aee62SJacques Vidrine sp = cp; 125248aee62SJacques Vidrine while (!isspace(*cp) && *cp != '#' && *cp != '\0') 12658f0484fSRodney W. Grimes cp++; 127*b47e69e6SEd Maste *cp = '\0'; 128248aee62SJacques Vidrine sl_add(sl, strdup(sp)); 12958f0484fSRodney W. Grimes } 13058f0484fSRodney W. Grimes (void)fclose(fp); 131248aee62SJacques Vidrine return NS_SUCCESS; 132248aee62SJacques Vidrine } 133248aee62SJacques Vidrine 134248aee62SJacques Vidrine #ifdef HESIOD 135b231cb39SDavid E. O'Brien static int _dns_initshells(void *, void *, va_list); 136248aee62SJacques Vidrine 137248aee62SJacques Vidrine /*ARGSUSED*/ 138248aee62SJacques Vidrine static int 13955b6b759SCraig Rodrigues _dns_initshells(void *rv, void *cb_data, va_list ap) 140248aee62SJacques Vidrine { 141248aee62SJacques Vidrine char shellname[] = "shells-XXXXX"; 142248aee62SJacques Vidrine int hsindex, hpi, r; 143248aee62SJacques Vidrine char **hp; 144248aee62SJacques Vidrine void *context; 145248aee62SJacques Vidrine 146248aee62SJacques Vidrine if (sl) 147248aee62SJacques Vidrine sl_free(sl, 1); 148248aee62SJacques Vidrine sl = sl_init(); 149248aee62SJacques Vidrine r = NS_UNAVAIL; 150248aee62SJacques Vidrine if (hesiod_init(&context) == -1) 151248aee62SJacques Vidrine return (r); 152248aee62SJacques Vidrine 153248aee62SJacques Vidrine for (hsindex = 0; ; hsindex++) { 154248aee62SJacques Vidrine snprintf(shellname, sizeof(shellname)-1, "shells-%d", hsindex); 155248aee62SJacques Vidrine hp = hesiod_resolve(context, shellname, "shells"); 156248aee62SJacques Vidrine if (hp == NULL) { 157248aee62SJacques Vidrine if (errno == ENOENT) { 158248aee62SJacques Vidrine if (hsindex == 0) 159248aee62SJacques Vidrine r = NS_NOTFOUND; 160248aee62SJacques Vidrine else 161248aee62SJacques Vidrine r = NS_SUCCESS; 162248aee62SJacques Vidrine } 163248aee62SJacques Vidrine break; 164248aee62SJacques Vidrine } else { 165248aee62SJacques Vidrine for (hpi = 0; hp[hpi]; hpi++) 166248aee62SJacques Vidrine sl_add(sl, hp[hpi]); 167248aee62SJacques Vidrine free(hp); 168248aee62SJacques Vidrine } 169248aee62SJacques Vidrine } 170248aee62SJacques Vidrine hesiod_end(context); 171248aee62SJacques Vidrine return (r); 172248aee62SJacques Vidrine } 173248aee62SJacques Vidrine #endif /* HESIOD */ 174248aee62SJacques Vidrine 175248aee62SJacques Vidrine #ifdef YP 176b231cb39SDavid E. O'Brien static int _nis_initshells(void *, void *, va_list); 177248aee62SJacques Vidrine 178248aee62SJacques Vidrine /*ARGSUSED*/ 179248aee62SJacques Vidrine static int 18055b6b759SCraig Rodrigues _nis_initshells(void *rv, void *cb_data, va_list ap) 181248aee62SJacques Vidrine { 182248aee62SJacques Vidrine static char *ypdomain; 1830d74f328SRobert Drehmel char *key, *data; 1840d74f328SRobert Drehmel char *lastkey; 1850d74f328SRobert Drehmel int keylen, datalen; 1860d74f328SRobert Drehmel int r; 187248aee62SJacques Vidrine 188248aee62SJacques Vidrine if (sl) 189248aee62SJacques Vidrine sl_free(sl, 1); 190248aee62SJacques Vidrine sl = sl_init(); 191248aee62SJacques Vidrine 192248aee62SJacques Vidrine if (ypdomain == NULL) { 193248aee62SJacques Vidrine switch (yp_get_default_domain(&ypdomain)) { 194248aee62SJacques Vidrine case 0: 195248aee62SJacques Vidrine break; 196248aee62SJacques Vidrine case YPERR_RESRC: 197248aee62SJacques Vidrine return NS_TRYAGAIN; 198248aee62SJacques Vidrine default: 199248aee62SJacques Vidrine return NS_UNAVAIL; 200248aee62SJacques Vidrine } 201248aee62SJacques Vidrine } 202248aee62SJacques Vidrine 2030d74f328SRobert Drehmel /* 2040d74f328SRobert Drehmel * `key' and `data' point to strings dynamically allocated by 2050d74f328SRobert Drehmel * the yp_... functions. 2060d74f328SRobert Drehmel * `data' is directly put into the stringlist of shells. 2070d74f328SRobert Drehmel */ 208248aee62SJacques Vidrine key = data = NULL; 2090d74f328SRobert Drehmel if (yp_first(ypdomain, "shells", &key, &keylen, &data, &datalen)) 210248aee62SJacques Vidrine return NS_UNAVAIL; 2110d74f328SRobert Drehmel do { 212248aee62SJacques Vidrine data[datalen] = '\0'; /* clear trailing \n */ 213248aee62SJacques Vidrine sl_add(sl, data); 2140d74f328SRobert Drehmel 2150d74f328SRobert Drehmel lastkey = key; 2160d74f328SRobert Drehmel r = yp_next(ypdomain, "shells", lastkey, keylen, 2170d74f328SRobert Drehmel &key, &keylen, &data, &datalen); 2180d74f328SRobert Drehmel free(lastkey); 2190d74f328SRobert Drehmel } while (r == 0); 2200d74f328SRobert Drehmel 2210d74f328SRobert Drehmel if (r == YPERR_NOMORE) { 2220d74f328SRobert Drehmel /* 2230d74f328SRobert Drehmel * `data' and `key' ought to be NULL - do not try to free them. 2240d74f328SRobert Drehmel */ 2250d74f328SRobert Drehmel return NS_SUCCESS; 226248aee62SJacques Vidrine } 2270d74f328SRobert Drehmel 2280d74f328SRobert Drehmel return NS_UNAVAIL; 229248aee62SJacques Vidrine } 230248aee62SJacques Vidrine #endif /* YP */ 231248aee62SJacques Vidrine 232248aee62SJacques Vidrine static const char *const * 23355b6b759SCraig Rodrigues initshells(void) 234248aee62SJacques Vidrine { 235248aee62SJacques Vidrine static const ns_dtab dtab[] = { 236248aee62SJacques Vidrine NS_FILES_CB(_local_initshells, NULL) 237248aee62SJacques Vidrine NS_DNS_CB(_dns_initshells, NULL) 238248aee62SJacques Vidrine NS_NIS_CB(_nis_initshells, NULL) 239248aee62SJacques Vidrine { 0 } 240248aee62SJacques Vidrine }; 241248aee62SJacques Vidrine if (sl) 242248aee62SJacques Vidrine sl_free(sl, 1); 243248aee62SJacques Vidrine sl = sl_init(); 244248aee62SJacques Vidrine 2450030cba4SJacques Vidrine if (_nsdispatch(NULL, dtab, NSDB_SHELLS, "initshells", __nsdefaultsrc) 246248aee62SJacques Vidrine != NS_SUCCESS) { 247248aee62SJacques Vidrine if (sl) 248248aee62SJacques Vidrine sl_free(sl, 1); 2495b7aa0fcSJilles Tjoelker sl = sl_init(); 2505b7aa0fcSJilles Tjoelker /* 2515b7aa0fcSJilles Tjoelker * Local shells should NOT be added here. They should be 2525b7aa0fcSJilles Tjoelker * added in /etc/shells. 2535b7aa0fcSJilles Tjoelker */ 2545b7aa0fcSJilles Tjoelker sl_add(sl, strdup(_PATH_BSHELL)); 2555b7aa0fcSJilles Tjoelker sl_add(sl, strdup(_PATH_CSHELL)); 256248aee62SJacques Vidrine } 257248aee62SJacques Vidrine sl_add(sl, NULL); 258248aee62SJacques Vidrine 259248aee62SJacques Vidrine return (const char *const *)(sl->sl_str); 26058f0484fSRodney W. Grimes } 261