xref: /titanic_41/usr/src/lib/nsswitch/ldap/common/getexecattr.c (revision bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2eb)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <secdb.h>
27 #include <exec_attr.h>
28 #include "ldap_common.h"
29 
30 
31 /* exec_attr attributes filters */
32 #define	ISWILD(x)		(x == NULL) ? "*" : x
33 #define	_EXEC_NAME		"cn"
34 #define	_EXEC_POLICY		"SolarisKernelSecurityPolicy"
35 #define	_EXEC_TYPE		"SolarisProfileType"
36 #define	_EXEC_RES1		"SolarisAttrRes1"
37 #define	_EXEC_RES2		"SolarisAttrRes2"
38 #define	_EXEC_ID		"SolarisProfileId"
39 #define	_EXEC_ATTRS		"SolarisAttrKeyValue"
40 #define	_EXEC_GETEXECNAME	"(&(objectClass=SolarisExecAttr)(cn=%s)"\
41 				"(SolarisKernelSecurityPolicy=%s)"\
42 				"(SolarisProfileType=%s))"
43 #define	_EXEC_GETEXECNAME_SSD	"(&(%%s)(cn=%s)"\
44 				"(SolarisKernelSecurityPolicy=%s)"\
45 				"(SolarisProfileType=%s))"
46 #define	_EXEC_GETEXECID		"(&(objectClass=SolarisExecAttr)"\
47 				"(SolarisProfileId=%s)"\
48 				"(SolarisKernelSecurityPolicy=%s)"\
49 				"(SolarisProfileType=%s))"
50 #define	_EXEC_GETEXECID_SSD	"(&(%%s)"\
51 				"(SolarisProfileId=%s)"\
52 				"(SolarisKernelSecurityPolicy=%s)"\
53 				"(SolarisProfileType=%s))"
54 #define	_EXEC_GETEXECNAMEID	"(&(objectClass=SolarisExecAttr)(cn=%s)"\
55 				"(SolarisProfileId=%s)"\
56 				"(SolarisKernelSecurityPolicy=%s)"\
57 				"(SolarisProfileType=%s))"
58 #define	_EXEC_GETEXECNAMEID_SSD	"(&(%%s)(cn=%s)"\
59 				"(SolarisProfileId=%s)"\
60 				"(SolarisKernelSecurityPolicy=%s)"\
61 				"(SolarisProfileType=%s))"
62 
63 
64 /* from libnsl */
65 extern int _doexeclist(nss_XbyY_args_t *);
66 extern char *_exec_wild_id(char *, const char *);
67 extern void _exec_cleanup(nss_status_t, nss_XbyY_args_t *);
68 
69 
70 static const char *exec_attrs[] = {
71 	_EXEC_NAME,
72 	_EXEC_POLICY,
73 	_EXEC_TYPE,
74 	_EXEC_RES1,
75 	_EXEC_RES2,
76 	_EXEC_ID,
77 	_EXEC_ATTRS,
78 	(char *)NULL
79 };
80 
81 
82 #ifdef	DEBUG
83 static void
84 _print_execstr(execstr_t *exec)
85 {
86 
87 	(void) fprintf(stdout, "      exec-name: [%s]\n", exec->name);
88 	if (exec->policy != (char *)NULL) {
89 		(void) fprintf(stdout, "      policy: [%s]\n", exec->policy);
90 	}
91 	if (exec->type != (char *)NULL) {
92 		(void) fprintf(stdout, "      type: [%s]\n", exec->type);
93 	}
94 	if (exec->res1 != (char *)NULL) {
95 		(void) fprintf(stdout, "      res1: [%s]\n", exec->res1);
96 	}
97 	if (exec->res2 != (char *)NULL) {
98 		(void) fprintf(stdout, "      res2: [%s]\n", exec->res2);
99 	}
100 	if (exec->id != (char *)NULL) {
101 		(void) fprintf(stdout, "      id: [%s]\n", exec->id);
102 	}
103 	if (exec->attr != (char *)NULL) {
104 		(void) fprintf(stdout, "      attr: [%s]\n", exec->attr);
105 	}
106 	if (exec->next != (execstr_t *)NULL) {
107 		(void) fprintf(stdout, "      next: [%s]\n", exec->next->name);
108 		(void) fprintf(stdout, "\n");
109 		_print_execstr(exec->next);
110 	}
111 }
112 #endif	/* DEBUG */
113 
114 
115 static int
116 _exec_ldap_exec2ent(ns_ldap_entry_t *entry, nss_XbyY_args_t *argp)
117 {
118 
119 	int			i;
120 	unsigned long		len = 0L;
121 	int			buflen = (int)0;
122 	char			*nullstring = (char *)NULL;
123 	char			*buffer = (char *)NULL;
124 	char			*ceiling = (char *)NULL;
125 	execstr_t		*exec = (execstr_t *)NULL;
126 	ns_ldap_attr_t		*attrptr;
127 
128 	buffer = argp->buf.buffer;
129 	buflen = (size_t)argp->buf.buflen;
130 	(void) memset(argp->buf.buffer, 0, buflen);
131 	exec = (execstr_t *)(argp->buf.result);
132 	ceiling = buffer + buflen;
133 	exec->name = (char *)NULL;
134 	exec->policy = (char *)NULL;
135 	exec->type = (char *)NULL;
136 	exec->res1 = (char *)NULL;
137 	exec->res2 = (char *)NULL;
138 	exec->id = (char *)NULL;
139 	exec->attr = (char *)NULL;
140 
141 	for (i = 0; i < entry->attr_count; i++) {
142 		attrptr = entry->attr_pair[i];
143 		if (attrptr == NULL) {
144 			return ((int)NSS_STR_PARSE_PARSE);
145 		}
146 		if (strcasecmp(attrptr->attrname, _EXEC_NAME) == 0) {
147 			if ((attrptr->attrvalue[0] == NULL) ||
148 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
149 				return ((int)NSS_STR_PARSE_PARSE);
150 			}
151 			exec->name = buffer;
152 			buffer += len + 1;
153 			if (buffer >= ceiling) {
154 				return ((int)NSS_STR_PARSE_ERANGE);
155 			}
156 			(void) strcpy(exec->name, attrptr->attrvalue[0]);
157 			continue;
158 		}
159 		if (strcasecmp(attrptr->attrname, _EXEC_POLICY) == 0) {
160 			if ((attrptr->attrvalue[0] == NULL) ||
161 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
162 				exec->policy = nullstring;
163 			} else {
164 				exec->policy = buffer;
165 				buffer += len + 1;
166 				if (buffer >= ceiling) {
167 					return ((int)NSS_STR_PARSE_ERANGE);
168 				}
169 				(void) strcpy(exec->policy,
170 				    attrptr->attrvalue[0]);
171 			}
172 			continue;
173 		}
174 		if (strcasecmp(attrptr->attrname, _EXEC_TYPE) == 0) {
175 			if ((attrptr->attrvalue[0] == NULL) ||
176 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
177 				exec->type = nullstring;
178 			} else {
179 				exec->type = buffer;
180 				buffer += len + 1;
181 				if (buffer >= ceiling) {
182 					return ((int)NSS_STR_PARSE_ERANGE);
183 				}
184 				(void) strcpy(exec->type,
185 				    attrptr->attrvalue[0]);
186 			}
187 			continue;
188 		}
189 		if (strcasecmp(attrptr->attrname, _EXEC_RES1) == 0) {
190 			if ((attrptr->attrvalue[0] == NULL) ||
191 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
192 				exec->res1 = nullstring;
193 			} else {
194 				exec->res1 = buffer;
195 				buffer += len + 1;
196 				if (buffer >= ceiling) {
197 					return ((int)NSS_STR_PARSE_ERANGE);
198 				}
199 				(void) strcpy(exec->res1,
200 				    attrptr->attrvalue[0]);
201 			}
202 			continue;
203 		}
204 		if (strcasecmp(attrptr->attrname, _EXEC_RES2) == 0) {
205 			if ((attrptr->attrvalue[0] == NULL) ||
206 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
207 				exec->res2 = nullstring;
208 			} else {
209 				exec->res2 = buffer;
210 				buffer += len + 1;
211 				if (buffer >= ceiling) {
212 					return ((int)NSS_STR_PARSE_ERANGE);
213 				}
214 				(void) strcpy(exec->res2,
215 				    attrptr->attrvalue[0]);
216 			}
217 			continue;
218 		}
219 		if (strcasecmp(attrptr->attrname, _EXEC_ID) == 0) {
220 			if ((attrptr->attrvalue[0] == NULL) ||
221 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
222 				exec->id = nullstring;
223 			} else {
224 				exec->id = buffer;
225 				buffer += len + 1;
226 				if (buffer >= ceiling) {
227 					return ((int)NSS_STR_PARSE_ERANGE);
228 				}
229 				(void) strcpy(exec->id, attrptr->attrvalue[0]);
230 			}
231 			continue;
232 		}
233 		if (strcasecmp(attrptr->attrname, _EXEC_ATTRS) == 0) {
234 			if ((attrptr->attrvalue[0] == NULL) ||
235 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
236 				exec->attr = nullstring;
237 			} else {
238 				exec->attr = buffer;
239 				buffer += len + 1;
240 				if (buffer >= ceiling) {
241 					return ((int)NSS_STR_PARSE_ERANGE);
242 				}
243 				(void) strcpy(exec->attr,
244 				    attrptr->attrvalue[0]);
245 			}
246 			continue;
247 		}
248 	}
249 
250 	exec->next = (execstr_t *)NULL;
251 
252 #ifdef	DEBUG
253 	(void) fprintf(stdout, "\n[getexecattr.c: _exec_ldap_exec2ent]\n");
254 	_print_execstr(exec);
255 #endif	/* DEBUG */
256 
257 	return ((int)NSS_STR_PARSE_SUCCESS);
258 }
259 
260 
261 /*
262  * place the results from ldap object structure into the file format
263  * returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE}
264  */
265 static int
266 _nss_ldap_exec2str(ldap_backend_ptr be, nss_XbyY_args_t *argp)
267 {
268 	int			status = NSS_STR_PARSE_SUCCESS;
269 	ns_ldap_result_t	*result = be->result;
270 	int			len;
271 	char			*buffer, **name, **policy, **type;
272 	char			**res1, **res2, **id, **attr;
273 	char			*policy_str, *type_str, *res1_str, *res2_str;
274 	char			*id_str, *attr_str;
275 
276 	if (result == NULL)
277 		return (NSS_STR_PARSE_PARSE);
278 
279 	(void) memset(argp->buf.buffer, 0, argp->buf.buflen);
280 
281 	name = __ns_ldap_getAttr(result->entry, _EXEC_NAME);
282 	if (name == NULL || name[0] == NULL ||
283 	    (strlen(name[0]) < 1)) {
284 		status = NSS_STR_PARSE_PARSE;
285 		goto result_exec2str;
286 	}
287 
288 	policy = __ns_ldap_getAttr(result->entry, _EXEC_POLICY);
289 
290 	if (policy == NULL || policy[0] == NULL)
291 		policy_str = _NO_VALUE;
292 	else
293 		policy_str = policy[0];
294 
295 	type = __ns_ldap_getAttr(result->entry, _EXEC_TYPE);
296 	if (type == NULL || type[0] == NULL)
297 		type_str = _NO_VALUE;
298 	else
299 		type_str = type[0];
300 
301 	res1 = __ns_ldap_getAttr(result->entry, _EXEC_RES1);
302 	if (res1 == NULL || res1[0] == NULL)
303 		res1_str = _NO_VALUE;
304 	else
305 		res1_str = res1[0];
306 
307 	res2 = __ns_ldap_getAttr(result->entry, _EXEC_RES2);
308 	if (res2 == NULL || res2[0] == NULL)
309 		res2_str = _NO_VALUE;
310 	else
311 		res2_str = res2[0];
312 
313 	id = __ns_ldap_getAttr(result->entry, _EXEC_ID);
314 	if (id == NULL || id[0] == NULL)
315 		id_str = _NO_VALUE;
316 	else
317 		id_str = id[0];
318 
319 	attr = __ns_ldap_getAttr(result->entry, _EXEC_ATTRS);
320 	if (attr == NULL || attr[0] == NULL)
321 		attr_str = _NO_VALUE;
322 	else
323 		attr_str = attr[0];
324 
325 	/* 7 = 6 ':' + 1 '\0' */
326 	len = strlen(name[0]) + strlen(policy_str) + strlen(type_str) +
327 	    strlen(res1_str) + strlen(res2_str) + strlen(id_str) +
328 	    strlen(attr_str) + 7;
329 
330 	if (len > argp->buf.buflen) {
331 		status = NSS_STR_PARSE_ERANGE;
332 		goto  result_exec2str;
333 	}
334 	if (argp->buf.result != NULL) {
335 		if ((be->buffer = calloc(1, len)) == NULL) {
336 			status = NSS_STR_PARSE_PARSE;
337 			goto result_exec2str;
338 		}
339 		buffer = be->buffer;
340 	} else
341 		buffer = argp->buf.buffer;
342 
343 	(void) snprintf(buffer, len, "%s:%s:%s:%s:%s:%s:%s",
344 	    name[0], policy_str, type_str, res1_str,
345 	    res2_str, id_str, attr_str);
346 	/* The front end marshaller does not need the trailing null */
347 	if (argp->buf.result != NULL)
348 		be->buflen = strlen(buffer);
349 result_exec2str:
350 	(void) __ns_ldap_freeResult(&be->result);
351 	return (status);
352 }
353 
354 
355 static nss_status_t
356 _exec_process_val(ldap_backend_ptr be, nss_XbyY_args_t *argp)
357 {
358 	int 			status;
359 	nss_status_t		nss_stat = NSS_UNAVAIL;
360 	ns_ldap_attr_t		*attrptr;
361 	ns_ldap_entry_t		*entry;
362 	ns_ldap_result_t	*result = be->result;
363 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
364 
365 	argp->returnval = NULL;
366 	attrptr = getattr(result, 0);
367 	if (attrptr == NULL) {
368 		(void) __ns_ldap_freeResult(&be->result);
369 		return (nss_stat);
370 	}
371 	for (entry = result->entry; entry != NULL; entry = entry->next) {
372 		status = _exec_ldap_exec2ent(entry, argp);
373 		switch (status) {
374 		case NSS_STR_PARSE_SUCCESS:
375 			argp->returnval = argp->buf.result;
376 			nss_stat = NSS_SUCCESS;
377 			if (IS_GET_ALL(_priv_exec->search_flag)) {
378 				if (_doexeclist(argp) == 0) {
379 					nss_stat = NSS_UNAVAIL;
380 				}
381 			}
382 			break;
383 		case NSS_STR_PARSE_ERANGE:
384 			argp->erange = 1;
385 			nss_stat = NSS_NOTFOUND;
386 			break;
387 		case NSS_STR_PARSE_PARSE:
388 			nss_stat = NSS_NOTFOUND;
389 			break;
390 		default:
391 			nss_stat = NSS_UNAVAIL;
392 			break;
393 		}
394 
395 		if (IS_GET_ONE(_priv_exec->search_flag) ||
396 		    (nss_stat != NSS_SUCCESS)) {
397 			break;
398 		}
399 	}
400 
401 	return (nss_stat);
402 }
403 
404 
405 /*
406  * Check if we have either an exact match or a wild-card entry for that id.
407  */
408 static nss_status_t
409 get_wild(ldap_backend_ptr be, nss_XbyY_args_t *argp, int getby_flag)
410 {
411 	char		*dup_id = NULL;
412 	char		*wild_id;
413 	char		searchfilter[SEARCHFILTERLEN];
414 	char		userdata[SEARCHFILTERLEN];
415 	char		name[SEARCHFILTERLEN];
416 	char		id[SEARCHFILTERLEN];
417 	int		ret;
418 	nss_status_t	nss_stat = NSS_NOTFOUND;
419 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
420 	const char	*policy = _priv_exec->policy;
421 	const char	*type = _priv_exec->type;
422 
423 	if (strpbrk(policy, "*()\\") != NULL ||
424 	    type != NULL && strpbrk(type, "*()\\") != NULL)
425 		return ((nss_status_t)NSS_NOTFOUND);
426 
427 	if (_priv_exec->id != NULL)
428 		dup_id = strdup(_priv_exec->id);
429 
430 	switch (getby_flag) {
431 	case NSS_DBOP_EXECATTR_BYNAMEID:
432 		if (_ldap_filter_name(name, _priv_exec->name,
433 		    sizeof (name)) != 0)
434 			goto go_out;
435 		break;
436 	}
437 
438 	wild_id = dup_id;
439 	do {
440 		if (wild_id != NULL) {
441 			if (_ldap_filter_name(id, wild_id, sizeof (id)) != 0)
442 				goto go_out;
443 		} else
444 			(void) strlcpy(id, "*", sizeof (id));
445 
446 		switch (getby_flag) {
447 		case NSS_DBOP_EXECATTR_BYID:
448 			ret = snprintf(searchfilter, sizeof (searchfilter),
449 			    _EXEC_GETEXECID, id, policy, ISWILD(type));
450 			if (ret >= sizeof (searchfilter) || ret < 0)
451 				goto go_out;
452 			ret = snprintf(userdata, sizeof (userdata),
453 			    _EXEC_GETEXECID_SSD, id, policy, ISWILD(type));
454 			if (ret >= sizeof (userdata) || ret < 0)
455 				goto go_out;
456 			break;
457 
458 		case NSS_DBOP_EXECATTR_BYNAMEID:
459 			ret = snprintf(searchfilter, sizeof (searchfilter),
460 			    _EXEC_GETEXECNAMEID, name, id,
461 			    policy, ISWILD(type));
462 			if (ret >= sizeof (searchfilter) || ret < 0)
463 				goto go_out;
464 			ret = snprintf(userdata, sizeof (userdata),
465 			    _EXEC_GETEXECNAMEID_SSD, name, id,
466 			    policy, ISWILD(type));
467 			if (ret >= sizeof (userdata) || ret < 0)
468 				goto go_out;
469 			break;
470 
471 		default:
472 			goto go_out;
473 		}
474 		nss_stat = _nss_ldap_nocb_lookup(be, argp, _EXECATTR,
475 		    searchfilter, NULL, _merge_SSD_filter, userdata);
476 		if (nss_stat == NSS_SUCCESS)
477 			break;
478 	} while ((wild_id = _exec_wild_id(wild_id, type)) != NULL);
479 
480 go_out:
481 	free(dup_id);
482 
483 	return (nss_stat);
484 }
485 
486 static nss_status_t
487 exec_attr_process_val(ldap_backend_ptr be, nss_XbyY_args_t *argp) {
488 
489 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
490 	int		stat, nss_stat = NSS_SUCCESS;
491 
492 	if (IS_GET_ONE(_priv_exec->search_flag)) {
493 		/* ns_ldap_entry_t -> file format */
494 		stat = (*be->ldapobj2str)(be, argp);
495 
496 		if (stat == NSS_STR_PARSE_SUCCESS) {
497 			if (argp->buf.result != NULL) {
498 				/* file format -> execstr_t */
499 				stat = (*argp->str2ent)(be->buffer,
500 					be->buflen,
501 					argp->buf.result,
502 					argp->buf.buffer,
503 					argp->buf.buflen);
504 				if (stat == NSS_STR_PARSE_SUCCESS) {
505 					argp->returnval = argp->buf.result;
506 					argp->returnlen = 1; /* irrelevant */
507 					nss_stat = NSS_SUCCESS;
508 				} else {
509 					argp->returnval = NULL;
510 					argp->returnlen = 0;
511 					nss_stat = NSS_NOTFOUND;
512 				}
513 			} else {
514 				/* return file format in argp->buf.buffer */
515 				argp->returnval = argp->buf.buffer;
516 				argp->returnlen = strlen(argp->buf.buffer);
517 				nss_stat = NSS_SUCCESS;
518 			}
519 		} else {
520 			argp->returnval = NULL;
521 			argp->returnlen = 0;
522 			nss_stat = NSS_NOTFOUND;
523 		}
524 	} else {
525 		/* GET_ALL */
526 		nss_stat = _exec_process_val(be, argp);
527 		_exec_cleanup(nss_stat, argp);
528 	}
529 
530 	return (nss_stat);
531 
532 }
533 
534 static nss_status_t
535 getbynam(ldap_backend_ptr be, void *a)
536 {
537 	char		searchfilter[SEARCHFILTERLEN];
538 	char		userdata[SEARCHFILTERLEN];
539 	char		name[SEARCHFILTERLEN];
540 	int		ret;
541 	nss_status_t	nss_stat;
542 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
543 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
544 	const char	*policy = _priv_exec->policy;
545 	const char	*type = _priv_exec->type;
546 
547 	if (strpbrk(policy, "*()\\") != NULL ||
548 	    type != NULL && strpbrk(type, "*()\\") != NULL ||
549 	    _ldap_filter_name(name, _priv_exec->name, sizeof (name)) != 0)
550 		return ((nss_status_t)NSS_NOTFOUND);
551 	ret = snprintf(searchfilter, sizeof (searchfilter),
552 	    _EXEC_GETEXECNAME, name, policy, ISWILD(type));
553 	if (ret >= sizeof (searchfilter) || ret < 0)
554 		return ((nss_status_t)NSS_NOTFOUND);
555 	ret = snprintf(userdata, sizeof (userdata),
556 	    _EXEC_GETEXECNAME_SSD, name, policy, ISWILD(type));
557 	if (ret >= sizeof (userdata) || ret < 0)
558 		return ((nss_status_t)NSS_NOTFOUND);
559 
560 	nss_stat = _nss_ldap_nocb_lookup(be, argp, _EXECATTR,
561 	    searchfilter, NULL, _merge_SSD_filter, userdata);
562 
563 	if (nss_stat ==  NSS_SUCCESS)
564 		nss_stat = exec_attr_process_val(be, argp);
565 
566 	return (nss_stat);
567 }
568 
569 static nss_status_t
570 getbyid(ldap_backend_ptr be, void *a)
571 {
572 	nss_status_t	nss_stat = NSS_SUCCESS;
573 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
574 
575 	nss_stat = get_wild(be, argp, NSS_DBOP_EXECATTR_BYID);
576 
577 	if (nss_stat ==  NSS_SUCCESS)
578 		nss_stat = exec_attr_process_val(be, argp);
579 
580 	return (nss_stat);
581 }
582 
583 
584 static nss_status_t
585 getbynameid(ldap_backend_ptr be, void *a)
586 {
587 	nss_status_t	nss_stat;
588 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
589 
590 	nss_stat = get_wild(be, argp, NSS_DBOP_EXECATTR_BYNAMEID);
591 
592 	if (nss_stat ==  NSS_SUCCESS)
593 		nss_stat = exec_attr_process_val(be, argp);
594 
595 	return (nss_stat);
596 }
597 
598 
599 static ldap_backend_op_t execattr_ops[] = {
600 	_nss_ldap_destr,
601 	_nss_ldap_endent,
602 	_nss_ldap_setent,
603 	_nss_ldap_getent,
604 	getbynam,
605 	getbyid,
606 	getbynameid
607 };
608 
609 
610 /*ARGSUSED0*/
611 nss_backend_t *
612 _nss_ldap_exec_attr_constr(const char *dummy1,
613     const char *dummy2,
614     const char *dummy3,
615     const char *dummy4,
616     const char *dummy5,
617     const char *dummy6,
618     const char *dummy7)
619 {
620 #ifdef	DEBUG
621 	(void) fprintf(stdout,
622 	    "\n[getexecattr.c: _nss_ldap_exec_attr_constr]\n");
623 #endif
624 	return ((nss_backend_t *)_nss_ldap_constr(execattr_ops,
625 	    sizeof (execattr_ops)/sizeof (execattr_ops[0]), _EXECATTR,
626 	    exec_attrs, _nss_ldap_exec2str));
627 }
628