1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1999-2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include "mt.h" 30*7c478bd9Sstevel@tonic-gate #include <stdio.h> 31*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 33*7c478bd9Sstevel@tonic-gate #include <nss_dbdefs.h> 34*7c478bd9Sstevel@tonic-gate #include <rpc/trace.h> 35*7c478bd9Sstevel@tonic-gate #include <string.h> 36*7c478bd9Sstevel@tonic-gate #include <strings.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 38*7c478bd9Sstevel@tonic-gate #include <thread.h> 39*7c478bd9Sstevel@tonic-gate #include <synch.h> 40*7c478bd9Sstevel@tonic-gate #include <nsswitch.h> 41*7c478bd9Sstevel@tonic-gate #include <prof_attr.h> 42*7c478bd9Sstevel@tonic-gate #include <exec_attr.h> 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate /* externs from libc */ 45*7c478bd9Sstevel@tonic-gate extern void _nss_db_state_destr(struct nss_db_state *); 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate /* externs from parse.c */ 48*7c478bd9Sstevel@tonic-gate extern char *_strtok_escape(char *, char *, char **); 49*7c478bd9Sstevel@tonic-gate extern char *_strdup_null(char *); 50*7c478bd9Sstevel@tonic-gate /* extern from getprofattr.c */ 51*7c478bd9Sstevel@tonic-gate extern int str2profattr(const char *, int, void *, char *, int); 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate char *_exec_wild_id(char *, const char *); 54*7c478bd9Sstevel@tonic-gate execstr_t *_dup_execstr(execstr_t *); 55*7c478bd9Sstevel@tonic-gate void _free_execstr(execstr_t *); 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate static char *_nsw_search_path = NULL; 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate /* 60*7c478bd9Sstevel@tonic-gate * Unsynchronized, but it affects only efficiency, not correctness 61*7c478bd9Sstevel@tonic-gate */ 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate static DEFINE_NSS_DB_ROOT(exec_root); 64*7c478bd9Sstevel@tonic-gate static DEFINE_NSS_GETENT(context); 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate void 67*7c478bd9Sstevel@tonic-gate _nss_initf_execattr(nss_db_params_t *p) 68*7c478bd9Sstevel@tonic-gate { 69*7c478bd9Sstevel@tonic-gate trace1(TR__nss_initf_execattr, 0); 70*7c478bd9Sstevel@tonic-gate p->name = NSS_DBNAM_EXECATTR; 71*7c478bd9Sstevel@tonic-gate p->config_name = NSS_DBNAM_PROFATTR; /* use config for "prof_attr" */ 72*7c478bd9Sstevel@tonic-gate trace1(TR__nss_initf_execattr, 1); 73*7c478bd9Sstevel@tonic-gate } 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate void 76*7c478bd9Sstevel@tonic-gate _nsw_initf_execattr(nss_db_params_t *p) 77*7c478bd9Sstevel@tonic-gate { 78*7c478bd9Sstevel@tonic-gate trace1(TR__nss_initf_execattr, 0); 79*7c478bd9Sstevel@tonic-gate p->name = NSS_DBNAM_EXECATTR; 80*7c478bd9Sstevel@tonic-gate p->flags |= NSS_USE_DEFAULT_CONFIG; 81*7c478bd9Sstevel@tonic-gate p->default_config = _nsw_search_path; 82*7c478bd9Sstevel@tonic-gate trace1(TR__nss_initf_execattr, 1); 83*7c478bd9Sstevel@tonic-gate } 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate void 86*7c478bd9Sstevel@tonic-gate _nsw_initf_profattr(nss_db_params_t *p) 87*7c478bd9Sstevel@tonic-gate { 88*7c478bd9Sstevel@tonic-gate trace1(TR__nss_initf_execattr, 0); 89*7c478bd9Sstevel@tonic-gate p->name = NSS_DBNAM_PROFATTR; 90*7c478bd9Sstevel@tonic-gate p->flags |= NSS_USE_DEFAULT_CONFIG; 91*7c478bd9Sstevel@tonic-gate p->default_config = _nsw_search_path; 92*7c478bd9Sstevel@tonic-gate trace1(TR__nss_initf_execattr, 1); 93*7c478bd9Sstevel@tonic-gate } 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate /* 96*7c478bd9Sstevel@tonic-gate * Return values: 0 = success, 1 = parse error, 2 = erange ... The structure 97*7c478bd9Sstevel@tonic-gate * pointer passed in is a structure in the caller's space wherein the field 98*7c478bd9Sstevel@tonic-gate * pointers would be set to areas in the buffer if need be. instring and buffer 99*7c478bd9Sstevel@tonic-gate * should be separate areas. 100*7c478bd9Sstevel@tonic-gate */ 101*7c478bd9Sstevel@tonic-gate int 102*7c478bd9Sstevel@tonic-gate str2execattr(const char *instr, int lenstr, void *ent, char *buffer, int buflen) 103*7c478bd9Sstevel@tonic-gate { 104*7c478bd9Sstevel@tonic-gate char *last = (char *)NULL; 105*7c478bd9Sstevel@tonic-gate char *sep = KV_TOKEN_DELIMIT; 106*7c478bd9Sstevel@tonic-gate char *empty = KV_EMPTY; 107*7c478bd9Sstevel@tonic-gate execstr_t *exec = (execstr_t *)ent; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate if (exec == NULL) { 110*7c478bd9Sstevel@tonic-gate return (NSS_STR_PARSE_PARSE); 111*7c478bd9Sstevel@tonic-gate } 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate trace3(TR_str2execattr, 0, lenstr, buflen); 114*7c478bd9Sstevel@tonic-gate if ((instr >= buffer && (buffer + buflen) > instr) || 115*7c478bd9Sstevel@tonic-gate (buffer >= instr && (instr + lenstr) > buffer)) { 116*7c478bd9Sstevel@tonic-gate trace3(TR_str2execattr, 1, lenstr, buflen); 117*7c478bd9Sstevel@tonic-gate return (NSS_STR_PARSE_PARSE); 118*7c478bd9Sstevel@tonic-gate } 119*7c478bd9Sstevel@tonic-gate if (lenstr >= buflen) { 120*7c478bd9Sstevel@tonic-gate trace3(TR_str2execattr, 1, lenstr, buflen); 121*7c478bd9Sstevel@tonic-gate return (NSS_STR_PARSE_ERANGE); 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate strncpy(buffer, instr, buflen); 124*7c478bd9Sstevel@tonic-gate /* 125*7c478bd9Sstevel@tonic-gate * Remove newline that nis (yp_match) puts at the 126*7c478bd9Sstevel@tonic-gate * end of the entry it retrieves from the map. 127*7c478bd9Sstevel@tonic-gate */ 128*7c478bd9Sstevel@tonic-gate if (buffer[lenstr] == '\n') { 129*7c478bd9Sstevel@tonic-gate buffer[lenstr] = '\0'; 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate exec->name = _strtok_escape(buffer, sep, &last); 133*7c478bd9Sstevel@tonic-gate exec->policy = _strtok_escape(NULL, sep, &last); 134*7c478bd9Sstevel@tonic-gate exec->type = _strtok_escape(NULL, sep, &last); 135*7c478bd9Sstevel@tonic-gate exec->res1 = _strtok_escape(NULL, sep, &last); 136*7c478bd9Sstevel@tonic-gate exec->res2 = _strtok_escape(NULL, sep, &last); 137*7c478bd9Sstevel@tonic-gate exec->id = _strtok_escape(NULL, sep, &last); 138*7c478bd9Sstevel@tonic-gate exec->attr = _strtok_escape(NULL, sep, &last); 139*7c478bd9Sstevel@tonic-gate exec->next = (execstr_t *)NULL; 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate return (NSS_STR_PARSE_SUCCESS); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate void 146*7c478bd9Sstevel@tonic-gate _setexecattr(void) 147*7c478bd9Sstevel@tonic-gate { 148*7c478bd9Sstevel@tonic-gate trace1(TR_setexecattr, 0); 149*7c478bd9Sstevel@tonic-gate nss_setent(&exec_root, _nss_initf_execattr, &context); 150*7c478bd9Sstevel@tonic-gate trace1(TR_setexecattr, 0); 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate void 155*7c478bd9Sstevel@tonic-gate _endexecattr(void) 156*7c478bd9Sstevel@tonic-gate { 157*7c478bd9Sstevel@tonic-gate trace1(TR_endexecattr, 0); 158*7c478bd9Sstevel@tonic-gate nss_endent(&exec_root, _nss_initf_execattr, &context); 159*7c478bd9Sstevel@tonic-gate nss_delete(&exec_root); 160*7c478bd9Sstevel@tonic-gate trace1(TR_endexecattr, 0); 161*7c478bd9Sstevel@tonic-gate } 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate execstr_t * 165*7c478bd9Sstevel@tonic-gate _getexecattr(execstr_t *result, char *buffer, int buflen, int *errnop) 166*7c478bd9Sstevel@tonic-gate { 167*7c478bd9Sstevel@tonic-gate nss_status_t res; 168*7c478bd9Sstevel@tonic-gate nss_XbyY_args_t arg; 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate trace2(TR_getexecattr, 0, buflen); 171*7c478bd9Sstevel@tonic-gate NSS_XbyY_INIT(&arg, result, buffer, buflen, str2execattr); 172*7c478bd9Sstevel@tonic-gate res = nss_getent(&exec_root, _nss_initf_execattr, &context, &arg); 173*7c478bd9Sstevel@tonic-gate arg.status = res; 174*7c478bd9Sstevel@tonic-gate *errnop = arg.h_errno; 175*7c478bd9Sstevel@tonic-gate trace2(TR_getexecattr, 1, buflen); 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate return ((execstr_t *)NSS_XbyY_FINI(&arg)); 178*7c478bd9Sstevel@tonic-gate } 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate execstr_t * 181*7c478bd9Sstevel@tonic-gate _getexecprof(char *name, 182*7c478bd9Sstevel@tonic-gate char *type, 183*7c478bd9Sstevel@tonic-gate char *id, 184*7c478bd9Sstevel@tonic-gate int search_flag, 185*7c478bd9Sstevel@tonic-gate execstr_t *result, 186*7c478bd9Sstevel@tonic-gate char *buffer, 187*7c478bd9Sstevel@tonic-gate int buflen, 188*7c478bd9Sstevel@tonic-gate int *errnop) 189*7c478bd9Sstevel@tonic-gate { 190*7c478bd9Sstevel@tonic-gate int getby_flag; 191*7c478bd9Sstevel@tonic-gate char policy_buf[BUFSIZ]; 192*7c478bd9Sstevel@tonic-gate const char *empty = (const char *)NULL; 193*7c478bd9Sstevel@tonic-gate nss_status_t res = NSS_NOTFOUND; 194*7c478bd9Sstevel@tonic-gate nss_XbyY_args_t arg; 195*7c478bd9Sstevel@tonic-gate _priv_execattr _priv_exec; 196*7c478bd9Sstevel@tonic-gate static mutex_t _nsw_exec_lock = DEFAULTMUTEX; 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate trace2(TR_getexecprof, 0, _buflen); 199*7c478bd9Sstevel@tonic-gate NSS_XbyY_INIT(&arg, result, buffer, buflen, str2execattr); 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate _priv_exec.name = (name == NULL) ? empty : (const char *)name; 202*7c478bd9Sstevel@tonic-gate _priv_exec.type = (type == NULL) ? empty : (const char *)type; 203*7c478bd9Sstevel@tonic-gate _priv_exec.id = (id == NULL) ? empty : (const char *)id; 204*7c478bd9Sstevel@tonic-gate #ifdef SI_SECPOLICY 205*7c478bd9Sstevel@tonic-gate if (sysinfo(SI_SECPOLICY, policy_buf, BUFSIZ) == -1) 206*7c478bd9Sstevel@tonic-gate #endif /* SI_SECPOLICY */ 207*7c478bd9Sstevel@tonic-gate strncpy(policy_buf, DEFAULT_POLICY, BUFSIZ); 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate retry_policy: 210*7c478bd9Sstevel@tonic-gate _priv_exec.policy = policy_buf; 211*7c478bd9Sstevel@tonic-gate _priv_exec.search_flag = search_flag; 212*7c478bd9Sstevel@tonic-gate _priv_exec.head_exec = (execstr_t *)NULL; 213*7c478bd9Sstevel@tonic-gate _priv_exec.prev_exec = (execstr_t *)NULL; 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate if ((name != NULL) && (id != NULL)) { 216*7c478bd9Sstevel@tonic-gate getby_flag = NSS_DBOP_EXECATTR_BYNAMEID; 217*7c478bd9Sstevel@tonic-gate } else if (name != NULL) { 218*7c478bd9Sstevel@tonic-gate getby_flag = NSS_DBOP_EXECATTR_BYNAME; 219*7c478bd9Sstevel@tonic-gate } else if (id != NULL) { 220*7c478bd9Sstevel@tonic-gate getby_flag = NSS_DBOP_EXECATTR_BYID; 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate arg.key.attrp = &(_priv_exec); 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate switch (getby_flag) { 226*7c478bd9Sstevel@tonic-gate case NSS_DBOP_EXECATTR_BYID: 227*7c478bd9Sstevel@tonic-gate res = nss_search(&exec_root, _nss_initf_execattr, getby_flag, 228*7c478bd9Sstevel@tonic-gate &arg); 229*7c478bd9Sstevel@tonic-gate break; 230*7c478bd9Sstevel@tonic-gate case NSS_DBOP_EXECATTR_BYNAMEID: 231*7c478bd9Sstevel@tonic-gate case NSS_DBOP_EXECATTR_BYNAME: 232*7c478bd9Sstevel@tonic-gate { 233*7c478bd9Sstevel@tonic-gate char pbuf[NSS_BUFLEN_PROFATTR]; 234*7c478bd9Sstevel@tonic-gate profstr_t prof; 235*7c478bd9Sstevel@tonic-gate nss_status_t pres; 236*7c478bd9Sstevel@tonic-gate nss_XbyY_args_t parg; 237*7c478bd9Sstevel@tonic-gate enum __nsw_parse_err pserr; 238*7c478bd9Sstevel@tonic-gate struct __nsw_lookup *lookups = NULL; 239*7c478bd9Sstevel@tonic-gate struct __nsw_switchconfig *conf = NULL; 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate if (conf = __nsw_getconfig(NSS_DBNAM_PROFATTR, &pserr)) 242*7c478bd9Sstevel@tonic-gate if ((lookups = conf->lookups) == NULL) 243*7c478bd9Sstevel@tonic-gate goto out; 244*7c478bd9Sstevel@tonic-gate NSS_XbyY_INIT(&parg, &prof, pbuf, NSS_BUFLEN_PROFATTR, 245*7c478bd9Sstevel@tonic-gate str2profattr); 246*7c478bd9Sstevel@tonic-gate parg.key.name = name; 247*7c478bd9Sstevel@tonic-gate do { 248*7c478bd9Sstevel@tonic-gate /* 249*7c478bd9Sstevel@tonic-gate * search the exec_attr entry only in the scope 250*7c478bd9Sstevel@tonic-gate * that we find the profile in. 251*7c478bd9Sstevel@tonic-gate * if conf = NULL, search in local files only, 252*7c478bd9Sstevel@tonic-gate * as we were not able to read nsswitch.conf. 253*7c478bd9Sstevel@tonic-gate */ 254*7c478bd9Sstevel@tonic-gate DEFINE_NSS_DB_ROOT(prof_root); 255*7c478bd9Sstevel@tonic-gate if (mutex_lock(&_nsw_exec_lock) != 0) 256*7c478bd9Sstevel@tonic-gate goto out; 257*7c478bd9Sstevel@tonic-gate _nsw_search_path = (conf == NULL) 258*7c478bd9Sstevel@tonic-gate ? NSS_FILES_ONLY 259*7c478bd9Sstevel@tonic-gate : lookups->service_name; 260*7c478bd9Sstevel@tonic-gate pres = nss_search(&prof_root, 261*7c478bd9Sstevel@tonic-gate _nsw_initf_profattr, 262*7c478bd9Sstevel@tonic-gate NSS_DBOP_PROFATTR_BYNAME, &parg); 263*7c478bd9Sstevel@tonic-gate if (pres == NSS_SUCCESS) { 264*7c478bd9Sstevel@tonic-gate DEFINE_NSS_DB_ROOT(pexec_root); 265*7c478bd9Sstevel@tonic-gate res = nss_search(&pexec_root, 266*7c478bd9Sstevel@tonic-gate _nsw_initf_execattr, getby_flag, 267*7c478bd9Sstevel@tonic-gate &arg); 268*7c478bd9Sstevel@tonic-gate _nss_db_state_destr(pexec_root.s); 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate _nss_db_state_destr(prof_root.s); 271*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&_nsw_exec_lock); 272*7c478bd9Sstevel@tonic-gate if ((pres == NSS_SUCCESS) || (conf == NULL)) 273*7c478bd9Sstevel@tonic-gate break; 274*7c478bd9Sstevel@tonic-gate } while (lookups && (lookups = lookups->next)); 275*7c478bd9Sstevel@tonic-gate } 276*7c478bd9Sstevel@tonic-gate break; 277*7c478bd9Sstevel@tonic-gate default: 278*7c478bd9Sstevel@tonic-gate break; 279*7c478bd9Sstevel@tonic-gate } 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate out: 282*7c478bd9Sstevel@tonic-gate /* 283*7c478bd9Sstevel@tonic-gate * If we can't find an entry for the current default policy 284*7c478bd9Sstevel@tonic-gate * fall back to the old "suser" policy. The nameservice is 285*7c478bd9Sstevel@tonic-gate * shared between different OS releases. 286*7c478bd9Sstevel@tonic-gate */ 287*7c478bd9Sstevel@tonic-gate if (res == NSS_NOTFOUND && strcmp(policy_buf, DEFAULT_POLICY) == 0) { 288*7c478bd9Sstevel@tonic-gate (void) strlcpy(policy_buf, SUSER_POLICY, BUFSIZ); 289*7c478bd9Sstevel@tonic-gate goto retry_policy; 290*7c478bd9Sstevel@tonic-gate } 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate arg.status = res; 293*7c478bd9Sstevel@tonic-gate *errnop = res; 294*7c478bd9Sstevel@tonic-gate trace2(TR_getexecprof, 1, buflen); 295*7c478bd9Sstevel@tonic-gate return ((execstr_t *)NSS_XbyY_FINI(&arg)); 296*7c478bd9Sstevel@tonic-gate } 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate int 300*7c478bd9Sstevel@tonic-gate _doexeclist(nss_XbyY_args_t *argp) 301*7c478bd9Sstevel@tonic-gate { 302*7c478bd9Sstevel@tonic-gate int status = 1; 303*7c478bd9Sstevel@tonic-gate _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); 304*7c478bd9Sstevel@tonic-gate execstr_t *exec = (execstr_t *)((argp->buf.result)); 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate if (_priv_exec->head_exec == NULL) { 307*7c478bd9Sstevel@tonic-gate if (_priv_exec->head_exec = _dup_execstr(exec)) 308*7c478bd9Sstevel@tonic-gate _priv_exec->prev_exec = _priv_exec->head_exec; 309*7c478bd9Sstevel@tonic-gate else 310*7c478bd9Sstevel@tonic-gate status = 0; 311*7c478bd9Sstevel@tonic-gate } else { 312*7c478bd9Sstevel@tonic-gate if (_priv_exec->prev_exec->next = _dup_execstr(exec)) 313*7c478bd9Sstevel@tonic-gate _priv_exec->prev_exec = _priv_exec->prev_exec->next; 314*7c478bd9Sstevel@tonic-gate else 315*7c478bd9Sstevel@tonic-gate status = 0; 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate memset(argp->buf.buffer, NULL, argp->buf.buflen); 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate return (status); 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate } 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate /* 325*7c478bd9Sstevel@tonic-gate * Converts id to a wildcard string. e.g.: 326*7c478bd9Sstevel@tonic-gate * For type = KV_COMMAND: /usr/ccs/bin/what ---> /usr/ccs/bin/\* ---> \* 327*7c478bd9Sstevel@tonic-gate * For type = KV_ACTION: Dtfile;*;*;*;0 ---> *;*;*;*;* 328*7c478bd9Sstevel@tonic-gate * 329*7c478bd9Sstevel@tonic-gate * Returns NULL if id is already a wild-card. 330*7c478bd9Sstevel@tonic-gate */ 331*7c478bd9Sstevel@tonic-gate char * 332*7c478bd9Sstevel@tonic-gate _exec_wild_id(char *id, const char *type) 333*7c478bd9Sstevel@tonic-gate { 334*7c478bd9Sstevel@tonic-gate char c_id = '/'; 335*7c478bd9Sstevel@tonic-gate char *pchar = NULL; 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate if ((id == NULL) || (type == NULL)) 338*7c478bd9Sstevel@tonic-gate return (NULL); 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate if (strcmp(type, KV_ACTION) == 0) { 341*7c478bd9Sstevel@tonic-gate return ((strcmp(id, KV_ACTION_WILDCARD) == 0) ? NULL : 342*7c478bd9Sstevel@tonic-gate KV_ACTION_WILDCARD); 343*7c478bd9Sstevel@tonic-gate } else if (strcmp(type, KV_COMMAND) == 0) { 344*7c478bd9Sstevel@tonic-gate if ((pchar = rindex(id, c_id)) == NULL) 345*7c478bd9Sstevel@tonic-gate /* 346*7c478bd9Sstevel@tonic-gate * id = \* 347*7c478bd9Sstevel@tonic-gate */ 348*7c478bd9Sstevel@tonic-gate return (NULL); 349*7c478bd9Sstevel@tonic-gate else if (*(++pchar) == KV_WILDCHAR) 350*7c478bd9Sstevel@tonic-gate /* 351*7c478bd9Sstevel@tonic-gate * id = /usr/ccs/bin/\* 352*7c478bd9Sstevel@tonic-gate */ 353*7c478bd9Sstevel@tonic-gate return (pchar); 354*7c478bd9Sstevel@tonic-gate /* 355*7c478bd9Sstevel@tonic-gate * id = /usr/ccs/bin/what 356*7c478bd9Sstevel@tonic-gate */ 357*7c478bd9Sstevel@tonic-gate strcpy(pchar, KV_WILDCARD); 358*7c478bd9Sstevel@tonic-gate return (id); 359*7c478bd9Sstevel@tonic-gate } 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate return (NULL); 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate } 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate execstr_t * 367*7c478bd9Sstevel@tonic-gate _dup_execstr(execstr_t *old_exec) 368*7c478bd9Sstevel@tonic-gate { 369*7c478bd9Sstevel@tonic-gate execstr_t *new_exec = (execstr_t *)NULL; 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate if (old_exec == NULL) { 372*7c478bd9Sstevel@tonic-gate return ((execstr_t *)NULL); 373*7c478bd9Sstevel@tonic-gate } 374*7c478bd9Sstevel@tonic-gate if ((new_exec = (execstr_t *)malloc(sizeof (execstr_t))) != NULL) { 375*7c478bd9Sstevel@tonic-gate new_exec->name = _strdup_null(old_exec->name); 376*7c478bd9Sstevel@tonic-gate new_exec->type = _strdup_null(old_exec->type); 377*7c478bd9Sstevel@tonic-gate new_exec->policy = _strdup_null(old_exec->policy); 378*7c478bd9Sstevel@tonic-gate new_exec->res1 = _strdup_null(old_exec->res1); 379*7c478bd9Sstevel@tonic-gate new_exec->res2 = _strdup_null(old_exec->res2); 380*7c478bd9Sstevel@tonic-gate new_exec->id = _strdup_null(old_exec->id); 381*7c478bd9Sstevel@tonic-gate new_exec->attr = _strdup_null(old_exec->attr); 382*7c478bd9Sstevel@tonic-gate new_exec->next = old_exec->next; 383*7c478bd9Sstevel@tonic-gate } 384*7c478bd9Sstevel@tonic-gate return (new_exec); 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate void 388*7c478bd9Sstevel@tonic-gate _free_execstr(execstr_t *exec) 389*7c478bd9Sstevel@tonic-gate { 390*7c478bd9Sstevel@tonic-gate if (exec != NULL) { 391*7c478bd9Sstevel@tonic-gate free(exec->name); 392*7c478bd9Sstevel@tonic-gate free(exec->type); 393*7c478bd9Sstevel@tonic-gate free(exec->policy); 394*7c478bd9Sstevel@tonic-gate free(exec->res1); 395*7c478bd9Sstevel@tonic-gate free(exec->res2); 396*7c478bd9Sstevel@tonic-gate free(exec->id); 397*7c478bd9Sstevel@tonic-gate free(exec->attr); 398*7c478bd9Sstevel@tonic-gate _free_execstr(exec->next); 399*7c478bd9Sstevel@tonic-gate free(exec); 400*7c478bd9Sstevel@tonic-gate } 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate void 404*7c478bd9Sstevel@tonic-gate _exec_cleanup(nss_status_t res, nss_XbyY_args_t *argp) 405*7c478bd9Sstevel@tonic-gate { 406*7c478bd9Sstevel@tonic-gate _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate if (res == NSS_SUCCESS) { 409*7c478bd9Sstevel@tonic-gate if (_priv_exec->head_exec != NULL) { 410*7c478bd9Sstevel@tonic-gate argp->buf.result = _priv_exec->head_exec; 411*7c478bd9Sstevel@tonic-gate argp->returnval = argp->buf.result; 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate } else { 414*7c478bd9Sstevel@tonic-gate if (_priv_exec->head_exec != NULL) 415*7c478bd9Sstevel@tonic-gate _free_execstr(_priv_exec->head_exec); 416*7c478bd9Sstevel@tonic-gate argp->returnval = NULL; 417*7c478bd9Sstevel@tonic-gate } 418*7c478bd9Sstevel@tonic-gate } 419