/* * 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); }
/* * FS ACL (acl_t) Functions */ acl_t * smb_fsacl_alloc(int acenum, int flags) { acl_t *acl; acl = acl_alloc(ACE_T); acl->acl_cnt = acenum; acl->acl_aclp = kmem_zalloc(acl->acl_entry_size * acenum, KM_SLEEP); acl->acl_flags = flags; return (acl); }
/* * Take an acl array and build an acl_t. */ acl_t * acl_to_aclp(enum acl_type type, void *acl, int count) { acl_t *aclp; aclp = acl_alloc(type); if (aclp == NULL) return (aclp); aclp->acl_aclp = acl; aclp->acl_cnt = count; return (aclp); }
acl_t * acl_dup(acl_t *aclp) { acl_t *newaclp; newaclp = acl_alloc(aclp->acl_type); if (newaclp == NULL) return (NULL); newaclp->acl_aclp = malloc(aclp->acl_entry_size * aclp->acl_cnt); if (newaclp->acl_aclp == NULL) { acl_free(newaclp); return (NULL); } (void) memcpy(newaclp->acl_aclp, aclp->acl_aclp, aclp->acl_entry_size * aclp->acl_cnt); newaclp->acl_cnt = aclp->acl_cnt; return (newaclp); }
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); }