Home | History | Annotate | Line # | Download | only in gen
getpwent.c revision 1.14.8.1
      1  1.14.8.1    lukem /*	$NetBSD: getpwent.c,v 1.14.8.1 1996/11/06 00:48:37 lukem Exp $	*/
      2      1.12      cgd 
      3       1.1      cgd /*
      4      1.12      cgd  * Copyright (c) 1988, 1993
      5      1.12      cgd  *	The Regents of the University of California.  All rights reserved.
      6      1.14     phil  * Portions Copyright (c) 1994, 1995, Jason Downs.  All rights reserved.
      7  1.14.8.1    lukem  * Portions Copyright (c) 1995, 1996
      8  1.14.8.1    lukem  *	Luke Mewburn <lm (at) werj.com.au>. All rights reserved.
      9       1.1      cgd  *
     10       1.1      cgd  * Redistribution and use in source and binary forms, with or without
     11       1.1      cgd  * modification, are permitted provided that the following conditions
     12       1.1      cgd  * are met:
     13       1.1      cgd  * 1. Redistributions of source code must retain the above copyright
     14       1.1      cgd  *    notice, this list of conditions and the following disclaimer.
     15       1.1      cgd  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1      cgd  *    notice, this list of conditions and the following disclaimer in the
     17       1.1      cgd  *    documentation and/or other materials provided with the distribution.
     18       1.1      cgd  * 3. All advertising materials mentioning features or use of this software
     19       1.1      cgd  *    must display the following acknowledgement:
     20       1.1      cgd  *	This product includes software developed by the University of
     21       1.1      cgd  *	California, Berkeley and its contributors.
     22       1.1      cgd  * 4. Neither the name of the University nor the names of its contributors
     23       1.1      cgd  *    may be used to endorse or promote products derived from this software
     24       1.1      cgd  *    without specific prior written permission.
     25       1.1      cgd  *
     26       1.1      cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     27       1.1      cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     28       1.1      cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     29       1.1      cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     30       1.1      cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     31       1.1      cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     32       1.1      cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     33       1.1      cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     34       1.1      cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     35       1.1      cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     36       1.1      cgd  * SUCH DAMAGE.
     37       1.1      cgd  */
     38       1.1      cgd 
     39       1.1      cgd #if defined(LIBC_SCCS) && !defined(lint)
     40      1.12      cgd #if 0
     41      1.12      cgd static char sccsid[] = "@(#)getpwent.c	8.1 (Berkeley) 6/4/93";
     42      1.12      cgd #else
     43  1.14.8.1    lukem static char rcsid[] = "$NetBSD: getpwent.c,v 1.14.8.1 1996/11/06 00:48:37 lukem Exp $";
     44      1.12      cgd #endif
     45       1.1      cgd #endif /* LIBC_SCCS and not lint */
     46       1.1      cgd 
     47       1.1      cgd #include <sys/param.h>
     48       1.1      cgd #include <fcntl.h>
     49       1.1      cgd #include <db.h>
     50       1.1      cgd #include <syslog.h>
     51       1.1      cgd #include <pwd.h>
     52       1.1      cgd #include <utmp.h>
     53       1.1      cgd #include <errno.h>
     54       1.1      cgd #include <unistd.h>
     55       1.1      cgd #include <stdlib.h>
     56       1.1      cgd #include <string.h>
     57       1.1      cgd #include <limits.h>
     58      1.14     phil #include <netgroup.h>
     59  1.14.8.1    lukem #include <nsswitch.h>
     60  1.14.8.1    lukem #ifdef HESIOD
     61  1.14.8.1    lukem #include <hesiod.h>
     62  1.14.8.1    lukem #endif
     63       1.4  deraadt #ifdef YP
     64      1.14     phil #include <machine/param.h>
     65       1.4  deraadt #include <stdio.h>
     66       1.4  deraadt #include <rpc/rpc.h>
     67       1.4  deraadt #include <rpcsvc/yp_prot.h>
     68       1.4  deraadt #include <rpcsvc/ypclnt.h>
     69       1.4  deraadt #endif
     70       1.1      cgd 
     71       1.1      cgd static struct passwd _pw_passwd;	/* password structure */
     72       1.1      cgd static DB *_pw_db;			/* password database */
     73       1.1      cgd static int _pw_keynum;			/* key counter */
     74       1.1      cgd static int _pw_stayopen;		/* keep fd's open */
     75      1.14     phil static int _pw_flags;			/* password flags */
     76  1.14.8.1    lukem 
     77      1.14     phil static int __hashpw __P((DBT *));
     78      1.14     phil static int __initdb __P((void));
     79      1.14     phil 
     80      1.14     phil const char __yp_token[] = "__YP!";	/* Let pwd_mkdb pull this in. */
     81       1.1      cgd 
     82       1.4  deraadt #ifdef YP
     83       1.4  deraadt static char     *__ypcurrent, *__ypdomain;
     84      1.14     phil static int      __ypcurrentlen;
     85  1.14.8.1    lukem #endif
     86  1.14.8.1    lukem 
     87  1.14.8.1    lukem #ifdef HESIOD
     88  1.14.8.1    lukem static int	 _pw_hesnum;
     89  1.14.8.1    lukem #endif
     90  1.14.8.1    lukem 
     91  1.14.8.1    lukem #if defined(YP) || defined(HESIOD)
     92  1.14.8.1    lukem enum _pwmode { PWMODE_NONE, PWMODE_FULL, PWMODE_USER, PWMODE_NETGRP };
     93  1.14.8.1    lukem static enum _pwmode	 __pwmode;
     94  1.14.8.1    lukem 
     95  1.14.8.1    lukem static struct passwd	*__pwproto = (struct passwd *)NULL;
     96  1.14.8.1    lukem static int		 __pwproto_flags;
     97  1.14.8.1    lukem static char		 line[1024];
     98  1.14.8.1    lukem static long		 prbuf[1024 / sizeof(long)];
     99  1.14.8.1    lukem static DB		*__pwexclude = (DB *)NULL;
    100      1.14     phil 
    101  1.14.8.1    lukem /*
    102  1.14.8.1    lukem  * add a name to the compat mode exclude list
    103  1.14.8.1    lukem  */
    104      1.14     phil static int
    105  1.14.8.1    lukem __pwexclude_add(name)
    106  1.14.8.1    lukem 	const char *name;
    107      1.14     phil {
    108      1.14     phil 	DBT key, data;
    109      1.14     phil 
    110      1.14     phil 	/* initialize the exclusion table if needed. */
    111  1.14.8.1    lukem 	if(__pwexclude == (DB *)NULL) {
    112  1.14.8.1    lukem 		__pwexclude = dbopen(NULL, O_RDWR, 600, DB_HASH, NULL);
    113  1.14.8.1    lukem 		if(__pwexclude == (DB *)NULL)
    114      1.14     phil 			return(1);
    115      1.14     phil 	}
    116      1.14     phil 
    117      1.14     phil 	/* set up the key */
    118      1.14     phil 	key.data = (char *)name;
    119      1.14     phil 	key.size = strlen(name);
    120      1.14     phil 
    121      1.14     phil 	/* data is nothing. */
    122      1.14     phil 	data.data = NULL;
    123      1.14     phil 	data.size = 0;
    124      1.14     phil 
    125      1.14     phil 	/* store it */
    126  1.14.8.1    lukem 	if((__pwexclude->put)(__pwexclude, &key, &data, 0) == -1)
    127      1.14     phil 		return(1);
    128      1.14     phil 
    129      1.14     phil 	return(0);
    130      1.14     phil }
    131      1.14     phil 
    132  1.14.8.1    lukem /*
    133  1.14.8.1    lukem  * test if a name is in the compat mode exclude list
    134  1.14.8.1    lukem  */
    135      1.14     phil static int
    136  1.14.8.1    lukem __pwexclude_is(name)
    137  1.14.8.1    lukem 	const char *name;
    138      1.14     phil {
    139      1.14     phil 	DBT key, data;
    140      1.14     phil 
    141  1.14.8.1    lukem 	if(__pwexclude == (DB *)NULL)
    142      1.14     phil 		return(0);	/* nothing excluded */
    143      1.14     phil 
    144      1.14     phil 	/* set up the key */
    145      1.14     phil 	key.data = (char *)name;
    146      1.14     phil 	key.size = strlen(name);
    147      1.14     phil 
    148  1.14.8.1    lukem 	if((__pwexclude->get)(__pwexclude, &key, &data, 0) == 0)
    149      1.14     phil 		return(1);	/* excluded */
    150      1.14     phil 
    151      1.14     phil 	return(0);
    152      1.14     phil }
    153      1.14     phil 
    154  1.14.8.1    lukem /*
    155  1.14.8.1    lukem  * setup the compat mode prototype template
    156  1.14.8.1    lukem  */
    157      1.14     phil static void
    158  1.14.8.1    lukem __pwproto_set()
    159      1.14     phil {
    160      1.14     phil 	register char *ptr;
    161      1.14     phil 	register struct passwd *pw = &_pw_passwd;
    162      1.14     phil 
    163      1.14     phil 	/* make this the new prototype */
    164      1.14     phil 	ptr = (char *)prbuf;
    165      1.14     phil 
    166      1.14     phil 	/* first allocate the struct. */
    167  1.14.8.1    lukem 	__pwproto = (struct passwd *)ptr;
    168      1.14     phil 	ptr += sizeof(struct passwd);
    169      1.14     phil 
    170      1.14     phil 	/* name */
    171      1.14     phil 	if(pw->pw_name && (pw->pw_name)[0]) {
    172      1.14     phil 		ptr = (char *)ALIGN(ptr);
    173  1.14.8.1    lukem 		memmove(ptr, pw->pw_name, strlen(pw->pw_name) + 1);
    174  1.14.8.1    lukem 		__pwproto->pw_name = ptr;
    175      1.14     phil 		ptr += (strlen(pw->pw_name) + 1);
    176      1.14     phil 	} else
    177  1.14.8.1    lukem 		__pwproto->pw_name = (char *)NULL;
    178      1.14     phil 
    179      1.14     phil 	/* password */
    180      1.14     phil 	if(pw->pw_passwd && (pw->pw_passwd)[0]) {
    181      1.14     phil 		ptr = (char *)ALIGN(ptr);
    182  1.14.8.1    lukem 		memmove(ptr, pw->pw_passwd, strlen(pw->pw_passwd) + 1);
    183  1.14.8.1    lukem 		__pwproto->pw_passwd = ptr;
    184      1.14     phil 		ptr += (strlen(pw->pw_passwd) + 1);
    185      1.14     phil 	} else
    186  1.14.8.1    lukem 		__pwproto->pw_passwd = (char *)NULL;
    187      1.14     phil 
    188      1.14     phil 	/* uid */
    189  1.14.8.1    lukem 	__pwproto->pw_uid = pw->pw_uid;
    190      1.14     phil 
    191      1.14     phil 	/* gid */
    192  1.14.8.1    lukem 	__pwproto->pw_gid = pw->pw_gid;
    193      1.14     phil 
    194      1.14     phil 	/* change (ignored anyway) */
    195  1.14.8.1    lukem 	__pwproto->pw_change = pw->pw_change;
    196      1.14     phil 
    197      1.14     phil 	/* class (ignored anyway) */
    198  1.14.8.1    lukem 	__pwproto->pw_class = "";
    199      1.14     phil 
    200      1.14     phil 	/* gecos */
    201      1.14     phil 	if(pw->pw_gecos && (pw->pw_gecos)[0]) {
    202      1.14     phil 		ptr = (char *)ALIGN(ptr);
    203  1.14.8.1    lukem 		memmove(ptr, pw->pw_gecos, strlen(pw->pw_gecos) + 1);
    204  1.14.8.1    lukem 		__pwproto->pw_gecos = ptr;
    205      1.14     phil 		ptr += (strlen(pw->pw_gecos) + 1);
    206      1.14     phil 	} else
    207  1.14.8.1    lukem 		__pwproto->pw_gecos = (char *)NULL;
    208      1.14     phil 
    209      1.14     phil 	/* dir */
    210      1.14     phil 	if(pw->pw_dir && (pw->pw_dir)[0]) {
    211      1.14     phil 		ptr = (char *)ALIGN(ptr);
    212  1.14.8.1    lukem 		memmove(ptr, pw->pw_dir, strlen(pw->pw_dir) + 1);
    213  1.14.8.1    lukem 		__pwproto->pw_dir = ptr;
    214      1.14     phil 		ptr += (strlen(pw->pw_dir) + 1);
    215      1.14     phil 	} else
    216  1.14.8.1    lukem 		__pwproto->pw_dir = (char *)NULL;
    217      1.14     phil 
    218      1.14     phil 	/* shell */
    219      1.14     phil 	if(pw->pw_shell && (pw->pw_shell)[0]) {
    220      1.14     phil 		ptr = (char *)ALIGN(ptr);
    221  1.14.8.1    lukem 		memmove(ptr, pw->pw_shell, strlen(pw->pw_shell) + 1);
    222  1.14.8.1    lukem 		__pwproto->pw_shell = ptr;
    223      1.14     phil 		ptr += (strlen(pw->pw_shell) + 1);
    224      1.14     phil 	} else
    225  1.14.8.1    lukem 		__pwproto->pw_shell = (char *)NULL;
    226      1.14     phil 
    227      1.14     phil 	/* expire (ignored anyway) */
    228  1.14.8.1    lukem 	__pwproto->pw_expire = pw->pw_expire;
    229      1.14     phil 
    230      1.14     phil 	/* flags */
    231  1.14.8.1    lukem 	__pwproto_flags = _pw_flags;
    232      1.14     phil }
    233       1.4  deraadt 
    234  1.14.8.1    lukem /*
    235  1.14.8.1    lukem  * parse an old-style passwd file line (from NIS or HESIOD)
    236  1.14.8.1    lukem  */
    237       1.5  deraadt static int
    238  1.14.8.1    lukem __pwparse(pw, s)
    239  1.14.8.1    lukem 	struct passwd *pw;
    240  1.14.8.1    lukem 	char *s;
    241       1.4  deraadt {
    242       1.4  deraadt 	char *bp, *cp;
    243       1.4  deraadt 
    244      1.14     phil 	/* since this is currently using strsep(), parse it first */
    245       1.4  deraadt 	bp = s;
    246       1.4  deraadt 	pw->pw_name = strsep(&bp, ":\n");
    247       1.4  deraadt 	pw->pw_passwd = strsep(&bp, ":\n");
    248       1.4  deraadt 	if (!(cp = strsep(&bp, ":\n")))
    249       1.4  deraadt 		return 1;
    250       1.4  deraadt 	pw->pw_uid = atoi(cp);
    251       1.4  deraadt 	if (!(cp = strsep(&bp, ":\n")))
    252      1.13  mycroft 		return 1;
    253       1.4  deraadt 	pw->pw_gid = atoi(cp);
    254       1.4  deraadt 	pw->pw_change = 0;
    255       1.4  deraadt 	pw->pw_class = "";
    256       1.4  deraadt 	pw->pw_gecos = strsep(&bp, ":\n");
    257       1.4  deraadt 	pw->pw_dir = strsep(&bp, ":\n");
    258       1.4  deraadt 	pw->pw_shell = strsep(&bp, ":\n");
    259       1.4  deraadt 	pw->pw_expire = 0;
    260      1.14     phil 
    261      1.14     phil 	/* now let the prototype override, if set. */
    262  1.14.8.1    lukem 	if(__pwproto != (struct passwd *)NULL) {
    263  1.14.8.1    lukem #ifdef PW_OVERRIDE_PASSWD
    264  1.14.8.1    lukem 		if(__pwproto->pw_passwd != (char *)NULL)
    265  1.14.8.1    lukem 			pw->pw_passwd = __pwproto->pw_passwd;
    266  1.14.8.1    lukem #endif
    267  1.14.8.1    lukem 		if(!(__pwproto_flags & _PASSWORD_NOUID))
    268  1.14.8.1    lukem 			pw->pw_uid = __pwproto->pw_uid;
    269  1.14.8.1    lukem 		if(!(__pwproto_flags & _PASSWORD_NOGID))
    270  1.14.8.1    lukem 			pw->pw_gid = __pwproto->pw_gid;
    271  1.14.8.1    lukem 		if(__pwproto->pw_gecos != (char *)NULL)
    272  1.14.8.1    lukem 			pw->pw_gecos = __pwproto->pw_gecos;
    273  1.14.8.1    lukem 		if(__pwproto->pw_dir != (char *)NULL)
    274  1.14.8.1    lukem 			pw->pw_dir = __pwproto->pw_dir;
    275  1.14.8.1    lukem 		if(__pwproto->pw_shell != (char *)NULL)
    276  1.14.8.1    lukem 			pw->pw_shell = __pwproto->pw_shell;
    277      1.14     phil 	}
    278       1.4  deraadt 	return 0;
    279       1.4  deraadt }
    280  1.14.8.1    lukem #endif /* YP || HESIOD */
    281       1.4  deraadt 
    282  1.14.8.1    lukem /*
    283  1.14.8.1    lukem  * local files implementation of getpw*()
    284  1.14.8.1    lukem  * varargs: type, [ uid (type == _PW_KEYBYUID) | name (type == _PW_KEYBYNAME) ]
    285  1.14.8.1    lukem  */
    286  1.14.8.1    lukem static int
    287  1.14.8.1    lukem _local_getpw(rv, cb_data, ap)
    288  1.14.8.1    lukem 	void	*rv;
    289  1.14.8.1    lukem 	void	*cb_data;
    290  1.14.8.1    lukem 	va_list	 ap;
    291       1.1      cgd {
    292       1.1      cgd 	DBT key;
    293  1.14.8.1    lukem 	char		 bf[MAX(UT_NAMESIZE, sizeof(_pw_keynum)) + 1];
    294  1.14.8.1    lukem 	int		 search, len, uid, rval;
    295  1.14.8.1    lukem 	const char	*name;
    296  1.14.8.1    lukem 
    297       1.1      cgd 
    298       1.1      cgd 	if (!_pw_db && !__initdb())
    299  1.14.8.1    lukem 		return NS_UNAVAIL;
    300       1.1      cgd 
    301  1.14.8.1    lukem 	search = va_arg(ap, int);
    302  1.14.8.1    lukem 	bf[0] = search;
    303  1.14.8.1    lukem 	switch (search) {
    304  1.14.8.1    lukem 	case _PW_KEYBYNUM:
    305  1.14.8.1    lukem 		++_pw_keynum;
    306  1.14.8.1    lukem 		memmove(bf + 1, (char *)&_pw_keynum, sizeof(_pw_keynum));
    307  1.14.8.1    lukem 		key.size = sizeof(_pw_keynum) + 1;
    308  1.14.8.1    lukem 		break;
    309  1.14.8.1    lukem 	case _PW_KEYBYNAME:
    310  1.14.8.1    lukem 		name = va_arg(ap, const char *);
    311  1.14.8.1    lukem 		len = strlen(name);
    312  1.14.8.1    lukem 		memmove(bf + 1, name, MIN(len, UT_NAMESIZE));
    313  1.14.8.1    lukem 		key.size = len + 1;
    314  1.14.8.1    lukem 		break;
    315  1.14.8.1    lukem 	case _PW_KEYBYUID:
    316  1.14.8.1    lukem 		uid = va_arg(ap, int);
    317  1.14.8.1    lukem 		memmove(bf + 1, (char *)&uid, sizeof(len));
    318  1.14.8.1    lukem 		key.size = sizeof(uid) + 1;
    319  1.14.8.1    lukem 		break;
    320  1.14.8.1    lukem 	default:
    321  1.14.8.1    lukem 		abort();
    322  1.14.8.1    lukem 	}
    323      1.14     phil 
    324  1.14.8.1    lukem 	key.data = (u_char *)bf;
    325  1.14.8.1    lukem 	rval = __hashpw(&key);
    326  1.14.8.1    lukem 
    327  1.14.8.1    lukem 	if (!_pw_stayopen && (search != _PW_KEYBYNUM)) {
    328  1.14.8.1    lukem 		(void)(_pw_db->close)(_pw_db);
    329  1.14.8.1    lukem 		_pw_db = (DB *)NULL;
    330  1.14.8.1    lukem 	}
    331  1.14.8.1    lukem 	return (rval);
    332  1.14.8.1    lukem } /* _local_getpw */
    333  1.14.8.1    lukem 
    334  1.14.8.1    lukem #ifdef HESIOD
    335  1.14.8.1    lukem /*
    336  1.14.8.1    lukem  * hesiod implementation of getpw*()
    337  1.14.8.1    lukem  * varargs: type, [ uid (type == _PW_KEYBYUID) | name (type == _PW_KEYBYNAME) ]
    338  1.14.8.1    lukem  */
    339  1.14.8.1    lukem static int
    340  1.14.8.1    lukem _dns_getpw(rv, cb_data, ap)
    341  1.14.8.1    lukem 	void	*rv;
    342  1.14.8.1    lukem 	void	*cb_data;
    343  1.14.8.1    lukem 	va_list	 ap;
    344  1.14.8.1    lukem {
    345  1.14.8.1    lukem 	const char	 *name;
    346  1.14.8.1    lukem 	int		  uid, search;
    347  1.14.8.1    lukem 	char		**hp;
    348  1.14.8.1    lukem 
    349  1.14.8.1    lukem 
    350  1.14.8.1    lukem 	search = va_arg(ap, int);
    351  1.14.8.1    lukem 	switch (search) {
    352  1.14.8.1    lukem 	case _PW_KEYBYNUM:
    353  1.14.8.1    lukem 		snprintf(line, sizeof(line) - 1, "passwd-%d", _pw_hesnum);
    354  1.14.8.1    lukem 		_pw_hesnum++;
    355  1.14.8.1    lukem 		break;
    356  1.14.8.1    lukem 	case _PW_KEYBYNAME:
    357  1.14.8.1    lukem 		name = va_arg(ap, const char *);
    358  1.14.8.1    lukem 		strncpy(line, name, sizeof(line));
    359  1.14.8.1    lukem 		break;
    360  1.14.8.1    lukem 	case _PW_KEYBYUID:
    361  1.14.8.1    lukem 		uid = va_arg(ap, int);
    362  1.14.8.1    lukem 		sprintf(line, "%d", uid);
    363  1.14.8.1    lukem 		break;
    364  1.14.8.1    lukem 	default:
    365  1.14.8.1    lukem 		abort();
    366  1.14.8.1    lukem 	}
    367  1.14.8.1    lukem 	line[sizeof(line) - 1] = '\0';
    368  1.14.8.1    lukem 
    369  1.14.8.1    lukem 	hp = hes_resolve(line, "passwd");
    370  1.14.8.1    lukem 	if (hp == NULL) {
    371  1.14.8.1    lukem 		switch (hes_error()) {
    372  1.14.8.1    lukem 		case HES_ER_NOTFOUND:
    373  1.14.8.1    lukem 			if (search == _PW_KEYBYNUM)
    374  1.14.8.1    lukem 				_pw_hesnum = 0;
    375  1.14.8.1    lukem 			return NS_NOTFOUND;
    376  1.14.8.1    lukem 		case HES_ER_OK:
    377  1.14.8.1    lukem 			abort();
    378  1.14.8.1    lukem 		default:
    379  1.14.8.1    lukem 			return NS_UNAVAIL;
    380  1.14.8.1    lukem 		}
    381  1.14.8.1    lukem 	}
    382  1.14.8.1    lukem 
    383  1.14.8.1    lukem 	strncpy(line, hp[0], sizeof(line));	/* only check first elem */
    384  1.14.8.1    lukem 	line[sizeof(line) - 1] = '\0';
    385  1.14.8.1    lukem 	hes_free(hp);
    386  1.14.8.1    lukem 	if (__pwparse(&_pw_passwd, line))
    387  1.14.8.1    lukem 		return NS_UNAVAIL;
    388  1.14.8.1    lukem 	return NS_SUCCESS;
    389  1.14.8.1    lukem } /* _dns_getpw */
    390  1.14.8.1    lukem #endif
    391  1.14.8.1    lukem 
    392  1.14.8.1    lukem #ifdef YP
    393  1.14.8.1    lukem /*
    394  1.14.8.1    lukem  * nis implementation of getpw*()
    395  1.14.8.1    lukem  * varargs: type, [ uid (type == _PW_KEYBYUID) | name (type == _PW_KEYBYNAME) ]
    396  1.14.8.1    lukem  */
    397  1.14.8.1    lukem static int
    398  1.14.8.1    lukem _nis_getpw(rv, cb_data, ap)
    399  1.14.8.1    lukem 	void	*rv;
    400  1.14.8.1    lukem 	void	*cb_data;
    401  1.14.8.1    lukem 	va_list	 ap;
    402  1.14.8.1    lukem {
    403  1.14.8.1    lukem 	const char	*name;
    404  1.14.8.1    lukem 	int		 uid, search;
    405  1.14.8.1    lukem 	char		*key, *data;
    406  1.14.8.1    lukem 	char		*map = "passwd.byname";
    407  1.14.8.1    lukem 	int		 keylen, datalen, r;
    408  1.14.8.1    lukem 
    409  1.14.8.1    lukem 	if(__ypdomain == NULL) {
    410  1.14.8.1    lukem 		if(_yp_check(&__ypdomain) == 0)
    411  1.14.8.1    lukem 			return NS_UNAVAIL;
    412  1.14.8.1    lukem 	}
    413  1.14.8.1    lukem 
    414  1.14.8.1    lukem 	search = va_arg(ap, int);
    415  1.14.8.1    lukem 	switch (search) {
    416  1.14.8.1    lukem 	case _PW_KEYBYNUM:
    417  1.14.8.1    lukem 		break;
    418  1.14.8.1    lukem 	case _PW_KEYBYNAME:
    419  1.14.8.1    lukem 		name = va_arg(ap, const char *);
    420  1.14.8.1    lukem 		strncpy(line, name, sizeof(line));
    421  1.14.8.1    lukem 		break;
    422  1.14.8.1    lukem 	case _PW_KEYBYUID:
    423  1.14.8.1    lukem 		uid = va_arg(ap, int);
    424  1.14.8.1    lukem 		sprintf(line, "%d", uid);
    425  1.14.8.1    lukem 		map = "passwd.byuid";
    426  1.14.8.1    lukem 		break;
    427  1.14.8.1    lukem 	default:
    428  1.14.8.1    lukem 		abort();
    429       1.4  deraadt 			}
    430  1.14.8.1    lukem 	line[sizeof(line) - 1] = '\0';
    431  1.14.8.1    lukem 	if (search != _PW_KEYBYNUM) {
    432  1.14.8.1    lukem 		r = yp_match(__ypdomain, map, line, strlen(line),
    433  1.14.8.1    lukem 				&data, &datalen);
    434  1.14.8.1    lukem 		switch (r) {
    435  1.14.8.1    lukem 		case 0:
    436  1.14.8.1    lukem 			break;
    437  1.14.8.1    lukem 		case YPERR_KEY:
    438  1.14.8.1    lukem 			free(data);
    439  1.14.8.1    lukem 			return NS_NOTFOUND;
    440  1.14.8.1    lukem 		default:
    441  1.14.8.1    lukem 			free(data);
    442  1.14.8.1    lukem 			return NS_UNAVAIL;
    443  1.14.8.1    lukem 		}
    444  1.14.8.1    lukem 		data[datalen] = '\0';		/* clear trailing \n */
    445  1.14.8.1    lukem 		strncpy(line, data, sizeof(line));
    446  1.14.8.1    lukem 		line[sizeof(line) - 1] = '\0';
    447  1.14.8.1    lukem 		free(data);
    448  1.14.8.1    lukem 		if (__pwparse(&_pw_passwd, line))
    449  1.14.8.1    lukem 			return NS_UNAVAIL;
    450  1.14.8.1    lukem 		return NS_SUCCESS;
    451       1.4  deraadt 		}
    452  1.14.8.1    lukem 
    453  1.14.8.1    lukem 	for (;;) {
    454  1.14.8.1    lukem 		if (__ypcurrent) {
    455  1.14.8.1    lukem 			r = yp_next(__ypdomain, map,
    456      1.14     phil 					__ypcurrent, __ypcurrentlen,
    457      1.14     phil 					&key, &keylen, &data, &datalen);
    458      1.14     phil 				free(__ypcurrent);
    459  1.14.8.1    lukem 			switch (r) {
    460  1.14.8.1    lukem 			case 0:
    461  1.14.8.1    lukem 				break;
    462  1.14.8.1    lukem 			case YPERR_NOMORE:
    463  1.14.8.1    lukem 				__ypcurrent = NULL;
    464  1.14.8.1    lukem 				free(data);
    465  1.14.8.1    lukem 				return NS_NOTFOUND;
    466  1.14.8.1    lukem 			default:
    467  1.14.8.1    lukem 				free(data);
    468  1.14.8.1    lukem 				return NS_UNAVAIL;
    469      1.14     phil 				}
    470      1.14     phil 				__ypcurrent = key;
    471      1.14     phil 				__ypcurrentlen = keylen;
    472      1.14     phil 			} else {
    473  1.14.8.1    lukem 			if (yp_first(__ypdomain, map, &__ypcurrent,
    474  1.14.8.1    lukem 					&__ypcurrentlen, &data, &datalen)) {
    475      1.14     phil 						free(data);
    476  1.14.8.1    lukem 				return NS_UNAVAIL;
    477  1.14.8.1    lukem 			}
    478      1.14     phil 				}
    479  1.14.8.1    lukem 		data[datalen] = '\0';		/* clear trailing \n */
    480  1.14.8.1    lukem 		strncpy(line, data, sizeof(line));
    481  1.14.8.1    lukem 		line[sizeof(line) - 1] = '\0';
    482       1.4  deraadt 				free(data);
    483  1.14.8.1    lukem 		if (! __pwparse(&_pw_passwd, line))
    484  1.14.8.1    lukem 			return NS_SUCCESS;
    485      1.14     phil 			}
    486  1.14.8.1    lukem 	/* NOTREACHED */
    487  1.14.8.1    lukem } /* _nis_getpw */
    488  1.14.8.1    lukem #endif
    489  1.14.8.1    lukem 
    490  1.14.8.1    lukem #if defined(YP) || defined(HESIOD)
    491  1.14.8.1    lukem /*
    492  1.14.8.1    lukem  * See if the compat token is in the database.  Only works if pwd_mkdb knows
    493  1.14.8.1    lukem  * about the token.
    494  1.14.8.1    lukem  */
    495  1.14.8.1    lukem static int
    496  1.14.8.1    lukem __has_compatpw()
    497  1.14.8.1    lukem {
    498  1.14.8.1    lukem 	DBT key, data;
    499  1.14.8.1    lukem 	DBT pkey, pdata;
    500  1.14.8.1    lukem 	int len;
    501  1.14.8.1    lukem 	char bf[UT_NAMESIZE];
    502  1.14.8.1    lukem 
    503  1.14.8.1    lukem 	key.data = (u_char *)__yp_token;
    504  1.14.8.1    lukem 	key.size = strlen(__yp_token);
    505  1.14.8.1    lukem 
    506  1.14.8.1    lukem 	/* Pre-token database support. */
    507  1.14.8.1    lukem 	bf[0] = _PW_KEYBYNAME;
    508  1.14.8.1    lukem 	len = strlen("+");
    509  1.14.8.1    lukem 	bcopy("+", bf + 1, MIN(len, UT_NAMESIZE));
    510  1.14.8.1    lukem 	pkey.data = (u_char *)bf;
    511  1.14.8.1    lukem 	pkey.size = len + 1;
    512  1.14.8.1    lukem 
    513  1.14.8.1    lukem 	if ((_pw_db->get)(_pw_db, &key, &data, 0)
    514  1.14.8.1    lukem 	    && (_pw_db->get)(_pw_db, &pkey, &pdata, 0))
    515  1.14.8.1    lukem 		return(0);		/* No compat token */
    516  1.14.8.1    lukem 	return(1);
    517  1.14.8.1    lukem }
    518  1.14.8.1    lukem 
    519  1.14.8.1    lukem /*
    520  1.14.8.1    lukem  * log an error if "files" or "compat" is specified in passwd_compat database
    521  1.14.8.1    lukem  */
    522  1.14.8.1    lukem static int
    523  1.14.8.1    lukem _bad_getpw(rv, cb_data, ap)
    524  1.14.8.1    lukem 	void	*rv;
    525  1.14.8.1    lukem 	void	*cb_data;
    526  1.14.8.1    lukem 	va_list	 ap;
    527  1.14.8.1    lukem {
    528  1.14.8.1    lukem 	static int warned;
    529  1.14.8.1    lukem 	if (!warned) {
    530  1.14.8.1    lukem 		syslog(LOG_ERR,
    531  1.14.8.1    lukem 			"nsswitch.conf passwd_compat database can't use '%s'",
    532  1.14.8.1    lukem 			(char *)cb_data);
    533  1.14.8.1    lukem 	}
    534  1.14.8.1    lukem 	warned = 1;
    535  1.14.8.1    lukem 	return NS_UNAVAIL;
    536  1.14.8.1    lukem }
    537  1.14.8.1    lukem 
    538  1.14.8.1    lukem /*
    539  1.14.8.1    lukem  * when a name lookup in compat mode is required (e.g., '+name', or a name in
    540  1.14.8.1    lukem  * '+@netgroup'), look it up in the 'passwd_compat' nsswitch database.
    541  1.14.8.1    lukem  * only Hesiod and NIS is supported - it doesn't make sense to lookup
    542  1.14.8.1    lukem  * compat names from 'files' or 'compat'.
    543  1.14.8.1    lukem  */
    544  1.14.8.1    lukem static int
    545  1.14.8.1    lukem __getpwcompat(type, uid, name)
    546  1.14.8.1    lukem 	int		 type;
    547  1.14.8.1    lukem 	int		 uid;
    548  1.14.8.1    lukem 	const char	*name;
    549  1.14.8.1    lukem {
    550  1.14.8.1    lukem 	static ns_dtab	dtab;
    551  1.14.8.1    lukem 
    552  1.14.8.1    lukem 	NS_FILES_CB(dtab, _bad_getpw, "files");
    553  1.14.8.1    lukem 	NS_DNS_CB(dtab, _dns_getpw, NULL);
    554  1.14.8.1    lukem 	NS_NIS_CB(dtab, _nis_getpw, NULL);
    555  1.14.8.1    lukem 	NS_COMPAT_CB(dtab, _bad_getpw, "compat");
    556  1.14.8.1    lukem 
    557  1.14.8.1    lukem 	switch (type) {
    558  1.14.8.1    lukem 	case _PW_KEYBYNUM:
    559  1.14.8.1    lukem 		return nsdispatch(NULL, dtab, NSDB_PASSWD_COMPAT, type);
    560  1.14.8.1    lukem 	case _PW_KEYBYNAME:
    561  1.14.8.1    lukem 		return nsdispatch(NULL, dtab, NSDB_PASSWD_COMPAT, type, name);
    562  1.14.8.1    lukem 	case _PW_KEYBYUID:
    563  1.14.8.1    lukem 		return nsdispatch(NULL, dtab, NSDB_PASSWD_COMPAT, type, uid);
    564  1.14.8.1    lukem 	default:
    565  1.14.8.1    lukem 		abort();
    566  1.14.8.1    lukem 	}
    567  1.14.8.1    lukem }
    568  1.14.8.1    lukem 
    569  1.14.8.1    lukem /*
    570  1.14.8.1    lukem  * compat implementation of getpwent()
    571  1.14.8.1    lukem  * varargs: type, [ uid (type == _PW_KEYBYUID) | name (type == _PW_KEYBYNAME) ]
    572  1.14.8.1    lukem  */
    573  1.14.8.1    lukem static int
    574  1.14.8.1    lukem _compat_getpwent(rv, cb_data, ap)
    575  1.14.8.1    lukem 	void	*rv;
    576  1.14.8.1    lukem 	void	*cb_data;
    577  1.14.8.1    lukem 	va_list	 ap;
    578  1.14.8.1    lukem {
    579  1.14.8.1    lukem 	DBT		 key;
    580  1.14.8.1    lukem 	char		 bf[sizeof(_pw_keynum) + 1];
    581  1.14.8.1    lukem 	static char	*name = (char *)NULL;
    582  1.14.8.1    lukem 	const char	*user, *host, *dom;
    583  1.14.8.1    lukem 	int		 has_compatpw;
    584  1.14.8.1    lukem 
    585  1.14.8.1    lukem 	if (!_pw_db && !__initdb())
    586  1.14.8.1    lukem 		return(NS_UNAVAIL);
    587  1.14.8.1    lukem 
    588  1.14.8.1    lukem 	has_compatpw = __has_compatpw();
    589  1.14.8.1    lukem 
    590  1.14.8.1    lukem again:
    591  1.14.8.1    lukem 	if (has_compatpw && (__pwmode != PWMODE_NONE)) {
    592  1.14.8.1    lukem 		int r;
    593  1.14.8.1    lukem 
    594  1.14.8.1    lukem 		switch (__pwmode) {
    595  1.14.8.1    lukem 		case PWMODE_FULL:
    596  1.14.8.1    lukem 			r = __getpwcompat(_PW_KEYBYNUM, 0, NULL);
    597  1.14.8.1    lukem 			if (r == NS_SUCCESS)
    598  1.14.8.1    lukem 				return(r);
    599  1.14.8.1    lukem 			__pwmode = PWMODE_NONE;
    600      1.14     phil 			break;
    601  1.14.8.1    lukem 		case PWMODE_NETGRP:
    602  1.14.8.1    lukem 			r = getnetgrent(&host, &user, &dom);
    603  1.14.8.1    lukem 			if (r == 0) {	/* end of group */
    604      1.14     phil 				endnetgrent();
    605  1.14.8.1    lukem 				__pwmode = PWMODE_NONE;
    606  1.14.8.1    lukem 				break;
    607       1.4  deraadt 			}
    608  1.14.8.1    lukem 			if (!user || !*user)
    609  1.14.8.1    lukem 				break;
    610  1.14.8.1    lukem 			r = __getpwcompat(_PW_KEYBYNAME, 0, user);
    611  1.14.8.1    lukem 			if (r == NS_SUCCESS)
    612  1.14.8.1    lukem 				return(r);
    613      1.14     phil 			break;
    614  1.14.8.1    lukem 		case PWMODE_USER:
    615  1.14.8.1    lukem 			if(name == (char *)NULL) {
    616  1.14.8.1    lukem 				__pwmode = PWMODE_NONE;
    617  1.14.8.1    lukem 				break;
    618       1.4  deraadt 			}
    619  1.14.8.1    lukem 			r = __getpwcompat(_PW_KEYBYNAME, 0, name);
    620  1.14.8.1    lukem 			free(name);
    621  1.14.8.1    lukem 			name = (char *)NULL;
    622  1.14.8.1    lukem 			if (r == NS_SUCCESS)
    623  1.14.8.1    lukem 				return(r);
    624      1.14     phil 			break;
    625  1.14.8.1    lukem 		case PWMODE_NONE:
    626  1.14.8.1    lukem 			abort();
    627       1.4  deraadt 		}
    628  1.14.8.1    lukem 		goto again;
    629       1.4  deraadt 	}
    630       1.4  deraadt 
    631       1.1      cgd 	++_pw_keynum;
    632       1.1      cgd 	bf[0] = _PW_KEYBYNUM;
    633       1.1      cgd 	bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum));
    634       1.1      cgd 	key.data = (u_char *)bf;
    635       1.1      cgd 	key.size = sizeof(_pw_keynum) + 1;
    636  1.14.8.1    lukem 	if(__hashpw(&key) == NS_SUCCESS) {
    637      1.14     phil 		/* if we don't have YP at all, don't bother. */
    638  1.14.8.1    lukem 		if(has_compatpw) {
    639      1.14     phil 			if(_pw_passwd.pw_name[0] == '+') {
    640      1.14     phil 				/* set the mode */
    641      1.14     phil 				switch(_pw_passwd.pw_name[1]) {
    642      1.14     phil 				case '\0':
    643  1.14.8.1    lukem 					__pwmode = PWMODE_FULL;
    644      1.14     phil 					break;
    645      1.14     phil 				case '@':
    646  1.14.8.1    lukem 					__pwmode = PWMODE_NETGRP;
    647      1.14     phil 					setnetgrent(_pw_passwd.pw_name + 2);
    648      1.14     phil 					break;
    649      1.14     phil 				default:
    650  1.14.8.1    lukem 					__pwmode = PWMODE_USER;
    651      1.14     phil 					name = strdup(_pw_passwd.pw_name + 1);
    652      1.14     phil 					break;
    653      1.14     phil 				}
    654      1.14     phil 
    655      1.14     phil 				/* save the prototype */
    656  1.14.8.1    lukem 				__pwproto_set();
    657      1.14     phil 				goto again;
    658      1.14     phil 			} else if(_pw_passwd.pw_name[0] == '-') {
    659      1.14     phil 				/* an attempted exclusion */
    660      1.14     phil 				switch(_pw_passwd.pw_name[1]) {
    661      1.14     phil 				case '\0':
    662      1.14     phil 					break;
    663      1.14     phil 				case '@':
    664      1.14     phil 					setnetgrent(_pw_passwd.pw_name + 2);
    665      1.14     phil 					while(getnetgrent(&host, &user, &dom)) {
    666      1.14     phil 						if(user && *user)
    667  1.14.8.1    lukem 							__pwexclude_add(user);
    668      1.14     phil 					}
    669      1.14     phil 					endnetgrent();
    670      1.14     phil 					break;
    671      1.14     phil 				default:
    672  1.14.8.1    lukem 					__pwexclude_add(_pw_passwd.pw_name + 1);
    673      1.14     phil 					break;
    674      1.14     phil 				}
    675      1.14     phil 				goto again;
    676      1.14     phil 			}
    677       1.4  deraadt 		}
    678  1.14.8.1    lukem 		return(NS_SUCCESS);
    679       1.4  deraadt 	}
    680  1.14.8.1    lukem 	return(NS_NOTFOUND);
    681       1.1      cgd }
    682       1.1      cgd 
    683      1.14     phil /*
    684  1.14.8.1    lukem  * compat implementation of getpwnam() & getpwuid()
    685  1.14.8.1    lukem  * varargs: type, [ uid (type == _PW_KEYBYUID) | name (type == _PW_KEYBYNAME) ]
    686      1.14     phil  */
    687      1.14     phil static int
    688  1.14.8.1    lukem _compat_getpw(rv, cb_data, ap)
    689  1.14.8.1    lukem 	void	*rv;
    690  1.14.8.1    lukem 	void	*cb_data;
    691  1.14.8.1    lukem 	va_list	 ap;
    692       1.1      cgd {
    693       1.1      cgd 	DBT key;
    694  1.14.8.1    lukem 	int		 len;
    695      1.10  deraadt 	char bf[UT_NAMESIZE + 1];
    696      1.10  deraadt 
    697  1.14.8.1    lukem 	int		 search = va_arg(ap, int);
    698  1.14.8.1    lukem 	int		 uid = 0;
    699  1.14.8.1    lukem 	const char	*name = (char *)NULL;
    700  1.14.8.1    lukem 	int		 rval = NS_NOTFOUND;
    701  1.14.8.1    lukem 
    702      1.10  deraadt 	if (!_pw_db && !__initdb())
    703  1.14.8.1    lukem 		return(NS_UNAVAIL);
    704  1.14.8.1    lukem 
    705  1.14.8.1    lukem 	switch (search) {
    706  1.14.8.1    lukem 	case _PW_KEYBYNAME:
    707  1.14.8.1    lukem 		name = va_arg(ap, const char *);
    708  1.14.8.1    lukem 		break;
    709  1.14.8.1    lukem 	case _PW_KEYBYUID:
    710  1.14.8.1    lukem 		uid = va_arg(ap, int);
    711  1.14.8.1    lukem 		break;
    712  1.14.8.1    lukem 	default:
    713  1.14.8.1    lukem 		abort();
    714  1.14.8.1    lukem 	}
    715       1.4  deraadt 
    716      1.10  deraadt 	/*
    717      1.14     phil 	 * If YP is active, we must sequence through the passwd file
    718      1.14     phil 	 * in sequence.
    719      1.10  deraadt 	 */
    720  1.14.8.1    lukem 	if (__has_compatpw()) {
    721      1.10  deraadt 		int r;
    722      1.14     phil 		int s = -1;
    723      1.14     phil 		const char *host, *user, *dom;
    724       1.4  deraadt 
    725      1.10  deraadt 		for(_pw_keynum=1; _pw_keynum; _pw_keynum++) {
    726      1.10  deraadt 			bf[0] = _PW_KEYBYNUM;
    727      1.10  deraadt 			bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum));
    728      1.10  deraadt 			key.data = (u_char *)bf;
    729      1.10  deraadt 			key.size = sizeof(_pw_keynum) + 1;
    730  1.14.8.1    lukem 			if(__hashpw(&key) != NS_SUCCESS)
    731      1.10  deraadt 				break;
    732      1.14     phil 			switch(_pw_passwd.pw_name[0]) {
    733      1.14     phil 			case '+':
    734      1.14     phil 				/* save the prototype */
    735  1.14.8.1    lukem 				__pwproto_set();
    736      1.14     phil 
    737      1.14     phil 				switch(_pw_passwd.pw_name[1]) {
    738      1.14     phil 				case '\0':
    739  1.14.8.1    lukem 					r = __getpwcompat(search, uid, name);
    740  1.14.8.1    lukem 					if (r != NS_SUCCESS)
    741      1.14     phil 						continue;
    742      1.14     phil 					break;
    743      1.14     phil 				case '@':
    744      1.14     phil pwnam_netgrp:
    745      1.14     phil 					if(s == -1)	/* first time */
    746      1.14     phil 						setnetgrent(_pw_passwd.pw_name + 2);
    747      1.14     phil 					s = getnetgrent(&host, &user, &dom);
    748      1.14     phil 					if(s == 0) {	/* end of group */
    749      1.14     phil 						endnetgrent();
    750      1.14     phil 						s = -1;
    751      1.14     phil 						continue;
    752  1.14.8.1    lukem 					}
    753  1.14.8.1    lukem 					if(!user || !*user)
    754      1.14     phil 							goto pwnam_netgrp;
    755  1.14.8.1    lukem 
    756  1.14.8.1    lukem 					r = __getpwcompat(_PW_KEYBYNAME,
    757  1.14.8.1    lukem 								0, user);
    758  1.14.8.1    lukem 					if (r == NS_UNAVAIL)
    759  1.14.8.1    lukem 						return(r);
    760  1.14.8.1    lukem 					if (r == NS_NOTFOUND)
    761      1.14     phil 							/*
    762  1.14.8.1    lukem 						 * just because this user is bad
    763  1.14.8.1    lukem 						 * doesn't mean they all are
    764      1.14     phil 							 */
    765      1.14     phil 							goto pwnam_netgrp;
    766      1.10  deraadt 					break;
    767      1.10  deraadt 				default:
    768      1.14     phil 					user = _pw_passwd.pw_name + 1;
    769  1.14.8.1    lukem 					r = __getpwcompat(_PW_KEYBYNAME,
    770  1.14.8.1    lukem 								0, user);
    771  1.14.8.1    lukem 					if (r == NS_UNAVAIL)
    772  1.14.8.1    lukem 						return(r);
    773  1.14.8.1    lukem 					if (r == NS_NOTFOUND)
    774      1.14     phil 						continue;
    775      1.14     phil 					break;
    776       1.4  deraadt 				}
    777  1.14.8.1    lukem 				if(__pwexclude_is(_pw_passwd.pw_name)) {
    778  1.14.8.1    lukem 					if (s == 1)	/* inside netgrp */
    779      1.14     phil 						goto pwnam_netgrp;
    780      1.10  deraadt 					continue;
    781      1.14     phil 				}
    782      1.14     phil 				break;
    783      1.14     phil 			case '-':
    784      1.14     phil 				/* attempted exclusion */
    785      1.14     phil 				switch(_pw_passwd.pw_name[1]) {
    786      1.14     phil 				case '\0':
    787      1.14     phil 					break;
    788      1.14     phil 				case '@':
    789      1.14     phil 					setnetgrent(_pw_passwd.pw_name + 2);
    790      1.14     phil 					while(getnetgrent(&host, &user, &dom)) {
    791      1.14     phil 						if(user && *user)
    792  1.14.8.1    lukem 							__pwexclude_add(user);
    793      1.14     phil 					}
    794      1.14     phil 					endnetgrent();
    795      1.14     phil 					break;
    796      1.14     phil 				default:
    797  1.14.8.1    lukem 					__pwexclude_add(_pw_passwd.pw_name + 1);
    798      1.14     phil 					break;
    799      1.14     phil 				}
    800      1.14     phil 				break;
    801      1.14     phil 
    802      1.14     phil 				continue;
    803       1.4  deraadt 			}
    804  1.14.8.1    lukem 			if ((search == _PW_KEYBYNAME &&
    805  1.14.8.1    lukem 					strcmp(_pw_passwd.pw_name, name) == 0)
    806  1.14.8.1    lukem 				|| (search == _PW_KEYBYUID &&
    807  1.14.8.1    lukem 					_pw_passwd.pw_uid == uid)) {
    808  1.14.8.1    lukem 				rval = NS_SUCCESS;
    809  1.14.8.1    lukem 				break;
    810       1.4  deraadt 			}
    811      1.14     phil 			if(s == 1)	/* inside netgrp */
    812      1.14     phil 				goto pwnam_netgrp;
    813      1.10  deraadt 			continue;
    814       1.4  deraadt 		}
    815  1.14.8.1    lukem 		__pwproto = (struct passwd *)NULL;
    816  1.14.8.1    lukem 	} else {
    817  1.14.8.1    lukem 		bf[0] = _PW_KEYBYNAME;
    818  1.14.8.1    lukem 		len = strlen(name);
    819  1.14.8.1    lukem 		bcopy(name, bf + 1, MIN(len, UT_NAMESIZE));
    820  1.14.8.1    lukem 		key.data = (u_char *)bf;
    821  1.14.8.1    lukem 		key.size = len + 1;
    822  1.14.8.1    lukem 		rval = __hashpw(&key);
    823       1.4  deraadt 	}
    824       1.1      cgd 
    825       1.1      cgd 	if (!_pw_stayopen) {
    826       1.1      cgd 		(void)(_pw_db->close)(_pw_db);
    827       1.1      cgd 		_pw_db = (DB *)NULL;
    828       1.1      cgd 	}
    829  1.14.8.1    lukem 	if(__pwexclude != (DB *)NULL) {
    830  1.14.8.1    lukem 		(void)(__pwexclude->close)(__pwexclude);
    831  1.14.8.1    lukem 		__pwexclude = (DB *)NULL;
    832  1.14.8.1    lukem 	}
    833  1.14.8.1    lukem 	return rval;
    834       1.1      cgd }
    835  1.14.8.1    lukem #endif /* YP || HESIOD */
    836       1.1      cgd 
    837       1.1      cgd struct passwd *
    838  1.14.8.1    lukem getpwent()
    839       1.1      cgd {
    840  1.14.8.1    lukem 	int		r;
    841  1.14.8.1    lukem 	static ns_dtab	dtab;
    842      1.10  deraadt 
    843  1.14.8.1    lukem 	NS_FILES_CB(dtab, _local_getpw, NULL);
    844  1.14.8.1    lukem 	NS_DNS_CB(dtab, _dns_getpw, NULL);
    845  1.14.8.1    lukem 	NS_NIS_CB(dtab, _nis_getpw, NULL);
    846  1.14.8.1    lukem 	NS_COMPAT_CB(dtab, _compat_getpwent, NULL);
    847       1.4  deraadt 
    848  1.14.8.1    lukem 	r = nsdispatch(NULL, dtab, NSDB_PASSWD, _PW_KEYBYNUM);
    849  1.14.8.1    lukem 	return (r == NS_SUCCESS ? &_pw_passwd : (struct passwd *)NULL);
    850  1.14.8.1    lukem }
    851       1.4  deraadt 
    852  1.14.8.1    lukem struct passwd *
    853  1.14.8.1    lukem getpwnam(name)
    854  1.14.8.1    lukem 	const char *name;
    855  1.14.8.1    lukem {
    856  1.14.8.1    lukem 		int r;
    857  1.14.8.1    lukem 	static ns_dtab	dtab;
    858      1.14     phil 
    859  1.14.8.1    lukem 	NS_FILES_CB(dtab, _local_getpw, NULL);
    860  1.14.8.1    lukem 	NS_DNS_CB(dtab, _dns_getpw, NULL);
    861  1.14.8.1    lukem 	NS_NIS_CB(dtab, _nis_getpw, NULL);
    862  1.14.8.1    lukem 	NS_COMPAT_CB(dtab, _compat_getpw, NULL);
    863      1.14     phil 
    864  1.14.8.1    lukem 	if (name == NULL || name[0] == '\0')
    865      1.10  deraadt 		return (struct passwd *)NULL;
    866       1.1      cgd 
    867  1.14.8.1    lukem 	r = nsdispatch(NULL, dtab, NSDB_PASSWD, _PW_KEYBYNAME, name);
    868  1.14.8.1    lukem 	return (r == NS_SUCCESS ? &_pw_passwd : (struct passwd *)NULL);
    869  1.14.8.1    lukem }
    870       1.1      cgd 
    871  1.14.8.1    lukem struct passwd *
    872  1.14.8.1    lukem getpwuid(uid)
    873  1.14.8.1    lukem 	uid_t uid;
    874  1.14.8.1    lukem {
    875  1.14.8.1    lukem 	int		r;
    876  1.14.8.1    lukem 	static ns_dtab	dtab;
    877  1.14.8.1    lukem 
    878  1.14.8.1    lukem 	NS_FILES_CB(dtab, _local_getpw, NULL);
    879  1.14.8.1    lukem 	NS_DNS_CB(dtab, _dns_getpw, NULL);
    880  1.14.8.1    lukem 	NS_NIS_CB(dtab, _nis_getpw, NULL);
    881  1.14.8.1    lukem 	NS_COMPAT_CB(dtab, _compat_getpw, NULL);
    882  1.14.8.1    lukem 
    883  1.14.8.1    lukem 	r = nsdispatch(NULL, dtab, NSDB_PASSWD, _PW_KEYBYUID, (int)uid);
    884  1.14.8.1    lukem 	return (r == NS_SUCCESS ? &_pw_passwd : (struct passwd *)NULL);
    885       1.1      cgd }
    886       1.1      cgd 
    887       1.1      cgd int
    888       1.1      cgd setpassent(stayopen)
    889       1.1      cgd 	int stayopen;
    890       1.1      cgd {
    891       1.1      cgd 	_pw_keynum = 0;
    892       1.1      cgd 	_pw_stayopen = stayopen;
    893       1.9      jtc #ifdef YP
    894  1.14.8.1    lukem 	__pwmode = PWMODE_NONE;
    895       1.9      jtc 	if(__ypcurrent)
    896       1.9      jtc 		free(__ypcurrent);
    897       1.9      jtc 	__ypcurrent = NULL;
    898  1.14.8.1    lukem #endif
    899  1.14.8.1    lukem #ifdef HESIOD
    900  1.14.8.1    lukem 	_pw_hesnum = 0;
    901  1.14.8.1    lukem #endif
    902  1.14.8.1    lukem #if defined(YP) || defined(HESIOD)
    903  1.14.8.1    lukem 	if(__pwexclude != (DB *)NULL) {
    904  1.14.8.1    lukem 		(void)(__pwexclude->close)(__pwexclude);
    905  1.14.8.1    lukem 		__pwexclude = (DB *)NULL;
    906      1.14     phil 	}
    907  1.14.8.1    lukem 	__pwproto = (struct passwd *)NULL;
    908       1.9      jtc #endif
    909       1.1      cgd 	return(1);
    910       1.1      cgd }
    911       1.1      cgd 
    912       1.8      jtc void
    913       1.1      cgd setpwent()
    914       1.1      cgd {
    915       1.9      jtc 	(void) setpassent(0);
    916       1.1      cgd }
    917       1.1      cgd 
    918       1.1      cgd void
    919       1.1      cgd endpwent()
    920       1.1      cgd {
    921       1.1      cgd 	_pw_keynum = 0;
    922       1.1      cgd 	if (_pw_db) {
    923       1.1      cgd 		(void)(_pw_db->close)(_pw_db);
    924       1.1      cgd 		_pw_db = (DB *)NULL;
    925       1.1      cgd 	}
    926       1.4  deraadt #ifdef YP
    927  1.14.8.1    lukem 	__pwmode = PWMODE_NONE;
    928       1.4  deraadt 	if(__ypcurrent)
    929       1.4  deraadt 		free(__ypcurrent);
    930       1.4  deraadt 	__ypcurrent = NULL;
    931  1.14.8.1    lukem #endif
    932  1.14.8.1    lukem #ifdef HESIOD
    933  1.14.8.1    lukem 	_pw_hesnum = 0;
    934  1.14.8.1    lukem #endif
    935  1.14.8.1    lukem #if defined(YP) || defined(HESIOD)
    936  1.14.8.1    lukem 	if(__pwexclude != (DB *)NULL) {
    937  1.14.8.1    lukem 		(void)(__pwexclude->close)(__pwexclude);
    938  1.14.8.1    lukem 		__pwexclude = (DB *)NULL;
    939      1.14     phil 	}
    940  1.14.8.1    lukem 	__pwproto = (struct passwd *)NULL;
    941       1.4  deraadt #endif
    942       1.1      cgd }
    943       1.1      cgd 
    944       1.4  deraadt static int
    945       1.1      cgd __initdb()
    946       1.1      cgd {
    947       1.1      cgd 	static int warned;
    948       1.1      cgd 	char *p;
    949       1.1      cgd 
    950  1.14.8.1    lukem #if defined(YP) || defined(HESIOD)
    951  1.14.8.1    lukem 	__pwmode = PWMODE_NONE;
    952      1.14     phil #endif
    953       1.1      cgd 	p = (geteuid()) ? _PATH_MP_DB : _PATH_SMP_DB;
    954       1.3   proven 	_pw_db = dbopen(p, O_RDONLY, 0, DB_HASH, NULL);
    955       1.1      cgd 	if (_pw_db)
    956       1.1      cgd 		return(1);
    957       1.1      cgd 	if (!warned)
    958       1.1      cgd 		syslog(LOG_ERR, "%s: %m", p);
    959      1.11  deraadt 	warned = 1;
    960       1.1      cgd 	return(0);
    961       1.1      cgd }
    962       1.1      cgd 
    963       1.4  deraadt static int
    964       1.1      cgd __hashpw(key)
    965       1.1      cgd 	DBT *key;
    966       1.1      cgd {
    967       1.1      cgd 	register char *p, *t;
    968       1.1      cgd 	static u_int max;
    969       1.1      cgd 	static char *line;
    970       1.1      cgd 	DBT data;
    971       1.1      cgd 
    972  1.14.8.1    lukem 	switch ((_pw_db->get)(_pw_db, key, &data, 0)) {
    973  1.14.8.1    lukem 	case 0:
    974  1.14.8.1    lukem 		break;			/* found */
    975  1.14.8.1    lukem 	case 1:
    976  1.14.8.1    lukem 		return NS_NOTFOUND;	/* not found */
    977  1.14.8.1    lukem 	case -1:
    978  1.14.8.1    lukem 		return NS_UNAVAIL;	/* error in db routines */
    979  1.14.8.1    lukem 	default:
    980  1.14.8.1    lukem 		abort();
    981  1.14.8.1    lukem 	}
    982  1.14.8.1    lukem 
    983       1.1      cgd 	p = (char *)data.data;
    984      1.14     phil 	if (data.size > max && !(line = realloc(line, (max += 1024))))
    985  1.14.8.1    lukem 		return NS_UNAVAIL;
    986       1.1      cgd 
    987       1.1      cgd 	t = line;
    988      1.14     phil #define	EXPAND(e)	e = t; while ((*t++ = *p++));
    989       1.1      cgd 	EXPAND(_pw_passwd.pw_name);
    990       1.1      cgd 	EXPAND(_pw_passwd.pw_passwd);
    991  1.14.8.1    lukem 	memmove((char *)&_pw_passwd.pw_uid, p, sizeof(int));
    992       1.1      cgd 	p += sizeof(int);
    993  1.14.8.1    lukem 	memmove((char *)&_pw_passwd.pw_gid, p, sizeof(int));
    994       1.1      cgd 	p += sizeof(int);
    995  1.14.8.1    lukem 	memmove((char *)&_pw_passwd.pw_change, p, sizeof(time_t));
    996       1.1      cgd 	p += sizeof(time_t);
    997       1.1      cgd 	EXPAND(_pw_passwd.pw_class);
    998       1.1      cgd 	EXPAND(_pw_passwd.pw_gecos);
    999       1.1      cgd 	EXPAND(_pw_passwd.pw_dir);
   1000       1.1      cgd 	EXPAND(_pw_passwd.pw_shell);
   1001  1.14.8.1    lukem 	memmove((char *)&_pw_passwd.pw_expire, p, sizeof(time_t));
   1002       1.1      cgd 	p += sizeof(time_t);
   1003      1.14     phil 
   1004      1.14     phil 	/* See if there's any data left.  If so, read in flags. */
   1005      1.14     phil 	if (data.size > (p - (char *)data.data)) {
   1006  1.14.8.1    lukem 		memmove((char *)&_pw_flags, p, sizeof(int));
   1007      1.14     phil 		p += sizeof(int);
   1008      1.14     phil 	} else
   1009      1.14     phil 		_pw_flags = _PASSWORD_NOUID|_PASSWORD_NOGID;	/* default */
   1010      1.14     phil 
   1011  1.14.8.1    lukem 	return NS_SUCCESS;
   1012       1.1      cgd }
   1013