17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5cb5caa98Sdjl  * Common Development and Distribution License (the "License").
6cb5caa98Sdjl  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217257d1b4Sraf 
227c478bd9Sstevel@tonic-gate /*
237257d1b4Sraf  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate  * nis_common.c
297c478bd9Sstevel@tonic-gate  *
307c478bd9Sstevel@tonic-gate  * Common code and structures used by name-service-switch "nis" backends.
317c478bd9Sstevel@tonic-gate  */
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include "nis_common.h"
347c478bd9Sstevel@tonic-gate #include <string.h>
357c478bd9Sstevel@tonic-gate #include <synch.h>
367c478bd9Sstevel@tonic-gate #include <rpcsvc/ypclnt.h>
377c478bd9Sstevel@tonic-gate #include <rpcsvc/yp_prot.h>
387c478bd9Sstevel@tonic-gate #include <thread.h>
397c478bd9Sstevel@tonic-gate #include <ctype.h>
407c478bd9Sstevel@tonic-gate #include <stdlib.h>
417c478bd9Sstevel@tonic-gate #include <signal.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #ifndef	MT_UNSAFE_YP		/* Is the libnsl YP client code MT-unsafe? */
447c478bd9Sstevel@tonic-gate #define	MT_UNSAFE_YP	0	/* No, not any longer */
457c478bd9Sstevel@tonic-gate #endif
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate #if	MT_UNSAFE_YP
487c478bd9Sstevel@tonic-gate static mutex_t	one_lane = DEFAULTMUTEX;
497c478bd9Sstevel@tonic-gate #endif
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate /* <rpcsvc/ypclnt.h> uses (char *) where it should use (const char *) */
527c478bd9Sstevel@tonic-gate typedef char *grrr;
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate /*
557c478bd9Sstevel@tonic-gate  * The YP client code thinks it's being helpful by appending '\n' and '\0'
567c478bd9Sstevel@tonic-gate  *   to the values returned by yp_match() et al.  In order to do this it
577c478bd9Sstevel@tonic-gate  *   ends up doing more malloc()ing and data copying than would otherwise
587c478bd9Sstevel@tonic-gate  *   be necessary.  If we're interested in performance we should provide
597c478bd9Sstevel@tonic-gate  *   alternative library interfaces that skip the helpfulness and instead
607c478bd9Sstevel@tonic-gate  *   let the XDR routines dump the value directly into the buffer where
617c478bd9Sstevel@tonic-gate  *   we really want it.  For now, though, we just use the vanilla interface.
627c478bd9Sstevel@tonic-gate  */
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate static nss_status_t
switch_err(ypstatus,ismatch)657c478bd9Sstevel@tonic-gate switch_err(ypstatus, ismatch)
667c478bd9Sstevel@tonic-gate 	int			ypstatus;
677c478bd9Sstevel@tonic-gate 	int			ismatch;
687c478bd9Sstevel@tonic-gate {
697c478bd9Sstevel@tonic-gate 	switch (ypstatus) {
707c478bd9Sstevel@tonic-gate 	case 0:
71cb5caa98Sdjl 		errno = 0;
727c478bd9Sstevel@tonic-gate 		return (NSS_SUCCESS);
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate 	case YPERR_BADARGS:
757c478bd9Sstevel@tonic-gate 	case YPERR_KEY:
76cb5caa98Sdjl 		errno = 0;
777c478bd9Sstevel@tonic-gate 		return (NSS_NOTFOUND);
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 		/*
807c478bd9Sstevel@tonic-gate 		 *  When the YP server is running in DNS forwarding mode,
817c478bd9Sstevel@tonic-gate 		 *  the forwarder will return YPERR_NOMORE to us if it
827c478bd9Sstevel@tonic-gate 		 *  is unable to contact a server (i.e., it has timed out).
837c478bd9Sstevel@tonic-gate 		 *  The NSS_NISSERVDNS_TRYAGAIN is returned for timeout errors.
847c478bd9Sstevel@tonic-gate 		 */
857c478bd9Sstevel@tonic-gate 	case YPERR_NOMORE:
867c478bd9Sstevel@tonic-gate 		if (ismatch)
877c478bd9Sstevel@tonic-gate 			return (NSS_NISSERVDNS_TRYAGAIN);
887c478bd9Sstevel@tonic-gate 		else
897c478bd9Sstevel@tonic-gate 			return (NSS_NOTFOUND);
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	case YPERR_DOMAIN:
927c478bd9Sstevel@tonic-gate 	case YPERR_YPSERV:
937c478bd9Sstevel@tonic-gate 	case YPERR_BUSY:
947c478bd9Sstevel@tonic-gate 		return (NSS_TRYAGAIN);
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	default:
977c478bd9Sstevel@tonic-gate 		return (NSS_UNAVAIL);
987c478bd9Sstevel@tonic-gate 	}
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1027c478bd9Sstevel@tonic-gate nss_status_t
_nss_nis_setent(be,dummy)1037c478bd9Sstevel@tonic-gate _nss_nis_setent(be, dummy)
1047c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
1057c478bd9Sstevel@tonic-gate 	void			*dummy;
1067c478bd9Sstevel@tonic-gate {
1077c478bd9Sstevel@tonic-gate 	if (be->enum_key != 0) {
1087c478bd9Sstevel@tonic-gate 		free(be->enum_key);
1097c478bd9Sstevel@tonic-gate 		be->enum_key = 0;
1107c478bd9Sstevel@tonic-gate 	}
1117c478bd9Sstevel@tonic-gate 	be->enum_keylen = 0;
1127c478bd9Sstevel@tonic-gate 	return (NSS_SUCCESS);
1137c478bd9Sstevel@tonic-gate }
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate nss_status_t
_nss_nis_endent(be,dummy)1167c478bd9Sstevel@tonic-gate _nss_nis_endent(be, dummy)
1177c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
1187c478bd9Sstevel@tonic-gate 	void			*dummy;
1197c478bd9Sstevel@tonic-gate {
1207c478bd9Sstevel@tonic-gate 	return (_nss_nis_setent(be, dummy));
1217c478bd9Sstevel@tonic-gate 	/* Nothing else we can clean up, is there? */
1227c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate void
massage_netdb(const char ** valp,int * vallenp)1257c478bd9Sstevel@tonic-gate massage_netdb(const char **valp, int *vallenp)
1267c478bd9Sstevel@tonic-gate {
1277c478bd9Sstevel@tonic-gate 	const char		*first;
1287c478bd9Sstevel@tonic-gate 	const char		*last;
1297c478bd9Sstevel@tonic-gate 	const char		*val	= *valp;
1307c478bd9Sstevel@tonic-gate 	int			vallen	= *vallenp;
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 	if ((last = memchr(val, '#', vallen)) == 0) {
1337c478bd9Sstevel@tonic-gate 		last = val + vallen;
1347c478bd9Sstevel@tonic-gate 	}
1357c478bd9Sstevel@tonic-gate 	for (first = val;  first < last && isspace(*first);  first++) {
1367c478bd9Sstevel@tonic-gate 		;
1377c478bd9Sstevel@tonic-gate 	}
1387c478bd9Sstevel@tonic-gate 	for (/* cstyle */;  first < last && isspace(last[-1]);  last--) {
1397c478bd9Sstevel@tonic-gate 		;
1407c478bd9Sstevel@tonic-gate 	}
1417c478bd9Sstevel@tonic-gate 	/*
1427c478bd9Sstevel@tonic-gate 	 * Don't check for an empty line because it shouldn't ever
1437c478bd9Sstevel@tonic-gate 	 *   have made it into the YP map.
1447c478bd9Sstevel@tonic-gate 	 */
1457c478bd9Sstevel@tonic-gate 	*valp = first;
1467c478bd9Sstevel@tonic-gate 	*vallenp = (int)(last - first);
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate nss_status_t
_nss_nis_ypmatch(domain,map,key,valp,vallenp,ypstatusp)1507c478bd9Sstevel@tonic-gate _nss_nis_ypmatch(domain, map, key, valp, vallenp, ypstatusp)
1517c478bd9Sstevel@tonic-gate 	const char		*domain;
1527c478bd9Sstevel@tonic-gate 	const char		*map;
1537c478bd9Sstevel@tonic-gate 	const char		*key;
1547c478bd9Sstevel@tonic-gate 	char			**valp;
1557c478bd9Sstevel@tonic-gate 	int			*vallenp;
1567c478bd9Sstevel@tonic-gate 	int			*ypstatusp;
1577c478bd9Sstevel@tonic-gate {
1587c478bd9Sstevel@tonic-gate 	int			ypstatus;
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate #if	MT_UNSAFE_YP
1617c478bd9Sstevel@tonic-gate 	sigset_t		oldmask, newmask;
1627c478bd9Sstevel@tonic-gate 
163cb5caa98Sdjl 	(void) sigfillset(&newmask);
1647257d1b4Sraf 	(void) thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask);
1657257d1b4Sraf 	(void) mutex_lock(&one_lane);
1667c478bd9Sstevel@tonic-gate #endif
1677c478bd9Sstevel@tonic-gate 	ypstatus = __yp_match_cflookup((grrr)domain, (grrr)map,
1687c478bd9Sstevel@tonic-gate 			    (grrr)key, (int)strlen(key), valp, vallenp, 0);
1697c478bd9Sstevel@tonic-gate #if	MT_UNSAFE_YP
1707257d1b4Sraf 	(void) mutex_unlock(&one_lane);
1717257d1b4Sraf 	(void) thr_sigsetmask(SIG_SETMASK, &oldmask, NULL);
1727c478bd9Sstevel@tonic-gate #endif
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 	if (ypstatusp != 0) {
1757c478bd9Sstevel@tonic-gate 		*ypstatusp = ypstatus;
1767c478bd9Sstevel@tonic-gate 	}
1777c478bd9Sstevel@tonic-gate 	return (switch_err(ypstatus, 1));
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate /*
1817c478bd9Sstevel@tonic-gate  * XXX special version of _nss_nis_ypmatch() for handling C2 (passwd.adjunct)
1827c478bd9Sstevel@tonic-gate  * lookups when we need a reserved port.
1837c478bd9Sstevel@tonic-gate  */
184cb5caa98Sdjl 
185cb5caa98Sdjl static nss_status_t
_nss_nis_ypmatch_rsvdport(domain,map,key,valp,vallenp,ypstatusp)1867c478bd9Sstevel@tonic-gate _nss_nis_ypmatch_rsvdport(domain, map, key, valp, vallenp, ypstatusp)
1877c478bd9Sstevel@tonic-gate 	const char		*domain;
1887c478bd9Sstevel@tonic-gate 	const char		*map;
1897c478bd9Sstevel@tonic-gate 	const char		*key;
1907c478bd9Sstevel@tonic-gate 	char			**valp;
1917c478bd9Sstevel@tonic-gate 	int			*vallenp;
1927c478bd9Sstevel@tonic-gate 	int			*ypstatusp;
1937c478bd9Sstevel@tonic-gate {
1947c478bd9Sstevel@tonic-gate 	int			ypstatus;
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate #if	MT_UNSAFE_YP
1977c478bd9Sstevel@tonic-gate 	sigset_t		oldmask, newmask;
1987c478bd9Sstevel@tonic-gate 
199cb5caa98Sdjl 	(void) sigfillset(&newmask);
2007257d1b4Sraf 	(void) thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask);
2017257d1b4Sraf 	(void) mutex_lock(&one_lane);
2027c478bd9Sstevel@tonic-gate #endif
2037c478bd9Sstevel@tonic-gate 	ypstatus = __yp_match_rsvdport_cflookup((grrr)domain, (grrr)map,
2047c478bd9Sstevel@tonic-gate 			    (grrr)key, strlen(key), valp, vallenp, 0);
2057c478bd9Sstevel@tonic-gate #if	MT_UNSAFE_YP
2067257d1b4Sraf 	(void) mutex_unlock(&one_lane);
2077257d1b4Sraf 	(void) thr_sigsetmask(SIG_SETMASK, &oldmask, NULL);
2087c478bd9Sstevel@tonic-gate #endif
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 	if (ypstatusp != 0) {
2117c478bd9Sstevel@tonic-gate 		*ypstatusp = ypstatus;
2127c478bd9Sstevel@tonic-gate 	}
2137c478bd9Sstevel@tonic-gate 	return (switch_err(ypstatus, 1));
2147c478bd9Sstevel@tonic-gate }
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate nss_status_t
_nss_nis_lookup(be,args,netdb,map,key,ypstatusp)2177c478bd9Sstevel@tonic-gate _nss_nis_lookup(be, args, netdb, map, key, ypstatusp)
2187c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
2197c478bd9Sstevel@tonic-gate 	nss_XbyY_args_t		*args;
2207c478bd9Sstevel@tonic-gate 	int			netdb;
2217c478bd9Sstevel@tonic-gate 	const char		*map;
2227c478bd9Sstevel@tonic-gate 	const char		*key;
2237c478bd9Sstevel@tonic-gate 	int			*ypstatusp;
2247c478bd9Sstevel@tonic-gate {
2257c478bd9Sstevel@tonic-gate 	nss_status_t		res;
2267c478bd9Sstevel@tonic-gate 	int			vallen;
2277c478bd9Sstevel@tonic-gate 	char			*val;
2287c478bd9Sstevel@tonic-gate 	char			*free_ptr;
2297c478bd9Sstevel@tonic-gate 	int			parsestat;
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	if ((res = _nss_nis_ypmatch(be->domain, map, key, &val, &vallen,
2327c478bd9Sstevel@tonic-gate 				    ypstatusp)) != NSS_SUCCESS) {
2337c478bd9Sstevel@tonic-gate 		return (res);
2347c478bd9Sstevel@tonic-gate 	}
2357c478bd9Sstevel@tonic-gate 
236*2b4a7802SBaban Kenkre 	parsestat = NSS_STR_PARSE_SUCCESS;
237*2b4a7802SBaban Kenkre 	if (strcmp(map, "passwd.byname") == 0 ||
238*2b4a7802SBaban Kenkre 	    strcmp(map, "passwd.byuid") == 0) {
239*2b4a7802SBaban Kenkre 		parsestat = validate_passwd_ids(&val, &vallen, 1);
240*2b4a7802SBaban Kenkre 	} else if (strcmp(map, "group.byname") == 0)
241*2b4a7802SBaban Kenkre 		parsestat = validate_group_ids(&val, &vallen, 1);
242*2b4a7802SBaban Kenkre 	if (parsestat != NSS_STR_PARSE_SUCCESS) {
243*2b4a7802SBaban Kenkre 		free(val);
244*2b4a7802SBaban Kenkre 		return (NSS_NOTFOUND);
245*2b4a7802SBaban Kenkre 	}
246*2b4a7802SBaban Kenkre 
2477c478bd9Sstevel@tonic-gate 	free_ptr = val;
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 	if (netdb) {
2507c478bd9Sstevel@tonic-gate 		massage_netdb((const char **)&val, &vallen);
2517c478bd9Sstevel@tonic-gate 	}
2527c478bd9Sstevel@tonic-gate 
253cb5caa98Sdjl 	args->returnval = NULL;
254cb5caa98Sdjl 	args->returnlen = 0;
2557c478bd9Sstevel@tonic-gate 	parsestat = (*args->str2ent)(val, vallen,
2567c478bd9Sstevel@tonic-gate 			args->buf.result, args->buf.buffer, args->buf.buflen);
2577c478bd9Sstevel@tonic-gate 	if (parsestat == NSS_STR_PARSE_SUCCESS) {
2587c478bd9Sstevel@tonic-gate 		args->returnval = args->buf.result;
259cb5caa98Sdjl 		args->returnlen = vallen;
2607c478bd9Sstevel@tonic-gate 		res = NSS_SUCCESS;
2617c478bd9Sstevel@tonic-gate 	} else if (parsestat == NSS_STR_PARSE_ERANGE) {
2627c478bd9Sstevel@tonic-gate 		args->erange = 1;
2637c478bd9Sstevel@tonic-gate 		/* We won't find this otherwise, anyway */
2647c478bd9Sstevel@tonic-gate 		res = NSS_NOTFOUND;
2657c478bd9Sstevel@tonic-gate 	} /* else if (parsestat == NSS_STR_PARSE_PARSE) won't happen ! */
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 	free(free_ptr);
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 	return (res);
2707c478bd9Sstevel@tonic-gate }
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate nss_status_t
_nss_nis_lookup_rsvdport(be,args,netdb,map,key,ypstatusp)2737c478bd9Sstevel@tonic-gate _nss_nis_lookup_rsvdport(be, args, netdb, map, key, ypstatusp)
2747c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
2757c478bd9Sstevel@tonic-gate 	nss_XbyY_args_t		*args;
2767c478bd9Sstevel@tonic-gate 	int			netdb;
2777c478bd9Sstevel@tonic-gate 	const char		*map;
2787c478bd9Sstevel@tonic-gate 	const char		*key;
2797c478bd9Sstevel@tonic-gate 	int			*ypstatusp;
2807c478bd9Sstevel@tonic-gate {
2817c478bd9Sstevel@tonic-gate 	nss_status_t		res;
2827c478bd9Sstevel@tonic-gate 	int			vallen;
2837c478bd9Sstevel@tonic-gate 	char			*val;
2847c478bd9Sstevel@tonic-gate 	char			*free_ptr;
2857c478bd9Sstevel@tonic-gate 	int			parsestat;
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 	if ((res = _nss_nis_ypmatch_rsvdport(be->domain, map, key, &val,
2887c478bd9Sstevel@tonic-gate 				    &vallen, ypstatusp)) != NSS_SUCCESS) {
2897c478bd9Sstevel@tonic-gate 		return (res);
2907c478bd9Sstevel@tonic-gate 	}
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	free_ptr = val;
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	if (netdb) {
2957c478bd9Sstevel@tonic-gate 		massage_netdb((const char **)&val, &vallen);
2967c478bd9Sstevel@tonic-gate 	}
2977c478bd9Sstevel@tonic-gate 
298cb5caa98Sdjl 	args->returnval = NULL;
299cb5caa98Sdjl 	args->returnlen = 0;
3007c478bd9Sstevel@tonic-gate 	parsestat = (*args->str2ent)(val, vallen,
3017c478bd9Sstevel@tonic-gate 			args->buf.result, args->buf.buffer, args->buf.buflen);
3027c478bd9Sstevel@tonic-gate 	if (parsestat == NSS_STR_PARSE_SUCCESS) {
3037c478bd9Sstevel@tonic-gate 		args->returnval = args->buf.result;
304cb5caa98Sdjl 		args->returnlen = vallen;
3057c478bd9Sstevel@tonic-gate 		res = NSS_SUCCESS;
3067c478bd9Sstevel@tonic-gate 	} else if (parsestat == NSS_STR_PARSE_ERANGE) {
3077c478bd9Sstevel@tonic-gate 		args->erange = 1;
3087c478bd9Sstevel@tonic-gate 		/* We won't find this otherwise, anyway */
3097c478bd9Sstevel@tonic-gate 		res = NSS_NOTFOUND;
3107c478bd9Sstevel@tonic-gate 	} /* else if (parsestat == NSS_STR_PARSE_PARSE) won't happen ! */
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	free(free_ptr);
3137c478bd9Sstevel@tonic-gate 
3147c478bd9Sstevel@tonic-gate 	return (res);
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate static nss_status_t
do_getent(be,args,netdb)3187c478bd9Sstevel@tonic-gate do_getent(be, args, netdb)
3197c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
3207c478bd9Sstevel@tonic-gate 	nss_XbyY_args_t		*args;
3217c478bd9Sstevel@tonic-gate 	int			netdb;
3227c478bd9Sstevel@tonic-gate {
3237c478bd9Sstevel@tonic-gate 	nss_status_t		res;
3247c478bd9Sstevel@tonic-gate 	int			ypstatus;
3257c478bd9Sstevel@tonic-gate 	int			outkeylen, outvallen;
3267c478bd9Sstevel@tonic-gate 	char			*outkey, *outval;
3277c478bd9Sstevel@tonic-gate 	char			*free_ptr;
3287c478bd9Sstevel@tonic-gate 	int			parsestat;
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate #if	MT_UNSAFE_YP
3317c478bd9Sstevel@tonic-gate 	sigset_t		oldmask, newmask;
3327c478bd9Sstevel@tonic-gate 
333cb5caa98Sdjl 	(void) sigfillset(&newmask);
3347257d1b4Sraf 	(void) thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask);
3357257d1b4Sraf 	(void) mutex_lock(&one_lane);
3367c478bd9Sstevel@tonic-gate #endif
3377c478bd9Sstevel@tonic-gate 	if (be->enum_key == 0) {
3387c478bd9Sstevel@tonic-gate 		ypstatus = __yp_first_cflookup((grrr)be->domain,
3397c478bd9Sstevel@tonic-gate 					    (grrr)be->enum_map, &outkey,
3407c478bd9Sstevel@tonic-gate 					    &outkeylen, &outval,
3417c478bd9Sstevel@tonic-gate 					    &outvallen, 0);
3427c478bd9Sstevel@tonic-gate 	} else {
3437c478bd9Sstevel@tonic-gate 		ypstatus = __yp_next_cflookup((grrr)be->domain,
3447c478bd9Sstevel@tonic-gate 					    (grrr)be->enum_map, be->enum_key,
3457c478bd9Sstevel@tonic-gate 					    be->enum_keylen, &outkey,
3467c478bd9Sstevel@tonic-gate 					    &outkeylen, &outval,
3477c478bd9Sstevel@tonic-gate 					    &outvallen, 0);
3487c478bd9Sstevel@tonic-gate 	}
3497c478bd9Sstevel@tonic-gate #if	MT_UNSAFE_YP
3507257d1b4Sraf 	(void) mutex_unlock(&one_lane);
3517257d1b4Sraf 	(void) thr_sigsetmask(SIG_SETMASK, &oldmask, NULL);
3527c478bd9Sstevel@tonic-gate #endif
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate 	if ((res = switch_err(ypstatus, 0)) != NSS_SUCCESS) {
3557c478bd9Sstevel@tonic-gate 		return (res);
3567c478bd9Sstevel@tonic-gate 	}
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 	free_ptr = outval;
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate 	if (netdb) {
3617c478bd9Sstevel@tonic-gate 		massage_netdb((const char **)&outval, &outvallen);
3627c478bd9Sstevel@tonic-gate 	}
3637c478bd9Sstevel@tonic-gate 
364cb5caa98Sdjl 	args->returnval = NULL;
365cb5caa98Sdjl 	args->returnlen = 0;
3667c478bd9Sstevel@tonic-gate 	parsestat = (*args->str2ent)(outval, outvallen,
3677c478bd9Sstevel@tonic-gate 			args->buf.result, args->buf.buffer, args->buf.buflen);
3687c478bd9Sstevel@tonic-gate 	if (parsestat == NSS_STR_PARSE_SUCCESS) {
3697c478bd9Sstevel@tonic-gate 		args->returnval = args->buf.result;
370cb5caa98Sdjl 		args->returnlen = outvallen;
3717c478bd9Sstevel@tonic-gate 		res = NSS_SUCCESS;
3727c478bd9Sstevel@tonic-gate 	} else if (parsestat == NSS_STR_PARSE_ERANGE) {
3737c478bd9Sstevel@tonic-gate 		args->erange = 1;
3747c478bd9Sstevel@tonic-gate 		/* We won't find this otherwise, anyway */
3757c478bd9Sstevel@tonic-gate 		res = NSS_NOTFOUND;
3767c478bd9Sstevel@tonic-gate 	} /* else if (parsestat == NSS_STR_PARSE_PARSE) won't happen ! */
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate 	free(free_ptr);
3797c478bd9Sstevel@tonic-gate 
3807c478bd9Sstevel@tonic-gate 	if (be->enum_key != 0) {
3817c478bd9Sstevel@tonic-gate 		free(be->enum_key);
3827c478bd9Sstevel@tonic-gate 	}
3837c478bd9Sstevel@tonic-gate 	be->enum_key = outkey;
3847c478bd9Sstevel@tonic-gate 	be->enum_keylen = outkeylen;
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 	return (res);
3877c478bd9Sstevel@tonic-gate }
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate nss_status_t
_nss_nis_getent_rigid(be,args)3907c478bd9Sstevel@tonic-gate _nss_nis_getent_rigid(be, args)
3917c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
3927c478bd9Sstevel@tonic-gate 	void			*args;
3937c478bd9Sstevel@tonic-gate {
3947c478bd9Sstevel@tonic-gate 	return (do_getent(be, (nss_XbyY_args_t *)args, 0));
3957c478bd9Sstevel@tonic-gate }
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate nss_status_t
_nss_nis_getent_netdb(be,args)3987c478bd9Sstevel@tonic-gate _nss_nis_getent_netdb(be, args)
3997c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
4007c478bd9Sstevel@tonic-gate 	void			*args;
4017c478bd9Sstevel@tonic-gate {
4027c478bd9Sstevel@tonic-gate 	return (do_getent(be, (nss_XbyY_args_t *)args, 1));
4037c478bd9Sstevel@tonic-gate }
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate struct cb_data {
4077c478bd9Sstevel@tonic-gate 	void			*args;
4087c478bd9Sstevel@tonic-gate 	const char		*filter;
4097c478bd9Sstevel@tonic-gate 	nis_do_all_func_t	func;
4107c478bd9Sstevel@tonic-gate 	nss_status_t		result;
4117c478bd9Sstevel@tonic-gate };
4127c478bd9Sstevel@tonic-gate 
4137c478bd9Sstevel@tonic-gate enum { ITER_NEXT = 0, ITER_STOP = 1 };	/* Should be in <rpcsvc/ypclnt.h> */
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4167c478bd9Sstevel@tonic-gate static int
do_cback(instatus,inkey,inkeylen,inval,invallen,indata)4177c478bd9Sstevel@tonic-gate do_cback(instatus, inkey, inkeylen, inval, invallen, indata)
4187c478bd9Sstevel@tonic-gate 	int			instatus;
4197c478bd9Sstevel@tonic-gate 	const char		*inkey;
4207c478bd9Sstevel@tonic-gate 	int			inkeylen;
4217c478bd9Sstevel@tonic-gate 	const char		*inval;
4227c478bd9Sstevel@tonic-gate 	int			invallen;
4237c478bd9Sstevel@tonic-gate 	struct cb_data		*indata;
4247c478bd9Sstevel@tonic-gate {
4257c478bd9Sstevel@tonic-gate 	nss_status_t		res;
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate 	if (instatus != YP_TRUE) {
4287c478bd9Sstevel@tonic-gate 		return (ITER_NEXT);	/* yp_all may decide otherwise... */
4297c478bd9Sstevel@tonic-gate 	}
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate 	if (indata->filter != 0 && strstr(inval, indata->filter) == 0) {
4327c478bd9Sstevel@tonic-gate 		/*
4337c478bd9Sstevel@tonic-gate 		 * Optimization:  if the entry doesn't contain the filter
4347c478bd9Sstevel@tonic-gate 		 *   string then it can't be the entry we want, so don't
4357c478bd9Sstevel@tonic-gate 		 *   bother looking more closely at it.
4367c478bd9Sstevel@tonic-gate 		 */
4377c478bd9Sstevel@tonic-gate 		return (ITER_NEXT);
4387c478bd9Sstevel@tonic-gate 	}
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate 	res = (*indata->func)(inval, invallen, indata->args);
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate 	if (res == NSS_NOTFOUND) {
4437c478bd9Sstevel@tonic-gate 		return (ITER_NEXT);
4447c478bd9Sstevel@tonic-gate 	} else {
4457c478bd9Sstevel@tonic-gate 		indata->result = res;
4467c478bd9Sstevel@tonic-gate 		return (ITER_STOP);
4477c478bd9Sstevel@tonic-gate 	}
4487c478bd9Sstevel@tonic-gate }
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate nss_status_t
_nss_nis_do_all(be,args,filter,func)4517c478bd9Sstevel@tonic-gate _nss_nis_do_all(be, args, filter, func)
4527c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
4537c478bd9Sstevel@tonic-gate 	void			*args;
4547c478bd9Sstevel@tonic-gate 	const char		*filter;
4557c478bd9Sstevel@tonic-gate 	nis_do_all_func_t	func;
4567c478bd9Sstevel@tonic-gate {
4577c478bd9Sstevel@tonic-gate 	int			ypall_status;
4587c478bd9Sstevel@tonic-gate 	struct cb_data		data;
4597c478bd9Sstevel@tonic-gate 	struct ypall_callback	cback;
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate 	data.args	= args;
4627c478bd9Sstevel@tonic-gate 	data.filter	= filter;
4637c478bd9Sstevel@tonic-gate 	data.func	= func;
4647c478bd9Sstevel@tonic-gate 	data.result	= NSS_NOTFOUND;
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 	cback.foreach	= do_cback;
4677c478bd9Sstevel@tonic-gate 	cback.data	= (char *)&data;
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate #if	MT_UNSAFE_YP
4707c478bd9Sstevel@tonic-gate 	sigset_t		oldmask, newmask;
4717c478bd9Sstevel@tonic-gate 
472cb5caa98Sdjl 	(void) sigfillset(&newmask);
4737257d1b4Sraf 	(void) thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask);
4747257d1b4Sraf 	(void) mutex_lock(&one_lane);
4757c478bd9Sstevel@tonic-gate #endif
4767c478bd9Sstevel@tonic-gate 	ypall_status = __yp_all_cflookup((grrr)be->domain,
4777c478bd9Sstevel@tonic-gate 			(grrr) be->enum_map, &cback, 0);
4787c478bd9Sstevel@tonic-gate #if	MT_UNSAFE_YP
4797257d1b4Sraf 	(void) mutex_unlock(&one_lane);
4807257d1b4Sraf 	(void) thr_sigsetmask(SIG_SETMASK, &oldmask, NULL);
4817c478bd9Sstevel@tonic-gate #endif
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate 	switch (ypall_status) {
4847c478bd9Sstevel@tonic-gate 	    case 0:
4857c478bd9Sstevel@tonic-gate 		return (data.result);
4867c478bd9Sstevel@tonic-gate 	    case YPERR_DOMAIN:
4877c478bd9Sstevel@tonic-gate 	    case YPERR_YPSERV:
4887c478bd9Sstevel@tonic-gate 	    case YPERR_BUSY:		/* Probably never get this, but... */
4897c478bd9Sstevel@tonic-gate 		return (NSS_TRYAGAIN);
4907c478bd9Sstevel@tonic-gate 	    default:
4917c478bd9Sstevel@tonic-gate 		return (NSS_UNAVAIL);
4927c478bd9Sstevel@tonic-gate 	}
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate struct XbyY_data {
4967c478bd9Sstevel@tonic-gate 	nss_XbyY_args_t		*args;
4977c478bd9Sstevel@tonic-gate 	nis_XY_check_func	func;
4987c478bd9Sstevel@tonic-gate 	int			netdb;
4997c478bd9Sstevel@tonic-gate };
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate static nss_status_t
XbyY_iterator(instr,instr_len,a)5027c478bd9Sstevel@tonic-gate XbyY_iterator(instr, instr_len, a)
5037c478bd9Sstevel@tonic-gate 	const char		*instr;
5047c478bd9Sstevel@tonic-gate 	int			instr_len;
5057c478bd9Sstevel@tonic-gate 	void			*a;
5067c478bd9Sstevel@tonic-gate {
5077c478bd9Sstevel@tonic-gate 	struct XbyY_data	*xydata	= (struct XbyY_data *)a;
5087c478bd9Sstevel@tonic-gate 	nss_XbyY_args_t		*args	= xydata->args;
5097c478bd9Sstevel@tonic-gate 	nss_status_t		res;
5107c478bd9Sstevel@tonic-gate 	int			parsestat;
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate 	if (xydata->netdb) {
5137c478bd9Sstevel@tonic-gate 		massage_netdb(&instr, &instr_len);
5147c478bd9Sstevel@tonic-gate 	}
5157c478bd9Sstevel@tonic-gate 
516cb5caa98Sdjl 	args->returnval = NULL;
517cb5caa98Sdjl 	args->returnlen = 0;
5187c478bd9Sstevel@tonic-gate 	parsestat = (*args->str2ent)(instr, instr_len,
5197c478bd9Sstevel@tonic-gate 			args->buf.result, args->buf.buffer, args->buf.buflen);
5207c478bd9Sstevel@tonic-gate 	if (parsestat == NSS_STR_PARSE_SUCCESS) {
5217c478bd9Sstevel@tonic-gate 		args->returnval = args->buf.result;
5227c478bd9Sstevel@tonic-gate 		if ((*xydata->func)(args)) {
5237c478bd9Sstevel@tonic-gate 			res = NSS_SUCCESS;
524cb5caa98Sdjl 			args->returnlen = instr_len;
5257c478bd9Sstevel@tonic-gate 		} else {
5267c478bd9Sstevel@tonic-gate 			res = NSS_NOTFOUND;
5277c478bd9Sstevel@tonic-gate 			args->returnval = 0;
5287c478bd9Sstevel@tonic-gate 		}
5297c478bd9Sstevel@tonic-gate 	} else if (parsestat == NSS_STR_PARSE_ERANGE) {
5307c478bd9Sstevel@tonic-gate 		/*
5317c478bd9Sstevel@tonic-gate 		 * If we got here because (*str2ent)() found that the buffer
5327c478bd9Sstevel@tonic-gate 		 * wasn't big enough, maybe we should quit and return erange.
5337c478bd9Sstevel@tonic-gate 		 * Instead we'll keep looking and eventually return "not
5347c478bd9Sstevel@tonic-gate 		 * found" -- it's a bug, but not an earth-shattering one.
5357c478bd9Sstevel@tonic-gate 		 */
5367c478bd9Sstevel@tonic-gate 		args->erange = 1;	/* <== Is this a good idea? */
5377c478bd9Sstevel@tonic-gate 		res = NSS_NOTFOUND;
5387c478bd9Sstevel@tonic-gate 	} /* else if (parsestat == NSS_STR_PARSE_PARSE) won't happen ! */
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 	return (res);
5417c478bd9Sstevel@tonic-gate }
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate nss_status_t
_nss_nis_XY_all(be,args,netdb,filter,func)5447c478bd9Sstevel@tonic-gate _nss_nis_XY_all(be, args, netdb, filter, func)
5457c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
5467c478bd9Sstevel@tonic-gate 	nss_XbyY_args_t		*args;
5477c478bd9Sstevel@tonic-gate 	int			netdb;
5487c478bd9Sstevel@tonic-gate 	const char		*filter;
5497c478bd9Sstevel@tonic-gate 	nis_XY_check_func	func;
5507c478bd9Sstevel@tonic-gate {
5517c478bd9Sstevel@tonic-gate 	struct XbyY_data	data;
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 	data.args = args;
5547c478bd9Sstevel@tonic-gate 	data.func = func;
5557c478bd9Sstevel@tonic-gate 	data.netdb = netdb;
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 	return (_nss_nis_do_all(be, &data, filter, XbyY_iterator));
5587c478bd9Sstevel@tonic-gate 	/* Now how many levels of callbacks was that? */
5597c478bd9Sstevel@tonic-gate }
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate /*ARGSUSED*/
5637c478bd9Sstevel@tonic-gate nss_status_t
_nss_nis_destr(be,dummy)5647c478bd9Sstevel@tonic-gate _nss_nis_destr(be, dummy)
5657c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
5667c478bd9Sstevel@tonic-gate 	void			*dummy;
5677c478bd9Sstevel@tonic-gate {
5687c478bd9Sstevel@tonic-gate 	if (be != 0) {
5697c478bd9Sstevel@tonic-gate 		/* === Should change to invoke ops[ENDENT] ? */
570cb5caa98Sdjl 		(void) _nss_nis_endent(be, 0);
5717c478bd9Sstevel@tonic-gate 		free(be);
5727c478bd9Sstevel@tonic-gate 	}
5737c478bd9Sstevel@tonic-gate 	return (NSS_SUCCESS);	/* In case anyone is dumb enough to check */
5747c478bd9Sstevel@tonic-gate }
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate /* We want to lock this even if the YP routines are MT-safe */
5777c478bd9Sstevel@tonic-gate static mutex_t	yp_domain_lock = DEFAULTMUTEX;
5787c478bd9Sstevel@tonic-gate static char	*yp_domain;
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate const char *
_nss_nis_domain()5817c478bd9Sstevel@tonic-gate _nss_nis_domain()
5827c478bd9Sstevel@tonic-gate {
5837c478bd9Sstevel@tonic-gate 	char			*domain;
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate 	/*
5867c478bd9Sstevel@tonic-gate 	 * This much locking is probably more "by the book" than necessary...
5877c478bd9Sstevel@tonic-gate 	 */
5887c478bd9Sstevel@tonic-gate 	sigset_t		oldmask, newmask;
5897c478bd9Sstevel@tonic-gate 
590cb5caa98Sdjl 	(void) sigfillset(&newmask);
5917257d1b4Sraf 	(void) thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask);
5927257d1b4Sraf 	(void) mutex_lock(&yp_domain_lock);
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate 	if ((domain = yp_domain) == 0) {
5957c478bd9Sstevel@tonic-gate #if	MT_UNSAFE_YP
5967257d1b4Sraf 		(void) mutex_lock(&one_lane);
5977c478bd9Sstevel@tonic-gate #endif
5987c478bd9Sstevel@tonic-gate 		if (yp_get_default_domain(&yp_domain) == 0) {
5997c478bd9Sstevel@tonic-gate 			domain = yp_domain;
6007c478bd9Sstevel@tonic-gate 		}
6017c478bd9Sstevel@tonic-gate #if	MT_UNSAFE_YP
6027257d1b4Sraf 		(void) mutex_unlock(&one_lane);
6037c478bd9Sstevel@tonic-gate #endif
6047c478bd9Sstevel@tonic-gate 	}
6057c478bd9Sstevel@tonic-gate 
6067257d1b4Sraf 	(void) mutex_unlock(&yp_domain_lock);
6077257d1b4Sraf 	(void) thr_sigsetmask(SIG_SETMASK, &oldmask, NULL);
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate 	return (domain);
6107c478bd9Sstevel@tonic-gate }
6117c478bd9Sstevel@tonic-gate 
6127c478bd9Sstevel@tonic-gate nss_backend_t *
_nss_nis_constr(ops,n_ops,enum_map)6137c478bd9Sstevel@tonic-gate _nss_nis_constr(ops, n_ops, enum_map)
6147c478bd9Sstevel@tonic-gate 	nis_backend_op_t	ops[];
6157c478bd9Sstevel@tonic-gate 	int			n_ops;
6167c478bd9Sstevel@tonic-gate 	const char		*enum_map;
6177c478bd9Sstevel@tonic-gate {
6187c478bd9Sstevel@tonic-gate 	const char		*domain;
6197c478bd9Sstevel@tonic-gate 	nis_backend_ptr_t	be;
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate 	if ((domain = _nss_nis_domain()) == 0 ||
6227c478bd9Sstevel@tonic-gate 	    (be = (nis_backend_ptr_t)malloc(sizeof (*be))) == 0) {
6237c478bd9Sstevel@tonic-gate 		return (0);
6247c478bd9Sstevel@tonic-gate 	}
6257c478bd9Sstevel@tonic-gate 	be->ops		= ops;
6267c478bd9Sstevel@tonic-gate 	be->n_ops	= n_ops;
6277c478bd9Sstevel@tonic-gate 	be->domain	= domain;
6287c478bd9Sstevel@tonic-gate 	be->enum_map	= enum_map;   /* Don't strdup, assume valid forever */
6297c478bd9Sstevel@tonic-gate 	be->enum_key	= 0;
6307c478bd9Sstevel@tonic-gate 	be->enum_keylen	= 0;
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate 	return ((nss_backend_t *)be);
6337c478bd9Sstevel@tonic-gate }
634cb5caa98Sdjl 
635cb5caa98Sdjl /*
636cb5caa98Sdjl  * This routine is used to parse lines of the form:
637cb5caa98Sdjl  * 	name number aliases
638cb5caa98Sdjl  * It returns 1 if the key in argp matches any one of the
639cb5caa98Sdjl  * names in the line, otherwise 0
640cb5caa98Sdjl  * Used by rpc
641cb5caa98Sdjl  */
642cb5caa98Sdjl int
_nss_nis_check_name_aliases(nss_XbyY_args_t * argp,const char * line,int linelen)643cb5caa98Sdjl _nss_nis_check_name_aliases(nss_XbyY_args_t *argp, const char *line,
644cb5caa98Sdjl 	int linelen)
645cb5caa98Sdjl {
646cb5caa98Sdjl 	const char	*limit, *linep, *keyp;
647cb5caa98Sdjl 
648cb5caa98Sdjl 	linep = line;
649cb5caa98Sdjl 	limit = line + linelen;
650cb5caa98Sdjl 	keyp = argp->key.name;
651cb5caa98Sdjl 
652cb5caa98Sdjl 	/* compare name */
653cb5caa98Sdjl 	while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) {
654cb5caa98Sdjl 		keyp++;
655cb5caa98Sdjl 		linep++;
656cb5caa98Sdjl 	}
657cb5caa98Sdjl 	if (*keyp == '\0' && linep < limit && isspace(*linep))
658cb5caa98Sdjl 		return (1);
659cb5caa98Sdjl 	/* skip remainder of the name, if any */
660cb5caa98Sdjl 	while (linep < limit && !isspace(*linep))
661cb5caa98Sdjl 		linep++;
662cb5caa98Sdjl 	/* skip the delimiting spaces */
663cb5caa98Sdjl 	while (linep < limit && isspace(*linep))
664cb5caa98Sdjl 		linep++;
665cb5caa98Sdjl 	/* compare with the aliases */
666cb5caa98Sdjl 	while (linep < limit) {
667cb5caa98Sdjl 		/*
668cb5caa98Sdjl 		 * 1st pass: skip number
669cb5caa98Sdjl 		 * Other passes: skip remainder of the alias name, if any
670cb5caa98Sdjl 		 */
671cb5caa98Sdjl 		while (linep < limit && !isspace(*linep))
672cb5caa98Sdjl 			linep++;
673cb5caa98Sdjl 		/* skip the delimiting spaces */
674cb5caa98Sdjl 		while (linep < limit && isspace(*linep))
675cb5caa98Sdjl 			linep++;
676cb5caa98Sdjl 		/* compare with the alias name */
677cb5caa98Sdjl 		keyp = argp->key.name;
678cb5caa98Sdjl 		while (*keyp && linep < limit && !isspace(*linep) &&
6797257d1b4Sraf 		    *keyp == *linep) {
680cb5caa98Sdjl 			keyp++;
681cb5caa98Sdjl 			linep++;
682cb5caa98Sdjl 		}
683cb5caa98Sdjl 		if (*keyp == '\0' && (linep == limit || isspace(*linep)))
684cb5caa98Sdjl 			return (1);
685cb5caa98Sdjl 	}
686cb5caa98Sdjl 	return (0);
687cb5caa98Sdjl }
688