xref: /onnv-gate/usr/src/lib/libbsm/common/getdadefs.c (revision 1914:8a8c5f225b1b)
11676Sjpk /*
21676Sjpk  * CDDL HEADER START
31676Sjpk  *
41676Sjpk  * The contents of this file are subject to the terms of the
51676Sjpk  * Common Development and Distribution License (the "License").
61676Sjpk  * You may not use this file except in compliance with the License.
71676Sjpk  *
81676Sjpk  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91676Sjpk  * or http://www.opensolaris.org/os/licensing.
101676Sjpk  * See the License for the specific language governing permissions
111676Sjpk  * and limitations under the License.
121676Sjpk  *
131676Sjpk  * When distributing Covered Code, include this CDDL HEADER in each
141676Sjpk  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151676Sjpk  * If applicable, add the following below this CDDL HEADER, with the
161676Sjpk  * fields enclosed by brackets "[]" replaced with your own identifying
171676Sjpk  * information: Portions Copyright [yyyy] [name of copyright owner]
181676Sjpk  *
191676Sjpk  * CDDL HEADER END
201676Sjpk  */
211676Sjpk /*
221676Sjpk  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
231676Sjpk  * Use is subject to license terms.
241676Sjpk  */
251676Sjpk 
261676Sjpk #pragma ident	"%Z%%M%	%I%	%E% SMI"
271676Sjpk 
281676Sjpk #include <string.h>
291676Sjpk #include <stdlib.h>
301676Sjpk #include <bsm/devices.h>
311676Sjpk #include <bsm/devalloc.h>
321676Sjpk 
331676Sjpk char *strtok_r(char *, const char *, char **);
341676Sjpk 
351676Sjpk /* externs from getdaent.c */
361676Sjpk extern char *trim_white(char *);
371676Sjpk extern int pack_white(char *);
381676Sjpk extern char *getdadmfield(char *, char *);
391676Sjpk extern int getdadmline(char *, int, FILE *);
401676Sjpk 
411676Sjpk extern char *_strdup_null(char *);
421676Sjpk 
431676Sjpk static struct _dadefbuff {
441676Sjpk 	FILE		*_dadeff;
451676Sjpk 			/* pointer into /etc/security/tsol/devalloc_defaults */
461676Sjpk 	da_defs_t	_interpdadefs;
471676Sjpk 	char		_interpdadefline[DA_BUFSIZE + 1];
481676Sjpk 	char		 *_DADEFS;
491676Sjpk } *__dadefbuff;
501676Sjpk 
511676Sjpk #define	dadeff		(_df->_dadeff)
521676Sjpk #define	interpdadefs	(_df->_interpdadefs)
531676Sjpk #define	interpdadefline	(_df->_interpdadefline)
541676Sjpk #define	DADEFS_FILE	(_df->_DADEFS)
551676Sjpk 
561676Sjpk static da_defs_t	*dadef_interpret(char *);
571676Sjpk int dadef_matchtype(da_defs_t *, char *);
581676Sjpk 
591676Sjpk /*
601676Sjpk  * _dadefalloc -
611676Sjpk  *	allocates common buffers and structures.
621676Sjpk  * 	returns pointer to the new structure, else returns NULL on error.
631676Sjpk  */
641676Sjpk static struct _dadefbuff *
_dadefalloc(void)651676Sjpk _dadefalloc(void)
661676Sjpk {
671676Sjpk 	struct _dadefbuff *_df = __dadefbuff;
681676Sjpk 
691676Sjpk 	if (_df == NULL) {
701676Sjpk 		_df = (struct _dadefbuff *)calloc((unsigned)1,
711676Sjpk 		    (unsigned)sizeof (*__dadefbuff));
721676Sjpk 		if (_df == NULL)
731676Sjpk 			return (NULL);
741676Sjpk 		DADEFS_FILE = "/etc/security/tsol/devalloc_defaults";
751676Sjpk 		__dadefbuff = _df;
761676Sjpk 	}
771676Sjpk 
781676Sjpk 	return (__dadefbuff);
791676Sjpk }
801676Sjpk 
811676Sjpk /*
821676Sjpk  * setdadefent -
831676Sjpk  *	rewinds devalloc_defaults file to the begining.
841676Sjpk  */
851676Sjpk 
861676Sjpk void
setdadefent(void)871676Sjpk setdadefent(void)
881676Sjpk {
891676Sjpk 	struct _dadefbuff *_df = _dadefalloc();
901676Sjpk 
911676Sjpk 	if (_df == NULL)
921676Sjpk 		return;
931676Sjpk 	if (dadeff == NULL)
94*1914Scasper 		dadeff = fopen(DADEFS_FILE, "rF");
951676Sjpk 	else
961676Sjpk 		rewind(dadeff);
971676Sjpk }
981676Sjpk 
991676Sjpk /*
1001676Sjpk  * enddadefent -
1011676Sjpk  *	closes devalloc_defaults file.
1021676Sjpk  */
1031676Sjpk 
1041676Sjpk void
enddadefent(void)1051676Sjpk enddadefent(void)
1061676Sjpk {
1071676Sjpk 	struct _dadefbuff *_df = _dadefalloc();
1081676Sjpk 
1091676Sjpk 	if (_df == NULL)
1101676Sjpk 		return;
1111676Sjpk 	if (dadeff != NULL) {
1121676Sjpk 		(void) fclose(dadeff);
1131676Sjpk 		dadeff = NULL;
1141676Sjpk 	}
1151676Sjpk }
1161676Sjpk 
1171676Sjpk void
freedadefent(da_defs_t * da_def)1181676Sjpk freedadefent(da_defs_t *da_def)
1191676Sjpk {
1201676Sjpk 	if (da_def == NULL)
1211676Sjpk 		return;
1221676Sjpk 	_kva_free(da_def->devopts);
1231676Sjpk 	da_def->devopts = NULL;
1241676Sjpk }
1251676Sjpk 
1261676Sjpk /*
1271676Sjpk  * getdadefent -
1281676Sjpk  *	When first called, returns a pointer to the first da_defs_t
1291676Sjpk  * 	structure in devalloc_defaults; thereafter, it returns a pointer to the
1301676Sjpk  *	next da_defs_t structure in the file. Thus, successive calls can be
1311676Sjpk  *	used to search the entire file.
1321676Sjpk  *	call to getdadefent should be bracketed by setdadefent and enddadefent.
1331676Sjpk  *	returns NULL on error.
1341676Sjpk  */
1351676Sjpk da_defs_t *
getdadefent(void)1361676Sjpk getdadefent(void)
1371676Sjpk {
1381676Sjpk 	char			line1[DA_BUFSIZE + 1];
1391676Sjpk 	da_defs_t		*da_def;
1401676Sjpk 	struct _dadefbuff	*_df = _dadefalloc();
1411676Sjpk 
1421676Sjpk 	if ((_df == 0) || (dadeff == NULL))
1431676Sjpk 		return (NULL);
1441676Sjpk 
1451676Sjpk 	while (getdadmline(line1, (int)sizeof (line1), dadeff) != 0) {
1461676Sjpk 		if ((da_def = dadef_interpret(line1)) == NULL)
1471676Sjpk 			continue;
1481676Sjpk 		return (da_def);
1491676Sjpk 	}
1501676Sjpk 
1511676Sjpk 	return (NULL);
1521676Sjpk }
1531676Sjpk 
1541676Sjpk /*
1551676Sjpk  * getdadeftype -
1561676Sjpk  * 	searches from the beginning of devalloc_defaults for the device
1571676Sjpk  *	specified by its type.
1581676Sjpk  *	call to getdadeftype should be bracketed by setdadefent and enddadefent.
1591676Sjpk  * 	returns pointer to da_defs_t for the device if it is found, else
1601676Sjpk  *	returns NULL if device not found or in case of error.
1611676Sjpk  */
1621676Sjpk da_defs_t *
getdadeftype(char * type)1631676Sjpk getdadeftype(char *type)
1641676Sjpk {
1651676Sjpk 	char			line1[DA_BUFSIZE + 1];
1661676Sjpk 	da_defs_t		*da_def;
1671676Sjpk 	struct _dadefbuff	*_df = _dadefalloc();
1681676Sjpk 
1691676Sjpk 	if ((type == NULL) || (_df == NULL) || (dadeff == NULL))
1701676Sjpk 		return (NULL);
1711676Sjpk 
1721676Sjpk 	while (getdadmline(line1, (int)sizeof (line1), dadeff) != 0) {
1731676Sjpk 		if (strstr(line1, type) == NULL)
1741676Sjpk 			continue;
1751676Sjpk 		if ((da_def = dadef_interpret(line1)) == NULL)
1761676Sjpk 			continue;
1771676Sjpk 		if (dadef_matchtype(da_def, type))
1781676Sjpk 			return (da_def);
1791676Sjpk 		freedadefent(da_def);
1801676Sjpk 	}
1811676Sjpk 
1821676Sjpk 	return (NULL);
1831676Sjpk }
1841676Sjpk 
1851676Sjpk /*
1861676Sjpk  * dadef_matchtype -
1871676Sjpk  *	checks if the specified da_defs_t is for the device type specified.
1881676Sjpk  *	returns 1 if match found, else, returns 0.
1891676Sjpk  */
1901676Sjpk int
dadef_matchtype(da_defs_t * da_def,char * type)1911676Sjpk dadef_matchtype(da_defs_t *da_def, char *type)
1921676Sjpk {
1931676Sjpk 	if (da_def->devtype == NULL)
1941676Sjpk 		return (0);
1951676Sjpk 
1961676Sjpk 	return ((strcmp(da_def->devtype, type) == 0));
1971676Sjpk }
1981676Sjpk 
1991676Sjpk /*
2001676Sjpk  * dadef_interpret -
2011676Sjpk  *	parses val and initializes pointers in da_defs_t.
2021676Sjpk  * 	returns pointer to parsed da_defs_t entry, else returns NULL on error.
2031676Sjpk  */
2041676Sjpk static da_defs_t  *
dadef_interpret(char * val)2051676Sjpk dadef_interpret(char *val)
2061676Sjpk {
2071676Sjpk 	struct _dadefbuff	*_df = _dadefalloc();
2081676Sjpk 	int			i;
2091676Sjpk 	char			*opts;
2101676Sjpk 	kva_t			*kvap;
2111676Sjpk 	kv_t			*kvp;
2121676Sjpk 
2131676Sjpk 	if (_df == NULL)
2141676Sjpk 		return (NULL);
2151676Sjpk 
2161676Sjpk 	(void) strcpy(interpdadefline, val);
2171676Sjpk 	interpdadefs.devtype = getdadmfield(interpdadefline, KV_TOKEN_DELIMIT);
2181676Sjpk 	opts = getdadmfield(NULL, KV_TOKEN_DELIMIT);
2191676Sjpk 	interpdadefs.devopts = NULL;
2201676Sjpk 	if (interpdadefs.devtype == NULL)
2211676Sjpk 		return (NULL);
2221676Sjpk 	if (opts != NULL)
2231676Sjpk 		interpdadefs.devopts =
2241676Sjpk 		    _str2kva(opts, KV_ASSIGN, KV_DELIMITER);
2251676Sjpk 	/* remove any extraneous whitespace in the options */
2261676Sjpk 	if ((kvap = interpdadefs.devopts) != NULL) {
2271676Sjpk 		for (i = 0, kvp = kvap->data; i < kvap->length; i++, kvp++) {
2281676Sjpk 			(void) pack_white(kvp->key);
2291676Sjpk 			(void) pack_white(kvp->value);
2301676Sjpk 		}
2311676Sjpk 	}
2321676Sjpk 
2331676Sjpk 	return (&interpdadefs);
2341676Sjpk }
235