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
smb_sd_init(smb_sd_t * sd,uint8_t revision)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
smb_sd_term(smb_sd_t * sd)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
smb_sd_len(smb_sd_t * sd,uint32_t secinfo)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
smb_sd_get_secinfo(smb_sd_t * sd)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
smb_sd_adjust_read_mask(int mask)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
smb_sd_read_acl(char * path,smb_fssd_t * fs_sd)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
smb_sd_read(char * path,smb_sd_t * sd,uint32_t secinfo)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
smb_sd_write_acl(char * path,smb_fssd_t * fs_sd)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
smb_sd_write(char * path,smb_sd_t * sd,uint32_t secinfo)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
smb_sd_tofs(smb_sd_t * sd,smb_fssd_t * fs_sd)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
smb_sd_fromfs(smb_fssd_t * fs_sd,smb_sd_t * sd)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
smb_sd_set_dacl(smb_sd_t * sd,smb_acl_t * acl,boolean_t present,int flags)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
smb_sd_set_sacl(smb_sd_t * sd,smb_acl_t * acl,boolean_t present,int flags)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
smb_fssd_init(smb_fssd_t * fs_sd,uint32_t secinfo,uint32_t flags)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
smb_fssd_term(smb_fssd_t * fs_sd)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