FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
/*
 * Retrieve a file's ACL
 */
Retrieve a file's ACL
Retrieve a file ' s ACL
int
zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
{
	zfs_acl_t	*aclp;
	ulong_t		mask;
	int		error;
	int 		count = 0;
	int		largeace = 0;
	mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT |
	    VSA_ACE_ACLFLAGS | VSA_ACE_ALLTYPES);
	if (mask == 0)
		return (SET_ERROR(ENOSYS));
	if (error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr))
		return (error);
	mutex_enter(&zp->z_acl_lock);
	ASSERT_VOP_LOCKED(ZTOV(zp), __func__);
	error = zfs_acl_node_read(zp, &aclp, B_FALSE);
	if (error != 0) {
		mutex_exit(&zp->z_acl_lock);
		return (error);
	}
	if ((zp->z_pflags & ZFS_ACL_OBJ_ACE) && !(mask & VSA_ACE_ALLTYPES)) {
		void *zacep = NULL;
		uint64_t who;
		uint32_t access_mask;
		uint16_t type, iflags;
		while (zacep = zfs_acl_next_ace(aclp, zacep,
		    &who, &access_mask, &iflags, &type)) {
			switch (type) {
			case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
			case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
			case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
			case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
				largeace++;
				continue;
			default:
				count++;
			}
		}
		vsecp->vsa_aclcnt = count;
	} else
		count = (int)aclp->z_acl_count;
	if (mask & VSA_ACECNT) {
		vsecp->vsa_aclcnt = count;
	}
	if (mask & VSA_ACE) {
		size_t aclsz;
		aclsz = count * sizeof (ace_t) +
		    sizeof (ace_object_t) * largeace;
		vsecp->vsa_aclentp = kmem_alloc(aclsz, KM_SLEEP);
		vsecp->vsa_aclentsz = aclsz;
		if (aclp->z_version == ZFS_ACL_VERSION_FUID)
			zfs_copy_fuid_2_ace(zp->z_zfsvfs, aclp, cr,
			    vsecp->vsa_aclentp, !(mask & VSA_ACE_ALLTYPES));
		else {
			zfs_acl_node_t *aclnode;
			void *start = vsecp->vsa_aclentp;
			for (aclnode = list_head(&aclp->z_acl); aclnode;
			    aclnode = list_next(&aclp->z_acl, aclnode)) {
				bcopy(aclnode->z_acldata, start,
				    aclnode->z_size);
				start = (caddr_t)start + aclnode->z_size;
			}
			ASSERT((caddr_t)start - (caddr_t)vsecp->vsa_aclentp ==
			    aclp->z_acl_bytes);
		}
	}
	if (mask & VSA_ACE_ACLFLAGS) {
		vsecp->vsa_aclflags = 0;
		if (zp->z_pflags & ZFS_ACL_DEFAULTED)
			vsecp->vsa_aclflags |= ACL_DEFAULTED;
		if (zp->z_pflags & ZFS_ACL_PROTECTED)
			vsecp->vsa_aclflags |= ACL_PROTECTED;
		if (zp->z_pflags & ZFS_ACL_AUTO_INHERIT)
			vsecp->vsa_aclflags |= ACL_AUTO_INHERIT;
	}
	mutex_exit(&zp->z_acl_lock);
	return (0);
}
int zfs_getacl ( znode_t * zp , vsecattr_t * vsecp , boolean_t skipaclchk , cred_t * cr ) { zfs_acl_t * aclp ; ulong_t mask ; int error ; int count = 0 ; int largeace = 0 ; mask = vsecp -> vsa_mask & ( VSA_ACE | VSA_ACECNT | VSA_ACE_ACLFLAGS | VSA_ACE_ALLTYPES ) ; if ( mask == 0 ) return ( SET_ERROR ( ENOSYS ) ) ; if ( error = zfs_zaccess ( zp , ACE_READ_ACL , 0 , skipaclchk , cr ) ) return ( error ) ; mutex_enter ( & zp -> z_acl_lock ) ; ASSERT_VOP_LOCKED ( ZTOV ( zp ) , __func__ ) ; error = zfs_acl_node_read ( zp , & aclp , B_FALSE ) ; if ( error != 0 ) { mutex_exit ( & zp -> z_acl_lock ) ; return ( error ) ; } if ( ( zp -> z_pflags & ZFS_ACL_OBJ_ACE ) && ! ( mask & VSA_ACE_ALLTYPES ) ) { void * zacep = NULL ; uint64_t who ; uint32_t access_mask ; uint16_t type , iflags ; while ( zacep = zfs_acl_next_ace ( aclp , zacep , & who , & access_mask , & iflags , & type ) ) { switch ( type ) { case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE : case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE : case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE : case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE : largeace ++ ; continue ; default : count ++ ; } } vsecp -> vsa_aclcnt = count ; } else count = ( int ) aclp -> z_acl_count ; if ( mask & VSA_ACECNT ) { vsecp -> vsa_aclcnt = count ; } if ( mask & VSA_ACE ) { size_t aclsz ; aclsz = count * sizeof ( ace_t ) + sizeof ( ace_object_t ) * largeace ; vsecp -> vsa_aclentp = kmem_alloc ( aclsz , KM_SLEEP ) ; vsecp -> vsa_aclentsz = aclsz ; if ( aclp -> z_version == ZFS_ACL_VERSION_FUID ) zfs_copy_fuid_2_ace ( zp -> z_zfsvfs , aclp , cr , vsecp -> vsa_aclentp , ! ( mask & VSA_ACE_ALLTYPES ) ) ; else { zfs_acl_node_t * aclnode ; void * start = vsecp -> vsa_aclentp ; for ( aclnode = list_head ( & aclp -> z_acl ) ; aclnode ; aclnode = list_next ( & aclp -> z_acl , aclnode ) ) { bcopy ( aclnode -> z_acldata , start , aclnode -> z_size ) ; start = ( caddr_t ) start + aclnode -> z_size ; } ASSERT ( ( caddr_t ) start - ( caddr_t ) vsecp -> vsa_aclentp == aclp -> z_acl_bytes ) ; } } if ( mask & VSA_ACE_ACLFLAGS ) { vsecp -> vsa_aclflags = 0 ; if ( zp -> z_pflags & ZFS_ACL_DEFAULTED ) vsecp -> vsa_aclflags |= ACL_DEFAULTED ; if ( zp -> z_pflags & ZFS_ACL_PROTECTED ) vsecp -> vsa_aclflags |= ACL_PROTECTED ; if ( zp -> z_pflags & ZFS_ACL_AUTO_INHERIT ) vsecp -> vsa_aclflags |= ACL_AUTO_INHERIT ; } mutex_exit ( & zp -> z_acl_lock ) ; return ( 0 ) ; }
Retrieve a file's ACL
Retrieve a file ' s ACL
/*
	 * Scan ACL to determine number of ACEs
	 */