1*9832Samw@Sun.COM /* 2*9832Samw@Sun.COM * CDDL HEADER START 3*9832Samw@Sun.COM * 4*9832Samw@Sun.COM * The contents of this file are subject to the terms of the 5*9832Samw@Sun.COM * Common Development and Distribution License (the "License"). 6*9832Samw@Sun.COM * You may not use this file except in compliance with the License. 7*9832Samw@Sun.COM * 8*9832Samw@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*9832Samw@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*9832Samw@Sun.COM * See the License for the specific language governing permissions 11*9832Samw@Sun.COM * and limitations under the License. 12*9832Samw@Sun.COM * 13*9832Samw@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*9832Samw@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*9832Samw@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*9832Samw@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*9832Samw@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*9832Samw@Sun.COM * 19*9832Samw@Sun.COM * CDDL HEADER END 20*9832Samw@Sun.COM */ 21*9832Samw@Sun.COM /* 22*9832Samw@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*9832Samw@Sun.COM * Use is subject to license terms. 24*9832Samw@Sun.COM */ 25*9832Samw@Sun.COM 26*9832Samw@Sun.COM /* 27*9832Samw@Sun.COM * This is a helper file to get/set Windows SD. This is used by 28*9832Samw@Sun.COM * SRVSVC service. 29*9832Samw@Sun.COM */ 30*9832Samw@Sun.COM #include <strings.h> 31*9832Samw@Sun.COM #include <libzfs.h> 32*9832Samw@Sun.COM #include <smbsrv/nterror.h> 33*9832Samw@Sun.COM #include <smbsrv/ntstatus.h> 34*9832Samw@Sun.COM #include <smbsrv/libmlsvc.h> 35*9832Samw@Sun.COM #include <smbsrv/ndl/srvsvc.ndl> 36*9832Samw@Sun.COM 37*9832Samw@Sun.COM /* Size of offset members in mslm_security_descriptor structure */ 38*9832Samw@Sun.COM #define SRVSVC_SD_OFFSET_SZ 16 39*9832Samw@Sun.COM 40*9832Samw@Sun.COM #define SRVSVC_ACE_OFFSET 8 41*9832Samw@Sun.COM #define SRVSVC_SID_OFFSET 8 42*9832Samw@Sun.COM 43*9832Samw@Sun.COM static uint32_t srvsvc_sd_status_to_error(uint32_t); 44*9832Samw@Sun.COM static uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *); 45*9832Samw@Sun.COM static uint32_t srvsvc_sd_set_absolute(uint8_t *, smb_sd_t *); 46*9832Samw@Sun.COM 47*9832Samw@Sun.COM /* 48*9832Samw@Sun.COM * This method computes ACL on share path from a share name. 49*9832Samw@Sun.COM * Return 0 upon success, -1 upon failure. 50*9832Samw@Sun.COM */ 51*9832Samw@Sun.COM static int 52*9832Samw@Sun.COM srvsvc_shareacl_getpath(smb_share_t *si, char *shr_acl_path) 53*9832Samw@Sun.COM { 54*9832Samw@Sun.COM char dataset[MAXPATHLEN]; 55*9832Samw@Sun.COM char mp[ZFS_MAXPROPLEN]; 56*9832Samw@Sun.COM libzfs_handle_t *libhd; 57*9832Samw@Sun.COM zfs_handle_t *zfshd; 58*9832Samw@Sun.COM int ret = 0; 59*9832Samw@Sun.COM 60*9832Samw@Sun.COM ret = smb_getdataset(si->shr_path, dataset, MAXPATHLEN); 61*9832Samw@Sun.COM if (ret != 0) 62*9832Samw@Sun.COM return (ret); 63*9832Samw@Sun.COM 64*9832Samw@Sun.COM if ((libhd = libzfs_init()) == NULL) 65*9832Samw@Sun.COM return (-1); 66*9832Samw@Sun.COM 67*9832Samw@Sun.COM if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) { 68*9832Samw@Sun.COM libzfs_fini(libhd); 69*9832Samw@Sun.COM return (-1); 70*9832Samw@Sun.COM } 71*9832Samw@Sun.COM 72*9832Samw@Sun.COM if (zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, mp, sizeof (mp), NULL, 73*9832Samw@Sun.COM NULL, 0, B_FALSE) != 0) { 74*9832Samw@Sun.COM zfs_close(zfshd); 75*9832Samw@Sun.COM libzfs_fini(libhd); 76*9832Samw@Sun.COM return (-1); 77*9832Samw@Sun.COM } 78*9832Samw@Sun.COM 79*9832Samw@Sun.COM zfs_close(zfshd); 80*9832Samw@Sun.COM libzfs_fini(libhd); 81*9832Samw@Sun.COM 82*9832Samw@Sun.COM (void) snprintf(shr_acl_path, MAXPATHLEN, "%s/.zfs/shares/%s", 83*9832Samw@Sun.COM mp, si->shr_name); 84*9832Samw@Sun.COM 85*9832Samw@Sun.COM return (ret); 86*9832Samw@Sun.COM } 87*9832Samw@Sun.COM 88*9832Samw@Sun.COM /* 89*9832Samw@Sun.COM * This method sets Security Descriptor on a share path. 90*9832Samw@Sun.COM * 91*9832Samw@Sun.COM * Returns: 92*9832Samw@Sun.COM * ERROR_SUCCESS 93*9832Samw@Sun.COM * ERROR_NOT_ENOUGH_MEMORY 94*9832Samw@Sun.COM * ERROR_INVALID_ACL 95*9832Samw@Sun.COM * ERROR_INVALID_SID 96*9832Samw@Sun.COM * ERROR_INVALID_SECURITY_DESCR 97*9832Samw@Sun.COM * ERROR_NONE_MAPPED 98*9832Samw@Sun.COM * ERROR_INTERNAL_ERROR 99*9832Samw@Sun.COM * ERROR_PATH_NOT_FOUND 100*9832Samw@Sun.COM */ 101*9832Samw@Sun.COM uint32_t 102*9832Samw@Sun.COM srvsvc_sd_set(smb_share_t *si, uint8_t *sdbuf) 103*9832Samw@Sun.COM { 104*9832Samw@Sun.COM smb_sd_t sd; 105*9832Samw@Sun.COM uint32_t status = ERROR_SUCCESS; 106*9832Samw@Sun.COM char path[MAXPATHLEN]; 107*9832Samw@Sun.COM int ret = 0; 108*9832Samw@Sun.COM 109*9832Samw@Sun.COM ret = srvsvc_shareacl_getpath(si, path); 110*9832Samw@Sun.COM if (ret != 0) 111*9832Samw@Sun.COM return (ERROR_PATH_NOT_FOUND); 112*9832Samw@Sun.COM 113*9832Samw@Sun.COM smb_sd_init(&sd, 0); 114*9832Samw@Sun.COM status = srvsvc_sd_set_absolute(sdbuf, &sd); 115*9832Samw@Sun.COM if (status != ERROR_SUCCESS) { 116*9832Samw@Sun.COM smb_sd_term(&sd); 117*9832Samw@Sun.COM return (status); 118*9832Samw@Sun.COM } 119*9832Samw@Sun.COM 120*9832Samw@Sun.COM status = smb_sd_write(path, &sd, SMB_DACL_SECINFO); 121*9832Samw@Sun.COM status = srvsvc_sd_status_to_error(status); 122*9832Samw@Sun.COM smb_sd_term(&sd); 123*9832Samw@Sun.COM 124*9832Samw@Sun.COM return (status); 125*9832Samw@Sun.COM } 126*9832Samw@Sun.COM 127*9832Samw@Sun.COM /* 128*9832Samw@Sun.COM * This method returns a Security Descriptor of a share path in self relative 129*9832Samw@Sun.COM * format. Call to this function with NULL buffer, returns the size of the 130*9832Samw@Sun.COM * security descriptor, which can be used to allocate buffer. 131*9832Samw@Sun.COM * 132*9832Samw@Sun.COM * Returns: 133*9832Samw@Sun.COM * ERROR_SUCCESS 134*9832Samw@Sun.COM * ERROR_NOT_ENOUGH_MEMORY 135*9832Samw@Sun.COM * ERROR_INVALID_ACL 136*9832Samw@Sun.COM * ERROR_INVALID_SID 137*9832Samw@Sun.COM * ERROR_INVALID_SECURITY_DESCR 138*9832Samw@Sun.COM * ERROR_INVALID_PARAMETER 139*9832Samw@Sun.COM * ERROR_NONE_MAPPED 140*9832Samw@Sun.COM * ERROR_INTERNAL_ERROR 141*9832Samw@Sun.COM * ERROR_PATH_NOT_FOUND 142*9832Samw@Sun.COM */ 143*9832Samw@Sun.COM uint32_t 144*9832Samw@Sun.COM srvsvc_sd_get(smb_share_t *si, uint8_t *sdbuf, uint32_t *size) 145*9832Samw@Sun.COM { 146*9832Samw@Sun.COM smb_sd_t sd; 147*9832Samw@Sun.COM uint32_t status = ERROR_SUCCESS; 148*9832Samw@Sun.COM char path[MAXPATHLEN]; 149*9832Samw@Sun.COM int ret = 0; 150*9832Samw@Sun.COM 151*9832Samw@Sun.COM if (sdbuf == NULL && size == NULL) 152*9832Samw@Sun.COM return (ERROR_INVALID_PARAMETER); 153*9832Samw@Sun.COM 154*9832Samw@Sun.COM ret = srvsvc_shareacl_getpath(si, path); 155*9832Samw@Sun.COM if (ret != 0) 156*9832Samw@Sun.COM return (ERROR_PATH_NOT_FOUND); 157*9832Samw@Sun.COM 158*9832Samw@Sun.COM bzero(&sd, sizeof (smb_sd_t)); 159*9832Samw@Sun.COM status = smb_sd_read(path, &sd, SMB_ALL_SECINFO); 160*9832Samw@Sun.COM status = srvsvc_sd_status_to_error(status); 161*9832Samw@Sun.COM if (status != ERROR_SUCCESS) { 162*9832Samw@Sun.COM smb_sd_term(&sd); 163*9832Samw@Sun.COM return (status); 164*9832Samw@Sun.COM } 165*9832Samw@Sun.COM 166*9832Samw@Sun.COM if (sdbuf == NULL) { 167*9832Samw@Sun.COM *size = smb_sd_len(&sd, SMB_ALL_SECINFO); 168*9832Samw@Sun.COM smb_sd_term(&sd); 169*9832Samw@Sun.COM return (status); 170*9832Samw@Sun.COM } 171*9832Samw@Sun.COM 172*9832Samw@Sun.COM status = srvsvc_sd_set_relative(&sd, sdbuf); 173*9832Samw@Sun.COM 174*9832Samw@Sun.COM smb_sd_term(&sd); 175*9832Samw@Sun.COM return (status); 176*9832Samw@Sun.COM } 177*9832Samw@Sun.COM 178*9832Samw@Sun.COM /* 179*9832Samw@Sun.COM * This method converts an ACE from absolute (pointer) to 180*9832Samw@Sun.COM * self relative (flat buffer) format. 181*9832Samw@Sun.COM * 182*9832Samw@Sun.COM * Returns Win32 error codes. 183*9832Samw@Sun.COM */ 184*9832Samw@Sun.COM static uint32_t 185*9832Samw@Sun.COM srvsvc_ace_set_relative(mslm_ace_t *m_ace, struct mslm_sid *m_sid, 186*9832Samw@Sun.COM smb_ace_t *ace) 187*9832Samw@Sun.COM { 188*9832Samw@Sun.COM if ((m_ace == NULL) || (ace == NULL)) 189*9832Samw@Sun.COM return (ERROR_INVALID_PARAMETER); 190*9832Samw@Sun.COM 191*9832Samw@Sun.COM bcopy(&ace->se_hdr, &m_ace->header, sizeof (mslm_ace_hdr_t)); 192*9832Samw@Sun.COM m_ace->mask = ace->se_mask; 193*9832Samw@Sun.COM 194*9832Samw@Sun.COM if ((ace->se_sid == NULL) || (m_sid == NULL)) 195*9832Samw@Sun.COM return (ERROR_INVALID_PARAMETER); 196*9832Samw@Sun.COM bcopy(ace->se_sid, m_sid, smb_sid_len(ace->se_sid)); 197*9832Samw@Sun.COM 198*9832Samw@Sun.COM return (ERROR_SUCCESS); 199*9832Samw@Sun.COM } 200*9832Samw@Sun.COM 201*9832Samw@Sun.COM /* 202*9832Samw@Sun.COM * This method converts an ACL from absolute (pointer) to 203*9832Samw@Sun.COM * self relative (flat buffer) format. 204*9832Samw@Sun.COM * 205*9832Samw@Sun.COM * Returns an initialized mslm_acl structure on success. 206*9832Samw@Sun.COM * Returns NULL on failure. 207*9832Samw@Sun.COM */ 208*9832Samw@Sun.COM static struct mslm_acl * 209*9832Samw@Sun.COM srvsvc_acl_set_relative(uint8_t *sdbuf, smb_acl_t *acl) 210*9832Samw@Sun.COM { 211*9832Samw@Sun.COM struct mslm_acl *m_acl; 212*9832Samw@Sun.COM 213*9832Samw@Sun.COM if (sdbuf == NULL) 214*9832Samw@Sun.COM return (NULL); 215*9832Samw@Sun.COM 216*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 217*9832Samw@Sun.COM m_acl = (struct mslm_acl *)sdbuf; 218*9832Samw@Sun.COM m_acl->revision = acl->sl_revision; 219*9832Samw@Sun.COM m_acl->sbz1 = 0; 220*9832Samw@Sun.COM m_acl->size = acl->sl_bsize; 221*9832Samw@Sun.COM m_acl->sbz2 = 0; 222*9832Samw@Sun.COM m_acl->ace_count = acl->sl_acecnt; 223*9832Samw@Sun.COM 224*9832Samw@Sun.COM return (m_acl); 225*9832Samw@Sun.COM } 226*9832Samw@Sun.COM 227*9832Samw@Sun.COM /* 228*9832Samw@Sun.COM * This method converts Security Descriptor from absolute (pointer) to 229*9832Samw@Sun.COM * self relative (flat buffer) format. 230*9832Samw@Sun.COM * 231*9832Samw@Sun.COM * Returns Win32 error codes. 232*9832Samw@Sun.COM */ 233*9832Samw@Sun.COM static uint32_t 234*9832Samw@Sun.COM srvsvc_sd_set_relative(smb_sd_t *sd, uint8_t *sdbuf) 235*9832Samw@Sun.COM { 236*9832Samw@Sun.COM mslm_security_descriptor_t *msd; 237*9832Samw@Sun.COM int offset, len, i; 238*9832Samw@Sun.COM smb_ace_t *ace; 239*9832Samw@Sun.COM mslm_ace_t *m_ace; 240*9832Samw@Sun.COM struct mslm_sid *m_sid; 241*9832Samw@Sun.COM uint16_t ace_cnt; 242*9832Samw@Sun.COM uint32_t status = ERROR_SUCCESS; 243*9832Samw@Sun.COM 244*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 245*9832Samw@Sun.COM msd = (mslm_security_descriptor_t *)sdbuf; 246*9832Samw@Sun.COM if (msd == NULL) 247*9832Samw@Sun.COM return (ERROR_INVALID_SECURITY_DESCR); 248*9832Samw@Sun.COM 249*9832Samw@Sun.COM msd->revision = sd->sd_revision; 250*9832Samw@Sun.COM msd->sbz1 = 0; 251*9832Samw@Sun.COM msd->control = sd->sd_control | SE_SELF_RELATIVE; 252*9832Samw@Sun.COM 253*9832Samw@Sun.COM offset = sizeof (mslm_security_descriptor_t) - SRVSVC_SD_OFFSET_SZ; 254*9832Samw@Sun.COM msd->offset_owner = msd->offset_group = 0; 255*9832Samw@Sun.COM msd->offset_sacl = msd->offset_dacl = 0; 256*9832Samw@Sun.COM 257*9832Samw@Sun.COM if (sd->sd_owner != NULL) { 258*9832Samw@Sun.COM msd->offset_owner = offset; 259*9832Samw@Sun.COM 260*9832Samw@Sun.COM if (sd->sd_owner == NULL) 261*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 262*9832Samw@Sun.COM 263*9832Samw@Sun.COM len = smb_sid_len(sd->sd_owner); 264*9832Samw@Sun.COM bcopy(sd->sd_owner, &sdbuf[offset], len); 265*9832Samw@Sun.COM offset += len; 266*9832Samw@Sun.COM } 267*9832Samw@Sun.COM 268*9832Samw@Sun.COM if (sd->sd_group != NULL) { 269*9832Samw@Sun.COM msd->offset_group = offset; 270*9832Samw@Sun.COM 271*9832Samw@Sun.COM if (sd->sd_group == NULL) 272*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 273*9832Samw@Sun.COM 274*9832Samw@Sun.COM len = smb_sid_len(sd->sd_group); 275*9832Samw@Sun.COM bcopy(sd->sd_group, &sdbuf[offset], len); 276*9832Samw@Sun.COM offset += len; 277*9832Samw@Sun.COM } 278*9832Samw@Sun.COM 279*9832Samw@Sun.COM if (sd->sd_sacl != NULL) { 280*9832Samw@Sun.COM msd->offset_sacl = offset; 281*9832Samw@Sun.COM msd->sacl = srvsvc_acl_set_relative(&sdbuf[offset], 282*9832Samw@Sun.COM sd->sd_sacl); 283*9832Samw@Sun.COM if (msd->sacl == NULL) 284*9832Samw@Sun.COM return (ERROR_INVALID_PARAMETER); 285*9832Samw@Sun.COM 286*9832Samw@Sun.COM ace = sd->sd_sacl->sl_aces; 287*9832Samw@Sun.COM ace_cnt = msd->sacl->ace_count; 288*9832Samw@Sun.COM offset += SRVSVC_ACE_OFFSET; 289*9832Samw@Sun.COM 290*9832Samw@Sun.COM for (i = 0; i < ace_cnt; i++, ace++) { 291*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 292*9832Samw@Sun.COM m_ace = (mslm_ace_t *)&sdbuf[offset]; 293*9832Samw@Sun.COM offset += SRVSVC_SID_OFFSET; 294*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 295*9832Samw@Sun.COM m_sid = (struct mslm_sid *)&sdbuf[offset]; 296*9832Samw@Sun.COM 297*9832Samw@Sun.COM status = srvsvc_ace_set_relative(m_ace, m_sid, ace); 298*9832Samw@Sun.COM if (status != ERROR_SUCCESS) 299*9832Samw@Sun.COM return (status); 300*9832Samw@Sun.COM offset += smb_sid_len(ace->se_sid); 301*9832Samw@Sun.COM } 302*9832Samw@Sun.COM } 303*9832Samw@Sun.COM 304*9832Samw@Sun.COM if (sd->sd_dacl != NULL) { 305*9832Samw@Sun.COM msd->offset_dacl = offset; 306*9832Samw@Sun.COM msd->dacl = srvsvc_acl_set_relative(&sdbuf[offset], 307*9832Samw@Sun.COM sd->sd_dacl); 308*9832Samw@Sun.COM if (msd->dacl == NULL) 309*9832Samw@Sun.COM return (ERROR_INVALID_PARAMETER); 310*9832Samw@Sun.COM 311*9832Samw@Sun.COM ace = sd->sd_dacl->sl_aces; 312*9832Samw@Sun.COM ace_cnt = msd->dacl->ace_count; 313*9832Samw@Sun.COM offset += SRVSVC_ACE_OFFSET; 314*9832Samw@Sun.COM 315*9832Samw@Sun.COM for (i = 0; i < ace_cnt; i++, ace++) { 316*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 317*9832Samw@Sun.COM m_ace = (mslm_ace_t *)&sdbuf[offset]; 318*9832Samw@Sun.COM offset += SRVSVC_SID_OFFSET; 319*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 320*9832Samw@Sun.COM m_sid = (struct mslm_sid *)&sdbuf[offset]; 321*9832Samw@Sun.COM 322*9832Samw@Sun.COM status = srvsvc_ace_set_relative(m_ace, m_sid, ace); 323*9832Samw@Sun.COM if (status != ERROR_SUCCESS) 324*9832Samw@Sun.COM return (status); 325*9832Samw@Sun.COM offset += smb_sid_len(ace->se_sid); 326*9832Samw@Sun.COM } 327*9832Samw@Sun.COM } 328*9832Samw@Sun.COM 329*9832Samw@Sun.COM return (status); 330*9832Samw@Sun.COM } 331*9832Samw@Sun.COM 332*9832Samw@Sun.COM /* 333*9832Samw@Sun.COM * This method converts an ACE from self relative (flat buffer) to 334*9832Samw@Sun.COM * absolute (pointer) format. 335*9832Samw@Sun.COM * 336*9832Samw@Sun.COM * Returns Win32 error codes. 337*9832Samw@Sun.COM */ 338*9832Samw@Sun.COM static uint32_t 339*9832Samw@Sun.COM srvsvc_ace_set_absolute(mslm_ace_t *m_ace, struct mslm_sid *m_sid, 340*9832Samw@Sun.COM smb_ace_t *ace) 341*9832Samw@Sun.COM { 342*9832Samw@Sun.COM int sid_size = 0; 343*9832Samw@Sun.COM if ((m_ace == NULL) || (ace == NULL) || (m_sid == NULL)) 344*9832Samw@Sun.COM return (ERROR_INVALID_PARAMETER); 345*9832Samw@Sun.COM 346*9832Samw@Sun.COM bzero(ace, sizeof (smb_ace_t)); 347*9832Samw@Sun.COM bcopy(&m_ace->header, &ace->se_hdr, sizeof (mslm_ace_hdr_t)); 348*9832Samw@Sun.COM ace->se_mask = m_ace->mask; 349*9832Samw@Sun.COM 350*9832Samw@Sun.COM sid_size = smb_sid_len((smb_sid_t *)m_sid); 351*9832Samw@Sun.COM if ((ace->se_sid = malloc(sid_size)) == NULL) 352*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 353*9832Samw@Sun.COM bcopy(m_sid, ace->se_sid, sid_size); 354*9832Samw@Sun.COM 355*9832Samw@Sun.COM return (ERROR_SUCCESS); 356*9832Samw@Sun.COM } 357*9832Samw@Sun.COM 358*9832Samw@Sun.COM /* 359*9832Samw@Sun.COM * This method converts an ACL from self relative (flat buffer) to 360*9832Samw@Sun.COM * absolute (pointer) format. 361*9832Samw@Sun.COM * 362*9832Samw@Sun.COM * Returns an initialized smb_acl_t structure on success. 363*9832Samw@Sun.COM * Returns NULL on failure. 364*9832Samw@Sun.COM */ 365*9832Samw@Sun.COM static smb_acl_t * 366*9832Samw@Sun.COM srvsvc_acl_set_absolute(uint8_t *sdbuf, int *offset) 367*9832Samw@Sun.COM { 368*9832Samw@Sun.COM uint8_t rev; 369*9832Samw@Sun.COM uint16_t sz, ace_cnt; 370*9832Samw@Sun.COM smb_acl_t *acl; 371*9832Samw@Sun.COM 372*9832Samw@Sun.COM bcopy(&sdbuf[*offset], &rev, sizeof (uint8_t)); 373*9832Samw@Sun.COM *offset += 2; /* Pad for Sbz1 */ 374*9832Samw@Sun.COM bcopy(&sdbuf[*offset], &sz, sizeof (uint16_t)); 375*9832Samw@Sun.COM *offset += 2; 376*9832Samw@Sun.COM bcopy(&sdbuf[*offset], &ace_cnt, sizeof (uint16_t)); 377*9832Samw@Sun.COM *offset += 4; /* Pad for Sbz2 */ 378*9832Samw@Sun.COM 379*9832Samw@Sun.COM acl = smb_acl_alloc(rev, sz, ace_cnt); 380*9832Samw@Sun.COM 381*9832Samw@Sun.COM return (acl); 382*9832Samw@Sun.COM } 383*9832Samw@Sun.COM 384*9832Samw@Sun.COM /* 385*9832Samw@Sun.COM * This method converts Security Descriptor from self relative (flat buffer) to 386*9832Samw@Sun.COM * absolute (pointer) format. 387*9832Samw@Sun.COM * 388*9832Samw@Sun.COM * Returns Win32 error codes. 389*9832Samw@Sun.COM */ 390*9832Samw@Sun.COM static uint32_t 391*9832Samw@Sun.COM srvsvc_sd_set_absolute(uint8_t *sdbuf, smb_sd_t *sd) 392*9832Samw@Sun.COM { 393*9832Samw@Sun.COM mslm_security_descriptor_t *msd; 394*9832Samw@Sun.COM mslm_ace_t *m_ace; 395*9832Samw@Sun.COM struct mslm_sid *m_sid; 396*9832Samw@Sun.COM smb_ace_t *ace; 397*9832Samw@Sun.COM uint16_t ace_cnt; 398*9832Samw@Sun.COM int offset, i, sid_size; 399*9832Samw@Sun.COM uint32_t status = ERROR_SUCCESS; 400*9832Samw@Sun.COM 401*9832Samw@Sun.COM if (sdbuf == NULL) 402*9832Samw@Sun.COM return (ERROR_INVALID_SECURITY_DESCR); 403*9832Samw@Sun.COM 404*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 405*9832Samw@Sun.COM msd = (mslm_security_descriptor_t *)sdbuf; 406*9832Samw@Sun.COM 407*9832Samw@Sun.COM sd->sd_revision = msd->revision; 408*9832Samw@Sun.COM sd->sd_control = msd->control & (~SE_SELF_RELATIVE); 409*9832Samw@Sun.COM 410*9832Samw@Sun.COM if (msd->offset_owner != 0) { 411*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 412*9832Samw@Sun.COM m_sid = (struct mslm_sid *)&sdbuf[msd->offset_owner]; 413*9832Samw@Sun.COM sid_size = smb_sid_len((smb_sid_t *)m_sid); 414*9832Samw@Sun.COM 415*9832Samw@Sun.COM if ((sd->sd_owner = malloc(sid_size)) == NULL) 416*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 417*9832Samw@Sun.COM bcopy(m_sid, sd->sd_owner, sid_size); 418*9832Samw@Sun.COM } 419*9832Samw@Sun.COM 420*9832Samw@Sun.COM if (msd->offset_group != 0) { 421*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 422*9832Samw@Sun.COM m_sid = (struct mslm_sid *)&sdbuf[msd->offset_group]; 423*9832Samw@Sun.COM sid_size = smb_sid_len((smb_sid_t *)m_sid); 424*9832Samw@Sun.COM 425*9832Samw@Sun.COM if ((sd->sd_group = malloc(sid_size)) == NULL) 426*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 427*9832Samw@Sun.COM bcopy(m_sid, sd->sd_group, sid_size); 428*9832Samw@Sun.COM } 429*9832Samw@Sun.COM 430*9832Samw@Sun.COM if (msd->offset_sacl != 0) { 431*9832Samw@Sun.COM offset = msd->offset_sacl; 432*9832Samw@Sun.COM sd->sd_sacl = srvsvc_acl_set_absolute(sdbuf, &offset); 433*9832Samw@Sun.COM if (sd->sd_sacl == NULL) 434*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 435*9832Samw@Sun.COM 436*9832Samw@Sun.COM ace = sd->sd_sacl->sl_aces; 437*9832Samw@Sun.COM ace_cnt = sd->sd_sacl->sl_acecnt; 438*9832Samw@Sun.COM 439*9832Samw@Sun.COM for (i = 0; i < ace_cnt; i++, ace++) { 440*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 441*9832Samw@Sun.COM m_ace = (mslm_ace_t *)&sdbuf[offset]; 442*9832Samw@Sun.COM offset += SRVSVC_SID_OFFSET; 443*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 444*9832Samw@Sun.COM m_sid = (struct mslm_sid *)&sdbuf[offset]; 445*9832Samw@Sun.COM 446*9832Samw@Sun.COM status = srvsvc_ace_set_absolute(m_ace, m_sid, ace); 447*9832Samw@Sun.COM if (status != ERROR_SUCCESS) 448*9832Samw@Sun.COM return (status); 449*9832Samw@Sun.COM offset += smb_sid_len(ace->se_sid); 450*9832Samw@Sun.COM } 451*9832Samw@Sun.COM } 452*9832Samw@Sun.COM 453*9832Samw@Sun.COM if (msd->offset_dacl != 0) { 454*9832Samw@Sun.COM offset = msd->offset_dacl; 455*9832Samw@Sun.COM sd->sd_dacl = srvsvc_acl_set_absolute(sdbuf, &offset); 456*9832Samw@Sun.COM if (sd->sd_dacl == NULL) 457*9832Samw@Sun.COM return (ERROR_NOT_ENOUGH_MEMORY); 458*9832Samw@Sun.COM 459*9832Samw@Sun.COM ace = sd->sd_dacl->sl_aces; 460*9832Samw@Sun.COM ace_cnt = sd->sd_dacl->sl_acecnt; 461*9832Samw@Sun.COM 462*9832Samw@Sun.COM for (i = 0; i < ace_cnt; i++, ace++) { 463*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 464*9832Samw@Sun.COM m_ace = (mslm_ace_t *)&sdbuf[offset]; 465*9832Samw@Sun.COM offset += SRVSVC_SID_OFFSET; 466*9832Samw@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 467*9832Samw@Sun.COM m_sid = (struct mslm_sid *)&sdbuf[offset]; 468*9832Samw@Sun.COM 469*9832Samw@Sun.COM status = srvsvc_ace_set_absolute(m_ace, m_sid, ace); 470*9832Samw@Sun.COM if (status != ERROR_SUCCESS) 471*9832Samw@Sun.COM return (status); 472*9832Samw@Sun.COM offset += smb_sid_len(ace->se_sid); 473*9832Samw@Sun.COM } 474*9832Samw@Sun.COM } 475*9832Samw@Sun.COM 476*9832Samw@Sun.COM return (status); 477*9832Samw@Sun.COM } 478*9832Samw@Sun.COM 479*9832Samw@Sun.COM /* 480*9832Samw@Sun.COM * This method maps NT status codes into Win 32 error codes. 481*9832Samw@Sun.COM * This method operates on status codes that are related 482*9832Samw@Sun.COM * to processing of Security Descriptor. 483*9832Samw@Sun.COM */ 484*9832Samw@Sun.COM static uint32_t 485*9832Samw@Sun.COM srvsvc_sd_status_to_error(uint32_t status) 486*9832Samw@Sun.COM { 487*9832Samw@Sun.COM int i; 488*9832Samw@Sun.COM static struct { 489*9832Samw@Sun.COM uint32_t nt_status; 490*9832Samw@Sun.COM uint32_t err_code; 491*9832Samw@Sun.COM } errmap[] = { 492*9832Samw@Sun.COM { NT_STATUS_SUCCESS, ERROR_SUCCESS }, 493*9832Samw@Sun.COM { NT_STATUS_INVALID_ACL, ERROR_INVALID_ACL }, 494*9832Samw@Sun.COM { NT_STATUS_INVALID_SID, ERROR_INVALID_SID }, 495*9832Samw@Sun.COM { NT_STATUS_NONE_MAPPED, ERROR_NONE_MAPPED } 496*9832Samw@Sun.COM }; 497*9832Samw@Sun.COM 498*9832Samw@Sun.COM for (i = 0; i < (sizeof (errmap) / sizeof (errmap[0])); ++i) { 499*9832Samw@Sun.COM if (status == errmap[i].nt_status) 500*9832Samw@Sun.COM return (errmap[i].err_code); 501*9832Samw@Sun.COM } 502*9832Samw@Sun.COM 503*9832Samw@Sun.COM return (ERROR_INTERNAL_ERROR); 504*9832Samw@Sun.COM } 505