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) &&
679cb5caa98Sdjl *keyp == *linep) {
680cb5caa98Sdjl keyp++;
681cb5caa98Sdjl linep++;
682cb5caa98Sdjl }
683cb5caa98Sdjl if (*keyp == '\0' && (linep == limit || isspace(*linep)))
684cb5caa98Sdjl return (1);
685cb5caa98Sdjl }
686cb5caa98Sdjl return (0);
687cb5caa98Sdjl }
688