129bd2886SAlan Wright /* 229bd2886SAlan Wright * CDDL HEADER START 329bd2886SAlan Wright * 429bd2886SAlan Wright * The contents of this file are subject to the terms of the 529bd2886SAlan Wright * Common Development and Distribution License (the "License"). 629bd2886SAlan Wright * You may not use this file except in compliance with the License. 729bd2886SAlan Wright * 829bd2886SAlan Wright * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 929bd2886SAlan Wright * or http://www.opensolaris.org/os/licensing. 1029bd2886SAlan Wright * See the License for the specific language governing permissions 1129bd2886SAlan Wright * and limitations under the License. 1229bd2886SAlan Wright * 1329bd2886SAlan Wright * When distributing Covered Code, include this CDDL HEADER in each 1429bd2886SAlan Wright * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1529bd2886SAlan Wright * If applicable, add the following below this CDDL HEADER, with the 1629bd2886SAlan Wright * fields enclosed by brackets "[]" replaced with your own identifying 1729bd2886SAlan Wright * information: Portions Copyright [yyyy] [name of copyright owner] 1829bd2886SAlan Wright * 1929bd2886SAlan Wright * CDDL HEADER END 2029bd2886SAlan Wright */ 21148c5f43SAlan Wright 2229bd2886SAlan Wright /* 23148c5f43SAlan Wright * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 2429bd2886SAlan Wright */ 2529bd2886SAlan Wright 2629bd2886SAlan Wright /* 2729bd2886SAlan Wright * This module provides Security Descriptor handling functions. 2829bd2886SAlan Wright */ 2929bd2886SAlan Wright 3029bd2886SAlan Wright #include <strings.h> 3129bd2886SAlan Wright #include <assert.h> 32*1fdeec65Sjoyce mcintosh #include <errno.h> 3329bd2886SAlan Wright #include <smbsrv/ntifs.h> 3429bd2886SAlan Wright #include <smbsrv/smb_idmap.h> 35b1352070SAlan Wright #include <smbsrv/libsmb.h> 3629bd2886SAlan Wright 3729bd2886SAlan Wright #define SMB_SHR_ACE_READ_PERMS (ACE_READ_PERMS | ACE_EXECUTE | ACE_SYNCHRONIZE) 3829bd2886SAlan Wright #define SMB_SHR_ACE_CONTROL_PERMS (ACE_MODIFY_PERMS & (~ACE_DELETE_CHILD)) 3929bd2886SAlan Wright 409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * This mapping table is provided to map permissions set by chmod 429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * using 'read_set' and 'modify_set' to what Windows share ACL GUI 439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * expects as Read and Control, respectively. 449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 45b1352070SAlan Wright static struct { 46b1352070SAlan Wright int am_ace_perms; 47b1352070SAlan Wright int am_share_perms; 48b1352070SAlan Wright } smb_ace_map[] = { 49b1352070SAlan Wright { ACE_MODIFY_PERMS, SMB_SHR_ACE_CONTROL_PERMS }, 50b1352070SAlan Wright { ACE_READ_PERMS, SMB_SHR_ACE_READ_PERMS } 51b1352070SAlan Wright }; 52b1352070SAlan Wright 53b1352070SAlan Wright #define SMB_ACE_MASK_MAP_SIZE (sizeof (smb_ace_map)/sizeof (smb_ace_map[0])) 54b1352070SAlan Wright 5529bd2886SAlan Wright static void smb_sd_set_sacl(smb_sd_t *, smb_acl_t *, boolean_t, int); 5629bd2886SAlan Wright static void smb_sd_set_dacl(smb_sd_t *, smb_acl_t *, boolean_t, int); 5729bd2886SAlan Wright 5829bd2886SAlan Wright void 5929bd2886SAlan Wright smb_sd_init(smb_sd_t *sd, uint8_t revision) 6029bd2886SAlan Wright { 6129bd2886SAlan Wright bzero(sd, sizeof (smb_sd_t)); 6229bd2886SAlan Wright sd->sd_revision = revision; 6329bd2886SAlan Wright } 6429bd2886SAlan Wright 6529bd2886SAlan Wright /* 6629bd2886SAlan Wright * smb_sd_term 6729bd2886SAlan Wright * 6829bd2886SAlan Wright * Free non-NULL members of 'sd' which has to be in 6929bd2886SAlan Wright * absolute (pointer) form. 7029bd2886SAlan Wright */ 7129bd2886SAlan Wright void 7229bd2886SAlan Wright smb_sd_term(smb_sd_t *sd) 7329bd2886SAlan Wright { 7429bd2886SAlan Wright assert(sd); 7529bd2886SAlan Wright assert((sd->sd_control & SE_SELF_RELATIVE) == 0); 7629bd2886SAlan Wright 7729bd2886SAlan Wright smb_sid_free(sd->sd_owner); 7829bd2886SAlan Wright smb_sid_free(sd->sd_group); 7929bd2886SAlan Wright smb_acl_free(sd->sd_dacl); 8029bd2886SAlan Wright smb_acl_free(sd->sd_sacl); 8129bd2886SAlan Wright 8229bd2886SAlan Wright bzero(sd, sizeof (smb_sd_t)); 8329bd2886SAlan Wright } 8429bd2886SAlan Wright 8529bd2886SAlan Wright uint32_t 8629bd2886SAlan Wright smb_sd_len(smb_sd_t *sd, uint32_t secinfo) 8729bd2886SAlan Wright { 8829bd2886SAlan Wright uint32_t length = SMB_SD_HDRSIZE; 8929bd2886SAlan Wright 9029bd2886SAlan Wright if (secinfo & SMB_OWNER_SECINFO) 9129bd2886SAlan Wright length += smb_sid_len(sd->sd_owner); 9229bd2886SAlan Wright 9329bd2886SAlan Wright if (secinfo & SMB_GROUP_SECINFO) 9429bd2886SAlan Wright length += smb_sid_len(sd->sd_group); 9529bd2886SAlan Wright 9629bd2886SAlan Wright if (secinfo & SMB_DACL_SECINFO) 9729bd2886SAlan Wright length += smb_acl_len(sd->sd_dacl); 9829bd2886SAlan Wright 9929bd2886SAlan Wright if (secinfo & SMB_SACL_SECINFO) 10029bd2886SAlan Wright length += smb_acl_len(sd->sd_sacl); 10129bd2886SAlan Wright 10229bd2886SAlan Wright return (length); 10329bd2886SAlan Wright } 10429bd2886SAlan Wright 10529bd2886SAlan Wright /* 10629bd2886SAlan Wright * smb_sd_get_secinfo 10729bd2886SAlan Wright * 10829bd2886SAlan Wright * Return the security information mask for the specified security 10929bd2886SAlan Wright * descriptor. 11029bd2886SAlan Wright */ 11129bd2886SAlan Wright uint32_t 11229bd2886SAlan Wright smb_sd_get_secinfo(smb_sd_t *sd) 11329bd2886SAlan Wright { 11429bd2886SAlan Wright uint32_t sec_info = 0; 11529bd2886SAlan Wright 11629bd2886SAlan Wright if (sd == NULL) 11729bd2886SAlan Wright return (0); 11829bd2886SAlan Wright 11929bd2886SAlan Wright if (sd->sd_owner) 12029bd2886SAlan Wright sec_info |= SMB_OWNER_SECINFO; 12129bd2886SAlan Wright 12229bd2886SAlan Wright if (sd->sd_group) 12329bd2886SAlan Wright sec_info |= SMB_GROUP_SECINFO; 12429bd2886SAlan Wright 12529bd2886SAlan Wright if (sd->sd_dacl) 12629bd2886SAlan Wright sec_info |= SMB_DACL_SECINFO; 12729bd2886SAlan Wright 12829bd2886SAlan Wright if (sd->sd_sacl) 12929bd2886SAlan Wright sec_info |= SMB_SACL_SECINFO; 13029bd2886SAlan Wright 13129bd2886SAlan Wright return (sec_info); 13229bd2886SAlan Wright } 13329bd2886SAlan Wright 13429bd2886SAlan Wright /* 13529bd2886SAlan Wright * Adjust the Access Mask so that ZFS ACE mask and Windows ACE read mask match. 13629bd2886SAlan Wright */ 13729bd2886SAlan Wright static int 13829bd2886SAlan Wright smb_sd_adjust_read_mask(int mask) 13929bd2886SAlan Wright { 140b1352070SAlan Wright int i; 141b1352070SAlan Wright 142b1352070SAlan Wright for (i = 0; i < SMB_ACE_MASK_MAP_SIZE; ++i) { 143b1352070SAlan Wright if (smb_ace_map[i].am_ace_perms == mask) 144b1352070SAlan Wright return (smb_ace_map[i].am_share_perms); 145b1352070SAlan Wright } 146b1352070SAlan Wright 1479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (mask); 14829bd2886SAlan Wright } 14929bd2886SAlan Wright 15029bd2886SAlan Wright /* 15129bd2886SAlan Wright * Get ZFS acl from the share path via acl_get() method. 15229bd2886SAlan Wright */ 15329bd2886SAlan Wright static uint32_t 15429bd2886SAlan Wright smb_sd_read_acl(char *path, smb_fssd_t *fs_sd) 15529bd2886SAlan Wright { 15629bd2886SAlan Wright acl_t *z_acl; 15729bd2886SAlan Wright ace_t *z_ace; 15829bd2886SAlan Wright 15929bd2886SAlan Wright fs_sd->sd_gid = fs_sd->sd_uid = 0; 16029bd2886SAlan Wright 161*1fdeec65Sjoyce mcintosh errno = 0; 162*1fdeec65Sjoyce mcintosh if (acl_get(path, 0, &z_acl) != 0) { 163*1fdeec65Sjoyce mcintosh switch (errno) { 164*1fdeec65Sjoyce mcintosh case EACCES: 165*1fdeec65Sjoyce mcintosh return (NT_STATUS_ACCESS_DENIED); 166*1fdeec65Sjoyce mcintosh case ENOENT: 167*1fdeec65Sjoyce mcintosh return (NT_STATUS_OBJECT_PATH_NOT_FOUND); 168*1fdeec65Sjoyce mcintosh default: 16929bd2886SAlan Wright return (NT_STATUS_INTERNAL_ERROR); 170*1fdeec65Sjoyce mcintosh } 171*1fdeec65Sjoyce mcintosh } 17229bd2886SAlan Wright 17329bd2886SAlan Wright if ((z_ace = (ace_t *)z_acl->acl_aclp) == NULL) 17429bd2886SAlan Wright return (NT_STATUS_INVALID_ACL); 17529bd2886SAlan Wright 1769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States for (int i = 0; i < z_acl->acl_cnt; i++, z_ace++) 1779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States z_ace->a_access_mask = 1789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_sd_adjust_read_mask(z_ace->a_access_mask); 17929bd2886SAlan Wright 18029bd2886SAlan Wright fs_sd->sd_zdacl = z_acl; 18129bd2886SAlan Wright fs_sd->sd_zsacl = NULL; 18229bd2886SAlan Wright return (NT_STATUS_SUCCESS); 18329bd2886SAlan Wright } 18429bd2886SAlan Wright 18529bd2886SAlan Wright /* 18629bd2886SAlan Wright * smb_sd_read 18729bd2886SAlan Wright * 18829bd2886SAlan Wright * Reads ZFS acl from filesystem using acl_get() method. Convert the ZFS acl to 18929bd2886SAlan Wright * a Win SD and return the Win SD in absolute form. 19029bd2886SAlan Wright * 19129bd2886SAlan Wright * NOTE: upon successful return caller MUST free the memory allocated 19229bd2886SAlan Wright * for the returned SD by calling smb_sd_term(). 19329bd2886SAlan Wright */ 19429bd2886SAlan Wright uint32_t 19529bd2886SAlan Wright smb_sd_read(char *path, smb_sd_t *sd, uint32_t secinfo) 19629bd2886SAlan Wright { 19729bd2886SAlan Wright smb_fssd_t fs_sd; 19829bd2886SAlan Wright uint32_t status = NT_STATUS_SUCCESS; 19929bd2886SAlan Wright uint32_t sd_flags; 20029bd2886SAlan Wright int error; 20129bd2886SAlan Wright 20229bd2886SAlan Wright sd_flags = SMB_FSSD_FLAGS_DIR; 20329bd2886SAlan Wright smb_fssd_init(&fs_sd, secinfo, sd_flags); 20429bd2886SAlan Wright 20529bd2886SAlan Wright error = smb_sd_read_acl(path, &fs_sd); 20629bd2886SAlan Wright if (error != NT_STATUS_SUCCESS) { 20729bd2886SAlan Wright smb_fssd_term(&fs_sd); 20829bd2886SAlan Wright return (error); 20929bd2886SAlan Wright } 21029bd2886SAlan Wright 21129bd2886SAlan Wright status = smb_sd_fromfs(&fs_sd, sd); 21229bd2886SAlan Wright smb_fssd_term(&fs_sd); 21329bd2886SAlan Wright 21429bd2886SAlan Wright return (status); 21529bd2886SAlan Wright } 21629bd2886SAlan Wright 21729bd2886SAlan Wright /* 21829bd2886SAlan Wright * Apply ZFS acl to the share path via acl_set() method. 2199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * A NULL ACL pointer here represents an error. 2209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Null or empty ACLs are handled in smb_sd_tofs(). 22129bd2886SAlan Wright */ 22229bd2886SAlan Wright static uint32_t 22329bd2886SAlan Wright smb_sd_write_acl(char *path, smb_fssd_t *fs_sd) 22429bd2886SAlan Wright { 22529bd2886SAlan Wright acl_t *z_acl; 22629bd2886SAlan Wright ace_t *z_ace; 22729bd2886SAlan Wright uint32_t status = NT_STATUS_SUCCESS; 22829bd2886SAlan Wright 2299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States z_acl = fs_sd->sd_zdacl; 2309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (z_acl == NULL) 23129bd2886SAlan Wright return (NT_STATUS_INVALID_ACL); 23229bd2886SAlan Wright 2339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States z_ace = (ace_t *)z_acl->acl_aclp; 2349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (z_ace == NULL) 23529bd2886SAlan Wright return (NT_STATUS_INVALID_ACL); 23629bd2886SAlan Wright 23729bd2886SAlan Wright fs_sd->sd_gid = fs_sd->sd_uid = 0; 23829bd2886SAlan Wright if (acl_set(path, z_acl) != 0) 23929bd2886SAlan Wright status = NT_STATUS_INTERNAL_ERROR; 24029bd2886SAlan Wright 24129bd2886SAlan Wright return (status); 24229bd2886SAlan Wright } 24329bd2886SAlan Wright 24429bd2886SAlan Wright /* 24529bd2886SAlan Wright * smb_sd_write 24629bd2886SAlan Wright * 24729bd2886SAlan Wright * Takes a Win SD in absolute form, converts it to 24829bd2886SAlan Wright * ZFS acl and applies the acl to the share path via acl_set() method. 24929bd2886SAlan Wright */ 25029bd2886SAlan Wright uint32_t 25129bd2886SAlan Wright smb_sd_write(char *path, smb_sd_t *sd, uint32_t secinfo) 25229bd2886SAlan Wright { 25329bd2886SAlan Wright smb_fssd_t fs_sd; 25429bd2886SAlan Wright uint32_t status = NT_STATUS_SUCCESS; 25529bd2886SAlan Wright uint32_t sd_flags; 25629bd2886SAlan Wright int error; 25729bd2886SAlan Wright 25829bd2886SAlan Wright sd_flags = SMB_FSSD_FLAGS_DIR; 25929bd2886SAlan Wright smb_fssd_init(&fs_sd, secinfo, sd_flags); 26029bd2886SAlan Wright 26129bd2886SAlan Wright error = smb_sd_tofs(sd, &fs_sd); 26229bd2886SAlan Wright if (error != NT_STATUS_SUCCESS) { 26329bd2886SAlan Wright smb_fssd_term(&fs_sd); 26429bd2886SAlan Wright return (error); 26529bd2886SAlan Wright } 26629bd2886SAlan Wright 26729bd2886SAlan Wright status = smb_sd_write_acl(path, &fs_sd); 26829bd2886SAlan Wright smb_fssd_term(&fs_sd); 26929bd2886SAlan Wright 27029bd2886SAlan Wright return (status); 27129bd2886SAlan Wright } 27229bd2886SAlan Wright 27329bd2886SAlan Wright /* 27429bd2886SAlan Wright * smb_sd_tofs 27529bd2886SAlan Wright * 27629bd2886SAlan Wright * Creates a filesystem security structure based on the given 27729bd2886SAlan Wright * Windows security descriptor. 27829bd2886SAlan Wright */ 27929bd2886SAlan Wright uint32_t 28029bd2886SAlan Wright smb_sd_tofs(smb_sd_t *sd, smb_fssd_t *fs_sd) 28129bd2886SAlan Wright { 28229bd2886SAlan Wright smb_sid_t *sid; 28329bd2886SAlan Wright uint32_t status = NT_STATUS_SUCCESS; 28429bd2886SAlan Wright uint16_t sd_control; 28529bd2886SAlan Wright idmap_stat idm_stat; 28629bd2886SAlan Wright int idtype; 28729bd2886SAlan Wright int flags = 0; 28829bd2886SAlan Wright 28929bd2886SAlan Wright sd_control = sd->sd_control; 29029bd2886SAlan Wright 29129bd2886SAlan Wright /* 29229bd2886SAlan Wright * ZFS only has one set of flags so for now only 29329bd2886SAlan Wright * Windows DACL flags are taken into account. 29429bd2886SAlan Wright */ 29529bd2886SAlan Wright if (sd_control & SE_DACL_DEFAULTED) 29629bd2886SAlan Wright flags |= ACL_DEFAULTED; 29729bd2886SAlan Wright if (sd_control & SE_DACL_AUTO_INHERITED) 29829bd2886SAlan Wright flags |= ACL_AUTO_INHERIT; 29929bd2886SAlan Wright if (sd_control & SE_DACL_PROTECTED) 30029bd2886SAlan Wright flags |= ACL_PROTECTED; 30129bd2886SAlan Wright 30229bd2886SAlan Wright if (fs_sd->sd_flags & SMB_FSSD_FLAGS_DIR) 30329bd2886SAlan Wright flags |= ACL_IS_DIR; 30429bd2886SAlan Wright 30529bd2886SAlan Wright /* Owner */ 30629bd2886SAlan Wright if (fs_sd->sd_secinfo & SMB_OWNER_SECINFO) { 30729bd2886SAlan Wright sid = sd->sd_owner; 30829bd2886SAlan Wright if (!smb_sid_isvalid(sid)) 30929bd2886SAlan Wright return (NT_STATUS_INVALID_SID); 31029bd2886SAlan Wright 31129bd2886SAlan Wright idtype = SMB_IDMAP_USER; 31229bd2886SAlan Wright idm_stat = smb_idmap_getid(sid, &fs_sd->sd_uid, &idtype); 31329bd2886SAlan Wright if (idm_stat != IDMAP_SUCCESS) { 31429bd2886SAlan Wright return (NT_STATUS_NONE_MAPPED); 31529bd2886SAlan Wright } 31629bd2886SAlan Wright } 31729bd2886SAlan Wright 31829bd2886SAlan Wright /* Group */ 31929bd2886SAlan Wright if (fs_sd->sd_secinfo & SMB_GROUP_SECINFO) { 32029bd2886SAlan Wright sid = sd->sd_group; 32129bd2886SAlan Wright if (!smb_sid_isvalid(sid)) 32229bd2886SAlan Wright return (NT_STATUS_INVALID_SID); 32329bd2886SAlan Wright 32429bd2886SAlan Wright idtype = SMB_IDMAP_GROUP; 32529bd2886SAlan Wright idm_stat = smb_idmap_getid(sid, &fs_sd->sd_gid, &idtype); 32629bd2886SAlan Wright if (idm_stat != IDMAP_SUCCESS) { 32729bd2886SAlan Wright return (NT_STATUS_NONE_MAPPED); 32829bd2886SAlan Wright } 32929bd2886SAlan Wright } 33029bd2886SAlan Wright 33129bd2886SAlan Wright /* DACL */ 33229bd2886SAlan Wright if (fs_sd->sd_secinfo & SMB_DACL_SECINFO) { 33329bd2886SAlan Wright if (sd->sd_control & SE_DACL_PRESENT) { 33429bd2886SAlan Wright status = smb_acl_to_zfs(sd->sd_dacl, flags, 33529bd2886SAlan Wright SMB_DACL_SECINFO, &fs_sd->sd_zdacl); 33629bd2886SAlan Wright if (status != NT_STATUS_SUCCESS) 33729bd2886SAlan Wright return (status); 33829bd2886SAlan Wright } 33929bd2886SAlan Wright else 34029bd2886SAlan Wright return (NT_STATUS_INVALID_ACL); 34129bd2886SAlan Wright } 34229bd2886SAlan Wright 34329bd2886SAlan Wright /* SACL */ 34429bd2886SAlan Wright if (fs_sd->sd_secinfo & SMB_SACL_SECINFO) { 34529bd2886SAlan Wright if (sd->sd_control & SE_SACL_PRESENT) { 34629bd2886SAlan Wright status = smb_acl_to_zfs(sd->sd_sacl, flags, 34729bd2886SAlan Wright SMB_SACL_SECINFO, &fs_sd->sd_zsacl); 34829bd2886SAlan Wright if (status != NT_STATUS_SUCCESS) { 34929bd2886SAlan Wright return (status); 35029bd2886SAlan Wright } 35129bd2886SAlan Wright } else { 35229bd2886SAlan Wright return (NT_STATUS_INVALID_ACL); 35329bd2886SAlan Wright } 35429bd2886SAlan Wright } 35529bd2886SAlan Wright 35629bd2886SAlan Wright return (status); 35729bd2886SAlan Wright } 35829bd2886SAlan Wright 35929bd2886SAlan Wright /* 36029bd2886SAlan Wright * smb_sd_fromfs 36129bd2886SAlan Wright * 36229bd2886SAlan Wright * Makes an Windows style security descriptor in absolute form 36329bd2886SAlan Wright * based on the given filesystem security information. 36429bd2886SAlan Wright * 36529bd2886SAlan Wright * Should call smb_sd_term() for the returned sd to free allocated 36629bd2886SAlan Wright * members. 36729bd2886SAlan Wright */ 368fe1c642dSBill Krier uint32_t 36929bd2886SAlan Wright smb_sd_fromfs(smb_fssd_t *fs_sd, smb_sd_t *sd) 37029bd2886SAlan Wright { 37129bd2886SAlan Wright uint32_t status = NT_STATUS_SUCCESS; 37229bd2886SAlan Wright smb_acl_t *acl = NULL; 37329bd2886SAlan Wright smb_sid_t *sid; 37429bd2886SAlan Wright idmap_stat idm_stat; 37529bd2886SAlan Wright 37629bd2886SAlan Wright assert(fs_sd); 37729bd2886SAlan Wright assert(sd); 37829bd2886SAlan Wright 37929bd2886SAlan Wright smb_sd_init(sd, SECURITY_DESCRIPTOR_REVISION); 38029bd2886SAlan Wright 38129bd2886SAlan Wright /* Owner */ 38229bd2886SAlan Wright if (fs_sd->sd_secinfo & SMB_OWNER_SECINFO) { 38329bd2886SAlan Wright idm_stat = smb_idmap_getsid(fs_sd->sd_uid, 38429bd2886SAlan Wright SMB_IDMAP_USER, &sid); 38529bd2886SAlan Wright 38629bd2886SAlan Wright if (idm_stat != IDMAP_SUCCESS) { 38729bd2886SAlan Wright smb_sd_term(sd); 38829bd2886SAlan Wright return (NT_STATUS_NONE_MAPPED); 38929bd2886SAlan Wright } 39029bd2886SAlan Wright 39129bd2886SAlan Wright sd->sd_owner = sid; 39229bd2886SAlan Wright } 39329bd2886SAlan Wright 39429bd2886SAlan Wright /* Group */ 39529bd2886SAlan Wright if (fs_sd->sd_secinfo & SMB_GROUP_SECINFO) { 39629bd2886SAlan Wright idm_stat = smb_idmap_getsid(fs_sd->sd_gid, 39729bd2886SAlan Wright SMB_IDMAP_GROUP, &sid); 39829bd2886SAlan Wright 39929bd2886SAlan Wright if (idm_stat != IDMAP_SUCCESS) { 40029bd2886SAlan Wright smb_sd_term(sd); 40129bd2886SAlan Wright return (NT_STATUS_NONE_MAPPED); 40229bd2886SAlan Wright } 40329bd2886SAlan Wright 40429bd2886SAlan Wright sd->sd_group = sid; 40529bd2886SAlan Wright } 40629bd2886SAlan Wright 40729bd2886SAlan Wright /* DACL */ 40829bd2886SAlan Wright if (fs_sd->sd_secinfo & SMB_DACL_SECINFO) { 40929bd2886SAlan Wright if (fs_sd->sd_zdacl != NULL) { 410f96bd5c8SAlan Wright acl = smb_acl_from_zfs(fs_sd->sd_zdacl); 41129bd2886SAlan Wright if (acl == NULL) { 41229bd2886SAlan Wright smb_sd_term(sd); 41329bd2886SAlan Wright return (NT_STATUS_INTERNAL_ERROR); 41429bd2886SAlan Wright } 41529bd2886SAlan Wright 41629bd2886SAlan Wright /* 41729bd2886SAlan Wright * Need to sort the ACL before send it to Windows 41829bd2886SAlan Wright * clients. Winodws GUI is sensitive about the order 41929bd2886SAlan Wright * of ACEs. 42029bd2886SAlan Wright */ 42129bd2886SAlan Wright smb_acl_sort(acl); 42229bd2886SAlan Wright smb_sd_set_dacl(sd, acl, B_TRUE, 42329bd2886SAlan Wright fs_sd->sd_zdacl->acl_flags); 42429bd2886SAlan Wright } else { 42529bd2886SAlan Wright smb_sd_set_dacl(sd, NULL, B_FALSE, 0); 42629bd2886SAlan Wright } 42729bd2886SAlan Wright } 42829bd2886SAlan Wright 42929bd2886SAlan Wright /* SACL */ 43029bd2886SAlan Wright if (fs_sd->sd_secinfo & SMB_SACL_SECINFO) { 43129bd2886SAlan Wright if (fs_sd->sd_zsacl != NULL) { 432f96bd5c8SAlan Wright acl = smb_acl_from_zfs(fs_sd->sd_zsacl); 43329bd2886SAlan Wright if (acl == NULL) { 43429bd2886SAlan Wright smb_sd_term(sd); 43529bd2886SAlan Wright return (NT_STATUS_INTERNAL_ERROR); 43629bd2886SAlan Wright } 43729bd2886SAlan Wright 43829bd2886SAlan Wright smb_sd_set_sacl(sd, acl, B_TRUE, 43929bd2886SAlan Wright fs_sd->sd_zsacl->acl_flags); 44029bd2886SAlan Wright } else { 44129bd2886SAlan Wright smb_sd_set_sacl(sd, NULL, B_FALSE, 0); 44229bd2886SAlan Wright } 44329bd2886SAlan Wright } 44429bd2886SAlan Wright 44529bd2886SAlan Wright return (status); 44629bd2886SAlan Wright } 44729bd2886SAlan Wright 44829bd2886SAlan Wright static void 44929bd2886SAlan Wright smb_sd_set_dacl(smb_sd_t *sd, smb_acl_t *acl, boolean_t present, int flags) 45029bd2886SAlan Wright { 45129bd2886SAlan Wright assert((sd->sd_control & SE_SELF_RELATIVE) == 0); 45229bd2886SAlan Wright 45329bd2886SAlan Wright sd->sd_dacl = acl; 45429bd2886SAlan Wright 45529bd2886SAlan Wright if (flags & ACL_DEFAULTED) 45629bd2886SAlan Wright sd->sd_control |= SE_DACL_DEFAULTED; 45729bd2886SAlan Wright if (flags & ACL_AUTO_INHERIT) 45829bd2886SAlan Wright sd->sd_control |= SE_DACL_AUTO_INHERITED; 45929bd2886SAlan Wright if (flags & ACL_PROTECTED) 46029bd2886SAlan Wright sd->sd_control |= SE_DACL_PROTECTED; 46129bd2886SAlan Wright 46229bd2886SAlan Wright if (present) 46329bd2886SAlan Wright sd->sd_control |= SE_DACL_PRESENT; 46429bd2886SAlan Wright } 46529bd2886SAlan Wright 46629bd2886SAlan Wright static void 46729bd2886SAlan Wright smb_sd_set_sacl(smb_sd_t *sd, smb_acl_t *acl, boolean_t present, int flags) 46829bd2886SAlan Wright { 46929bd2886SAlan Wright assert((sd->sd_control & SE_SELF_RELATIVE) == 0); 47029bd2886SAlan Wright 47129bd2886SAlan Wright sd->sd_sacl = acl; 47229bd2886SAlan Wright 47329bd2886SAlan Wright if (flags & ACL_DEFAULTED) 47429bd2886SAlan Wright sd->sd_control |= SE_SACL_DEFAULTED; 47529bd2886SAlan Wright if (flags & ACL_AUTO_INHERIT) 47629bd2886SAlan Wright sd->sd_control |= SE_SACL_AUTO_INHERITED; 47729bd2886SAlan Wright if (flags & ACL_PROTECTED) 47829bd2886SAlan Wright sd->sd_control |= SE_SACL_PROTECTED; 47929bd2886SAlan Wright 48029bd2886SAlan Wright if (present) 48129bd2886SAlan Wright sd->sd_control |= SE_SACL_PRESENT; 48229bd2886SAlan Wright } 48329bd2886SAlan Wright 48429bd2886SAlan Wright /* 48529bd2886SAlan Wright * smb_fssd_init 48629bd2886SAlan Wright * 48729bd2886SAlan Wright * Initializes the given FS SD structure. 48829bd2886SAlan Wright */ 48929bd2886SAlan Wright void 49029bd2886SAlan Wright smb_fssd_init(smb_fssd_t *fs_sd, uint32_t secinfo, uint32_t flags) 49129bd2886SAlan Wright { 49229bd2886SAlan Wright bzero(fs_sd, sizeof (smb_fssd_t)); 49329bd2886SAlan Wright fs_sd->sd_secinfo = secinfo; 49429bd2886SAlan Wright fs_sd->sd_flags = flags; 49529bd2886SAlan Wright } 49629bd2886SAlan Wright 49729bd2886SAlan Wright /* 49829bd2886SAlan Wright * smb_fssd_term 49929bd2886SAlan Wright * 50029bd2886SAlan Wright * Frees allocated memory for acl fields. 50129bd2886SAlan Wright */ 50229bd2886SAlan Wright void 50329bd2886SAlan Wright smb_fssd_term(smb_fssd_t *fs_sd) 50429bd2886SAlan Wright { 50529bd2886SAlan Wright assert(fs_sd); 50629bd2886SAlan Wright 50729bd2886SAlan Wright acl_free(fs_sd->sd_zdacl); 50829bd2886SAlan Wright acl_free(fs_sd->sd_zsacl); 50929bd2886SAlan Wright 51029bd2886SAlan Wright bzero(fs_sd, sizeof (smb_fssd_t)); 51129bd2886SAlan Wright } 512