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  */
217c478bd9Sstevel@tonic-gate /*
2201ef659dSJoep Vesseur  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
25d00075c7SMarcel Telka /*
26d00075c7SMarcel Telka  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
27d00075c7SMarcel Telka  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include "mt.h"
307c478bd9Sstevel@tonic-gate #include <stdio.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <nss_dbdefs.h>
347c478bd9Sstevel@tonic-gate #include <string.h>
357c478bd9Sstevel@tonic-gate #include <strings.h>
367c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
377c478bd9Sstevel@tonic-gate #include <thread.h>
387c478bd9Sstevel@tonic-gate #include <synch.h>
397c478bd9Sstevel@tonic-gate #include <nsswitch.h>
407c478bd9Sstevel@tonic-gate #include <prof_attr.h>
417c478bd9Sstevel@tonic-gate #include <exec_attr.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate /* externs from libc */
447c478bd9Sstevel@tonic-gate extern void _nss_db_state_destr(struct nss_db_state *);
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate /* externs from parse.c */
477c478bd9Sstevel@tonic-gate extern char *_strtok_escape(char *, char *, char **);
487c478bd9Sstevel@tonic-gate extern char *_strdup_null(char *);
497c478bd9Sstevel@tonic-gate /* extern from getprofattr.c */
507c478bd9Sstevel@tonic-gate extern int str2profattr(const char *, int, void *, char *, int);
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate char *_exec_wild_id(char *, const char *);
537c478bd9Sstevel@tonic-gate execstr_t *_dup_execstr(execstr_t *);
547c478bd9Sstevel@tonic-gate void _free_execstr(execstr_t *);
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate static char *_nsw_search_path = NULL;
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate /*
597c478bd9Sstevel@tonic-gate  * Unsynchronized, but it affects only efficiency, not correctness
607c478bd9Sstevel@tonic-gate  */
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate static DEFINE_NSS_DB_ROOT(exec_root);
637c478bd9Sstevel@tonic-gate static DEFINE_NSS_GETENT(context);
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate void
_nss_initf_execattr(nss_db_params_t * p)667c478bd9Sstevel@tonic-gate _nss_initf_execattr(nss_db_params_t *p)
677c478bd9Sstevel@tonic-gate {
687c478bd9Sstevel@tonic-gate 	p->name = NSS_DBNAM_EXECATTR;
697c478bd9Sstevel@tonic-gate 	p->config_name    = NSS_DBNAM_PROFATTR; /* use config for "prof_attr" */
707c478bd9Sstevel@tonic-gate }
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate void
_nsw_initf_execattr(nss_db_params_t * p)737c478bd9Sstevel@tonic-gate _nsw_initf_execattr(nss_db_params_t *p)
747c478bd9Sstevel@tonic-gate {
757c478bd9Sstevel@tonic-gate 	p->name = NSS_DBNAM_EXECATTR;
767c478bd9Sstevel@tonic-gate 	p->flags |= NSS_USE_DEFAULT_CONFIG;
777c478bd9Sstevel@tonic-gate 	p->default_config = _nsw_search_path;
787c478bd9Sstevel@tonic-gate }
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate void
_nsw_initf_profattr(nss_db_params_t * p)817c478bd9Sstevel@tonic-gate _nsw_initf_profattr(nss_db_params_t *p)
827c478bd9Sstevel@tonic-gate {
837c478bd9Sstevel@tonic-gate 	p->name = NSS_DBNAM_PROFATTR;
847c478bd9Sstevel@tonic-gate 	p->flags |= NSS_USE_DEFAULT_CONFIG;
857c478bd9Sstevel@tonic-gate 	p->default_config = _nsw_search_path;
867c478bd9Sstevel@tonic-gate }
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate /*
897c478bd9Sstevel@tonic-gate  * Return values: 0 = success, 1 = parse error, 2 = erange ... The structure
907c478bd9Sstevel@tonic-gate  * pointer passed in is a structure in the caller's space wherein the field
917c478bd9Sstevel@tonic-gate  * pointers would be set to areas in the buffer if need be. instring and buffer
927c478bd9Sstevel@tonic-gate  * should be separate areas.
937c478bd9Sstevel@tonic-gate  */
947c478bd9Sstevel@tonic-gate int
str2execattr(const char * instr,int lenstr,void * ent,char * buffer,int buflen)957c478bd9Sstevel@tonic-gate str2execattr(const char *instr, int lenstr, void *ent, char *buffer, int buflen)
967c478bd9Sstevel@tonic-gate {
9761961e0fSrobinson 	char		*last = NULL;
987c478bd9Sstevel@tonic-gate 	char		*sep = KV_TOKEN_DELIMIT;
997c478bd9Sstevel@tonic-gate 	execstr_t	*exec = (execstr_t *)ent;
1007c478bd9Sstevel@tonic-gate 
10161961e0fSrobinson 	if (lenstr >= buflen)
1027c478bd9Sstevel@tonic-gate 		return (NSS_STR_PARSE_ERANGE);
103cb5caa98Sdjl 
104cb5caa98Sdjl 	if (instr != buffer)
105cb5caa98Sdjl 		(void) strncpy(buffer, instr, buflen);
106cb5caa98Sdjl 
1077c478bd9Sstevel@tonic-gate 	/*
1087c478bd9Sstevel@tonic-gate 	 * Remove newline that nis (yp_match) puts at the
1097c478bd9Sstevel@tonic-gate 	 * end of the entry it retrieves from the map.
1107c478bd9Sstevel@tonic-gate 	 */
1117c478bd9Sstevel@tonic-gate 	if (buffer[lenstr] == '\n') {
1127c478bd9Sstevel@tonic-gate 		buffer[lenstr] = '\0';
1137c478bd9Sstevel@tonic-gate 	}
1147c478bd9Sstevel@tonic-gate 
115cb5caa98Sdjl 	/* quick exit do not entry fill if not needed */
116cb5caa98Sdjl 	if (ent == (void *)NULL)
117cb5caa98Sdjl 		return (NSS_STR_PARSE_SUCCESS);
118cb5caa98Sdjl 
1197c478bd9Sstevel@tonic-gate 	exec->name = _strtok_escape(buffer, sep, &last);
1207c478bd9Sstevel@tonic-gate 	exec->policy = _strtok_escape(NULL, sep, &last);
1217c478bd9Sstevel@tonic-gate 	exec->type = _strtok_escape(NULL, sep, &last);
1227c478bd9Sstevel@tonic-gate 	exec->res1 = _strtok_escape(NULL, sep, &last);
1237c478bd9Sstevel@tonic-gate 	exec->res2 = _strtok_escape(NULL, sep, &last);
1247c478bd9Sstevel@tonic-gate 	exec->id = _strtok_escape(NULL, sep, &last);
1257c478bd9Sstevel@tonic-gate 	exec->attr = _strtok_escape(NULL, sep, &last);
12661961e0fSrobinson 	exec->next = NULL;
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 	return (NSS_STR_PARSE_SUCCESS);
1297c478bd9Sstevel@tonic-gate }
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate void
_setexecattr(void)1337c478bd9Sstevel@tonic-gate _setexecattr(void)
1347c478bd9Sstevel@tonic-gate {
1357c478bd9Sstevel@tonic-gate 	nss_setent(&exec_root, _nss_initf_execattr, &context);
1367c478bd9Sstevel@tonic-gate }
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate void
_endexecattr(void)1407c478bd9Sstevel@tonic-gate _endexecattr(void)
1417c478bd9Sstevel@tonic-gate {
1427c478bd9Sstevel@tonic-gate 	nss_endent(&exec_root, _nss_initf_execattr, &context);
1437c478bd9Sstevel@tonic-gate 	nss_delete(&exec_root);
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate execstr_t *
_getexecattr(execstr_t * result,char * buffer,int buflen,int * errnop)1487c478bd9Sstevel@tonic-gate _getexecattr(execstr_t *result, char *buffer, int buflen, int *errnop)
1497c478bd9Sstevel@tonic-gate {
1507c478bd9Sstevel@tonic-gate 	nss_status_t    res;
1517c478bd9Sstevel@tonic-gate 	nss_XbyY_args_t arg;
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	NSS_XbyY_INIT(&arg, result, buffer, buflen, str2execattr);
1547c478bd9Sstevel@tonic-gate 	res = nss_getent(&exec_root, _nss_initf_execattr, &context, &arg);
1557c478bd9Sstevel@tonic-gate 	arg.status = res;
1567c478bd9Sstevel@tonic-gate 	*errnop = arg.h_errno;
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	return ((execstr_t *)NSS_XbyY_FINI(&arg));
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate execstr_t *
_getexecprof(char * name,char * type,char * id,int search_flag,execstr_t * result,char * buffer,int buflen,int * errnop)1627c478bd9Sstevel@tonic-gate _getexecprof(char *name,
1637c478bd9Sstevel@tonic-gate     char *type,
1647c478bd9Sstevel@tonic-gate     char *id,
1657c478bd9Sstevel@tonic-gate     int search_flag,
1667c478bd9Sstevel@tonic-gate     execstr_t *result,
1677c478bd9Sstevel@tonic-gate     char *buffer,
1687c478bd9Sstevel@tonic-gate     int buflen,
1697c478bd9Sstevel@tonic-gate     int *errnop)
1707c478bd9Sstevel@tonic-gate {
1717c478bd9Sstevel@tonic-gate 	int		getby_flag;
1727c478bd9Sstevel@tonic-gate 	char		policy_buf[BUFSIZ];
1737c478bd9Sstevel@tonic-gate 	nss_status_t	res = NSS_NOTFOUND;
1747c478bd9Sstevel@tonic-gate 	nss_XbyY_args_t	arg;
1757c478bd9Sstevel@tonic-gate 	_priv_execattr	_priv_exec;
1767c478bd9Sstevel@tonic-gate 	static mutex_t	_nsw_exec_lock = DEFAULTMUTEX;
1777c478bd9Sstevel@tonic-gate 
178d00075c7SMarcel Telka 	if ((name != NULL) && (id != NULL)) {
179d00075c7SMarcel Telka 		getby_flag = NSS_DBOP_EXECATTR_BYNAMEID;
180d00075c7SMarcel Telka 	} else if (name != NULL) {
181d00075c7SMarcel Telka 		getby_flag = NSS_DBOP_EXECATTR_BYNAME;
182d00075c7SMarcel Telka 	} else if (id != NULL) {
183d00075c7SMarcel Telka 		getby_flag = NSS_DBOP_EXECATTR_BYID;
184d00075c7SMarcel Telka 	} else {
185d00075c7SMarcel Telka 		return (NULL);
186d00075c7SMarcel Telka 	}
187d00075c7SMarcel Telka 
1887c478bd9Sstevel@tonic-gate 	NSS_XbyY_INIT(&arg, result, buffer, buflen, str2execattr);
1897c478bd9Sstevel@tonic-gate 
190d00075c7SMarcel Telka 	_priv_exec.name = name;
191d00075c7SMarcel Telka 	_priv_exec.type = type;
192d00075c7SMarcel Telka 	_priv_exec.id = id;
1937c478bd9Sstevel@tonic-gate #ifdef SI_SECPOLICY
1947c478bd9Sstevel@tonic-gate 	if (sysinfo(SI_SECPOLICY, policy_buf, BUFSIZ) == -1)
1957c478bd9Sstevel@tonic-gate #endif	/* SI_SECPOLICY */
19661961e0fSrobinson 	(void) strncpy(policy_buf, DEFAULT_POLICY, BUFSIZ);
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate retry_policy:
199d00075c7SMarcel Telka 	_priv_exec.policy = IS_SEARCH_ALL(search_flag) ? NULL : policy_buf;
2007c478bd9Sstevel@tonic-gate 	_priv_exec.search_flag = search_flag;
20161961e0fSrobinson 	_priv_exec.head_exec = NULL;
20261961e0fSrobinson 	_priv_exec.prev_exec = NULL;
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 	arg.key.attrp = &(_priv_exec);
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	switch (getby_flag) {
2077c478bd9Sstevel@tonic-gate 	case NSS_DBOP_EXECATTR_BYID:
2087c478bd9Sstevel@tonic-gate 		res = nss_search(&exec_root, _nss_initf_execattr, getby_flag,
2097c478bd9Sstevel@tonic-gate 		    &arg);
2107c478bd9Sstevel@tonic-gate 		break;
2117c478bd9Sstevel@tonic-gate 	case NSS_DBOP_EXECATTR_BYNAMEID:
2127c478bd9Sstevel@tonic-gate 	case NSS_DBOP_EXECATTR_BYNAME:
2137c478bd9Sstevel@tonic-gate 		{
2147c478bd9Sstevel@tonic-gate 			char			pbuf[NSS_BUFLEN_PROFATTR];
2157c478bd9Sstevel@tonic-gate 			profstr_t		prof;
2167c478bd9Sstevel@tonic-gate 			nss_status_t		pres;
2177c478bd9Sstevel@tonic-gate 			nss_XbyY_args_t		parg;
2187c478bd9Sstevel@tonic-gate 			enum __nsw_parse_err	pserr;
2197c478bd9Sstevel@tonic-gate 			struct __nsw_lookup	*lookups = NULL;
2207c478bd9Sstevel@tonic-gate 			struct __nsw_switchconfig *conf = NULL;
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 			if (conf = __nsw_getconfig(NSS_DBNAM_PROFATTR, &pserr))
2237c478bd9Sstevel@tonic-gate 				if ((lookups = conf->lookups) == NULL)
2247c478bd9Sstevel@tonic-gate 					goto out;
2257c478bd9Sstevel@tonic-gate 			NSS_XbyY_INIT(&parg, &prof, pbuf, NSS_BUFLEN_PROFATTR,
2267c478bd9Sstevel@tonic-gate 			    str2profattr);
2277c478bd9Sstevel@tonic-gate 			parg.key.name = name;
2287c478bd9Sstevel@tonic-gate 			do {
2297c478bd9Sstevel@tonic-gate 				/*
2307c478bd9Sstevel@tonic-gate 				 * search the exec_attr entry only in the scope
2317c478bd9Sstevel@tonic-gate 				 * that we find the profile in.
2327c478bd9Sstevel@tonic-gate 				 * if conf = NULL, search in local files only,
2337c478bd9Sstevel@tonic-gate 				 * as we were not able to read nsswitch.conf.
2347c478bd9Sstevel@tonic-gate 				 */
2357c478bd9Sstevel@tonic-gate 				DEFINE_NSS_DB_ROOT(prof_root);
2367c478bd9Sstevel@tonic-gate 				if (mutex_lock(&_nsw_exec_lock) != 0)
2377c478bd9Sstevel@tonic-gate 					goto out;
2387c478bd9Sstevel@tonic-gate 				_nsw_search_path = (conf == NULL)
2397c478bd9Sstevel@tonic-gate 				    ? NSS_FILES_ONLY
2407c478bd9Sstevel@tonic-gate 				    : lookups->service_name;
2417c478bd9Sstevel@tonic-gate 				pres = nss_search(&prof_root,
2427c478bd9Sstevel@tonic-gate 				    _nsw_initf_profattr,
2437c478bd9Sstevel@tonic-gate 				    NSS_DBOP_PROFATTR_BYNAME, &parg);
2447c478bd9Sstevel@tonic-gate 				if (pres == NSS_SUCCESS) {
2457c478bd9Sstevel@tonic-gate 					DEFINE_NSS_DB_ROOT(pexec_root);
2467c478bd9Sstevel@tonic-gate 					res = nss_search(&pexec_root,
2477c478bd9Sstevel@tonic-gate 					    _nsw_initf_execattr, getby_flag,
2487c478bd9Sstevel@tonic-gate 					    &arg);
249cb5caa98Sdjl 					if (pexec_root.s != NULL)
250cb5caa98Sdjl 						_nss_db_state_destr(
25101ef659dSJoep Vesseur 						    pexec_root.s);
2527c478bd9Sstevel@tonic-gate 				}
253cb5caa98Sdjl 				if (prof_root.s != NULL)
254cb5caa98Sdjl 					_nss_db_state_destr(prof_root.s);
2557c478bd9Sstevel@tonic-gate 				(void) mutex_unlock(&_nsw_exec_lock);
2567c478bd9Sstevel@tonic-gate 				if ((pres == NSS_SUCCESS) || (conf == NULL))
2577c478bd9Sstevel@tonic-gate 					break;
2587c478bd9Sstevel@tonic-gate 			} while (lookups && (lookups = lookups->next));
2597c478bd9Sstevel@tonic-gate 		}
2607c478bd9Sstevel@tonic-gate 		break;
2617c478bd9Sstevel@tonic-gate 	default:
2627c478bd9Sstevel@tonic-gate 		break;
2637c478bd9Sstevel@tonic-gate 	}
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate out:
2667c478bd9Sstevel@tonic-gate 	/*
2677c478bd9Sstevel@tonic-gate 	 * If we can't find an entry for the current default policy
2687c478bd9Sstevel@tonic-gate 	 * fall back to the old "suser" policy.  The nameservice is
2697c478bd9Sstevel@tonic-gate 	 * shared between different OS releases.
2707c478bd9Sstevel@tonic-gate 	 */
27101ef659dSJoep Vesseur 	if (!IS_SEARCH_ALL(search_flag) &&
27201ef659dSJoep Vesseur 	    (res == NSS_NOTFOUND && strcmp(policy_buf, DEFAULT_POLICY) == 0)) {
2737c478bd9Sstevel@tonic-gate 		(void) strlcpy(policy_buf, SUSER_POLICY, BUFSIZ);
2747c478bd9Sstevel@tonic-gate 		goto retry_policy;
2757c478bd9Sstevel@tonic-gate 	}
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate 	arg.status = res;
2787c478bd9Sstevel@tonic-gate 	*errnop = res;
2797c478bd9Sstevel@tonic-gate 	return ((execstr_t *)NSS_XbyY_FINI(&arg));
2807c478bd9Sstevel@tonic-gate }
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate int
_doexeclist(nss_XbyY_args_t * argp)2847c478bd9Sstevel@tonic-gate _doexeclist(nss_XbyY_args_t *argp)
2857c478bd9Sstevel@tonic-gate {
2867c478bd9Sstevel@tonic-gate 	int		status = 1;
2877c478bd9Sstevel@tonic-gate 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
2887c478bd9Sstevel@tonic-gate 	execstr_t	*exec = (execstr_t *)((argp->buf.result));
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 	if (_priv_exec->head_exec == NULL) {
2917c478bd9Sstevel@tonic-gate 		if (_priv_exec->head_exec = _dup_execstr(exec))
2927c478bd9Sstevel@tonic-gate 			_priv_exec->prev_exec = _priv_exec->head_exec;
2937c478bd9Sstevel@tonic-gate 		else
2947c478bd9Sstevel@tonic-gate 			status = 0;
2957c478bd9Sstevel@tonic-gate 	} else {
2967c478bd9Sstevel@tonic-gate 		if (_priv_exec->prev_exec->next = _dup_execstr(exec))
2977c478bd9Sstevel@tonic-gate 			_priv_exec->prev_exec = _priv_exec->prev_exec->next;
2987c478bd9Sstevel@tonic-gate 		else
2997c478bd9Sstevel@tonic-gate 			status = 0;
3007c478bd9Sstevel@tonic-gate 	}
301*344db6f4SToomas Soome 	(void) memset(argp->buf.buffer, 0, argp->buf.buflen);
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	return (status);
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate /*
3097c478bd9Sstevel@tonic-gate  * Converts id to a wildcard string. e.g.:
3107c478bd9Sstevel@tonic-gate  *   For type = KV_COMMAND: /usr/ccs/bin/what ---> /usr/ccs/bin/\* ---> \*
3117c478bd9Sstevel@tonic-gate  *   For type = KV_ACTION: Dtfile;*;*;*;0 ---> *;*;*;*;*
3127c478bd9Sstevel@tonic-gate  *
3137c478bd9Sstevel@tonic-gate  * Returns NULL if id is already a wild-card.
3147c478bd9Sstevel@tonic-gate  */
3157c478bd9Sstevel@tonic-gate char *
_exec_wild_id(char * id,const char * type)3167c478bd9Sstevel@tonic-gate _exec_wild_id(char *id, const char *type)
3177c478bd9Sstevel@tonic-gate {
3187c478bd9Sstevel@tonic-gate 	char	c_id = '/';
3197c478bd9Sstevel@tonic-gate 	char	*pchar = NULL;
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	if ((id == NULL) || (type == NULL))
3227c478bd9Sstevel@tonic-gate 		return (NULL);
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate 	if (strcmp(type, KV_ACTION) == 0) {
3257c478bd9Sstevel@tonic-gate 		return ((strcmp(id, KV_ACTION_WILDCARD) == 0) ? NULL :
3267c478bd9Sstevel@tonic-gate 		    KV_ACTION_WILDCARD);
3277c478bd9Sstevel@tonic-gate 	} else if (strcmp(type, KV_COMMAND) == 0) {
3287c478bd9Sstevel@tonic-gate 		if ((pchar = rindex(id, c_id)) == NULL)
3297c478bd9Sstevel@tonic-gate 			/*
3307c478bd9Sstevel@tonic-gate 			 * id = \*
3317c478bd9Sstevel@tonic-gate 			 */
3327c478bd9Sstevel@tonic-gate 			return (NULL);
3337c478bd9Sstevel@tonic-gate 		else if (*(++pchar) == KV_WILDCHAR)
3347c478bd9Sstevel@tonic-gate 			/*
3357c478bd9Sstevel@tonic-gate 			 * id = /usr/ccs/bin/\*
3367c478bd9Sstevel@tonic-gate 			 */
3377c478bd9Sstevel@tonic-gate 			return (pchar);
3387c478bd9Sstevel@tonic-gate 		/*
3397c478bd9Sstevel@tonic-gate 		 * id = /usr/ccs/bin/what
3407c478bd9Sstevel@tonic-gate 		 */
34161961e0fSrobinson 		(void) strcpy(pchar, KV_WILDCARD);
3427c478bd9Sstevel@tonic-gate 		return (id);
3437c478bd9Sstevel@tonic-gate 	}
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 	return (NULL);
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate }
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate execstr_t *
_dup_execstr(execstr_t * old_exec)3517c478bd9Sstevel@tonic-gate _dup_execstr(execstr_t *old_exec)
3527c478bd9Sstevel@tonic-gate {
35361961e0fSrobinson 	execstr_t *new_exec = NULL;
3547c478bd9Sstevel@tonic-gate 
35561961e0fSrobinson 	if (old_exec == NULL)
35661961e0fSrobinson 		return (NULL);
35761961e0fSrobinson 	if ((new_exec = malloc(sizeof (execstr_t))) != NULL) {
3587c478bd9Sstevel@tonic-gate 		new_exec->name = _strdup_null(old_exec->name);
3597c478bd9Sstevel@tonic-gate 		new_exec->type = _strdup_null(old_exec->type);
3607c478bd9Sstevel@tonic-gate 		new_exec->policy = _strdup_null(old_exec->policy);
3617c478bd9Sstevel@tonic-gate 		new_exec->res1 = _strdup_null(old_exec->res1);
3627c478bd9Sstevel@tonic-gate 		new_exec->res2 = _strdup_null(old_exec->res2);
3637c478bd9Sstevel@tonic-gate 		new_exec->id = _strdup_null(old_exec->id);
3647c478bd9Sstevel@tonic-gate 		new_exec->attr = _strdup_null(old_exec->attr);
3657c478bd9Sstevel@tonic-gate 		new_exec->next = old_exec->next;
3667c478bd9Sstevel@tonic-gate 	}
3677c478bd9Sstevel@tonic-gate 	return (new_exec);
3687c478bd9Sstevel@tonic-gate }
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate void
_free_execstr(execstr_t * exec)3717c478bd9Sstevel@tonic-gate _free_execstr(execstr_t *exec)
3727c478bd9Sstevel@tonic-gate {
3737c478bd9Sstevel@tonic-gate 	if (exec != NULL) {
3747c478bd9Sstevel@tonic-gate 		free(exec->name);
3757c478bd9Sstevel@tonic-gate 		free(exec->type);
3767c478bd9Sstevel@tonic-gate 		free(exec->policy);
3777c478bd9Sstevel@tonic-gate 		free(exec->res1);
3787c478bd9Sstevel@tonic-gate 		free(exec->res2);
3797c478bd9Sstevel@tonic-gate 		free(exec->id);
3807c478bd9Sstevel@tonic-gate 		free(exec->attr);
3817c478bd9Sstevel@tonic-gate 		_free_execstr(exec->next);
3827c478bd9Sstevel@tonic-gate 		free(exec);
3837c478bd9Sstevel@tonic-gate 	}
3847c478bd9Sstevel@tonic-gate }
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate void
_exec_cleanup(nss_status_t res,nss_XbyY_args_t * argp)3877c478bd9Sstevel@tonic-gate _exec_cleanup(nss_status_t res, nss_XbyY_args_t *argp)
3887c478bd9Sstevel@tonic-gate {
3897c478bd9Sstevel@tonic-gate 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
3907c478bd9Sstevel@tonic-gate 
3917c478bd9Sstevel@tonic-gate 	if (res == NSS_SUCCESS) {
3927c478bd9Sstevel@tonic-gate 		if (_priv_exec->head_exec != NULL) {
3937c478bd9Sstevel@tonic-gate 			argp->buf.result = _priv_exec->head_exec;
3947c478bd9Sstevel@tonic-gate 			argp->returnval = argp->buf.result;
3957c478bd9Sstevel@tonic-gate 		}
3967c478bd9Sstevel@tonic-gate 	} else {
3977c478bd9Sstevel@tonic-gate 		if (_priv_exec->head_exec != NULL)
3987c478bd9Sstevel@tonic-gate 			_free_execstr(_priv_exec->head_exec);
3997c478bd9Sstevel@tonic-gate 		argp->returnval = NULL;
4007c478bd9Sstevel@tonic-gate 	}
4017c478bd9Sstevel@tonic-gate }
402