19832Samw@Sun.COM /*
29832Samw@Sun.COM * CDDL HEADER START
39832Samw@Sun.COM *
49832Samw@Sun.COM * The contents of this file are subject to the terms of the
59832Samw@Sun.COM * Common Development and Distribution License (the "License").
69832Samw@Sun.COM * You may not use this file except in compliance with the License.
79832Samw@Sun.COM *
89832Samw@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99832Samw@Sun.COM * or http://www.opensolaris.org/os/licensing.
109832Samw@Sun.COM * See the License for the specific language governing permissions
119832Samw@Sun.COM * and limitations under the License.
129832Samw@Sun.COM *
139832Samw@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
149832Samw@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159832Samw@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
169832Samw@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
179832Samw@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
189832Samw@Sun.COM *
199832Samw@Sun.COM * CDDL HEADER END
209832Samw@Sun.COM */
2112508Samw@Sun.COM
229832Samw@Sun.COM /*
2312508Samw@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
249832Samw@Sun.COM */
259832Samw@Sun.COM
269832Samw@Sun.COM /*
279832Samw@Sun.COM * This module provides Security Descriptor handling functions.
289832Samw@Sun.COM */
299832Samw@Sun.COM
309832Samw@Sun.COM #include <strings.h>
319832Samw@Sun.COM #include <assert.h>
32*12914SJoyce.McIntosh@Sun.COM #include <errno.h>
339832Samw@Sun.COM #include <smbsrv/ntifs.h>
349832Samw@Sun.COM #include <smbsrv/smb_idmap.h>
359914Samw@Sun.COM #include <smbsrv/libsmb.h>
369832Samw@Sun.COM
379832Samw@Sun.COM #define SMB_SHR_ACE_READ_PERMS (ACE_READ_PERMS | ACE_EXECUTE | ACE_SYNCHRONIZE)
389832Samw@Sun.COM #define SMB_SHR_ACE_CONTROL_PERMS (ACE_MODIFY_PERMS & (~ACE_DELETE_CHILD))
399832Samw@Sun.COM
4011963SAfshin.Ardakani@Sun.COM /*
4111963SAfshin.Ardakani@Sun.COM * This mapping table is provided to map permissions set by chmod
4211963SAfshin.Ardakani@Sun.COM * using 'read_set' and 'modify_set' to what Windows share ACL GUI
4311963SAfshin.Ardakani@Sun.COM * expects as Read and Control, respectively.
4411963SAfshin.Ardakani@Sun.COM */
459914Samw@Sun.COM static struct {
469914Samw@Sun.COM int am_ace_perms;
479914Samw@Sun.COM int am_share_perms;
489914Samw@Sun.COM } smb_ace_map[] = {
499914Samw@Sun.COM { ACE_MODIFY_PERMS, SMB_SHR_ACE_CONTROL_PERMS },
509914Samw@Sun.COM { ACE_READ_PERMS, SMB_SHR_ACE_READ_PERMS }
519914Samw@Sun.COM };
529914Samw@Sun.COM
539914Samw@Sun.COM #define SMB_ACE_MASK_MAP_SIZE (sizeof (smb_ace_map)/sizeof (smb_ace_map[0]))
549914Samw@Sun.COM
559832Samw@Sun.COM static void smb_sd_set_sacl(smb_sd_t *, smb_acl_t *, boolean_t, int);
569832Samw@Sun.COM static void smb_sd_set_dacl(smb_sd_t *, smb_acl_t *, boolean_t, int);
579832Samw@Sun.COM
589832Samw@Sun.COM void
smb_sd_init(smb_sd_t * sd,uint8_t revision)599832Samw@Sun.COM smb_sd_init(smb_sd_t *sd, uint8_t revision)
609832Samw@Sun.COM {
619832Samw@Sun.COM bzero(sd, sizeof (smb_sd_t));
629832Samw@Sun.COM sd->sd_revision = revision;
639832Samw@Sun.COM }
649832Samw@Sun.COM
659832Samw@Sun.COM /*
669832Samw@Sun.COM * smb_sd_term
679832Samw@Sun.COM *
689832Samw@Sun.COM * Free non-NULL members of 'sd' which has to be in
699832Samw@Sun.COM * absolute (pointer) form.
709832Samw@Sun.COM */
719832Samw@Sun.COM void
smb_sd_term(smb_sd_t * sd)729832Samw@Sun.COM smb_sd_term(smb_sd_t *sd)
739832Samw@Sun.COM {
749832Samw@Sun.COM assert(sd);
759832Samw@Sun.COM assert((sd->sd_control & SE_SELF_RELATIVE) == 0);
769832Samw@Sun.COM
779832Samw@Sun.COM smb_sid_free(sd->sd_owner);
789832Samw@Sun.COM smb_sid_free(sd->sd_group);
799832Samw@Sun.COM smb_acl_free(sd->sd_dacl);
809832Samw@Sun.COM smb_acl_free(sd->sd_sacl);
819832Samw@Sun.COM
829832Samw@Sun.COM bzero(sd, sizeof (smb_sd_t));
839832Samw@Sun.COM }
849832Samw@Sun.COM
859832Samw@Sun.COM uint32_t
smb_sd_len(smb_sd_t * sd,uint32_t secinfo)869832Samw@Sun.COM smb_sd_len(smb_sd_t *sd, uint32_t secinfo)
879832Samw@Sun.COM {
889832Samw@Sun.COM uint32_t length = SMB_SD_HDRSIZE;
899832Samw@Sun.COM
909832Samw@Sun.COM if (secinfo & SMB_OWNER_SECINFO)
919832Samw@Sun.COM length += smb_sid_len(sd->sd_owner);
929832Samw@Sun.COM
939832Samw@Sun.COM if (secinfo & SMB_GROUP_SECINFO)
949832Samw@Sun.COM length += smb_sid_len(sd->sd_group);
959832Samw@Sun.COM
969832Samw@Sun.COM if (secinfo & SMB_DACL_SECINFO)
979832Samw@Sun.COM length += smb_acl_len(sd->sd_dacl);
989832Samw@Sun.COM
999832Samw@Sun.COM if (secinfo & SMB_SACL_SECINFO)
1009832Samw@Sun.COM length += smb_acl_len(sd->sd_sacl);
1019832Samw@Sun.COM
1029832Samw@Sun.COM return (length);
1039832Samw@Sun.COM }
1049832Samw@Sun.COM
1059832Samw@Sun.COM /*
1069832Samw@Sun.COM * smb_sd_get_secinfo
1079832Samw@Sun.COM *
1089832Samw@Sun.COM * Return the security information mask for the specified security
1099832Samw@Sun.COM * descriptor.
1109832Samw@Sun.COM */
1119832Samw@Sun.COM uint32_t
smb_sd_get_secinfo(smb_sd_t * sd)1129832Samw@Sun.COM smb_sd_get_secinfo(smb_sd_t *sd)
1139832Samw@Sun.COM {
1149832Samw@Sun.COM uint32_t sec_info = 0;
1159832Samw@Sun.COM
1169832Samw@Sun.COM if (sd == NULL)
1179832Samw@Sun.COM return (0);
1189832Samw@Sun.COM
1199832Samw@Sun.COM if (sd->sd_owner)
1209832Samw@Sun.COM sec_info |= SMB_OWNER_SECINFO;
1219832Samw@Sun.COM
1229832Samw@Sun.COM if (sd->sd_group)
1239832Samw@Sun.COM sec_info |= SMB_GROUP_SECINFO;
1249832Samw@Sun.COM
1259832Samw@Sun.COM if (sd->sd_dacl)
1269832Samw@Sun.COM sec_info |= SMB_DACL_SECINFO;
1279832Samw@Sun.COM
1289832Samw@Sun.COM if (sd->sd_sacl)
1299832Samw@Sun.COM sec_info |= SMB_SACL_SECINFO;
1309832Samw@Sun.COM
1319832Samw@Sun.COM return (sec_info);
1329832Samw@Sun.COM }
1339832Samw@Sun.COM
1349832Samw@Sun.COM /*
1359832Samw@Sun.COM * Adjust the Access Mask so that ZFS ACE mask and Windows ACE read mask match.
1369832Samw@Sun.COM */
1379832Samw@Sun.COM static int
smb_sd_adjust_read_mask(int mask)1389832Samw@Sun.COM smb_sd_adjust_read_mask(int mask)
1399832Samw@Sun.COM {
1409914Samw@Sun.COM int i;
1419914Samw@Sun.COM
1429914Samw@Sun.COM for (i = 0; i < SMB_ACE_MASK_MAP_SIZE; ++i) {
1439914Samw@Sun.COM if (smb_ace_map[i].am_ace_perms == mask)
1449914Samw@Sun.COM return (smb_ace_map[i].am_share_perms);
1459914Samw@Sun.COM }
1469914Samw@Sun.COM
14711963SAfshin.Ardakani@Sun.COM return (mask);
1489832Samw@Sun.COM }
1499832Samw@Sun.COM
1509832Samw@Sun.COM /*
1519832Samw@Sun.COM * Get ZFS acl from the share path via acl_get() method.
1529832Samw@Sun.COM */
1539832Samw@Sun.COM static uint32_t
smb_sd_read_acl(char * path,smb_fssd_t * fs_sd)1549832Samw@Sun.COM smb_sd_read_acl(char *path, smb_fssd_t *fs_sd)
1559832Samw@Sun.COM {
1569832Samw@Sun.COM acl_t *z_acl;
1579832Samw@Sun.COM ace_t *z_ace;
1589832Samw@Sun.COM
1599832Samw@Sun.COM fs_sd->sd_gid = fs_sd->sd_uid = 0;
1609832Samw@Sun.COM
161*12914SJoyce.McIntosh@Sun.COM errno = 0;
162*12914SJoyce.McIntosh@Sun.COM if (acl_get(path, 0, &z_acl) != 0) {
163*12914SJoyce.McIntosh@Sun.COM switch (errno) {
164*12914SJoyce.McIntosh@Sun.COM case EACCES:
165*12914SJoyce.McIntosh@Sun.COM return (NT_STATUS_ACCESS_DENIED);
166*12914SJoyce.McIntosh@Sun.COM case ENOENT:
167*12914SJoyce.McIntosh@Sun.COM return (NT_STATUS_OBJECT_PATH_NOT_FOUND);
168*12914SJoyce.McIntosh@Sun.COM default:
169*12914SJoyce.McIntosh@Sun.COM return (NT_STATUS_INTERNAL_ERROR);
170*12914SJoyce.McIntosh@Sun.COM }
171*12914SJoyce.McIntosh@Sun.COM }
1729832Samw@Sun.COM
1739832Samw@Sun.COM if ((z_ace = (ace_t *)z_acl->acl_aclp) == NULL)
1749832Samw@Sun.COM return (NT_STATUS_INVALID_ACL);
1759832Samw@Sun.COM
17611963SAfshin.Ardakani@Sun.COM for (int i = 0; i < z_acl->acl_cnt; i++, z_ace++)
17711963SAfshin.Ardakani@Sun.COM z_ace->a_access_mask =
17811963SAfshin.Ardakani@Sun.COM smb_sd_adjust_read_mask(z_ace->a_access_mask);
1799832Samw@Sun.COM
1809832Samw@Sun.COM fs_sd->sd_zdacl = z_acl;
1819832Samw@Sun.COM fs_sd->sd_zsacl = NULL;
1829832Samw@Sun.COM return (NT_STATUS_SUCCESS);
1839832Samw@Sun.COM }
1849832Samw@Sun.COM
1859832Samw@Sun.COM /*
1869832Samw@Sun.COM * smb_sd_read
1879832Samw@Sun.COM *
1889832Samw@Sun.COM * Reads ZFS acl from filesystem using acl_get() method. Convert the ZFS acl to
1899832Samw@Sun.COM * a Win SD and return the Win SD in absolute form.
1909832Samw@Sun.COM *
1919832Samw@Sun.COM * NOTE: upon successful return caller MUST free the memory allocated
1929832Samw@Sun.COM * for the returned SD by calling smb_sd_term().
1939832Samw@Sun.COM */
1949832Samw@Sun.COM uint32_t
smb_sd_read(char * path,smb_sd_t * sd,uint32_t secinfo)1959832Samw@Sun.COM smb_sd_read(char *path, smb_sd_t *sd, uint32_t secinfo)
1969832Samw@Sun.COM {
1979832Samw@Sun.COM smb_fssd_t fs_sd;
1989832Samw@Sun.COM uint32_t status = NT_STATUS_SUCCESS;
1999832Samw@Sun.COM uint32_t sd_flags;
2009832Samw@Sun.COM int error;
2019832Samw@Sun.COM
2029832Samw@Sun.COM sd_flags = SMB_FSSD_FLAGS_DIR;
2039832Samw@Sun.COM smb_fssd_init(&fs_sd, secinfo, sd_flags);
2049832Samw@Sun.COM
2059832Samw@Sun.COM error = smb_sd_read_acl(path, &fs_sd);
2069832Samw@Sun.COM if (error != NT_STATUS_SUCCESS) {
2079832Samw@Sun.COM smb_fssd_term(&fs_sd);
2089832Samw@Sun.COM return (error);
2099832Samw@Sun.COM }
2109832Samw@Sun.COM
2119832Samw@Sun.COM status = smb_sd_fromfs(&fs_sd, sd);
2129832Samw@Sun.COM smb_fssd_term(&fs_sd);
2139832Samw@Sun.COM
2149832Samw@Sun.COM return (status);
2159832Samw@Sun.COM }
2169832Samw@Sun.COM
2179832Samw@Sun.COM /*
2189832Samw@Sun.COM * Apply ZFS acl to the share path via acl_set() method.
21911963SAfshin.Ardakani@Sun.COM * A NULL ACL pointer here represents an error.
22011963SAfshin.Ardakani@Sun.COM * Null or empty ACLs are handled in smb_sd_tofs().
2219832Samw@Sun.COM */
2229832Samw@Sun.COM static uint32_t
smb_sd_write_acl(char * path,smb_fssd_t * fs_sd)2239832Samw@Sun.COM smb_sd_write_acl(char *path, smb_fssd_t *fs_sd)
2249832Samw@Sun.COM {
2259832Samw@Sun.COM acl_t *z_acl;
2269832Samw@Sun.COM ace_t *z_ace;
2279832Samw@Sun.COM uint32_t status = NT_STATUS_SUCCESS;
2289832Samw@Sun.COM
22911963SAfshin.Ardakani@Sun.COM z_acl = fs_sd->sd_zdacl;
23011963SAfshin.Ardakani@Sun.COM if (z_acl == NULL)
2319832Samw@Sun.COM return (NT_STATUS_INVALID_ACL);
2329832Samw@Sun.COM
23311963SAfshin.Ardakani@Sun.COM z_ace = (ace_t *)z_acl->acl_aclp;
23411963SAfshin.Ardakani@Sun.COM if (z_ace == NULL)
2359832Samw@Sun.COM return (NT_STATUS_INVALID_ACL);
2369832Samw@Sun.COM
2379832Samw@Sun.COM fs_sd->sd_gid = fs_sd->sd_uid = 0;
2389832Samw@Sun.COM if (acl_set(path, z_acl) != 0)
2399832Samw@Sun.COM status = NT_STATUS_INTERNAL_ERROR;
2409832Samw@Sun.COM
2419832Samw@Sun.COM return (status);
2429832Samw@Sun.COM }
2439832Samw@Sun.COM
2449832Samw@Sun.COM /*
2459832Samw@Sun.COM * smb_sd_write
2469832Samw@Sun.COM *
2479832Samw@Sun.COM * Takes a Win SD in absolute form, converts it to
2489832Samw@Sun.COM * ZFS acl and applies the acl to the share path via acl_set() method.
2499832Samw@Sun.COM */
2509832Samw@Sun.COM uint32_t
smb_sd_write(char * path,smb_sd_t * sd,uint32_t secinfo)2519832Samw@Sun.COM smb_sd_write(char *path, smb_sd_t *sd, uint32_t secinfo)
2529832Samw@Sun.COM {
2539832Samw@Sun.COM smb_fssd_t fs_sd;
2549832Samw@Sun.COM uint32_t status = NT_STATUS_SUCCESS;
2559832Samw@Sun.COM uint32_t sd_flags;
2569832Samw@Sun.COM int error;
2579832Samw@Sun.COM
2589832Samw@Sun.COM sd_flags = SMB_FSSD_FLAGS_DIR;
2599832Samw@Sun.COM smb_fssd_init(&fs_sd, secinfo, sd_flags);
2609832Samw@Sun.COM
2619832Samw@Sun.COM error = smb_sd_tofs(sd, &fs_sd);
2629832Samw@Sun.COM if (error != NT_STATUS_SUCCESS) {
2639832Samw@Sun.COM smb_fssd_term(&fs_sd);
2649832Samw@Sun.COM return (error);
2659832Samw@Sun.COM }
2669832Samw@Sun.COM
2679832Samw@Sun.COM status = smb_sd_write_acl(path, &fs_sd);
2689832Samw@Sun.COM smb_fssd_term(&fs_sd);
2699832Samw@Sun.COM
2709832Samw@Sun.COM return (status);
2719832Samw@Sun.COM }
2729832Samw@Sun.COM
2739832Samw@Sun.COM /*
2749832Samw@Sun.COM * smb_sd_tofs
2759832Samw@Sun.COM *
2769832Samw@Sun.COM * Creates a filesystem security structure based on the given
2779832Samw@Sun.COM * Windows security descriptor.
2789832Samw@Sun.COM */
2799832Samw@Sun.COM uint32_t
smb_sd_tofs(smb_sd_t * sd,smb_fssd_t * fs_sd)2809832Samw@Sun.COM smb_sd_tofs(smb_sd_t *sd, smb_fssd_t *fs_sd)
2819832Samw@Sun.COM {
2829832Samw@Sun.COM smb_sid_t *sid;
2839832Samw@Sun.COM uint32_t status = NT_STATUS_SUCCESS;
2849832Samw@Sun.COM uint16_t sd_control;
2859832Samw@Sun.COM idmap_stat idm_stat;
2869832Samw@Sun.COM int idtype;
2879832Samw@Sun.COM int flags = 0;
2889832Samw@Sun.COM
2899832Samw@Sun.COM sd_control = sd->sd_control;
2909832Samw@Sun.COM
2919832Samw@Sun.COM /*
2929832Samw@Sun.COM * ZFS only has one set of flags so for now only
2939832Samw@Sun.COM * Windows DACL flags are taken into account.
2949832Samw@Sun.COM */
2959832Samw@Sun.COM if (sd_control & SE_DACL_DEFAULTED)
2969832Samw@Sun.COM flags |= ACL_DEFAULTED;
2979832Samw@Sun.COM if (sd_control & SE_DACL_AUTO_INHERITED)
2989832Samw@Sun.COM flags |= ACL_AUTO_INHERIT;
2999832Samw@Sun.COM if (sd_control & SE_DACL_PROTECTED)
3009832Samw@Sun.COM flags |= ACL_PROTECTED;
3019832Samw@Sun.COM
3029832Samw@Sun.COM if (fs_sd->sd_flags & SMB_FSSD_FLAGS_DIR)
3039832Samw@Sun.COM flags |= ACL_IS_DIR;
3049832Samw@Sun.COM
3059832Samw@Sun.COM /* Owner */
3069832Samw@Sun.COM if (fs_sd->sd_secinfo & SMB_OWNER_SECINFO) {
3079832Samw@Sun.COM sid = sd->sd_owner;
3089832Samw@Sun.COM if (!smb_sid_isvalid(sid))
3099832Samw@Sun.COM return (NT_STATUS_INVALID_SID);
3109832Samw@Sun.COM
3119832Samw@Sun.COM idtype = SMB_IDMAP_USER;
3129832Samw@Sun.COM idm_stat = smb_idmap_getid(sid, &fs_sd->sd_uid, &idtype);
3139832Samw@Sun.COM if (idm_stat != IDMAP_SUCCESS) {
3149832Samw@Sun.COM return (NT_STATUS_NONE_MAPPED);
3159832Samw@Sun.COM }
3169832Samw@Sun.COM }
3179832Samw@Sun.COM
3189832Samw@Sun.COM /* Group */
3199832Samw@Sun.COM if (fs_sd->sd_secinfo & SMB_GROUP_SECINFO) {
3209832Samw@Sun.COM sid = sd->sd_group;
3219832Samw@Sun.COM if (!smb_sid_isvalid(sid))
3229832Samw@Sun.COM return (NT_STATUS_INVALID_SID);
3239832Samw@Sun.COM
3249832Samw@Sun.COM idtype = SMB_IDMAP_GROUP;
3259832Samw@Sun.COM idm_stat = smb_idmap_getid(sid, &fs_sd->sd_gid, &idtype);
3269832Samw@Sun.COM if (idm_stat != IDMAP_SUCCESS) {
3279832Samw@Sun.COM return (NT_STATUS_NONE_MAPPED);
3289832Samw@Sun.COM }
3299832Samw@Sun.COM }
3309832Samw@Sun.COM
3319832Samw@Sun.COM /* DACL */
3329832Samw@Sun.COM if (fs_sd->sd_secinfo & SMB_DACL_SECINFO) {
3339832Samw@Sun.COM if (sd->sd_control & SE_DACL_PRESENT) {
3349832Samw@Sun.COM status = smb_acl_to_zfs(sd->sd_dacl, flags,
3359832Samw@Sun.COM SMB_DACL_SECINFO, &fs_sd->sd_zdacl);
3369832Samw@Sun.COM if (status != NT_STATUS_SUCCESS)
3379832Samw@Sun.COM return (status);
3389832Samw@Sun.COM }
3399832Samw@Sun.COM else
3409832Samw@Sun.COM return (NT_STATUS_INVALID_ACL);
3419832Samw@Sun.COM }
3429832Samw@Sun.COM
3439832Samw@Sun.COM /* SACL */
3449832Samw@Sun.COM if (fs_sd->sd_secinfo & SMB_SACL_SECINFO) {
3459832Samw@Sun.COM if (sd->sd_control & SE_SACL_PRESENT) {
3469832Samw@Sun.COM status = smb_acl_to_zfs(sd->sd_sacl, flags,
3479832Samw@Sun.COM SMB_SACL_SECINFO, &fs_sd->sd_zsacl);
3489832Samw@Sun.COM if (status != NT_STATUS_SUCCESS) {
3499832Samw@Sun.COM return (status);
3509832Samw@Sun.COM }
3519832Samw@Sun.COM } else {
3529832Samw@Sun.COM return (NT_STATUS_INVALID_ACL);
3539832Samw@Sun.COM }
3549832Samw@Sun.COM }
3559832Samw@Sun.COM
3569832Samw@Sun.COM return (status);
3579832Samw@Sun.COM }
3589832Samw@Sun.COM
3599832Samw@Sun.COM /*
3609832Samw@Sun.COM * smb_sd_fromfs
3619832Samw@Sun.COM *
3629832Samw@Sun.COM * Makes an Windows style security descriptor in absolute form
3639832Samw@Sun.COM * based on the given filesystem security information.
3649832Samw@Sun.COM *
3659832Samw@Sun.COM * Should call smb_sd_term() for the returned sd to free allocated
3669832Samw@Sun.COM * members.
3679832Samw@Sun.COM */
36811337SWilliam.Krier@Sun.COM uint32_t
smb_sd_fromfs(smb_fssd_t * fs_sd,smb_sd_t * sd)3699832Samw@Sun.COM smb_sd_fromfs(smb_fssd_t *fs_sd, smb_sd_t *sd)
3709832Samw@Sun.COM {
3719832Samw@Sun.COM uint32_t status = NT_STATUS_SUCCESS;
3729832Samw@Sun.COM smb_acl_t *acl = NULL;
3739832Samw@Sun.COM smb_sid_t *sid;
3749832Samw@Sun.COM idmap_stat idm_stat;
3759832Samw@Sun.COM
3769832Samw@Sun.COM assert(fs_sd);
3779832Samw@Sun.COM assert(sd);
3789832Samw@Sun.COM
3799832Samw@Sun.COM smb_sd_init(sd, SECURITY_DESCRIPTOR_REVISION);
3809832Samw@Sun.COM
3819832Samw@Sun.COM /* Owner */
3829832Samw@Sun.COM if (fs_sd->sd_secinfo & SMB_OWNER_SECINFO) {
3839832Samw@Sun.COM idm_stat = smb_idmap_getsid(fs_sd->sd_uid,
3849832Samw@Sun.COM SMB_IDMAP_USER, &sid);
3859832Samw@Sun.COM
3869832Samw@Sun.COM if (idm_stat != IDMAP_SUCCESS) {
3879832Samw@Sun.COM smb_sd_term(sd);
3889832Samw@Sun.COM return (NT_STATUS_NONE_MAPPED);
3899832Samw@Sun.COM }
3909832Samw@Sun.COM
3919832Samw@Sun.COM sd->sd_owner = sid;
3929832Samw@Sun.COM }
3939832Samw@Sun.COM
3949832Samw@Sun.COM /* Group */
3959832Samw@Sun.COM if (fs_sd->sd_secinfo & SMB_GROUP_SECINFO) {
3969832Samw@Sun.COM idm_stat = smb_idmap_getsid(fs_sd->sd_gid,
3979832Samw@Sun.COM SMB_IDMAP_GROUP, &sid);
3989832Samw@Sun.COM
3999832Samw@Sun.COM if (idm_stat != IDMAP_SUCCESS) {
4009832Samw@Sun.COM smb_sd_term(sd);
4019832Samw@Sun.COM return (NT_STATUS_NONE_MAPPED);
4029832Samw@Sun.COM }
4039832Samw@Sun.COM
4049832Samw@Sun.COM sd->sd_group = sid;
4059832Samw@Sun.COM }
4069832Samw@Sun.COM
4079832Samw@Sun.COM /* DACL */
4089832Samw@Sun.COM if (fs_sd->sd_secinfo & SMB_DACL_SECINFO) {
4099832Samw@Sun.COM if (fs_sd->sd_zdacl != NULL) {
41011447Samw@Sun.COM acl = smb_acl_from_zfs(fs_sd->sd_zdacl);
4119832Samw@Sun.COM if (acl == NULL) {
4129832Samw@Sun.COM smb_sd_term(sd);
4139832Samw@Sun.COM return (NT_STATUS_INTERNAL_ERROR);
4149832Samw@Sun.COM }
4159832Samw@Sun.COM
4169832Samw@Sun.COM /*
4179832Samw@Sun.COM * Need to sort the ACL before send it to Windows
4189832Samw@Sun.COM * clients. Winodws GUI is sensitive about the order
4199832Samw@Sun.COM * of ACEs.
4209832Samw@Sun.COM */
4219832Samw@Sun.COM smb_acl_sort(acl);
4229832Samw@Sun.COM smb_sd_set_dacl(sd, acl, B_TRUE,
4239832Samw@Sun.COM fs_sd->sd_zdacl->acl_flags);
4249832Samw@Sun.COM } else {
4259832Samw@Sun.COM smb_sd_set_dacl(sd, NULL, B_FALSE, 0);
4269832Samw@Sun.COM }
4279832Samw@Sun.COM }
4289832Samw@Sun.COM
4299832Samw@Sun.COM /* SACL */
4309832Samw@Sun.COM if (fs_sd->sd_secinfo & SMB_SACL_SECINFO) {
4319832Samw@Sun.COM if (fs_sd->sd_zsacl != NULL) {
43211447Samw@Sun.COM acl = smb_acl_from_zfs(fs_sd->sd_zsacl);
4339832Samw@Sun.COM if (acl == NULL) {
4349832Samw@Sun.COM smb_sd_term(sd);
4359832Samw@Sun.COM return (NT_STATUS_INTERNAL_ERROR);
4369832Samw@Sun.COM }
4379832Samw@Sun.COM
4389832Samw@Sun.COM smb_sd_set_sacl(sd, acl, B_TRUE,
4399832Samw@Sun.COM fs_sd->sd_zsacl->acl_flags);
4409832Samw@Sun.COM } else {
4419832Samw@Sun.COM smb_sd_set_sacl(sd, NULL, B_FALSE, 0);
4429832Samw@Sun.COM }
4439832Samw@Sun.COM }
4449832Samw@Sun.COM
4459832Samw@Sun.COM return (status);
4469832Samw@Sun.COM }
4479832Samw@Sun.COM
4489832Samw@Sun.COM static void
smb_sd_set_dacl(smb_sd_t * sd,smb_acl_t * acl,boolean_t present,int flags)4499832Samw@Sun.COM smb_sd_set_dacl(smb_sd_t *sd, smb_acl_t *acl, boolean_t present, int flags)
4509832Samw@Sun.COM {
4519832Samw@Sun.COM assert((sd->sd_control & SE_SELF_RELATIVE) == 0);
4529832Samw@Sun.COM
4539832Samw@Sun.COM sd->sd_dacl = acl;
4549832Samw@Sun.COM
4559832Samw@Sun.COM if (flags & ACL_DEFAULTED)
4569832Samw@Sun.COM sd->sd_control |= SE_DACL_DEFAULTED;
4579832Samw@Sun.COM if (flags & ACL_AUTO_INHERIT)
4589832Samw@Sun.COM sd->sd_control |= SE_DACL_AUTO_INHERITED;
4599832Samw@Sun.COM if (flags & ACL_PROTECTED)
4609832Samw@Sun.COM sd->sd_control |= SE_DACL_PROTECTED;
4619832Samw@Sun.COM
4629832Samw@Sun.COM if (present)
4639832Samw@Sun.COM sd->sd_control |= SE_DACL_PRESENT;
4649832Samw@Sun.COM }
4659832Samw@Sun.COM
4669832Samw@Sun.COM static void
smb_sd_set_sacl(smb_sd_t * sd,smb_acl_t * acl,boolean_t present,int flags)4679832Samw@Sun.COM smb_sd_set_sacl(smb_sd_t *sd, smb_acl_t *acl, boolean_t present, int flags)
4689832Samw@Sun.COM {
4699832Samw@Sun.COM assert((sd->sd_control & SE_SELF_RELATIVE) == 0);
4709832Samw@Sun.COM
4719832Samw@Sun.COM sd->sd_sacl = acl;
4729832Samw@Sun.COM
4739832Samw@Sun.COM if (flags & ACL_DEFAULTED)
4749832Samw@Sun.COM sd->sd_control |= SE_SACL_DEFAULTED;
4759832Samw@Sun.COM if (flags & ACL_AUTO_INHERIT)
4769832Samw@Sun.COM sd->sd_control |= SE_SACL_AUTO_INHERITED;
4779832Samw@Sun.COM if (flags & ACL_PROTECTED)
4789832Samw@Sun.COM sd->sd_control |= SE_SACL_PROTECTED;
4799832Samw@Sun.COM
4809832Samw@Sun.COM if (present)
4819832Samw@Sun.COM sd->sd_control |= SE_SACL_PRESENT;
4829832Samw@Sun.COM }
4839832Samw@Sun.COM
4849832Samw@Sun.COM /*
4859832Samw@Sun.COM * smb_fssd_init
4869832Samw@Sun.COM *
4879832Samw@Sun.COM * Initializes the given FS SD structure.
4889832Samw@Sun.COM */
4899832Samw@Sun.COM void
smb_fssd_init(smb_fssd_t * fs_sd,uint32_t secinfo,uint32_t flags)4909832Samw@Sun.COM smb_fssd_init(smb_fssd_t *fs_sd, uint32_t secinfo, uint32_t flags)
4919832Samw@Sun.COM {
4929832Samw@Sun.COM bzero(fs_sd, sizeof (smb_fssd_t));
4939832Samw@Sun.COM fs_sd->sd_secinfo = secinfo;
4949832Samw@Sun.COM fs_sd->sd_flags = flags;
4959832Samw@Sun.COM }
4969832Samw@Sun.COM
4979832Samw@Sun.COM /*
4989832Samw@Sun.COM * smb_fssd_term
4999832Samw@Sun.COM *
5009832Samw@Sun.COM * Frees allocated memory for acl fields.
5019832Samw@Sun.COM */
5029832Samw@Sun.COM void
smb_fssd_term(smb_fssd_t * fs_sd)5039832Samw@Sun.COM smb_fssd_term(smb_fssd_t *fs_sd)
5049832Samw@Sun.COM {
5059832Samw@Sun.COM assert(fs_sd);
5069832Samw@Sun.COM
5079832Samw@Sun.COM acl_free(fs_sd->sd_zdacl);
5089832Samw@Sun.COM acl_free(fs_sd->sd_zsacl);
5099832Samw@Sun.COM
5109832Samw@Sun.COM bzero(fs_sd, sizeof (smb_fssd_t));
5119832Samw@Sun.COM }
512