usr/src/uts/common/fs/nfs/nfs4_srv.c
changeset 1676 37f4a3e2bd99
parent 1146 c3555cdf52c2
child 2035 a29bc457bcb9
equal deleted inserted replaced
1675:5791e75682d0 1676:37f4a3e2bd99
     1 /*
     1 /*
     2  * CDDL HEADER START
     2  * CDDL HEADER START
     3  *
     3  *
     4  * The contents of this file are subject to the terms of the
     4  * The contents of this file are subject to the terms of the
     5  * Common Development and Distribution License, Version 1.0 only
     5  * Common Development and Distribution License (the "License").
     6  * (the "License").  You may not use this file except in compliance
     6  * You may not use this file except in compliance with the License.
     7  * with the License.
       
     8  *
     7  *
     9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    10  * or http://www.opensolaris.org/os/licensing.
     9  * or http://www.opensolaris.org/os/licensing.
    11  * See the License for the specific language governing permissions
    10  * See the License for the specific language governing permissions
    12  * and limitations under the License.
    11  * and limitations under the License.
    18  * information: Portions Copyright [yyyy] [name of copyright owner]
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
    19  *
    18  *
    20  * CDDL HEADER END
    19  * CDDL HEADER END
    21  */
    20  */
    22 /*
    21 /*
    23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
    22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
    24  * Use is subject to license terms.
    23  * Use is subject to license terms.
    25  */
    24  */
    26 
    25 
    27 /*
    26 /*
    28  *	Copyright (c) 1983,1984,1985,1986,1987,1988,1989  AT&T.
    27  *	Copyright (c) 1983,1984,1985,1986,1987,1988,1989  AT&T.
    52 #include <sys/nbmlock.h>
    51 #include <sys/nbmlock.h>
    53 #include <sys/share.h>
    52 #include <sys/share.h>
    54 #include <sys/atomic.h>
    53 #include <sys/atomic.h>
    55 #include <sys/policy.h>
    54 #include <sys/policy.h>
    56 #include <sys/fem.h>
    55 #include <sys/fem.h>
       
    56 #include <sys/sdt.h>
    57 
    57 
    58 #include <rpc/types.h>
    58 #include <rpc/types.h>
    59 #include <rpc/auth.h>
    59 #include <rpc/auth.h>
    60 #include <rpc/rpcsec_gss.h>
    60 #include <rpc/rpcsec_gss.h>
    61 #include <rpc/svc.h>
    61 #include <rpc/svc.h>
    69 #include <sys/strsun.h>
    69 #include <sys/strsun.h>
    70 
    70 
    71 #include <inet/common.h>
    71 #include <inet/common.h>
    72 #include <inet/ip.h>
    72 #include <inet/ip.h>
    73 #include <inet/ip6.h>
    73 #include <inet/ip6.h>
       
    74 
       
    75 #include <sys/tsol/label.h>
       
    76 #include <sys/tsol/tndb.h>
    74 
    77 
    75 #define	RFS4_MAXLOCK_TRIES 4	/* Try to get the lock this many times */
    78 #define	RFS4_MAXLOCK_TRIES 4	/* Try to get the lock this many times */
    76 static int rfs4_maxlock_tries = RFS4_MAXLOCK_TRIES;
    79 static int rfs4_maxlock_tries = RFS4_MAXLOCK_TRIES;
    77 #define	RFS4_LOCK_DELAY 10	/* Milliseconds */
    80 #define	RFS4_LOCK_DELAY 10	/* Milliseconds */
    78 static clock_t rfs4_lock_delay = RFS4_LOCK_DELAY;
    81 static clock_t rfs4_lock_delay = RFS4_LOCK_DELAY;
   132  * cookie: uint64_t   +  utf8namelen: uint_t  +   utf8name padded to 8 bytes
   135  * cookie: uint64_t   +  utf8namelen: uint_t  +   utf8name padded to 8 bytes
   133  *
   136  *
   134  */
   137  */
   135 #define	DIRENT64_TO_DIRCOUNT(dp) \
   138 #define	DIRENT64_TO_DIRCOUNT(dp) \
   136 	(3 * BYTES_PER_XDR_UNIT + DIRENT64_NAMELEN((dp)->d_reclen))
   139 	(3 * BYTES_PER_XDR_UNIT + DIRENT64_NAMELEN((dp)->d_reclen))
       
   140 
       
   141 /*
       
   142  * types of label comparison
       
   143  */
       
   144 #define	EQUALITY_CHECK	0
       
   145 #define	DOMINANCE_CHECK	1
   137 
   146 
   138 time_t rfs4_start_time;			/* Initialized in rfs4_srvrinit */
   147 time_t rfs4_start_time;			/* Initialized in rfs4_srvrinit */
   139 
   148 
   140 static sysid_t lockt_sysid;		/* dummy sysid for all LOCKT calls */
   149 static sysid_t lockt_sysid;		/* dummy sysid for all LOCKT calls */
   141 
   150 
  1162 	kmem_free(resok_val, count * sizeof (secinfo4));
  1171 	kmem_free(resok_val, count * sizeof (secinfo4));
  1163 	resp->SECINFO4resok_len = 0;
  1172 	resp->SECINFO4resok_len = 0;
  1164 	resp->SECINFO4resok_val = NULL;
  1173 	resp->SECINFO4resok_val = NULL;
  1165 }
  1174 }
  1166 
  1175 
       
  1176 /*
       
  1177  * do label check on client label and server's file lable.
       
  1178  */
       
  1179 static boolean_t
       
  1180 do_rfs4_label_check(bslabel_t *clabel, vnode_t *vp, int flag)
       
  1181 {
       
  1182 	bslabel_t *slabel;
       
  1183 	ts_label_t *tslabel;
       
  1184 	boolean_t result;
       
  1185 
       
  1186 	if ((tslabel = nfs4_getflabel(vp)) == NULL) {
       
  1187 		return (B_FALSE);
       
  1188 	}
       
  1189 	slabel = label2bslabel(tslabel);
       
  1190 	DTRACE_PROBE4(tx__rfs4__log__info__labelcheck, char *,
       
  1191 	    "comparing server's file label(1) with client label(2) (vp(3))",
       
  1192 	    bslabel_t *, slabel, bslabel_t *, clabel, vnode_t *, vp);
       
  1193 
       
  1194 	if (flag == EQUALITY_CHECK)
       
  1195 		result = blequal(clabel, slabel);
       
  1196 	else
       
  1197 		result = bldominates(clabel, slabel);
       
  1198 	label_rele(tslabel);
       
  1199 	return (result);
       
  1200 }
       
  1201 
  1167 /* ARGSUSED */
  1202 /* ARGSUSED */
  1168 static void
  1203 static void
  1169 rfs4_op_access(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
  1204 rfs4_op_access(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
  1170 	struct compound_state *cs)
  1205 	struct compound_state *cs)
  1171 {
  1206 {
  1174 	int error;
  1209 	int error;
  1175 	vnode_t *vp;
  1210 	vnode_t *vp;
  1176 	struct vattr va;
  1211 	struct vattr va;
  1177 	int checkwriteperm;
  1212 	int checkwriteperm;
  1178 	cred_t *cr = cs->cr;
  1213 	cred_t *cr = cs->cr;
       
  1214 	bslabel_t *clabel, *slabel;
       
  1215 	ts_label_t *tslabel;
       
  1216 	boolean_t admin_low_client;
  1179 
  1217 
  1180 #if 0	/* XXX allow access even if !cs->access. Eventually only pseudo fs */
  1218 #if 0	/* XXX allow access even if !cs->access. Eventually only pseudo fs */
  1181 	if (cs->access == CS_ACCESS_DENIED) {
  1219 	if (cs->access == CS_ACCESS_DENIED) {
  1182 		*cs->statusp = resp->status = NFS4ERR_ACCESS;
  1220 		*cs->statusp = resp->status = NFS4ERR_ACCESS;
  1183 		return;
  1221 		return;
  1215 	error = VOP_GETATTR(vp, &va, 0, cr);
  1253 	error = VOP_GETATTR(vp, &va, 0, cr);
  1216 	if (error) {
  1254 	if (error) {
  1217 		*cs->statusp = resp->status = puterrno4(error);
  1255 		*cs->statusp = resp->status = puterrno4(error);
  1218 		return;
  1256 		return;
  1219 	}
  1257 	}
  1220 
       
  1221 	resp->access = 0;
  1258 	resp->access = 0;
  1222 	resp->supported = 0;
  1259 	resp->supported = 0;
  1223 
  1260 
       
  1261 	if (is_system_labeled()) {
       
  1262 		ASSERT(req->rq_label != NULL);
       
  1263 		clabel = req->rq_label;
       
  1264 		DTRACE_PROBE2(tx__rfs4__log__info__opaccess__clabel, char *,
       
  1265 		    "got client label from request(1)",
       
  1266 		    struct svc_req *, req);
       
  1267 		if (!blequal(&l_admin_low->tsl_label, clabel)) {
       
  1268 			if ((tslabel = nfs4_getflabel(vp)) == NULL) {
       
  1269 				*cs->statusp = resp->status = puterrno4(EACCES);
       
  1270 				return;
       
  1271 			}
       
  1272 			slabel = label2bslabel(tslabel);
       
  1273 			DTRACE_PROBE3(tx__rfs4__log__info__opaccess__slabel,
       
  1274 			    char *, "got server label(1) for vp(2)",
       
  1275 			    bslabel_t *, slabel, vnode_t *, vp);
       
  1276 
       
  1277 			admin_low_client = B_FALSE;
       
  1278 		} else
       
  1279 			admin_low_client = B_TRUE;
       
  1280 	}
       
  1281 
  1224 	if (args->access & ACCESS4_READ) {
  1282 	if (args->access & ACCESS4_READ) {
  1225 		error = VOP_ACCESS(vp, VREAD, 0, cr);
  1283 		error = VOP_ACCESS(vp, VREAD, 0, cr);
  1226 		if (!error && !MANDLOCK(vp, va.va_mode))
  1284 		if (!error && !MANDLOCK(vp, va.va_mode) &&
       
  1285 		    (!is_system_labeled() || admin_low_client ||
       
  1286 		    bldominates(clabel, slabel)))
  1227 			resp->access |= ACCESS4_READ;
  1287 			resp->access |= ACCESS4_READ;
  1228 		resp->supported |= ACCESS4_READ;
  1288 		resp->supported |= ACCESS4_READ;
  1229 	}
  1289 	}
  1230 	if ((args->access & ACCESS4_LOOKUP) && vp->v_type == VDIR) {
  1290 	if ((args->access & ACCESS4_LOOKUP) && vp->v_type == VDIR) {
  1231 		error = VOP_ACCESS(vp, VEXEC, 0, cr);
  1291 		error = VOP_ACCESS(vp, VEXEC, 0, cr);
  1232 		if (!error)
  1292 		if (!error && (!is_system_labeled() || admin_low_client ||
       
  1293 		    bldominates(clabel, slabel)))
  1233 			resp->access |= ACCESS4_LOOKUP;
  1294 			resp->access |= ACCESS4_LOOKUP;
  1234 		resp->supported |= ACCESS4_LOOKUP;
  1295 		resp->supported |= ACCESS4_LOOKUP;
  1235 	}
  1296 	}
  1236 	if (checkwriteperm &&
  1297 	if (checkwriteperm &&
  1237 	    (args->access & (ACCESS4_MODIFY|ACCESS4_EXTEND))) {
  1298 	    (args->access & (ACCESS4_MODIFY|ACCESS4_EXTEND))) {
  1238 		error = VOP_ACCESS(vp, VWRITE, 0, cr);
  1299 		error = VOP_ACCESS(vp, VWRITE, 0, cr);
  1239 		if (!error && !MANDLOCK(vp, va.va_mode))
  1300 		if (!error && !MANDLOCK(vp, va.va_mode) &&
       
  1301 		    (!is_system_labeled() || admin_low_client ||
       
  1302 		    blequal(clabel, slabel)))
  1240 			resp->access |=
  1303 			resp->access |=
  1241 			    (args->access & (ACCESS4_MODIFY|ACCESS4_EXTEND));
  1304 			    (args->access & (ACCESS4_MODIFY|ACCESS4_EXTEND));
  1242 		resp->supported |= (ACCESS4_MODIFY|ACCESS4_EXTEND);
  1305 		resp->supported |= (ACCESS4_MODIFY|ACCESS4_EXTEND);
  1243 	}
  1306 	}
  1244 
  1307 
  1245 	if (checkwriteperm &&
  1308 	if (checkwriteperm &&
  1246 	    (args->access & ACCESS4_DELETE) && vp->v_type == VDIR) {
  1309 	    (args->access & ACCESS4_DELETE) && vp->v_type == VDIR) {
  1247 		error = VOP_ACCESS(vp, VWRITE, 0, cr);
  1310 		error = VOP_ACCESS(vp, VWRITE, 0, cr);
  1248 		if (!error)
  1311 		if (!error && (!is_system_labeled() || admin_low_client ||
       
  1312 		    blequal(clabel, slabel)))
  1249 			resp->access |= ACCESS4_DELETE;
  1313 			resp->access |= ACCESS4_DELETE;
  1250 		resp->supported |= ACCESS4_DELETE;
  1314 		resp->supported |= ACCESS4_DELETE;
  1251 	}
  1315 	}
  1252 	if (args->access & ACCESS4_EXECUTE && vp->v_type != VDIR) {
  1316 	if (args->access & ACCESS4_EXECUTE && vp->v_type != VDIR) {
  1253 		error = VOP_ACCESS(vp, VEXEC, 0, cr);
  1317 		error = VOP_ACCESS(vp, VEXEC, 0, cr);
  1254 		if (!error && !MANDLOCK(vp, va.va_mode))
  1318 		if (!error && !MANDLOCK(vp, va.va_mode) &&
       
  1319 		    (!is_system_labeled() || admin_low_client ||
       
  1320 		    bldominates(clabel, slabel)))
  1255 			resp->access |= ACCESS4_EXECUTE;
  1321 			resp->access |= ACCESS4_EXECUTE;
  1256 		resp->supported |= ACCESS4_EXECUTE;
  1322 		resp->supported |= ACCESS4_EXECUTE;
  1257 	}
  1323 	}
       
  1324 
       
  1325 	if (is_system_labeled() && !admin_low_client)
       
  1326 		label_rele(tslabel);
  1258 
  1327 
  1259 	*cs->statusp = resp->status = NFS4_OK;
  1328 	*cs->statusp = resp->status = NFS4_OK;
  1260 }
  1329 }
  1261 
  1330 
  1262 /* ARGSUSED */
  1331 /* ARGSUSED */
  2539 			cs->vp = oldvp;
  2608 			cs->vp = oldvp;
  2540 			return (stat);
  2609 			return (stat);
  2541 		}
  2610 		}
  2542 	}
  2611 	}
  2543 
  2612 
       
  2613 	/*
       
  2614 	 * After various NFS checks, do a label check on the path
       
  2615 	 * component. The label on this path should either be the
       
  2616 	 * global zone's label or a zone's label. We are only
       
  2617 	 * interested in the zone's label because exported files
       
  2618 	 * in global zone is accessible (though read-only) to
       
  2619 	 * clients. The exportability/visibility check is already
       
  2620 	 * done before reaching this code.
       
  2621 	 */
       
  2622 	if (is_system_labeled()) {
       
  2623 		bslabel_t *clabel;
       
  2624 
       
  2625 		ASSERT(req->rq_label != NULL);
       
  2626 		clabel = req->rq_label;
       
  2627 		DTRACE_PROBE2(tx__rfs4__log__info__oplookup__clabel, char *,
       
  2628 		    "got client label from request(1)", struct svc_req *, req);
       
  2629 
       
  2630 		if (!blequal(&l_admin_low->tsl_label, clabel)) {
       
  2631 			if (!do_rfs4_label_check(clabel, vp, DOMINANCE_CHECK)) {
       
  2632 				error = EACCES;
       
  2633 				goto err_out;
       
  2634 			}
       
  2635 		} else {
       
  2636 			/*
       
  2637 			 * We grant access to admin_low label clients
       
  2638 			 * only if the client is trusted, i.e. also
       
  2639 			 * running Solaris Trusted Extension.
       
  2640 			 */
       
  2641 			struct sockaddr	*ca;
       
  2642 			int		addr_type;
       
  2643 			void		*ipaddr;
       
  2644 			tsol_tpc_t	*tp;
       
  2645 
       
  2646 			ca = (struct sockaddr *)svc_getrpccaller(
       
  2647 			    req->rq_xprt)->buf;
       
  2648 			if (ca->sa_family == AF_INET) {
       
  2649 				addr_type = IPV4_VERSION;
       
  2650 				ipaddr = &((struct sockaddr_in *)ca)->sin_addr;
       
  2651 			} else if (ca->sa_family == AF_INET6) {
       
  2652 				addr_type = IPV6_VERSION;
       
  2653 				ipaddr = &((struct sockaddr_in6 *)
       
  2654 				    ca)->sin6_addr;
       
  2655 			}
       
  2656 			tp = find_tpc(ipaddr, addr_type, B_FALSE);
       
  2657 			if (tp == NULL || tp->tpc_tp.tp_doi !=
       
  2658 			    l_admin_low->tsl_doi || tp->tpc_tp.host_type !=
       
  2659 			    SUN_CIPSO) {
       
  2660 				error = EACCES;
       
  2661 				goto err_out;
       
  2662 			}
       
  2663 		}
       
  2664 	}
       
  2665 
  2544 	error = makefh4(&cs->fh, vp, cs->exi);
  2666 	error = makefh4(&cs->fh, vp, cs->exi);
  2545 
  2667 
       
  2668 err_out:
  2546 	if (error) {
  2669 	if (error) {
  2547 		if (is_newvp) {
  2670 		if (is_newvp) {
  2548 			VN_RELE(cs->vp);
  2671 			VN_RELE(cs->vp);
  2549 			cs->vp = oldvp;
  2672 			cs->vp = oldvp;
  2550 		} else
  2673 		} else
  3573 	struct vattr bdva, idva, adva;
  3696 	struct vattr bdva, idva, adva;
  3574 	char *nm;
  3697 	char *nm;
  3575 	uint_t len;
  3698 	uint_t len;
  3576 	rfs4_file_t *fp;
  3699 	rfs4_file_t *fp;
  3577 	int in_crit = 0;
  3700 	int in_crit = 0;
       
  3701 	bslabel_t *clabel;
  3578 
  3702 
  3579 	/* CURRENT_FH: directory */
  3703 	/* CURRENT_FH: directory */
  3580 	dvp = cs->vp;
  3704 	dvp = cs->vp;
  3581 	if (dvp == NULL) {
  3705 	if (dvp == NULL) {
  3582 		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
  3706 		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
  3664 			if (fp) {
  3788 			if (fp) {
  3665 				rfs4_clear_dont_grant(fp);
  3789 				rfs4_clear_dont_grant(fp);
  3666 				rfs4_file_rele(fp);
  3790 				rfs4_file_rele(fp);
  3667 			}
  3791 			}
  3668 			return;
  3792 			return;
       
  3793 		}
       
  3794 	}
       
  3795 
       
  3796 	/* check label before allowing removal */
       
  3797 	if (is_system_labeled()) {
       
  3798 		ASSERT(req->rq_label != NULL);
       
  3799 		clabel = req->rq_label;
       
  3800 		DTRACE_PROBE2(tx__rfs4__log__info__opremove__clabel, char *,
       
  3801 		    "got client label from request(1)",
       
  3802 		    struct svc_req *, req);
       
  3803 		if (!blequal(&l_admin_low->tsl_label, clabel)) {
       
  3804 			if (!do_rfs4_label_check(clabel, vp, EQUALITY_CHECK)) {
       
  3805 				*cs->statusp = resp->status = NFS4ERR_ACCESS;
       
  3806 				kmem_free(nm, len);
       
  3807 				if (in_crit)
       
  3808 					nbl_end_crit(vp);
       
  3809 				VN_RELE(vp);
       
  3810 				if (fp) {
       
  3811 					rfs4_clear_dont_grant(fp);
       
  3812 					rfs4_file_rele(fp);
       
  3813 				}
       
  3814 				return;
       
  3815 			}
  3669 		}
  3816 		}
  3670 	}
  3817 	}
  3671 
  3818 
  3672 	/* Get dir "before" change value */
  3819 	/* Get dir "before" change value */
  3673 	bdva.va_mask = AT_CTIME|AT_SEQ;
  3820 	bdva.va_mask = AT_CTIME|AT_SEQ;
  3807 	char *onm, *nnm;
  3954 	char *onm, *nnm;
  3808 	uint_t olen, nlen;
  3955 	uint_t olen, nlen;
  3809 	rfs4_file_t *fp, *sfp;
  3956 	rfs4_file_t *fp, *sfp;
  3810 	int in_crit_src, in_crit_targ;
  3957 	int in_crit_src, in_crit_targ;
  3811 	int fp_rele_grant_hold, sfp_rele_grant_hold;
  3958 	int fp_rele_grant_hold, sfp_rele_grant_hold;
       
  3959 	bslabel_t *clabel;
  3812 
  3960 
  3813 	fp = sfp = NULL;
  3961 	fp = sfp = NULL;
  3814 	srcvp = targvp = NULL;
  3962 	srcvp = targvp = NULL;
  3815 	in_crit_src = in_crit_targ = 0;
  3963 	in_crit_src = in_crit_targ = 0;
  3816 	fp_rele_grant_hold = sfp_rele_grant_hold = 0;
  3964 	fp_rele_grant_hold = sfp_rele_grant_hold = 0;
  3896 	if (rdonly4(cs->exi, cs->vp, req)) {
  4044 	if (rdonly4(cs->exi, cs->vp, req)) {
  3897 		*cs->statusp = resp->status = NFS4ERR_ROFS;
  4045 		*cs->statusp = resp->status = NFS4ERR_ROFS;
  3898 		kmem_free(onm, olen);
  4046 		kmem_free(onm, olen);
  3899 		kmem_free(nnm, nlen);
  4047 		kmem_free(nnm, nlen);
  3900 		return;
  4048 		return;
       
  4049 	}
       
  4050 
       
  4051 	/* check label of the target dir */
       
  4052 	if (is_system_labeled()) {
       
  4053 		ASSERT(req->rq_label != NULL);
       
  4054 		clabel = req->rq_label;
       
  4055 		DTRACE_PROBE2(tx__rfs4__log__info__oprename__clabel, char *,
       
  4056 		    "got client label from request(1)",
       
  4057 		    struct svc_req *, req);
       
  4058 		if (!blequal(&l_admin_low->tsl_label, clabel)) {
       
  4059 			if (!do_rfs4_label_check(clabel, ndvp,
       
  4060 			    EQUALITY_CHECK)) {
       
  4061 				*cs->statusp = resp->status = NFS4ERR_ACCESS;
       
  4062 				return;
       
  4063 			}
       
  4064 		}
  3901 	}
  4065 	}
  3902 
  4066 
  3903 	/*
  4067 	/*
  3904 	 * Is the source a file and have a delegation?
  4068 	 * Is the source a file and have a delegation?
  3905 	 * We don't need to acquire va_seq before these lookups, if
  4069 	 * We don't need to acquire va_seq before these lookups, if
  4710 rfs4_op_setattr(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
  4874 rfs4_op_setattr(nfs_argop4 *argop, nfs_resop4 *resop, struct svc_req *req,
  4711 	struct compound_state *cs)
  4875 	struct compound_state *cs)
  4712 {
  4876 {
  4713 	SETATTR4args *args = &argop->nfs_argop4_u.opsetattr;
  4877 	SETATTR4args *args = &argop->nfs_argop4_u.opsetattr;
  4714 	SETATTR4res *resp = &resop->nfs_resop4_u.opsetattr;
  4878 	SETATTR4res *resp = &resop->nfs_resop4_u.opsetattr;
       
  4879 	bslabel_t *clabel;
  4715 
  4880 
  4716 	if (cs->vp == NULL) {
  4881 	if (cs->vp == NULL) {
  4717 		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
  4882 		*cs->statusp = resp->status = NFS4ERR_NOFILEHANDLE;
  4718 		return;
  4883 		return;
  4719 	}
  4884 	}
  4730 	resp->attrsset = 0;
  4895 	resp->attrsset = 0;
  4731 
  4896 
  4732 	if (rdonly4(cs->exi, cs->vp, req)) {
  4897 	if (rdonly4(cs->exi, cs->vp, req)) {
  4733 		*cs->statusp = resp->status = NFS4ERR_ROFS;
  4898 		*cs->statusp = resp->status = NFS4ERR_ROFS;
  4734 		return;
  4899 		return;
       
  4900 	}
       
  4901 
       
  4902 	/* check label before setting attributes */
       
  4903 	if (is_system_labeled()) {
       
  4904 		ASSERT(req->rq_label != NULL);
       
  4905 		clabel = req->rq_label;
       
  4906 		DTRACE_PROBE2(tx__rfs4__log__info__opsetattr__clabel, char *,
       
  4907 		    "got client label from request(1)",
       
  4908 		    struct svc_req *, req);
       
  4909 		if (!blequal(&l_admin_low->tsl_label, clabel)) {
       
  4910 			if (!do_rfs4_label_check(clabel, cs->vp,
       
  4911 			    EQUALITY_CHECK)) {
       
  4912 				*cs->statusp = resp->status = NFS4ERR_ACCESS;
       
  4913 				return;
       
  4914 			}
       
  4915 		}
  4735 	}
  4916 	}
  4736 
  4917 
  4737 	*cs->statusp = resp->status =
  4918 	*cs->statusp = resp->status =
  4738 		do_rfs4_op_setattr(&resp->attrsset, &args->obj_attributes, cs,
  4919 		do_rfs4_op_setattr(&resp->attrsset, &args->obj_attributes, cs,
  4739 			&args->stateid);
  4920 			&args->stateid);
  5185 
  5366 
  5186 	if (cs.basecr)
  5367 	if (cs.basecr)
  5187 		crfree(cs.basecr);
  5368 		crfree(cs.basecr);
  5188 	if (cs.cr)
  5369 	if (cs.cr)
  5189 		crfree(cs.cr);
  5370 		crfree(cs.cr);
       
  5371 	/*
       
  5372 	 * done with this compound request, free the label
       
  5373 	 */
       
  5374 
       
  5375 	if (req->rq_label != NULL) {
       
  5376 		kmem_free(req->rq_label, sizeof (bslabel_t));
       
  5377 		req->rq_label = NULL;
       
  5378 	}
  5190 }
  5379 }
  5191 
  5380 
  5192 /*
  5381 /*
  5193  * XXX because of what appears to be duplicate calls to rfs4_compound_free
  5382  * XXX because of what appears to be duplicate calls to rfs4_compound_free
  5194  * XXX zero out the tag and array values. Need to investigate why the
  5383  * XXX zero out the tag and array values. Need to investigate why the
  5575 	len_t reqsize;
  5764 	len_t reqsize;
  5576 	int error;
  5765 	int error;
  5577 	bool_t trunc;
  5766 	bool_t trunc;
  5578 	caller_context_t ct;
  5767 	caller_context_t ct;
  5579 	component4 *component;
  5768 	component4 *component;
       
  5769 	bslabel_t *clabel;
  5580 
  5770 
  5581 	sarg.sbp = &sb;
  5771 	sarg.sbp = &sb;
  5582 
  5772 
  5583 	dvp = cs->vp;
  5773 	dvp = cs->vp;
  5584 
  5774 
  5585 	/* Check if the file system is read only */
  5775 	/* Check if the file system is read only */
  5586 	if (rdonly4(cs->exi, dvp, req))
  5776 	if (rdonly4(cs->exi, dvp, req))
  5587 		return (NFS4ERR_ROFS);
  5777 		return (NFS4ERR_ROFS);
       
  5778 
       
  5779 	/* check the label of including directory */
       
  5780 	if (is_system_labeled()) {
       
  5781 		ASSERT(req->rq_label != NULL);
       
  5782 		clabel = req->rq_label;
       
  5783 		DTRACE_PROBE2(tx__rfs4__log__info__opremove__clabel, char *,
       
  5784 		    "got client label from request(1)",
       
  5785 		    struct svc_req *, req);
       
  5786 		if (!blequal(&l_admin_low->tsl_label, clabel)) {
       
  5787 			if (!do_rfs4_label_check(clabel, dvp, EQUALITY_CHECK)) {
       
  5788 				return (NFS4ERR_ACCESS);
       
  5789 			}
       
  5790 		}
       
  5791 	}
  5588 
  5792 
  5589 	/*
  5793 	/*
  5590 	 * Get the last component of path name in nm. cs will reference
  5794 	 * Get the last component of path name in nm. cs will reference
  5591 	 * the including directory on success.
  5795 	 * the including directory on success.
  5592 	 */
  5796 	 */