17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * 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.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22d75d0dc9Stz  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
2645916cd2Sjpk #include <ctype.h>
277c478bd9Sstevel@tonic-gate #include <string.h>
2845916cd2Sjpk #include <stdlib.h>
2945916cd2Sjpk #include <tsol/label.h>
307c478bd9Sstevel@tonic-gate #include <bsm/devices.h>
3145916cd2Sjpk #include <bsm/devalloc.h>
327c478bd9Sstevel@tonic-gate 
3345916cd2Sjpk extern char *_strdup_null(char *);
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate static struct _dabuff {
3645916cd2Sjpk 	FILE		*_daf;	/* pointer into /etc/security/device_allocate */
3745916cd2Sjpk 	devalloc_t	_interpdevalloc;
3845916cd2Sjpk 	char		_interpdaline[DA_BUFSIZE + 1];
3945916cd2Sjpk 	char		 *_DEVALLOC;
407c478bd9Sstevel@tonic-gate } *__dabuff;
417c478bd9Sstevel@tonic-gate 
4245916cd2Sjpk #define	daf	(_da->_daf)
4345916cd2Sjpk #define	interpdevalloc	(_da->_interpdevalloc)
4445916cd2Sjpk #define	interpdaline	(_da->_interpdaline)
4545916cd2Sjpk #define	DEVALLOC_FILE	(_da->_DEVALLOC)
4645916cd2Sjpk static devalloc_t	*da_interpret(char *);
4745916cd2Sjpk 
4845916cd2Sjpk int da_matchname(devalloc_t *, char *);
4945916cd2Sjpk int da_matchtype(devalloc_t *, char *);
5045916cd2Sjpk 
5145916cd2Sjpk static int system_labeled = 0;
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate /*
5445916cd2Sjpk  * trim_white -
5545916cd2Sjpk  *	trims off leading and trailing white space from input string.
5645916cd2Sjpk  * 	The leading white space is skipped by moving the pointer forward.
5745916cd2Sjpk  * 	The trailing white space is removed by nulling the white space
5845916cd2Sjpk  *	characters.
5945916cd2Sjpk  *	returns pointer to non-white string, else returns NULL if input string
6045916cd2Sjpk  *	is null or if the resulting string has zero length.
617c478bd9Sstevel@tonic-gate  */
6245916cd2Sjpk char *
trim_white(char * ptr)6345916cd2Sjpk trim_white(char *ptr)
647c478bd9Sstevel@tonic-gate {
6545916cd2Sjpk 	char	*tptr;
6645916cd2Sjpk 
677c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
687c478bd9Sstevel@tonic-gate 		return (NULL);
6945916cd2Sjpk 	while (isspace(*ptr))
707c478bd9Sstevel@tonic-gate 		ptr++;
7145916cd2Sjpk 	tptr = ptr + strlen(ptr);
7245916cd2Sjpk 	while (tptr != ptr && isspace(tptr[-1]))
7345916cd2Sjpk 		--tptr;
7445916cd2Sjpk 	*tptr = '\0';
7545916cd2Sjpk 	if (*ptr == '\0')
767c478bd9Sstevel@tonic-gate 		return (NULL);
7745916cd2Sjpk 
787c478bd9Sstevel@tonic-gate 	return (ptr);
797c478bd9Sstevel@tonic-gate }
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate /*
8245916cd2Sjpk  * pack_white -
8345916cd2Sjpk  *	trims off multiple occurrences of white space from input string.
8445916cd2Sjpk  * 	returns the number of spaces retained
857c478bd9Sstevel@tonic-gate  */
8645916cd2Sjpk int
pack_white(char * ptr)8745916cd2Sjpk pack_white(char *ptr)
887c478bd9Sstevel@tonic-gate {
8945916cd2Sjpk 	int	cnt = 0;
9045916cd2Sjpk 	char	*tptr, ch;
917c478bd9Sstevel@tonic-gate 
9245916cd2Sjpk 	if (ptr == NULL)
9345916cd2Sjpk 		return (0);
9445916cd2Sjpk 	tptr = ptr;
9545916cd2Sjpk 	while (isspace(*tptr))
9645916cd2Sjpk 		tptr++;
9745916cd2Sjpk 	for (;;) {
9845916cd2Sjpk 		while ((ch = *tptr) != '\0' && !isspace(ch)) {
9945916cd2Sjpk 			*ptr++ = ch;
10045916cd2Sjpk 			tptr++;
10145916cd2Sjpk 		}
10245916cd2Sjpk 		while (isspace(*tptr))
10345916cd2Sjpk 			tptr++;
10445916cd2Sjpk 		if (*tptr == '\0')
10545916cd2Sjpk 			break;
10645916cd2Sjpk 		*ptr++ = ' ';
10745916cd2Sjpk 		cnt++;
10845916cd2Sjpk 	}
10945916cd2Sjpk 	*ptr = '\0';
1107c478bd9Sstevel@tonic-gate 
11145916cd2Sjpk 	return (cnt);
1127c478bd9Sstevel@tonic-gate }
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate /*
11545916cd2Sjpk  * getdadmline -
11645916cd2Sjpk  *	reads one device_alloc/device_maps line from stream into buff of len
11745916cd2Sjpk  *	bytes. Continued lines from stream are concatenated into one line in
11845916cd2Sjpk  *	buff. Comments are removed from buff.
11945916cd2Sjpk  *	returns the number of characters in buff, else returns 0 if no
12045916cd2Sjpk  * 	characters are read or an error occurred.
1217c478bd9Sstevel@tonic-gate  */
12245916cd2Sjpk int
getdadmline(char * buff,int len,FILE * stream)12345916cd2Sjpk getdadmline(char *buff, int len, FILE *stream)
1247c478bd9Sstevel@tonic-gate {
12545916cd2Sjpk 	int 	tmpcnt;
12645916cd2Sjpk 	int 	charcnt = 0;
12745916cd2Sjpk 	int 	fileerr = 0;
12845916cd2Sjpk 	int 	contline = 0;
12945916cd2Sjpk 	char 	*cp;
13045916cd2Sjpk 	char 	*ccp;
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 	do {
1337c478bd9Sstevel@tonic-gate 		cp = buff;
134*baf3abb9SToomas Soome 		*cp = '\0';
1357c478bd9Sstevel@tonic-gate 		do {
13645916cd2Sjpk 			contline = 0;
1377c478bd9Sstevel@tonic-gate 			if (fgets(cp, len - charcnt, stream) == NULL) {
1387c478bd9Sstevel@tonic-gate 				fileerr = 1;
1397c478bd9Sstevel@tonic-gate 				break;
1407c478bd9Sstevel@tonic-gate 			}
14145916cd2Sjpk 			ccp = strchr(cp, '\n');
1427c478bd9Sstevel@tonic-gate 			if (ccp != NULL) {
14345916cd2Sjpk 				if (ccp != cp && ccp[-1] == '\\') {
14445916cd2Sjpk 					ccp--;
1457c478bd9Sstevel@tonic-gate 					contline = 1;
14645916cd2Sjpk 				}
14745916cd2Sjpk 				else
1487c478bd9Sstevel@tonic-gate 					contline = 0;
149*baf3abb9SToomas Soome 				*ccp = '\0';
1507c478bd9Sstevel@tonic-gate 			}
1517c478bd9Sstevel@tonic-gate 			tmpcnt = strlen(cp);
15245916cd2Sjpk 			cp += tmpcnt;
15345916cd2Sjpk 			charcnt += tmpcnt;
1547c478bd9Sstevel@tonic-gate 		} while ((contline) || (charcnt == 0));
1557c478bd9Sstevel@tonic-gate 		ccp = strpbrk(buff, "#");
1567c478bd9Sstevel@tonic-gate 		if (ccp != NULL)
157*baf3abb9SToomas Soome 			*ccp = '\0';
1587c478bd9Sstevel@tonic-gate 		charcnt = strlen(buff);
1597c478bd9Sstevel@tonic-gate 	} while ((fileerr == 0) && (charcnt == 0));
16045916cd2Sjpk 
16145916cd2Sjpk 	if (fileerr && !charcnt)
1627c478bd9Sstevel@tonic-gate 		return (0);
16345916cd2Sjpk 	else
1647c478bd9Sstevel@tonic-gate 		return (charcnt);
1657c478bd9Sstevel@tonic-gate }
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate /*
16845916cd2Sjpk  * _daalloc -
16945916cd2Sjpk  *	allocates common buffers and structures.
17045916cd2Sjpk  * 	returns pointer to the new structure, else returns NULL on error.
1717c478bd9Sstevel@tonic-gate  */
17245916cd2Sjpk static struct _dabuff *
_daalloc(void)17345916cd2Sjpk _daalloc(void)
1747c478bd9Sstevel@tonic-gate {
17545916cd2Sjpk 	struct _dabuff	*_da = __dabuff;
1767c478bd9Sstevel@tonic-gate 
17745916cd2Sjpk 	if (_da == NULL) {
17845916cd2Sjpk 		_da = (struct _dabuff *)calloc((unsigned)1,
17945916cd2Sjpk 		    (unsigned)sizeof (*__dabuff));
18045916cd2Sjpk 		if (_da == NULL)
18145916cd2Sjpk 			return (NULL);
18245916cd2Sjpk 		DEVALLOC_FILE = "/etc/security/device_allocate";
18345916cd2Sjpk 		daf = NULL;
18445916cd2Sjpk 		__dabuff = _da;
18545916cd2Sjpk 		system_labeled = is_system_labeled();
1867c478bd9Sstevel@tonic-gate 	}
1877c478bd9Sstevel@tonic-gate 
18845916cd2Sjpk 	return (__dabuff);
18945916cd2Sjpk }
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate /*
19245916cd2Sjpk  * getdadmfield -
19345916cd2Sjpk  *	gets individual fields separated by skip in ptr.
1947c478bd9Sstevel@tonic-gate  */
19545916cd2Sjpk char *
getdadmfield(char * ptr,char * skip)19645916cd2Sjpk getdadmfield(char *ptr, char *skip)
1977c478bd9Sstevel@tonic-gate {
19845916cd2Sjpk 	static char	*tptr = NULL;
19945916cd2Sjpk 	char		*pend;
2007c478bd9Sstevel@tonic-gate 
20145916cd2Sjpk 	/* check for a continuing search */
20245916cd2Sjpk 	if (ptr == NULL)
20345916cd2Sjpk 		ptr = tptr;
20445916cd2Sjpk 	/* check for source end */
20545916cd2Sjpk 	if (ptr == NULL || *ptr == '\0')
20645916cd2Sjpk 		return (NULL);
20745916cd2Sjpk 	/* find terminator */
20845916cd2Sjpk 	pend = strpbrk(ptr, skip);
20945916cd2Sjpk 	/* terminate and set continuation pointer */
21045916cd2Sjpk 	if (pend != NULL) {
21145916cd2Sjpk 		*pend++ = '\0';
21245916cd2Sjpk 		tptr = pend;
21345916cd2Sjpk 	} else
21445916cd2Sjpk 		tptr = NULL;
21545916cd2Sjpk 	/*
21645916cd2Sjpk 	 * trim off any surrounding white space, return what's left
21745916cd2Sjpk 	 */
2187c478bd9Sstevel@tonic-gate 
21945916cd2Sjpk 	return (trim_white(ptr));
22045916cd2Sjpk }
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate /*
22345916cd2Sjpk  * setdaent -
22445916cd2Sjpk  *	rewinds the device_allocate file to the begining.
2257c478bd9Sstevel@tonic-gate  */
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate void
setdaent(void)22845916cd2Sjpk setdaent(void)
2297c478bd9Sstevel@tonic-gate {
23045916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
2317c478bd9Sstevel@tonic-gate 
23245916cd2Sjpk 	if (_da == NULL)
2337c478bd9Sstevel@tonic-gate 		return;
23445916cd2Sjpk 	if (daf == NULL)
235004388ebScasper 		daf = fopen(DEVALLOC_FILE, "rF");
23645916cd2Sjpk 	else
2377c478bd9Sstevel@tonic-gate 		rewind(daf);
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate /*
24145916cd2Sjpk  * enddaent -
24245916cd2Sjpk  *	closes device_allocate file.
2437c478bd9Sstevel@tonic-gate  */
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate void
enddaent(void)24645916cd2Sjpk enddaent(void)
2477c478bd9Sstevel@tonic-gate {
24845916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
2497c478bd9Sstevel@tonic-gate 
25045916cd2Sjpk 	if (_da == NULL)
2517c478bd9Sstevel@tonic-gate 		return;
2527c478bd9Sstevel@tonic-gate 	if (daf != NULL) {
2537c478bd9Sstevel@tonic-gate 		(void) fclose(daf);
2547c478bd9Sstevel@tonic-gate 		daf = NULL;
2557c478bd9Sstevel@tonic-gate 	}
2567c478bd9Sstevel@tonic-gate }
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate /*
25945916cd2Sjpk  * setdafile -
26045916cd2Sjpk  *	changes the default device_allocate file to the one specified.
26145916cd2Sjpk  * 	It does not close the previous file. If this is desired, enddaent
26245916cd2Sjpk  *	should be called prior to setdafile.
2637c478bd9Sstevel@tonic-gate  */
2647c478bd9Sstevel@tonic-gate void
setdafile(char * file)26545916cd2Sjpk setdafile(char *file)
2667c478bd9Sstevel@tonic-gate {
26745916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
2687c478bd9Sstevel@tonic-gate 
26945916cd2Sjpk 	if (_da == NULL)
2707c478bd9Sstevel@tonic-gate 		return;
2717c478bd9Sstevel@tonic-gate 	if (daf != NULL) {
2727c478bd9Sstevel@tonic-gate 		(void) fclose(daf);
2737c478bd9Sstevel@tonic-gate 		daf = NULL;
2747c478bd9Sstevel@tonic-gate 	}
27545916cd2Sjpk 	DEVALLOC_FILE = file;
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate 
27845916cd2Sjpk void
freedaent(devalloc_t * dap)27945916cd2Sjpk freedaent(devalloc_t *dap)
28045916cd2Sjpk {
28145916cd2Sjpk 	if (dap == NULL)
28245916cd2Sjpk 		return;
28345916cd2Sjpk 	_kva_free(dap->da_devopts);
28445916cd2Sjpk 	dap->da_devopts = NULL;
28545916cd2Sjpk }
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate /*
28845916cd2Sjpk  * getdaon -
28945916cd2Sjpk  *	checks if device_allocate has string DEVICE_ALLOCATION=ON or
29045916cd2Sjpk  *	DEVICE_ALLOCATION=OFF string in it.
29145916cd2Sjpk  *	returns 1 if the string is DEVICE_ALLOCATION=ON, 0 if it is
29245916cd2Sjpk  *	DEVICE_ALLOCATION=OFF, -1 if neither string present.
29345916cd2Sjpk  */
29445916cd2Sjpk int
getdaon()29545916cd2Sjpk getdaon()
29645916cd2Sjpk {
29745916cd2Sjpk 	int		is_on = -1;
29845916cd2Sjpk 	char		line1[DA_BUFSIZE + 1];
29945916cd2Sjpk 	struct _dabuff *_da = _daalloc();
30045916cd2Sjpk 
30145916cd2Sjpk 	setdaent();
30245916cd2Sjpk 	if ((_da == NULL) || (daf == NULL)) {
30345916cd2Sjpk 		enddaent();
30445916cd2Sjpk 		return (is_on);
30545916cd2Sjpk 	}
30645916cd2Sjpk 	while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
30745916cd2Sjpk 		if (strncmp(line1, DA_ON_STR, (strlen(DA_ON_STR) - 1)) == 0) {
30845916cd2Sjpk 			is_on = 1;
30945916cd2Sjpk 			break;
31045916cd2Sjpk 		} else if (strncmp(line1, DA_OFF_STR,
31145916cd2Sjpk 		    (strlen(DA_OFF_STR) - 1)) == 0) {
31245916cd2Sjpk 			is_on = 0;
31345916cd2Sjpk 			break;
31445916cd2Sjpk 		}
31545916cd2Sjpk 	}
31645916cd2Sjpk 	enddaent();
31745916cd2Sjpk 
31845916cd2Sjpk 	return (is_on);
31945916cd2Sjpk }
32045916cd2Sjpk 
32145916cd2Sjpk /*
32245916cd2Sjpk  * getdaent -
32345916cd2Sjpk  *	When first called, returns a pointer to the first devalloc_t
32445916cd2Sjpk  * 	structure in device_allocate; thereafter, it returns a pointer to the
32545916cd2Sjpk  *	next devalloc_t structure in the file. Thus, successive calls can be
32645916cd2Sjpk  *	used to search the entire file.
32745916cd2Sjpk  *	call to getdaent should be bracketed by setdaent and enddaent.
32845916cd2Sjpk  *	returns NULL on error.
3297c478bd9Sstevel@tonic-gate  */
3307c478bd9Sstevel@tonic-gate devalloc_t *
getdaent(void)33145916cd2Sjpk getdaent(void)
3327c478bd9Sstevel@tonic-gate {
33345916cd2Sjpk 	char		line1[DA_BUFSIZE + 1];
33445916cd2Sjpk 	devalloc_t	*da;
33545916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
3367c478bd9Sstevel@tonic-gate 
33745916cd2Sjpk 	if ((_da == 0) || (daf == NULL))
3387c478bd9Sstevel@tonic-gate 		return (NULL);
33945916cd2Sjpk 
34045916cd2Sjpk 	while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
34145916cd2Sjpk 		if ((strncmp(line1, DA_ON_STR, (strlen(DA_ON_STR) - 1)) == 0) ||
34245916cd2Sjpk 		    (strncmp(line1, DA_OFF_STR, (strlen(DA_OFF_STR) - 1)) == 0))
34345916cd2Sjpk 			continue;
34445916cd2Sjpk 		if ((da = da_interpret(line1)) == NULL)
34545916cd2Sjpk 			continue;
34645916cd2Sjpk 		return (da);
3477c478bd9Sstevel@tonic-gate 	}
3487c478bd9Sstevel@tonic-gate 
34945916cd2Sjpk 	return (NULL);
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate /*
35345916cd2Sjpk  * getdanam
35445916cd2Sjpk  * 	searches from the beginning of device_allocate for the device specified
35545916cd2Sjpk  * 	by its name.
35645916cd2Sjpk  *	call to getdanam should be bracketed by setdaent and enddaent.
35745916cd2Sjpk  * 	returns pointer to devalloc_t for the device if it is found, else
35845916cd2Sjpk  *	returns NULL if device not found or in case of error.
3597c478bd9Sstevel@tonic-gate  */
3607c478bd9Sstevel@tonic-gate devalloc_t *
getdanam(char * name)36145916cd2Sjpk getdanam(char *name)
3627c478bd9Sstevel@tonic-gate {
36345916cd2Sjpk 	char		line[DA_BUFSIZE + 1];
36445916cd2Sjpk 	devalloc_t	*da;
36545916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
3667c478bd9Sstevel@tonic-gate 
36745916cd2Sjpk 	if ((name == NULL) || (_da == 0) || (daf == NULL))
3687c478bd9Sstevel@tonic-gate 		return (NULL);
36945916cd2Sjpk 
37045916cd2Sjpk 	while (getdadmline(line, (int)sizeof (line), daf) != 0) {
37145916cd2Sjpk 		if (strstr(line, name) == NULL)
37245916cd2Sjpk 			continue;
37345916cd2Sjpk 		if ((da = da_interpret(line)) == NULL)
37445916cd2Sjpk 			continue;
37545916cd2Sjpk 		if (da_matchname(da, name)) {
37645916cd2Sjpk 			enddaent();
37745916cd2Sjpk 			return (da);
37845916cd2Sjpk 		}
37945916cd2Sjpk 		freedaent(da);
3807c478bd9Sstevel@tonic-gate 	}
3817c478bd9Sstevel@tonic-gate 
38245916cd2Sjpk 	return (NULL);
3837c478bd9Sstevel@tonic-gate }
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate /*
38645916cd2Sjpk  * getdatype -
38745916cd2Sjpk  * 	searches from the beginning of device_allocate for the device specified
38845916cd2Sjpk  * 	by its type.
38945916cd2Sjpk  *	call to getdatype should be bracketed by setdaent and enddaent.
39045916cd2Sjpk  * 	returns pointer to devalloc_t for the device if it is found, else
39145916cd2Sjpk  *	returns NULL if device not found or in case of error.
3927c478bd9Sstevel@tonic-gate  */
39345916cd2Sjpk devalloc_t *
getdatype(char * type)39445916cd2Sjpk getdatype(char *type)
3957c478bd9Sstevel@tonic-gate {
39645916cd2Sjpk 	char		line1[DA_BUFSIZE + 1];
39745916cd2Sjpk 	devalloc_t	*da;
39845916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
39945916cd2Sjpk 
40045916cd2Sjpk 	if ((type == NULL) || (_da == NULL) || (daf == NULL))
40145916cd2Sjpk 		return (NULL);
40245916cd2Sjpk 
40345916cd2Sjpk 	while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
40445916cd2Sjpk 		if (strstr(line1, type) == NULL)
40545916cd2Sjpk 			continue;
40645916cd2Sjpk 		if ((da = da_interpret(line1)) == NULL)
4077c478bd9Sstevel@tonic-gate 			continue;
40845916cd2Sjpk 		if (da_matchtype(da, type))
40945916cd2Sjpk 			return (da);
41045916cd2Sjpk 		freedaent(da);
4117c478bd9Sstevel@tonic-gate 	}
41245916cd2Sjpk 
41345916cd2Sjpk 	return (NULL);
4147c478bd9Sstevel@tonic-gate }
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate /*
41745916cd2Sjpk  * da_matchname -
41845916cd2Sjpk  *	checks if the specified devalloc_t is for the device specified.
41945916cd2Sjpk  * 	returns 1 if it is, else returns 0.
4207c478bd9Sstevel@tonic-gate  */
42145916cd2Sjpk int
da_matchname(devalloc_t * dap,char * name)42245916cd2Sjpk da_matchname(devalloc_t *dap, char *name)
4237c478bd9Sstevel@tonic-gate {
42445916cd2Sjpk 	if (dap->da_devname == NULL)
4257c478bd9Sstevel@tonic-gate 		return (0);
42645916cd2Sjpk 
42745916cd2Sjpk 	return ((strcmp(dap->da_devname, name) == 0));
42845916cd2Sjpk }
42945916cd2Sjpk 
43045916cd2Sjpk /*
43145916cd2Sjpk  * da_matchtype -
43245916cd2Sjpk  *	checks if the specified devalloc_t is for the device type specified.
43345916cd2Sjpk  *	returns 1 if match found, else, returns 0.
43445916cd2Sjpk  */
43545916cd2Sjpk int
da_matchtype(devalloc_t * da,char * type)43645916cd2Sjpk da_matchtype(devalloc_t *da, char *type)
43745916cd2Sjpk {
43845916cd2Sjpk 	if (da->da_devtype == NULL)
4397c478bd9Sstevel@tonic-gate 		return (0);
44045916cd2Sjpk 
44145916cd2Sjpk 	return ((strcmp(da->da_devtype, type) == 0));
4427c478bd9Sstevel@tonic-gate }
4437c478bd9Sstevel@tonic-gate 
44445916cd2Sjpk /*
44545916cd2Sjpk  * da_match -
44645916cd2Sjpk  * 	calls da_matchname or da_matchdev as appropriate.
44745916cd2Sjpk  */
44845916cd2Sjpk int
da_match(devalloc_t * dap,da_args * dargs)44945916cd2Sjpk da_match(devalloc_t *dap, da_args *dargs)
45045916cd2Sjpk {
45145916cd2Sjpk 	if (dargs->devinfo->devname)
45245916cd2Sjpk 		return (da_matchname(dap, dargs->devinfo->devname));
45345916cd2Sjpk 	else if (dargs->devinfo->devtype)
45445916cd2Sjpk 		return (da_matchtype(dap, dargs->devinfo->devtype));
45545916cd2Sjpk 
45645916cd2Sjpk 	return (0);
45745916cd2Sjpk }
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate /*
46045916cd2Sjpk  * da_interpret -
46145916cd2Sjpk  *	parses val and initializes pointers in devalloc_t.
46245916cd2Sjpk  * 	returns pointer to parsed devalloc_t entry, else returns NULL on error.
4637c478bd9Sstevel@tonic-gate  */
4647c478bd9Sstevel@tonic-gate static devalloc_t  *
da_interpret(char * val)46545916cd2Sjpk da_interpret(char *val)
4667c478bd9Sstevel@tonic-gate {
46745916cd2Sjpk 	struct _dabuff	*_da = _daalloc();
46845916cd2Sjpk 	char	*opts;
46945916cd2Sjpk 	int	i;
47045916cd2Sjpk 	kva_t	*kvap;
47145916cd2Sjpk 	kv_t	*kvp;
4727c478bd9Sstevel@tonic-gate 
47345916cd2Sjpk 	if (_da == NULL)
47445916cd2Sjpk 		return (NULL);
47545916cd2Sjpk 
47645916cd2Sjpk 	(void) strcpy(interpdaline, val);
47745916cd2Sjpk 	interpdevalloc.da_devname = getdadmfield(interpdaline, KV_DELIMITER);
47845916cd2Sjpk 	interpdevalloc.da_devtype = getdadmfield(NULL, KV_DELIMITER);
47945916cd2Sjpk 	opts = getdadmfield(NULL, KV_DELIMITER);
48045916cd2Sjpk 	(void) getdadmfield(NULL, KV_DELIMITER);	/* reserved field */
48145916cd2Sjpk 	interpdevalloc.da_devauth = getdadmfield(NULL, KV_DELIMITER);
48245916cd2Sjpk 	interpdevalloc.da_devexec = getdadmfield(NULL, KV_DELIMITER);
48345916cd2Sjpk 	interpdevalloc.da_devopts = NULL;
48445916cd2Sjpk 	if (interpdevalloc.da_devname == NULL ||
48545916cd2Sjpk 	    interpdevalloc.da_devtype == NULL)
48645916cd2Sjpk 		return (NULL);
48745916cd2Sjpk 	if ((opts != NULL) &&
48845916cd2Sjpk 	    (strncmp(opts, DA_RESERVED, strlen(DA_RESERVED)) != 0)) {
48945916cd2Sjpk 		interpdevalloc.da_devopts =
49045916cd2Sjpk 		    _str2kva(opts, KV_ASSIGN, KV_TOKEN_DELIMIT);
49145916cd2Sjpk 	}
49245916cd2Sjpk 	/* remove any extraneous whitespace in the options */
49345916cd2Sjpk 	if ((kvap = interpdevalloc.da_devopts) != NULL) {
49445916cd2Sjpk 		for (i = 0, kvp = kvap->data; i < kvap->length; i++, kvp++) {
49545916cd2Sjpk 			(void) pack_white(kvp->key);
49645916cd2Sjpk 			(void) pack_white(kvp->value);
49745916cd2Sjpk 		}
49845916cd2Sjpk 	}
49945916cd2Sjpk 
50045916cd2Sjpk 	if (system_labeled) {
50145916cd2Sjpk 		/* if label range is not defined, use the default range. */
50245916cd2Sjpk 		int		i = 0, nlen = 0;
50345916cd2Sjpk 		char		*minstr = NULL, *maxstr = NULL;
50445916cd2Sjpk 		kva_t		*nkvap = NULL;
50545916cd2Sjpk 		kv_t		*ndata = NULL, *odata = NULL;
50645916cd2Sjpk 
50745916cd2Sjpk 		if (kvap == NULL) {
50845916cd2Sjpk 			nlen = 2;	/* minlabel, maxlabel */
50945916cd2Sjpk 		} else {
51045916cd2Sjpk 			nlen += kvap->length;
51145916cd2Sjpk 			if ((minstr = kva_match(kvap, DAOPT_MINLABEL)) == NULL)
51245916cd2Sjpk 				nlen++;
51345916cd2Sjpk 			if ((maxstr = kva_match(kvap, DAOPT_MAXLABEL)) == NULL)
51445916cd2Sjpk 				nlen++;
51545916cd2Sjpk 		}
51645916cd2Sjpk 		if ((minstr != NULL) && (maxstr != NULL))
51745916cd2Sjpk 			/*
51845916cd2Sjpk 			 * label range provided; we don't need to construct
51945916cd2Sjpk 			 * default range.
52045916cd2Sjpk 			 */
52145916cd2Sjpk 			goto out;
52245916cd2Sjpk 		nkvap = _new_kva(nlen);
52345916cd2Sjpk 		ndata = nkvap->data;
52445916cd2Sjpk 		if (kvap != NULL) {
52545916cd2Sjpk 			for (i = 0; i < kvap->length; i++) {
52645916cd2Sjpk 				odata = kvap->data;
52745916cd2Sjpk 				ndata[i].key = _strdup_null(odata[i].key);
52845916cd2Sjpk 				ndata[i].value = _strdup_null(odata[i].value);
52945916cd2Sjpk 				nkvap->length++;
53045916cd2Sjpk 			}
53145916cd2Sjpk 		}
53245916cd2Sjpk 		if (minstr == NULL) {
53345916cd2Sjpk 			ndata[i].key = strdup(DAOPT_MINLABEL);
53445916cd2Sjpk 			ndata[i].value = strdup(DA_DEFAULT_MIN);
53545916cd2Sjpk 			nkvap->length++;
53645916cd2Sjpk 			i++;
53745916cd2Sjpk 		}
53845916cd2Sjpk 		if (maxstr == NULL) {
53945916cd2Sjpk 			ndata[i].key = strdup(DAOPT_MAXLABEL);
54045916cd2Sjpk 			ndata[i].value = strdup(DA_DEFAULT_MAX);
54145916cd2Sjpk 			nkvap->length++;
54245916cd2Sjpk 		}
54345916cd2Sjpk 		interpdevalloc.da_devopts = nkvap;
54445916cd2Sjpk 	}
5457c478bd9Sstevel@tonic-gate 
54645916cd2Sjpk out:
5477c478bd9Sstevel@tonic-gate 	return (&interpdevalloc);
5487c478bd9Sstevel@tonic-gate }
549