145916cd2Sjpk /* 245916cd2Sjpk * CDDL HEADER START 345916cd2Sjpk * 445916cd2Sjpk * The contents of this file are subject to the terms of the 545916cd2Sjpk * Common Development and Distribution License (the "License"). 645916cd2Sjpk * You may not use this file except in compliance with the License. 745916cd2Sjpk * 845916cd2Sjpk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 945916cd2Sjpk * or http://www.opensolaris.org/os/licensing. 1045916cd2Sjpk * See the License for the specific language governing permissions 1145916cd2Sjpk * and limitations under the License. 1245916cd2Sjpk * 1345916cd2Sjpk * When distributing Covered Code, include this CDDL HEADER in each 1445916cd2Sjpk * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1545916cd2Sjpk * If applicable, add the following below this CDDL HEADER, with the 1645916cd2Sjpk * fields enclosed by brackets "[]" replaced with your own identifying 1745916cd2Sjpk * information: Portions Copyright [yyyy] [name of copyright owner] 1845916cd2Sjpk * 1945916cd2Sjpk * CDDL HEADER END 2045916cd2Sjpk */ 2145916cd2Sjpk /* 2245916cd2Sjpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 2345916cd2Sjpk * Use is subject to license terms. 2445916cd2Sjpk */ 2545916cd2Sjpk 2645916cd2Sjpk #pragma ident "%Z%%M% %I% %E% SMI" 2745916cd2Sjpk 2845916cd2Sjpk #include <string.h> 2945916cd2Sjpk #include <stdlib.h> 3045916cd2Sjpk #include <bsm/devices.h> 3145916cd2Sjpk #include <bsm/devalloc.h> 3245916cd2Sjpk 3345916cd2Sjpk char *strtok_r(char *, const char *, char **); 3445916cd2Sjpk 3545916cd2Sjpk /* externs from getdaent.c */ 3645916cd2Sjpk extern char *trim_white(char *); 3745916cd2Sjpk extern int pack_white(char *); 3845916cd2Sjpk extern char *getdadmfield(char *, char *); 3945916cd2Sjpk extern int getdadmline(char *, int, FILE *); 4045916cd2Sjpk 4145916cd2Sjpk extern char *_strdup_null(char *); 4245916cd2Sjpk 4345916cd2Sjpk static struct _dadefbuff { 4445916cd2Sjpk FILE *_dadeff; 4545916cd2Sjpk /* pointer into /etc/security/tsol/devalloc_defaults */ 4645916cd2Sjpk da_defs_t _interpdadefs; 4745916cd2Sjpk char _interpdadefline[DA_BUFSIZE + 1]; 4845916cd2Sjpk char *_DADEFS; 4945916cd2Sjpk } *__dadefbuff; 5045916cd2Sjpk 5145916cd2Sjpk #define dadeff (_df->_dadeff) 5245916cd2Sjpk #define interpdadefs (_df->_interpdadefs) 5345916cd2Sjpk #define interpdadefline (_df->_interpdadefline) 5445916cd2Sjpk #define DADEFS_FILE (_df->_DADEFS) 5545916cd2Sjpk 5645916cd2Sjpk static da_defs_t *dadef_interpret(char *); 5745916cd2Sjpk int dadef_matchtype(da_defs_t *, char *); 5845916cd2Sjpk 5945916cd2Sjpk /* 6045916cd2Sjpk * _dadefalloc - 6145916cd2Sjpk * allocates common buffers and structures. 6245916cd2Sjpk * returns pointer to the new structure, else returns NULL on error. 6345916cd2Sjpk */ 6445916cd2Sjpk static struct _dadefbuff * 6545916cd2Sjpk _dadefalloc(void) 6645916cd2Sjpk { 6745916cd2Sjpk struct _dadefbuff *_df = __dadefbuff; 6845916cd2Sjpk 6945916cd2Sjpk if (_df == NULL) { 7045916cd2Sjpk _df = (struct _dadefbuff *)calloc((unsigned)1, 7145916cd2Sjpk (unsigned)sizeof (*__dadefbuff)); 7245916cd2Sjpk if (_df == NULL) 7345916cd2Sjpk return (NULL); 7445916cd2Sjpk DADEFS_FILE = "/etc/security/tsol/devalloc_defaults"; 7545916cd2Sjpk __dadefbuff = _df; 7645916cd2Sjpk } 7745916cd2Sjpk 7845916cd2Sjpk return (__dadefbuff); 7945916cd2Sjpk } 8045916cd2Sjpk 8145916cd2Sjpk /* 8245916cd2Sjpk * setdadefent - 8345916cd2Sjpk * rewinds devalloc_defaults file to the begining. 8445916cd2Sjpk */ 8545916cd2Sjpk 8645916cd2Sjpk void 8745916cd2Sjpk setdadefent(void) 8845916cd2Sjpk { 8945916cd2Sjpk struct _dadefbuff *_df = _dadefalloc(); 9045916cd2Sjpk 9145916cd2Sjpk if (_df == NULL) 9245916cd2Sjpk return; 9345916cd2Sjpk if (dadeff == NULL) 94*004388ebScasper dadeff = fopen(DADEFS_FILE, "rF"); 9545916cd2Sjpk else 9645916cd2Sjpk rewind(dadeff); 9745916cd2Sjpk } 9845916cd2Sjpk 9945916cd2Sjpk /* 10045916cd2Sjpk * enddadefent - 10145916cd2Sjpk * closes devalloc_defaults file. 10245916cd2Sjpk */ 10345916cd2Sjpk 10445916cd2Sjpk void 10545916cd2Sjpk enddadefent(void) 10645916cd2Sjpk { 10745916cd2Sjpk struct _dadefbuff *_df = _dadefalloc(); 10845916cd2Sjpk 10945916cd2Sjpk if (_df == NULL) 11045916cd2Sjpk return; 11145916cd2Sjpk if (dadeff != NULL) { 11245916cd2Sjpk (void) fclose(dadeff); 11345916cd2Sjpk dadeff = NULL; 11445916cd2Sjpk } 11545916cd2Sjpk } 11645916cd2Sjpk 11745916cd2Sjpk void 11845916cd2Sjpk freedadefent(da_defs_t *da_def) 11945916cd2Sjpk { 12045916cd2Sjpk if (da_def == NULL) 12145916cd2Sjpk return; 12245916cd2Sjpk _kva_free(da_def->devopts); 12345916cd2Sjpk da_def->devopts = NULL; 12445916cd2Sjpk } 12545916cd2Sjpk 12645916cd2Sjpk /* 12745916cd2Sjpk * getdadefent - 12845916cd2Sjpk * When first called, returns a pointer to the first da_defs_t 12945916cd2Sjpk * structure in devalloc_defaults; thereafter, it returns a pointer to the 13045916cd2Sjpk * next da_defs_t structure in the file. Thus, successive calls can be 13145916cd2Sjpk * used to search the entire file. 13245916cd2Sjpk * call to getdadefent should be bracketed by setdadefent and enddadefent. 13345916cd2Sjpk * returns NULL on error. 13445916cd2Sjpk */ 13545916cd2Sjpk da_defs_t * 13645916cd2Sjpk getdadefent(void) 13745916cd2Sjpk { 13845916cd2Sjpk char line1[DA_BUFSIZE + 1]; 13945916cd2Sjpk da_defs_t *da_def; 14045916cd2Sjpk struct _dadefbuff *_df = _dadefalloc(); 14145916cd2Sjpk 14245916cd2Sjpk if ((_df == 0) || (dadeff == NULL)) 14345916cd2Sjpk return (NULL); 14445916cd2Sjpk 14545916cd2Sjpk while (getdadmline(line1, (int)sizeof (line1), dadeff) != 0) { 14645916cd2Sjpk if ((da_def = dadef_interpret(line1)) == NULL) 14745916cd2Sjpk continue; 14845916cd2Sjpk return (da_def); 14945916cd2Sjpk } 15045916cd2Sjpk 15145916cd2Sjpk return (NULL); 15245916cd2Sjpk } 15345916cd2Sjpk 15445916cd2Sjpk /* 15545916cd2Sjpk * getdadeftype - 15645916cd2Sjpk * searches from the beginning of devalloc_defaults for the device 15745916cd2Sjpk * specified by its type. 15845916cd2Sjpk * call to getdadeftype should be bracketed by setdadefent and enddadefent. 15945916cd2Sjpk * returns pointer to da_defs_t for the device if it is found, else 16045916cd2Sjpk * returns NULL if device not found or in case of error. 16145916cd2Sjpk */ 16245916cd2Sjpk da_defs_t * 16345916cd2Sjpk getdadeftype(char *type) 16445916cd2Sjpk { 16545916cd2Sjpk char line1[DA_BUFSIZE + 1]; 16645916cd2Sjpk da_defs_t *da_def; 16745916cd2Sjpk struct _dadefbuff *_df = _dadefalloc(); 16845916cd2Sjpk 16945916cd2Sjpk if ((type == NULL) || (_df == NULL) || (dadeff == NULL)) 17045916cd2Sjpk return (NULL); 17145916cd2Sjpk 17245916cd2Sjpk while (getdadmline(line1, (int)sizeof (line1), dadeff) != 0) { 17345916cd2Sjpk if (strstr(line1, type) == NULL) 17445916cd2Sjpk continue; 17545916cd2Sjpk if ((da_def = dadef_interpret(line1)) == NULL) 17645916cd2Sjpk continue; 17745916cd2Sjpk if (dadef_matchtype(da_def, type)) 17845916cd2Sjpk return (da_def); 17945916cd2Sjpk freedadefent(da_def); 18045916cd2Sjpk } 18145916cd2Sjpk 18245916cd2Sjpk return (NULL); 18345916cd2Sjpk } 18445916cd2Sjpk 18545916cd2Sjpk /* 18645916cd2Sjpk * dadef_matchtype - 18745916cd2Sjpk * checks if the specified da_defs_t is for the device type specified. 18845916cd2Sjpk * returns 1 if match found, else, returns 0. 18945916cd2Sjpk */ 19045916cd2Sjpk int 19145916cd2Sjpk dadef_matchtype(da_defs_t *da_def, char *type) 19245916cd2Sjpk { 19345916cd2Sjpk if (da_def->devtype == NULL) 19445916cd2Sjpk return (0); 19545916cd2Sjpk 19645916cd2Sjpk return ((strcmp(da_def->devtype, type) == 0)); 19745916cd2Sjpk } 19845916cd2Sjpk 19945916cd2Sjpk /* 20045916cd2Sjpk * dadef_interpret - 20145916cd2Sjpk * parses val and initializes pointers in da_defs_t. 20245916cd2Sjpk * returns pointer to parsed da_defs_t entry, else returns NULL on error. 20345916cd2Sjpk */ 20445916cd2Sjpk static da_defs_t * 20545916cd2Sjpk dadef_interpret(char *val) 20645916cd2Sjpk { 20745916cd2Sjpk struct _dadefbuff *_df = _dadefalloc(); 20845916cd2Sjpk int i; 20945916cd2Sjpk char *opts; 21045916cd2Sjpk kva_t *kvap; 21145916cd2Sjpk kv_t *kvp; 21245916cd2Sjpk 21345916cd2Sjpk if (_df == NULL) 21445916cd2Sjpk return (NULL); 21545916cd2Sjpk 21645916cd2Sjpk (void) strcpy(interpdadefline, val); 21745916cd2Sjpk interpdadefs.devtype = getdadmfield(interpdadefline, KV_TOKEN_DELIMIT); 21845916cd2Sjpk opts = getdadmfield(NULL, KV_TOKEN_DELIMIT); 21945916cd2Sjpk interpdadefs.devopts = NULL; 22045916cd2Sjpk if (interpdadefs.devtype == NULL) 22145916cd2Sjpk return (NULL); 22245916cd2Sjpk if (opts != NULL) 22345916cd2Sjpk interpdadefs.devopts = 22445916cd2Sjpk _str2kva(opts, KV_ASSIGN, KV_DELIMITER); 22545916cd2Sjpk /* remove any extraneous whitespace in the options */ 22645916cd2Sjpk if ((kvap = interpdadefs.devopts) != NULL) { 22745916cd2Sjpk for (i = 0, kvp = kvap->data; i < kvap->length; i++, kvp++) { 22845916cd2Sjpk (void) pack_white(kvp->key); 22945916cd2Sjpk (void) pack_white(kvp->value); 23045916cd2Sjpk } 23145916cd2Sjpk } 23245916cd2Sjpk 23345916cd2Sjpk return (&interpdadefs); 23445916cd2Sjpk } 235