Ejemplo n.º 1
0
/*
 * Let avp handle security attributes (acl's).
 */
static int
devfs_getsecattr(struct vnode *vp, struct vsecattr *vsap, int flags,
    struct cred *cr)
{
	dvnode_t *dv = VTODV(vp);
	struct vnode *avp;
	int	error;

	dcmn_err2(("devfs_getsecattr %s\n", dv->dv_name));
	ASSERT(vp->v_type == VDIR || vp->v_type == VCHR || vp->v_type == VBLK);

	rw_enter(&dv->dv_contents, RW_READER);

	avp = dv->dv_attrvp;

	/* fabricate the acl */
	if (avp == NULL) {
		error = fs_fab_acl(vp, vsap, flags, cr);
		rw_exit(&dv->dv_contents);
		return (error);
	}

	error = VOP_GETSECATTR(avp, vsap, flags, cr);
	dsysdebug(error, ("vop_getsecattr %s %d\n", VTODV(vp)->dv_name, error));
	rw_exit(&dv->dv_contents);
	return (error);
}
Ejemplo n.º 2
0
/* ARGSUSED */
void
acl2_getacl(GETACL2args *args, GETACL2res *resp, struct exportinfo *exi,
    struct svc_req *req, cred_t *cr, bool_t ro)
{
	int error;
	vnode_t *vp;
	vattr_t va;

	vp = nfs_fhtovp(&args->fh, exi);
	if (vp == NULL) {
		resp->status = NFSERR_STALE;
		return;
	}

	bzero((caddr_t)&resp->resok.acl, sizeof (resp->resok.acl));

	resp->resok.acl.vsa_mask = args->mask;

	error = VOP_GETSECATTR(vp, &resp->resok.acl, 0, cr, NULL);

	if ((error == ENOSYS) && !(exi->exi_export.ex_flags & EX_NOACLFAB)) {
		/*
		 * If the underlying file system doesn't support
		 * aclent_t type acls, fabricate an acl.  This is
		 * required in order to to support existing clients
		 * that require the call to VOP_GETSECATTR to
		 * succeed while making the assumption that all
		 * file systems support aclent_t type acls.  This
		 * causes problems for servers exporting ZFS file
		 * systems because ZFS supports ace_t type acls,
		 * and fails (with ENOSYS) when asked for aclent_t
		 * type acls.
		 *
		 * Note: if the fs_fab_acl() fails, we have other problems.
		 * This error should be returned to the caller.
		 */
		error = fs_fab_acl(vp, &resp->resok.acl, 0, cr, NULL);
	}

	if (error) {
		VN_RELE(vp);
		resp->status = puterrno(error);
		return;
	}

	va.va_mask = AT_ALL;
	error = rfs4_delegated_getattr(vp, &va, 0, cr);

	VN_RELE(vp);

	/* check for overflowed values */
	if (!error) {
		error = vattr_to_nattr(&va, &resp->resok.attr);
	}
	if (error) {
		resp->status = puterrno(error);
		if (resp->resok.acl.vsa_aclcnt > 0 &&
		    resp->resok.acl.vsa_aclentp != NULL) {
			kmem_free((caddr_t)resp->resok.acl.vsa_aclentp,
			    resp->resok.acl.vsa_aclcnt * sizeof (aclent_t));
		}
		if (resp->resok.acl.vsa_dfaclcnt > 0 &&
		    resp->resok.acl.vsa_dfaclentp != NULL) {
			kmem_free((caddr_t)resp->resok.acl.vsa_dfaclentp,
			    resp->resok.acl.vsa_dfaclcnt * sizeof (aclent_t));
		}
		return;
	}

	resp->status = NFS_OK;
	if (!(args->mask & NA_ACL)) {
		if (resp->resok.acl.vsa_aclcnt > 0 &&
		    resp->resok.acl.vsa_aclentp != NULL) {
			kmem_free((caddr_t)resp->resok.acl.vsa_aclentp,
			    resp->resok.acl.vsa_aclcnt * sizeof (aclent_t));
		}
		resp->resok.acl.vsa_aclentp = NULL;
	}
	if (!(args->mask & NA_DFACL)) {
		if (resp->resok.acl.vsa_dfaclcnt > 0 &&
		    resp->resok.acl.vsa_dfaclentp != NULL) {
			kmem_free((caddr_t)resp->resok.acl.vsa_dfaclentp,
			    resp->resok.acl.vsa_dfaclcnt * sizeof (aclent_t));
		}
		resp->resok.acl.vsa_dfaclentp = NULL;
	}
}
Ejemplo n.º 3
0
/* ARGSUSED */
void
acl3_getacl(GETACL3args *args, GETACL3res *resp, struct exportinfo *exi,
    struct svc_req *req, cred_t *cr, bool_t ro)
{
	int error;
	vnode_t *vp;
	vattr_t *vap;
	vattr_t va;

	vap = NULL;

	vp = nfs3_fhtovp(&args->fh, exi);
	if (vp == NULL) {
		error = ESTALE;
		goto out;
	}

	va.va_mask = AT_ALL;
	vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;

	bzero((caddr_t)&resp->resok.acl, sizeof (resp->resok.acl));

	resp->resok.acl.vsa_mask = args->mask;

	error = VOP_GETSECATTR(vp, &resp->resok.acl, 0, cr, NULL);

	if ((error == ENOSYS) && !(exi->exi_export.ex_flags & EX_NOACLFAB)) {
		/*
		 * If the underlying file system doesn't support
		 * aclent_t type acls, fabricate an acl.  This is
		 * required in order to to support existing clients
		 * that require the call to VOP_GETSECATTR to
		 * succeed while making the assumption that all
		 * file systems support aclent_t type acls.  This
		 * causes problems for servers exporting ZFS file
		 * systems because ZFS supports ace_t type acls,
		 * and fails (with ENOSYS) when asked for aclent_t
		 * type acls.
		 *
		 * Note: if the fs_fab_acl() fails, we have other problems.
		 * This error should be returned to the caller.
		 */
		error = fs_fab_acl(vp, &resp->resok.acl, 0, cr, NULL);
	}

	if (error)
		goto out;

	va.va_mask = AT_ALL;
	vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;

	VN_RELE(vp);

	resp->status = NFS3_OK;
	vattr_to_post_op_attr(vap, &resp->resok.attr);
	if (!(args->mask & NA_ACL)) {
		if (resp->resok.acl.vsa_aclcnt > 0 &&
		    resp->resok.acl.vsa_aclentp != NULL) {
			kmem_free((caddr_t)resp->resok.acl.vsa_aclentp,
			    resp->resok.acl.vsa_aclcnt * sizeof (aclent_t));
		}
		resp->resok.acl.vsa_aclentp = NULL;
	}
	if (!(args->mask & NA_DFACL)) {
		if (resp->resok.acl.vsa_dfaclcnt > 0 &&
		    resp->resok.acl.vsa_dfaclentp != NULL) {
			kmem_free((caddr_t)resp->resok.acl.vsa_dfaclentp,
			    resp->resok.acl.vsa_dfaclcnt * sizeof (aclent_t));
		}
		resp->resok.acl.vsa_dfaclentp = NULL;
	}
	return;

out:
	if (curthread->t_flag & T_WOULDBLOCK) {
		curthread->t_flag &= ~T_WOULDBLOCK;
		resp->status = NFS3ERR_JUKEBOX;
	} else
		resp->status = puterrno3(error);
out1:
	if (vp != NULL)
		VN_RELE(vp);
	vattr_to_post_op_attr(vap, &resp->resfail.attr);
}