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 */ 219832Samw@Sun.COM /* 229832Samw@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 239832Samw@Sun.COM * Use is subject to license terms. 249832Samw@Sun.COM */ 259832Samw@Sun.COM 269832Samw@Sun.COM /* 279832Samw@Sun.COM * This is a helper file to get/set Windows SD. This is used by 289832Samw@Sun.COM * SRVSVC service. 299832Samw@Sun.COM */ 309832Samw@Sun.COM #include <strings.h> 319832Samw@Sun.COM #include <libzfs.h> 329832Samw@Sun.COM #include <smbsrv/nterror.h> 339832Samw@Sun.COM #include <smbsrv/ntstatus.h> 349832Samw@Sun.COM #include <smbsrv/libmlsvc.h> 359832Samw@Sun.COM #include <smbsrv/ndl/srvsvc.ndl> 369832Samw@Sun.COM 379832Samw@Sun.COM /* Size of offset members in mslm_security_descriptor structure */ 389832Samw@Sun.COM #define SRVSVC_SD_OFFSET_SZ 16 399832Samw@Sun.COM 409832Samw@Sun.COM #define SRVSVC_ACE_OFFSET 8 419832Samw@Sun.COM #define SRVSVC_SID_OFFSET 8 429832Samw@Sun.COM 43*11337SWilliam.Krier@Sun.COM static uint32_t srvsvc_sd_get_autohome(const smb_share_t *, smb_sd_t *); 449832Samw@Sun.COM static uint32_t srvsvc_sd_status_to_error(uint32_t); 459832Samw@Sun.COM static uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *); 469832Samw@Sun.COM static uint32_t srvsvc_sd_set_absolute(uint8_t *, smb_sd_t *); 479832Samw@Sun.COM 489832Samw@Sun.COM /* 499832Samw@Sun.COM * This method computes ACL on share path from a share name. 509832Samw@Sun.COM * Return 0 upon success, -1 upon failure. 519832Samw@Sun.COM */ 529832Samw@Sun.COM static int 539832Samw@Sun.COM srvsvc_shareacl_getpath(smb_share_t *si, char *shr_acl_path) 549832Samw@Sun.COM { 559832Samw@Sun.COM char dataset[MAXPATHLEN]; 569832Samw@Sun.COM char mp[ZFS_MAXPROPLEN]; 579832Samw@Sun.COM libzfs_handle_t *libhd; 589832Samw@Sun.COM zfs_handle_t *zfshd; 599832Samw@Sun.COM int ret = 0; 609832Samw@Sun.COM 619832Samw@Sun.COM ret = smb_getdataset(si->shr_path, dataset, MAXPATHLEN); 629832Samw@Sun.COM if (ret != 0) 639832Samw@Sun.COM return (ret); 649832Samw@Sun.COM 659832Samw@Sun.COM if ((libhd = libzfs_init()) == NULL) 669832Samw@Sun.COM return (-1); 679832Samw@Sun.COM 689832Samw@Sun.COM if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) { 699832Samw@Sun.COM libzfs_fini(libhd); 709832Samw@Sun.COM return (-1); 719832Samw@Sun.COM } 729832Samw@Sun.COM 739832Samw@Sun.COM if (zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, mp, sizeof (mp), NULL, 749832Samw@Sun.COM NULL, 0, B_FALSE) != 0) { 759832Samw@Sun.COM zfs_close(zfshd); 769832Samw@Sun.COM libzfs_fini(libhd); 779832Samw@Sun.COM return (-1); 789832Samw@Sun.COM } 799832Samw@Sun.COM 809832Samw@Sun.COM zfs_close(zfshd); 819832Samw@Sun.COM libzfs_fini(libhd); 829832Samw@Sun.COM 839832Samw@Sun.COM (void) snprintf(shr_acl_path, MAXPATHLEN, "%s/.zfs/shares/%s", 849832Samw@Sun.COM mp, si->shr_name); 859832Samw@Sun.COM 869832Samw@Sun.COM return (ret); 879832Samw@Sun.COM } 889832Samw@Sun.COM 899832Samw@Sun.COM /* 909832Samw@Sun.COM * This method sets Security Descriptor on a share path. 919832Samw@Sun.COM * 929832Samw@Sun.COM * Returns: 939832Samw@Sun.COM * ERROR_SUCCESS 949832Samw@Sun.COM * ERROR_NOT_ENOUGH_MEMORY 959832Samw@Sun.COM * ERROR_INVALID_ACL 969832Samw@Sun.COM * ERROR_INVALID_SID 979832Samw@Sun.COM * ERROR_INVALID_SECURITY_DESCR 989832Samw@Sun.COM * ERROR_NONE_MAPPED 999832Samw@Sun.COM * ERROR_INTERNAL_ERROR 1009832Samw@Sun.COM * ERROR_PATH_NOT_FOUND 1019832Samw@Sun.COM */ 1029832Samw@Sun.COM uint32_t 1039832Samw@Sun.COM srvsvc_sd_set(smb_share_t *si, uint8_t *sdbuf) 1049832Samw@Sun.COM { 1059832Samw@Sun.COM smb_sd_t sd; 1069832Samw@Sun.COM uint32_t status = ERROR_SUCCESS; 1079832Samw@Sun.COM char path[MAXPATHLEN]; 1089832Samw@Sun.COM int ret = 0; 1099832Samw@Sun.COM 1109832Samw@Sun.COM ret = srvsvc_shareacl_getpath(si, path); 1119832Samw@Sun.COM if (ret != 0) 1129832Samw@Sun.COM return (ERROR_PATH_NOT_FOUND); 1139832Samw@Sun.COM 1149832Samw@Sun.COM smb_sd_init(&sd, 0); 1159832Samw@Sun.COM status = srvsvc_sd_set_absolute(sdbuf, &sd); 1169832Samw@Sun.COM if (status != ERROR_SUCCESS) { 1179832Samw@Sun.COM smb_sd_term(&sd); 1189832Samw@Sun.COM return (status); 1199832Samw@Sun.COM } 1209832Samw@Sun.COM 1219832Samw@Sun.COM status = smb_sd_write(path, &sd, SMB_DACL_SECINFO); 1229832Samw@Sun.COM status = srvsvc_sd_status_to_error(status); 1239832Samw@Sun.COM smb_sd_term(&sd); 1249832Samw@Sun.COM 1259832Samw@Sun.COM return (status); 1269832Samw@Sun.COM } 1279832Samw@Sun.COM 1289832Samw@Sun.COM /* 1299832Samw@Sun.COM * This method returns a Security Descriptor of a share path in self relative 1309832Samw@Sun.COM * format. Call to this function with NULL buffer, returns the size of the 1319832Samw@Sun.COM * security descriptor, which can be used to allocate buffer. 1329832Samw@Sun.COM * 1339832Samw@Sun.COM * Returns: 1349832Samw@Sun.COM * ERROR_SUCCESS 1359832Samw@Sun.COM * ERROR_NOT_ENOUGH_MEMORY 1369832Samw@Sun.COM * ERROR_INVALID_ACL 1379832Samw@Sun.COM * ERROR_INVALID_SID 1389832Samw@Sun.COM * ERROR_INVALID_SECURITY_DESCR 1399832Samw@Sun.COM * ERROR_INVALID_PARAMETER 1409832Samw@Sun.COM * ERROR_NONE_MAPPED 1419832Samw@Sun.COM * ERROR_INTERNAL_ERROR 1429832Samw@Sun.COM * ERROR_PATH_NOT_FOUND 1439832Samw@Sun.COM */ 1449832Samw@Sun.COM uint32_t 1459832Samw@Sun.COM srvsvc_sd_get(smb_share_t *si, uint8_t *sdbuf, uint32_t *size) 1469832Samw@Sun.COM { 1479832Samw@Sun.COM smb_sd_t sd; 1489832Samw@Sun.COM uint32_t status = ERROR_SUCCESS; 1499832Samw@Sun.COM char path[MAXPATHLEN]; 1509832Samw@Sun.COM int ret = 0; 1519832Samw@Sun.COM 1529832Samw@Sun.COM if (sdbuf == NULL && size == NULL) 1539832Samw@Sun.COM return (ERROR_INVALID_PARAMETER); 1549832Samw@Sun.COM 155*11337SWilliam.Krier@Sun.COM bzero(&sd, sizeof (smb_sd_t)); 1569832Samw@Sun.COM 157*11337SWilliam.Krier@Sun.COM if (si->shr_flags & SMB_SHRF_AUTOHOME) { 158*11337SWilliam.Krier@Sun.COM status = srvsvc_sd_get_autohome(si, &sd); 159*11337SWilliam.Krier@Sun.COM } else { 160*11337SWilliam.Krier@Sun.COM ret = srvsvc_shareacl_getpath(si, path); 161*11337SWilliam.Krier@Sun.COM if (ret != 0) 162*11337SWilliam.Krier@Sun.COM return (ERROR_PATH_NOT_FOUND); 163*11337SWilliam.Krier@Sun.COM 164*11337SWilliam.Krier@Sun.COM status = smb_sd_read(path, &sd, SMB_ALL_SECINFO); 165*11337SWilliam.Krier@Sun.COM status = srvsvc_sd_status_to_error(status); 166*11337SWilliam.Krier@Sun.COM } 167*11337SWilliam.Krier@Sun.COM 1689832Samw@Sun.COM if (status != ERROR_SUCCESS) { 1699832Samw@Sun.COM smb_sd_term(&sd); 1709832Samw@Sun.COM return (status); 1719832Samw@Sun.COM } 1729832Samw@Sun.COM 1739832Samw@Sun.COM if (sdbuf == NULL) { 1749832Samw@Sun.COM *size = smb_sd_len(&sd, SMB_ALL_SECINFO); 1759832Samw@Sun.COM smb_sd_term(&sd); 1769832Samw@Sun.COM return (status); 1779832Samw@Sun.COM } 1789832Samw@Sun.COM 1799832Samw@Sun.COM status = srvsvc_sd_set_relative(&sd, sdbuf); 1809832Samw@Sun.COM 1819832Samw@Sun.COM smb_sd_term(&sd); 1829832Samw@Sun.COM return (status); 1839832Samw@Sun.COM } 1849832Samw@Sun.COM 185*11337SWilliam.Krier@Sun.COM static uint32_t 186*11337SWilliam.Krier@Sun.COM srvsvc_sd_get_autohome(const smb_share_t *si, smb_sd_t *sd) 187*11337SWilliam.Krier@Sun.COM { 188*11337SWilliam.Krier@Sun.COM smb_fssd_t fs_sd; 189*11337SWilliam.Krier@Sun.COM acl_t *acl; 190*11337SWilliam.Krier@Sun.COM uint32_t status; 191*11337SWilliam.Krier@Sun.COM 192*11337SWilliam.Krier@Sun.COM if (acl_fromtext("owner@:rwxpdDaARWcCos::allow", &acl) != 0) 193*11337SWilliam.Krier@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 194*11337SWilliam.Krier@Sun.COM 195*11337SWilliam.Krier@Sun.COM smb_fssd_init(&fs_sd, SMB_ALL_SECINFO, SMB_FSSD_FLAGS_DIR); 196*11337SWilliam.Krier@Sun.COM fs_sd.sd_uid = si->shr_uid; 197*11337SWilliam.Krier@Sun.COM fs_sd.sd_gid = si->shr_gid; 198*11337SWilliam.Krier@Sun.COM fs_sd.sd_zdacl = acl; 199*11337SWilliam.Krier@Sun.COM fs_sd.sd_zsacl = NULL; 200*11337SWilliam.Krier@Sun.COM 201*11337SWilliam.Krier@Sun.COM status = smb_sd_fromfs(&fs_sd, sd); 202*11337SWilliam.Krier@Sun.COM status = srvsvc_sd_status_to_error(status); 203*11337SWilliam.Krier@Sun.COM smb_fssd_term(&fs_sd); 204*11337SWilliam.Krier@Sun.COM return (status); 205*11337SWilliam.Krier@Sun.COM } 206*11337SWilliam.Krier@Sun.COM 2079832Samw@Sun.COM /* 2089832Samw@Sun.COM * This method converts an ACE from absolute (pointer) to 2099832Samw@Sun.COM * self relative (flat buffer) format. 2109832Samw@Sun.COM * 2119832Samw@Sun.COM * Returns Win32 error codes. 2129832Samw@Sun.COM */ 2139832Samw@Sun.COM static uint32_t 2149832Samw@Sun.COM srvsvc_ace_set_relative(mslm_ace_t *m_ace, struct mslm_sid *m_sid, 2159832Samw@Sun.COM smb_ace_t *ace) 2169832Samw@Sun.COM { 2179832Samw@Sun.COM if ((m_ace == NULL) || (ace == NULL)) 2189832Samw@Sun.COM return (ERROR_INVALID_PARAMETER); 2199832Samw@Sun.COM 2209832Samw@Sun.COM bcopy(&ace->se_hdr, &m_ace->header, sizeof (mslm_ace_hdr_t)); 2219832Samw@Sun.COM m_ace->mask = ace->se_mask; 2229832Samw@Sun.COM 2239832Samw@Sun.COM if ((ace->se_sid == NULL) || (m_sid == NULL)) 2249832Samw@Sun.COM return (ERROR_INVALID_PARAMETER); 2259832Samw@Sun.COM bcopy(ace->se_sid, m_sid, smb_sid_len(ace->se_sid)); 2269832Samw@Sun.COM 2279832Samw@Sun.COM return (ERROR_SUCCESS); 2289832Samw@Sun.COM } 2299832Samw@Sun.COM 2309832Samw@Sun.COM /* 2319832Samw@Sun.COM * This method converts an ACL from absolute (pointer) to 2329832Samw@Sun.COM * self relative (flat buffer) format. 2339832Samw@Sun.COM * 2349832Samw@Sun.COM * Returns an initialized mslm_acl structure on success. 2359832Samw@Sun.COM * Returns NULL on failure. 2369832Samw@Sun.COM */ 2379832Samw@Sun.COM static struct mslm_acl * 2389832Samw@Sun.COM srvsvc_acl_set_relative(uint8_t *sdbuf, smb_acl_t *acl) 2399832Samw@Sun.COM { 2409832Samw@Sun.COM struct mslm_acl *m_acl; 2419832Samw@Sun.COM 2429832Samw@Sun.COM if (sdbuf == NULL) 2439832Samw@Sun.COM return (NULL); 2449832Samw@Sun.COM 2459832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 2469832Samw@Sun.COM m_acl = (struct mslm_acl *)sdbuf; 2479832Samw@Sun.COM m_acl->revision = acl->sl_revision; 2489832Samw@Sun.COM m_acl->sbz1 = 0; 2499832Samw@Sun.COM m_acl->size = acl->sl_bsize; 2509832Samw@Sun.COM m_acl->sbz2 = 0; 2519832Samw@Sun.COM m_acl->ace_count = acl->sl_acecnt; 2529832Samw@Sun.COM 2539832Samw@Sun.COM return (m_acl); 2549832Samw@Sun.COM } 2559832Samw@Sun.COM 2569832Samw@Sun.COM /* 2579832Samw@Sun.COM * This method converts Security Descriptor from absolute (pointer) to 2589832Samw@Sun.COM * self relative (flat buffer) format. 2599832Samw@Sun.COM * 2609832Samw@Sun.COM * Returns Win32 error codes. 2619832Samw@Sun.COM */ 2629832Samw@Sun.COM static uint32_t 2639832Samw@Sun.COM srvsvc_sd_set_relative(smb_sd_t *sd, uint8_t *sdbuf) 2649832Samw@Sun.COM { 2659832Samw@Sun.COM mslm_security_descriptor_t *msd; 2669832Samw@Sun.COM int offset, len, i; 2679832Samw@Sun.COM smb_ace_t *ace; 2689832Samw@Sun.COM mslm_ace_t *m_ace; 2699832Samw@Sun.COM struct mslm_sid *m_sid; 2709832Samw@Sun.COM uint16_t ace_cnt; 2719832Samw@Sun.COM uint32_t status = ERROR_SUCCESS; 2729832Samw@Sun.COM 2739832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 2749832Samw@Sun.COM msd = (mslm_security_descriptor_t *)sdbuf; 2759832Samw@Sun.COM if (msd == NULL) 2769832Samw@Sun.COM return (ERROR_INVALID_SECURITY_DESCR); 2779832Samw@Sun.COM 2789832Samw@Sun.COM msd->revision = sd->sd_revision; 2799832Samw@Sun.COM msd->sbz1 = 0; 2809832Samw@Sun.COM msd->control = sd->sd_control | SE_SELF_RELATIVE; 2819832Samw@Sun.COM 2829832Samw@Sun.COM offset = sizeof (mslm_security_descriptor_t) - SRVSVC_SD_OFFSET_SZ; 2839832Samw@Sun.COM msd->offset_owner = msd->offset_group = 0; 2849832Samw@Sun.COM msd->offset_sacl = msd->offset_dacl = 0; 2859832Samw@Sun.COM 2869832Samw@Sun.COM if (sd->sd_owner != NULL) { 2879832Samw@Sun.COM msd->offset_owner = offset; 2889832Samw@Sun.COM 2899832Samw@Sun.COM if (sd->sd_owner == NULL) 2909832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 2919832Samw@Sun.COM 2929832Samw@Sun.COM len = smb_sid_len(sd->sd_owner); 2939832Samw@Sun.COM bcopy(sd->sd_owner, &sdbuf[offset], len); 2949832Samw@Sun.COM offset += len; 2959832Samw@Sun.COM } 2969832Samw@Sun.COM 2979832Samw@Sun.COM if (sd->sd_group != NULL) { 2989832Samw@Sun.COM msd->offset_group = offset; 2999832Samw@Sun.COM 3009832Samw@Sun.COM if (sd->sd_group == NULL) 3019832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 3029832Samw@Sun.COM 3039832Samw@Sun.COM len = smb_sid_len(sd->sd_group); 3049832Samw@Sun.COM bcopy(sd->sd_group, &sdbuf[offset], len); 3059832Samw@Sun.COM offset += len; 3069832Samw@Sun.COM } 3079832Samw@Sun.COM 3089832Samw@Sun.COM if (sd->sd_sacl != NULL) { 3099832Samw@Sun.COM msd->offset_sacl = offset; 3109832Samw@Sun.COM msd->sacl = srvsvc_acl_set_relative(&sdbuf[offset], 3119832Samw@Sun.COM sd->sd_sacl); 3129832Samw@Sun.COM if (msd->sacl == NULL) 3139832Samw@Sun.COM return (ERROR_INVALID_PARAMETER); 3149832Samw@Sun.COM 3159832Samw@Sun.COM ace = sd->sd_sacl->sl_aces; 3169832Samw@Sun.COM ace_cnt = msd->sacl->ace_count; 3179832Samw@Sun.COM offset += SRVSVC_ACE_OFFSET; 3189832Samw@Sun.COM 3199832Samw@Sun.COM for (i = 0; i < ace_cnt; i++, ace++) { 3209832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 3219832Samw@Sun.COM m_ace = (mslm_ace_t *)&sdbuf[offset]; 3229832Samw@Sun.COM offset += SRVSVC_SID_OFFSET; 3239832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 3249832Samw@Sun.COM m_sid = (struct mslm_sid *)&sdbuf[offset]; 3259832Samw@Sun.COM 3269832Samw@Sun.COM status = srvsvc_ace_set_relative(m_ace, m_sid, ace); 3279832Samw@Sun.COM if (status != ERROR_SUCCESS) 3289832Samw@Sun.COM return (status); 3299832Samw@Sun.COM offset += smb_sid_len(ace->se_sid); 3309832Samw@Sun.COM } 3319832Samw@Sun.COM } 3329832Samw@Sun.COM 3339832Samw@Sun.COM if (sd->sd_dacl != NULL) { 3349832Samw@Sun.COM msd->offset_dacl = offset; 3359832Samw@Sun.COM msd->dacl = srvsvc_acl_set_relative(&sdbuf[offset], 3369832Samw@Sun.COM sd->sd_dacl); 3379832Samw@Sun.COM if (msd->dacl == NULL) 3389832Samw@Sun.COM return (ERROR_INVALID_PARAMETER); 3399832Samw@Sun.COM 3409832Samw@Sun.COM ace = sd->sd_dacl->sl_aces; 3419832Samw@Sun.COM ace_cnt = msd->dacl->ace_count; 3429832Samw@Sun.COM offset += SRVSVC_ACE_OFFSET; 3439832Samw@Sun.COM 3449832Samw@Sun.COM for (i = 0; i < ace_cnt; i++, ace++) { 3459832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 3469832Samw@Sun.COM m_ace = (mslm_ace_t *)&sdbuf[offset]; 3479832Samw@Sun.COM offset += SRVSVC_SID_OFFSET; 3489832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 3499832Samw@Sun.COM m_sid = (struct mslm_sid *)&sdbuf[offset]; 3509832Samw@Sun.COM 3519832Samw@Sun.COM status = srvsvc_ace_set_relative(m_ace, m_sid, ace); 3529832Samw@Sun.COM if (status != ERROR_SUCCESS) 3539832Samw@Sun.COM return (status); 3549832Samw@Sun.COM offset += smb_sid_len(ace->se_sid); 3559832Samw@Sun.COM } 3569832Samw@Sun.COM } 3579832Samw@Sun.COM 3589832Samw@Sun.COM return (status); 3599832Samw@Sun.COM } 3609832Samw@Sun.COM 3619832Samw@Sun.COM /* 3629832Samw@Sun.COM * This method converts an ACE from self relative (flat buffer) to 3639832Samw@Sun.COM * absolute (pointer) format. 3649832Samw@Sun.COM * 3659832Samw@Sun.COM * Returns Win32 error codes. 3669832Samw@Sun.COM */ 3679832Samw@Sun.COM static uint32_t 3689832Samw@Sun.COM srvsvc_ace_set_absolute(mslm_ace_t *m_ace, struct mslm_sid *m_sid, 3699832Samw@Sun.COM smb_ace_t *ace) 3709832Samw@Sun.COM { 3719832Samw@Sun.COM int sid_size = 0; 3729832Samw@Sun.COM if ((m_ace == NULL) || (ace == NULL) || (m_sid == NULL)) 3739832Samw@Sun.COM return (ERROR_INVALID_PARAMETER); 3749832Samw@Sun.COM 3759832Samw@Sun.COM bzero(ace, sizeof (smb_ace_t)); 3769832Samw@Sun.COM bcopy(&m_ace->header, &ace->se_hdr, sizeof (mslm_ace_hdr_t)); 3779832Samw@Sun.COM ace->se_mask = m_ace->mask; 3789832Samw@Sun.COM 3799832Samw@Sun.COM sid_size = smb_sid_len((smb_sid_t *)m_sid); 3809832Samw@Sun.COM if ((ace->se_sid = malloc(sid_size)) == NULL) 3819832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 3829832Samw@Sun.COM bcopy(m_sid, ace->se_sid, sid_size); 3839832Samw@Sun.COM 3849832Samw@Sun.COM return (ERROR_SUCCESS); 3859832Samw@Sun.COM } 3869832Samw@Sun.COM 3879832Samw@Sun.COM /* 3889832Samw@Sun.COM * This method converts an ACL from self relative (flat buffer) to 3899832Samw@Sun.COM * absolute (pointer) format. 3909832Samw@Sun.COM * 3919832Samw@Sun.COM * Returns an initialized smb_acl_t structure on success. 3929832Samw@Sun.COM * Returns NULL on failure. 3939832Samw@Sun.COM */ 3949832Samw@Sun.COM static smb_acl_t * 3959832Samw@Sun.COM srvsvc_acl_set_absolute(uint8_t *sdbuf, int *offset) 3969832Samw@Sun.COM { 3979832Samw@Sun.COM uint8_t rev; 3989832Samw@Sun.COM uint16_t sz, ace_cnt; 3999832Samw@Sun.COM smb_acl_t *acl; 4009832Samw@Sun.COM 4019832Samw@Sun.COM bcopy(&sdbuf[*offset], &rev, sizeof (uint8_t)); 4029832Samw@Sun.COM *offset += 2; /* Pad for Sbz1 */ 4039832Samw@Sun.COM bcopy(&sdbuf[*offset], &sz, sizeof (uint16_t)); 4049832Samw@Sun.COM *offset += 2; 4059832Samw@Sun.COM bcopy(&sdbuf[*offset], &ace_cnt, sizeof (uint16_t)); 4069832Samw@Sun.COM *offset += 4; /* Pad for Sbz2 */ 4079832Samw@Sun.COM 4089832Samw@Sun.COM acl = smb_acl_alloc(rev, sz, ace_cnt); 4099832Samw@Sun.COM 4109832Samw@Sun.COM return (acl); 4119832Samw@Sun.COM } 4129832Samw@Sun.COM 4139832Samw@Sun.COM /* 4149832Samw@Sun.COM * This method converts Security Descriptor from self relative (flat buffer) to 4159832Samw@Sun.COM * absolute (pointer) format. 4169832Samw@Sun.COM * 4179832Samw@Sun.COM * Returns Win32 error codes. 4189832Samw@Sun.COM */ 4199832Samw@Sun.COM static uint32_t 4209832Samw@Sun.COM srvsvc_sd_set_absolute(uint8_t *sdbuf, smb_sd_t *sd) 4219832Samw@Sun.COM { 4229832Samw@Sun.COM mslm_security_descriptor_t *msd; 4239832Samw@Sun.COM mslm_ace_t *m_ace; 4249832Samw@Sun.COM struct mslm_sid *m_sid; 4259832Samw@Sun.COM smb_ace_t *ace; 4269832Samw@Sun.COM uint16_t ace_cnt; 4279832Samw@Sun.COM int offset, i, sid_size; 4289832Samw@Sun.COM uint32_t status = ERROR_SUCCESS; 4299832Samw@Sun.COM 4309832Samw@Sun.COM if (sdbuf == NULL) 4319832Samw@Sun.COM return (ERROR_INVALID_SECURITY_DESCR); 4329832Samw@Sun.COM 4339832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 4349832Samw@Sun.COM msd = (mslm_security_descriptor_t *)sdbuf; 4359832Samw@Sun.COM 4369832Samw@Sun.COM sd->sd_revision = msd->revision; 4379832Samw@Sun.COM sd->sd_control = msd->control & (~SE_SELF_RELATIVE); 4389832Samw@Sun.COM 4399832Samw@Sun.COM if (msd->offset_owner != 0) { 4409832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 4419832Samw@Sun.COM m_sid = (struct mslm_sid *)&sdbuf[msd->offset_owner]; 4429832Samw@Sun.COM sid_size = smb_sid_len((smb_sid_t *)m_sid); 4439832Samw@Sun.COM 4449832Samw@Sun.COM if ((sd->sd_owner = malloc(sid_size)) == NULL) 4459832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 4469832Samw@Sun.COM bcopy(m_sid, sd->sd_owner, sid_size); 4479832Samw@Sun.COM } 4489832Samw@Sun.COM 4499832Samw@Sun.COM if (msd->offset_group != 0) { 4509832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 4519832Samw@Sun.COM m_sid = (struct mslm_sid *)&sdbuf[msd->offset_group]; 4529832Samw@Sun.COM sid_size = smb_sid_len((smb_sid_t *)m_sid); 4539832Samw@Sun.COM 4549832Samw@Sun.COM if ((sd->sd_group = malloc(sid_size)) == NULL) 4559832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 4569832Samw@Sun.COM bcopy(m_sid, sd->sd_group, sid_size); 4579832Samw@Sun.COM } 4589832Samw@Sun.COM 4599832Samw@Sun.COM if (msd->offset_sacl != 0) { 4609832Samw@Sun.COM offset = msd->offset_sacl; 4619832Samw@Sun.COM sd->sd_sacl = srvsvc_acl_set_absolute(sdbuf, &offset); 4629832Samw@Sun.COM if (sd->sd_sacl == NULL) 4639832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 4649832Samw@Sun.COM 4659832Samw@Sun.COM ace = sd->sd_sacl->sl_aces; 4669832Samw@Sun.COM ace_cnt = sd->sd_sacl->sl_acecnt; 4679832Samw@Sun.COM 4689832Samw@Sun.COM for (i = 0; i < ace_cnt; i++, ace++) { 4699832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 4709832Samw@Sun.COM m_ace = (mslm_ace_t *)&sdbuf[offset]; 4719832Samw@Sun.COM offset += SRVSVC_SID_OFFSET; 4729832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 4739832Samw@Sun.COM m_sid = (struct mslm_sid *)&sdbuf[offset]; 4749832Samw@Sun.COM 4759832Samw@Sun.COM status = srvsvc_ace_set_absolute(m_ace, m_sid, ace); 4769832Samw@Sun.COM if (status != ERROR_SUCCESS) 4779832Samw@Sun.COM return (status); 4789832Samw@Sun.COM offset += smb_sid_len(ace->se_sid); 4799832Samw@Sun.COM } 4809832Samw@Sun.COM } 4819832Samw@Sun.COM 4829832Samw@Sun.COM if (msd->offset_dacl != 0) { 4839832Samw@Sun.COM offset = msd->offset_dacl; 4849832Samw@Sun.COM sd->sd_dacl = srvsvc_acl_set_absolute(sdbuf, &offset); 4859832Samw@Sun.COM if (sd->sd_dacl == NULL) 4869832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 4879832Samw@Sun.COM 4889832Samw@Sun.COM ace = sd->sd_dacl->sl_aces; 4899832Samw@Sun.COM ace_cnt = sd->sd_dacl->sl_acecnt; 4909832Samw@Sun.COM 4919832Samw@Sun.COM for (i = 0; i < ace_cnt; i++, ace++) { 4929832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 4939832Samw@Sun.COM m_ace = (mslm_ace_t *)&sdbuf[offset]; 4949832Samw@Sun.COM offset += SRVSVC_SID_OFFSET; 4959832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 4969832Samw@Sun.COM m_sid = (struct mslm_sid *)&sdbuf[offset]; 4979832Samw@Sun.COM 4989832Samw@Sun.COM status = srvsvc_ace_set_absolute(m_ace, m_sid, ace); 4999832Samw@Sun.COM if (status != ERROR_SUCCESS) 5009832Samw@Sun.COM return (status); 5019832Samw@Sun.COM offset += smb_sid_len(ace->se_sid); 5029832Samw@Sun.COM } 5039832Samw@Sun.COM } 5049832Samw@Sun.COM 5059832Samw@Sun.COM return (status); 5069832Samw@Sun.COM } 5079832Samw@Sun.COM 5089832Samw@Sun.COM /* 5099832Samw@Sun.COM * This method maps NT status codes into Win 32 error codes. 5109832Samw@Sun.COM * This method operates on status codes that are related 5119832Samw@Sun.COM * to processing of Security Descriptor. 5129832Samw@Sun.COM */ 5139832Samw@Sun.COM static uint32_t 5149832Samw@Sun.COM srvsvc_sd_status_to_error(uint32_t status) 5159832Samw@Sun.COM { 5169832Samw@Sun.COM int i; 5179832Samw@Sun.COM static struct { 5189832Samw@Sun.COM uint32_t nt_status; 5199832Samw@Sun.COM uint32_t err_code; 5209832Samw@Sun.COM } errmap[] = { 5219832Samw@Sun.COM { NT_STATUS_SUCCESS, ERROR_SUCCESS }, 5229832Samw@Sun.COM { NT_STATUS_INVALID_ACL, ERROR_INVALID_ACL }, 5239832Samw@Sun.COM { NT_STATUS_INVALID_SID, ERROR_INVALID_SID }, 5249832Samw@Sun.COM { NT_STATUS_NONE_MAPPED, ERROR_NONE_MAPPED } 5259832Samw@Sun.COM }; 5269832Samw@Sun.COM 5279832Samw@Sun.COM for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) { 5289832Samw@Sun.COM if (status == errmap[i].nt_status) 5299832Samw@Sun.COM return (errmap[i].err_code); 5309832Samw@Sun.COM } 5319832Samw@Sun.COM 5329832Samw@Sun.COM return (ERROR_INTERNAL_ERROR); 5339832Samw@Sun.COM } 534