OpenSolaris_b135/lib/libbsm/common/getdevicerange.c

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <stdlib.h>
#include <errno.h>
#include <tsol/label.h>
#include <bsm/devices.h>


/*
 * getdevicerange
 *	Gets the minimum and maximum labels within which the device can
 *	be used. If label range is not specified for the device in
 *	device_allocate, defaults to admin_low and admin_high.
 *	Returns malloc'ed blrange pointer, or NULL on any error.
 */
blrange_t *
getdevicerange(const char *dev)
{
	int		err;
	char		*lstr;
	devalloc_t	*da;
	devmap_t	*dm;
	blrange_t	*range;

	errno = 0;
	if ((range = malloc(sizeof (blrange_t))) == NULL)
		return (NULL);
	if ((range->lower_bound = blabel_alloc()) == NULL) {
		free(range);
		return (NULL);
	}
	if ((range->upper_bound = blabel_alloc()) == NULL) {
		blabel_free(range->lower_bound);
		free(range);
		return (NULL);
	}

	/*
	 * If an entry is found for the named device,
	 * return its label range.
	 */
	setdaent();
	if ((da = getdanam((char *)dev)) == NULL) {
		setdmapent();
		/* check for an actual device file */
		if ((dm = getdmapdev((char *)dev)) != NULL) {
			da = getdanam(dm->dmap_devname);
			freedmapent(dm);
		}
		enddmapent();
	}
	enddaent();
	if (da == NULL) {
		bsllow(range->lower_bound);
		bslhigh(range->upper_bound);
	} else {
		lstr = kva_match(da->da_devopts, DAOPT_MINLABEL);
		if (lstr == NULL) {
			bsllow(range->lower_bound);
		} else if (stobsl(lstr, range->lower_bound, NO_CORRECTION,
		    &err) == 0) {
			blabel_free(range->lower_bound);
			blabel_free(range->upper_bound);
			free(range);
			errno = ENOTSUP;
			return (NULL);
		}
		lstr = kva_match(da->da_devopts, DAOPT_MAXLABEL);
		if (lstr == NULL) {
			bslhigh(range->upper_bound);
		} else if (stobsl(lstr, range->upper_bound, NO_CORRECTION,
		    &err) == 0) {
			blabel_free(range->lower_bound);
			blabel_free(range->upper_bound);
			free(range);
			errno = ENOTSUP;
			return (NULL);
		}
		freedaent(da);
	}

	return (range);
}