Пример #1
0
/*
 * smb_fsacl_from_vsa
 *
 * Converts given vsecattr_t structure to a acl_t structure.
 *
 * The allocated memory for retuned acl_t should be freed by
 * calling acl_free().
 */
acl_t *
smb_fsacl_from_vsa(vsecattr_t *vsecattr, acl_type_t acl_type)
{
	int		aclbsize = 0;	/* size of acl list in bytes */
	int		dfaclbsize = 0;	/* size of default acl list in bytes */
	int		numacls;
	acl_t		*acl_info;

	ASSERT(vsecattr);

	acl_info = acl_alloc(acl_type);
	if (acl_info == NULL)
		return (NULL);

	acl_info->acl_flags = 0;

	switch (acl_type) {

	case ACLENT_T:
		numacls = vsecattr->vsa_aclcnt + vsecattr->vsa_dfaclcnt;
		aclbsize = vsecattr->vsa_aclcnt * sizeof (aclent_t);
		dfaclbsize = vsecattr->vsa_dfaclcnt * sizeof (aclent_t);

		acl_info->acl_cnt = numacls;
		acl_info->acl_aclp = kmem_alloc(aclbsize + dfaclbsize,
		    KM_SLEEP);
		(void) memcpy(acl_info->acl_aclp, vsecattr->vsa_aclentp,
		    aclbsize);
		(void) memcpy((char *)acl_info->acl_aclp + aclbsize,
		    vsecattr->vsa_dfaclentp, dfaclbsize);

		if (acl_info->acl_cnt <= MIN_ACL_ENTRIES)
			acl_info->acl_flags |= ACL_IS_TRIVIAL;

		break;

	case ACE_T:
		aclbsize = vsecattr->vsa_aclcnt * sizeof (ace_t);
		acl_info->acl_cnt = vsecattr->vsa_aclcnt;
		acl_info->acl_flags = vsecattr->vsa_aclflags;
		acl_info->acl_aclp = kmem_alloc(aclbsize, KM_SLEEP);
		(void) memcpy(acl_info->acl_aclp, vsecattr->vsa_aclentp,
		    aclbsize);
		if (ace_trivial(acl_info->acl_aclp, acl_info->acl_cnt) == 0)
			acl_info->acl_flags |= ACL_IS_TRIVIAL;

		break;

	default:
		acl_free(acl_info);
		return (NULL);
	}

	if (aclbsize && vsecattr->vsa_aclentp)
		kmem_free(vsecattr->vsa_aclentp, aclbsize);
	if (dfaclbsize && vsecattr->vsa_dfaclentp)
		kmem_free(vsecattr->vsa_dfaclentp, dfaclbsize);

	return (acl_info);
}
Пример #2
0
/*
 * Determine whether a file has a trivial ACL
 * returns: 	0 = trivial
 *		1 = nontrivial
 *		<0 some other system failure, such as ENOENT or EPERM
 */
int
acl_trivial(const char *filename)
{
	int acl_flavor;
	int aclcnt;
	int cntcmd;
	int val = 0;
	ace_t *acep;

	acl_flavor = pathconf(filename, _PC_ACL_ENABLED);

	if (acl_flavor == _ACL_ACE_ENABLED)
		cntcmd = ACE_GETACLCNT;
	else
		cntcmd = GETACLCNT;

	aclcnt = acl(filename, cntcmd, 0, NULL);
	if (aclcnt > 0) {
		if (acl_flavor == _ACL_ACE_ENABLED) {
			acep = malloc(sizeof (ace_t) * aclcnt);
			if (acep == NULL)
				return (-1);
			if (acl(filename, ACE_GETACL,
			    aclcnt, acep) < 0) {
				free(acep);
				return (-1);
			}

			val = ace_trivial(acep, aclcnt);
			free(acep);

		} else if (aclcnt > MIN_ACL_ENTRIES)
			val = 1;
	}
	return (val);
}
Пример #3
0
static int
cacl_get(acl_inp inp, int get_flag, int type, acl_t **aclp)
{
	const char *fname;
	int fd;
	int ace_acl = 0;
	int error;
	int getcmd, cntcmd;
	acl_t *acl_info;
	int	save_errno;
	int	stat_error;
	struct stat64 statbuf;

	*aclp = NULL;
	if (type == ACL_PATH) {
		fname = inp.file;
		ace_acl = pathconf(fname, _PC_ACL_ENABLED);
	} else {
		fd = inp.fd;
		ace_acl = fpathconf(fd, _PC_ACL_ENABLED);
	}

	/*
	 * if acl's aren't supported then
	 * send it through the old GETACL interface
	 */
	if (ace_acl == 0 || ace_acl == -1) {
		ace_acl = _ACL_ACLENT_ENABLED;
	}

	if (ace_acl & _ACL_ACE_ENABLED) {
		cntcmd = ACE_GETACLCNT;
		getcmd = ACE_GETACL;
		acl_info = acl_alloc(ACE_T);
	} else {
		cntcmd = GETACLCNT;
		getcmd = GETACL;
		acl_info = acl_alloc(ACLENT_T);
	}

	if (acl_info == NULL)
		return (-1);

	if (type == ACL_PATH) {
		acl_info->acl_cnt = acl(fname, cntcmd, 0, NULL);
	} else {
		acl_info->acl_cnt = facl(fd, cntcmd, 0, NULL);
	}

	save_errno = errno;
	if (acl_info->acl_cnt < 0) {
		acl_free(acl_info);
		errno = save_errno;
		return (-1);
	}

	if (acl_info->acl_cnt == 0) {
		acl_free(acl_info);
		errno = save_errno;
		return (0);
	}

	acl_info->acl_aclp =
	    malloc(acl_info->acl_cnt * acl_info->acl_entry_size);
	save_errno = errno;

	if (acl_info->acl_aclp == NULL) {
		acl_free(acl_info);
		errno = save_errno;
		return (-1);
	}

	if (type == ACL_PATH) {
		stat_error = stat64(fname, &statbuf);
		error = acl(fname, getcmd, acl_info->acl_cnt,
		    acl_info->acl_aclp);
	} else {
		stat_error = fstat64(fd, &statbuf);
		error = facl(fd, getcmd, acl_info->acl_cnt,
		    acl_info->acl_aclp);
	}

	save_errno = errno;
	if (error == -1) {
		acl_free(acl_info);
		errno = save_errno;
		return (-1);
	}


	if (stat_error == 0) {
		acl_info->acl_flags =
		    (S_ISDIR(statbuf.st_mode) ? ACL_IS_DIR : 0);
	} else
		acl_info->acl_flags = 0;

	switch (acl_info->acl_type) {
	case ACLENT_T:
		if (acl_info->acl_cnt <= MIN_ACL_ENTRIES)
			acl_info->acl_flags |= ACL_IS_TRIVIAL;
		break;
	case ACE_T:
		if (ace_trivial(acl_info->acl_aclp, acl_info->acl_cnt) == 0)
			acl_info->acl_flags |= ACL_IS_TRIVIAL;
		break;
	default:
		errno = EINVAL;
		acl_free(acl_info);
		return (-1);
	}

	if ((acl_info->acl_flags & ACL_IS_TRIVIAL) &&
	    (get_flag & ACL_NO_TRIVIAL)) {
		acl_free(acl_info);
		errno = 0;
		return (0);
	}

	*aclp = acl_info;
	return (0);
}