changeset 7909:014da53c34aa default tip

[PATCH v2] Default Contexts This patch introduces default context support.
author John Weeks <john.weeks@sun.com>
date Thu, 07 May 2009 13:13:23 -0700
parents e46c729cc0ef
children
files usr/src/cmd/fmac/Makefile usr/src/cmd/fmac/etc/Makefile usr/src/cmd/fmac/etc/contexts/Makefile usr/src/cmd/fmac/etc/contexts/default_contexts usr/src/cmd/fmac/etc/contexts/default_type usr/src/cmd/fmac/etc/contexts/failsafe_context usr/src/cmd/fmac/etc/contexts/users/Makefile usr/src/cmd/fmac/etc/contexts/users/sysadm_u usr/src/cmd/fmac/etc/contexts/users/user_u usr/src/cmd/fmac/etc/default_user usr/src/cmd/fmac/newrole/newrole.c usr/src/cmd/fmac/policy/users usr/src/common/fmac/policy/flask/access_vectors usr/src/common/fmac/ss/services.c usr/src/head/fmac/fmac.h usr/src/lib/libc/amd64/Makefile usr/src/lib/libc/i386/Makefile.com usr/src/lib/libc/inc/fmac_private.h usr/src/lib/libc/port/gen/fmac_config.c usr/src/lib/libc/port/gen/freecon.c usr/src/lib/libc/port/gen/freeconary.c usr/src/lib/libc/port/gen/get_context_list.c usr/src/lib/libc/port/gen/get_default_type.c usr/src/lib/libc/port/gen/getfmacuserbyname.c usr/src/lib/libc/port/gen/security_compute_user.c usr/src/lib/libc/port/mapfile-vers usr/src/lib/libc/port/sys/fmacsys.c usr/src/lib/libc/sparc/Makefile usr/src/lib/libc/sparcv9/Makefile usr/src/lib/libsecdb/user_attr.txt usr/src/lib/pam_modules/unix_cred/unix_cred.c usr/src/pkgdefs/SUNWcsr/prototype_com usr/src/uts/common/sys/fmac/fmac.h usr/src/uts/common/sys/fmac/security.h usr/src/uts/common/syscall/fmacsys.c
diffstat 35 files changed, 2111 insertions(+), 105 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/fmac/Makefile	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/cmd/fmac/Makefile	Thu May 07 13:13:23 2009 -0700
@@ -20,7 +20,7 @@
 #
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #
@@ -36,7 +36,8 @@
 		getfilecon	\
 		setfilecon	\
 		newrole		\
-		fmacsetup
+		fmacsetup	\
+		etc
 
 SUBDIR_POLICY =			\
 		policy
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fmac/etc/Makefile	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,59 @@
+#
+# 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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+FMACPROG = default_user
+SUBDIRS= contexts
+
+include ../../Makefile.cmd
+
+all:=			TARGET= ALL
+install:=		TARGET= install
+
+FMACD=			$(ROOTETC)/security/fmac
+FMACCONTEXTSPROG=	$(FMACPROG:%=$(FMACD)/%)
+
+FILEMODE= 0644
+OWNER= root
+GROUP= sys
+
+all: $(FMACPROG)
+
+install: all $(FMACD) $(FMACCONTEXTSPROG) $(SUBDIRS)
+
+$(FMACD)/% : %
+	$(INS.file)
+
+$(FMACD):
+	$(INS.dir)
+
+$(SUBDIRS): FRC
+	cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+clean clobber lint:
+
+include ../../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fmac/etc/contexts/Makefile	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,61 @@
+#
+# 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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+FMACPROG= default_type default_contexts failsafe_context
+SUBDIRS= users
+
+include ../../../Makefile.cmd
+
+all:=			TARGET= all
+install:=		TARGET= install
+
+FMACCONTEXTSD=		$(ROOTETC)/security/fmac/contexts
+FMACCONTEXTSPROG=	$(FMACPROG:%=$(FMACCONTEXTSD)/%)
+
+FILEMODE= 0644
+OWNER= root
+GROUP= sys
+
+.KEEP_STATE:
+
+all: $(FMACPROG)
+
+install:	all $(FMACCONTEXTSD) $(FMACCONTEXTSPROG) $(SUBDIRS)
+
+$(FMACCONTEXTSD)/% : %
+	$(INS.file)
+
+$(FMACCONTEXTSD):
+	$(INS.dir)
+
+$(SUBDIRS): FRC
+	@cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+clean clobber lint:
+
+include ../../../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fmac/etc/contexts/default_contexts	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,27 @@
+#
+# 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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+system_r:sshd_t:u		user_r:user_t:u
+system_r:local_login_t:u	user_r:user_t:u
+system_r:crond_t:u		user_r:user_t:u
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fmac/etc/contexts/default_type	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,27 @@
+#
+# 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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+user_r:user_t
+sysadm_r:sysadm_t
+root:sysadm_t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fmac/etc/contexts/failsafe_context	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,25 @@
+#
+# 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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+user_r:user_t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fmac/etc/contexts/users/Makefile	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,53 @@
+#
+# 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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+FMACPROG= sysadm_u user_u
+
+include ../../../../Makefile.cmd
+
+FMACCONTEXTSUSERSD= $(ROOTETC)/security/fmac/contexts/users
+FMACCONTEXTSUSERSPROG=	$(FMACPROG:%=$(FMACCONTEXTSUSERSD)/%)
+FILEMODE= 0644
+OWNER= root
+GROUP= sys
+
+.KEEP_STATE:
+
+all: $(FMACPROG)
+
+install: all $(FMACCONTEXTSUSERSD) $(FMACCONTEXTSUSERSPROG)
+
+$(FMACCONTEXTSUSERSD)/% : %
+	$(INS.file)
+
+$(FMACCONTEXTSUSERSD):
+	$(INS.dir)
+
+FRC:
+
+clean clobber lint:
+
+include ../../../../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fmac/etc/contexts/users/sysadm_u	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,29 @@
+#
+# 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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+system_r:sshd_t:u		user_r:user_t:u
+system_r:login_t:u		sysadm_r:sysadm_t:u user_r:user_t:u
+system_r:local_login_t:u	sysadm_r:sysadm_t:u user_r:user_t:u
+system_r:crond_t:u		sysadm_r:sysadm_t:u
+system_r:initrc_t		user_r:user_t:u
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fmac/etc/contexts/users/user_u	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,24 @@
+#
+# 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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fmac/etc/default_user	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,25 @@
+#
+# 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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+user_u:u
--- a/usr/src/cmd/fmac/newrole/newrole.c	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/cmd/fmac/newrole/newrole.c	Thu May 07 13:13:23 2009 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -141,8 +141,10 @@
 	/* Merge process and requested context fields */
 	if (n_role == NULL)
 		n_role = p_role;
-	if (n_type == NULL)
-		n_type = p_type;
+	if (n_type == NULL) {
+		if (get_default_type(n_role, (char **)&n_type) != 0)
+			n_type = p_type;
+	}
 	if (n_level == NULL && p_level != NULL)
 		n_level = p_level;
 
--- a/usr/src/cmd/fmac/policy/users	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/cmd/fmac/policy/users	Thu May 07 13:13:23 2009 -0700
@@ -20,7 +20,7 @@
 #
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -63,12 +63,3 @@
 #
 
 user sysadm_u roles { user_r sysadm_r };
-
-#
-# The following users correspond to Unix identities.
-# These identities are typically assigned as the user attribute
-# when login starts the user shell.
-#
-
-user root roles { user_r sysadm_r };
-
--- a/usr/src/common/fmac/policy/flask/access_vectors	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/common/fmac/policy/flask/access_vectors	Thu May 07 13:13:23 2009 -0700
@@ -20,6 +20,11 @@
 #
 
 #
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
 # Original files contributed to OpenSolaris.org under license by the
 # United States Government (NSA) to Sun Microsystems, Inc.
 #
@@ -306,6 +311,7 @@
 	setenforce
 	load_policy
 	compute_av
+	compute_user
 	check_context
 }
 
--- a/usr/src/common/fmac/ss/services.c	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/common/fmac/ss/services.c	Thu May 07 13:13:23 2009 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -167,7 +167,7 @@
 					    (!ebitmap_get_bit(&r1->dominates,
 					    val2 - 1) &&
 					    !ebitmap_get_bit(&r2->dominates,
-						val1 - 1));
+					    val1 - 1));
 					continue;
 				default:
 					break;
@@ -249,7 +249,7 @@
 
 	if (!tclass || tclass > policydb.p_classes.nprim) {
 		(void) printf("security_compute_av:  unrecognized class %d\n",
-		tclass);
+		    tclass);
 		return (EINVAL);
 	}
 	tclass_datum = policydb.class_val_to_struct[tclass - 1];
@@ -292,7 +292,7 @@
 	while (constraint) {
 		if ((constraint->permissions & (avd->allowed)) &&
 		    !constraint_expr_eval(scontext, tcontext,
-			constraint->expr)) {
+		    constraint->expr)) {
 			avd->allowed =
 			    (avd->allowed) & ~(constraint->permissions);
 		}
@@ -407,7 +407,7 @@
 	if (!scontextp) {
 		return (ENOMEM);
 	}
-	*scontext = (security_context_t) scontextp;
+	*scontext = (security_context_t)scontextp;
 
 	/*
 	 * Copy the user name, role name and type name into the context.
@@ -455,7 +455,7 @@
 			*scontext_len = strlen(initial_sid_to_string[sid]) + 1;
 			scontextp = SS_ALLOC_NOSLEEP(*scontext_len);
 			(void) strcpy(scontextp, initial_sid_to_string[sid]);
-			*scontext = (security_context_t) scontextp;
+			*scontext = (security_context_t)scontextp;
 			return (0);
 		}
 		(void) printf("security_sid_to_context:  called before initial "
@@ -522,7 +522,7 @@
 	/* Parse the security context. */
 
 	rc = (EINVAL);
-	scontextp = (char *) scontext2;
+	scontextp = (char *)scontext2;
 
 	/* Extract the user. */
 	p = scontextp;
@@ -534,8 +534,8 @@
 
 	*p++ = 0;
 
-	usrdatum = (user_datum_t *) hashtab_search(policydb.p_users.table,
-	    (hashtab_key_t) scontextp);
+	usrdatum = (user_datum_t *)hashtab_search(policydb.p_users.table,
+	    (hashtab_key_t)scontextp);
 	if (!usrdatum)
 		goto out;
 
@@ -551,8 +551,8 @@
 
 	*p++ = 0;
 
-	role = (role_datum_t *) hashtab_search(policydb.p_roles.table,
-	    (hashtab_key_t) scontextp);
+	role = (role_datum_t *)hashtab_search(policydb.p_roles.table,
+	    (hashtab_key_t)scontextp);
 	if (!role)
 		goto out;
 	context.role = role->value;
@@ -564,8 +564,8 @@
 	oldc = *p;
 	*p++ = 0;
 
-	typdatum = (type_datum_t *) hashtab_search(policydb.p_types.table,
-	    (hashtab_key_t) scontextp);
+	typdatum = (type_datum_t *)hashtab_search(policydb.p_types.table,
+	    (hashtab_key_t)scontextp);
 
 	if (!typdatum)
 		goto out;
@@ -830,10 +830,10 @@
 	perm_datum_t *perdatum, *perdatum2;
 
 
-	h = (hashtab_t) p;
-	perdatum = (perm_datum_t *) datum;
+	h = (hashtab_t)p;
+	perdatum = (perm_datum_t *)datum;
 
-	perdatum2 = (perm_datum_t *) hashtab_search(h, key);
+	perdatum2 = (perm_datum_t *)hashtab_search(h, key);
 	if (!perdatum2) {
 		(void) printf("security:  permission %s disappeared", key);
 		return (-1);
@@ -857,11 +857,11 @@
 	policydb_t *newp;
 	class_datum_t *cladatum, *cladatum2;
 
-	newp = (policydb_t *) p;
-	cladatum = (class_datum_t *) datum;
+	newp = (policydb_t *)p;
+	cladatum = (class_datum_t *)datum;
 
 	cladatum2 =
-	    (class_datum_t *) hashtab_search(newp->p_classes.table, key);
+	    (class_datum_t *)hashtab_search(newp->p_classes.table, key);
 	if (!cladatum2) {
 		(void) printf("security:  class %s disappeared\n", key);
 		return (-1);
@@ -889,7 +889,7 @@
 		}
 	}
 	if (hashtab_map(cladatum->permissions.table, validate_perm,
-			cladatum2->permissions.table)) {
+	    cladatum2->permissions.table)) {
 		(void) printf(" in access vector definition for class %s\n",
 		    key);
 		return (-1);
@@ -949,14 +949,14 @@
 
 	_NOTE(ARGUNUSED(key));
 
-	args = (convert_context_args_t *) p;
+	args = (convert_context_args_t *)p;
 
 	if (context_cpy(&oldc, c))
 		return (ENOMEM);
 
 	/* Convert the user. */
-	usrdatum = (user_datum_t *) hashtab_search(args->newp->p_users.table,
-			    args->oldp->p_user_val_to_name[c->user - 1]);
+	usrdatum = (user_datum_t *)hashtab_search(args->newp->p_users.table,
+	    args->oldp->p_user_val_to_name[c->user - 1]);
 
 	if (!usrdatum) {
 		goto bad;
@@ -964,15 +964,15 @@
 	c->user = usrdatum->value;
 
 	/* Convert the role. */
-	role = (role_datum_t *) hashtab_search(args->newp->p_roles.table,
-			    args->oldp->p_role_val_to_name[c->role - 1]);
+	role = (role_datum_t *)hashtab_search(args->newp->p_roles.table,
+	    args->oldp->p_role_val_to_name[c->role - 1]);
 	if (!role) {
 		goto bad;
 	}
 	c->role = role->value;
 
 	/* Convert the type. */
-	typdatum = (type_datum_t *) hashtab_search(args->newp->p_types.table,
+	typdatum = (type_datum_t *)hashtab_search(args->newp->p_types.table,
 	    args->oldp->p_type_val_to_name[c->type - 1]);
 	if (!typdatum) {
 		goto bad;
@@ -1338,7 +1338,7 @@
 		goto out;
 	}
 
-	user = (user_datum_t *) hashtab_search(policydb.p_users.table,
+	user = (user_datum_t *)hashtab_search(policydb.p_users.table,
 	    username);
 	if (!user) {
 		rc = EINVAL;
@@ -1376,7 +1376,7 @@
 				    &sid);
 				if (rc) {
 					SS_FREE(mysids,
-						maxnel*sizeof (security_id_t));
+					    maxnel*sizeof (security_id_t));
 					goto out;
 				}
 				if (mynel < maxnel) {
@@ -1415,6 +1415,14 @@
 	return (rc);
 }
 
+void
+security_free_user_sids(security_id_t *sids, uint32_t nel)
+{
+	if (nel)
+		SS_FREE(sids,
+		    (((nel/SIDS_NEL)+1)*SIDS_NEL)*sizeof (security_id_t));
+}
+
 /*
  * Return the SID to use for a file in a filesystem
  * that cannot support a persistent label mapping or use another
--- a/usr/src/head/fmac/fmac.h	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/head/fmac/fmac.h	Thu May 07 13:13:23 2009 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -44,7 +44,8 @@
 int security_compute_av(security_context_t scontext,
     security_context_t tcontext, security_class_t tclass,
     access_vector_t request, struct av_decision *avd);
-
+int security_compute_user(security_context_t scontext, const char *username,
+    security_context_t **context);
 int security_check_context(security_context_t context);
 int security_getenforce(void);
 int security_setenforce(int mode);
@@ -55,8 +56,23 @@
 int setexeccon(security_context_t context);
 int getprevcon(security_context_t *context);
 void freecon(security_context_t context);
+void freeconary(security_context_t *context);
 int getfilecon(const char *path, char **secctxp);
 int setfilecon(const char *path, char *secctx);
+int getfmacuserbyname(const char *name, char **fmacuser, char **level);
+int get_default_type(const char *role, char **type);
+int get_default_context(const char *user, security_context_t fromcon,
+    security_context_t *newcon);
+int get_default_context_with_level(const char *user, const char *level,
+    security_context_t fromcon, security_context_t *newcon);
+int get_default_context_with_role(const char *user, const char *role,
+    security_context_t fromcon, security_context_t *newcon);
+int get_default_context_with_rolelevel(const char *user, const char *role,
+    const char *level, security_context_t fromcon, security_context_t *newcon);
+int get_ordered_context_list(const char *user, security_context_t fromcon,
+    security_context_t **list);
+int get_ordered_context_list_with_level(const char *user, const char *level,
+    security_context_t fromcon, security_context_t **list);
 #ifdef __cplusplus
 }
 #endif
--- a/usr/src/lib/libc/amd64/Makefile	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/lib/libc/amd64/Makefile	Thu May 07 13:13:23 2009 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -106,7 +106,13 @@
 	ecvt.o			\
 	errlst.o		\
 	filecon.o		\
+	fmac_config.o		\
 	fmac_context.o		\
+	freecon.o		\
+	freeconary.o		\
+	get_context_list.o	\
+	get_default_type.o	\
+	getfmacuserbyname.o	\
 	amd64_data.o		\
 	ldivide.o		\
 	lock.o			\
@@ -119,6 +125,7 @@
 	new_list.o		\
 	proc64_id.o		\
 	proc64_support.o	\
+	security_compute_user.o	\
 	setjmp.o		\
 	siginfolst.o		\
 	siglongjmp.o		\
--- a/usr/src/lib/libc/i386/Makefile.com	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/lib/libc/i386/Makefile.com	Thu May 07 13:13:23 2009 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -427,7 +427,10 @@
 	fdetach.o		\
 	fdopendir.o		\
 	filecon.o		\
+	fmac_config.o		\
 	fmtmsg.o		\
+	freecon.o		\
+	freeconary.o		\
 	ftime.o			\
 	ftok.o			\
 	ftw.o			\
@@ -438,6 +441,7 @@
 	getdtblsize.o		\
 	getenv.o		\
 	getexecname.o		\
+	getfmacuserbyname.o	\
 	getgrnam.o		\
 	getgrnam_r.o		\
 	gethostid.o		\
@@ -466,6 +470,8 @@
 	getwd.o			\
 	getwidth.o		\
 	getxby_door.o		\
+	get_context_list.o	\
+	get_default_type.o	\
 	gtxt.o			\
 	hsearch.o		\
 	iconv.o			\
@@ -546,6 +552,7 @@
 	rewinddir.o		\
 	rindex.o		\
 	scandir.o		\
+	security_compute_user.o	\
 	seekdir.o		\
 	select.o		\
 	select_large_fdset.o	\
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libc/inc/fmac_private.h	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,65 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _FMAC_PRIVATE_H
+#define	_FMAC_PRIVATE_H
+
+/*
+ * Block comment that describes the contents of this file.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const char *fmac_default_type_path();
+const char *fmac_policy_root();
+const char *fmac_path();
+const char *fmac_default_context_path();
+const char *fmac_securetty_types_path();
+const char *fmac_failsafe_context_path();
+const char *fmac_removable_context_path();
+const char *fmac_binary_policy_path();
+const char *fmac_file_context_path();
+const char *fmac_homedir_context_path();
+const char *fmac_media_context_path();
+const char *fmac_customizable_types_path();
+const char *fmac_contexts_path();
+const char *fmac_user_contexts_path();
+const char *fmac_booleans_path();
+const char *fmac_users_path();
+const char *fmac_default_user_path();
+const char *fmac_default_translations_path();
+const char *fmac_netfilter_context_path();
+const char *fmac_file_context_homedir_path();
+const char *fmac_file_context_local_path();
+const char *fmac_x_context_path();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FMAC_PRIVATE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libc/port/gen/fmac_config.c	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,262 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * This source code originated from
+ * http://www.nsa.gov/selinux/archives/libselinux-2.0.65.tgz
+ * with the following LICENSE file in the top-level of the tar archive:
+ *
+ * This library (libselinux) is public domain software, i.e. not copyrighted.
+ *
+ * Warranty Exclusion
+ * ------------------
+ * You agree that this software is a
+ * non-commercially developed program that may contain "bugs" (as that
+ * term is used in the industry) and that it may not function as intended.
+ * The software is licensed "as is". NSA makes no, and hereby expressly
+ * disclaims all, warranties, express, implied, statutory, or otherwise
+ * with respect to the software, including noninfringement and the implied
+ * warranties of merchantability and fitness for a particular purpose.
+ *
+ * Limitation of Liability
+ * -----------------------
+ * In no event will NSA be liable for any damages, including loss of data,
+ * lost profits, cost of cover, or other special, incidental,
+ * consequential, direct or indirect damages arising from the software or
+ * the use thereof, however caused and on any theory of liability. This
+ * limitation will apply even if NSA has been advised of the possibility
+ * of such damage. You acknowledge that this is a reasonable allocation of
+ * risk.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <unistd.h>
+#include "fmac_private.h"
+
+#define	FMACDIR "/etc/security/fmac"
+#define	FMACCONFIG FMACDIR "config"
+#define	FMACDEFAULT "targeted"
+#define	FMACTYPETAG "FMACTYPE="
+#define	FMACTAG "FMAC="
+#define	SETLOCALDEFS "SETLOCALDEFS="
+#define	REQUIRESEUSERS "REQUIRESEUSERS="
+
+/* Indices for file paths arrays. */
+#define	BINPOLICY		0
+#define	CONTEXTS_DIR		1
+#define	FILE_CONTEXTS		2
+#define	HOMEDIR_CONTEXTS	3
+#define	DEFAULT_CONTEXTS	4
+#define	USER_CONTEXTS		5
+#define	FAILSAFE_CONTEXT	6
+#define	DEFAULT_TYPE		7
+#define	BOOLEANS		8
+#define	MEDIA_CONTEXTS		9
+#define	REMOVABLE_CONTEXT	10
+#define	CUSTOMIZABLE_TYPES	11
+#define	USERS_DIR		12
+#define	DEFAULT_USER		13
+#define	TRANSLATIONS		14
+#define	NETFILTER_CONTEXTS	15
+#define	FILE_CONTEXTS_HOMEDIR	16
+#define	FILE_CONTEXTS_LOCAL	17
+#define	SECURETTY_TYPES		18
+#define	X_CONTEXTS		19
+#define	NEL			20
+
+#define	FMAC_PATH(s)	FMACDIR s
+
+/* New layout is relative to FMACDIR/policytype. */
+static char *file_paths[NEL] = {
+	FMAC_PATH("/ss_policy"),
+	FMAC_PATH("/contexts"),
+	FMAC_PATH("/contexts/files/file_contexts"),
+	FMAC_PATH("/contexts/files/homedir_template"),
+	FMAC_PATH("/contexts/default_contexts"),
+	FMAC_PATH("/contexts/users/"),
+	FMAC_PATH("/contexts/failsafe_context"),
+	FMAC_PATH("/contexts/default_type"),
+	FMAC_PATH("/booleans"),
+	FMAC_PATH("/contexts/files/media"),
+	FMAC_PATH("/contexts/removable_context"),
+	FMAC_PATH("/contexts/customizable_types"),
+	FMAC_PATH("/users/"),
+	FMAC_PATH("/default_user"),
+	FMAC_PATH("/setrans.conf"),
+	FMAC_PATH("/contexts/netfilter_contexts"),
+	FMAC_PATH("/contexts/files/file_contexts.homedirs"),
+	FMAC_PATH("/contexts/files/file_contexts.local"),
+	FMAC_PATH("/contexts/securetty_types"),
+	FMAC_PATH("/contexts/x_contexts")
+};
+
+static char *fmac_policyroot = FMACDIR;
+static char *fmac_rootpath = FMACDIR;
+
+static const char *
+get_path(int idx)
+{
+	return (file_paths[idx]);
+}
+
+const char *
+fmac_default_type_path()
+{
+	return (get_path(DEFAULT_TYPE));
+}
+
+
+const char *
+fmac_policy_root()
+{
+	return (fmac_policyroot);
+}
+
+const char *
+fmac_path()
+{
+	return (fmac_rootpath);
+}
+
+const char *
+fmac_default_context_path()
+{
+	return (get_path(DEFAULT_CONTEXTS));
+}
+
+const char *
+fmac_securetty_types_path()
+{
+	return (get_path(SECURETTY_TYPES));
+}
+
+const char *
+fmac_failsafe_context_path()
+{
+	return (get_path(FAILSAFE_CONTEXT));
+}
+
+const char *
+fmac_removable_context_path()
+{
+	return (get_path(REMOVABLE_CONTEXT));
+}
+
+const char *
+fmac_binary_policy_path()
+{
+	return (get_path(BINPOLICY));
+}
+
+const char *
+fmac_file_context_path()
+{
+	return (get_path(FILE_CONTEXTS));
+}
+
+const char *
+fmac_homedir_context_path()
+{
+	return (get_path(HOMEDIR_CONTEXTS));
+}
+
+const char *
+fmac_media_context_path()
+{
+	return (get_path(MEDIA_CONTEXTS));
+}
+
+const char *
+fmac_customizable_types_path()
+{
+	return (get_path(CUSTOMIZABLE_TYPES));
+}
+
+const char *
+fmac_contexts_path()
+{
+	return (get_path(CONTEXTS_DIR));
+}
+
+const char *
+fmac_user_contexts_path()
+{
+	return (get_path(USER_CONTEXTS));
+}
+
+const char *
+fmac_booleans_path()
+{
+	return (get_path(BOOLEANS));
+}
+
+const char *
+fmac_users_path()
+{
+	return (get_path(USERS_DIR));
+}
+
+const char *
+fmac_default_user_path()
+{
+	return (get_path(DEFAULT_USER));
+}
+
+const char *
+fmac_translations_path()
+{
+	return (get_path(TRANSLATIONS));
+}
+
+const char *
+fmac_netfilter_context_path()
+{
+	return (get_path(NETFILTER_CONTEXTS));
+}
+
+const char *
+fmac_file_context_homedir_path()
+{
+	return (get_path(FILE_CONTEXTS_HOMEDIR));
+}
+
+const char *
+fmac_file_context_local_path()
+{
+	return (get_path(FILE_CONTEXTS_LOCAL));
+}
+
+const char *
+fmac_x_context_path()
+{
+	return (get_path(X_CONTEXTS));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libc/port/gen/freecon.c	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,66 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * This source code originated from
+ * http://www.nsa.gov/selinux/archives/libselinux-2.0.65.tgz
+ * with the following LICENSE file in the top-level of the tar archive:
+ *
+ * This library (libselinux) is public domain software, i.e. not copyrighted.
+ *
+ * Warranty Exclusion
+ * ------------------
+ * You agree that this software is a
+ * non-commercially developed program that may contain "bugs" (as that
+ * term is used in the industry) and that it may not function as intended.
+ * The software is licensed "as is". NSA makes no, and hereby expressly
+ * disclaims all, warranties, express, implied, statutory, or otherwise
+ * with respect to the software, including noninfringement and the implied
+ * warranties of merchantability and fitness for a particular purpose.
+ *
+ * Limitation of Liability
+ * -----------------------
+ * In no event will NSA be liable for any damages, including loss of data,
+ * lost profits, cost of cover, or other special, incidental,
+ * consequential, direct or indirect damages arising from the software or
+ * the use thereof, however caused and on any theory of liability. This
+ * limitation will apply even if NSA has been advised of the possibility
+ * of such damage. You acknowledge that this is a reasonable allocation of
+ * risk.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fmac/fmac.h>
+
+#pragma weak _freecon = freecon
+
+void
+freecon(security_context_t context)
+{
+	free(context);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libc/port/gen/freeconary.c	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,74 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * This source code originated from
+ * http://www.nsa.gov/selinux/archives/libselinux-2.0.65.tgz
+ * with the following LICENSE file in the top-level of the tar archive:
+ *
+ * This library (libselinux) is public domain software, i.e. not copyrighted.
+ *
+ * Warranty Exclusion
+ * ------------------
+ * You agree that this software is a
+ * non-commercially developed program that may contain "bugs" (as that
+ * term is used in the industry) and that it may not function as intended.
+ * The software is licensed "as is". NSA makes no, and hereby expressly
+ * disclaims all, warranties, express, implied, statutory, or otherwise
+ * with respect to the software, including noninfringement and the implied
+ * warranties of merchantability and fitness for a particular purpose.
+ *
+ * Limitation of Liability
+ * -----------------------
+ * In no event will NSA be liable for any damages, including loss of data,
+ * lost profits, cost of cover, or other special, incidental,
+ * consequential, direct or indirect damages arising from the software or
+ * the use thereof, however caused and on any theory of liability. This
+ * limitation will apply even if NSA has been advised of the possibility
+ * of such damage. You acknowledge that this is a reasonable allocation of
+ * risk.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fmac/fmac.h>
+
+#pragma weak _freeconary = freeconary
+
+void
+freeconary(security_context_t *context)
+{
+	char **ptr;
+
+	if (!context)
+		return;
+
+	for (ptr = context; *ptr; ptr++) {
+		free(*ptr);
+	}
+	free(context);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libc/port/gen/get_context_list.c	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,634 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * This source code originated from
+ * http://www.nsa.gov/selinux/archives/libselinux-2.0.65.tgz
+ * with the following LICENSE file in the top-level of the tar archive:
+ *
+ * This library (libselinux) is public domain software, i.e. not copyrighted.
+ *
+ * Warranty Exclusion
+ * ------------------
+ * You agree that this software is a
+ * non-commercially developed program that may contain "bugs" (as that
+ * term is used in the industry) and that it may not function as intended.
+ * The software is licensed "as is". NSA makes no, and hereby expressly
+ * disclaims all, warranties, express, implied, statutory, or otherwise
+ * with respect to the software, including noninfringement and the implied
+ * warranties of merchantability and fitness for a particular purpose.
+ *
+ * Limitation of Liability
+ * -----------------------
+ * In no event will NSA be liable for any damages, including loss of data,
+ * lost profits, cost of cover, or other special, incidental,
+ * consequential, direct or indirect damages arising from the software or
+ * the use thereof, however caused and on any theory of liability. This
+ * limitation will apply even if NSA has been advised of the possibility
+ * of such damage. You acknowledge that this is a reasonable allocation of
+ * risk.
+ */
+
+#pragma weak _get_default_context_with_role = get_default_context_with_role
+#pragma weak _get_default_context_with_rolelevel = \
+    get_default_context_with_rolelevel
+#pragma weak _get_default_context = get_default_context
+#pragma weak _get_ordered_context_list_with_level = \
+    get_ordered_context_list_with_level
+#pragma weak _get_default_context_with_level = get_default_context_with_level
+#pragma weak _get_ordered_context_list = get_ordered_context_list
+
+#include "lint.h"
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <fmac/fmac.h>
+#include <fmac/fmac_context.h>
+#include "fmac_private.h"
+
+#define	FMAC_DEFAULTUSER "user_u"
+
+int
+get_default_context_with_role(const char *user, const char *role,
+    security_context_t fromcon, security_context_t *newcon)
+{
+	security_context_t *conary;
+	char **ptr;
+	fmac_context_t con;
+	const char *role2;
+	int rc;
+
+	rc = get_ordered_context_list(user, fromcon, &conary);
+	if (rc <= 0)
+		return (-1);
+
+	for (ptr = conary; *ptr; ptr++) {
+		con = fmac_context_new(*ptr);
+		if (!con)
+			continue;
+		role2 = fmac_context_role_get(con);
+		if (role2 && strcmp(role, role2) == 0) {
+			fmac_context_free(con);
+			break;
+		}
+		fmac_context_free(con);
+	}
+
+	rc = -1;
+	if (!(*ptr))
+		goto out;
+	*newcon = strdup(*ptr);
+	if (!(*newcon))
+		goto out;
+	rc = 0;
+out:
+	freeconary(conary);
+	return (rc);
+}
+
+int
+get_default_context_with_rolelevel(const char *user, const char *role,
+    const char *level, security_context_t fromcon, security_context_t *newcon)
+{
+
+	int rc = 0;
+	int freefrom = 0;
+	fmac_context_t con;
+	char *newfromcon;
+	if (!level)
+		return (get_default_context_with_role(user, role, fromcon,
+		    newcon));
+
+	if (!fromcon) {
+		rc = getcon(&fromcon);
+		if (rc < 0)
+			return (rc);
+		freefrom = 1;
+	}
+
+	rc = -1;
+	con = fmac_context_new(fromcon);
+	if (!con)
+		goto out;
+
+	if (fmac_context_range_set(con, level))
+		goto out;
+
+	newfromcon = fmac_context_str(con);
+	if (!newfromcon)
+		goto out;
+
+	rc = get_default_context_with_role(user, role, newfromcon, newcon);
+
+out:
+	fmac_context_free(con);
+	if (freefrom)
+		freecon(fromcon);
+	return (rc);
+
+}
+
+int
+get_default_context(const char *user, security_context_t fromcon,
+    security_context_t *newcon)
+{
+	security_context_t *conary;
+	int rc;
+
+	rc = get_ordered_context_list(user, fromcon, &conary);
+	if (rc <= 0)
+		return (-1);
+
+	*newcon = strdup(conary[0]);
+	freeconary(conary);
+	if (!(*newcon))
+		return (-1);
+	return (0);
+}
+
+static int
+find_partialcon(security_context_t *list, unsigned int nreach, char *part)
+{
+	const char *conrole, *contype;
+	char *partrole, *parttype, *ptr;
+	fmac_context_t con;
+	unsigned int i;
+
+	partrole = part;
+	ptr = part;
+	while (*ptr && !isspace(*ptr) && *ptr != ':')
+		ptr++;
+	if (*ptr != ':')
+		return (-1);
+	*ptr++ = 0;
+	parttype = ptr;
+	while (*ptr && !isspace(*ptr) && *ptr != ':')
+		ptr++;
+	*ptr = 0;
+
+	for (i = 0; i < nreach; i++) {
+		con = fmac_context_new(list[i]);
+		if (!con)
+			return (-1);
+		conrole = fmac_context_role_get(con);
+		contype = fmac_context_type_get(con);
+		if (!conrole || !contype) {
+			fmac_context_free(con);
+			return (-1);
+		}
+		if (strcmp(conrole, partrole) == 0 &&
+		    strcmp(contype, parttype) == 0) {
+			fmac_context_free(con);
+			return (i);
+		}
+		fmac_context_free(con);
+	}
+
+	return (-1);
+}
+
+static int
+get_context_order(FILE *fp, security_context_t fromcon,
+    security_context_t *reachable, unsigned int nreach,
+    unsigned int *ordering, unsigned int *nordered)
+{
+	char *start, *end = NULL;
+	char *line = NULL;
+	int len;
+	int found = 0;
+	const char *fromrole, *fromtype;
+	char *linerole, *linetype;
+	unsigned int i;
+	fmac_context_t con;
+	int rc;
+
+	errno = -EINVAL;
+
+	/*
+	 * Extract the role and type of the fromcon for matching.
+	 * User identity and MLS range can be variable.
+	 */
+	con = fmac_context_new(fromcon);
+	if (!con)
+		return (-1);
+	fromrole = fmac_context_role_get(con);
+	fromtype = fmac_context_type_get(con);
+	if (!fromrole || !fromtype) {
+		fmac_context_free(con);
+		return (-1);
+	}
+
+	if ((line = malloc(1024)) == NULL) {
+		fmac_context_free(con);
+		return (-1);
+	}
+
+	while (fgets(line, 1024, fp) != NULL) {
+		len = strlen(line);
+		if (line[len - 1] == '\n')
+			line[len - 1] = 0;
+
+		/* Skip leading whitespace. */
+		start = line;
+		while (*start && isspace(*start))
+			start++;
+		if (!(*start))
+			continue;
+
+		/* Find the end of the (partial) fromcon in the line. */
+		end = start;
+		while (*end && !isspace(*end))
+			end++;
+		if (!(*end))
+			continue;
+
+		/* Check for a match. */
+		linerole = start;
+		while (*start && !isspace(*start) && *start != ':')
+			start++;
+		if (*start != ':')
+			continue;
+		*start = 0;
+		linetype = ++start;
+		while (*start && !isspace(*start) && *start != ':')
+			start++;
+		if (!(*start))
+			continue;
+		*start = 0;
+		if (strcmp(fromrole, linerole) == 0 &&
+		    strcmp(fromtype, linetype) == 0) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found) {
+		errno = ENOENT;
+		rc = -1;
+		goto out;
+	}
+
+	start = ++end;
+	while (*start) {
+		/* Skip leading whitespace */
+		while (*start && isspace(*start))
+			start++;
+		if (!(*start))
+			break;
+
+		/* Find the end of this partial context. */
+		end = start;
+		while (*end && !isspace(*end))
+			end++;
+		if (*end)
+			*end++ = 0;
+
+		/* Check for a match in the reachable list. */
+		rc = find_partialcon(reachable, nreach, start);
+		if (rc < 0) {
+			/* No match, skip it. */
+			start = end;
+			continue;
+		}
+
+		/*
+		 * If a match is found and the entry is not already ordered
+		 * (e.g. due to prior match in prior config file), then set
+		 * the ordering for it.
+		 */
+		i = rc;
+		if (ordering[i] == nreach)
+			ordering[i] = (*nordered)++;
+		start = end;
+	}
+
+	rc = 0;
+
+out:
+	fmac_context_free(con);
+	free(line);
+	return (rc);
+}
+
+static int
+get_failsafe_context(const char *user, security_context_t *newcon)
+{
+	FILE *fp;
+	char buf[255], *ptr;
+	size_t plen, nlen;
+	int found = 0;
+	int rc;
+
+	fp = fopen(fmac_failsafe_context_path(), "r");
+	if (!fp)
+		return (-1);
+
+	while (fgets(buf, sizeof (buf), fp) != NULL) {
+		plen = strlen(buf);
+
+		if (buf[plen - 1] == '\n')
+			buf[plen - 1] = 0;
+
+		/* Skip leading whitespace. */
+		ptr = buf;
+		while (*ptr && isspace(*ptr))
+			ptr++;
+		if (!(*ptr) || *ptr == '#')
+			continue;
+		plen = strlen(ptr);
+
+		found = 1;
+		break;
+	}
+
+	(void) fclose(fp);
+
+	if (!found) {
+		*newcon = 0;
+		return (-1);
+	}
+retry:
+	nlen = strlen(user) + 1 + plen + 1;
+	*newcon = malloc(nlen);
+	if (!(*newcon))
+		return (-1);
+	rc = snprintf(*newcon, nlen, "%s:%s", user, ptr);
+	if (rc < 0 || (size_t)rc >= nlen) {
+		free(*newcon);
+		*newcon = 0;
+		return (-1);
+	}
+
+	/*
+	 * If possible, check the context to catch
+	 * errors early rather than waiting until the
+	 * caller tries to use setexeccon on the context.
+	 * But this may not always be possible, e.g. if
+	 * selinuxfs isn't mounted.
+	 */
+	if (security_check_context(*newcon) && errno != ENOENT) {
+		free(*newcon);
+		*newcon = 0;
+		if (strcmp(user, FMAC_DEFAULTUSER)) {
+			user = FMAC_DEFAULTUSER;
+			goto retry;
+		}
+		return (-1);
+	}
+
+	return (0);
+}
+
+struct context_order {
+	security_context_t con;
+	unsigned int order;
+};
+
+static int
+order_compare(const void *A, const void *B)
+{
+	const struct context_order *c1 = A, *c2 = B;
+	if (c1->order < c2->order)
+		return (-1);
+	else if (c1->order > c2->order)
+		return (1);
+	return (strcmp(c1->con, c2->con));
+}
+
+int
+get_ordered_context_list_with_level(const char *user, const char *level,
+    security_context_t fromcon, security_context_t **list)
+{
+	int rc;
+	int freefrom = 0;
+	fmac_context_t con;
+	char *newfromcon;
+
+	if (!level)
+		return (get_ordered_context_list(user, fromcon, list));
+
+	if (!fromcon) {
+		rc = getcon(&fromcon);
+		if (rc < 0)
+			return (rc);
+		freefrom = 1;
+	}
+
+	rc = -1;
+	con = fmac_context_new(fromcon);
+	if (!con)
+		goto out;
+
+	if (fmac_context_range_set(con, level))
+		goto out;
+
+	newfromcon = fmac_context_str(con);
+	if (!newfromcon)
+		goto out;
+
+	rc = get_ordered_context_list(user, newfromcon, list);
+
+out:
+	fmac_context_free(con);
+	if (freefrom)
+		freecon(fromcon);
+	return (rc);
+}
+
+int
+get_default_context_with_level(const char *user, const char *level,
+    security_context_t fromcon, security_context_t *newcon)
+{
+	security_context_t *conary;
+	int rc;
+
+	rc = get_ordered_context_list_with_level(user, level, fromcon, &conary);
+	if (rc <= 0)
+		return (-1);
+
+	*newcon = strdup(conary[0]);
+	freeconary(conary);
+	if (!(*newcon))
+		return (-1);
+	return (0);
+}
+
+int
+get_ordered_context_list(const char *user, security_context_t fromcon,
+    security_context_t **list)
+{
+	security_context_t *reachable = NULL;
+	unsigned int *ordering = NULL;
+	struct context_order *co = NULL;
+	char **ptr;
+	int rc = 0;
+	unsigned int nreach = 0, nordered = 0, freefrom = 0, i;
+	FILE *fp;
+	char *fname = NULL;
+	size_t fname_len;
+	const char *user_contexts_path = fmac_user_contexts_path();
+
+	if (!fromcon) {
+		/*
+		 * Get the current context and use it for the starting context
+		 */
+		rc = getcon(&fromcon);
+		if (rc < 0)
+			return (rc);
+		freefrom = 1;
+	}
+
+	/* Determine the set of reachable contexts for the user. */
+	rc = security_compute_user(fromcon, user, &reachable);
+	if (rc < 0) {
+		/* Retry with the default SELinux user identity. */
+		user = FMAC_DEFAULTUSER;
+		rc = security_compute_user(fromcon, user, &reachable);
+		if (rc < 0)
+			goto failsafe;
+	}
+	nreach = 0;
+	for (ptr = reachable; *ptr; ptr++)
+		nreach++;
+	if (!nreach)
+		goto failsafe;
+
+	/* Initialize ordering array. */
+	ordering = malloc(nreach * sizeof (unsigned int));
+	if (!ordering)
+		goto oom_order;
+	for (i = 0; i < nreach; i++)
+		ordering[i] = nreach;
+
+	/*
+	 * Determine the ordering to apply from the optional per-user config
+	 * and from the global config.
+	 */
+	fname_len = strlen(user_contexts_path) + strlen(user) + 2;
+	fname = malloc(fname_len);
+	if (!fname)
+		goto oom_order;
+	(void) snprintf(fname, fname_len, "%s%s", user_contexts_path, user);
+	fp = fopen(fname, "r");
+	if (fp) {
+		(void) get_context_order(fp, fromcon, reachable, nreach,
+		    ordering, &nordered);
+		(void) fclose(fp);
+		if (rc < 0 && errno != ENOENT) {
+			syslog(LOG_NOTICE,
+			    "%s:  error in processing configuration file %s\n",
+			    __func__, fname);
+			/* Fall through, try global config */
+		}
+	}
+	free(fname);
+	fp = fopen(fmac_default_context_path(), "r");
+	if (fp) {
+		(void) get_context_order(fp, fromcon, reachable, nreach,
+		    ordering, &nordered);
+		(void) fclose(fp);
+		if (rc < 0 && errno != ENOENT) {
+			/* Fall through */
+			syslog(LOG_NOTICE,
+			    "%s:  error in processing configuration file %s\n",
+			    __func__, fmac_default_context_path());
+		}
+	}
+
+	/* Apply the ordering. */
+	if (nordered) {
+		co = malloc(nreach * sizeof (struct context_order));
+		if (!co)
+			goto oom_order;
+		for (i = 0; i < nreach; i++) {
+			co[i].con = reachable[i];
+			co[i].order = ordering[i];
+		}
+		qsort(co, nreach, sizeof (struct context_order), order_compare);
+		for (i = 0; i < nreach; i++)
+			reachable[i] = co[i].con;
+		free(co);
+	}
+
+	/*
+	 * Return the ordered list.
+	 * If we successfully ordered it, then only report the ordered entries
+	 * to the caller.  Otherwise, fall back to the entire reachable list.
+	 */
+	if (nordered && nordered < nreach) {
+		for (i = nordered; i < nreach; i++)
+			free(reachable[i]);
+		reachable[nordered] = NULL;
+		rc = nordered;
+	} else {
+		rc = nreach;
+	}
+
+out:
+	*list = reachable;
+
+	free(ordering);
+	if (freefrom)
+		freecon(fromcon);
+
+	return (rc);
+
+failsafe:
+	/*
+	 * Unable to determine a reachable context list, try to fall back to
+	 * the "failsafe" context to at least permit root login
+	 * for emergency recovery if possible.
+	 */
+	freeconary(reachable);
+	reachable = malloc(2 * sizeof (security_context_t));
+	if (!reachable) {
+		rc = -1;
+		goto out;
+	}
+	reachable[0] = reachable[1] = 0;
+	rc = get_failsafe_context(user, &reachable[0]);
+	if (rc < 0) {
+		freeconary(reachable);
+		reachable = NULL;
+		goto out;
+	}
+	rc = 1;			/* one context in the list */
+	goto out;
+
+oom_order:
+	/*
+	 * Unable to order context list due to OOM condition.
+	 * Fall back to unordered reachable context list.
+	 */
+	rc = nreach;
+	goto out;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libc/port/gen/get_default_type.c	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,124 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * This source code originated from
+ * http://www.nsa.gov/selinux/archives/libselinux-2.0.65.tgz
+ * with the following LICENSE file in the top-level of the tar archive:
+ *
+ * This library (libselinux) is public domain software, i.e. not copyrighted.
+ *
+ * Warranty Exclusion
+ * ------------------
+ * You agree that this software is a
+ * non-commercially developed program that may contain "bugs" (as that
+ * term is used in the industry) and that it may not function as intended.
+ * The software is licensed "as is". NSA makes no, and hereby expressly
+ * disclaims all, warranties, express, implied, statutory, or otherwise
+ * with respect to the software, including noninfringement and the implied
+ * warranties of merchantability and fitness for a particular purpose.
+ *
+ * Limitation of Liability
+ * -----------------------
+ * In no event will NSA be liable for any damages, including loss of data,
+ * lost profits, cost of cover, or other special, incidental,
+ * consequential, direct or indirect damages arising from the software or
+ * the use thereof, however caused and on any theory of liability. This
+ * limitation will apply even if NSA has been advised of the possibility
+ * of such damage. You acknowledge that this is a reasonable allocation of
+ * risk.
+ */
+
+#pragma weak _get_default_type = get_default_type
+
+#include "lint.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "fmac_private.h"
+
+static int find_default_type(FILE *fp, const char *role, char **type);
+
+int
+get_default_type(const char *role, char **type)
+{
+	FILE *fp = NULL;
+
+	fp = fopen(fmac_default_type_path(), "r");
+	if (!fp)
+		return (-1);
+
+	if (find_default_type(fp, role, type) < 0) {
+		(void) fclose(fp);
+		return (-1);
+	}
+
+	(void) fclose(fp);
+	return (0);
+}
+
+static int
+find_default_type(FILE *fp, const char *role, char **type)
+{
+	char buf[250];
+	char *ptr = "", *end, *t;
+	size_t len;
+	int found = 0;
+
+	len = strlen(role);
+	while (!feof(fp)) {
+		if (!fgets(buf, sizeof (buf), fp))
+			return (-1);
+		if (buf[strlen(buf) - 1])
+			buf[strlen(buf) - 1] = 0;
+
+		ptr = buf;
+		while (*ptr && isspace(*ptr))
+			ptr++;
+		if (!(*ptr))
+			continue;
+
+		if (strncmp(role, ptr, len) == 0) {
+			end = ptr + len;
+			if (*end == ':') {
+				found = 1;
+				ptr = ++end;
+				break;
+			}
+		}
+	}
+
+	if (!found)
+		return (-1);
+
+	t = malloc(strlen(buf) - len);
+	if (!t)
+		return (-1);
+	strcpy(t, ptr);
+	*type = t;
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libc/port/gen/getfmacuserbyname.c	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,171 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma weak _getfmacuserbyname = getfmacuserbyname
+
+#include "lint.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <strings.h>
+#include <errno.h>
+#include <user_attr.h>
+#include <dlfcn.h>
+#include <fmac/fmac.h>
+#include "fmac_private.h"
+
+typedef userattr_t *(*real_getusernam_t)(const char *);
+typedef void (*real_free_userattr_t)(userattr_t *);
+typedef char *(*real_kva_match_t)(kva_t *, char *);
+
+static real_getusernam_t real_getusernam = NULL;
+static real_free_userattr_t real_free_userattr;
+static real_kva_match_t real_kva_match;
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <strings.h>
+#include <errno.h>
+
+static int
+get_default_user(char **user, char **level)
+{
+	FILE *fp;
+	char *linebuf;
+	char *user_p = NULL;
+	char *level_p = NULL;
+	char *user_c = NULL;
+	char *level_c = NULL;
+
+	if ((fp = fopen(fmac_default_user_path(), "r")) == NULL)
+		return (-1);
+
+	if ((linebuf = (char *)malloc(FMAC_MAX_CONTEXT_LEN)) == NULL) {
+		(void) fclose(fp);
+		return (-1);
+	}
+
+	while (fgets(linebuf, FMAC_MAX_CONTEXT_LEN, fp) != NULL) {
+		char *p = linebuf;
+		char *lasts;
+
+		p[strcspn(p, "\n")] = 0;
+
+		while (isspace(*p))
+			p++;
+
+		if (strlen(p) == 0 || *p == '#')
+			continue;
+
+		user_p = strtok_r(p, ":", &lasts);
+		level_p = strtok_r(NULL, "", &lasts);
+
+		if (user_p)
+			break;
+	}
+
+	if (user_p) {
+		if (user_c = strdup(user_p)) {
+			if (level_p) {
+				if (level_c = strdup(level_p)) {
+					*user = user_c;
+					*level = level_c;
+				} else {
+					free(user_c);
+					user_c = NULL;
+				}
+			} else {
+				*user = user_c;
+			}
+		}
+	}
+
+	free(linebuf);
+	(void) fclose(fp);
+
+	if (user_c)
+		return (0);
+	else {
+		errno = ENOENT;
+		return (-1);
+	}
+}
+
+int
+getfmacuserbyname(const char *name, char **fmacuser, char **level)
+{
+	userattr_t	*ua;
+	char		*ua_fmacuser;
+	char		*ua_level;
+	int		err = 0;
+
+	if (real_getusernam == NULL) {
+		void *handle = dlopen("libsecdb.so.1", RTLD_LAZY);
+
+		if (handle == NULL)
+			return (-1);
+
+		if ((real_getusernam = (real_getusernam_t)dlsym(handle,
+		    "getusernam")) == NULL ||
+		    (real_kva_match = (real_kva_match_t)dlsym(handle,
+		    "kva_match")) == NULL ||
+		    (real_free_userattr = (real_free_userattr_t)dlsym(handle,
+		    "free_userattr")) == NULL) {
+			dlclose(handle);
+			return (-1);
+		}
+	}
+
+	if (((ua = real_getusernam(name)) == NULL) ||
+	    ((ua_fmacuser = real_kva_match(ua->attr, "fmac_user")) == NULL)) {
+		/*
+		 * Use the default_user entry if it exists.
+		 */
+		err = get_default_user(fmacuser, level);
+		goto done;
+	}
+
+	if ((*fmacuser = strdup(ua_fmacuser)) == NULL) {
+		err = -1;
+		goto done;
+	}
+
+	if ((ua_level = real_kva_match(ua->attr, "fmac_level")) != NULL) {
+		if ((*level = strdup(ua_level)) == NULL) {
+			free(*fmacuser);
+			*fmacuser = NULL;
+			err = -1;
+			goto done;
+		}
+	} else
+		*level = NULL;
+
+done:
+	real_free_userattr(ua);
+
+	return (err);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libc/port/gen/security_compute_user.c	Thu May 07 13:13:23 2009 -0700
@@ -0,0 +1,129 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * This source code originated from
+ * http://www.nsa.gov/selinux/archives/libselinux-2.0.65.tgz
+ * with the following LICENSE file in the top-level of the tar archive:
+ *
+ * This library (libselinux) is public domain software, i.e. not copyrighted.
+ *
+ * Warranty Exclusion
+ * ------------------
+ * You agree that this software is a
+ * non-commercially developed program that may contain "bugs" (as that
+ * term is used in the industry) and that it may not function as intended.
+ * The software is licensed "as is". NSA makes no, and hereby expressly
+ * disclaims all, warranties, express, implied, statutory, or otherwise
+ * with respect to the software, including noninfringement and the implied
+ * warranties of merchantability and fitness for a particular purpose.
+ *
+ * Limitation of Liability
+ * -----------------------
+ * In no event will NSA be liable for any damages, including loss of data,
+ * lost profits, cost of cover, or other special, incidental,
+ * consequential, direct or indirect damages arising from the software or
+ * the use thereof, however caused and on any theory of liability. This
+ * limitation will apply even if NSA has been advised of the possibility
+ * of such damage. You acknowledge that this is a reasonable allocation of
+ * risk.
+ */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include <string.h>
+#include <unistd.h>
+#include <fmac/fmac.h>
+
+#pragma weak _security_compute_user = security_compute_user
+
+/*
+ * Since the number of contexts returned from the kernel is unknown,
+ * allocate a large buffer. In the future, this could be changed to
+ * retry with a larger buffer if ENOMEM is returned.
+ */
+#define	SCU_SIZE	(1024*32)
+
+int
+security_compute_user(security_context_t scontext, const char *user,
+    security_context_t **context)
+{
+	char **ary;
+	char *buf, *ptr;
+	size_t size;
+	int ret;
+	unsigned int i, nel;
+
+	size = SCU_SIZE;
+	buf = malloc(size);
+
+	if (!buf) {
+		ret = -1;
+		goto out;
+	}
+
+	memset(buf, 0, size);
+
+	ret = syscall(SYS_fmacsys, FMACSYS_SECURITYCOMPUTEUSER, scontext, user,
+	    buf, size);
+
+	if (ret < 0)
+		goto out2;
+
+	nel = ret;
+
+	ary = malloc((nel + 1) * sizeof (char *));
+
+	if (!ary) {
+		ret = -1;
+		goto out2;
+	}
+
+	ptr = buf;
+
+	for (i = 0; i < nel; i++) {
+		ary[i] = strdup(ptr);
+		if (!ary[i]) {
+			freeconary(ary);
+			ret = -1;
+			goto out2;
+		}
+		ptr += strlen(ptr) + 1;
+	}
+
+	ary[nel] = NULL;
+	*context = ary;
+	ret = 0;
+out2:
+	free(buf);
+out:
+	return (ret);
+}
--- a/usr/src/lib/libc/port/mapfile-vers	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/lib/libc/port/mapfile-vers	Thu May 07 13:13:23 2009 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -87,14 +87,23 @@
 	forkallx;
 	forkx;
 	freecon;
+	freeconary;
 	fsetattr;
 	getattrat;
 	getcon;
 	getexeccon;
 	getfilecon;
+	getfmacuserbyname;
 	getpagesizes2;
 	getpidcon;
 	getprevcon;
+	get_default_type;
+	get_default_context;
+	get_default_context_with_level;
+	get_default_context_with_role;
+	get_default_context_with_rolelevel;
+	get_ordered_context_list;
+	get_ordered_context_list_with_level;
 	htonl;
 	htonll;
 	htons;
@@ -133,6 +142,7 @@
 	sched_yield;
 	security_check_context;
 	security_compute_av;
+	security_compute_user;
 	security_getenforce;
 	security_load_policy;
 	security_setenforce;
--- a/usr/src/lib/libc/port/sys/fmacsys.c	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/lib/libc/port/sys/fmacsys.c	Thu May 07 13:13:23 2009 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -193,9 +193,3 @@
 	} else
 		return (-1);
 }
-
-void
-freecon(security_context_t context)
-{
-	free(context);
-}
--- a/usr/src/lib/libc/sparc/Makefile	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/lib/libc/sparc/Makefile	Thu May 07 13:13:23 2009 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -450,7 +450,10 @@
 	fdetach.o		\
 	fdopendir.o		\
 	filecon.o		\
+	fmac_config.o		\
 	fmtmsg.o		\
+	freecon.o		\
+	freeconary.o		\
 	ftime.o			\
 	ftok.o			\
 	ftw.o			\
@@ -461,6 +464,7 @@
 	getdtblsize.o		\
 	getenv.o		\
 	getexecname.o		\
+	getfmacuserbyname.o	\
 	getgrnam.o		\
 	getgrnam_r.o		\
 	gethostid.o		\
@@ -489,6 +493,8 @@
 	getwd.o			\
 	getwidth.o		\
 	getxby_door.o		\
+	get_context_list.o	\
+	get_default_type.o	\
 	gtxt.o			\
 	hsearch.o		\
 	iconv.o			\
@@ -570,6 +576,7 @@
 	rewinddir.o		\
 	rindex.o		\
 	scandir.o		\
+	security_compute_user.o	\
 	seekdir.o		\
 	select.o		\
 	select_large_fdset.o	\
--- a/usr/src/lib/libc/sparcv9/Makefile	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/lib/libc/sparcv9/Makefile	Thu May 07 13:13:23 2009 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -411,7 +411,10 @@
 	fdetach.o		\
 	fdopendir.o		\
 	filecon.o		\
+	fmac_config.o		\
 	fmtmsg.o		\
+	freecon.o		\
+	freeconary.o		\
 	ftime.o			\
 	ftok.o			\
 	ftw.o			\
@@ -422,6 +425,7 @@
 	getdtblsize.o		\
 	getenv.o		\
 	getexecname.o		\
+	getfmacuserbyname.o	\
 	getgrnam.o		\
 	getgrnam_r.o		\
 	gethostid.o		\
@@ -450,6 +454,8 @@
 	getwd.o			\
 	getwidth.o		\
 	getxby_door.o		\
+	get_context_list.o	\
+	get_default_type.o	\
 	gtxt.o			\
 	hsearch.o		\
 	iconv.o			\
@@ -531,6 +537,7 @@
 	rewinddir.o		\
 	rindex.o		\
 	scandir.o		\
+	security_compute_user.o	\
 	seekdir.o		\
 	select.o		\
 	setlabel.o		\
--- a/usr/src/lib/libsecdb/user_attr.txt	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/lib/libsecdb/user_attr.txt	Thu May 07 13:13:23 2009 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # CDDL HEADER START
@@ -26,7 +26,7 @@
 # user attributes. see user_attr(4)
 #
 #
-root::::auths=solaris.*,solaris.grant;profiles=All;lock_after_retries=no;min_label=admin_low;clearance=admin_high
+root::::auths=solaris.*,solaris.grant;profiles=All;lock_after_retries=no;min_label=admin_low;clearance=admin_high;fmac_user=sysadm_u;fmac_level=u
 lp::::profiles=Printer Management
 adm::::profiles=Log Management
 dladm::::auths=solaris.smf.manage.wpa,solaris.smf.modify
--- a/usr/src/lib/pam_modules/unix_cred/unix_cred.c	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/lib/pam_modules/unix_cred/unix_cred.c	Thu May 07 13:13:23 2009 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -51,9 +51,6 @@
 #define	PROJECT		"project="
 #define	PROJSZ		(sizeof (PROJECT) - 1)
 
-#define	DEFAULT_USER_CONTEXT	"user_u:user_r:user_t"
-#define	DEFAULT_ROOT_CONTEXT	"root:sysadm_r:sysadm_t"
-
 /*
  *	unix_cred - PAM auth modules must contain both pam_sm_authenticate
  *		and pam_sm_setcred.  Some other auth module is responsible
@@ -176,6 +173,9 @@
 	char		*kvs;
 	struct passwd	pwd;
 	char		pwbuf[NSS_BUFLEN_PASSWD];
+	security_context_t newcon = NULL;
+	char		*fmac_user = NULL;
+	char		*fmac_level = NULL;
 
 	for (i = 0; i < argc; i++) {
 		if (strcmp(argv[i], "debug") == 0)
@@ -599,61 +599,53 @@
 	}
 	(void) setpflags(PRIV_AWARE, 0);
 
-	if ((flags & PAM_ESTABLISH_CRED) && is_fmac_enabled() > 0) {
-		security_context_t	context;
+	if (is_fmac_enabled() > 0) {
+
+		if (flags & PAM_ESTABLISH_CRED) {
+
+			if (getfmacuserbyname(user, &fmac_user,
+			    &fmac_level) != 0) {
+				syslog(LOG_AUTH | LOG_ERR,
+				    "pam_setcred: can't determine fmac "
+				    "user for: %s", user);
+					ret = PAM_CRED_ERR;
+				goto out;
+			}
 
-		if ((ua == NULL || ua->attr == NULL ||
-		    (context = kva_match(ua->attr, "context")) == NULL)) {
-			/*
-			 * Use hardcoded defaults until a mechanism
-			 * to obtain configured values is implemented.
-			 */
-			if (strcmp(user, "root") == 0)
-				context = DEFAULT_ROOT_CONTEXT;
-			else
-				context = DEFAULT_USER_CONTEXT;
+			if (get_default_context_with_level(fmac_user,
+			    fmac_level, NULL, &newcon) != 0) {
+				syslog(LOG_AUTH | LOG_ERR,
+				    "pam_setcred: can't determine fmac user");
+				ret = PAM_CRED_ERR;
+				goto out;
+			}
+		} else
+			goto out;
+
+		if (security_check_context(newcon) != 0) {
+			syslog(LOG_AUTH | LOG_ERR,
+			    "pam_setcred: invalid context: %s",
+			    newcon);
+			ret = PAM_CRED_ERR;
+			goto out;
 		}
 
-		if (security_check_context(context) != 0) {
-			if (security_getenforce() == 1) {
-				/* Enforcing - return an error */
-				syslog(LOG_AUTH | LOG_ERR,
-				    "pam_setcred: invalid context: %s",
-				    context);
-				ret = PAM_CRED_ERR;
-				goto out;
-			} else {
-				/*
-				 * Permissive - log the error and use
-				 * defaults
-				 */
-				syslog(LOG_AUTH | LOG_ERR,
-				    "pam_setcred: invalid context: %s",
-				    context);
-				if (strcmp(user, "root") == 0)
-					context = DEFAULT_ROOT_CONTEXT;
-				else
-					context = DEFAULT_USER_CONTEXT;
-			}
-		}
-
-		if (setexeccon(context) != 0) {
+		if (setexeccon(newcon) != 0) {
 			if (security_getenforce() == 1) {
 				/* Enforcing - return an error */
 				syslog(LOG_AUTH | LOG_ERR,
 				    "pam_setcred: setexeccon failed for: %s",
-				    context);
+				    newcon);
 				ret = PAM_CRED_ERR;
 				goto out;
 			} else {
 				/* Permissive - log the error */
 				syslog(LOG_AUTH | LOG_ERR,
 				    "pam_setcred: setexeccon failed for: %s",
-				    context);
+				    newcon);
 			}
 		}
 	}
-
 out:
 	(void) defopen(NULL);
 
@@ -665,6 +657,12 @@
 		priv_freeset(def);
 	if (tset != NULL)
 		priv_freeset(tset);
+	if (newcon != NULL)
+		freecon(newcon);
+	if (fmac_user != NULL)
+		free(fmac_user);
+	if (fmac_level != NULL)
+		free(fmac_level);
 
 	return (ret);
 }
--- a/usr/src/pkgdefs/SUNWcsr/prototype_com	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/pkgdefs/SUNWcsr/prototype_com	Thu May 07 13:13:23 2009 -0700
@@ -20,7 +20,7 @@
 #
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # This required package information file contains a list of package contents.
@@ -285,6 +285,14 @@
 d none etc/security/fmac 755 root bin
 f none etc/security/fmac/ss_policy 644 root sys
 f none etc/security/fmac/file_contexts 644 root sys
+f none etc/security/fmac/default_user 644 root sys
+d none etc/security/fmac/contexts 755 root sys
+f none etc/security/fmac/contexts/failsafe_context 644 root sys
+f none etc/security/fmac/contexts/default_contexts 644 root sys
+f none etc/security/fmac/contexts/default_type 644 root sys
+d none etc/security/fmac/contexts/users 755 root sys
+f none etc/security/fmac/contexts/users/user_u 644 root sys
+f none etc/security/fmac/contexts/users/sysadm_u 644 root sys
 f none etc/security/kmfpolicy.xml 644 root bin
 d none etc/security/lib 755 root sys
 f none etc/security/lib/audio_clean 555 root sys
--- a/usr/src/uts/common/sys/fmac/fmac.h	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/uts/common/sys/fmac/fmac.h	Thu May 07 13:13:23 2009 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -66,6 +66,7 @@
 #define	FMACSYS_LSETFILECON		14
 #define	FMACSYS_FGETFILECON		15
 #define	FMACSYS_FSETFILECON		16
+#define	FMACSYS_SECURITYCOMPUTEUSER	17
 
 #if defined(_KERNEL)
 extern int fmac_enabled;
--- a/usr/src/uts/common/sys/fmac/security.h	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/uts/common/sys/fmac/security.h	Thu May 07 13:13:23 2009 -0700
@@ -20,6 +20,11 @@
  */
 
 /*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
  * Original files contributed to OpenSolaris.org under license by the
  * United States Government (NSA) to Sun Microsystems, Inc.
  */
@@ -132,6 +137,11 @@
 	uint32_t *nel);
 
 /*
+ * Free the set of SIDs allocated by security_get_user_sids()
+ */
+void security_free_user_sids(security_id_t *sids, uint32_t nel);
+
+/*
  * Return the SIDs to use for an unlabeled file system
  * that is being mounted from the device with the
  * the kdevname `name'.  The `fs_sid' SID is returned for
--- a/usr/src/uts/common/syscall/fmacsys.c	Fri Apr 03 08:46:00 2009 -0700
+++ b/usr/src/uts/common/syscall/fmacsys.c	Thu May 07 13:13:23 2009 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -402,6 +402,81 @@
 	return (set_errno(ENOSYS));
 }
 
+static int
+fmac_securitycomputeuser(security_context_t scontext, const char *username,
+    void *buf, size_t buf_len)
+{
+	char		*kbuf;
+	size_t		kcontext_len;
+	security_id_t	*sids;
+	security_id_t	fromsid;
+	uint32_t	nel = 0;
+	int		err;
+	char		*toptr;
+
+	if (err = avc_has_perm(crgetsecid(CRED()), SECINITSID_SECURITY,
+	    SECCLASS_SECURITY, SECURITY__COMPUTE_USER, NULL))
+		return (set_errno(err));
+
+	kbuf = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP);
+
+	if (err = copyinstr(scontext, kbuf, FMAC_MAX_CONTEXT_LEN,
+	    &kcontext_len))
+		goto out;
+
+	if (err = security_context_to_sid(kbuf, kcontext_len, &fromsid)) {
+		goto out;
+	}
+
+	if (err = copyinstr(username, kbuf, FMAC_MAX_CONTEXT_LEN, NULL)) {
+		goto out;
+	}
+
+	if ((err = security_get_user_sids(fromsid, kbuf, &sids, &nel)) == 0) {
+		int i;
+
+		kmem_free(kbuf, FMAC_MAX_CONTEXT_LEN);
+		kbuf = NULL;
+
+		toptr = buf;
+
+		for (i = 0; i < nel; i++) {
+			security_context_t context;
+			uint32_t context_len;
+			int count = 0;
+
+			if ((err = security_sid_to_context(sids[i], &context,
+			    &context_len)) == 0) {
+				if (count + context_len > buf_len) {
+					err = ENOMEM;
+					security_context_free(context);
+					goto out;
+				}
+				if (copyout(context, toptr, context_len)) {
+					err = EFAULT;
+					security_context_free(context);
+					goto out;
+				}
+				toptr += context_len;
+				count += context_len;
+				security_context_free(context);
+			} else
+				goto out;
+		}
+	}
+out:
+	if (kbuf)
+		kmem_free(kbuf, FMAC_MAX_CONTEXT_LEN);
+
+	if (nel)
+		security_free_user_sids(sids, nel);
+
+	if (err)
+		return (set_errno(err));
+	else
+		return (nel);
+}
+
 int
 fmacsys(int op, void *a1, void *a2, void *a3, void *a4, void *a5)
 {
@@ -453,6 +528,9 @@
 	case FMACSYS_FSETFILECON:
 		return (fmacsys_fsetfilecon((int)(uintptr_t)a1,
 		    (security_context_t)a2));
+	case FMACSYS_SECURITYCOMPUTEUSER:
+		return (fmac_securitycomputeuser((security_context_t)a1,
+		    (const char *)a2, (void *)a3, (size_t)a4));
 	default:
 		return (set_errno(ENOSYS));
 	}