158f0484fSRodney W. Grimes /* 258f0484fSRodney W. Grimes * Copyright (c) 1988, 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. 1358f0484fSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 1458f0484fSRodney W. Grimes * must display the following acknowledgement: 1558f0484fSRodney W. Grimes * This product includes software developed by the University of 1658f0484fSRodney W. Grimes * California, Berkeley and its contributors. 1758f0484fSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 1858f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software 1958f0484fSRodney W. Grimes * without specific prior written permission. 2058f0484fSRodney W. Grimes * 2158f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2258f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2358f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2458f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2558f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2658f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2758f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2858f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2958f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3058f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3158f0484fSRodney W. Grimes * SUCH DAMAGE. 3258f0484fSRodney W. Grimes */ 3358f0484fSRodney W. Grimes 3458f0484fSRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint) 35adf6ad9eSPeter Wemm static char sccsid[] = "@(#)getpwent.c 8.2 (Berkeley) 4/27/95"; 3658f0484fSRodney W. Grimes #endif /* LIBC_SCCS and not lint */ 3758f0484fSRodney W. Grimes 38958f4e36SBill Paul #include <stdio.h> 3958f0484fSRodney W. Grimes #include <sys/param.h> 4058f0484fSRodney W. Grimes #include <fcntl.h> 4158f0484fSRodney W. Grimes #include <db.h> 4258f0484fSRodney W. Grimes #include <syslog.h> 4358f0484fSRodney W. Grimes #include <pwd.h> 4458f0484fSRodney W. Grimes #include <utmp.h> 4558f0484fSRodney W. Grimes #include <errno.h> 4658f0484fSRodney W. Grimes #include <unistd.h> 4758f0484fSRodney W. Grimes #include <stdlib.h> 4858f0484fSRodney W. Grimes #include <string.h> 4958f0484fSRodney W. Grimes #include <limits.h> 50958f4e36SBill Paul #include <grp.h> 5158f0484fSRodney W. Grimes 5251295a4dSJordan K. Hubbard extern void setnetgrent __P(( char * )); 5351295a4dSJordan K. Hubbard extern int getnetgrent __P(( char **, char **, char ** )); 5451295a4dSJordan K. Hubbard extern int innetgr __P(( const char *, const char *, const char *, const char * )); 5551295a4dSJordan K. Hubbard 56adf6ad9eSPeter Wemm /* 57adf6ad9eSPeter Wemm * The lookup techniques and data extraction code here must be kept 58adf6ad9eSPeter Wemm * in sync with that in `pwd_mkdb'. 59adf6ad9eSPeter Wemm */ 60adf6ad9eSPeter Wemm 6158f0484fSRodney W. Grimes static struct passwd _pw_passwd; /* password structure */ 6258f0484fSRodney W. Grimes static DB *_pw_db; /* password database */ 6358f0484fSRodney W. Grimes static int _pw_keynum; /* key counter */ 6458f0484fSRodney W. Grimes static int _pw_stayopen; /* keep fd's open */ 65d5b7518dSGarrett Wollman #ifdef YP 66958f4e36SBill Paul #include <rpc/rpc.h> 67958f4e36SBill Paul #include <rpcsvc/yp_prot.h> 68958f4e36SBill Paul #include <rpcsvc/ypclnt.h> 6994c53e1fSBill Paul 70d5b7518dSGarrett Wollman static struct passwd _pw_copy; 7194c53e1fSBill Paul static DBT empty = { NULL, 0 }; 7294c53e1fSBill Paul static DB *_ypcache = (DB *)NULL; 7394c53e1fSBill Paul static int _yp_exclusions = 0; 74d5b7518dSGarrett Wollman static int _yp_enabled; /* set true when yp enabled */ 75d5b7518dSGarrett Wollman static int _pw_stepping_yp; /* set true when stepping thru map */ 7694c53e1fSBill Paul static char _ypnam[YPMAXRECORD]; 772be5d4cbSBill Paul #define YP_HAVE_MASTER 2 782be5d4cbSBill Paul #define YP_HAVE_ADJUNCT 1 792be5d4cbSBill Paul #define YP_HAVE_NONE 0 803948edc2SBill Paul static int _gotmaster; 813948edc2SBill Paul static char *_pw_yp_domain; 8294c53e1fSBill Paul static inline int unwind __P(( char * )); 8394c53e1fSBill Paul static inline void _ypinitdb __P(( void )); 8494c53e1fSBill Paul static int _havemaster __P((char *)); 8594c53e1fSBill Paul static int _getyppass __P((struct passwd *, const char *, const char * )); 8694c53e1fSBill Paul static int _nextyppass __P((struct passwd *)); 873948edc2SBill Paul #endif 883948edc2SBill Paul static int __hashpw(), __initdb(); 89d5b7518dSGarrett Wollman 9058f0484fSRodney W. Grimes struct passwd * 9158f0484fSRodney W. Grimes getpwent() 9258f0484fSRodney W. Grimes { 9358f0484fSRodney W. Grimes DBT key; 9458f0484fSRodney W. Grimes char bf[sizeof(_pw_keynum) + 1]; 95d5b7518dSGarrett Wollman int rv; 9658f0484fSRodney W. Grimes 9758f0484fSRodney W. Grimes if (!_pw_db && !__initdb()) 9858f0484fSRodney W. Grimes return((struct passwd *)NULL); 9958f0484fSRodney W. Grimes 100d5b7518dSGarrett Wollman #ifdef YP 101d5b7518dSGarrett Wollman if(_pw_stepping_yp) { 102d5b7518dSGarrett Wollman _pw_passwd = _pw_copy; 10394c53e1fSBill Paul if (unwind((char *)&_ypnam)) 104d454389cSBill Paul return(&_pw_passwd); 105d5b7518dSGarrett Wollman } 106958f4e36SBill Paul #endif 107d454389cSBill Paul tryagain: 108d454389cSBill Paul 10958f0484fSRodney W. Grimes ++_pw_keynum; 11058f0484fSRodney W. Grimes bf[0] = _PW_KEYBYNUM; 11158f0484fSRodney W. Grimes bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum)); 11258f0484fSRodney W. Grimes key.data = (u_char *)bf; 11358f0484fSRodney W. Grimes key.size = sizeof(_pw_keynum) + 1; 114d5b7518dSGarrett Wollman rv = __hashpw(&key); 115d5b7518dSGarrett Wollman if(!rv) return (struct passwd *)NULL; 116d5b7518dSGarrett Wollman #ifdef YP 11782844700SBill Paul if(_pw_passwd.pw_name[0] == '+' || _pw_passwd.pw_name[0] == '-') { 11894c53e1fSBill Paul bzero((char *)&_ypnam, sizeof(_ypnam)); 11994c53e1fSBill Paul bcopy(_pw_passwd.pw_name, _ypnam, 12094c53e1fSBill Paul strlen(_pw_passwd.pw_name)); 121d5b7518dSGarrett Wollman _pw_copy = _pw_passwd; 12294c53e1fSBill Paul if (unwind((char *)&_ypnam) == 0) 123d454389cSBill Paul goto tryagain; 124d454389cSBill Paul else 125d454389cSBill Paul return(&_pw_passwd); 126d5b7518dSGarrett Wollman } 127d5b7518dSGarrett Wollman #else 128d5b7518dSGarrett Wollman /* Ignore YP password file entries when YP is disabled. */ 12982844700SBill Paul if(_pw_passwd.pw_name[0] == '+' || _pw_passwd.pw_name[0] == '-') { 130d5b7518dSGarrett Wollman goto tryagain; 131d5b7518dSGarrett Wollman } 132d5b7518dSGarrett Wollman #endif 133d5b7518dSGarrett Wollman return(&_pw_passwd); 13458f0484fSRodney W. Grimes } 13558f0484fSRodney W. Grimes 13658f0484fSRodney W. Grimes struct passwd * 13758f0484fSRodney W. Grimes getpwnam(name) 13858f0484fSRodney W. Grimes const char *name; 13958f0484fSRodney W. Grimes { 14058f0484fSRodney W. Grimes DBT key; 14158f0484fSRodney W. Grimes int len, rval; 142d5b7518dSGarrett Wollman char bf[UT_NAMESIZE + 2]; 14358f0484fSRodney W. Grimes 14458f0484fSRodney W. Grimes if (!_pw_db && !__initdb()) 14558f0484fSRodney W. Grimes return((struct passwd *)NULL); 14658f0484fSRodney W. Grimes 14758f0484fSRodney W. Grimes bf[0] = _PW_KEYBYNAME; 14858f0484fSRodney W. Grimes len = strlen(name); 14958f0484fSRodney W. Grimes bcopy(name, bf + 1, MIN(len, UT_NAMESIZE)); 15058f0484fSRodney W. Grimes key.data = (u_char *)bf; 15158f0484fSRodney W. Grimes key.size = len + 1; 15258f0484fSRodney W. Grimes rval = __hashpw(&key); 15358f0484fSRodney W. Grimes 154d5b7518dSGarrett Wollman #ifdef YP 1555f115c9dSBill Paul if (!rval && _yp_enabled) 156d5b7518dSGarrett Wollman rval = _getyppass(&_pw_passwd, name, "passwd.byname"); 157c7da24ddSGarrett Wollman #endif 158d5b7518dSGarrett Wollman /* 159d5b7518dSGarrett Wollman * Prevent login attempts when YP is not enabled but YP entries 160d5b7518dSGarrett Wollman * are in /etc/master.passwd. 161d5b7518dSGarrett Wollman */ 16282844700SBill Paul if (rval && (_pw_passwd.pw_name[0] == '+'|| 16382844700SBill Paul _pw_passwd.pw_name[0] == '-')) rval = 0; 164bb38a730SGarrett Wollman 1659531ca93SBill Paul endpwent(); 16658f0484fSRodney W. Grimes return(rval ? &_pw_passwd : (struct passwd *)NULL); 16758f0484fSRodney W. Grimes } 16858f0484fSRodney W. Grimes 16958f0484fSRodney W. Grimes struct passwd * 17058f0484fSRodney W. Grimes getpwuid(uid) 171adf6ad9eSPeter Wemm uid_t uid; 17258f0484fSRodney W. Grimes { 17358f0484fSRodney W. Grimes DBT key; 17458f0484fSRodney W. Grimes int keyuid, rval; 17558f0484fSRodney W. Grimes char bf[sizeof(keyuid) + 1]; 17658f0484fSRodney W. Grimes 17758f0484fSRodney W. Grimes if (!_pw_db && !__initdb()) 17858f0484fSRodney W. Grimes return((struct passwd *)NULL); 17958f0484fSRodney W. Grimes 18058f0484fSRodney W. Grimes bf[0] = _PW_KEYBYUID; 18158f0484fSRodney W. Grimes keyuid = uid; 18258f0484fSRodney W. Grimes bcopy(&keyuid, bf + 1, sizeof(keyuid)); 18358f0484fSRodney W. Grimes key.data = (u_char *)bf; 18458f0484fSRodney W. Grimes key.size = sizeof(keyuid) + 1; 18558f0484fSRodney W. Grimes rval = __hashpw(&key); 18658f0484fSRodney W. Grimes 187d5b7518dSGarrett Wollman #ifdef YP 188d5b7518dSGarrett Wollman if (!rval && _yp_enabled) { 189d5b7518dSGarrett Wollman char ypbuf[16]; /* big enough for 32-bit uids and then some */ 190d5b7518dSGarrett Wollman snprintf(ypbuf, sizeof ypbuf, "%u", (unsigned)uid); 191d5b7518dSGarrett Wollman rval = _getyppass(&_pw_passwd, ypbuf, "passwd.byuid"); 192d5b7518dSGarrett Wollman } 193d5b7518dSGarrett Wollman #endif 19482844700SBill Paul /* 19582844700SBill Paul * Prevent login attempts when YP is not enabled but YP entries 19682844700SBill Paul * are in /etc/master.passwd. 19782844700SBill Paul */ 19882844700SBill Paul if (rval && (_pw_passwd.pw_name[0] == '+'|| 19982844700SBill Paul _pw_passwd.pw_name[0] == '-')) rval = 0; 2009531ca93SBill Paul 2019531ca93SBill Paul endpwent(); 20258f0484fSRodney W. Grimes return(rval ? &_pw_passwd : (struct passwd *)NULL); 20358f0484fSRodney W. Grimes } 20458f0484fSRodney W. Grimes 20558f0484fSRodney W. Grimes int 20658f0484fSRodney W. Grimes setpassent(stayopen) 20758f0484fSRodney W. Grimes int stayopen; 20858f0484fSRodney W. Grimes { 20958f0484fSRodney W. Grimes _pw_keynum = 0; 210d5b7518dSGarrett Wollman #ifdef YP 21194c53e1fSBill Paul _pw_stepping_yp = 0; 212d5b7518dSGarrett Wollman #endif 21358f0484fSRodney W. Grimes _pw_stayopen = stayopen; 21458f0484fSRodney W. Grimes return(1); 21558f0484fSRodney W. Grimes } 21658f0484fSRodney W. Grimes 21758f0484fSRodney W. Grimes int 21858f0484fSRodney W. Grimes setpwent() 21958f0484fSRodney W. Grimes { 22058f0484fSRodney W. Grimes _pw_keynum = 0; 221d5b7518dSGarrett Wollman #ifdef YP 22294c53e1fSBill Paul _pw_stepping_yp = 0; 223d5b7518dSGarrett Wollman #endif 22458f0484fSRodney W. Grimes _pw_stayopen = 0; 22558f0484fSRodney W. Grimes return(1); 22658f0484fSRodney W. Grimes } 22758f0484fSRodney W. Grimes 22858f0484fSRodney W. Grimes void 22958f0484fSRodney W. Grimes endpwent() 23058f0484fSRodney W. Grimes { 23158f0484fSRodney W. Grimes _pw_keynum = 0; 232d5b7518dSGarrett Wollman #ifdef YP 23394c53e1fSBill Paul _pw_stepping_yp = 0; 234d5b7518dSGarrett Wollman #endif 23558f0484fSRodney W. Grimes if (_pw_db) { 23658f0484fSRodney W. Grimes (void)(_pw_db->close)(_pw_db); 23758f0484fSRodney W. Grimes _pw_db = (DB *)NULL; 23858f0484fSRodney W. Grimes } 23994c53e1fSBill Paul #ifdef YP 24094c53e1fSBill Paul if (_ypcache) { 24194c53e1fSBill Paul (void)(_ypcache->close)(_ypcache); 24294c53e1fSBill Paul _ypcache = (DB *)NULL; 24394c53e1fSBill Paul _yp_exclusions = 0; 24494c53e1fSBill Paul } 24594c53e1fSBill Paul #endif 24658f0484fSRodney W. Grimes } 24758f0484fSRodney W. Grimes 24851295a4dSJordan K. Hubbard static int 24958f0484fSRodney W. Grimes __initdb() 25058f0484fSRodney W. Grimes { 25158f0484fSRodney W. Grimes static int warned; 25258f0484fSRodney W. Grimes char *p; 25358f0484fSRodney W. Grimes 25458f0484fSRodney W. Grimes p = (geteuid()) ? _PATH_MP_DB : _PATH_SMP_DB; 25558f0484fSRodney W. Grimes _pw_db = dbopen(p, O_RDONLY, 0, DB_HASH, NULL); 256d5b7518dSGarrett Wollman if (_pw_db) { 257d5b7518dSGarrett Wollman #ifdef YP 258d5b7518dSGarrett Wollman DBT key, data; 259d5b7518dSGarrett Wollman char buf[] = { _PW_KEYYPENABLED }; 260d5b7518dSGarrett Wollman key.data = buf; 261d5b7518dSGarrett Wollman key.size = 1; 262d5b7518dSGarrett Wollman if ((_pw_db->get)(_pw_db, &key, &data, 0)) { 263d5b7518dSGarrett Wollman _yp_enabled = 0; 264d5b7518dSGarrett Wollman } else { 265468bb86aSGarrett Wollman _yp_enabled = (int)*((char *)data.data) - 2; 2663948edc2SBill Paul /* Don't even bother with this if we aren't root. */ 2673948edc2SBill Paul if (!geteuid()) { 2683948edc2SBill Paul if (!_pw_yp_domain) 2693948edc2SBill Paul if (yp_get_default_domain(&_pw_yp_domain)) 2703948edc2SBill Paul return(1); 2713948edc2SBill Paul _gotmaster = _havemaster(_pw_yp_domain); 2722be5d4cbSBill Paul } else _gotmaster = YP_HAVE_NONE; 27394c53e1fSBill Paul if (!_ypcache) 27494c53e1fSBill Paul _ypinitdb(); 275d5b7518dSGarrett Wollman } 276d5b7518dSGarrett Wollman #endif 27758f0484fSRodney W. Grimes return(1); 278d5b7518dSGarrett Wollman } 27988ce2dd1SBill Paul if (!warned++) 28058f0484fSRodney W. Grimes syslog(LOG_ERR, "%s: %m", p); 28158f0484fSRodney W. Grimes return(0); 28258f0484fSRodney W. Grimes } 28358f0484fSRodney W. Grimes 28451295a4dSJordan K. Hubbard static int 28558f0484fSRodney W. Grimes __hashpw(key) 28658f0484fSRodney W. Grimes DBT *key; 28758f0484fSRodney W. Grimes { 28858f0484fSRodney W. Grimes register char *p, *t; 28958f0484fSRodney W. Grimes static u_int max; 29058f0484fSRodney W. Grimes static char *line; 29158f0484fSRodney W. Grimes DBT data; 29258f0484fSRodney W. Grimes 2935f115c9dSBill Paul if ((_pw_db->get)(_pw_db, key, &data, 0)) 29458f0484fSRodney W. Grimes return(0); 29558f0484fSRodney W. Grimes p = (char *)data.data; 2968be26e5dSWolfram Schneider 2978be26e5dSWolfram Schneider /* increase buffer size for long lines if necessary */ 2988be26e5dSWolfram Schneider if (data.size > max) { 2998be26e5dSWolfram Schneider max = data.size + 1024; 3008be26e5dSWolfram Schneider if (!(line = realloc(line, max))) 30158f0484fSRodney W. Grimes return(0); 3028be26e5dSWolfram Schneider } 30358f0484fSRodney W. Grimes 304adf6ad9eSPeter Wemm /* THIS CODE MUST MATCH THAT IN pwd_mkdb. */ 30558f0484fSRodney W. Grimes t = line; 30651295a4dSJordan K. Hubbard #define EXPAND(e) e = t; while ( (*t++ = *p++) ); 307adf6ad9eSPeter Wemm #define SCALAR(v) memmove(&(v), p, sizeof v); p += sizeof v 30858f0484fSRodney W. Grimes EXPAND(_pw_passwd.pw_name); 30958f0484fSRodney W. Grimes EXPAND(_pw_passwd.pw_passwd); 310adf6ad9eSPeter Wemm SCALAR(_pw_passwd.pw_uid); 311adf6ad9eSPeter Wemm SCALAR(_pw_passwd.pw_gid); 312adf6ad9eSPeter Wemm SCALAR(_pw_passwd.pw_change); 31358f0484fSRodney W. Grimes EXPAND(_pw_passwd.pw_class); 31458f0484fSRodney W. Grimes EXPAND(_pw_passwd.pw_gecos); 31558f0484fSRodney W. Grimes EXPAND(_pw_passwd.pw_dir); 31658f0484fSRodney W. Grimes EXPAND(_pw_passwd.pw_shell); 317adf6ad9eSPeter Wemm SCALAR(_pw_passwd.pw_expire); 318d5b7518dSGarrett Wollman bcopy(p, (char *)&_pw_passwd.pw_fields, sizeof _pw_passwd.pw_fields); 319d5b7518dSGarrett Wollman p += sizeof _pw_passwd.pw_fields; 32058f0484fSRodney W. Grimes return(1); 32158f0484fSRodney W. Grimes } 322d5b7518dSGarrett Wollman 323d5b7518dSGarrett Wollman #ifdef YP 32494c53e1fSBill Paul 3259531ca93SBill Paul /* 32694c53e1fSBill Paul * Create a DB hash database in memory. Bet you didn't know you 32794c53e1fSBill Paul * could do a dbopen() will a NULL filename, did you. 3289531ca93SBill Paul */ 32994c53e1fSBill Paul static inline void _ypinitdb() 3309531ca93SBill Paul { 33194c53e1fSBill Paul if (_ypcache == (DB *)NULL) 33294c53e1fSBill Paul _ypcache = dbopen(NULL, O_RDWR, 600, DB_HASH, NULL); 33389395683SBill Paul return; 3349531ca93SBill Paul } 3359531ca93SBill Paul 3369531ca93SBill Paul /* 33794c53e1fSBill Paul * See if a user is in the blackballed list. 3389531ca93SBill Paul */ 33994c53e1fSBill Paul static inline int lookup(name) 34094c53e1fSBill Paul char *name; 3419531ca93SBill Paul { 34294c53e1fSBill Paul DBT key; 3439531ca93SBill Paul 34494c53e1fSBill Paul if (!_yp_exclusions) 34594c53e1fSBill Paul return(0); 34694c53e1fSBill Paul 34794c53e1fSBill Paul key.data = name; 34894c53e1fSBill Paul key.size = strlen(name); 34994c53e1fSBill Paul 35094c53e1fSBill Paul if ((_ypcache->get)(_ypcache, &key, &empty, 0)) { 35194c53e1fSBill Paul return(0); 3529531ca93SBill Paul } 3539531ca93SBill Paul 354d454389cSBill Paul return(1); 355d454389cSBill Paul } 35694c53e1fSBill Paul 35794c53e1fSBill Paul /* 35894c53e1fSBill Paul * Store a blackballed user in an in-core hash database. 35994c53e1fSBill Paul */ 36094c53e1fSBill Paul static inline void store(key) 36194c53e1fSBill Paul char *key; 36294c53e1fSBill Paul { 36394c53e1fSBill Paul DBT lkey; 36494c53e1fSBill Paul /* 36594c53e1fSBill Paul if (lookup(key)) 36694c53e1fSBill Paul return; 36794c53e1fSBill Paul */ 36894c53e1fSBill Paul 36994c53e1fSBill Paul _yp_exclusions = 1; 37094c53e1fSBill Paul 37194c53e1fSBill Paul lkey.data = key; 37294c53e1fSBill Paul lkey.size = strlen(key); 37394c53e1fSBill Paul 37494c53e1fSBill Paul (void)(_ypcache->put)(_ypcache, &lkey, &empty, R_NOOVERWRITE); 37594c53e1fSBill Paul } 37694c53e1fSBill Paul 37794c53e1fSBill Paul /* 37894c53e1fSBill Paul * Parse the + entries in the password database and do appropriate 37994c53e1fSBill Paul * NIS lookups. While ugly to look at, this is optimized to do only 38094c53e1fSBill Paul * as many lookups as are absolutely necessary in any given case. 38194c53e1fSBill Paul * Basically, the getpwent() function will feed us + and - lines 38294c53e1fSBill Paul * as they appear in the database. For + lines, we do netgroup/group 38394c53e1fSBill Paul * and user lookups to find all usernames that match the rule and 38494c53e1fSBill Paul * extract them from the NIS passwd maps. For - lines, we save the 38594c53e1fSBill Paul * matching names in a database and a) exlude them, and b) make sure 38694c53e1fSBill Paul * we don't consider them when processing other + lines that appear 38794c53e1fSBill Paul * later. 38894c53e1fSBill Paul */ 38994c53e1fSBill Paul static inline int unwind(grp) 39094c53e1fSBill Paul char *grp; 39194c53e1fSBill Paul { 39294c53e1fSBill Paul char *user, *host, *domain; 39394c53e1fSBill Paul static int latch = 0; 39494c53e1fSBill Paul static struct group *gr = NULL; 39594c53e1fSBill Paul int rv = 0; 39694c53e1fSBill Paul 39794c53e1fSBill Paul if (grp[0] == '+') { 39894c53e1fSBill Paul if (strlen(grp) == 1) { 39994c53e1fSBill Paul return(_nextyppass(&_pw_passwd)); 40094c53e1fSBill Paul } 40194c53e1fSBill Paul if (grp[1] == '@') { 40294c53e1fSBill Paul _pw_stepping_yp = 1; 40394c53e1fSBill Paul grpagain: 40494c53e1fSBill Paul if (gr != NULL) { 40594c53e1fSBill Paul if (*gr->gr_mem != NULL) { 40694c53e1fSBill Paul if (lookup(*gr->gr_mem)) { 40794c53e1fSBill Paul gr->gr_mem++; 40894c53e1fSBill Paul goto grpagain; 40994c53e1fSBill Paul } 41094c53e1fSBill Paul rv = _getyppass(&_pw_passwd, 41194c53e1fSBill Paul *gr->gr_mem, 41294c53e1fSBill Paul "passwd.byname"); 41394c53e1fSBill Paul gr->gr_mem++; 41494c53e1fSBill Paul return(rv); 41594c53e1fSBill Paul } else { 41694c53e1fSBill Paul endgrent(); 41794c53e1fSBill Paul latch = 0; 41894c53e1fSBill Paul gr = NULL; 41994c53e1fSBill Paul return(0); 420d454389cSBill Paul } 421d454389cSBill Paul } 42294c53e1fSBill Paul if (!latch) { 42394c53e1fSBill Paul setnetgrent(grp+2); 42494c53e1fSBill Paul latch++; 425d454389cSBill Paul } 42694c53e1fSBill Paul again: 42794c53e1fSBill Paul if (getnetgrent(&host, &user, &domain) == NULL) { 42894c53e1fSBill Paul if ((gr = getgrnam(grp+2)) != NULL) 42994c53e1fSBill Paul goto grpagain; 43094c53e1fSBill Paul latch = 0; 43194c53e1fSBill Paul _pw_stepping_yp = 0; 43294c53e1fSBill Paul return(0); 43394c53e1fSBill Paul } else { 43494c53e1fSBill Paul if (lookup(user)) 43594c53e1fSBill Paul goto again; 43694c53e1fSBill Paul if (_getyppass(&_pw_passwd, user, 43794c53e1fSBill Paul "passwd.byname")) 43894c53e1fSBill Paul return(1); 43994c53e1fSBill Paul else 44094c53e1fSBill Paul goto again; 441d454389cSBill Paul } 44294c53e1fSBill Paul } else { 44394c53e1fSBill Paul if (lookup(grp+1)) 44494c53e1fSBill Paul return(0); 44594c53e1fSBill Paul return(_getyppass(&_pw_passwd, grp+1, "passwd.byname")); 44694c53e1fSBill Paul } 44794c53e1fSBill Paul } else { 44894c53e1fSBill Paul if (grp[1] == '@') { 44994c53e1fSBill Paul setnetgrent(grp+2); 45094c53e1fSBill Paul rv = 0; 45194c53e1fSBill Paul while(getnetgrent(&host, &user, &domain) != NULL) { 45294c53e1fSBill Paul store(user); 45394c53e1fSBill Paul rv++; 45494c53e1fSBill Paul } 45594c53e1fSBill Paul if (!rv && (gr = getgrnam(grp+2)) != NULL) { 45694c53e1fSBill Paul while(gr->gr_mem) { 45794c53e1fSBill Paul store(gr->gr_mem); 45894c53e1fSBill Paul gr->gr_mem++; 45994c53e1fSBill Paul } 46094c53e1fSBill Paul } 46194c53e1fSBill Paul } else { 46294c53e1fSBill Paul store(grp+1); 46394c53e1fSBill Paul } 46494c53e1fSBill Paul } 46594c53e1fSBill Paul return(0); 46694c53e1fSBill Paul } 46794c53e1fSBill Paul 46894c53e1fSBill Paul /* 46994c53e1fSBill Paul * See if a user is a member of a particular group. 47094c53e1fSBill Paul */ 47194c53e1fSBill Paul static inline int ingr(grp, name) 47294c53e1fSBill Paul char *grp; 47394c53e1fSBill Paul char *name; 47494c53e1fSBill Paul { 47594c53e1fSBill Paul register struct group *gr; 47694c53e1fSBill Paul 47794c53e1fSBill Paul if ((gr = getgrnam(grp)) == NULL) 47894c53e1fSBill Paul return(0); 47994c53e1fSBill Paul 48094c53e1fSBill Paul while(*gr->gr_mem) { 48194c53e1fSBill Paul if (!strcmp(*gr->gr_mem, name)) { 48294c53e1fSBill Paul endgrent(); 48394c53e1fSBill Paul return(1); 48494c53e1fSBill Paul } 48594c53e1fSBill Paul gr->gr_mem++; 48694c53e1fSBill Paul } 48794c53e1fSBill Paul 48894c53e1fSBill Paul endgrent(); 48994c53e1fSBill Paul return(0); 49094c53e1fSBill Paul } 49194c53e1fSBill Paul 49294c53e1fSBill Paul /* 49394c53e1fSBill Paul * Check a user against the +@netgroup/-@netgroup lines listed in 49494c53e1fSBill Paul * the local password database. Also checks +user/-user lines. 49594c53e1fSBill Paul * If no netgroup exists that matches +@netgroup/-@netgroup, 49694c53e1fSBill Paul * try searching regular groups with the same name. 49794c53e1fSBill Paul */ 49894c53e1fSBill Paul static inline int verf(name) 49994c53e1fSBill Paul char *name; 50094c53e1fSBill Paul { 50194c53e1fSBill Paul DBT key; 50294c53e1fSBill Paul char bf[sizeof(_pw_keynum) + 1]; 50394c53e1fSBill Paul int keynum = 0; 50494c53e1fSBill Paul 50594c53e1fSBill Paul again: 50694c53e1fSBill Paul ++keynum; 50794c53e1fSBill Paul bf[0] = _PW_KEYYPBYNUM; 50894c53e1fSBill Paul bcopy((char *)&keynum, bf + 1, sizeof(keynum)); 50994c53e1fSBill Paul key.data = (u_char *)bf; 51094c53e1fSBill Paul key.size = sizeof(keynum) + 1; 51194c53e1fSBill Paul if (!__hashpw(&key)) { 51294c53e1fSBill Paul /* Try again using old format */ 51394c53e1fSBill Paul bf[0] = _PW_KEYBYNUM; 51494c53e1fSBill Paul bcopy((char *)&keynum, bf + 1, sizeof(keynum)); 51594c53e1fSBill Paul key.data = (u_char *)bf; 51694c53e1fSBill Paul if (!__hashpw(&key)) 51794c53e1fSBill Paul return(0); 51894c53e1fSBill Paul } 51994c53e1fSBill Paul if (_pw_passwd.pw_name[0] != '+' && (_pw_passwd.pw_name[0] != '-')) 52094c53e1fSBill Paul goto again; 52194c53e1fSBill Paul if (_pw_passwd.pw_name[0] == '+') { 52294c53e1fSBill Paul if (strlen(_pw_passwd.pw_name) == 1) /* Wildcard */ 52394c53e1fSBill Paul return(1); 52494c53e1fSBill Paul if (_pw_passwd.pw_name[1] == '@') { 52594c53e1fSBill Paul if ((innetgr(_pw_passwd.pw_name+2, NULL, name, 52694c53e1fSBill Paul _pw_yp_domain) || 52794c53e1fSBill Paul ingr(_pw_passwd.pw_name+2, name)) && !lookup(name)) 52894c53e1fSBill Paul return(1); 52994c53e1fSBill Paul else 53094c53e1fSBill Paul goto again; 53194c53e1fSBill Paul } else { 53294c53e1fSBill Paul if (!strcmp(name, _pw_passwd.pw_name+1) && 53394c53e1fSBill Paul !lookup(name)) 53494c53e1fSBill Paul return(1); 53594c53e1fSBill Paul else 53694c53e1fSBill Paul goto again; 53794c53e1fSBill Paul } 53894c53e1fSBill Paul } 53994c53e1fSBill Paul if (_pw_passwd.pw_name[0] == '-') { 54094c53e1fSBill Paul /* Note that a minus wildcard is a no-op. */ 54194c53e1fSBill Paul if (_pw_passwd.pw_name[1] == '@') { 54294c53e1fSBill Paul if (innetgr(_pw_passwd.pw_name+2, NULL, name, 54394c53e1fSBill Paul _pw_yp_domain) || 54494c53e1fSBill Paul ingr(_pw_passwd.pw_name+2, name)) { 54594c53e1fSBill Paul store(name); 54694c53e1fSBill Paul return(0); 54794c53e1fSBill Paul } else 54894c53e1fSBill Paul goto again; 54994c53e1fSBill Paul } else { 55094c53e1fSBill Paul if (!strcmp(name, _pw_passwd.pw_name+1)) { 55194c53e1fSBill Paul store(name); 55294c53e1fSBill Paul return(0); 55394c53e1fSBill Paul } else 55494c53e1fSBill Paul goto again; 55594c53e1fSBill Paul } 55694c53e1fSBill Paul 557d454389cSBill Paul } 558d454389cSBill Paul return(0); 559d454389cSBill Paul } 560d454389cSBill Paul 5612be5d4cbSBill Paul static char * _get_adjunct_pw(name) 5622be5d4cbSBill Paul char *name; 5632be5d4cbSBill Paul { 5642be5d4cbSBill Paul static char adjunctbuf[YPMAXRECORD+2]; 5652be5d4cbSBill Paul int rval; 5662be5d4cbSBill Paul char *result; 5672be5d4cbSBill Paul int resultlen; 5682be5d4cbSBill Paul char *map = "passwd.adjunct.byname"; 5692be5d4cbSBill Paul char *s; 5702be5d4cbSBill Paul 5712be5d4cbSBill Paul if ((rval = yp_match(_pw_yp_domain, map, name, strlen(name), 5722be5d4cbSBill Paul &result, &resultlen))) 5732be5d4cbSBill Paul return(NULL); 5742be5d4cbSBill Paul 5751d2493ffSBill Paul strncpy(adjunctbuf, result, resultlen); 5761d2493ffSBill Paul adjunctbuf[resultlen] = '\0'; 5772be5d4cbSBill Paul free(result); 5782be5d4cbSBill Paul result = (char *)&adjunctbuf; 5792be5d4cbSBill Paul 5802be5d4cbSBill Paul /* Don't care about the name. */ 5812be5d4cbSBill Paul if ((s = strsep(&result, ":")) == NULL) 5822be5d4cbSBill Paul return (NULL); /* name */ 5832be5d4cbSBill Paul if ((s = strsep(&result, ":")) == NULL) 5842be5d4cbSBill Paul return (NULL); /* password */ 5852be5d4cbSBill Paul 5862be5d4cbSBill Paul return(s); 5872be5d4cbSBill Paul } 5882be5d4cbSBill Paul 5896c0828a6SBill Paul static int 5901d2493ffSBill Paul _pw_breakout_yp(struct passwd *pw, char *res, int resultlen, int master) 591d5b7518dSGarrett Wollman { 5928b102407SPoul-Henning Kamp char *s, *result; 5933948edc2SBill Paul static char resbuf[YPMAXRECORD+2]; 594d3628763SRodney W. Grimes 5953948edc2SBill Paul /* 5963948edc2SBill Paul * Be triple, ultra super-duper paranoid: reject entries 5973948edc2SBill Paul * that start with a + or -. yp_mkdb and /var/yp/Makefile 5983948edc2SBill Paul * are _both_ supposed to strip these out, but you never 5993948edc2SBill Paul * know. 6003948edc2SBill Paul */ 6013948edc2SBill Paul if (*res == '+' || *res == '-') 6023948edc2SBill Paul return 0; 6033948edc2SBill Paul 6043948edc2SBill Paul /* 6053948edc2SBill Paul * The NIS protocol definition limits the size of an NIS 6063948edc2SBill Paul * record to YPMAXRECORD bytes. We need to do a copy to 6073948edc2SBill Paul * a static buffer here since the memory pointed to by 6083948edc2SBill Paul * res will be free()ed when this function returns. 6093948edc2SBill Paul */ 6101d2493ffSBill Paul strncpy((char *)&resbuf, res, resultlen); 6111d2493ffSBill Paul resbuf[resultlen] = '\0'; 6123948edc2SBill Paul result = (char *)&resbuf; 613d5b7518dSGarrett Wollman 6146c0828a6SBill Paul /* 6156c0828a6SBill Paul * XXX Sanity check: make sure all fields are valid (no NULLs). 6166c0828a6SBill Paul * If we find a badly formatted entry, we punt. 6176c0828a6SBill Paul */ 6186c0828a6SBill Paul if ((s = strsep(&result, ":")) == NULL) return 0; /* name */ 6193948edc2SBill Paul /* 6203948edc2SBill Paul * We don't care what pw_fields says: we _always_ want the 6213948edc2SBill Paul * username returned to us by NIS. 6223948edc2SBill Paul */ 623d5b7518dSGarrett Wollman pw->pw_name = s; 624d5b7518dSGarrett Wollman pw->pw_fields |= _PWF_NAME; 625d5b7518dSGarrett Wollman 6266c0828a6SBill Paul if ((s = strsep(&result, ":")) == NULL) return 0; /* password */ 627d5b7518dSGarrett Wollman if(!(pw->pw_fields & _PWF_PASSWD)) { 6282be5d4cbSBill Paul /* SunOS passwd.adjunct hack */ 62909e84628SBill Paul if (master == YP_HAVE_ADJUNCT && strstr(s, "##") != NULL) { 6302be5d4cbSBill Paul char *realpw; 6312be5d4cbSBill Paul realpw = _get_adjunct_pw(pw->pw_name); 6322be5d4cbSBill Paul if (realpw == NULL) 633d5b7518dSGarrett Wollman pw->pw_passwd = s; 6342be5d4cbSBill Paul else 6352be5d4cbSBill Paul pw->pw_passwd = realpw; 6362be5d4cbSBill Paul } else { 6372be5d4cbSBill Paul pw->pw_passwd = s; 6382be5d4cbSBill Paul } 639d5b7518dSGarrett Wollman pw->pw_fields |= _PWF_PASSWD; 640d5b7518dSGarrett Wollman } 641d5b7518dSGarrett Wollman 6426c0828a6SBill Paul if ((s = strsep(&result, ":")) == NULL) return 0; /* uid */ 643d5b7518dSGarrett Wollman if(!(pw->pw_fields & _PWF_UID)) { 644d5b7518dSGarrett Wollman pw->pw_uid = atoi(s); 645d5b7518dSGarrett Wollman pw->pw_fields |= _PWF_UID; 646d5b7518dSGarrett Wollman } 647d5b7518dSGarrett Wollman 6486c0828a6SBill Paul if ((s = strsep(&result, ":")) == NULL) return 0; /* gid */ 649d5b7518dSGarrett Wollman if(!(pw->pw_fields & _PWF_GID)) { 650d5b7518dSGarrett Wollman pw->pw_gid = atoi(s); 651d5b7518dSGarrett Wollman pw->pw_fields |= _PWF_GID; 652d5b7518dSGarrett Wollman } 653d5b7518dSGarrett Wollman 6542be5d4cbSBill Paul if (master == YP_HAVE_MASTER) { 6556c0828a6SBill Paul if ((s = strsep(&result, ":")) == NULL) return 0; /* class */ 656d0ef6688SBill Paul if(!(pw->pw_fields & _PWF_CLASS)) { 657d0ef6688SBill Paul pw->pw_class = s; 658d0ef6688SBill Paul pw->pw_fields |= _PWF_CLASS; 659d0ef6688SBill Paul } 660d0ef6688SBill Paul 6616c0828a6SBill Paul if ((s = strsep(&result, ":")) == NULL) return 0; /* change */ 662d0ef6688SBill Paul if(!(pw->pw_fields & _PWF_CHANGE)) { 663d0ef6688SBill Paul pw->pw_change = atol(s); 664d0ef6688SBill Paul pw->pw_fields |= _PWF_CHANGE; 665d0ef6688SBill Paul } 666d0ef6688SBill Paul 6676c0828a6SBill Paul if ((s = strsep(&result, ":")) == NULL) return 0; /* expire */ 668d0ef6688SBill Paul if(!(pw->pw_fields & _PWF_EXPIRE)) { 669d0ef6688SBill Paul pw->pw_expire = atol(s); 670d0ef6688SBill Paul pw->pw_fields |= _PWF_EXPIRE; 671d0ef6688SBill Paul } 672d66efc62SBill Paul } 673d0ef6688SBill Paul 6746c0828a6SBill Paul if ((s = strsep(&result, ":")) == NULL) return 0; /* gecos */ 675d0ef6688SBill Paul if(!(pw->pw_fields & _PWF_GECOS)) { 676d0ef6688SBill Paul pw->pw_gecos = s; 677d0ef6688SBill Paul pw->pw_fields |= _PWF_GECOS; 678d0ef6688SBill Paul } 679d0ef6688SBill Paul 6806c0828a6SBill Paul if ((s = strsep(&result, ":")) == NULL) return 0; /* dir */ 681d0ef6688SBill Paul if(!(pw->pw_fields & _PWF_DIR)) { 682d0ef6688SBill Paul pw->pw_dir = s; 683d0ef6688SBill Paul pw->pw_fields |= _PWF_DIR; 684d0ef6688SBill Paul } 685d0ef6688SBill Paul 6866c0828a6SBill Paul if ((s = strsep(&result, ":")) == NULL) return 0; /* shell */ 687d0ef6688SBill Paul if(!(pw->pw_fields & _PWF_SHELL)) { 688d0ef6688SBill Paul pw->pw_shell = s; 689d0ef6688SBill Paul pw->pw_fields |= _PWF_SHELL; 690d0ef6688SBill Paul } 6916c0828a6SBill Paul 6923948edc2SBill Paul /* Be consistent. */ 6933948edc2SBill Paul if ((s = strchr(pw->pw_shell, '\n'))) *s = '\0'; 6943948edc2SBill Paul 6956c0828a6SBill Paul return 1; 696d0ef6688SBill Paul } 697d0ef6688SBill Paul 698d5b7518dSGarrett Wollman static int 699c333ae82SDavid Nugent _havemaster(char *_yp_domain) 700d0ef6688SBill Paul { 7012be5d4cbSBill Paul int order; 7022be5d4cbSBill Paul int rval; 703d0ef6688SBill Paul 704c333ae82SDavid Nugent if (!(rval = yp_order(_yp_domain, "master.passwd.byname", &order))) 7052be5d4cbSBill Paul return(YP_HAVE_MASTER); 7062be5d4cbSBill Paul 7072be5d4cbSBill Paul /* 7082be5d4cbSBill Paul * NIS+ in YP compat mode doesn't support 7092be5d4cbSBill Paul * YPPROC_ORDER -- no point in continuing. 7102be5d4cbSBill Paul */ 7112be5d4cbSBill Paul if (rval == YPERR_YPERR) 7122be5d4cbSBill Paul return(YP_HAVE_NONE); 7132be5d4cbSBill Paul 7142be5d4cbSBill Paul /* master.passwd doesn't exist -- try passwd.adjunct */ 7152be5d4cbSBill Paul if (rval == YPERR_MAP) { 716c333ae82SDavid Nugent rval = yp_order(_yp_domain, "passwd.adjunct.byname", &order); 7172be5d4cbSBill Paul if (!rval) 7182be5d4cbSBill Paul return(YP_HAVE_ADJUNCT); 719b38bb6d3SBill Paul } 7202be5d4cbSBill Paul 7212be5d4cbSBill Paul return (YP_HAVE_NONE); 722d0ef6688SBill Paul } 723d0ef6688SBill Paul 724d0ef6688SBill Paul static int 725d5b7518dSGarrett Wollman _getyppass(struct passwd *pw, const char *name, const char *map) 726d5b7518dSGarrett Wollman { 727d5b7518dSGarrett Wollman char *result, *s; 728d5b7518dSGarrett Wollman int resultlen; 7293948edc2SBill Paul int rv; 73094c53e1fSBill Paul char mastermap[YPMAXRECORD]; 731d5b7518dSGarrett Wollman 732d5b7518dSGarrett Wollman if(!_pw_yp_domain) { 733d5b7518dSGarrett Wollman if(yp_get_default_domain(&_pw_yp_domain)) 734d5b7518dSGarrett Wollman return 0; 735d5b7518dSGarrett Wollman } 736d5b7518dSGarrett Wollman 737d0ef6688SBill Paul sprintf(mastermap,"%s",map); 738d0ef6688SBill Paul 7392be5d4cbSBill Paul if (_gotmaster == YP_HAVE_MASTER) 740320ce7b7SBill Paul sprintf(mastermap,"master.%s", map); 741d0ef6688SBill Paul 742958f4e36SBill Paul if(yp_match(_pw_yp_domain, (char *)&mastermap, name, strlen(name), 743d5b7518dSGarrett Wollman &result, &resultlen)) 744d5b7518dSGarrett Wollman return 0; 745d5b7518dSGarrett Wollman 74694c53e1fSBill Paul if (!_pw_stepping_yp) { 7473948edc2SBill Paul s = strchr(result, ':'); 7483948edc2SBill Paul if (s) { 7493948edc2SBill Paul *s = '\0'; 7503948edc2SBill Paul } else { 7513948edc2SBill Paul /* Must be a malformed entry if no colons. */ 7523948edc2SBill Paul free(result); 7533948edc2SBill Paul return(0); 7543948edc2SBill Paul } 75594c53e1fSBill Paul 75694c53e1fSBill Paul if (!verf(result)) { 75794c53e1fSBill Paul *s = ':'; 7589531ca93SBill Paul free(result); 7599531ca93SBill Paul return(0); 7603948edc2SBill Paul } 76194c53e1fSBill Paul 7623948edc2SBill Paul *s = ':'; /* Put back the colon we previously replaced with a NUL. */ 76394c53e1fSBill Paul } 76494c53e1fSBill Paul 7651d2493ffSBill Paul rv = _pw_breakout_yp(pw, result, resultlen, _gotmaster); 7663948edc2SBill Paul free(result); 7673948edc2SBill Paul return(rv); 768d5b7518dSGarrett Wollman } 769d5b7518dSGarrett Wollman 770d5b7518dSGarrett Wollman static int 771d5b7518dSGarrett Wollman _nextyppass(struct passwd *pw) 772d5b7518dSGarrett Wollman { 773958f4e36SBill Paul static char *key; 774d5b7518dSGarrett Wollman static int keylen; 7753948edc2SBill Paul char *lastkey, *result, *s; 776d5b7518dSGarrett Wollman int resultlen; 777d5b7518dSGarrett Wollman int rv; 778d0ef6688SBill Paul char *map = "passwd.byname"; 779d5b7518dSGarrett Wollman 780d5b7518dSGarrett Wollman if(!_pw_yp_domain) { 781d5b7518dSGarrett Wollman if(yp_get_default_domain(&_pw_yp_domain)) 782d5b7518dSGarrett Wollman return 0; 783d5b7518dSGarrett Wollman } 784d5b7518dSGarrett Wollman 7852be5d4cbSBill Paul if (_gotmaster == YP_HAVE_MASTER) 786d0ef6688SBill Paul map = "master.passwd.byname"; 787d0ef6688SBill Paul 788d5b7518dSGarrett Wollman if(!_pw_stepping_yp) { 789d5b7518dSGarrett Wollman if(key) free(key); 790d0ef6688SBill Paul rv = yp_first(_pw_yp_domain, map, 791d5b7518dSGarrett Wollman &key, &keylen, &result, &resultlen); 792d5b7518dSGarrett Wollman if(rv) { 793d5b7518dSGarrett Wollman return 0; 794d5b7518dSGarrett Wollman } 795d5b7518dSGarrett Wollman _pw_stepping_yp = 1; 796d5b7518dSGarrett Wollman goto unpack; 797d5b7518dSGarrett Wollman } else { 798d5b7518dSGarrett Wollman tryagain: 799d5b7518dSGarrett Wollman lastkey = key; 800d0ef6688SBill Paul rv = yp_next(_pw_yp_domain, map, key, keylen, 801d5b7518dSGarrett Wollman &key, &keylen, &result, &resultlen); 802d5b7518dSGarrett Wollman free(lastkey); 803d5b7518dSGarrett Wollman unpack: 804d5b7518dSGarrett Wollman if(rv) { 805d5b7518dSGarrett Wollman _pw_stepping_yp = 0; 806d5b7518dSGarrett Wollman return 0; 807d5b7518dSGarrett Wollman } 808d5b7518dSGarrett Wollman 8093948edc2SBill Paul s = strchr(result, ':'); 8103948edc2SBill Paul if (s) { 8113948edc2SBill Paul *s = '\0'; 8123948edc2SBill Paul } else { 81394c53e1fSBill Paul /* Must be a malformed entry if no colons. */ 814d5b7518dSGarrett Wollman free(result); 815d5b7518dSGarrett Wollman goto tryagain; 816d5b7518dSGarrett Wollman } 81794c53e1fSBill Paul 81894c53e1fSBill Paul if (lookup(result)) { 81994c53e1fSBill Paul *s = ':'; 8209531ca93SBill Paul free(result); 8219531ca93SBill Paul goto tryagain; 8223948edc2SBill Paul } 82394c53e1fSBill Paul 82494c53e1fSBill Paul *s = ':'; /* Put back the colon we previously replaced with a NUL. */ 8251d2493ffSBill Paul if (_pw_breakout_yp(pw, result, resultlen, _gotmaster)) { 8263948edc2SBill Paul free(result); 827400b8413SBill Paul return(1); 8283948edc2SBill Paul } else { 8293948edc2SBill Paul free(result); 830400b8413SBill Paul goto tryagain; 831d5b7518dSGarrett Wollman } 832d5b7518dSGarrett Wollman } 8333948edc2SBill Paul } 834d5b7518dSGarrett Wollman 835d5b7518dSGarrett Wollman #endif /* YP */ 836