1*45916cd2Sjpk /* 2*45916cd2Sjpk * CDDL HEADER START 3*45916cd2Sjpk * 4*45916cd2Sjpk * The contents of this file are subject to the terms of the 5*45916cd2Sjpk * Common Development and Distribution License (the "License"). 6*45916cd2Sjpk * You may not use this file except in compliance with the License. 7*45916cd2Sjpk * 8*45916cd2Sjpk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*45916cd2Sjpk * or http://www.opensolaris.org/os/licensing. 10*45916cd2Sjpk * See the License for the specific language governing permissions 11*45916cd2Sjpk * and limitations under the License. 12*45916cd2Sjpk * 13*45916cd2Sjpk * When distributing Covered Code, include this CDDL HEADER in each 14*45916cd2Sjpk * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*45916cd2Sjpk * If applicable, add the following below this CDDL HEADER, with the 16*45916cd2Sjpk * fields enclosed by brackets "[]" replaced with your own identifying 17*45916cd2Sjpk * information: Portions Copyright [yyyy] [name of copyright owner] 18*45916cd2Sjpk * 19*45916cd2Sjpk * CDDL HEADER END 20*45916cd2Sjpk */ 21*45916cd2Sjpk /* 22*45916cd2Sjpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*45916cd2Sjpk * Use is subject to license terms. 24*45916cd2Sjpk */ 25*45916cd2Sjpk 26*45916cd2Sjpk #pragma ident "%Z%%M% %I% %E% SMI" 27*45916cd2Sjpk 28*45916cd2Sjpk #include <string.h> 29*45916cd2Sjpk #include <stdlib.h> 30*45916cd2Sjpk #include <bsm/devices.h> 31*45916cd2Sjpk #include <bsm/devalloc.h> 32*45916cd2Sjpk 33*45916cd2Sjpk char *strtok_r(char *, const char *, char **); 34*45916cd2Sjpk 35*45916cd2Sjpk /* externs from getdaent.c */ 36*45916cd2Sjpk extern char *trim_white(char *); 37*45916cd2Sjpk extern int pack_white(char *); 38*45916cd2Sjpk extern char *getdadmfield(char *, char *); 39*45916cd2Sjpk extern int getdadmline(char *, int, FILE *); 40*45916cd2Sjpk 41*45916cd2Sjpk extern char *_strdup_null(char *); 42*45916cd2Sjpk 43*45916cd2Sjpk static struct _dadefbuff { 44*45916cd2Sjpk FILE *_dadeff; 45*45916cd2Sjpk /* pointer into /etc/security/tsol/devalloc_defaults */ 46*45916cd2Sjpk da_defs_t _interpdadefs; 47*45916cd2Sjpk char _interpdadefline[DA_BUFSIZE + 1]; 48*45916cd2Sjpk char *_DADEFS; 49*45916cd2Sjpk } *__dadefbuff; 50*45916cd2Sjpk 51*45916cd2Sjpk #define dadeff (_df->_dadeff) 52*45916cd2Sjpk #define interpdadefs (_df->_interpdadefs) 53*45916cd2Sjpk #define interpdadefline (_df->_interpdadefline) 54*45916cd2Sjpk #define DADEFS_FILE (_df->_DADEFS) 55*45916cd2Sjpk 56*45916cd2Sjpk static da_defs_t *dadef_interpret(char *); 57*45916cd2Sjpk int dadef_matchtype(da_defs_t *, char *); 58*45916cd2Sjpk 59*45916cd2Sjpk /* 60*45916cd2Sjpk * _dadefalloc - 61*45916cd2Sjpk * allocates common buffers and structures. 62*45916cd2Sjpk * returns pointer to the new structure, else returns NULL on error. 63*45916cd2Sjpk */ 64*45916cd2Sjpk static struct _dadefbuff * 65*45916cd2Sjpk _dadefalloc(void) 66*45916cd2Sjpk { 67*45916cd2Sjpk struct _dadefbuff *_df = __dadefbuff; 68*45916cd2Sjpk 69*45916cd2Sjpk if (_df == NULL) { 70*45916cd2Sjpk _df = (struct _dadefbuff *)calloc((unsigned)1, 71*45916cd2Sjpk (unsigned)sizeof (*__dadefbuff)); 72*45916cd2Sjpk if (_df == NULL) 73*45916cd2Sjpk return (NULL); 74*45916cd2Sjpk DADEFS_FILE = "/etc/security/tsol/devalloc_defaults"; 75*45916cd2Sjpk __dadefbuff = _df; 76*45916cd2Sjpk } 77*45916cd2Sjpk 78*45916cd2Sjpk return (__dadefbuff); 79*45916cd2Sjpk } 80*45916cd2Sjpk 81*45916cd2Sjpk /* 82*45916cd2Sjpk * setdadefent - 83*45916cd2Sjpk * rewinds devalloc_defaults file to the begining. 84*45916cd2Sjpk */ 85*45916cd2Sjpk 86*45916cd2Sjpk void 87*45916cd2Sjpk setdadefent(void) 88*45916cd2Sjpk { 89*45916cd2Sjpk struct _dadefbuff *_df = _dadefalloc(); 90*45916cd2Sjpk 91*45916cd2Sjpk if (_df == NULL) 92*45916cd2Sjpk return; 93*45916cd2Sjpk if (dadeff == NULL) 94*45916cd2Sjpk dadeff = fopen(DADEFS_FILE, "r"); 95*45916cd2Sjpk else 96*45916cd2Sjpk rewind(dadeff); 97*45916cd2Sjpk } 98*45916cd2Sjpk 99*45916cd2Sjpk /* 100*45916cd2Sjpk * enddadefent - 101*45916cd2Sjpk * closes devalloc_defaults file. 102*45916cd2Sjpk */ 103*45916cd2Sjpk 104*45916cd2Sjpk void 105*45916cd2Sjpk enddadefent(void) 106*45916cd2Sjpk { 107*45916cd2Sjpk struct _dadefbuff *_df = _dadefalloc(); 108*45916cd2Sjpk 109*45916cd2Sjpk if (_df == NULL) 110*45916cd2Sjpk return; 111*45916cd2Sjpk if (dadeff != NULL) { 112*45916cd2Sjpk (void) fclose(dadeff); 113*45916cd2Sjpk dadeff = NULL; 114*45916cd2Sjpk } 115*45916cd2Sjpk } 116*45916cd2Sjpk 117*45916cd2Sjpk void 118*45916cd2Sjpk freedadefent(da_defs_t *da_def) 119*45916cd2Sjpk { 120*45916cd2Sjpk if (da_def == NULL) 121*45916cd2Sjpk return; 122*45916cd2Sjpk _kva_free(da_def->devopts); 123*45916cd2Sjpk da_def->devopts = NULL; 124*45916cd2Sjpk } 125*45916cd2Sjpk 126*45916cd2Sjpk /* 127*45916cd2Sjpk * getdadefent - 128*45916cd2Sjpk * When first called, returns a pointer to the first da_defs_t 129*45916cd2Sjpk * structure in devalloc_defaults; thereafter, it returns a pointer to the 130*45916cd2Sjpk * next da_defs_t structure in the file. Thus, successive calls can be 131*45916cd2Sjpk * used to search the entire file. 132*45916cd2Sjpk * call to getdadefent should be bracketed by setdadefent and enddadefent. 133*45916cd2Sjpk * returns NULL on error. 134*45916cd2Sjpk */ 135*45916cd2Sjpk da_defs_t * 136*45916cd2Sjpk getdadefent(void) 137*45916cd2Sjpk { 138*45916cd2Sjpk char line1[DA_BUFSIZE + 1]; 139*45916cd2Sjpk da_defs_t *da_def; 140*45916cd2Sjpk struct _dadefbuff *_df = _dadefalloc(); 141*45916cd2Sjpk 142*45916cd2Sjpk if ((_df == 0) || (dadeff == NULL)) 143*45916cd2Sjpk return (NULL); 144*45916cd2Sjpk 145*45916cd2Sjpk while (getdadmline(line1, (int)sizeof (line1), dadeff) != 0) { 146*45916cd2Sjpk if ((da_def = dadef_interpret(line1)) == NULL) 147*45916cd2Sjpk continue; 148*45916cd2Sjpk return (da_def); 149*45916cd2Sjpk } 150*45916cd2Sjpk 151*45916cd2Sjpk return (NULL); 152*45916cd2Sjpk } 153*45916cd2Sjpk 154*45916cd2Sjpk /* 155*45916cd2Sjpk * getdadeftype - 156*45916cd2Sjpk * searches from the beginning of devalloc_defaults for the device 157*45916cd2Sjpk * specified by its type. 158*45916cd2Sjpk * call to getdadeftype should be bracketed by setdadefent and enddadefent. 159*45916cd2Sjpk * returns pointer to da_defs_t for the device if it is found, else 160*45916cd2Sjpk * returns NULL if device not found or in case of error. 161*45916cd2Sjpk */ 162*45916cd2Sjpk da_defs_t * 163*45916cd2Sjpk getdadeftype(char *type) 164*45916cd2Sjpk { 165*45916cd2Sjpk char line1[DA_BUFSIZE + 1]; 166*45916cd2Sjpk da_defs_t *da_def; 167*45916cd2Sjpk struct _dadefbuff *_df = _dadefalloc(); 168*45916cd2Sjpk 169*45916cd2Sjpk if ((type == NULL) || (_df == NULL) || (dadeff == NULL)) 170*45916cd2Sjpk return (NULL); 171*45916cd2Sjpk 172*45916cd2Sjpk while (getdadmline(line1, (int)sizeof (line1), dadeff) != 0) { 173*45916cd2Sjpk if (strstr(line1, type) == NULL) 174*45916cd2Sjpk continue; 175*45916cd2Sjpk if ((da_def = dadef_interpret(line1)) == NULL) 176*45916cd2Sjpk continue; 177*45916cd2Sjpk if (dadef_matchtype(da_def, type)) 178*45916cd2Sjpk return (da_def); 179*45916cd2Sjpk freedadefent(da_def); 180*45916cd2Sjpk } 181*45916cd2Sjpk 182*45916cd2Sjpk return (NULL); 183*45916cd2Sjpk } 184*45916cd2Sjpk 185*45916cd2Sjpk /* 186*45916cd2Sjpk * dadef_matchtype - 187*45916cd2Sjpk * checks if the specified da_defs_t is for the device type specified. 188*45916cd2Sjpk * returns 1 if match found, else, returns 0. 189*45916cd2Sjpk */ 190*45916cd2Sjpk int 191*45916cd2Sjpk dadef_matchtype(da_defs_t *da_def, char *type) 192*45916cd2Sjpk { 193*45916cd2Sjpk if (da_def->devtype == NULL) 194*45916cd2Sjpk return (0); 195*45916cd2Sjpk 196*45916cd2Sjpk return ((strcmp(da_def->devtype, type) == 0)); 197*45916cd2Sjpk } 198*45916cd2Sjpk 199*45916cd2Sjpk /* 200*45916cd2Sjpk * dadef_interpret - 201*45916cd2Sjpk * parses val and initializes pointers in da_defs_t. 202*45916cd2Sjpk * returns pointer to parsed da_defs_t entry, else returns NULL on error. 203*45916cd2Sjpk */ 204*45916cd2Sjpk static da_defs_t * 205*45916cd2Sjpk dadef_interpret(char *val) 206*45916cd2Sjpk { 207*45916cd2Sjpk struct _dadefbuff *_df = _dadefalloc(); 208*45916cd2Sjpk int i; 209*45916cd2Sjpk char *opts; 210*45916cd2Sjpk kva_t *kvap; 211*45916cd2Sjpk kv_t *kvp; 212*45916cd2Sjpk 213*45916cd2Sjpk if (_df == NULL) 214*45916cd2Sjpk return (NULL); 215*45916cd2Sjpk 216*45916cd2Sjpk (void) strcpy(interpdadefline, val); 217*45916cd2Sjpk interpdadefs.devtype = getdadmfield(interpdadefline, KV_TOKEN_DELIMIT); 218*45916cd2Sjpk opts = getdadmfield(NULL, KV_TOKEN_DELIMIT); 219*45916cd2Sjpk interpdadefs.devopts = NULL; 220*45916cd2Sjpk if (interpdadefs.devtype == NULL) 221*45916cd2Sjpk return (NULL); 222*45916cd2Sjpk if (opts != NULL) 223*45916cd2Sjpk interpdadefs.devopts = 224*45916cd2Sjpk _str2kva(opts, KV_ASSIGN, KV_DELIMITER); 225*45916cd2Sjpk /* remove any extraneous whitespace in the options */ 226*45916cd2Sjpk if ((kvap = interpdadefs.devopts) != NULL) { 227*45916cd2Sjpk for (i = 0, kvp = kvap->data; i < kvap->length; i++, kvp++) { 228*45916cd2Sjpk (void) pack_white(kvp->key); 229*45916cd2Sjpk (void) pack_white(kvp->value); 230*45916cd2Sjpk } 231*45916cd2Sjpk } 232*45916cd2Sjpk 233*45916cd2Sjpk return (&interpdadefs); 234*45916cd2Sjpk } 235