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 2004 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 <sys/types.h> 30*0Sstevel@tonic-gate #include <stdio.h> 31*0Sstevel@tonic-gate #include <string.h> 32*0Sstevel@tonic-gate #include <stdlib.h> 33*0Sstevel@tonic-gate #include <nss_dbdefs.h> 34*0Sstevel@tonic-gate #include <deflt.h> 35*0Sstevel@tonic-gate #include <exec_attr.h> 36*0Sstevel@tonic-gate #include <user_attr.h> 37*0Sstevel@tonic-gate #include <auth_attr.h> 38*0Sstevel@tonic-gate #include <prof_attr.h> 39*0Sstevel@tonic-gate #include <getxby_door.h> 40*0Sstevel@tonic-gate #include <sys/mman.h> 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gate /* Externs from libnsl */ 44*0Sstevel@tonic-gate extern execstr_t *_getexecattr(execstr_t *, char *, int, int *); 45*0Sstevel@tonic-gate extern void _setexecattr(void); 46*0Sstevel@tonic-gate extern void _endexecattr(void); 47*0Sstevel@tonic-gate extern execstr_t *_getexecprof(const char *, const char *, const char *, int, 48*0Sstevel@tonic-gate execstr_t *, char *, int, int *); 49*0Sstevel@tonic-gate extern userstr_t *_getusernam(const char *, userstr_t *, char *, int, int *); 50*0Sstevel@tonic-gate extern userstr_t *_getuserattr(userstr_t *, char *, int, int *); 51*0Sstevel@tonic-gate extern char *_strtok_escape(char *, char *, char **); 52*0Sstevel@tonic-gate extern char *_strdup_null(char *); 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate static execattr_t *userprof(const char *, const char *, const char *, int); 55*0Sstevel@tonic-gate static execattr_t *get_tail(execattr_t *); 56*0Sstevel@tonic-gate static execattr_t *execstr2attr(execstr_t *); 57*0Sstevel@tonic-gate static execstr_t *process_getexec(execstr_t *, char *, int, nsc_data_t *); 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate execattr_t * 60*0Sstevel@tonic-gate getexecattr() 61*0Sstevel@tonic-gate { 62*0Sstevel@tonic-gate int err = 0; 63*0Sstevel@tonic-gate char buf[NSS_BUFLEN_EXECATTR]; 64*0Sstevel@tonic-gate execstr_t exec; 65*0Sstevel@tonic-gate execstr_t *tmp; 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate tmp = _getexecattr(&exec, buf, NSS_BUFLEN_EXECATTR, &err); 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate return (execstr2attr(tmp)); 70*0Sstevel@tonic-gate } 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate execattr_t * 74*0Sstevel@tonic-gate getexecprof(const char *name, const char *type, const char *id, int search_flag) 75*0Sstevel@tonic-gate { 76*0Sstevel@tonic-gate int len_unique; 77*0Sstevel@tonic-gate int err = 0; 78*0Sstevel@tonic-gate int ndata = 0; 79*0Sstevel@tonic-gate int adata = 0; 80*0Sstevel@tonic-gate char unique[NSS_BUFLEN_EXECATTR]; 81*0Sstevel@tonic-gate char buf[NSS_BUFLEN_EXECATTR]; 82*0Sstevel@tonic-gate execattr_t *head = (execattr_t *)NULL; 83*0Sstevel@tonic-gate execattr_t *prev = (execattr_t *)NULL; 84*0Sstevel@tonic-gate execstr_t exec; 85*0Sstevel@tonic-gate execstr_t *tmp; 86*0Sstevel@tonic-gate execstr_t *resptr = (execstr_t *)NULL; 87*0Sstevel@tonic-gate nsc_data_t *sptr = (nsc_data_t *)NULL; 88*0Sstevel@tonic-gate union { 89*0Sstevel@tonic-gate nsc_data_t s_d; 90*0Sstevel@tonic-gate char s_b[NSS_BUFLEN_EXECATTR]; 91*0Sstevel@tonic-gate } space; 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate (void) memset(unique, 0, NSS_BUFLEN_EXECATTR); 94*0Sstevel@tonic-gate (void) memset(&exec, 0, sizeof (execstr_t)); 95*0Sstevel@tonic-gate (void) memset(&space, 0, sizeof (space)); 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate if ((search_flag != GET_ONE) && (search_flag != GET_ALL)) { 98*0Sstevel@tonic-gate return ((execattr_t *)NULL); 99*0Sstevel@tonic-gate } 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate if ((name == NULL) && (type == NULL) && (id == NULL)) { 102*0Sstevel@tonic-gate setexecattr(); 103*0Sstevel@tonic-gate switch (search_flag) { 104*0Sstevel@tonic-gate case GET_ONE: 105*0Sstevel@tonic-gate head = getexecattr(); 106*0Sstevel@tonic-gate break; 107*0Sstevel@tonic-gate case GET_ALL: 108*0Sstevel@tonic-gate head = getexecattr(); 109*0Sstevel@tonic-gate prev = head; 110*0Sstevel@tonic-gate while (prev != NULL) { 111*0Sstevel@tonic-gate prev->next = getexecattr(); 112*0Sstevel@tonic-gate prev = prev->next; 113*0Sstevel@tonic-gate }; 114*0Sstevel@tonic-gate break; 115*0Sstevel@tonic-gate default: 116*0Sstevel@tonic-gate head = (execattr_t *)NULL; 117*0Sstevel@tonic-gate break; 118*0Sstevel@tonic-gate } 119*0Sstevel@tonic-gate endexecattr(); 120*0Sstevel@tonic-gate return (head); 121*0Sstevel@tonic-gate } 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate #ifdef PIC 124*0Sstevel@tonic-gate /* 125*0Sstevel@tonic-gate * If the search criteria is completely specified 126*0Sstevel@tonic-gate * and we only want a single entry, 127*0Sstevel@tonic-gate * then attempt to look up the entry using the nscd. 128*0Sstevel@tonic-gate * Only commands are cached. 129*0Sstevel@tonic-gate */ 130*0Sstevel@tonic-gate if (name && type && (strcmp(type, KV_COMMAND) == 0) && id && 131*0Sstevel@tonic-gate (search_flag == GET_ONE)) { 132*0Sstevel@tonic-gate if (snprintf(unique, NSS_BUFLEN_EXECATTR, "%s:%s:%s", 133*0Sstevel@tonic-gate name, type, id) >= NSS_BUFLEN_EXECATTR) { 134*0Sstevel@tonic-gate errno = ERANGE; 135*0Sstevel@tonic-gate return ((execattr_t *)NULL); 136*0Sstevel@tonic-gate } 137*0Sstevel@tonic-gate len_unique = strlen(unique); 138*0Sstevel@tonic-gate if ((len_unique >= (sizeof (space) - sizeof (nsc_data_t)))) { 139*0Sstevel@tonic-gate errno = ERANGE; 140*0Sstevel@tonic-gate return ((execattr_t *)NULL); 141*0Sstevel@tonic-gate } 142*0Sstevel@tonic-gate ndata = sizeof (space); 143*0Sstevel@tonic-gate adata = len_unique + sizeof (nsc_call_t) + 1; 144*0Sstevel@tonic-gate space.s_d.nsc_call.nsc_callnumber = GETEXECID; 145*0Sstevel@tonic-gate (void) strcpy(space.s_d.nsc_call.nsc_u.name, unique); 146*0Sstevel@tonic-gate sptr = &space.s_d; 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate switch (_nsc_trydoorcall(&sptr, &ndata, &adata)) { 149*0Sstevel@tonic-gate case SUCCESS: /* positive cache hit */ 150*0Sstevel@tonic-gate break; 151*0Sstevel@tonic-gate case NOTFOUND: /* negative cache hit */ 152*0Sstevel@tonic-gate return ((execattr_t *)NULL); 153*0Sstevel@tonic-gate default: 154*0Sstevel@tonic-gate resptr = _getexecprof(name, type, id, search_flag, 155*0Sstevel@tonic-gate &exec, buf, NSS_BUFLEN_EXECATTR, &err); 156*0Sstevel@tonic-gate return (execstr2attr(resptr)); 157*0Sstevel@tonic-gate } 158*0Sstevel@tonic-gate resptr = process_getexec(&exec, buf, NSS_BUFLEN_EXECATTR, 159*0Sstevel@tonic-gate sptr); 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate /* 162*0Sstevel@tonic-gate * check if doors reallocated the memory underneath us 163*0Sstevel@tonic-gate * if they did munmap it or suffer a memory leak 164*0Sstevel@tonic-gate */ 165*0Sstevel@tonic-gate if (sptr != &space.s_d) 166*0Sstevel@tonic-gate (void) munmap((void *)sptr, ndata); 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate return (execstr2attr(resptr)); 169*0Sstevel@tonic-gate } /* end if (name && type && id && search_flag == GET_ONE) */ 170*0Sstevel@tonic-gate #endif /* PIC */ 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate tmp = _getexecprof(name, 173*0Sstevel@tonic-gate type, 174*0Sstevel@tonic-gate id, 175*0Sstevel@tonic-gate search_flag, 176*0Sstevel@tonic-gate &exec, 177*0Sstevel@tonic-gate buf, 178*0Sstevel@tonic-gate NSS_BUFLEN_EXECATTR, 179*0Sstevel@tonic-gate &err); 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate return (execstr2attr(tmp)); 182*0Sstevel@tonic-gate } 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate execattr_t * 186*0Sstevel@tonic-gate getexecuser(const char *username, const char *type, const char *id, 187*0Sstevel@tonic-gate int search_flag) 188*0Sstevel@tonic-gate { 189*0Sstevel@tonic-gate int err = 0; 190*0Sstevel@tonic-gate char buf[NSS_BUFLEN_USERATTR]; 191*0Sstevel@tonic-gate userstr_t user; 192*0Sstevel@tonic-gate userstr_t *utmp; 193*0Sstevel@tonic-gate execattr_t *head = (execattr_t *)NULL; 194*0Sstevel@tonic-gate execattr_t *prev = (execattr_t *)NULL; 195*0Sstevel@tonic-gate execattr_t *new = (execattr_t *)NULL; 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate if ((search_flag != GET_ONE) && (search_flag != GET_ALL)) { 198*0Sstevel@tonic-gate return ((execattr_t *)NULL); 199*0Sstevel@tonic-gate } 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate if (username == NULL) { 202*0Sstevel@tonic-gate setuserattr(); 203*0Sstevel@tonic-gate /* avoid userstr2attr mallocs by calling libnsl directly */ 204*0Sstevel@tonic-gate utmp = _getuserattr(&user, buf, NSS_BUFLEN_USERATTR, &err); 205*0Sstevel@tonic-gate if (utmp == NULL) { 206*0Sstevel@tonic-gate return (head); 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate switch (search_flag) { 209*0Sstevel@tonic-gate case GET_ONE: 210*0Sstevel@tonic-gate head = userprof((const char *)(utmp->name), type, id, 211*0Sstevel@tonic-gate search_flag); 212*0Sstevel@tonic-gate break; 213*0Sstevel@tonic-gate case GET_ALL: 214*0Sstevel@tonic-gate head = userprof((const char *)(utmp->name), type, id, 215*0Sstevel@tonic-gate search_flag); 216*0Sstevel@tonic-gate if (head != NULL) { 217*0Sstevel@tonic-gate prev = get_tail(head); 218*0Sstevel@tonic-gate } 219*0Sstevel@tonic-gate while ((utmp = _getuserattr(&user, 220*0Sstevel@tonic-gate buf, NSS_BUFLEN_USERATTR, &err)) != NULL) { 221*0Sstevel@tonic-gate if ((new = 222*0Sstevel@tonic-gate userprof((const char *)(utmp->name), 223*0Sstevel@tonic-gate type, id, search_flag)) != NULL) { 224*0Sstevel@tonic-gate if (prev != NULL) { 225*0Sstevel@tonic-gate prev->next = new; 226*0Sstevel@tonic-gate prev = get_tail(prev->next); 227*0Sstevel@tonic-gate } else { 228*0Sstevel@tonic-gate head = new; 229*0Sstevel@tonic-gate prev = get_tail(head); 230*0Sstevel@tonic-gate } 231*0Sstevel@tonic-gate } 232*0Sstevel@tonic-gate } 233*0Sstevel@tonic-gate break; 234*0Sstevel@tonic-gate default: 235*0Sstevel@tonic-gate head = (execattr_t *)NULL; 236*0Sstevel@tonic-gate break; 237*0Sstevel@tonic-gate } 238*0Sstevel@tonic-gate enduserattr(); 239*0Sstevel@tonic-gate } else { 240*0Sstevel@tonic-gate head = userprof(username, type, id, search_flag); 241*0Sstevel@tonic-gate } 242*0Sstevel@tonic-gate 243*0Sstevel@tonic-gate return (head); 244*0Sstevel@tonic-gate } 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate execattr_t * 248*0Sstevel@tonic-gate match_execattr(execattr_t *exec, const char *profname, const char *type, 249*0Sstevel@tonic-gate const char *id) 250*0Sstevel@tonic-gate { 251*0Sstevel@tonic-gate execattr_t *execp = (execattr_t *)NULL; 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate for (execp = exec; execp != NULL; execp = execp->next) { 254*0Sstevel@tonic-gate if ((profname && execp->name && 255*0Sstevel@tonic-gate (strcmp(profname, execp->name) != 0)) || 256*0Sstevel@tonic-gate (type && execp->type && (strcmp(type, execp->type) != 0)) || 257*0Sstevel@tonic-gate (id && execp->id && (strcmp(id, execp->id) != 0))) 258*0Sstevel@tonic-gate continue; 259*0Sstevel@tonic-gate } 260*0Sstevel@tonic-gate 261*0Sstevel@tonic-gate return (execp); 262*0Sstevel@tonic-gate } 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate void 266*0Sstevel@tonic-gate setexecattr() 267*0Sstevel@tonic-gate { 268*0Sstevel@tonic-gate _setexecattr(); 269*0Sstevel@tonic-gate } 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate void 273*0Sstevel@tonic-gate endexecattr() 274*0Sstevel@tonic-gate { 275*0Sstevel@tonic-gate _endexecattr(); 276*0Sstevel@tonic-gate } 277*0Sstevel@tonic-gate 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate void 280*0Sstevel@tonic-gate free_execattr(execattr_t *exec) 281*0Sstevel@tonic-gate { 282*0Sstevel@tonic-gate if (exec != (execattr_t *)NULL) { 283*0Sstevel@tonic-gate free(exec->name); 284*0Sstevel@tonic-gate free(exec->type); 285*0Sstevel@tonic-gate free(exec->policy); 286*0Sstevel@tonic-gate free(exec->res1); 287*0Sstevel@tonic-gate free(exec->res2); 288*0Sstevel@tonic-gate free(exec->id); 289*0Sstevel@tonic-gate _kva_free(exec->attr); 290*0Sstevel@tonic-gate free_execattr(exec->next); 291*0Sstevel@tonic-gate free(exec); 292*0Sstevel@tonic-gate } 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gate static execattr_t * 297*0Sstevel@tonic-gate userprof(const char *username, const char *type, const char *id, 298*0Sstevel@tonic-gate int search_flag) 299*0Sstevel@tonic-gate { 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate int err = 0; 302*0Sstevel@tonic-gate char *last; 303*0Sstevel@tonic-gate char *sep = ","; 304*0Sstevel@tonic-gate char *proflist = (char *)NULL; 305*0Sstevel@tonic-gate char *profname = (char *)NULL; 306*0Sstevel@tonic-gate char buf[NSS_BUFLEN_USERATTR]; 307*0Sstevel@tonic-gate char pwdb[NSS_BUFLEN_PASSWD]; 308*0Sstevel@tonic-gate kva_t *user_attr; 309*0Sstevel@tonic-gate userstr_t user; 310*0Sstevel@tonic-gate userstr_t *utmp; 311*0Sstevel@tonic-gate execattr_t *exec; 312*0Sstevel@tonic-gate execattr_t *head = (execattr_t *)NULL; 313*0Sstevel@tonic-gate execattr_t *prev = (execattr_t *)NULL; 314*0Sstevel@tonic-gate struct passwd pwd; 315*0Sstevel@tonic-gate 316*0Sstevel@tonic-gate char *profArray[MAXPROFS]; 317*0Sstevel@tonic-gate int profcnt = 0; 318*0Sstevel@tonic-gate int i; 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate /* 321*0Sstevel@tonic-gate * Check if specified username is valid user 322*0Sstevel@tonic-gate */ 323*0Sstevel@tonic-gate if (getpwnam_r(username, &pwd, pwdb, sizeof (pwdb)) == NULL) { 324*0Sstevel@tonic-gate return (head); 325*0Sstevel@tonic-gate } 326*0Sstevel@tonic-gate 327*0Sstevel@tonic-gate utmp = _getusernam(username, &user, buf, NSS_BUFLEN_USERATTR, &err); 328*0Sstevel@tonic-gate if (utmp != NULL) { 329*0Sstevel@tonic-gate proflist = NULL; 330*0Sstevel@tonic-gate user_attr = _str2kva(user.attr, KV_ASSIGN, KV_DELIMITER); 331*0Sstevel@tonic-gate if ((proflist = kva_match(user_attr, "profiles")) != NULL) { 332*0Sstevel@tonic-gate /* Get the list of profiles for this user */ 333*0Sstevel@tonic-gate for (profname = _strtok_escape(proflist, sep, &last); 334*0Sstevel@tonic-gate profname != NULL; 335*0Sstevel@tonic-gate profname = _strtok_escape(NULL, sep, &last)) { 336*0Sstevel@tonic-gate getproflist(profname, profArray, &profcnt); 337*0Sstevel@tonic-gate } 338*0Sstevel@tonic-gate } 339*0Sstevel@tonic-gate } 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate /* Get the list of default profiles */ 342*0Sstevel@tonic-gate if (defopen(AUTH_POLICY) == NULL) { 343*0Sstevel@tonic-gate proflist = defread(DEF_PROF); 344*0Sstevel@tonic-gate (void) defopen(NULL); 345*0Sstevel@tonic-gate } 346*0Sstevel@tonic-gate if (proflist != NULL) { 347*0Sstevel@tonic-gate for (profname = _strtok_escape(proflist, sep, &last); 348*0Sstevel@tonic-gate profname != NULL; 349*0Sstevel@tonic-gate profname = _strtok_escape(NULL, sep, &last)) { 350*0Sstevel@tonic-gate getproflist(profname, profArray, &profcnt); 351*0Sstevel@tonic-gate } 352*0Sstevel@tonic-gate } 353*0Sstevel@tonic-gate 354*0Sstevel@tonic-gate if (profcnt == 0) { 355*0Sstevel@tonic-gate return (head); 356*0Sstevel@tonic-gate } 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gate /* Get execs from the list of profiles */ 359*0Sstevel@tonic-gate for (i = 0; i < profcnt; i++) { 360*0Sstevel@tonic-gate profname = profArray[i]; 361*0Sstevel@tonic-gate if ((exec = getexecprof(profname, type, id, search_flag)) != 362*0Sstevel@tonic-gate NULL) { 363*0Sstevel@tonic-gate if (search_flag == GET_ONE) { 364*0Sstevel@tonic-gate head = exec; 365*0Sstevel@tonic-gate break; 366*0Sstevel@tonic-gate } else if (search_flag == GET_ALL) { 367*0Sstevel@tonic-gate if (head == NULL) { 368*0Sstevel@tonic-gate head = exec; 369*0Sstevel@tonic-gate prev = get_tail(head); 370*0Sstevel@tonic-gate } else { 371*0Sstevel@tonic-gate prev->next = exec; 372*0Sstevel@tonic-gate prev = get_tail(exec); 373*0Sstevel@tonic-gate } 374*0Sstevel@tonic-gate } 375*0Sstevel@tonic-gate } 376*0Sstevel@tonic-gate } 377*0Sstevel@tonic-gate free_proflist(profArray, profcnt); 378*0Sstevel@tonic-gate return (head); 379*0Sstevel@tonic-gate } 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate 382*0Sstevel@tonic-gate static execattr_t * 383*0Sstevel@tonic-gate get_tail(execattr_t *exec) 384*0Sstevel@tonic-gate { 385*0Sstevel@tonic-gate execattr_t *i_exec = (execattr_t *)NULL; 386*0Sstevel@tonic-gate execattr_t *j_exec = (execattr_t *)NULL; 387*0Sstevel@tonic-gate 388*0Sstevel@tonic-gate if (exec != NULL) { 389*0Sstevel@tonic-gate if (exec->next == NULL) { 390*0Sstevel@tonic-gate j_exec = exec; 391*0Sstevel@tonic-gate } else { 392*0Sstevel@tonic-gate for (i_exec = exec->next; i_exec != NULL; 393*0Sstevel@tonic-gate i_exec = i_exec->next) { 394*0Sstevel@tonic-gate j_exec = i_exec; 395*0Sstevel@tonic-gate } 396*0Sstevel@tonic-gate } 397*0Sstevel@tonic-gate } 398*0Sstevel@tonic-gate 399*0Sstevel@tonic-gate return (j_exec); 400*0Sstevel@tonic-gate } 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gate 403*0Sstevel@tonic-gate static execattr_t * 404*0Sstevel@tonic-gate execstr2attr(execstr_t *es) 405*0Sstevel@tonic-gate { 406*0Sstevel@tonic-gate execattr_t *newexec; 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gate if (es == NULL) { 409*0Sstevel@tonic-gate return ((execattr_t *)NULL); 410*0Sstevel@tonic-gate } 411*0Sstevel@tonic-gate if ((newexec = (execattr_t *)malloc(sizeof (execattr_t))) == NULL) { 412*0Sstevel@tonic-gate return ((execattr_t *)NULL); 413*0Sstevel@tonic-gate } 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate newexec->name = _do_unescape(es->name); 416*0Sstevel@tonic-gate newexec->policy = _do_unescape(es->policy); 417*0Sstevel@tonic-gate newexec->type = _do_unescape(es->type); 418*0Sstevel@tonic-gate newexec->res1 = _do_unescape(es->res1); 419*0Sstevel@tonic-gate newexec->res2 = _do_unescape(es->res2); 420*0Sstevel@tonic-gate newexec->id = _do_unescape(es->id); 421*0Sstevel@tonic-gate newexec->attr = _str2kva(es->attr, KV_ASSIGN, KV_DELIMITER); 422*0Sstevel@tonic-gate if (es->next) { 423*0Sstevel@tonic-gate newexec->next = execstr2attr((execstr_t *)(es->next)); 424*0Sstevel@tonic-gate } else { 425*0Sstevel@tonic-gate newexec->next = (execattr_t *)NULL; 426*0Sstevel@tonic-gate } 427*0Sstevel@tonic-gate return (newexec); 428*0Sstevel@tonic-gate } 429*0Sstevel@tonic-gate 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate static execstr_t * 432*0Sstevel@tonic-gate process_getexec( 433*0Sstevel@tonic-gate execstr_t *result, 434*0Sstevel@tonic-gate char *buffer, 435*0Sstevel@tonic-gate int buflen, 436*0Sstevel@tonic-gate nsc_data_t *sptr) 437*0Sstevel@tonic-gate { 438*0Sstevel@tonic-gate char *fixed; 439*0Sstevel@tonic-gate #ifdef _LP64 440*0Sstevel@tonic-gate execstr_t exec64; 441*0Sstevel@tonic-gate 442*0Sstevel@tonic-gate fixed = (char *)(((uintptr_t)buffer + 7) & ~7); 443*0Sstevel@tonic-gate #else 444*0Sstevel@tonic-gate fixed = (char *)(((uintptr_t)buffer + 3) & ~3); 445*0Sstevel@tonic-gate #endif 446*0Sstevel@tonic-gate buflen -= fixed - buffer; 447*0Sstevel@tonic-gate buffer = fixed; 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate if (sptr->nsc_ret.nsc_return_code != SUCCESS) 450*0Sstevel@tonic-gate return ((execstr_t *)NULL); 451*0Sstevel@tonic-gate 452*0Sstevel@tonic-gate #ifdef _LP64 453*0Sstevel@tonic-gate if (sptr->nsc_ret.nsc_bufferbytesused - (int)sizeof (execstr32_t) 454*0Sstevel@tonic-gate > buflen) 455*0Sstevel@tonic-gate #else 456*0Sstevel@tonic-gate if (sptr->nsc_ret.nsc_bufferbytesused - (int)sizeof (execstr_t) 457*0Sstevel@tonic-gate > buflen) 458*0Sstevel@tonic-gate #endif 459*0Sstevel@tonic-gate { 460*0Sstevel@tonic-gate errno = ERANGE; 461*0Sstevel@tonic-gate return ((execstr_t *)NULL); 462*0Sstevel@tonic-gate } 463*0Sstevel@tonic-gate 464*0Sstevel@tonic-gate #ifdef _LP64 465*0Sstevel@tonic-gate (void) memcpy(buffer, (sptr->nsc_ret.nsc_u.buff + sizeof (execstr32_t)), 466*0Sstevel@tonic-gate (sptr->nsc_ret.nsc_bufferbytesused - sizeof (execstr32_t))); 467*0Sstevel@tonic-gate exec64.name = (char *)(sptr->nsc_ret.nsc_u.exec.name + 468*0Sstevel@tonic-gate (uintptr_t)buffer); 469*0Sstevel@tonic-gate exec64.type = (char *)(sptr->nsc_ret.nsc_u.exec.type + 470*0Sstevel@tonic-gate (uintptr_t)buffer); 471*0Sstevel@tonic-gate exec64.policy = (char *)(sptr->nsc_ret.nsc_u.exec.policy + 472*0Sstevel@tonic-gate (uintptr_t)buffer); 473*0Sstevel@tonic-gate exec64.res1 = (char *)(sptr->nsc_ret.nsc_u.exec.res1 + 474*0Sstevel@tonic-gate (uintptr_t)buffer); 475*0Sstevel@tonic-gate exec64.res2 = (char *)(sptr->nsc_ret.nsc_u.exec.res2 + 476*0Sstevel@tonic-gate (uintptr_t)buffer); 477*0Sstevel@tonic-gate exec64.id = (char *)(sptr->nsc_ret.nsc_u.exec.id + 478*0Sstevel@tonic-gate (uintptr_t)buffer); 479*0Sstevel@tonic-gate exec64.attr = (char *)(sptr->nsc_ret.nsc_u.exec.attr + 480*0Sstevel@tonic-gate (uintptr_t)buffer); 481*0Sstevel@tonic-gate exec64.next = (execstr_t *)NULL; 482*0Sstevel@tonic-gate *result = exec64; 483*0Sstevel@tonic-gate #else 484*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.exec.name += (uintptr_t)buffer; 485*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.exec.type += (uintptr_t)buffer; 486*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.exec.policy += (uintptr_t)buffer; 487*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.exec.res1 += (uintptr_t)buffer; 488*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.exec.res2 += (uintptr_t)buffer; 489*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.exec.id += (uintptr_t)buffer; 490*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.exec.attr += (uintptr_t)buffer; 491*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.exec.next = (execstr_t *)NULL; 492*0Sstevel@tonic-gate *result = sptr->nsc_ret.nsc_u.exec; 493*0Sstevel@tonic-gate (void) memcpy(buffer, (sptr->nsc_ret.nsc_u.buff + sizeof (execstr_t)), 494*0Sstevel@tonic-gate (sptr->nsc_ret.nsc_bufferbytesused - sizeof (execstr_t))); 495*0Sstevel@tonic-gate #endif 496*0Sstevel@tonic-gate return (result); 497*0Sstevel@tonic-gate } 498*0Sstevel@tonic-gate 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gate #ifdef DEBUG 501*0Sstevel@tonic-gate void 502*0Sstevel@tonic-gate print_execattr(execattr_t *exec) 503*0Sstevel@tonic-gate { 504*0Sstevel@tonic-gate extern void print_kva(kva_t *); 505*0Sstevel@tonic-gate char *empty = "empty"; 506*0Sstevel@tonic-gate 507*0Sstevel@tonic-gate if (exec != NULL) { 508*0Sstevel@tonic-gate printf("name=%s\n", exec->name ? exec->name : empty); 509*0Sstevel@tonic-gate printf("policy=%s\n", exec->policy ? exec->policy : empty); 510*0Sstevel@tonic-gate printf("type=%s\n", exec->type ? exec->type : empty); 511*0Sstevel@tonic-gate printf("res1=%s\n", exec->res1 ? exec->res1 : empty); 512*0Sstevel@tonic-gate printf("res2=%s\n", exec->res2 ? exec->res2 : empty); 513*0Sstevel@tonic-gate printf("id=%s\n", exec->id ? exec->id : empty); 514*0Sstevel@tonic-gate printf("attr=\n"); 515*0Sstevel@tonic-gate print_kva(exec->attr); 516*0Sstevel@tonic-gate fflush(stdout); 517*0Sstevel@tonic-gate if (exec->next) { 518*0Sstevel@tonic-gate print_execattr(exec->next); 519*0Sstevel@tonic-gate } 520*0Sstevel@tonic-gate } else { 521*0Sstevel@tonic-gate printf("NULL\n"); 522*0Sstevel@tonic-gate } 523*0Sstevel@tonic-gate } 524*0Sstevel@tonic-gate #endif /* DEBUG */ 525