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