Exemple #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);
}
/*
 * smb_vop_acl_read
 *
 * Reads the ACL of the specified file into 'aclp'.
 * acl_type is the type of ACL which the filesystem supports.
 *
 * Caller has to free the allocated memory for aclp by calling
 * acl_free().
 */
int
smb_vop_acl_read(vnode_t *vp, acl_t **aclp, int flags, acl_type_t acl_type,
    cred_t *cr)
{
	int error;
	vsecattr_t vsecattr;

	ASSERT(vp);
	ASSERT(aclp);

	*aclp = NULL;
	bzero(&vsecattr, sizeof (vsecattr_t));

	switch (acl_type) {
	case ACLENT_T:
		vsecattr.vsa_mask = VSA_ACL | VSA_ACLCNT | VSA_DFACL |
		    VSA_DFACLCNT;
		break;

	case ACE_T:
		vsecattr.vsa_mask = VSA_ACE | VSA_ACECNT | VSA_ACE_ACLFLAGS;
		break;

	default:
		return (EINVAL);
	}

	if (error = VOP_GETSECATTR(vp, &vsecattr, flags, cr, &smb_ct))
		return (error);

	*aclp = smb_fsacl_from_vsa(&vsecattr, acl_type);
	if (vp->v_type == VDIR)
		(*aclp)->acl_flags |= ACL_IS_DIR;

	return (0);
}
Exemple #3
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;
	}
}
Exemple #4
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);
}