1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 1999-2002 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <stdlib.h>
30*0Sstevel@tonic-gate #include <string.h>
31*0Sstevel@tonic-gate #include <sys/types.h>
32*0Sstevel@tonic-gate #include <exec_attr.h>
33*0Sstevel@tonic-gate #include <rpcsvc/ypclnt.h>
34*0Sstevel@tonic-gate #include <rpcsvc/yp_prot.h>
35*0Sstevel@tonic-gate #include "nis_common.h"
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate 
38*0Sstevel@tonic-gate /* extern from nis_common.c */
39*0Sstevel@tonic-gate extern void massage_netdb(const char **, int *);
40*0Sstevel@tonic-gate /* externs from libnsl */
41*0Sstevel@tonic-gate extern int _doexeclist(nss_XbyY_args_t *);
42*0Sstevel@tonic-gate extern char *_exec_wild_id(char *, const char *);
43*0Sstevel@tonic-gate extern void _exec_cleanup(nss_status_t, nss_XbyY_args_t *);
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate typedef struct __exec_nis_args {
47*0Sstevel@tonic-gate 	int		*yp_status;
48*0Sstevel@tonic-gate 	nss_XbyY_args_t	*argp;
49*0Sstevel@tonic-gate } _exec_nis_args;
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate 
52*0Sstevel@tonic-gate /*
53*0Sstevel@tonic-gate  * check_match: returns 1 if -  matching entry found and no more entries needed,
54*0Sstevel@tonic-gate  *				or, entry cannot be found because of error;
55*0Sstevel@tonic-gate  *		returns 0 if -  no matching entry found, or,
56*0Sstevel@tonic-gate  *				matching entry found and next match needed.
57*0Sstevel@tonic-gate  */
58*0Sstevel@tonic-gate static int
59*0Sstevel@tonic-gate check_match(nss_XbyY_args_t *argp, int check_policy)
60*0Sstevel@tonic-gate {
61*0Sstevel@tonic-gate 	execstr_t	*exec = (execstr_t *)(argp->returnval);
62*0Sstevel@tonic-gate 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
63*0Sstevel@tonic-gate 	const char	*name = _priv_exec->name;
64*0Sstevel@tonic-gate 	const char	*type = _priv_exec->type;
65*0Sstevel@tonic-gate 	const char	*id = _priv_exec->id;
66*0Sstevel@tonic-gate 	const char	*policy = _priv_exec->policy;
67*0Sstevel@tonic-gate 
68*0Sstevel@tonic-gate 	if (name && id) {
69*0Sstevel@tonic-gate 		/*
70*0Sstevel@tonic-gate 		 * NSS_DBOP_EXECATTR_BYNAMEID searched for name and id in
71*0Sstevel@tonic-gate 		 * _exec_nis_lookup already.
72*0Sstevel@tonic-gate 		 * If we're talking to pre-Solaris9 nis servers, check policy,
73*0Sstevel@tonic-gate 		 * as policy was not a searchable column then.
74*0Sstevel@tonic-gate 		 */
75*0Sstevel@tonic-gate 		if ((check_policy && policy &&
76*0Sstevel@tonic-gate 		    (strcmp(policy, exec->policy) != 0)) ||
77*0Sstevel@tonic-gate 		    (type && (strcmp(type, exec->type) != 0))) {
78*0Sstevel@tonic-gate 			return (0);
79*0Sstevel@tonic-gate 		}
80*0Sstevel@tonic-gate 	} else if ((policy && exec->policy &&
81*0Sstevel@tonic-gate 	    (strcmp(policy, exec->policy) != 0)) ||
82*0Sstevel@tonic-gate 	    (name && exec->name && (strcmp(name, exec->name) != 0)) ||
83*0Sstevel@tonic-gate 	    (type && exec->type && (strcmp(type, exec->type) != 0)) ||
84*0Sstevel@tonic-gate 	    (id && exec->id && (strcmp(id, exec->id) != 0))) {
85*0Sstevel@tonic-gate 		return (0);
86*0Sstevel@tonic-gate 	}
87*0Sstevel@tonic-gate 
88*0Sstevel@tonic-gate 	return (1);
89*0Sstevel@tonic-gate }
90*0Sstevel@tonic-gate 
91*0Sstevel@tonic-gate 
92*0Sstevel@tonic-gate static  nss_status_t
93*0Sstevel@tonic-gate _exec_nis_parse(const char *instr,
94*0Sstevel@tonic-gate     int instr_len,
95*0Sstevel@tonic-gate     nss_XbyY_args_t *argp,
96*0Sstevel@tonic-gate     int check_policy)
97*0Sstevel@tonic-gate {
98*0Sstevel@tonic-gate 	int		parse_stat;
99*0Sstevel@tonic-gate 	nss_status_t	res;
100*0Sstevel@tonic-gate 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate 	parse_stat = (*argp->str2ent)(instr, instr_len, argp->buf.result,
103*0Sstevel@tonic-gate 	    argp->buf.buffer, argp->buf.buflen);
104*0Sstevel@tonic-gate 	switch (parse_stat) {
105*0Sstevel@tonic-gate 	case NSS_STR_PARSE_SUCCESS:
106*0Sstevel@tonic-gate 		argp->returnval = argp->buf.result;
107*0Sstevel@tonic-gate 		if (check_match(argp, check_policy)) {
108*0Sstevel@tonic-gate 			res = NSS_SUCCESS;
109*0Sstevel@tonic-gate 			if (_priv_exec->search_flag == GET_ALL) {
110*0Sstevel@tonic-gate 				if (_doexeclist(argp) == 0) {
111*0Sstevel@tonic-gate 					res = NSS_UNAVAIL;
112*0Sstevel@tonic-gate 				}
113*0Sstevel@tonic-gate 			}
114*0Sstevel@tonic-gate 		} else {
115*0Sstevel@tonic-gate 			res = NSS_NOTFOUND;
116*0Sstevel@tonic-gate 		}
117*0Sstevel@tonic-gate 		break;
118*0Sstevel@tonic-gate 	case NSS_STR_PARSE_ERANGE:
119*0Sstevel@tonic-gate 		argp->erange = 1;
120*0Sstevel@tonic-gate 		res = NSS_NOTFOUND;
121*0Sstevel@tonic-gate 		break;
122*0Sstevel@tonic-gate 	default:
123*0Sstevel@tonic-gate 		res = NSS_UNAVAIL;
124*0Sstevel@tonic-gate 		break;
125*0Sstevel@tonic-gate 	}
126*0Sstevel@tonic-gate 
127*0Sstevel@tonic-gate 	return (res);
128*0Sstevel@tonic-gate }
129*0Sstevel@tonic-gate 
130*0Sstevel@tonic-gate /*
131*0Sstevel@tonic-gate  * This is the callback for yp_all. It returns 0 to indicate that it wants to
132*0Sstevel@tonic-gate  * be called again for further key-value pairs, or returns non-zero to stop the
133*0Sstevel@tonic-gate  * flow of key-value pairs. If it returns a non-zero value, it is not called
134*0Sstevel@tonic-gate  * again. The functional value of yp_all is then 0.
135*0Sstevel@tonic-gate  */
136*0Sstevel@tonic-gate static int
137*0Sstevel@tonic-gate _exec_nis_cb(int instatus,
138*0Sstevel@tonic-gate     char *inkey,
139*0Sstevel@tonic-gate     int inkeylen,
140*0Sstevel@tonic-gate     char *inval,
141*0Sstevel@tonic-gate     int invallen,
142*0Sstevel@tonic-gate     void *indata)
143*0Sstevel@tonic-gate {
144*0Sstevel@tonic-gate 	int		check_policy = 1; /* always check policy for yp_all */
145*0Sstevel@tonic-gate 	int		stop_cb;
146*0Sstevel@tonic-gate 	const char	*filter;
147*0Sstevel@tonic-gate 	char		*key = NULL;
148*0Sstevel@tonic-gate 	nss_status_t	res;
149*0Sstevel@tonic-gate 	_exec_nis_args	*eargp = (_exec_nis_args *)indata;
150*0Sstevel@tonic-gate 	nss_XbyY_args_t	*argp = eargp->argp;
151*0Sstevel@tonic-gate 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate 	if (instatus != YP_TRUE) {
154*0Sstevel@tonic-gate 		*(eargp->yp_status) = YPERR_YPERR;
155*0Sstevel@tonic-gate 		return (0);	/* yp_all may decide otherwise... */
156*0Sstevel@tonic-gate 	}
157*0Sstevel@tonic-gate 
158*0Sstevel@tonic-gate 	filter = (_priv_exec->name) ? _priv_exec->name : _priv_exec->id;
159*0Sstevel@tonic-gate 
160*0Sstevel@tonic-gate 	/*
161*0Sstevel@tonic-gate 	 * yp_all does not null terminate the entry it retrieves from the
162*0Sstevel@tonic-gate 	 * map, unlike yp_match. so we do it explicitly here.
163*0Sstevel@tonic-gate 	 */
164*0Sstevel@tonic-gate 	inval[invallen] = '\0';
165*0Sstevel@tonic-gate 
166*0Sstevel@tonic-gate 	/*
167*0Sstevel@tonic-gate 	 * Optimization:  if the entry doesn't contain the filter string then
168*0Sstevel@tonic-gate 	 * it can't be the entry we want, so don't bother looking more closely
169*0Sstevel@tonic-gate 	 * at it.
170*0Sstevel@tonic-gate 	 */
171*0Sstevel@tonic-gate 	if ((_priv_exec->policy &&
172*0Sstevel@tonic-gate 	    (strstr(inval, _priv_exec->policy) == NULL)) ||
173*0Sstevel@tonic-gate 	    (strstr(inval, filter) == NULL)) {
174*0Sstevel@tonic-gate 		*(eargp->yp_status) = YPERR_KEY;
175*0Sstevel@tonic-gate 		return (0);
176*0Sstevel@tonic-gate 	}
177*0Sstevel@tonic-gate 
178*0Sstevel@tonic-gate 	res = _exec_nis_parse(inval, invallen, argp, check_policy);
179*0Sstevel@tonic-gate 
180*0Sstevel@tonic-gate 	switch (res) {
181*0Sstevel@tonic-gate 	case NSS_SUCCESS:
182*0Sstevel@tonic-gate 		*(eargp->yp_status) = 0;
183*0Sstevel@tonic-gate 		stop_cb = (_priv_exec->search_flag == GET_ONE);
184*0Sstevel@tonic-gate 		break;
185*0Sstevel@tonic-gate 	case NSS_UNAVAIL:
186*0Sstevel@tonic-gate 		*(eargp->yp_status) = YPERR_KEY;
187*0Sstevel@tonic-gate 		stop_cb = 1;
188*0Sstevel@tonic-gate 		break;
189*0Sstevel@tonic-gate 	default:
190*0Sstevel@tonic-gate 		*(eargp->yp_status) = YPERR_YPERR;
191*0Sstevel@tonic-gate 		stop_cb = 0;
192*0Sstevel@tonic-gate 		break;
193*0Sstevel@tonic-gate 	}
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate 	return (stop_cb);
196*0Sstevel@tonic-gate }
197*0Sstevel@tonic-gate 
198*0Sstevel@tonic-gate static nss_status_t
199*0Sstevel@tonic-gate _exec_nis_lookup(nis_backend_ptr_t be, nss_XbyY_args_t *argp, int getby_flag)
200*0Sstevel@tonic-gate {
201*0Sstevel@tonic-gate 	int		ypstatus;
202*0Sstevel@tonic-gate 	nss_status_t	res = NSS_SUCCESS;
203*0Sstevel@tonic-gate 	nss_status_t	ypres;
204*0Sstevel@tonic-gate 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate 	if (getby_flag == NSS_DBOP_EXECATTR_BYNAMEID) {
207*0Sstevel@tonic-gate 		int		check_policy = 0;
208*0Sstevel@tonic-gate 		int		vallen;
209*0Sstevel@tonic-gate 		int		parse_stat;
210*0Sstevel@tonic-gate 		char		*val;
211*0Sstevel@tonic-gate 		char		key[MAX_INPUT];
212*0Sstevel@tonic-gate 
213*0Sstevel@tonic-gate 		/*
214*0Sstevel@tonic-gate 		 * Try using policy as part of search key. If that fails,
215*0Sstevel@tonic-gate 		 * (it will, in case of pre-Solaris9 nis server where policy
216*0Sstevel@tonic-gate 		 * was not searchable), try again without using policy.
217*0Sstevel@tonic-gate 		 */
218*0Sstevel@tonic-gate 		if (snprintf(key, MAX_INPUT, "%s%s%s%s%s", _priv_exec->name,
219*0Sstevel@tonic-gate 		    KV_TOKEN_DELIMIT, _priv_exec->policy, KV_TOKEN_DELIMIT,
220*0Sstevel@tonic-gate 		    _priv_exec->id) >= MAX_INPUT)
221*0Sstevel@tonic-gate 			return (NSS_NOTFOUND);
222*0Sstevel@tonic-gate 		do {
223*0Sstevel@tonic-gate 			ypres = _nss_nis_ypmatch(be->domain, NIS_MAP_EXECATTR,
224*0Sstevel@tonic-gate 			    key, &val, &vallen, &ypstatus);
225*0Sstevel@tonic-gate 			if ((check_policy == 0) && (ypstatus == YPERR_KEY)) {
226*0Sstevel@tonic-gate 				(void) snprintf(key, MAX_INPUT, "%s%s%s",
227*0Sstevel@tonic-gate 				    _priv_exec->name, KV_TOKEN_DELIMIT,
228*0Sstevel@tonic-gate 				    _priv_exec->id);
229*0Sstevel@tonic-gate 				check_policy = 1;
230*0Sstevel@tonic-gate 				continue;
231*0Sstevel@tonic-gate 			} else if (ypres != NSS_SUCCESS) {
232*0Sstevel@tonic-gate 				res = ypres;
233*0Sstevel@tonic-gate 				break;
234*0Sstevel@tonic-gate 			} else {
235*0Sstevel@tonic-gate 				massage_netdb((const char **)&val, &vallen);
236*0Sstevel@tonic-gate 				res = _exec_nis_parse((const char *)val,
237*0Sstevel@tonic-gate 				    vallen, argp, check_policy);
238*0Sstevel@tonic-gate 				break;
239*0Sstevel@tonic-gate 			}
240*0Sstevel@tonic-gate 		} while (res == NSS_SUCCESS);
241*0Sstevel@tonic-gate 	} else {
242*0Sstevel@tonic-gate 		int			ypstat = YPERR_YPERR;
243*0Sstevel@tonic-gate 		struct ypall_callback	cback;
244*0Sstevel@tonic-gate 		_exec_nis_args		eargs;
245*0Sstevel@tonic-gate 
246*0Sstevel@tonic-gate 		eargs.yp_status = &ypstat;
247*0Sstevel@tonic-gate 		eargs.argp = argp;
248*0Sstevel@tonic-gate 
249*0Sstevel@tonic-gate 		cback.foreach = _exec_nis_cb;
250*0Sstevel@tonic-gate 		cback.data = (void *)&eargs;
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate 		/*
253*0Sstevel@tonic-gate 		 * Instead of calling yp_all() doing hard lookup, we use
254*0Sstevel@tonic-gate 		 * the alternative function, __yp_all_cflookup(), to
255*0Sstevel@tonic-gate 		 * perform soft lookup when binding to nis servers with
256*0Sstevel@tonic-gate 		 * time-out control. Other than that, these two functions
257*0Sstevel@tonic-gate 		 * do exactly the same thing.
258*0Sstevel@tonic-gate 		 */
259*0Sstevel@tonic-gate 		ypstatus = __yp_all_cflookup((char *)(be->domain),
260*0Sstevel@tonic-gate 			(char *)(be->enum_map), &cback, 0);
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate 		/*
263*0Sstevel@tonic-gate 		 * For GET_ALL, check if we found anything at all.
264*0Sstevel@tonic-gate 		 */
265*0Sstevel@tonic-gate 		if (_priv_exec->head_exec != NULL)
266*0Sstevel@tonic-gate 			return (NSS_SUCCESS);
267*0Sstevel@tonic-gate 
268*0Sstevel@tonic-gate 		switch (ypstat) {
269*0Sstevel@tonic-gate 		case 0:
270*0Sstevel@tonic-gate 			res = NSS_SUCCESS;
271*0Sstevel@tonic-gate 			break;
272*0Sstevel@tonic-gate 		case YPERR_BUSY:
273*0Sstevel@tonic-gate 			res = NSS_TRYAGAIN;
274*0Sstevel@tonic-gate 			break;
275*0Sstevel@tonic-gate 		default:
276*0Sstevel@tonic-gate 			res = NSS_UNAVAIL;
277*0Sstevel@tonic-gate 			break;
278*0Sstevel@tonic-gate 		}
279*0Sstevel@tonic-gate 
280*0Sstevel@tonic-gate 	}
281*0Sstevel@tonic-gate 
282*0Sstevel@tonic-gate 	return (res);
283*0Sstevel@tonic-gate }
284*0Sstevel@tonic-gate 
285*0Sstevel@tonic-gate /*
286*0Sstevel@tonic-gate  * If search for exact match for id failed, get_wild checks if we have
287*0Sstevel@tonic-gate  * a wild-card entry for that id.
288*0Sstevel@tonic-gate  */
289*0Sstevel@tonic-gate static  nss_status_t
290*0Sstevel@tonic-gate get_wild(nis_backend_ptr_t be, nss_XbyY_args_t *argp, int getby_flag)
291*0Sstevel@tonic-gate {
292*0Sstevel@tonic-gate 	char		*orig_id = NULL;
293*0Sstevel@tonic-gate 	char		*old_id = NULL;
294*0Sstevel@tonic-gate 	char		*wild_id = NULL;
295*0Sstevel@tonic-gate 	nss_status_t	res = NSS_NOTFOUND;
296*0Sstevel@tonic-gate 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
297*0Sstevel@tonic-gate 
298*0Sstevel@tonic-gate 	orig_id = strdup(_priv_exec->id);
299*0Sstevel@tonic-gate 	old_id = strdup(_priv_exec->id);
300*0Sstevel@tonic-gate 	wild_id = old_id;
301*0Sstevel@tonic-gate 	while ((wild_id = _exec_wild_id(wild_id, _priv_exec->type)) != NULL) {
302*0Sstevel@tonic-gate 		_priv_exec->id = wild_id;
303*0Sstevel@tonic-gate 		res = _exec_nis_lookup(be, argp, getby_flag);
304*0Sstevel@tonic-gate 		if (res == NSS_SUCCESS)
305*0Sstevel@tonic-gate 			break;
306*0Sstevel@tonic-gate 	}
307*0Sstevel@tonic-gate 	_priv_exec->id = orig_id;
308*0Sstevel@tonic-gate 	if (old_id)
309*0Sstevel@tonic-gate 		free(old_id);
310*0Sstevel@tonic-gate 
311*0Sstevel@tonic-gate 	return (res);
312*0Sstevel@tonic-gate }
313*0Sstevel@tonic-gate 
314*0Sstevel@tonic-gate 
315*0Sstevel@tonic-gate static  nss_status_t
316*0Sstevel@tonic-gate getbynam(nis_backend_ptr_t be, void *a)
317*0Sstevel@tonic-gate {
318*0Sstevel@tonic-gate 	nss_status_t	res;
319*0Sstevel@tonic-gate 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
320*0Sstevel@tonic-gate 
321*0Sstevel@tonic-gate 	res = _exec_nis_lookup(be, argp, NSS_DBOP_EXECATTR_BYNAME);
322*0Sstevel@tonic-gate 
323*0Sstevel@tonic-gate 	_exec_cleanup(res, argp);
324*0Sstevel@tonic-gate 
325*0Sstevel@tonic-gate 	return (res);
326*0Sstevel@tonic-gate }
327*0Sstevel@tonic-gate 
328*0Sstevel@tonic-gate static  nss_status_t
329*0Sstevel@tonic-gate getbyid(nis_backend_ptr_t be, void *a)
330*0Sstevel@tonic-gate {
331*0Sstevel@tonic-gate 	nss_status_t	res;
332*0Sstevel@tonic-gate 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
333*0Sstevel@tonic-gate 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
334*0Sstevel@tonic-gate 
335*0Sstevel@tonic-gate 	res = _exec_nis_lookup(be, argp, NSS_DBOP_EXECATTR_BYID);
336*0Sstevel@tonic-gate 
337*0Sstevel@tonic-gate 	if (res != NSS_SUCCESS)
338*0Sstevel@tonic-gate 		res = get_wild(be, argp, NSS_DBOP_EXECATTR_BYID);
339*0Sstevel@tonic-gate 
340*0Sstevel@tonic-gate 	_exec_cleanup(res, argp);
341*0Sstevel@tonic-gate 
342*0Sstevel@tonic-gate 	return (res);
343*0Sstevel@tonic-gate }
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate 
346*0Sstevel@tonic-gate static  nss_status_t
347*0Sstevel@tonic-gate getbynameid(nis_backend_ptr_t be, void *a)
348*0Sstevel@tonic-gate {
349*0Sstevel@tonic-gate 	nss_status_t	res;
350*0Sstevel@tonic-gate 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
351*0Sstevel@tonic-gate 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
352*0Sstevel@tonic-gate 
353*0Sstevel@tonic-gate 	res = _exec_nis_lookup(be, argp, NSS_DBOP_EXECATTR_BYNAMEID);
354*0Sstevel@tonic-gate 
355*0Sstevel@tonic-gate 	if (res != NSS_SUCCESS)
356*0Sstevel@tonic-gate 		res = get_wild(be, argp, NSS_DBOP_EXECATTR_BYNAMEID);
357*0Sstevel@tonic-gate 
358*0Sstevel@tonic-gate 	_exec_cleanup(res, argp);
359*0Sstevel@tonic-gate 
360*0Sstevel@tonic-gate 	return (res);
361*0Sstevel@tonic-gate }
362*0Sstevel@tonic-gate 
363*0Sstevel@tonic-gate 
364*0Sstevel@tonic-gate static nis_backend_op_t execattr_ops[] = {
365*0Sstevel@tonic-gate 	_nss_nis_destr,
366*0Sstevel@tonic-gate 	_nss_nis_endent,
367*0Sstevel@tonic-gate 	_nss_nis_setent,
368*0Sstevel@tonic-gate 	_nss_nis_getent_netdb,
369*0Sstevel@tonic-gate 	getbynam,
370*0Sstevel@tonic-gate 	getbyid,
371*0Sstevel@tonic-gate 	getbynameid
372*0Sstevel@tonic-gate };
373*0Sstevel@tonic-gate 
374*0Sstevel@tonic-gate nss_backend_t *
375*0Sstevel@tonic-gate _nss_nis_exec_attr_constr(const char *dummy1,
376*0Sstevel@tonic-gate     const char *dummy2,
377*0Sstevel@tonic-gate     const char *dummy3,
378*0Sstevel@tonic-gate     const char *dummy4,
379*0Sstevel@tonic-gate     const char *dummy5,
380*0Sstevel@tonic-gate     const char *dummy6,
381*0Sstevel@tonic-gate     const char *dummy7)
382*0Sstevel@tonic-gate {
383*0Sstevel@tonic-gate 	return (_nss_nis_constr(execattr_ops,
384*0Sstevel@tonic-gate 		sizeof (execattr_ops)/sizeof (execattr_ops[0]),
385*0Sstevel@tonic-gate 		NIS_MAP_EXECATTR));
386*0Sstevel@tonic-gate }
387