changeset 11567:640c39cb2d82 onnv_132

PSARC 2009/683 Reserved uid/gid for distinguishing unmappable users/groups in NFSv4 ACLs 6261858 ls(1) -l, getfacl(1), and setfacl(1) can return "Permission denied" due to "nobody" and ACLs
author Lisa Week <lisa.week@sun.com>
date Tue, 19 Jan 2010 20:05:21 -0700
parents b49aee2993d2
children 73d521803f1a
files usr/src/cmd/Adm/group usr/src/cmd/Adm/sun/passwd usr/src/cmd/Adm/sun/shadow usr/src/pkgdefs/common_files/i.group usr/src/pkgdefs/common_files/i.passwd usr/src/pkgdefs/common_files/i.shadow usr/src/uts/common/fs/nfs/nfs4_acl.c usr/src/uts/common/fs/nfs/nfs4_srv_attr.c usr/src/uts/common/fs/nfs/nfs4_vnops.c usr/src/uts/common/nfs/nfs4.h usr/src/uts/common/sys/param.h
diffstat 11 files changed, 194 insertions(+), 79 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/Adm/group	Tue Jan 19 18:43:58 2010 -0800
+++ b/usr/src/cmd/Adm/group	Tue Jan 19 20:05:21 2010 -0700
@@ -21,6 +21,7 @@
 webservd::80:
 postgres::90:
 slocate::95:
+unknown::96:
 nobody::60001:
 noaccess::60002:
 nogroup::65534:
--- a/usr/src/cmd/Adm/sun/passwd	Tue Jan 19 18:43:58 2010 -0800
+++ b/usr/src/cmd/Adm/sun/passwd	Tue Jan 19 20:05:21 2010 -0700
@@ -18,6 +18,7 @@
 webservd:x:80:80:WebServer Reserved UID:/:
 postgres:x:90:90:PostgreSQL Reserved UID:/:/usr/bin/pfksh
 svctag:x:95:12:Service Tag UID:/:
+unknown:x:96:96:Unknown Remote UID:/:
 nobody:x:60001:60001:NFS Anonymous Access User:/:
 noaccess:x:60002:60002:No Access User:/:
 nobody4:x:65534:65534:SunOS 4.x NFS Anonymous Access User:/:
--- a/usr/src/cmd/Adm/sun/shadow	Tue Jan 19 18:43:58 2010 -0800
+++ b/usr/src/cmd/Adm/sun/shadow	Tue Jan 19 20:05:21 2010 -0700
@@ -18,6 +18,7 @@
 webservd:*LK*:::::::
 postgres:NP:::::::
 svctag:*LK*:6445::::::
+unknown:*LK*:::::::
 nobody:*LK*:6445::::::
 noaccess:*LK*:6445::::::
 nobody4:*LK*:6445::::::
--- a/usr/src/pkgdefs/common_files/i.group	Tue Jan 19 18:43:58 2010 -0800
+++ b/usr/src/pkgdefs/common_files/i.group	Tue Jan 19 20:05:21 2010 -0700
@@ -19,7 +19,7 @@
 #
 # CDDL HEADER END
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -294,6 +294,25 @@
 '"$OPENLDAPGROUP_LINE"'' $dest > $TEMPF
 			mv -f $TEMPF $dest
                 fi
+   	        #	
+		# Add the 'unknown' group if it doesn't already exist.
+                #
+		UNKNOWNGROUP_LINE="unknown::96:"
+                cur_name=`awk -F: '$3 == 96 {print $1}' $dest`
+                cur_id=`awk -F: '$1 == "unknown" {print $3}' $dest`
+                if [ ! -z "$cur_name" -a "$cur_name" != "unknown" ]; then
+                        echo "ERROR: Reserved GID 96 already assigned" \
+                            "to '$cur_name'" >> /tmp/CLEANUP
+                elif [ ! -z "$cur_id" -a "$cur_id" != "96" ]; then
+                        echo "NOTE: unknown group already assigned" \
+                            "to id '$cur_id'" >> /tmp/CLEANUP
+                elif grep "$UNKNOWNGROUP_LINE" $dest >/dev/null 2>&1; then
+                        :
+                else
+                        sed '/^slocate::95:/ a\
+'"$UNKNOWNGROUP_LINE"'' $dest > $TEMPF
+			mv -f $TEMPF $dest
+                fi
 	fi
 done
 exit 0
--- a/usr/src/pkgdefs/common_files/i.passwd	Tue Jan 19 18:43:58 2010 -0800
+++ b/usr/src/pkgdefs/common_files/i.passwd	Tue Jan 19 20:05:21 2010 -0700
@@ -19,7 +19,7 @@
 #
 # CDDL HEADER END
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -271,6 +271,26 @@
 '"$UPNP_LIN"'' $dest > $TEMPF
 			mv -f $TEMPF $dest
 		fi
+
+		#
+		# Add the 'unknown' user if it doesn't exist.
+		#
+     		UNKNOWN_LIN="unknown:x:96:96:Unknown Remote UID:/:"
+		cur_name=`awk -F: '$3 == 96 { print $1 }' $dest`
+		cur_id=`awk -F: '$1 == "unknown" { print $3 }' $dest`
+		if [ ! -z "$cur_name" -a "$cur_name" != "unknown" ]; then
+			echo "ERROR: Reserved UID 96 already assigned" \
+			    "to '$cur_name'" >> /tmp/CLEANUP
+		elif [ ! -z "$cur_id" -a "$cur_id" != "96" ]; then
+			echo "NOTE: unknown username already assigned" \
+			    "to id '$cur_id'" >> /tmp/CLEANUP
+		elif grep "$UNKNOWN_LIN" $dest > /dev/null 2>&1; then
+			:
+		else
+			sed '/^svctag:x/ a\
+'"$UNKNOWN_LIN"'' $dest > $TEMPF
+			mv -f $TEMPF $dest
+		fi
 	fi
 done
 
--- a/usr/src/pkgdefs/common_files/i.shadow	Tue Jan 19 18:43:58 2010 -0800
+++ b/usr/src/pkgdefs/common_files/i.shadow	Tue Jan 19 20:05:21 2010 -0700
@@ -19,7 +19,7 @@
 #
 # CDDL HEADER END
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -144,6 +144,18 @@
 		fi
 
 		#
+		# Add the 'unknown' reserved user if it doesn't exist.
+		#
+		UNKNOWN_LINE="unknown:*LK*:::::::"
+		if grep "^unknown:" $dest >/dev/null 2>&1 >/dev/null; then
+			:
+		else
+			printf '/^svctag:*LK*\na\n%s\n.\nw\nq\n' \
+			    "$UNKNOWN_LINE" | ed -s $dest > /dev/null
+		fi
+	
+
+		#
 		# Add the 'dladm' reserved user if it doesn't exist.
 		#
 		DLADM_LINE="dladm:*LK*:::::::"
--- a/usr/src/uts/common/fs/nfs/nfs4_acl.c	Tue Jan 19 18:43:58 2010 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs4_acl.c	Tue Jan 19 20:05:21 2010 -0700
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * The following naming convention is used in function names.
  *
@@ -73,16 +71,17 @@
 static ace4vals_t *ace4vals_find(nfsace4 *, avl_tree_t *, int *);
 static int ace4_to_aent_legal(nfsace4 *, int);
 static int ace4vals_to_aent(ace4vals_t *, aclent_t *, ace4_list_t *,
-    uid_t, gid_t, int, int, int);
+    uid_t, gid_t, int, int);
 static int ace4_list_to_aent(ace4_list_t *, aclent_t **, int *, uid_t, gid_t,
-    int, int, int);
+    int, int);
 static int ln_ace4_to_aent(nfsace4 *ace4, int n, uid_t, gid_t,
-    aclent_t **, int *, aclent_t **, int *, int, int, int);
+    aclent_t **, int *, aclent_t **, int *, int, int);
 static int ace4_cmp(nfsace4 *, nfsace4 *);
 static int acet_to_ace4(ace_t *, nfsace4 *, int);
-static int ace4_to_acet(nfsace4 *, ace_t *, uid_t, gid_t, int, int);
-static int validate_idmapping(utf8string *, uid_t, int, int, int);
+static int ace4_to_acet(nfsace4 *, ace_t *, uid_t, gid_t, int);
+static int validate_idmapping(utf8string *, uid_t *, int, int);
 static int u8s_mapped_to_nobody(utf8string *, uid_t, int);
+static void remap_id(uid_t *, int);
 static void ace4_mask_to_acet_mask(acemask4, uint32_t *);
 static void acet_mask_to_ace4_mask(uint32_t, acemask4 *);
 static void ace4_flags_to_acet_flags(aceflag4, uint16_t *);
@@ -616,9 +615,44 @@
 				acep->flag |= ACE4_IDENTIFIER_GROUP;
 				error = 0;
 			} else if (aclent[i].a_type & USER) {
+				/*
+				 * On the client, we do not allow an ACL with
+				 * ACEs containing the UID_UNKNOWN user to be
+				 * set.  This is because having UID_UNKNOWN in
+				 * an ACE can only come from the user having
+				 * done a read-modify-write ACL manipulation
+				 * (e.g. setfacl -m or chmod A+) when there
+				 * was an ACE with an unmappable group already
+				 * present.
+				 */
+				if (aclent[i].a_id == UID_UNKNOWN &&
+				    !isserver) {
+					DTRACE_PROBE(
+					    nfs4clnt__err__acl__uid__unknown);
+					NFS4_DEBUG(nfs4_acl_debug, (CE_NOTE,
+					    "ln_aent_to_ace4: UID_UNKNOWN is "
+					    "not allowed in the ACL"));
+					error = EACCES;
+					goto out;
+				}
+
 				error = nfs_idmap_uid_str(aclent[i].a_id,
 				    &acep->who, isserver);
 			} else {
+				/*
+				 * Same rule as UID_UNKNOWN (above).
+				 */
+				if (aclent[i].a_id == GID_UNKNOWN &&
+				    !isserver) {
+					DTRACE_PROBE(
+					    nfs4clnt__err__acl__gid__unknown);
+					NFS4_DEBUG(nfs4_acl_debug, (CE_NOTE,
+					    "ln_aent_to_ace4: GID_UNKNOWN is "
+					    "not allowed in the ACL"));
+					error = EACCES;
+					goto out;
+				}
+
 				error = nfs_idmap_gid_str(aclent[i].a_id,
 				    &acep->who, isserver);
 				acep->flag |= ACE4_IDENTIFIER_GROUP;
@@ -812,15 +846,14 @@
 
 	if (aclentacl->vsa_aclcnt > 0) {
 		error = ln_aent_to_ace4(aclentacl->vsa_aclentp,
-			aclentacl->vsa_aclcnt, &acebuf, &acecnt,
-			    isdir, isserver);
+		    aclentacl->vsa_aclcnt, &acebuf, &acecnt, isdir, isserver);
 		if (error != 0)
 			goto out;
 	}
 	if (aclentacl->vsa_dfaclcnt > 0) {
 		error = ln_aent_to_ace4(aclentacl->vsa_dfaclentp,
-			aclentacl->vsa_dfaclcnt, &dfacebuf, &dfacecnt,
-			    isdir, isserver);
+		    aclentacl->vsa_dfaclcnt, &dfacebuf, &dfacecnt, isdir,
+		    isserver);
 		if (error != 0)
 			goto out;
 	}
@@ -1157,7 +1190,7 @@
 
 static int
 ace4vals_to_aent(ace4vals_t *vals, aclent_t *dest, ace4_list_t *list,
-    uid_t owner, gid_t group, int isdir, int isserver, int just_count)
+    uid_t owner, gid_t group, int isdir, int isserver)
 {
 	int error;
 	acemask4 flips = ACE4_POSIX_SUPPORTED_BITS;
@@ -1197,8 +1230,8 @@
 			goto out;
 		}
 
-		error = validate_idmapping(vals->key, dest->a_id,
-		    (dest->a_type & USER ? 1 : 0), isserver, just_count);
+		error = validate_idmapping(vals->key, &dest->a_id,
+		    (dest->a_type & USER ? 1 : 0), isserver);
 		if (error != 0) {
 			goto out;
 		}
@@ -1222,7 +1255,7 @@
 
 static int
 ace4_list_to_aent(ace4_list_t *list, aclent_t **aclentp, int *aclcnt,
-    uid_t owner, gid_t group, int isdir, int isserver, int just_count)
+    uid_t owner, gid_t group, int isdir, int isserver)
 {
 	int error = 0;
 	aclent_t *aent, *result = NULL;
@@ -1232,14 +1265,13 @@
 	if ((list->seen & (USER_OBJ | GROUP_OBJ | OTHER_OBJ)) !=
 	    (USER_OBJ | GROUP_OBJ | OTHER_OBJ)) {
 		NFS4_DEBUG(nfs4_acl_debug, (CE_NOTE,
-			"ace4_list_to_aent: required aclent_t entites "
-			"missing"));
+		    "ace4_list_to_aent: required aclent_t entites missing"));
 		error = ENOTSUP;
 		goto out;
 	}
 	if ((! list->hasmask) && (list->numusers + list->numgroups > 0)) {
 		NFS4_DEBUG(nfs4_acl_debug, (CE_NOTE,
-			"ace4_list_to_aent: CLASS_OBJ (mask) missing"));
+		    "ace4_list_to_aent: CLASS_OBJ (mask) missing"));
 		error = ENOTSUP;
 		goto out;
 	}
@@ -1257,7 +1289,7 @@
 	/* USER_OBJ */
 	ASSERT(list->user_obj.aent_type & USER_OBJ);
 	error = ace4vals_to_aent(&list->user_obj, aent, list, owner, group,
-	    isdir, isserver, just_count);
+	    isdir, isserver);
 
 	if (error != 0)
 		goto out;
@@ -1268,7 +1300,7 @@
 	    vals = AVL_NEXT(&list->user, vals)) {
 		ASSERT(vals->aent_type & USER);
 		error = ace4vals_to_aent(vals, aent, list, owner, group,
-		    isdir, isserver, just_count);
+		    isdir, isserver);
 		if (error != 0)
 			goto out;
 		++aent;
@@ -1276,7 +1308,7 @@
 	/* GROUP_OBJ */
 	ASSERT(list->group_obj.aent_type & GROUP_OBJ);
 	error = ace4vals_to_aent(&list->group_obj, aent, list, owner, group,
-	    isdir, isserver, just_count);
+	    isdir, isserver);
 	if (error != 0)
 		goto out;
 	++aent;
@@ -1286,7 +1318,7 @@
 	    vals = AVL_NEXT(&list->group, vals)) {
 		ASSERT(vals->aent_type & GROUP);
 		error = ace4vals_to_aent(vals, aent, list, owner, group,
-		    isdir, isserver, just_count);
+		    isdir, isserver);
 		if (error != 0)
 			goto out;
 		++aent;
@@ -1320,7 +1352,7 @@
 	/* OTHER_OBJ */
 	ASSERT(list->other_obj.aent_type & OTHER_OBJ);
 	error = ace4vals_to_aent(&list->other_obj, aent, list, owner, group,
-	    isdir, isserver, just_count);
+	    isdir, isserver);
 	if (error != 0)
 		goto out;
 	++aent;
@@ -1346,7 +1378,7 @@
     uid_t owner, gid_t group,
     aclent_t **aclentp, int *aclcnt,
     aclent_t **dfaclentp, int *dfaclcnt,
-    int isdir, int isserver, int just_count)
+    int isdir, int isserver)
 {
 	int error = 0;
 	nfsace4 *ace4p;
@@ -1527,13 +1559,13 @@
 	/* done collating; produce the aclent_t lists */
 	if (normacl->state != ace4_unused) {
 		error = ace4_list_to_aent(normacl, aclentp, aclcnt,
-		    owner, group, isdir, isserver, just_count);
+		    owner, group, isdir, isserver);
 		if (error != 0)
 			goto out;
 	}
 	if (dfacl->state != ace4_unused) {
 		error = ace4_list_to_aent(dfacl, dfaclentp, dfaclcnt,
-		    owner, group, isdir, isserver, just_count);
+		    owner, group, isdir, isserver);
 		if (error != 0)
 			goto out;
 	}
@@ -1554,7 +1586,7 @@
  */
 int
 vs_ace4_to_aent(vsecattr_t *vs_ace4, vsecattr_t *vs_aent,
-    uid_t owner, gid_t group, int isdir, int isserver, int just_count)
+    uid_t owner, gid_t group, int isdir, int isserver)
 {
 	int error = 0;
 
@@ -1562,7 +1594,7 @@
 	    owner, group,
 	    (aclent_t **)&vs_aent->vsa_aclentp, &vs_aent->vsa_aclcnt,
 	    (aclent_t **)&vs_aent->vsa_dfaclentp, &vs_aent->vsa_dfaclcnt,
-	    isdir, isserver, just_count);
+	    isdir, isserver);
 	if (error != 0)
 		goto out;
 
@@ -1665,6 +1697,22 @@
 		(void) str_to_utf8(ACE4_WHO_GROUP, &nfsace4->who);
 	} else if (ace->a_flags & ACE_IDENTIFIER_GROUP) {
 		nfsace4->flag |= ACE4_IDENTIFIER_GROUP;
+		/*
+		 * On the client, we do not allow an ACL with ACEs containing
+		 * the "unknown"/GID_UNKNOWN group to be set.  This is because
+		 * it having GID_UNKNOWN in an ACE can only come from
+		 * the user having done a read-modify-write ACL manipulation
+		 * (e.g. setfacl -m or chmod A+) when there was an ACE with
+		 * an unmappable group already present.
+		 */
+		if (ace->a_who == GID_UNKNOWN && !isserver) {
+			DTRACE_PROBE(nfs4clnt__err__acl__gid__unknown);
+			NFS4_DEBUG(nfs4_acl_debug, (CE_NOTE,
+			    "acet_to_ace4: GID_UNKNOWN is not allowed in "
+			    "the ACL"));
+			error = EACCES;
+			goto out;
+		}
 		error = nfs_idmap_gid_str(ace->a_who, &nfsace4->who, isserver);
 		if (error != 0)
 			NFS4_DEBUG(nfs4_acl_debug, (CE_NOTE,
@@ -1674,6 +1722,17 @@
 	} else if (ace->a_flags & ACE_EVERYONE) {
 		(void) str_to_utf8(ACE4_WHO_EVERYONE, &nfsace4->who);
 	} else {
+		/*
+		 * Same rule as GID_UNKNOWN (above).
+		 */
+		if (ace->a_who == UID_UNKNOWN && !isserver) {
+			DTRACE_PROBE(nfs4clnt__err__acl__uid__unknown);
+			NFS4_DEBUG(nfs4_acl_debug, (CE_NOTE,
+			    "acet_to_ace4: UID_UNKNOWN is not allowed in "
+			    "the ACL"));
+			error = EACCES;
+			goto out;
+		}
 		error = nfs_idmap_uid_str(ace->a_who, &nfsace4->who, isserver);
 		if (error != 0)
 			NFS4_DEBUG(nfs4_acl_debug, (CE_NOTE,
@@ -1690,7 +1749,7 @@
  */
 static int
 ace4_to_acet(nfsace4 *nfsace4, ace_t *ace, uid_t owner, gid_t group,
-    int isserver, int just_count)
+    int isserver)
 {
 	int error = 0;
 
@@ -1774,7 +1833,7 @@
 			goto out;
 		}
 		error = validate_idmapping(&nfsace4->who,
-		    ace->a_who, FALSE, isserver, just_count);
+		    &ace->a_who, FALSE, isserver);
 		if (error != 0)
 			goto out;
 	} else {
@@ -1789,7 +1848,7 @@
 			goto out;
 		}
 		error = validate_idmapping(&nfsace4->who,
-		    ace->a_who, TRUE, isserver, just_count);
+		    &ace->a_who, TRUE, isserver);
 		if (error != 0)
 			goto out;
 	}
@@ -1910,7 +1969,7 @@
 
 int
 vs_ace4_to_acet(vsecattr_t *vs_ace4, vsecattr_t *vs_acet,
-    uid_t owner, gid_t group, int isserver, int just_count)
+    uid_t owner, gid_t group, int isserver)
 {
 	int error;
 	int i;
@@ -1935,7 +1994,7 @@
 	for (i = 0; i < vs_ace4->vsa_aclcnt; i++) {
 		error = ace4_to_acet((nfsace4 *)(vs_ace4->vsa_aclentp) + i,
 		    (ace_t *)(vs_acet->vsa_aclentp) + i, owner, group,
-		    isserver, just_count);
+		    isserver);
 		if (error != 0)
 			goto out;
 	}
@@ -2086,14 +2145,14 @@
 }
 
 static int
-validate_idmapping(utf8string *orig_who, uid_t mapped_id, int isuser,
-	int isserver, int just_count)
+validate_idmapping(utf8string *orig_who, uid_t *mapped_id, int isuser,
+	int isserver)
 {
-	if (u8s_mapped_to_nobody(orig_who, mapped_id, isuser)) {
+	if (u8s_mapped_to_nobody(orig_who, *mapped_id, isuser)) {
 		if (isserver) {
 			char	*who = NULL;
 			uint_t	len = 0;
-
+			/* SERVER */
 			/*
 			 * This code path gets executed on the server
 			 * in the case that we are setting an ACL.
@@ -2120,35 +2179,24 @@
 			 * This code path gets executed on the client
 			 * when we are getting an ACL.
 			 *
-			 * If the caller just requested the count
-			 * don't fail the request just because we
-			 * failed mapping the other portions of the
-			 * ACL.  Things such as vn_createat expect it's
-			 * call to VOP_GETSECATTR (to get the
-			 * default acl count) to succeed in order to
-			 * create a file.
-			 *
-			 * If the caller requested more than the count,
-			 * return an error as we will not want to
-			 * silently map user or group to "nobody"
-			 * because of the semantics that an ACL
-			 * modification interface (i.e. - setfacl -m)
+			 * We do not want to silently map user or group to
+			 * "nobody" because of the semantics that an ACL
+			 * modification interface (i.e. - setfacl -m, chmod A+)
 			 * may use to modify an ACL (i.e. - get the ACL
 			 * then use it as a basis for setting the
-			 * modified ACL).
+			 * modified ACL).  Therefore, change the mapping.
 			 */
 			who = utf8_to_str(orig_who, &len, NULL);
-			if (just_count) {
-				DTRACE_PROBE1(nfs4__acl__nobody, char *, who);
-				if (who != NULL)
-					kmem_free(who, len);
-				return (0);
-			} else {
-				DTRACE_PROBE1(nfs4__acl__nobody, char *, who);
-				if (who != NULL)
-					kmem_free(who, len);
-				return (EACCES);
-			}
+			DTRACE_PROBE1(nfs4__acl__nobody, char *, who);
+			if (who != NULL)
+				kmem_free(who, len);
+
+			/*
+			 * Re-mapped from UID_NOBODY/GID_NOBODY
+			 * to UID_UNKNOWN/GID_UNKNOWN and return.
+			 */
+			remap_id(mapped_id, isuser);
+			return (0);
 		}
 	}
 	return (0);
@@ -2169,3 +2217,17 @@
 
 	return (mapped_id == GID_NOBODY);
 }
+
+/*
+ * This function is used in the case that the utf8string passed over the wire
+ * was mapped to UID_NOBODY or GID_NOBODY and we will remap the id to
+ * to the appropriate mapping.  That is UID_UNKNOWN or GID_UNKNOWN.
+ */
+static void
+remap_id(uid_t *id, int isuser)
+{
+	if (isuser)
+		*id = UID_UNKNOWN;
+
+	*id = GID_UNKNOWN;
+}
--- a/usr/src/uts/common/fs/nfs/nfs4_srv_attr.c	Tue Jan 19 18:43:58 2010 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs4_srv_attr.c	Tue Jan 19 20:05:21 2010 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -1007,7 +1007,7 @@
 
 		if (whichacl & _ACL_ACE_ENABLED) {
 			error = vs_ace4_to_acet(&vs_ace4, &vs_native,
-			    vap->va_uid, vap->va_gid, TRUE, FALSE);
+			    vap->va_uid, vap->va_gid, TRUE);
 			if (error != 0)
 				break;
 			(void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
@@ -1017,8 +1017,7 @@
 			vs_acet_destroy(&vs_native);
 		} else if (whichacl & _ACL_ACLENT_ENABLED) {
 			error = vs_ace4_to_aent(&vs_ace4, &vs_native,
-			    vap->va_uid, vap->va_gid, vp->v_type == VDIR, TRUE,
-			    FALSE);
+			    vap->va_uid, vap->va_gid, vp->v_type == VDIR, TRUE);
 			if (error != 0)
 				break;
 			(void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
--- a/usr/src/uts/common/fs/nfs/nfs4_vnops.c	Tue Jan 19 18:43:58 2010 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs4_vnops.c	Tue Jan 19 20:05:21 2010 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -12478,8 +12478,7 @@
 	uint_t	orig_mask = vsap->vsa_mask;
 
 	if (orig_mask & (VSA_ACE | VSA_ACECNT)) {
-		error = vs_ace4_to_acet(filled_vsap, vsap, uid, gid,
-		    FALSE, ((orig_mask & VSA_ACE) ? FALSE : TRUE));
+		error = vs_ace4_to_acet(filled_vsap, vsap, uid, gid, FALSE);
 
 		if (error)
 			return (error);
@@ -12500,8 +12499,7 @@
 	} else if (orig_mask & (VSA_ACL | VSA_ACLCNT | VSA_DFACL |
 	    VSA_DFACLCNT)) {
 		error = vs_ace4_to_aent(filled_vsap, vsap, uid, gid,
-		    isdir, FALSE,
-		    ((orig_mask & (VSA_ACL | VSA_DFACL)) ? FALSE : TRUE));
+		    isdir, FALSE);
 
 		if (error)
 			return (error);
--- a/usr/src/uts/common/nfs/nfs4.h	Tue Jan 19 18:43:58 2010 -0800
+++ b/usr/src/uts/common/nfs/nfs4.h	Tue Jan 19 20:05:21 2010 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -1312,9 +1312,9 @@
 extern int	ln_ace4_cmp(nfsace4 *, nfsace4 *, int);
 extern int	vs_aent_to_ace4(vsecattr_t *, vsecattr_t *, int, int);
 extern int	vs_ace4_to_aent(vsecattr_t *, vsecattr_t *, uid_t, gid_t,
-    int, int, int);
+    int, int);
 extern int	vs_ace4_to_acet(vsecattr_t *, vsecattr_t *, uid_t, gid_t,
-    int, int);
+    int);
 extern int	vs_acet_to_ace4(vsecattr_t *, vsecattr_t *, int);
 extern void	vs_acet_destroy(vsecattr_t *);
 extern void	vs_ace4_destroy(vsecattr_t *);
--- a/usr/src/uts/common/sys/param.h	Tue Jan 19 18:43:58 2010 -0800
+++ b/usr/src/uts/common/sys/param.h	Tue Jan 19 20:05:21 2010 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -79,6 +79,8 @@
 
 #define	UID_NOBODY	60001	/* user ID no body */
 #define	GID_NOBODY	UID_NOBODY
+#define	UID_UNKNOWN	96
+#define	GID_UNKNOWN	UID_UNKNOWN
 #define	GID_SYS		3
 #define	UID_DLADM	15
 #define	UID_NOACCESS	60002	/* user ID no access */