xref: /illumos-gate/usr/src/lib/libbsm/common/getdadefs.c (revision 1da57d551424de5a9d469760be7c4b4d4f10a755)
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 #include <string.h>
2745916cd2Sjpk #include <stdlib.h>
2845916cd2Sjpk #include <bsm/devices.h>
2945916cd2Sjpk #include <bsm/devalloc.h>
3045916cd2Sjpk 
3145916cd2Sjpk char *strtok_r(char *, const char *, char **);
3245916cd2Sjpk 
3345916cd2Sjpk /* externs from getdaent.c */
3445916cd2Sjpk extern char *trim_white(char *);
3545916cd2Sjpk extern int pack_white(char *);
3645916cd2Sjpk extern char *getdadmfield(char *, char *);
3745916cd2Sjpk extern int getdadmline(char *, int, FILE *);
3845916cd2Sjpk 
3945916cd2Sjpk extern char *_strdup_null(char *);
4045916cd2Sjpk 
4145916cd2Sjpk static struct _dadefbuff {
4245916cd2Sjpk 	FILE		*_dadeff;
4345916cd2Sjpk 			/* pointer into /etc/security/tsol/devalloc_defaults */
4445916cd2Sjpk 	da_defs_t	_interpdadefs;
4545916cd2Sjpk 	char		_interpdadefline[DA_BUFSIZE + 1];
4645916cd2Sjpk 	char		 *_DADEFS;
4745916cd2Sjpk } *__dadefbuff;
4845916cd2Sjpk 
4945916cd2Sjpk #define	dadeff		(_df->_dadeff)
5045916cd2Sjpk #define	interpdadefs	(_df->_interpdadefs)
5145916cd2Sjpk #define	interpdadefline	(_df->_interpdadefline)
5245916cd2Sjpk #define	DADEFS_FILE	(_df->_DADEFS)
5345916cd2Sjpk 
5445916cd2Sjpk static da_defs_t	*dadef_interpret(char *);
5545916cd2Sjpk int dadef_matchtype(da_defs_t *, char *);
5645916cd2Sjpk 
5745916cd2Sjpk /*
5845916cd2Sjpk  * _dadefalloc -
5945916cd2Sjpk  *	allocates common buffers and structures.
6045916cd2Sjpk  * 	returns pointer to the new structure, else returns NULL on error.
6145916cd2Sjpk  */
6245916cd2Sjpk static struct _dadefbuff *
_dadefalloc(void)6345916cd2Sjpk _dadefalloc(void)
6445916cd2Sjpk {
6545916cd2Sjpk 	struct _dadefbuff *_df = __dadefbuff;
6645916cd2Sjpk 
6745916cd2Sjpk 	if (_df == NULL) {
6845916cd2Sjpk 		_df = (struct _dadefbuff *)calloc((unsigned)1,
6945916cd2Sjpk 		    (unsigned)sizeof (*__dadefbuff));
7045916cd2Sjpk 		if (_df == NULL)
7145916cd2Sjpk 			return (NULL);
7245916cd2Sjpk 		DADEFS_FILE = "/etc/security/tsol/devalloc_defaults";
7345916cd2Sjpk 		__dadefbuff = _df;
7445916cd2Sjpk 	}
7545916cd2Sjpk 
7645916cd2Sjpk 	return (__dadefbuff);
7745916cd2Sjpk }
7845916cd2Sjpk 
7945916cd2Sjpk /*
8045916cd2Sjpk  * setdadefent -
8145916cd2Sjpk  *	rewinds devalloc_defaults file to the begining.
8245916cd2Sjpk  */
8345916cd2Sjpk 
8445916cd2Sjpk void
setdadefent(void)8545916cd2Sjpk setdadefent(void)
8645916cd2Sjpk {
8745916cd2Sjpk 	struct _dadefbuff *_df = _dadefalloc();
8845916cd2Sjpk 
8945916cd2Sjpk 	if (_df == NULL)
9045916cd2Sjpk 		return;
9145916cd2Sjpk 	if (dadeff == NULL)
92*004388ebScasper 		dadeff = fopen(DADEFS_FILE, "rF");
9345916cd2Sjpk 	else
9445916cd2Sjpk 		rewind(dadeff);
9545916cd2Sjpk }
9645916cd2Sjpk 
9745916cd2Sjpk /*
9845916cd2Sjpk  * enddadefent -
9945916cd2Sjpk  *	closes devalloc_defaults file.
10045916cd2Sjpk  */
10145916cd2Sjpk 
10245916cd2Sjpk void
enddadefent(void)10345916cd2Sjpk enddadefent(void)
10445916cd2Sjpk {
10545916cd2Sjpk 	struct _dadefbuff *_df = _dadefalloc();
10645916cd2Sjpk 
10745916cd2Sjpk 	if (_df == NULL)
10845916cd2Sjpk 		return;
10945916cd2Sjpk 	if (dadeff != NULL) {
11045916cd2Sjpk 		(void) fclose(dadeff);
11145916cd2Sjpk 		dadeff = NULL;
11245916cd2Sjpk 	}
11345916cd2Sjpk }
11445916cd2Sjpk 
11545916cd2Sjpk void
freedadefent(da_defs_t * da_def)11645916cd2Sjpk freedadefent(da_defs_t *da_def)
11745916cd2Sjpk {
11845916cd2Sjpk 	if (da_def == NULL)
11945916cd2Sjpk 		return;
12045916cd2Sjpk 	_kva_free(da_def->devopts);
12145916cd2Sjpk 	da_def->devopts = NULL;
12245916cd2Sjpk }
12345916cd2Sjpk 
12445916cd2Sjpk /*
12545916cd2Sjpk  * getdadefent -
12645916cd2Sjpk  *	When first called, returns a pointer to the first da_defs_t
12745916cd2Sjpk  * 	structure in devalloc_defaults; thereafter, it returns a pointer to the
12845916cd2Sjpk  *	next da_defs_t structure in the file. Thus, successive calls can be
12945916cd2Sjpk  *	used to search the entire file.
13045916cd2Sjpk  *	call to getdadefent should be bracketed by setdadefent and enddadefent.
13145916cd2Sjpk  *	returns NULL on error.
13245916cd2Sjpk  */
13345916cd2Sjpk da_defs_t *
getdadefent(void)13445916cd2Sjpk getdadefent(void)
13545916cd2Sjpk {
13645916cd2Sjpk 	char			line1[DA_BUFSIZE + 1];
13745916cd2Sjpk 	da_defs_t		*da_def;
13845916cd2Sjpk 	struct _dadefbuff	*_df = _dadefalloc();
13945916cd2Sjpk 
14045916cd2Sjpk 	if ((_df == 0) || (dadeff == NULL))
14145916cd2Sjpk 		return (NULL);
14245916cd2Sjpk 
14345916cd2Sjpk 	while (getdadmline(line1, (int)sizeof (line1), dadeff) != 0) {
14445916cd2Sjpk 		if ((da_def = dadef_interpret(line1)) == NULL)
14545916cd2Sjpk 			continue;
14645916cd2Sjpk 		return (da_def);
14745916cd2Sjpk 	}
14845916cd2Sjpk 
14945916cd2Sjpk 	return (NULL);
15045916cd2Sjpk }
15145916cd2Sjpk 
15245916cd2Sjpk /*
15345916cd2Sjpk  * getdadeftype -
15445916cd2Sjpk  * 	searches from the beginning of devalloc_defaults for the device
15545916cd2Sjpk  *	specified by its type.
15645916cd2Sjpk  *	call to getdadeftype should be bracketed by setdadefent and enddadefent.
15745916cd2Sjpk  * 	returns pointer to da_defs_t for the device if it is found, else
15845916cd2Sjpk  *	returns NULL if device not found or in case of error.
15945916cd2Sjpk  */
16045916cd2Sjpk da_defs_t *
getdadeftype(char * type)16145916cd2Sjpk getdadeftype(char *type)
16245916cd2Sjpk {
16345916cd2Sjpk 	char			line1[DA_BUFSIZE + 1];
16445916cd2Sjpk 	da_defs_t		*da_def;
16545916cd2Sjpk 	struct _dadefbuff	*_df = _dadefalloc();
16645916cd2Sjpk 
16745916cd2Sjpk 	if ((type == NULL) || (_df == NULL) || (dadeff == NULL))
16845916cd2Sjpk 		return (NULL);
16945916cd2Sjpk 
17045916cd2Sjpk 	while (getdadmline(line1, (int)sizeof (line1), dadeff) != 0) {
17145916cd2Sjpk 		if (strstr(line1, type) == NULL)
17245916cd2Sjpk 			continue;
17345916cd2Sjpk 		if ((da_def = dadef_interpret(line1)) == NULL)
17445916cd2Sjpk 			continue;
17545916cd2Sjpk 		if (dadef_matchtype(da_def, type))
17645916cd2Sjpk 			return (da_def);
17745916cd2Sjpk 		freedadefent(da_def);
17845916cd2Sjpk 	}
17945916cd2Sjpk 
18045916cd2Sjpk 	return (NULL);
18145916cd2Sjpk }
18245916cd2Sjpk 
18345916cd2Sjpk /*
18445916cd2Sjpk  * dadef_matchtype -
18545916cd2Sjpk  *	checks if the specified da_defs_t is for the device type specified.
18645916cd2Sjpk  *	returns 1 if match found, else, returns 0.
18745916cd2Sjpk  */
18845916cd2Sjpk int
dadef_matchtype(da_defs_t * da_def,char * type)18945916cd2Sjpk dadef_matchtype(da_defs_t *da_def, char *type)
19045916cd2Sjpk {
19145916cd2Sjpk 	if (da_def->devtype == NULL)
19245916cd2Sjpk 		return (0);
19345916cd2Sjpk 
19445916cd2Sjpk 	return ((strcmp(da_def->devtype, type) == 0));
19545916cd2Sjpk }
19645916cd2Sjpk 
19745916cd2Sjpk /*
19845916cd2Sjpk  * dadef_interpret -
19945916cd2Sjpk  *	parses val and initializes pointers in da_defs_t.
20045916cd2Sjpk  * 	returns pointer to parsed da_defs_t entry, else returns NULL on error.
20145916cd2Sjpk  */
20245916cd2Sjpk static da_defs_t  *
dadef_interpret(char * val)20345916cd2Sjpk dadef_interpret(char *val)
20445916cd2Sjpk {
20545916cd2Sjpk 	struct _dadefbuff	*_df = _dadefalloc();
20645916cd2Sjpk 	int			i;
20745916cd2Sjpk 	char			*opts;
20845916cd2Sjpk 	kva_t			*kvap;
20945916cd2Sjpk 	kv_t			*kvp;
21045916cd2Sjpk 
21145916cd2Sjpk 	if (_df == NULL)
21245916cd2Sjpk 		return (NULL);
21345916cd2Sjpk 
21445916cd2Sjpk 	(void) strcpy(interpdadefline, val);
21545916cd2Sjpk 	interpdadefs.devtype = getdadmfield(interpdadefline, KV_TOKEN_DELIMIT);
21645916cd2Sjpk 	opts = getdadmfield(NULL, KV_TOKEN_DELIMIT);
21745916cd2Sjpk 	interpdadefs.devopts = NULL;
21845916cd2Sjpk 	if (interpdadefs.devtype == NULL)
21945916cd2Sjpk 		return (NULL);
22045916cd2Sjpk 	if (opts != NULL)
22145916cd2Sjpk 		interpdadefs.devopts =
22245916cd2Sjpk 		    _str2kva(opts, KV_ASSIGN, KV_DELIMITER);
22345916cd2Sjpk 	/* remove any extraneous whitespace in the options */
22445916cd2Sjpk 	if ((kvap = interpdadefs.devopts) != NULL) {
22545916cd2Sjpk 		for (i = 0, kvp = kvap->data; i < kvap->length; i++, kvp++) {
22645916cd2Sjpk 			(void) pack_white(kvp->key);
22745916cd2Sjpk 			(void) pack_white(kvp->value);
22845916cd2Sjpk 		}
22945916cd2Sjpk 	}
23045916cd2Sjpk 
23145916cd2Sjpk 	return (&interpdadefs);
23245916cd2Sjpk }
233