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