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 */
25*d00075c7SMarcel Telka /*
26*d00075c7SMarcel Telka * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
27*d00075c7SMarcel 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)
10561961e0fSrobinson (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
1787c478bd9Sstevel@tonic-gate if ((name != NULL) && (id != NULL)) {
1797c478bd9Sstevel@tonic-gate getby_flag = NSS_DBOP_EXECATTR_BYNAMEID;
1807c478bd9Sstevel@tonic-gate } else if (name != NULL) {
1817c478bd9Sstevel@tonic-gate getby_flag = NSS_DBOP_EXECATTR_BYNAME;
1827c478bd9Sstevel@tonic-gate } else if (id != NULL) {
1837c478bd9Sstevel@tonic-gate getby_flag = NSS_DBOP_EXECATTR_BYID;
184*d00075c7SMarcel Telka } else {
185*d00075c7SMarcel Telka return (NULL);
1867c478bd9Sstevel@tonic-gate }
1877c478bd9Sstevel@tonic-gate
188*d00075c7SMarcel Telka NSS_XbyY_INIT(&arg, result, buffer, buflen, str2execattr);
189*d00075c7SMarcel Telka
190*d00075c7SMarcel Telka _priv_exec.name = name;
191*d00075c7SMarcel Telka _priv_exec.type = type;
192*d00075c7SMarcel Telka _priv_exec.id = id;
193*d00075c7SMarcel Telka #ifdef SI_SECPOLICY
194*d00075c7SMarcel Telka if (sysinfo(SI_SECPOLICY, policy_buf, BUFSIZ) == -1)
195*d00075c7SMarcel Telka #endif /* SI_SECPOLICY */
196*d00075c7SMarcel Telka (void) strncpy(policy_buf, DEFAULT_POLICY, BUFSIZ);
197*d00075c7SMarcel Telka
198*d00075c7SMarcel Telka retry_policy:
199*d00075c7SMarcel Telka _priv_exec.policy = IS_SEARCH_ALL(search_flag) ? NULL : policy_buf;
200*d00075c7SMarcel Telka _priv_exec.search_flag = search_flag;
201*d00075c7SMarcel Telka _priv_exec.head_exec = NULL;
202*d00075c7SMarcel Telka _priv_exec.prev_exec = NULL;
203*d00075c7SMarcel Telka
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(
251cb5caa98Sdjl pexec_root.s);
2527c478bd9Sstevel@tonic-gate }
253cb5caa98Sdjl if (prof_root.s != NULL)
2547c478bd9Sstevel@tonic-gate _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 }
30161961e0fSrobinson (void) memset(argp->buf.buffer, NULL, 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