10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*2170Sevanl * Common Development and Distribution License (the "License"). 6*2170Sevanl * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 220Sstevel@tonic-gate * ns_nis.c 230Sstevel@tonic-gate * 24*2170Sevanl * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 250Sstevel@tonic-gate * Use is subject to license terms. 260Sstevel@tonic-gate */ 270Sstevel@tonic-gate 280Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 290Sstevel@tonic-gate 300Sstevel@tonic-gate #include <stdio.h> 310Sstevel@tonic-gate #include <stdlib.h> 320Sstevel@tonic-gate #include <unistd.h> 330Sstevel@tonic-gate #include <syslog.h> 340Sstevel@tonic-gate #include <string.h> 350Sstevel@tonic-gate #include <ctype.h> 360Sstevel@tonic-gate #include <nsswitch.h> 370Sstevel@tonic-gate #include <sys/param.h> 380Sstevel@tonic-gate #include <sys/types.h> 390Sstevel@tonic-gate #include <sys/systeminfo.h> 400Sstevel@tonic-gate #include <rpc/rpc.h> 410Sstevel@tonic-gate #include <rpcsvc/nfs_prot.h> 420Sstevel@tonic-gate #include <rpcsvc/ypclnt.h> 430Sstevel@tonic-gate #include <rpcsvc/yp_prot.h> 440Sstevel@tonic-gate #include <sys/errno.h> 450Sstevel@tonic-gate #include "automount.h" 460Sstevel@tonic-gate 470Sstevel@tonic-gate #define KEY 0 480Sstevel@tonic-gate #define CONTENTS 1 490Sstevel@tonic-gate 500Sstevel@tonic-gate static int replace_undscr_by_dot(char *); 510Sstevel@tonic-gate static int nis_err(int); 520Sstevel@tonic-gate 530Sstevel@tonic-gate static char nis_mydomain[YPMAXDOMAIN]; 540Sstevel@tonic-gate 550Sstevel@tonic-gate struct dir_cbdata { 560Sstevel@tonic-gate struct dir_entry **list; 570Sstevel@tonic-gate struct dir_entry *last; 580Sstevel@tonic-gate int error; 590Sstevel@tonic-gate }; 600Sstevel@tonic-gate 610Sstevel@tonic-gate static int readdir_callback(int, char *, int, const char *, 620Sstevel@tonic-gate int, struct dir_cbdata *); 630Sstevel@tonic-gate 640Sstevel@tonic-gate void 650Sstevel@tonic-gate init_nis(char **stack, char ***stkptr) 660Sstevel@tonic-gate { 670Sstevel@tonic-gate #ifdef lint 680Sstevel@tonic-gate stack = stack; 690Sstevel@tonic-gate stkptr = stkptr; 700Sstevel@tonic-gate #endif /* lint */ 710Sstevel@tonic-gate 720Sstevel@tonic-gate (void) sysinfo(SI_SRPC_DOMAIN, nis_mydomain, sizeof (nis_mydomain)); 730Sstevel@tonic-gate (void) __nis_reset_state(); /* XXX temporary hack for csh bug */ 740Sstevel@tonic-gate } 750Sstevel@tonic-gate 760Sstevel@tonic-gate /*ARGSUSED*/ 770Sstevel@tonic-gate int 780Sstevel@tonic-gate getmapent_nis(key, map, ml, stack, stkptr, iswildcard, isrestricted) 790Sstevel@tonic-gate char *key, *map; 800Sstevel@tonic-gate struct mapline *ml; 810Sstevel@tonic-gate char **stack; 820Sstevel@tonic-gate char ***stkptr; 830Sstevel@tonic-gate bool_t *iswildcard; 840Sstevel@tonic-gate bool_t isrestricted; 850Sstevel@tonic-gate { 860Sstevel@tonic-gate char *nisline = NULL; 870Sstevel@tonic-gate char *my_map = NULL; 880Sstevel@tonic-gate char *lp, *lq; 890Sstevel@tonic-gate int nislen, len; 900Sstevel@tonic-gate int nserr; 910Sstevel@tonic-gate 920Sstevel@tonic-gate if (iswildcard) 930Sstevel@tonic-gate *iswildcard = FALSE; 940Sstevel@tonic-gate nserr = yp_match(nis_mydomain, map, key, strlen(key), 950Sstevel@tonic-gate &nisline, &nislen); 960Sstevel@tonic-gate if (nserr == YPERR_MAP) { 970Sstevel@tonic-gate my_map = strdup(map); 980Sstevel@tonic-gate if (my_map == NULL) { 990Sstevel@tonic-gate syslog(LOG_ERR, 1000Sstevel@tonic-gate "getmapent_nis: memory alloc failed: %m"); 1010Sstevel@tonic-gate return (__NSW_UNAVAIL); 1020Sstevel@tonic-gate } 1030Sstevel@tonic-gate if (replace_undscr_by_dot(my_map)) 1040Sstevel@tonic-gate nserr = yp_match(nis_mydomain, my_map, key, 1050Sstevel@tonic-gate strlen(key), &nisline, &nislen); 1060Sstevel@tonic-gate } 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate if (nserr) { 1090Sstevel@tonic-gate if (nserr == YPERR_KEY) { 1100Sstevel@tonic-gate /* 1110Sstevel@tonic-gate * Try the default entry "*" 1120Sstevel@tonic-gate */ 1130Sstevel@tonic-gate if (my_map == NULL) 1140Sstevel@tonic-gate nserr = yp_match(nis_mydomain, map, "*", 1, 1150Sstevel@tonic-gate &nisline, &nislen); 1160Sstevel@tonic-gate else 1170Sstevel@tonic-gate nserr = yp_match(nis_mydomain, my_map, "*", 1, 1180Sstevel@tonic-gate &nisline, &nislen); 1190Sstevel@tonic-gate if (!nserr && iswildcard) 1200Sstevel@tonic-gate *iswildcard = TRUE; 1210Sstevel@tonic-gate } else { 1220Sstevel@tonic-gate if (verbose) 1230Sstevel@tonic-gate syslog(LOG_ERR, "%s: %s", 1240Sstevel@tonic-gate map, yperr_string(nserr)); 1250Sstevel@tonic-gate nserr = 1; 1260Sstevel@tonic-gate } 1270Sstevel@tonic-gate } 1280Sstevel@tonic-gate if (my_map != NULL) 1290Sstevel@tonic-gate free(my_map); 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate nserr = nis_err(nserr); 1320Sstevel@tonic-gate if (nserr) 1330Sstevel@tonic-gate goto done; 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate /* 1360Sstevel@tonic-gate * at this point we are sure that yp_match succeeded 1370Sstevel@tonic-gate * so massage the entry by 1380Sstevel@tonic-gate * 1. ignoring # and beyond 1390Sstevel@tonic-gate * 2. trim the trailing whitespace 1400Sstevel@tonic-gate */ 1410Sstevel@tonic-gate if (lp = strchr(nisline, '#')) 1420Sstevel@tonic-gate *lp = '\0'; 1430Sstevel@tonic-gate len = strlen(nisline); 1440Sstevel@tonic-gate if (len == 0) { 1450Sstevel@tonic-gate nserr = __NSW_NOTFOUND; 1460Sstevel@tonic-gate goto done; 1470Sstevel@tonic-gate } 1480Sstevel@tonic-gate lp = &nisline[len - 1]; 1490Sstevel@tonic-gate while (lp > nisline && isspace(*lp)) 1500Sstevel@tonic-gate *lp-- = '\0'; 1510Sstevel@tonic-gate if (lp == nisline) { 1520Sstevel@tonic-gate nserr = __NSW_NOTFOUND; 1530Sstevel@tonic-gate goto done; 1540Sstevel@tonic-gate } 1550Sstevel@tonic-gate (void) strcpy(ml->linebuf, nisline); 1560Sstevel@tonic-gate lp = ml->linebuf; 1570Sstevel@tonic-gate lq = ml->lineqbuf; 1580Sstevel@tonic-gate unquote(lp, lq); 1590Sstevel@tonic-gate /* now we have the correct line */ 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate nserr = __NSW_SUCCESS; 1620Sstevel@tonic-gate done: 1630Sstevel@tonic-gate if (nisline) 1640Sstevel@tonic-gate free((char *)nisline); 1650Sstevel@tonic-gate return (nserr); 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate } 1680Sstevel@tonic-gate 169249Sjwahlig int 1700Sstevel@tonic-gate loadmaster_nis(mapname, defopts, stack, stkptr) 1710Sstevel@tonic-gate char *mapname, *defopts; 1720Sstevel@tonic-gate char **stack; 1730Sstevel@tonic-gate char ***stkptr; 1740Sstevel@tonic-gate { 1750Sstevel@tonic-gate int first, err; 1760Sstevel@tonic-gate char *key, *nkey, *val; 1770Sstevel@tonic-gate int kl, nkl, vl; 1780Sstevel@tonic-gate char dir[256], map[256], qbuff[256]; 1790Sstevel@tonic-gate char *pmap, *opts, *my_mapname; 1800Sstevel@tonic-gate int count = 0; 1810Sstevel@tonic-gate 1820Sstevel@tonic-gate first = 1; 1830Sstevel@tonic-gate key = NULL; kl = 0; 1840Sstevel@tonic-gate nkey = NULL; nkl = 0; 1850Sstevel@tonic-gate val = NULL; vl = 0; 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate /* 1880Sstevel@tonic-gate * need a private copy of mapname, because we may change 1890Sstevel@tonic-gate * the underscores by dots. We however do not want the 1900Sstevel@tonic-gate * orignal to be changed, as we may want to use the 1910Sstevel@tonic-gate * original name in some other name service 1920Sstevel@tonic-gate */ 1930Sstevel@tonic-gate my_mapname = strdup(mapname); 1940Sstevel@tonic-gate if (my_mapname == NULL) { 1950Sstevel@tonic-gate syslog(LOG_ERR, "loadmaster_yp: memory alloc failed: %m"); 1960Sstevel@tonic-gate /* not the name svc's fault but ... */ 1970Sstevel@tonic-gate return (__NSW_UNAVAIL); 1980Sstevel@tonic-gate } 1990Sstevel@tonic-gate for (;;) { 2000Sstevel@tonic-gate if (first) { 2010Sstevel@tonic-gate first = 0; 2020Sstevel@tonic-gate err = yp_first(nis_mydomain, my_mapname, 2030Sstevel@tonic-gate &nkey, &nkl, &val, &vl); 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate if ((err == YPERR_MAP) && 2060Sstevel@tonic-gate (replace_undscr_by_dot(my_mapname))) 2070Sstevel@tonic-gate err = yp_first(nis_mydomain, my_mapname, 2080Sstevel@tonic-gate &nkey, &nkl, &val, &vl); 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate if ((err == YPERR_DOMAIN) || (err == YPERR_YPBIND)) { 2110Sstevel@tonic-gate syslog(LOG_ERR, 2120Sstevel@tonic-gate "can't read nis map %s: %s - retrying", 2130Sstevel@tonic-gate my_mapname, yperr_string(err)); 2140Sstevel@tonic-gate while ((err == YPERR_DOMAIN) || 2150Sstevel@tonic-gate (err == YPERR_YPBIND)) { 2160Sstevel@tonic-gate (void) sleep(20); 2170Sstevel@tonic-gate err = yp_first(nis_mydomain, my_mapname, 2180Sstevel@tonic-gate &nkey, &nkl, &val, &vl); 2190Sstevel@tonic-gate } 2200Sstevel@tonic-gate syslog(LOG_ERR, 2210Sstevel@tonic-gate "nis map %s: read OK.", my_mapname); 2220Sstevel@tonic-gate } 2230Sstevel@tonic-gate } else { 2240Sstevel@tonic-gate err = yp_next(nis_mydomain, my_mapname, key, kl, 2250Sstevel@tonic-gate &nkey, &nkl, &val, &vl); 2260Sstevel@tonic-gate } 2270Sstevel@tonic-gate if (err) { 2280Sstevel@tonic-gate if (err != YPERR_NOMORE && err != YPERR_MAP) 2290Sstevel@tonic-gate if (verbose) 2300Sstevel@tonic-gate syslog(LOG_ERR, "%s: %s", 2310Sstevel@tonic-gate my_mapname, yperr_string(err)); 2320Sstevel@tonic-gate break; 2330Sstevel@tonic-gate } 2340Sstevel@tonic-gate if (key) 2350Sstevel@tonic-gate free(key); 2360Sstevel@tonic-gate key = nkey; 2370Sstevel@tonic-gate kl = nkl; 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate if (kl >= 256 || vl >= 256) 2410Sstevel@tonic-gate break; 2420Sstevel@tonic-gate if (kl < 2 || vl < 1) 2430Sstevel@tonic-gate break; 2440Sstevel@tonic-gate if (isspace(*key) || *key == '#') 2450Sstevel@tonic-gate break; 2460Sstevel@tonic-gate (void) strncpy(dir, key, kl); 2470Sstevel@tonic-gate dir[kl] = '\0'; 2480Sstevel@tonic-gate if (macro_expand("", dir, qbuff, sizeof (dir))) { 2490Sstevel@tonic-gate syslog(LOG_ERR, 2500Sstevel@tonic-gate "%s in NIS map %s: entry too long (max %d chars)", 2510Sstevel@tonic-gate dir, my_mapname, sizeof (dir) - 1); 2520Sstevel@tonic-gate break; 2530Sstevel@tonic-gate } 2540Sstevel@tonic-gate (void) strncpy(map, val, vl); 2550Sstevel@tonic-gate map[vl] = '\0'; 2560Sstevel@tonic-gate if (macro_expand(dir, map, qbuff, sizeof (map))) { 2570Sstevel@tonic-gate syslog(LOG_ERR, 2580Sstevel@tonic-gate "%s in NIS map %s: entry too long (max %d chars)", 2590Sstevel@tonic-gate map, my_mapname, sizeof (map) - 1); 2600Sstevel@tonic-gate break; 2610Sstevel@tonic-gate } 2620Sstevel@tonic-gate pmap = map; 2630Sstevel@tonic-gate while (*pmap && isspace(*pmap)) 2640Sstevel@tonic-gate pmap++; /* skip blanks in front of map */ 2650Sstevel@tonic-gate opts = pmap; 2660Sstevel@tonic-gate while (*opts && !isspace(*opts)) 2670Sstevel@tonic-gate opts++; 2680Sstevel@tonic-gate if (*opts) { 2690Sstevel@tonic-gate *opts++ = '\0'; 2700Sstevel@tonic-gate while (*opts && isspace(*opts)) 2710Sstevel@tonic-gate opts++; 2720Sstevel@tonic-gate if (*opts == '-') 2730Sstevel@tonic-gate opts++; 2740Sstevel@tonic-gate else 2750Sstevel@tonic-gate opts = defopts; 2760Sstevel@tonic-gate } 2770Sstevel@tonic-gate free(val); 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate /* 2800Sstevel@tonic-gate * Check for no embedded blanks. 2810Sstevel@tonic-gate */ 2820Sstevel@tonic-gate if (strcspn(opts, " ") == strlen(opts)) { 2830Sstevel@tonic-gate dirinit(dir, pmap, opts, 0, stack, stkptr); 2840Sstevel@tonic-gate count++; 2850Sstevel@tonic-gate } else { 2860Sstevel@tonic-gate pr_msg("Warning: invalid entry for %s in NIS map %s ignored.\n", dir, mapname); 2870Sstevel@tonic-gate } 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate } 2900Sstevel@tonic-gate if (my_mapname) 2910Sstevel@tonic-gate free(my_mapname); 2920Sstevel@tonic-gate 2930Sstevel@tonic-gate /* 2940Sstevel@tonic-gate * In the context of a master map, if no entry is 2950Sstevel@tonic-gate * found, it is like NOTFOUND 2960Sstevel@tonic-gate */ 2970Sstevel@tonic-gate if (count > 0 && err == YPERR_NOMORE) 2980Sstevel@tonic-gate return (__NSW_SUCCESS); 2990Sstevel@tonic-gate else { 3000Sstevel@tonic-gate if (err) 3010Sstevel@tonic-gate return (nis_err(err)); 3020Sstevel@tonic-gate else 3030Sstevel@tonic-gate /* 3040Sstevel@tonic-gate * This case will happen if map is empty 3050Sstevel@tonic-gate * or none of the entries is valid 3060Sstevel@tonic-gate */ 3070Sstevel@tonic-gate return (__NSW_NOTFOUND); 3080Sstevel@tonic-gate } 3090Sstevel@tonic-gate } 3100Sstevel@tonic-gate 311249Sjwahlig int 3120Sstevel@tonic-gate loaddirect_nis(nismap, localmap, opts, stack, stkptr) 3130Sstevel@tonic-gate char *nismap, *localmap, *opts; 3140Sstevel@tonic-gate char **stack; 3150Sstevel@tonic-gate char ***stkptr; 3160Sstevel@tonic-gate { 3170Sstevel@tonic-gate int first, err, count; 3180Sstevel@tonic-gate char *key, *nkey, *val, *my_nismap; 3190Sstevel@tonic-gate int kl, nkl, vl; 3200Sstevel@tonic-gate char dir[100]; 3210Sstevel@tonic-gate 3220Sstevel@tonic-gate first = 1; 3230Sstevel@tonic-gate key = NULL; kl = 0; 3240Sstevel@tonic-gate nkey = NULL; nkl = 0; 3250Sstevel@tonic-gate val = NULL; vl = 0; 3260Sstevel@tonic-gate count = 0; 3270Sstevel@tonic-gate my_nismap = NULL; 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate my_nismap = strdup(nismap); 3300Sstevel@tonic-gate if (my_nismap == NULL) { 3310Sstevel@tonic-gate syslog(LOG_ERR, "loadmaster_yp: memory alloc failed: %m"); 3320Sstevel@tonic-gate return (__NSW_UNAVAIL); 3330Sstevel@tonic-gate } 3340Sstevel@tonic-gate for (;;) { 3350Sstevel@tonic-gate if (first) { 3360Sstevel@tonic-gate first = 0; 3370Sstevel@tonic-gate err = yp_first(nis_mydomain, my_nismap, &nkey, &nkl, 3380Sstevel@tonic-gate &val, &vl); 3390Sstevel@tonic-gate 3400Sstevel@tonic-gate if ((err == YPERR_MAP) && 3410Sstevel@tonic-gate (replace_undscr_by_dot(my_nismap))) 3420Sstevel@tonic-gate err = yp_first(nis_mydomain, my_nismap, 3430Sstevel@tonic-gate &nkey, &nkl, &val, &vl); 3440Sstevel@tonic-gate 3450Sstevel@tonic-gate if ((err == YPERR_DOMAIN) || (err == YPERR_YPBIND)) { 3460Sstevel@tonic-gate syslog(LOG_ERR, 3470Sstevel@tonic-gate "can't read nis map %s: %s - retrying", 3480Sstevel@tonic-gate my_nismap, yperr_string(err)); 3490Sstevel@tonic-gate while ((err == YPERR_DOMAIN) || 3500Sstevel@tonic-gate (err == YPERR_YPBIND)) { 3510Sstevel@tonic-gate (void) sleep(20); 3520Sstevel@tonic-gate err = yp_first(nis_mydomain, my_nismap, 3530Sstevel@tonic-gate &nkey, &nkl, &val, &vl); 3540Sstevel@tonic-gate } 3550Sstevel@tonic-gate syslog(LOG_ERR, 3560Sstevel@tonic-gate "nis map %s: read OK.", my_nismap); 3570Sstevel@tonic-gate } 3580Sstevel@tonic-gate } else { 3590Sstevel@tonic-gate err = yp_next(nis_mydomain, my_nismap, key, kl, 3600Sstevel@tonic-gate &nkey, &nkl, &val, &vl); 3610Sstevel@tonic-gate } 3620Sstevel@tonic-gate if (err) { 3630Sstevel@tonic-gate if (err != YPERR_NOMORE && err != YPERR_MAP) 3640Sstevel@tonic-gate syslog(LOG_ERR, "%s: %s", 3650Sstevel@tonic-gate my_nismap, yperr_string(err)); 3660Sstevel@tonic-gate break; 3670Sstevel@tonic-gate } 3680Sstevel@tonic-gate if (key) 3690Sstevel@tonic-gate free(key); 3700Sstevel@tonic-gate key = nkey; 3710Sstevel@tonic-gate kl = nkl; 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate if (kl < 2 || kl >= 100) 3740Sstevel@tonic-gate continue; 3750Sstevel@tonic-gate if (isspace(*key) || *key == '#') 3760Sstevel@tonic-gate continue; 3770Sstevel@tonic-gate (void) strncpy(dir, key, kl); 3780Sstevel@tonic-gate dir[kl] = '\0'; 3790Sstevel@tonic-gate 3800Sstevel@tonic-gate dirinit(dir, localmap, opts, 1, stack, stkptr); 3810Sstevel@tonic-gate count++; 3820Sstevel@tonic-gate free(val); 3830Sstevel@tonic-gate } 3840Sstevel@tonic-gate 3850Sstevel@tonic-gate if (my_nismap) 3860Sstevel@tonic-gate free(my_nismap); 3870Sstevel@tonic-gate 3880Sstevel@tonic-gate if (count > 0 && err == YPERR_NOMORE) 3890Sstevel@tonic-gate return (__NSW_SUCCESS); 3900Sstevel@tonic-gate else 3910Sstevel@tonic-gate return (nis_err(err)); 3920Sstevel@tonic-gate 3930Sstevel@tonic-gate } 3940Sstevel@tonic-gate 3950Sstevel@tonic-gate static int 3960Sstevel@tonic-gate replace_undscr_by_dot(map) 3970Sstevel@tonic-gate char *map; 3980Sstevel@tonic-gate { 3990Sstevel@tonic-gate int ret_val = 0; 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate while (*map) { 4020Sstevel@tonic-gate if (*map == '_') { 4030Sstevel@tonic-gate ret_val = 1; 4040Sstevel@tonic-gate *map = '.'; 4050Sstevel@tonic-gate } 4060Sstevel@tonic-gate map++; 4070Sstevel@tonic-gate } 4080Sstevel@tonic-gate return (ret_val); 4090Sstevel@tonic-gate } 4100Sstevel@tonic-gate 4110Sstevel@tonic-gate static int 4120Sstevel@tonic-gate nis_err(err) 4130Sstevel@tonic-gate int err; 4140Sstevel@tonic-gate { 4150Sstevel@tonic-gate switch (err) { 4160Sstevel@tonic-gate case 0: 4170Sstevel@tonic-gate return (__NSW_SUCCESS); 4180Sstevel@tonic-gate case YPERR_KEY: 4190Sstevel@tonic-gate return (__NSW_NOTFOUND); 4200Sstevel@tonic-gate case YPERR_MAP: 4210Sstevel@tonic-gate return (__NSW_UNAVAIL); 4220Sstevel@tonic-gate default: 4230Sstevel@tonic-gate return (__NSW_UNAVAIL); 4240Sstevel@tonic-gate } 4250Sstevel@tonic-gate } 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate int 4280Sstevel@tonic-gate getmapkeys_nis(nsmap, list, error, cache_time, stack, stkptr) 4290Sstevel@tonic-gate char *nsmap; 4300Sstevel@tonic-gate struct dir_entry **list; 4310Sstevel@tonic-gate int *error; 4320Sstevel@tonic-gate int *cache_time; 4330Sstevel@tonic-gate char **stack; 4340Sstevel@tonic-gate char ***stkptr; 4350Sstevel@tonic-gate { 4360Sstevel@tonic-gate int nserr; 4370Sstevel@tonic-gate struct dir_cbdata readdir_cbdata; 4380Sstevel@tonic-gate struct ypall_callback cback; 4390Sstevel@tonic-gate char *my_map = NULL; 4400Sstevel@tonic-gate 4410Sstevel@tonic-gate char *key = NULL, *val = NULL; 4420Sstevel@tonic-gate int nkl, vl; 4430Sstevel@tonic-gate 4440Sstevel@tonic-gate #ifdef lint 4450Sstevel@tonic-gate stack = stack; 4460Sstevel@tonic-gate stkptr = stkptr; 4470Sstevel@tonic-gate #endif /* lint */ 4480Sstevel@tonic-gate 4490Sstevel@tonic-gate *cache_time = RDDIR_CACHE_TIME; 4500Sstevel@tonic-gate 4510Sstevel@tonic-gate /* 4520Sstevel@tonic-gate * XXX Hack to determine if we need to replace '_' with '.' 4530Sstevel@tonic-gate * Have to use yp_first() since yp_all() simply fails if 4540Sstevel@tonic-gate * the map is not present 4550Sstevel@tonic-gate */ 4560Sstevel@tonic-gate my_map = strdup(nsmap); 4570Sstevel@tonic-gate if (my_map == NULL) { 4580Sstevel@tonic-gate syslog(LOG_ERR, 4590Sstevel@tonic-gate "getmapkeys_nis: memory alloc failed: %m"); 4600Sstevel@tonic-gate *error = ENOMEM; 4610Sstevel@tonic-gate return (__NSW_UNAVAIL); 4620Sstevel@tonic-gate } 4630Sstevel@tonic-gate nserr = yp_first(nis_mydomain, my_map, &key, &nkl, &val, &vl); 4640Sstevel@tonic-gate if (nserr == YPERR_MAP) { 4650Sstevel@tonic-gate if (replace_undscr_by_dot(my_map)) { 4660Sstevel@tonic-gate nserr = yp_first(nis_mydomain, my_map, 4670Sstevel@tonic-gate &key, &nkl, &val, &vl); 4680Sstevel@tonic-gate } 4690Sstevel@tonic-gate if (nserr == YPERR_MAP) { 4700Sstevel@tonic-gate /* 4710Sstevel@tonic-gate * map not found 4720Sstevel@tonic-gate */ 4730Sstevel@tonic-gate *error = 0; /* return an empty list */ 4740Sstevel@tonic-gate if (verbose) { 4750Sstevel@tonic-gate syslog(LOG_ERR, "%s: %s", 4760Sstevel@tonic-gate nsmap, yperr_string(nserr)); 4770Sstevel@tonic-gate } 4780Sstevel@tonic-gate free(my_map); 4790Sstevel@tonic-gate return (nis_err(nserr)); 4800Sstevel@tonic-gate } 4810Sstevel@tonic-gate } 482*2170Sevanl if (key) 483*2170Sevanl free(key); 484*2170Sevanl if (val) 485*2170Sevanl free(val); 4860Sstevel@tonic-gate 4870Sstevel@tonic-gate readdir_cbdata.list = list; 4880Sstevel@tonic-gate readdir_cbdata.last = NULL; 4890Sstevel@tonic-gate readdir_cbdata.error = 0; 4900Sstevel@tonic-gate 4910Sstevel@tonic-gate cback.foreach = readdir_callback; 4920Sstevel@tonic-gate cback.data = (char *)&readdir_cbdata; 4930Sstevel@tonic-gate 4940Sstevel@tonic-gate /* 4950Sstevel@tonic-gate * after all this song and dance we finally 4960Sstevel@tonic-gate * ask for the list of entries 4970Sstevel@tonic-gate */ 4980Sstevel@tonic-gate nserr = yp_all(nis_mydomain, my_map, &cback); 4990Sstevel@tonic-gate 5000Sstevel@tonic-gate free(my_map); 5010Sstevel@tonic-gate *error = readdir_cbdata.error; 5020Sstevel@tonic-gate if (nserr) { 5030Sstevel@tonic-gate if (verbose) 5040Sstevel@tonic-gate syslog(LOG_ERR, "%s: %s", nsmap, yperr_string(nserr)); 5050Sstevel@tonic-gate nserr = 1; 5060Sstevel@tonic-gate if (*error == 0) 5070Sstevel@tonic-gate *error = ENOENT; 5080Sstevel@tonic-gate 5090Sstevel@tonic-gate return (nis_err(nserr)); 5100Sstevel@tonic-gate } 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate return (__NSW_SUCCESS); 5130Sstevel@tonic-gate } 5140Sstevel@tonic-gate 5150Sstevel@tonic-gate static int 5160Sstevel@tonic-gate readdir_callback(instatus, inkey, inkeylen, inval, invallen, indata) 5170Sstevel@tonic-gate int instatus; 5180Sstevel@tonic-gate char *inkey; 5190Sstevel@tonic-gate int inkeylen; 5200Sstevel@tonic-gate const char *inval; 5210Sstevel@tonic-gate int invallen; 5220Sstevel@tonic-gate struct dir_cbdata *indata; 5230Sstevel@tonic-gate { 5240Sstevel@tonic-gate struct dir_entry **list = indata->list; 5250Sstevel@tonic-gate struct dir_entry *last = indata->last; 5260Sstevel@tonic-gate char key[MAXPATHLEN]; 5270Sstevel@tonic-gate 5280Sstevel@tonic-gate #ifdef lint 5290Sstevel@tonic-gate inval = inval; 5300Sstevel@tonic-gate invallen = invallen; 5310Sstevel@tonic-gate #endif 5320Sstevel@tonic-gate 5330Sstevel@tonic-gate if (instatus != YP_TRUE) 5340Sstevel@tonic-gate return (0); /* next entry. yp_all may decide otherwise... */ 5350Sstevel@tonic-gate 5360Sstevel@tonic-gate if (inkeylen == 0 || isspace(*inkey) || *inkey == '#') 5370Sstevel@tonic-gate return (0); 5380Sstevel@tonic-gate 5390Sstevel@tonic-gate /* 5400Sstevel@tonic-gate * yp_all allocates inkey with two extra bytes which contain 5410Sstevel@tonic-gate * NEWLINE and null but these two bytes are not reflected in 5420Sstevel@tonic-gate * inkeylen. 5430Sstevel@tonic-gate */ 5440Sstevel@tonic-gate strncpy(key, inkey, inkeylen); 5450Sstevel@tonic-gate key[inkeylen] = '\0'; 5460Sstevel@tonic-gate 5470Sstevel@tonic-gate /* 5480Sstevel@tonic-gate * Wildcard entry should be ignored - following entries should continue 5490Sstevel@tonic-gate * to be read to corroborate with the way we search for entries in yp, 5500Sstevel@tonic-gate * i.e., first for an exact key match and then a wildcard, if there's 5510Sstevel@tonic-gate * no exact key match. 5520Sstevel@tonic-gate */ 5530Sstevel@tonic-gate if (key[0] == '*' && key[1] == '\0') 5540Sstevel@tonic-gate return (0); 5550Sstevel@tonic-gate 5560Sstevel@tonic-gate if (add_dir_entry(key, list, &last)) { 5570Sstevel@tonic-gate indata->error = ENOMEM; 5580Sstevel@tonic-gate return (1); /* get no more entries */ 5590Sstevel@tonic-gate } 5600Sstevel@tonic-gate 5610Sstevel@tonic-gate indata->last = last; 5620Sstevel@tonic-gate indata->error = 0; 5630Sstevel@tonic-gate 5640Sstevel@tonic-gate return (0); 5650Sstevel@tonic-gate } 566