/* * smb_fsacl_getsids * * Batch all the uid/gid in given ZFS ACL to get their corresponding SIDs. */ static idmap_stat smb_fsacl_getsids(smb_idmap_batch_t *sib, acl_t *zacl, uid_t uid, gid_t gid) { ace_t *zace; idmap_stat idm_stat; smb_idmap_t *sim; uid_t id; int i, idtype; sim = sib->sib_maps; for (i = 0, zace = zacl->acl_aclp; i < zacl->acl_cnt; zace++, i++, sim++) { switch (zace->a_flags & ACE_TYPE_FLAGS) { case ACE_OWNER: id = uid; idtype = SMB_IDMAP_USER; break; case (ACE_GROUP | ACE_IDENTIFIER_GROUP): /* owning group */ id = gid; idtype = SMB_IDMAP_GROUP; break; case ACE_IDENTIFIER_GROUP: /* regular group */ id = zace->a_who; idtype = SMB_IDMAP_GROUP; break; case ACE_EVERYONE: idtype = SMB_IDMAP_EVERYONE; break; default: /* user entry */ id = zace->a_who; idtype = SMB_IDMAP_USER; } idm_stat = smb_idmap_batch_getsid(sib->sib_idmaph, sim, id, idtype); if (idm_stat != IDMAP_SUCCESS) { return (idm_stat); } } idm_stat = smb_idmap_batch_getmappings(sib); return (idm_stat); }
/* * smb_acl_to_zfs * * Converts given Windows ACL to a ZFS ACL. * * fs_acl will contain a pointer to the created ZFS ACL. * The allocated memory should be freed by calling * smb_fsacl_free(). * * Since the output parameter, fs_acl, is allocated in this * function, the caller has to make sure *fs_acl is NULL which * means it's not pointing to any memory. */ uint32_t smb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl) { smb_ace_t *ace; acl_t *zacl; ace_t *zace; smb_idmap_batch_t sib; smb_idmap_t *sim; idmap_stat idm_stat; char *sidstr; int i; ASSERT(fs_acl); ASSERT(*fs_acl == NULL); if (acl && !smb_acl_isvalid(acl, which_acl)) return (NT_STATUS_INVALID_ACL); if ((acl == NULL) || (acl->sl_acecnt == 0)) { if (which_acl == SMB_DACL_SECINFO) { *fs_acl = smb_fsacl_null_empty(acl == NULL); } return (NT_STATUS_SUCCESS); } idm_stat = smb_idmap_batch_create(&sib, acl->sl_acecnt, SMB_IDMAP_SID2ID); if (idm_stat != IDMAP_SUCCESS) return (NT_STATUS_INTERNAL_ERROR); sidstr = kmem_alloc(SMB_SID_STRSZ, KM_SLEEP); zacl = smb_fsacl_alloc(acl->sl_acecnt, flags); zace = zacl->acl_aclp; ace = acl->sl_aces; sim = sib.sib_maps; for (i = 0; i < acl->sl_acecnt; i++, zace++, ace++, sim++) { zace->a_type = ace->se_hdr.se_type & ACE_ALL_TYPES; zace->a_access_mask = smb_ace_mask_g2s(ace->se_mask); zace->a_flags = smb_ace_flags_tozfs(ace->se_hdr.se_flags); zace->a_who = (uid_t)-1; smb_sid_tostr(ace->se_sid, sidstr); if (!smb_ace_wellknown_update(sidstr, zace)) { sim->sim_id = &zace->a_who; idm_stat = smb_idmap_batch_getid(sib.sib_idmaph, sim, ace->se_sid, SMB_IDMAP_UNKNOWN); if (idm_stat != IDMAP_SUCCESS) { kmem_free(sidstr, SMB_SID_STRSZ); smb_fsacl_free(zacl); smb_idmap_batch_destroy(&sib); return (NT_STATUS_INTERNAL_ERROR); } } } kmem_free(sidstr, SMB_SID_STRSZ); idm_stat = smb_idmap_batch_getmappings(&sib); if (idm_stat != IDMAP_SUCCESS) { smb_fsacl_free(zacl); smb_idmap_batch_destroy(&sib); return (NT_STATUS_NONE_MAPPED); } /* * Set the ACEs group flag based on the type of ID returned. */ zace = zacl->acl_aclp; ace = acl->sl_aces; sim = sib.sib_maps; for (i = 0; i < acl->sl_acecnt; i++, zace++, ace++, sim++) { if (zace->a_who == (uid_t)-1) continue; if (sim->sim_idtype == SMB_IDMAP_GROUP) zace->a_flags |= ACE_IDENTIFIER_GROUP; } smb_idmap_batch_destroy(&sib); *fs_acl = zacl; return (NT_STATUS_SUCCESS); }