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.
24*87b81758SJoyce McIntosh * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
2529bd2886SAlan Wright */
2629bd2886SAlan Wright
2729bd2886SAlan Wright /*
2829bd2886SAlan Wright * This is a helper file to get/set Windows SD. This is used by
2929bd2886SAlan Wright * SRVSVC service.
3029bd2886SAlan Wright */
3129bd2886SAlan Wright #include <strings.h>
3229bd2886SAlan Wright #include <libzfs.h>
33148c5f43SAlan Wright
34148c5f43SAlan Wright #include <smbsrv/libsmb.h>
3529bd2886SAlan Wright #include <smbsrv/libmlsvc.h>
3629bd2886SAlan Wright #include <smbsrv/ndl/srvsvc.ndl>
3729bd2886SAlan Wright
3829bd2886SAlan Wright /* Size of offset members in mslm_security_descriptor structure */
3929bd2886SAlan Wright #define SRVSVC_SD_OFFSET_SZ 16
4029bd2886SAlan Wright
4129bd2886SAlan Wright #define SRVSVC_ACE_OFFSET 8
4229bd2886SAlan Wright #define SRVSVC_SID_OFFSET 8
4329bd2886SAlan Wright
44f96bd5c8SAlan Wright uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *);
45f96bd5c8SAlan Wright
46fe1c642dSBill Krier static uint32_t srvsvc_sd_get_autohome(const smb_share_t *, smb_sd_t *);
4729bd2886SAlan Wright static uint32_t srvsvc_sd_status_to_error(uint32_t);
4829bd2886SAlan Wright static uint32_t srvsvc_sd_set_absolute(uint8_t *, smb_sd_t *);
4929bd2886SAlan Wright
5029bd2886SAlan Wright /*
5129bd2886SAlan Wright * This method computes ACL on share path from a share name.
5229bd2886SAlan Wright * Return 0 upon success, -1 upon failure.
5329bd2886SAlan Wright */
5429bd2886SAlan Wright static int
srvsvc_shareacl_getpath(smb_share_t * si,char * shr_acl_path)5529bd2886SAlan Wright srvsvc_shareacl_getpath(smb_share_t *si, char *shr_acl_path)
5629bd2886SAlan Wright {
5729bd2886SAlan Wright char dataset[MAXPATHLEN];
5829bd2886SAlan Wright char mp[ZFS_MAXPROPLEN];
5929bd2886SAlan Wright libzfs_handle_t *libhd;
6029bd2886SAlan Wright zfs_handle_t *zfshd;
6129bd2886SAlan Wright int ret = 0;
6229bd2886SAlan Wright
6329bd2886SAlan Wright if ((libhd = libzfs_init()) == NULL)
6429bd2886SAlan Wright return (-1);
6529bd2886SAlan Wright
66*87b81758SJoyce McIntosh ret = smb_getdataset(libhd, si->shr_path, dataset, MAXPATHLEN);
67*87b81758SJoyce McIntosh if (ret != 0) {
68*87b81758SJoyce McIntosh libzfs_fini(libhd);
69*87b81758SJoyce McIntosh return (ret);
70*87b81758SJoyce McIntosh }
71*87b81758SJoyce McIntosh
72*87b81758SJoyce McIntosh
7329bd2886SAlan Wright if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
7429bd2886SAlan Wright libzfs_fini(libhd);
7529bd2886SAlan Wright return (-1);
7629bd2886SAlan Wright }
7729bd2886SAlan Wright
7829bd2886SAlan Wright if (zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, mp, sizeof (mp), NULL,
7929bd2886SAlan Wright NULL, 0, B_FALSE) != 0) {
8029bd2886SAlan Wright zfs_close(zfshd);
8129bd2886SAlan Wright libzfs_fini(libhd);
8229bd2886SAlan Wright return (-1);
8329bd2886SAlan Wright }
8429bd2886SAlan Wright
8529bd2886SAlan Wright zfs_close(zfshd);
8629bd2886SAlan Wright libzfs_fini(libhd);
8729bd2886SAlan Wright
8829bd2886SAlan Wright (void) snprintf(shr_acl_path, MAXPATHLEN, "%s/.zfs/shares/%s",
8929bd2886SAlan Wright mp, si->shr_name);
9029bd2886SAlan Wright
9129bd2886SAlan Wright return (ret);
9229bd2886SAlan Wright }
9329bd2886SAlan Wright
9429bd2886SAlan Wright /*
9529bd2886SAlan Wright * This method sets Security Descriptor on a share path.
9629bd2886SAlan Wright *
9729bd2886SAlan Wright * Returns:
9829bd2886SAlan Wright * ERROR_SUCCESS
9929bd2886SAlan Wright * ERROR_NOT_ENOUGH_MEMORY
10029bd2886SAlan Wright * ERROR_INVALID_ACL
10129bd2886SAlan Wright * ERROR_INVALID_SID
10229bd2886SAlan Wright * ERROR_INVALID_SECURITY_DESCR
10329bd2886SAlan Wright * ERROR_NONE_MAPPED
10429bd2886SAlan Wright * ERROR_INTERNAL_ERROR
10529bd2886SAlan Wright * ERROR_PATH_NOT_FOUND
10629bd2886SAlan Wright */
10729bd2886SAlan Wright uint32_t
srvsvc_sd_set(smb_share_t * si,uint8_t * sdbuf)10829bd2886SAlan Wright srvsvc_sd_set(smb_share_t *si, uint8_t *sdbuf)
10929bd2886SAlan Wright {
11029bd2886SAlan Wright smb_sd_t sd;
11129bd2886SAlan Wright uint32_t status = ERROR_SUCCESS;
11229bd2886SAlan Wright char path[MAXPATHLEN];
11329bd2886SAlan Wright int ret = 0;
11429bd2886SAlan Wright
11529bd2886SAlan Wright ret = srvsvc_shareacl_getpath(si, path);
11629bd2886SAlan Wright if (ret != 0)
11729bd2886SAlan Wright return (ERROR_PATH_NOT_FOUND);
11829bd2886SAlan Wright
11929bd2886SAlan Wright smb_sd_init(&sd, 0);
12029bd2886SAlan Wright status = srvsvc_sd_set_absolute(sdbuf, &sd);
12129bd2886SAlan Wright if (status != ERROR_SUCCESS) {
12229bd2886SAlan Wright smb_sd_term(&sd);
12329bd2886SAlan Wright return (status);
12429bd2886SAlan Wright }
12529bd2886SAlan Wright
12629bd2886SAlan Wright status = smb_sd_write(path, &sd, SMB_DACL_SECINFO);
12729bd2886SAlan Wright status = srvsvc_sd_status_to_error(status);
12829bd2886SAlan Wright smb_sd_term(&sd);
12929bd2886SAlan Wright
13029bd2886SAlan Wright return (status);
13129bd2886SAlan Wright }
13229bd2886SAlan Wright
13329bd2886SAlan Wright /*
13429bd2886SAlan Wright * This method returns a Security Descriptor of a share path in self relative
13529bd2886SAlan Wright * format. Call to this function with NULL buffer, returns the size of the
13629bd2886SAlan Wright * security descriptor, which can be used to allocate buffer.
13729bd2886SAlan Wright *
13829bd2886SAlan Wright * Returns:
13929bd2886SAlan Wright * ERROR_SUCCESS
14029bd2886SAlan Wright * ERROR_NOT_ENOUGH_MEMORY
14129bd2886SAlan Wright * ERROR_INVALID_ACL
14229bd2886SAlan Wright * ERROR_INVALID_SID
14329bd2886SAlan Wright * ERROR_INVALID_SECURITY_DESCR
14429bd2886SAlan Wright * ERROR_INVALID_PARAMETER
14529bd2886SAlan Wright * ERROR_NONE_MAPPED
14629bd2886SAlan Wright * ERROR_INTERNAL_ERROR
14729bd2886SAlan Wright * ERROR_PATH_NOT_FOUND
14829bd2886SAlan Wright */
14929bd2886SAlan Wright uint32_t
srvsvc_sd_get(smb_share_t * si,uint8_t * sdbuf,uint32_t * size)15029bd2886SAlan Wright srvsvc_sd_get(smb_share_t *si, uint8_t *sdbuf, uint32_t *size)
15129bd2886SAlan Wright {
15229bd2886SAlan Wright smb_sd_t sd;
15329bd2886SAlan Wright uint32_t status = ERROR_SUCCESS;
15429bd2886SAlan Wright char path[MAXPATHLEN];
15529bd2886SAlan Wright int ret = 0;
15629bd2886SAlan Wright
15729bd2886SAlan Wright if (sdbuf == NULL && size == NULL)
15829bd2886SAlan Wright return (ERROR_INVALID_PARAMETER);
15929bd2886SAlan Wright
16029bd2886SAlan Wright bzero(&sd, sizeof (smb_sd_t));
161fe1c642dSBill Krier
162fe1c642dSBill Krier if (si->shr_flags & SMB_SHRF_AUTOHOME) {
163fe1c642dSBill Krier status = srvsvc_sd_get_autohome(si, &sd);
164fe1c642dSBill Krier } else {
165fe1c642dSBill Krier ret = srvsvc_shareacl_getpath(si, path);
166fe1c642dSBill Krier if (ret != 0)
167fe1c642dSBill Krier return (ERROR_PATH_NOT_FOUND);
168fe1c642dSBill Krier
169fe1c642dSBill Krier status = smb_sd_read(path, &sd, SMB_ALL_SECINFO);
170fe1c642dSBill Krier status = srvsvc_sd_status_to_error(status);
171fe1c642dSBill Krier }
172fe1c642dSBill Krier
17329bd2886SAlan Wright if (status != ERROR_SUCCESS) {
17429bd2886SAlan Wright smb_sd_term(&sd);
17529bd2886SAlan Wright return (status);
17629bd2886SAlan Wright }
17729bd2886SAlan Wright
17829bd2886SAlan Wright if (sdbuf == NULL) {
17929bd2886SAlan Wright *size = smb_sd_len(&sd, SMB_ALL_SECINFO);
18029bd2886SAlan Wright smb_sd_term(&sd);
18129bd2886SAlan Wright return (status);
18229bd2886SAlan Wright }
18329bd2886SAlan Wright
18429bd2886SAlan Wright status = srvsvc_sd_set_relative(&sd, sdbuf);
18529bd2886SAlan Wright
18629bd2886SAlan Wright smb_sd_term(&sd);
18729bd2886SAlan Wright return (status);
18829bd2886SAlan Wright }
18929bd2886SAlan Wright
190fe1c642dSBill Krier static uint32_t
srvsvc_sd_get_autohome(const smb_share_t * si,smb_sd_t * sd)191fe1c642dSBill Krier srvsvc_sd_get_autohome(const smb_share_t *si, smb_sd_t *sd)
192fe1c642dSBill Krier {
193fe1c642dSBill Krier smb_fssd_t fs_sd;
194fe1c642dSBill Krier acl_t *acl;
195fe1c642dSBill Krier uint32_t status;
196fe1c642dSBill Krier
197fe1c642dSBill Krier if (acl_fromtext("owner@:rwxpdDaARWcCos::allow", &acl) != 0)
198fe1c642dSBill Krier return (ERROR_NOT_ENOUGH_MEMORY);
199fe1c642dSBill Krier
200fe1c642dSBill Krier smb_fssd_init(&fs_sd, SMB_ALL_SECINFO, SMB_FSSD_FLAGS_DIR);
201fe1c642dSBill Krier fs_sd.sd_uid = si->shr_uid;
202fe1c642dSBill Krier fs_sd.sd_gid = si->shr_gid;
203fe1c642dSBill Krier fs_sd.sd_zdacl = acl;
204fe1c642dSBill Krier fs_sd.sd_zsacl = NULL;
205fe1c642dSBill Krier
206fe1c642dSBill Krier status = smb_sd_fromfs(&fs_sd, sd);
207fe1c642dSBill Krier status = srvsvc_sd_status_to_error(status);
208fe1c642dSBill Krier smb_fssd_term(&fs_sd);
209fe1c642dSBill Krier return (status);
210fe1c642dSBill Krier }
211fe1c642dSBill Krier
21229bd2886SAlan Wright /*
21329bd2886SAlan Wright * This method converts an ACE from absolute (pointer) to
21429bd2886SAlan Wright * self relative (flat buffer) format.
21529bd2886SAlan Wright *
21629bd2886SAlan Wright * Returns Win32 error codes.
21729bd2886SAlan Wright */
21829bd2886SAlan Wright static uint32_t
srvsvc_ace_set_relative(mslm_ace_t * m_ace,struct mslm_sid * m_sid,smb_ace_t * ace)21929bd2886SAlan Wright srvsvc_ace_set_relative(mslm_ace_t *m_ace, struct mslm_sid *m_sid,
22029bd2886SAlan Wright smb_ace_t *ace)
22129bd2886SAlan Wright {
22229bd2886SAlan Wright if ((m_ace == NULL) || (ace == NULL))
22329bd2886SAlan Wright return (ERROR_INVALID_PARAMETER);
22429bd2886SAlan Wright
22529bd2886SAlan Wright bcopy(&ace->se_hdr, &m_ace->header, sizeof (mslm_ace_hdr_t));
22629bd2886SAlan Wright m_ace->mask = ace->se_mask;
22729bd2886SAlan Wright
22829bd2886SAlan Wright if ((ace->se_sid == NULL) || (m_sid == NULL))
22929bd2886SAlan Wright return (ERROR_INVALID_PARAMETER);
23029bd2886SAlan Wright bcopy(ace->se_sid, m_sid, smb_sid_len(ace->se_sid));
23129bd2886SAlan Wright
23229bd2886SAlan Wright return (ERROR_SUCCESS);
23329bd2886SAlan Wright }
23429bd2886SAlan Wright
23529bd2886SAlan Wright /*
23629bd2886SAlan Wright * This method converts an ACL from absolute (pointer) to
23729bd2886SAlan Wright * self relative (flat buffer) format.
23829bd2886SAlan Wright *
23929bd2886SAlan Wright * Returns an initialized mslm_acl structure on success.
24029bd2886SAlan Wright * Returns NULL on failure.
24129bd2886SAlan Wright */
24229bd2886SAlan Wright static struct mslm_acl *
srvsvc_acl_set_relative(uint8_t * sdbuf,smb_acl_t * acl)24329bd2886SAlan Wright srvsvc_acl_set_relative(uint8_t *sdbuf, smb_acl_t *acl)
24429bd2886SAlan Wright {
24529bd2886SAlan Wright struct mslm_acl *m_acl;
24629bd2886SAlan Wright
24729bd2886SAlan Wright if (sdbuf == NULL)
24829bd2886SAlan Wright return (NULL);
24929bd2886SAlan Wright
25029bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
25129bd2886SAlan Wright m_acl = (struct mslm_acl *)sdbuf;
25229bd2886SAlan Wright m_acl->revision = acl->sl_revision;
25329bd2886SAlan Wright m_acl->sbz1 = 0;
25429bd2886SAlan Wright m_acl->size = acl->sl_bsize;
25529bd2886SAlan Wright m_acl->sbz2 = 0;
25629bd2886SAlan Wright m_acl->ace_count = acl->sl_acecnt;
25729bd2886SAlan Wright
25829bd2886SAlan Wright return (m_acl);
25929bd2886SAlan Wright }
26029bd2886SAlan Wright
26129bd2886SAlan Wright /*
26229bd2886SAlan Wright * This method converts Security Descriptor from absolute (pointer) to
26329bd2886SAlan Wright * self relative (flat buffer) format.
26429bd2886SAlan Wright *
26529bd2886SAlan Wright * Returns Win32 error codes.
26629bd2886SAlan Wright */
267f96bd5c8SAlan Wright uint32_t
srvsvc_sd_set_relative(smb_sd_t * sd,uint8_t * sdbuf)26829bd2886SAlan Wright srvsvc_sd_set_relative(smb_sd_t *sd, uint8_t *sdbuf)
26929bd2886SAlan Wright {
27029bd2886SAlan Wright mslm_security_descriptor_t *msd;
27129bd2886SAlan Wright int offset, len, i;
27229bd2886SAlan Wright smb_ace_t *ace;
27329bd2886SAlan Wright mslm_ace_t *m_ace;
27429bd2886SAlan Wright struct mslm_sid *m_sid;
27529bd2886SAlan Wright uint16_t ace_cnt;
27629bd2886SAlan Wright uint32_t status = ERROR_SUCCESS;
27729bd2886SAlan Wright
27829bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
27929bd2886SAlan Wright msd = (mslm_security_descriptor_t *)sdbuf;
28029bd2886SAlan Wright if (msd == NULL)
28129bd2886SAlan Wright return (ERROR_INVALID_SECURITY_DESCR);
28229bd2886SAlan Wright
28329bd2886SAlan Wright msd->revision = sd->sd_revision;
28429bd2886SAlan Wright msd->sbz1 = 0;
28529bd2886SAlan Wright msd->control = sd->sd_control | SE_SELF_RELATIVE;
28629bd2886SAlan Wright
28729bd2886SAlan Wright offset = sizeof (mslm_security_descriptor_t) - SRVSVC_SD_OFFSET_SZ;
28829bd2886SAlan Wright msd->offset_owner = msd->offset_group = 0;
28929bd2886SAlan Wright msd->offset_sacl = msd->offset_dacl = 0;
29029bd2886SAlan Wright
29129bd2886SAlan Wright if (sd->sd_owner != NULL) {
29229bd2886SAlan Wright msd->offset_owner = offset;
29329bd2886SAlan Wright
29429bd2886SAlan Wright if (sd->sd_owner == NULL)
29529bd2886SAlan Wright return (ERROR_NOT_ENOUGH_MEMORY);
29629bd2886SAlan Wright
29729bd2886SAlan Wright len = smb_sid_len(sd->sd_owner);
29829bd2886SAlan Wright bcopy(sd->sd_owner, &sdbuf[offset], len);
29929bd2886SAlan Wright offset += len;
30029bd2886SAlan Wright }
30129bd2886SAlan Wright
30229bd2886SAlan Wright if (sd->sd_group != NULL) {
30329bd2886SAlan Wright msd->offset_group = offset;
30429bd2886SAlan Wright
30529bd2886SAlan Wright if (sd->sd_group == NULL)
30629bd2886SAlan Wright return (ERROR_NOT_ENOUGH_MEMORY);
30729bd2886SAlan Wright
30829bd2886SAlan Wright len = smb_sid_len(sd->sd_group);
30929bd2886SAlan Wright bcopy(sd->sd_group, &sdbuf[offset], len);
31029bd2886SAlan Wright offset += len;
31129bd2886SAlan Wright }
31229bd2886SAlan Wright
31329bd2886SAlan Wright if (sd->sd_sacl != NULL) {
31429bd2886SAlan Wright msd->offset_sacl = offset;
31529bd2886SAlan Wright msd->sacl = srvsvc_acl_set_relative(&sdbuf[offset],
31629bd2886SAlan Wright sd->sd_sacl);
31729bd2886SAlan Wright if (msd->sacl == NULL)
31829bd2886SAlan Wright return (ERROR_INVALID_PARAMETER);
31929bd2886SAlan Wright
32029bd2886SAlan Wright ace = sd->sd_sacl->sl_aces;
32129bd2886SAlan Wright ace_cnt = msd->sacl->ace_count;
32229bd2886SAlan Wright offset += SRVSVC_ACE_OFFSET;
32329bd2886SAlan Wright
32429bd2886SAlan Wright for (i = 0; i < ace_cnt; i++, ace++) {
32529bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
32629bd2886SAlan Wright m_ace = (mslm_ace_t *)&sdbuf[offset];
32729bd2886SAlan Wright offset += SRVSVC_SID_OFFSET;
32829bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
32929bd2886SAlan Wright m_sid = (struct mslm_sid *)&sdbuf[offset];
33029bd2886SAlan Wright
33129bd2886SAlan Wright status = srvsvc_ace_set_relative(m_ace, m_sid, ace);
33229bd2886SAlan Wright if (status != ERROR_SUCCESS)
33329bd2886SAlan Wright return (status);
33429bd2886SAlan Wright offset += smb_sid_len(ace->se_sid);
33529bd2886SAlan Wright }
33629bd2886SAlan Wright }
33729bd2886SAlan Wright
33829bd2886SAlan Wright if (sd->sd_dacl != NULL) {
33929bd2886SAlan Wright msd->offset_dacl = offset;
34029bd2886SAlan Wright msd->dacl = srvsvc_acl_set_relative(&sdbuf[offset],
34129bd2886SAlan Wright sd->sd_dacl);
34229bd2886SAlan Wright if (msd->dacl == NULL)
34329bd2886SAlan Wright return (ERROR_INVALID_PARAMETER);
34429bd2886SAlan Wright
34529bd2886SAlan Wright ace = sd->sd_dacl->sl_aces;
34629bd2886SAlan Wright ace_cnt = msd->dacl->ace_count;
34729bd2886SAlan Wright offset += SRVSVC_ACE_OFFSET;
34829bd2886SAlan Wright
34929bd2886SAlan Wright for (i = 0; i < ace_cnt; i++, ace++) {
35029bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
35129bd2886SAlan Wright m_ace = (mslm_ace_t *)&sdbuf[offset];
35229bd2886SAlan Wright offset += SRVSVC_SID_OFFSET;
35329bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
35429bd2886SAlan Wright m_sid = (struct mslm_sid *)&sdbuf[offset];
35529bd2886SAlan Wright
35629bd2886SAlan Wright status = srvsvc_ace_set_relative(m_ace, m_sid, ace);
35729bd2886SAlan Wright if (status != ERROR_SUCCESS)
35829bd2886SAlan Wright return (status);
35929bd2886SAlan Wright offset += smb_sid_len(ace->se_sid);
36029bd2886SAlan Wright }
36129bd2886SAlan Wright }
36229bd2886SAlan Wright
36329bd2886SAlan Wright return (status);
36429bd2886SAlan Wright }
36529bd2886SAlan Wright
36629bd2886SAlan Wright /*
36729bd2886SAlan Wright * This method converts an ACE from self relative (flat buffer) to
36829bd2886SAlan Wright * absolute (pointer) format.
36929bd2886SAlan Wright *
37029bd2886SAlan Wright * Returns Win32 error codes.
37129bd2886SAlan Wright */
37229bd2886SAlan Wright static uint32_t
srvsvc_ace_set_absolute(mslm_ace_t * m_ace,struct mslm_sid * m_sid,smb_ace_t * ace)37329bd2886SAlan Wright srvsvc_ace_set_absolute(mslm_ace_t *m_ace, struct mslm_sid *m_sid,
37429bd2886SAlan Wright smb_ace_t *ace)
37529bd2886SAlan Wright {
37629bd2886SAlan Wright int sid_size = 0;
37729bd2886SAlan Wright if ((m_ace == NULL) || (ace == NULL) || (m_sid == NULL))
37829bd2886SAlan Wright return (ERROR_INVALID_PARAMETER);
37929bd2886SAlan Wright
38029bd2886SAlan Wright bzero(ace, sizeof (smb_ace_t));
38129bd2886SAlan Wright bcopy(&m_ace->header, &ace->se_hdr, sizeof (mslm_ace_hdr_t));
38229bd2886SAlan Wright ace->se_mask = m_ace->mask;
38329bd2886SAlan Wright
38429bd2886SAlan Wright sid_size = smb_sid_len((smb_sid_t *)m_sid);
38529bd2886SAlan Wright if ((ace->se_sid = malloc(sid_size)) == NULL)
38629bd2886SAlan Wright return (ERROR_NOT_ENOUGH_MEMORY);
38729bd2886SAlan Wright bcopy(m_sid, ace->se_sid, sid_size);
38829bd2886SAlan Wright
38929bd2886SAlan Wright return (ERROR_SUCCESS);
39029bd2886SAlan Wright }
39129bd2886SAlan Wright
39229bd2886SAlan Wright /*
39329bd2886SAlan Wright * This method converts an ACL from self relative (flat buffer) to
39429bd2886SAlan Wright * absolute (pointer) format.
39529bd2886SAlan Wright *
39629bd2886SAlan Wright * Returns an initialized smb_acl_t structure on success.
39729bd2886SAlan Wright * Returns NULL on failure.
39829bd2886SAlan Wright */
39929bd2886SAlan Wright static smb_acl_t *
srvsvc_acl_set_absolute(uint8_t * sdbuf,int * offset)40029bd2886SAlan Wright srvsvc_acl_set_absolute(uint8_t *sdbuf, int *offset)
40129bd2886SAlan Wright {
40229bd2886SAlan Wright uint8_t rev;
40329bd2886SAlan Wright uint16_t sz, ace_cnt;
40429bd2886SAlan Wright smb_acl_t *acl;
40529bd2886SAlan Wright
40629bd2886SAlan Wright bcopy(&sdbuf[*offset], &rev, sizeof (uint8_t));
40729bd2886SAlan Wright *offset += 2; /* Pad for Sbz1 */
40829bd2886SAlan Wright bcopy(&sdbuf[*offset], &sz, sizeof (uint16_t));
40929bd2886SAlan Wright *offset += 2;
41029bd2886SAlan Wright bcopy(&sdbuf[*offset], &ace_cnt, sizeof (uint16_t));
41129bd2886SAlan Wright *offset += 4; /* Pad for Sbz2 */
41229bd2886SAlan Wright
41329bd2886SAlan Wright acl = smb_acl_alloc(rev, sz, ace_cnt);
41429bd2886SAlan Wright
41529bd2886SAlan Wright return (acl);
41629bd2886SAlan Wright }
41729bd2886SAlan Wright
41829bd2886SAlan Wright /*
41929bd2886SAlan Wright * This method converts Security Descriptor from self relative (flat buffer) to
42029bd2886SAlan Wright * absolute (pointer) format.
42129bd2886SAlan Wright *
42229bd2886SAlan Wright * Returns Win32 error codes.
42329bd2886SAlan Wright */
42429bd2886SAlan Wright static uint32_t
srvsvc_sd_set_absolute(uint8_t * sdbuf,smb_sd_t * sd)42529bd2886SAlan Wright srvsvc_sd_set_absolute(uint8_t *sdbuf, smb_sd_t *sd)
42629bd2886SAlan Wright {
42729bd2886SAlan Wright mslm_security_descriptor_t *msd;
42829bd2886SAlan Wright mslm_ace_t *m_ace;
42929bd2886SAlan Wright struct mslm_sid *m_sid;
43029bd2886SAlan Wright smb_ace_t *ace;
43129bd2886SAlan Wright uint16_t ace_cnt;
43229bd2886SAlan Wright int offset, i, sid_size;
43329bd2886SAlan Wright uint32_t status = ERROR_SUCCESS;
43429bd2886SAlan Wright
43529bd2886SAlan Wright if (sdbuf == NULL)
43629bd2886SAlan Wright return (ERROR_INVALID_SECURITY_DESCR);
43729bd2886SAlan Wright
43829bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
43929bd2886SAlan Wright msd = (mslm_security_descriptor_t *)sdbuf;
44029bd2886SAlan Wright
44129bd2886SAlan Wright sd->sd_revision = msd->revision;
44229bd2886SAlan Wright sd->sd_control = msd->control & (~SE_SELF_RELATIVE);
44329bd2886SAlan Wright
44429bd2886SAlan Wright if (msd->offset_owner != 0) {
44529bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
44629bd2886SAlan Wright m_sid = (struct mslm_sid *)&sdbuf[msd->offset_owner];
44729bd2886SAlan Wright sid_size = smb_sid_len((smb_sid_t *)m_sid);
44829bd2886SAlan Wright
44929bd2886SAlan Wright if ((sd->sd_owner = malloc(sid_size)) == NULL)
45029bd2886SAlan Wright return (ERROR_NOT_ENOUGH_MEMORY);
45129bd2886SAlan Wright bcopy(m_sid, sd->sd_owner, sid_size);
45229bd2886SAlan Wright }
45329bd2886SAlan Wright
45429bd2886SAlan Wright if (msd->offset_group != 0) {
45529bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
45629bd2886SAlan Wright m_sid = (struct mslm_sid *)&sdbuf[msd->offset_group];
45729bd2886SAlan Wright sid_size = smb_sid_len((smb_sid_t *)m_sid);
45829bd2886SAlan Wright
45929bd2886SAlan Wright if ((sd->sd_group = malloc(sid_size)) == NULL)
46029bd2886SAlan Wright return (ERROR_NOT_ENOUGH_MEMORY);
46129bd2886SAlan Wright bcopy(m_sid, sd->sd_group, sid_size);
46229bd2886SAlan Wright }
46329bd2886SAlan Wright
46429bd2886SAlan Wright if (msd->offset_sacl != 0) {
46529bd2886SAlan Wright offset = msd->offset_sacl;
46629bd2886SAlan Wright sd->sd_sacl = srvsvc_acl_set_absolute(sdbuf, &offset);
46729bd2886SAlan Wright if (sd->sd_sacl == NULL)
46829bd2886SAlan Wright return (ERROR_NOT_ENOUGH_MEMORY);
46929bd2886SAlan Wright
47029bd2886SAlan Wright ace = sd->sd_sacl->sl_aces;
47129bd2886SAlan Wright ace_cnt = sd->sd_sacl->sl_acecnt;
47229bd2886SAlan Wright
47329bd2886SAlan Wright for (i = 0; i < ace_cnt; i++, ace++) {
47429bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
47529bd2886SAlan Wright m_ace = (mslm_ace_t *)&sdbuf[offset];
47629bd2886SAlan Wright offset += SRVSVC_SID_OFFSET;
47729bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
47829bd2886SAlan Wright m_sid = (struct mslm_sid *)&sdbuf[offset];
47929bd2886SAlan Wright
48029bd2886SAlan Wright status = srvsvc_ace_set_absolute(m_ace, m_sid, ace);
48129bd2886SAlan Wright if (status != ERROR_SUCCESS)
48229bd2886SAlan Wright return (status);
48329bd2886SAlan Wright offset += smb_sid_len(ace->se_sid);
48429bd2886SAlan Wright }
48529bd2886SAlan Wright }
48629bd2886SAlan Wright
48729bd2886SAlan Wright if (msd->offset_dacl != 0) {
48829bd2886SAlan Wright offset = msd->offset_dacl;
48929bd2886SAlan Wright sd->sd_dacl = srvsvc_acl_set_absolute(sdbuf, &offset);
49029bd2886SAlan Wright if (sd->sd_dacl == NULL)
49129bd2886SAlan Wright return (ERROR_NOT_ENOUGH_MEMORY);
49229bd2886SAlan Wright
49329bd2886SAlan Wright ace = sd->sd_dacl->sl_aces;
49429bd2886SAlan Wright ace_cnt = sd->sd_dacl->sl_acecnt;
49529bd2886SAlan Wright
49629bd2886SAlan Wright for (i = 0; i < ace_cnt; i++, ace++) {
49729bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
49829bd2886SAlan Wright m_ace = (mslm_ace_t *)&sdbuf[offset];
49929bd2886SAlan Wright offset += SRVSVC_SID_OFFSET;
50029bd2886SAlan Wright /*LINTED E_BAD_PTR_CAST_ALIGN*/
50129bd2886SAlan Wright m_sid = (struct mslm_sid *)&sdbuf[offset];
50229bd2886SAlan Wright
50329bd2886SAlan Wright status = srvsvc_ace_set_absolute(m_ace, m_sid, ace);
50429bd2886SAlan Wright if (status != ERROR_SUCCESS)
50529bd2886SAlan Wright return (status);
50629bd2886SAlan Wright offset += smb_sid_len(ace->se_sid);
50729bd2886SAlan Wright }
50829bd2886SAlan Wright }
50929bd2886SAlan Wright
51029bd2886SAlan Wright return (status);
51129bd2886SAlan Wright }
51229bd2886SAlan Wright
51329bd2886SAlan Wright /*
51429bd2886SAlan Wright * This method maps NT status codes into Win 32 error codes.
51529bd2886SAlan Wright * This method operates on status codes that are related
51629bd2886SAlan Wright * to processing of Security Descriptor.
51729bd2886SAlan Wright */
51829bd2886SAlan Wright static uint32_t
srvsvc_sd_status_to_error(uint32_t status)51929bd2886SAlan Wright srvsvc_sd_status_to_error(uint32_t status)
52029bd2886SAlan Wright {
52129bd2886SAlan Wright int i;
52229bd2886SAlan Wright static struct {
52329bd2886SAlan Wright uint32_t nt_status;
52429bd2886SAlan Wright uint32_t err_code;
52529bd2886SAlan Wright } errmap[] = {
52629bd2886SAlan Wright { NT_STATUS_SUCCESS, ERROR_SUCCESS },
52729bd2886SAlan Wright { NT_STATUS_INVALID_ACL, ERROR_INVALID_ACL },
52829bd2886SAlan Wright { NT_STATUS_INVALID_SID, ERROR_INVALID_SID },
52929bd2886SAlan Wright { NT_STATUS_NONE_MAPPED, ERROR_NONE_MAPPED }
53029bd2886SAlan Wright };
53129bd2886SAlan Wright
53229bd2886SAlan Wright for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) {
53329bd2886SAlan Wright if (status == errmap[i].nt_status)
53429bd2886SAlan Wright return (errmap[i].err_code);
53529bd2886SAlan Wright }
53629bd2886SAlan Wright
53729bd2886SAlan Wright return (ERROR_INTERNAL_ERROR);
53829bd2886SAlan Wright }
539