1*02d09e03SGordon Ross /* 2*02d09e03SGordon Ross * CDDL HEADER START 3*02d09e03SGordon Ross * 4*02d09e03SGordon Ross * The contents of this file are subject to the terms of the 5*02d09e03SGordon Ross * Common Development and Distribution License (the "License"). 6*02d09e03SGordon Ross * You may not use this file except in compliance with the License. 7*02d09e03SGordon Ross * 8*02d09e03SGordon Ross * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*02d09e03SGordon Ross * or http://www.opensolaris.org/os/licensing. 10*02d09e03SGordon Ross * See the License for the specific language governing permissions 11*02d09e03SGordon Ross * and limitations under the License. 12*02d09e03SGordon Ross * 13*02d09e03SGordon Ross * When distributing Covered Code, include this CDDL HEADER in each 14*02d09e03SGordon Ross * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*02d09e03SGordon Ross * If applicable, add the following below this CDDL HEADER, with the 16*02d09e03SGordon Ross * fields enclosed by brackets "[]" replaced with your own identifying 17*02d09e03SGordon Ross * information: Portions Copyright [yyyy] [name of copyright owner] 18*02d09e03SGordon Ross * 19*02d09e03SGordon Ross * CDDL HEADER END 20*02d09e03SGordon Ross */ 21*02d09e03SGordon Ross 22*02d09e03SGordon Ross /* 23*02d09e03SGordon Ross * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*02d09e03SGordon Ross * Use is subject to license terms. 25*02d09e03SGordon Ross */ 26*02d09e03SGordon Ross 27*02d09e03SGordon Ross /* 28*02d09e03SGordon Ross * ACL conversion support for smbfs 29*02d09e03SGordon Ross * (To/from NT/ZFS-style ACLs.) 30*02d09e03SGordon Ross */ 31*02d09e03SGordon Ross 32*02d09e03SGordon Ross #include <sys/types.h> 33*02d09e03SGordon Ross #include <sys/errno.h> 34*02d09e03SGordon Ross #include <sys/acl.h> 35*02d09e03SGordon Ross #include <sys/byteorder.h> 36*02d09e03SGordon Ross 37*02d09e03SGordon Ross #ifdef _KERNEL 38*02d09e03SGordon Ross 39*02d09e03SGordon Ross #include <sys/cred.h> 40*02d09e03SGordon Ross #include <sys/cmn_err.h> 41*02d09e03SGordon Ross #include <sys/kmem.h> 42*02d09e03SGordon Ross #include <sys/sunddi.h> 43*02d09e03SGordon Ross #include <sys/vnode.h> 44*02d09e03SGordon Ross #include <sys/vfs.h> 45*02d09e03SGordon Ross 46*02d09e03SGordon Ross #include <sys/kidmap.h> 47*02d09e03SGordon Ross 48*02d09e03SGordon Ross #else /* _KERNEL */ 49*02d09e03SGordon Ross 50*02d09e03SGordon Ross #include <stdio.h> 51*02d09e03SGordon Ross #include <stdlib.h> 52*02d09e03SGordon Ross #include <strings.h> 53*02d09e03SGordon Ross 54*02d09e03SGordon Ross #include <idmap.h> 55*02d09e03SGordon Ross 56*02d09e03SGordon Ross #endif /* _KERNEL */ 57*02d09e03SGordon Ross 58*02d09e03SGordon Ross #include <netsmb/mchain.h> 59*02d09e03SGordon Ross #include <netsmb/smb.h> 60*02d09e03SGordon Ross #include "smbfs_ntacl.h" 61*02d09e03SGordon Ross 62*02d09e03SGordon Ross #ifdef _KERNEL 63*02d09e03SGordon Ross #define MALLOC(size) kmem_alloc(size, KM_SLEEP) 64*02d09e03SGordon Ross #define FREESZ(p, sz) kmem_free(p, sz) 65*02d09e03SGordon Ross #else /* _KERNEL */ 66*02d09e03SGordon Ross #define MALLOC(size) malloc(size) 67*02d09e03SGordon Ross #ifndef lint 68*02d09e03SGordon Ross #define FREESZ(p, sz) free(p) 69*02d09e03SGordon Ross #else /* lint */ 70*02d09e03SGordon Ross /* ARGSUSED */ 71*02d09e03SGordon Ross static void 72*02d09e03SGordon Ross FREESZ(void *p, size_t sz) 73*02d09e03SGordon Ross { 74*02d09e03SGordon Ross free(p); 75*02d09e03SGordon Ross } 76*02d09e03SGordon Ross #endif /* lint */ 77*02d09e03SGordon Ross #endif /* _KERNEL */ 78*02d09e03SGordon Ross 79*02d09e03SGordon Ross #define ERRCHK(expr) if ((error = expr) != 0) goto errout 80*02d09e03SGordon Ross 81*02d09e03SGordon Ross /* 82*02d09e03SGordon Ross * Security IDentifier (SID) 83*02d09e03SGordon Ross */ 84*02d09e03SGordon Ross static void 85*02d09e03SGordon Ross ifree_sid(i_ntsid_t *sid) 86*02d09e03SGordon Ross { 87*02d09e03SGordon Ross size_t sz; 88*02d09e03SGordon Ross 89*02d09e03SGordon Ross if (sid == NULL) 90*02d09e03SGordon Ross return; 91*02d09e03SGordon Ross 92*02d09e03SGordon Ross sz = I_SID_SIZE(sid->sid_subauthcount); 93*02d09e03SGordon Ross FREESZ(sid, sz); 94*02d09e03SGordon Ross } 95*02d09e03SGordon Ross 96*02d09e03SGordon Ross static int 97*02d09e03SGordon Ross md_get_sid(mdchain_t *mdp, i_ntsid_t **sidp) 98*02d09e03SGordon Ross { 99*02d09e03SGordon Ross i_ntsid_t *sid = NULL; 100*02d09e03SGordon Ross uint8_t revision, subauthcount; 101*02d09e03SGordon Ross uint32_t *subauthp; 102*02d09e03SGordon Ross size_t sidsz; 103*02d09e03SGordon Ross int error, i; 104*02d09e03SGordon Ross 105*02d09e03SGordon Ross if ((error = md_get_uint8(mdp, &revision)) != 0) 106*02d09e03SGordon Ross return (error); 107*02d09e03SGordon Ross if ((error = md_get_uint8(mdp, &subauthcount)) != 0) 108*02d09e03SGordon Ross return (error); 109*02d09e03SGordon Ross 110*02d09e03SGordon Ross sidsz = I_SID_SIZE(subauthcount); 111*02d09e03SGordon Ross 112*02d09e03SGordon Ross if ((sid = MALLOC(sidsz)) == NULL) 113*02d09e03SGordon Ross return (ENOMEM); 114*02d09e03SGordon Ross 115*02d09e03SGordon Ross bzero(sid, sidsz); 116*02d09e03SGordon Ross sid->sid_revision = revision; 117*02d09e03SGordon Ross sid->sid_subauthcount = subauthcount; 118*02d09e03SGordon Ross ERRCHK(md_get_mem(mdp, sid->sid_authority, 6, MB_MSYSTEM)); 119*02d09e03SGordon Ross 120*02d09e03SGordon Ross subauthp = &sid->sid_subauthvec[0]; 121*02d09e03SGordon Ross for (i = 0; i < subauthcount; i++) { 122*02d09e03SGordon Ross ERRCHK(md_get_uint32le(mdp, subauthp)); 123*02d09e03SGordon Ross subauthp++; 124*02d09e03SGordon Ross } 125*02d09e03SGordon Ross 126*02d09e03SGordon Ross /* Success! */ 127*02d09e03SGordon Ross *sidp = sid; 128*02d09e03SGordon Ross return (0); 129*02d09e03SGordon Ross 130*02d09e03SGordon Ross errout: 131*02d09e03SGordon Ross ifree_sid(sid); 132*02d09e03SGordon Ross return (error); 133*02d09e03SGordon Ross } 134*02d09e03SGordon Ross 135*02d09e03SGordon Ross static int 136*02d09e03SGordon Ross mb_put_sid(mbchain_t *mbp, i_ntsid_t *sid) 137*02d09e03SGordon Ross { 138*02d09e03SGordon Ross uint32_t *subauthp; 139*02d09e03SGordon Ross int error, i; 140*02d09e03SGordon Ross 141*02d09e03SGordon Ross if (sid == NULL) 142*02d09e03SGordon Ross return (EINVAL); 143*02d09e03SGordon Ross 144*02d09e03SGordon Ross ERRCHK(mb_put_uint8(mbp, sid->sid_revision)); 145*02d09e03SGordon Ross ERRCHK(mb_put_uint8(mbp, sid->sid_subauthcount)); 146*02d09e03SGordon Ross ERRCHK(mb_put_mem(mbp, sid->sid_authority, 6, MB_MSYSTEM)); 147*02d09e03SGordon Ross 148*02d09e03SGordon Ross subauthp = &sid->sid_subauthvec[0]; 149*02d09e03SGordon Ross for (i = 0; i < sid->sid_subauthcount; i++) { 150*02d09e03SGordon Ross ERRCHK(mb_put_uint32le(mbp, *subauthp)); 151*02d09e03SGordon Ross subauthp++; 152*02d09e03SGordon Ross } 153*02d09e03SGordon Ross 154*02d09e03SGordon Ross /* Success! */ 155*02d09e03SGordon Ross return (0); 156*02d09e03SGordon Ross 157*02d09e03SGordon Ross errout: 158*02d09e03SGordon Ross return (error); 159*02d09e03SGordon Ross } 160*02d09e03SGordon Ross 161*02d09e03SGordon Ross 162*02d09e03SGordon Ross /* 163*02d09e03SGordon Ross * Access Control Entry (ACE) 164*02d09e03SGordon Ross */ 165*02d09e03SGordon Ross static void 166*02d09e03SGordon Ross ifree_ace(i_ntace_t *ace) 167*02d09e03SGordon Ross { 168*02d09e03SGordon Ross 169*02d09e03SGordon Ross if (ace == NULL) 170*02d09e03SGordon Ross return; 171*02d09e03SGordon Ross 172*02d09e03SGordon Ross ifree_sid(ace->ace_sid); 173*02d09e03SGordon Ross FREESZ(ace, sizeof (*ace)); 174*02d09e03SGordon Ross } 175*02d09e03SGordon Ross 176*02d09e03SGordon Ross static int 177*02d09e03SGordon Ross md_get_ace(mdchain_t *mdp, i_ntace_t **acep) 178*02d09e03SGordon Ross { 179*02d09e03SGordon Ross mdchain_t tmp_md; 180*02d09e03SGordon Ross i_ntace_t *ace = NULL; 181*02d09e03SGordon Ross uint16_t ace_len; 182*02d09e03SGordon Ross int error; 183*02d09e03SGordon Ross 184*02d09e03SGordon Ross if ((ace = MALLOC(sizeof (*ace))) == NULL) 185*02d09e03SGordon Ross return (ENOMEM); 186*02d09e03SGordon Ross bzero(ace, sizeof (*ace)); 187*02d09e03SGordon Ross 188*02d09e03SGordon Ross /* 189*02d09e03SGordon Ross * The ACE is realy variable length, 190*02d09e03SGordon Ross * with format determined by the type. 191*02d09e03SGordon Ross * XXX: This only decodes types 0-7 192*02d09e03SGordon Ross * 193*02d09e03SGordon Ross * There may also be padding after it, so 194*02d09e03SGordon Ross * decode the using a copy of the mdchain, 195*02d09e03SGordon Ross * and then consume the specified length. 196*02d09e03SGordon Ross */ 197*02d09e03SGordon Ross tmp_md = *mdp; 198*02d09e03SGordon Ross 199*02d09e03SGordon Ross /* Fixed-size header */ 200*02d09e03SGordon Ross ERRCHK(md_get_uint8(&tmp_md, &ace->ace_type)); 201*02d09e03SGordon Ross ERRCHK(md_get_uint8(&tmp_md, &ace->ace_flags)); 202*02d09e03SGordon Ross ERRCHK(md_get_uint16le(&tmp_md, &ace_len)); 203*02d09e03SGordon Ross 204*02d09e03SGordon Ross /* Variable-size body */ 205*02d09e03SGordon Ross ERRCHK(md_get_uint32le(&tmp_md, &ace->ace_rights)); 206*02d09e03SGordon Ross ERRCHK(md_get_sid(&tmp_md, &ace->ace_sid)); 207*02d09e03SGordon Ross 208*02d09e03SGordon Ross /* Now actually consume ace_len */ 209*02d09e03SGordon Ross ERRCHK(md_get_mem(mdp, NULL, ace_len, MB_MSYSTEM)); 210*02d09e03SGordon Ross 211*02d09e03SGordon Ross /* Success! */ 212*02d09e03SGordon Ross *acep = ace; 213*02d09e03SGordon Ross return (0); 214*02d09e03SGordon Ross 215*02d09e03SGordon Ross errout: 216*02d09e03SGordon Ross ifree_ace(ace); 217*02d09e03SGordon Ross return (error); 218*02d09e03SGordon Ross } 219*02d09e03SGordon Ross 220*02d09e03SGordon Ross static int 221*02d09e03SGordon Ross mb_put_ace(mbchain_t *mbp, i_ntace_t *ace) 222*02d09e03SGordon Ross { 223*02d09e03SGordon Ross int cnt0, error; 224*02d09e03SGordon Ross uint16_t ace_len, *ace_len_p; 225*02d09e03SGordon Ross 226*02d09e03SGordon Ross if (ace == NULL) 227*02d09e03SGordon Ross return (EINVAL); 228*02d09e03SGordon Ross 229*02d09e03SGordon Ross cnt0 = mbp->mb_count; 230*02d09e03SGordon Ross 231*02d09e03SGordon Ross ERRCHK(mb_put_uint8(mbp, ace->ace_type)); 232*02d09e03SGordon Ross ERRCHK(mb_put_uint8(mbp, ace->ace_flags)); 233*02d09e03SGordon Ross ace_len_p = mb_reserve(mbp, sizeof (*ace_len_p)); 234*02d09e03SGordon Ross if (ace_len_p == NULL) { 235*02d09e03SGordon Ross error = ENOMEM; 236*02d09e03SGordon Ross goto errout; 237*02d09e03SGordon Ross } 238*02d09e03SGordon Ross ERRCHK(mb_put_uint32le(mbp, ace->ace_rights)); 239*02d09e03SGordon Ross 240*02d09e03SGordon Ross ERRCHK(mb_put_sid(mbp, ace->ace_sid)); 241*02d09e03SGordon Ross 242*02d09e03SGordon Ross ace_len = mbp->mb_count - cnt0; 243*02d09e03SGordon Ross *ace_len_p = htoles(ace_len); 244*02d09e03SGordon Ross 245*02d09e03SGordon Ross /* Success! */ 246*02d09e03SGordon Ross return (0); 247*02d09e03SGordon Ross 248*02d09e03SGordon Ross errout: 249*02d09e03SGordon Ross return (error); 250*02d09e03SGordon Ross } 251*02d09e03SGordon Ross 252*02d09e03SGordon Ross 253*02d09e03SGordon Ross /* 254*02d09e03SGordon Ross * Access Control List (ACL) 255*02d09e03SGordon Ross */ 256*02d09e03SGordon Ross 257*02d09e03SGordon Ross /* Not an OTW structure, so size can be at our convenience. */ 258*02d09e03SGordon Ross #define I_ACL_SIZE(cnt) (sizeof (i_ntacl_t) + (cnt) * sizeof (void *)) 259*02d09e03SGordon Ross 260*02d09e03SGordon Ross static void 261*02d09e03SGordon Ross ifree_acl(i_ntacl_t *acl) 262*02d09e03SGordon Ross { 263*02d09e03SGordon Ross i_ntace_t **acep; 264*02d09e03SGordon Ross size_t sz; 265*02d09e03SGordon Ross int i; 266*02d09e03SGordon Ross 267*02d09e03SGordon Ross if (acl == NULL) 268*02d09e03SGordon Ross return; 269*02d09e03SGordon Ross 270*02d09e03SGordon Ross acep = &acl->acl_acevec[0]; 271*02d09e03SGordon Ross for (i = 0; i < acl->acl_acecount; i++) { 272*02d09e03SGordon Ross ifree_ace(*acep); 273*02d09e03SGordon Ross acep++; 274*02d09e03SGordon Ross } 275*02d09e03SGordon Ross sz = I_ACL_SIZE(acl->acl_acecount); 276*02d09e03SGordon Ross FREESZ(acl, sz); 277*02d09e03SGordon Ross } 278*02d09e03SGordon Ross 279*02d09e03SGordon Ross static int 280*02d09e03SGordon Ross md_get_acl(mdchain_t *mdp, i_ntacl_t **aclp) 281*02d09e03SGordon Ross { 282*02d09e03SGordon Ross i_ntacl_t *acl = NULL; 283*02d09e03SGordon Ross i_ntace_t **acep; 284*02d09e03SGordon Ross uint8_t revision; 285*02d09e03SGordon Ross uint16_t acl_len, acecount; 286*02d09e03SGordon Ross size_t aclsz; 287*02d09e03SGordon Ross int i, error; 288*02d09e03SGordon Ross 289*02d09e03SGordon Ross if ((error = md_get_uint8(mdp, &revision)) != 0) 290*02d09e03SGordon Ross return (error); 291*02d09e03SGordon Ross if ((error = md_get_uint8(mdp, NULL)) != 0) 292*02d09e03SGordon Ross return (error); 293*02d09e03SGordon Ross if ((error = md_get_uint16le(mdp, &acl_len)) != 0) 294*02d09e03SGordon Ross return (error); 295*02d09e03SGordon Ross if ((error = md_get_uint16le(mdp, &acecount)) != 0) 296*02d09e03SGordon Ross return (error); 297*02d09e03SGordon Ross if ((error = md_get_uint16le(mdp, NULL)) != 0) 298*02d09e03SGordon Ross return (error); 299*02d09e03SGordon Ross 300*02d09e03SGordon Ross aclsz = I_ACL_SIZE(acecount); 301*02d09e03SGordon Ross if ((acl = MALLOC(aclsz)) == NULL) 302*02d09e03SGordon Ross return (ENOMEM); 303*02d09e03SGordon Ross bzero(acl, aclsz); 304*02d09e03SGordon Ross acl->acl_revision = revision; 305*02d09e03SGordon Ross acl->acl_acecount = acecount; 306*02d09e03SGordon Ross 307*02d09e03SGordon Ross acep = &acl->acl_acevec[0]; 308*02d09e03SGordon Ross for (i = 0; i < acl->acl_acecount; i++) { 309*02d09e03SGordon Ross ERRCHK(md_get_ace(mdp, acep)); 310*02d09e03SGordon Ross acep++; 311*02d09e03SGordon Ross } 312*02d09e03SGordon Ross /* 313*02d09e03SGordon Ross * There may be more data here, but 314*02d09e03SGordon Ross * the caller takes care of that. 315*02d09e03SGordon Ross */ 316*02d09e03SGordon Ross 317*02d09e03SGordon Ross /* Success! */ 318*02d09e03SGordon Ross *aclp = acl; 319*02d09e03SGordon Ross return (0); 320*02d09e03SGordon Ross 321*02d09e03SGordon Ross errout: 322*02d09e03SGordon Ross ifree_acl(acl); 323*02d09e03SGordon Ross return (error); 324*02d09e03SGordon Ross } 325*02d09e03SGordon Ross 326*02d09e03SGordon Ross static int 327*02d09e03SGordon Ross mb_put_acl(mbchain_t *mbp, i_ntacl_t *acl) 328*02d09e03SGordon Ross { 329*02d09e03SGordon Ross i_ntace_t **acep; 330*02d09e03SGordon Ross uint16_t acl_len, *acl_len_p; 331*02d09e03SGordon Ross int i, cnt0, error; 332*02d09e03SGordon Ross 333*02d09e03SGordon Ross cnt0 = mbp->mb_count; 334*02d09e03SGordon Ross 335*02d09e03SGordon Ross ERRCHK(mb_put_uint8(mbp, acl->acl_revision)); 336*02d09e03SGordon Ross ERRCHK(mb_put_uint8(mbp, 0)); /* pad1 */ 337*02d09e03SGordon Ross acl_len_p = mb_reserve(mbp, sizeof (*acl_len_p)); 338*02d09e03SGordon Ross if (acl_len_p == NULL) { 339*02d09e03SGordon Ross error = ENOMEM; 340*02d09e03SGordon Ross goto errout; 341*02d09e03SGordon Ross } 342*02d09e03SGordon Ross ERRCHK(mb_put_uint16le(mbp, acl->acl_acecount)); 343*02d09e03SGordon Ross ERRCHK(mb_put_uint16le(mbp, 0)); /* pad2 */ 344*02d09e03SGordon Ross 345*02d09e03SGordon Ross acep = &acl->acl_acevec[0]; 346*02d09e03SGordon Ross for (i = 0; i < acl->acl_acecount; i++) { 347*02d09e03SGordon Ross ERRCHK(mb_put_ace(mbp, *acep)); 348*02d09e03SGordon Ross acep++; 349*02d09e03SGordon Ross } 350*02d09e03SGordon Ross 351*02d09e03SGordon Ross /* Fill in acl_len_p */ 352*02d09e03SGordon Ross acl_len = mbp->mb_count - cnt0; 353*02d09e03SGordon Ross *acl_len_p = htoles(acl_len); 354*02d09e03SGordon Ross 355*02d09e03SGordon Ross /* Success! */ 356*02d09e03SGordon Ross return (0); 357*02d09e03SGordon Ross 358*02d09e03SGordon Ross errout: 359*02d09e03SGordon Ross return (error); 360*02d09e03SGordon Ross } 361*02d09e03SGordon Ross 362*02d09e03SGordon Ross 363*02d09e03SGordon Ross /* 364*02d09e03SGordon Ross * Security Descriptor 365*02d09e03SGordon Ross */ 366*02d09e03SGordon Ross void 367*02d09e03SGordon Ross smbfs_acl_free_sd(i_ntsd_t *sd) 368*02d09e03SGordon Ross { 369*02d09e03SGordon Ross 370*02d09e03SGordon Ross if (sd == NULL) 371*02d09e03SGordon Ross return; 372*02d09e03SGordon Ross 373*02d09e03SGordon Ross ifree_sid(sd->sd_owner); 374*02d09e03SGordon Ross ifree_sid(sd->sd_group); 375*02d09e03SGordon Ross ifree_acl(sd->sd_sacl); 376*02d09e03SGordon Ross ifree_acl(sd->sd_dacl); 377*02d09e03SGordon Ross 378*02d09e03SGordon Ross FREESZ(sd, sizeof (*sd)); 379*02d09e03SGordon Ross } 380*02d09e03SGordon Ross 381*02d09e03SGordon Ross /* 382*02d09e03SGordon Ross * Import a raw SD (mb chain) into "internal" form. 383*02d09e03SGordon Ross * (like "absolute" form per. NT docs) 384*02d09e03SGordon Ross * Returns allocated data in sdp 385*02d09e03SGordon Ross * 386*02d09e03SGordon Ross * Note: does NOT consume all the mdp data, so the 387*02d09e03SGordon Ross * caller has to take care of that if necessary. 388*02d09e03SGordon Ross */ 389*02d09e03SGordon Ross int 390*02d09e03SGordon Ross md_get_ntsd(mdchain_t *mdp, i_ntsd_t **sdp) 391*02d09e03SGordon Ross { 392*02d09e03SGordon Ross i_ntsd_t *sd = NULL; 393*02d09e03SGordon Ross mdchain_t top_md, tmp_md; 394*02d09e03SGordon Ross uint32_t owneroff, groupoff, sacloff, dacloff; 395*02d09e03SGordon Ross int error; 396*02d09e03SGordon Ross 397*02d09e03SGordon Ross if ((sd = MALLOC(sizeof (*sd))) == NULL) 398*02d09e03SGordon Ross return (ENOMEM); 399*02d09e03SGordon Ross bzero(sd, sizeof (*sd)); 400*02d09e03SGordon Ross 401*02d09e03SGordon Ross /* 402*02d09e03SGordon Ross * Offsets below are relative to this point, 403*02d09e03SGordon Ross * so save the mdp state for use below. 404*02d09e03SGordon Ross */ 405*02d09e03SGordon Ross top_md = *mdp; 406*02d09e03SGordon Ross 407*02d09e03SGordon Ross ERRCHK(md_get_uint8(mdp, &sd->sd_revision)); 408*02d09e03SGordon Ross ERRCHK(md_get_uint8(mdp, &sd->sd_rmctl)); 409*02d09e03SGordon Ross ERRCHK(md_get_uint16le(mdp, &sd->sd_flags)); 410*02d09e03SGordon Ross ERRCHK(md_get_uint32le(mdp, &owneroff)); 411*02d09e03SGordon Ross ERRCHK(md_get_uint32le(mdp, &groupoff)); 412*02d09e03SGordon Ross ERRCHK(md_get_uint32le(mdp, &sacloff)); 413*02d09e03SGordon Ross ERRCHK(md_get_uint32le(mdp, &dacloff)); 414*02d09e03SGordon Ross 415*02d09e03SGordon Ross /* 416*02d09e03SGordon Ross * For each section make a temporary copy of the 417*02d09e03SGordon Ross * top_md state, advance to the given offset, and 418*02d09e03SGordon Ross * pass that to the lower md_get_xxx functions. 419*02d09e03SGordon Ross * These could be marshalled in any order, but 420*02d09e03SGordon Ross * are normally found in the order shown here. 421*02d09e03SGordon Ross */ 422*02d09e03SGordon Ross if (sacloff) { 423*02d09e03SGordon Ross tmp_md = top_md; 424*02d09e03SGordon Ross md_get_mem(&tmp_md, NULL, sacloff, MB_MSYSTEM); 425*02d09e03SGordon Ross ERRCHK(md_get_acl(&tmp_md, &sd->sd_sacl)); 426*02d09e03SGordon Ross } 427*02d09e03SGordon Ross if (dacloff) { 428*02d09e03SGordon Ross tmp_md = top_md; 429*02d09e03SGordon Ross md_get_mem(&tmp_md, NULL, dacloff, MB_MSYSTEM); 430*02d09e03SGordon Ross ERRCHK(md_get_acl(&tmp_md, &sd->sd_dacl)); 431*02d09e03SGordon Ross } 432*02d09e03SGordon Ross if (owneroff) { 433*02d09e03SGordon Ross tmp_md = top_md; 434*02d09e03SGordon Ross md_get_mem(&tmp_md, NULL, owneroff, MB_MSYSTEM); 435*02d09e03SGordon Ross ERRCHK(md_get_sid(&tmp_md, &sd->sd_owner)); 436*02d09e03SGordon Ross } 437*02d09e03SGordon Ross if (groupoff) { 438*02d09e03SGordon Ross tmp_md = top_md; 439*02d09e03SGordon Ross md_get_mem(&tmp_md, NULL, groupoff, MB_MSYSTEM); 440*02d09e03SGordon Ross ERRCHK(md_get_sid(&tmp_md, &sd->sd_group)); 441*02d09e03SGordon Ross } 442*02d09e03SGordon Ross 443*02d09e03SGordon Ross /* Success! */ 444*02d09e03SGordon Ross *sdp = sd; 445*02d09e03SGordon Ross return (0); 446*02d09e03SGordon Ross 447*02d09e03SGordon Ross errout: 448*02d09e03SGordon Ross smbfs_acl_free_sd(sd); 449*02d09e03SGordon Ross return (error); 450*02d09e03SGordon Ross } 451*02d09e03SGordon Ross 452*02d09e03SGordon Ross /* 453*02d09e03SGordon Ross * Export an "internal" SD into an raw SD (mb chain). 454*02d09e03SGordon Ross * (a.k.a "self-relative" form per. NT docs) 455*02d09e03SGordon Ross * Returns allocated mbchain in mbp. 456*02d09e03SGordon Ross */ 457*02d09e03SGordon Ross int 458*02d09e03SGordon Ross mb_put_ntsd(mbchain_t *mbp, i_ntsd_t *sd) 459*02d09e03SGordon Ross { 460*02d09e03SGordon Ross uint32_t *owneroffp, *groupoffp, *sacloffp, *dacloffp; 461*02d09e03SGordon Ross uint32_t owneroff, groupoff, sacloff, dacloff; 462*02d09e03SGordon Ross int cnt0, error; 463*02d09e03SGordon Ross 464*02d09e03SGordon Ross cnt0 = mbp->mb_count; 465*02d09e03SGordon Ross owneroff = groupoff = sacloff = dacloff = 0; 466*02d09e03SGordon Ross 467*02d09e03SGordon Ross ERRCHK(mb_put_uint8(mbp, sd->sd_revision)); 468*02d09e03SGordon Ross ERRCHK(mb_put_uint8(mbp, sd->sd_rmctl)); 469*02d09e03SGordon Ross ERRCHK(mb_put_uint16le(mbp, sd->sd_flags)); 470*02d09e03SGordon Ross 471*02d09e03SGordon Ross owneroffp = mb_reserve(mbp, sizeof (*owneroffp)); 472*02d09e03SGordon Ross groupoffp = mb_reserve(mbp, sizeof (*groupoffp)); 473*02d09e03SGordon Ross sacloffp = mb_reserve(mbp, sizeof (*sacloffp)); 474*02d09e03SGordon Ross dacloffp = mb_reserve(mbp, sizeof (*dacloffp)); 475*02d09e03SGordon Ross if (owneroffp == NULL || groupoffp == NULL || 476*02d09e03SGordon Ross sacloffp == NULL || dacloffp == NULL) { 477*02d09e03SGordon Ross error = ENOMEM; 478*02d09e03SGordon Ross goto errout; 479*02d09e03SGordon Ross } 480*02d09e03SGordon Ross 481*02d09e03SGordon Ross /* 482*02d09e03SGordon Ross * These could be marshalled in any order, but 483*02d09e03SGordon Ross * are normally found in the order shown here. 484*02d09e03SGordon Ross */ 485*02d09e03SGordon Ross if (sd->sd_sacl) { 486*02d09e03SGordon Ross sacloff = mbp->mb_count - cnt0; 487*02d09e03SGordon Ross ERRCHK(mb_put_acl(mbp, sd->sd_sacl)); 488*02d09e03SGordon Ross } 489*02d09e03SGordon Ross if (sd->sd_dacl) { 490*02d09e03SGordon Ross dacloff = mbp->mb_count - cnt0; 491*02d09e03SGordon Ross ERRCHK(mb_put_acl(mbp, sd->sd_dacl)); 492*02d09e03SGordon Ross } 493*02d09e03SGordon Ross if (sd->sd_owner) { 494*02d09e03SGordon Ross owneroff = mbp->mb_count - cnt0; 495*02d09e03SGordon Ross ERRCHK(mb_put_sid(mbp, sd->sd_owner)); 496*02d09e03SGordon Ross } 497*02d09e03SGordon Ross if (sd->sd_group) { 498*02d09e03SGordon Ross groupoff = mbp->mb_count - cnt0; 499*02d09e03SGordon Ross ERRCHK(mb_put_sid(mbp, sd->sd_group)); 500*02d09e03SGordon Ross } 501*02d09e03SGordon Ross 502*02d09e03SGordon Ross /* Fill in the offsets */ 503*02d09e03SGordon Ross *owneroffp = htolel(owneroff); 504*02d09e03SGordon Ross *groupoffp = htolel(groupoff); 505*02d09e03SGordon Ross *sacloffp = htolel(sacloff); 506*02d09e03SGordon Ross *dacloffp = htolel(dacloff); 507*02d09e03SGordon Ross 508*02d09e03SGordon Ross /* Success! */ 509*02d09e03SGordon Ross return (0); 510*02d09e03SGordon Ross 511*02d09e03SGordon Ross errout: 512*02d09e03SGordon Ross return (error); 513*02d09e03SGordon Ross } 514*02d09e03SGordon Ross 515*02d09e03SGordon Ross 516*02d09e03SGordon Ross /* 517*02d09e03SGordon Ross * Helper functions for conversion between ZFS-style ACLs 518*02d09e03SGordon Ross * and Windows Security Descriptors. 519*02d09e03SGordon Ross */ 520*02d09e03SGordon Ross 521*02d09e03SGordon Ross 522*02d09e03SGordon Ross /* 523*02d09e03SGordon Ross * Convert an NT SID to a string. Optionally return the 524*02d09e03SGordon Ross * last sub-authority (or "relative ID" -- RID) in *ridp 525*02d09e03SGordon Ross * and truncate the output string after the domain part. 526*02d09e03SGordon Ross * If ridp==NULL, the output string is the whole SID, 527*02d09e03SGordon Ross * including both the domain and RID. 528*02d09e03SGordon Ross * 529*02d09e03SGordon Ross * Return length written, or -1 on error. 530*02d09e03SGordon Ross */ 531*02d09e03SGordon Ross int 532*02d09e03SGordon Ross smbfs_sid2str(i_ntsid_t *sid, 533*02d09e03SGordon Ross char *obuf, size_t osz, uint32_t *ridp) 534*02d09e03SGordon Ross { 535*02d09e03SGordon Ross char *s = obuf; 536*02d09e03SGordon Ross uint64_t auth = 0; 537*02d09e03SGordon Ross uint_t i, n; 538*02d09e03SGordon Ross uint32_t subs, *ip; 539*02d09e03SGordon Ross 540*02d09e03SGordon Ross n = snprintf(s, osz, "S-%u", sid->sid_revision); 541*02d09e03SGordon Ross if (n > osz) 542*02d09e03SGordon Ross return (-1); 543*02d09e03SGordon Ross s += n; osz -= n; 544*02d09e03SGordon Ross 545*02d09e03SGordon Ross for (i = 0; i < 6; i++) 546*02d09e03SGordon Ross auth = (auth << 8) | sid->sid_authority[i]; 547*02d09e03SGordon Ross n = snprintf(s, osz, "-%llu", (u_longlong_t)auth); 548*02d09e03SGordon Ross if (n > osz) 549*02d09e03SGordon Ross return (-1); 550*02d09e03SGordon Ross s += n; osz -= n; 551*02d09e03SGordon Ross 552*02d09e03SGordon Ross subs = sid->sid_subauthcount; 553*02d09e03SGordon Ross if (subs < 1 || subs > 15) 554*02d09e03SGordon Ross return (-1); 555*02d09e03SGordon Ross if (ridp) 556*02d09e03SGordon Ross subs--; 557*02d09e03SGordon Ross 558*02d09e03SGordon Ross ip = &sid->sid_subauthvec[0]; 559*02d09e03SGordon Ross for (; subs; subs--, ip++) { 560*02d09e03SGordon Ross n = snprintf(s, osz, "-%u", *ip); 561*02d09e03SGordon Ross if (n > osz) 562*02d09e03SGordon Ross return (-1); 563*02d09e03SGordon Ross s += n; osz -= n; 564*02d09e03SGordon Ross } 565*02d09e03SGordon Ross if (ridp) 566*02d09e03SGordon Ross *ridp = *ip; 567*02d09e03SGordon Ross 568*02d09e03SGordon Ross /* LINTED E_PTRDIFF_OVERFLOW */ 569*02d09e03SGordon Ross return (s - obuf); 570*02d09e03SGordon Ross } 571*02d09e03SGordon Ross 572*02d09e03SGordon Ross /* 573*02d09e03SGordon Ross * Our interface to the idmap service. 574*02d09e03SGordon Ross * 575*02d09e03SGordon Ross * The idmap API is _almost_ the same between 576*02d09e03SGordon Ross * kernel and user-level. But not quite... 577*02d09e03SGordon Ross * Hope this improves readability below. 578*02d09e03SGordon Ross */ 579*02d09e03SGordon Ross #ifdef _KERNEL 580*02d09e03SGordon Ross 581*02d09e03SGordon Ross #define I_GetPidBySid(GH, SPP, RID, PIDP, ISUP, SP) \ 582*02d09e03SGordon Ross kidmap_batch_getpidbysid(GH, SPP, RID, PIDP, ISUP, SP) 583*02d09e03SGordon Ross #define I_GetMappings kidmap_get_mappings 584*02d09e03SGordon Ross 585*02d09e03SGordon Ross #else /* _KERNEL */ 586*02d09e03SGordon Ross 587*02d09e03SGordon Ross #define I_GetPidBySid(GH, SPP, RID, PIDP, ISUP, SP) \ 588*02d09e03SGordon Ross idmap_get_pidbysid(GH, SPP, RID, 0, PIDP, ISUP, SP) 589*02d09e03SGordon Ross #define I_GetMappings idmap_get_mappings 590*02d09e03SGordon Ross 591*02d09e03SGordon Ross #endif /* _KERNEL */ 592*02d09e03SGordon Ross 593*02d09e03SGordon Ross struct mapinfo { 594*02d09e03SGordon Ross uid_t mi_uid; /* or gid */ 595*02d09e03SGordon Ross int mi_isuser; 596*02d09e03SGordon Ross idmap_stat mi_status; 597*02d09e03SGordon Ross }; 598*02d09e03SGordon Ross 599*02d09e03SGordon Ross /* 600*02d09e03SGordon Ross * A special value for mi_isuser (above) to indicate 601*02d09e03SGordon Ross * that the SID is the well-known "Everyone" (S-1-1-0). 602*02d09e03SGordon Ross * The idmap library only uses -1, 0, 1, so this value 603*02d09e03SGordon Ross * is arbitrary but must not overlap w/ idmap values. 604*02d09e03SGordon Ross * XXX: Could use a way for idmap to tell us when 605*02d09e03SGordon Ross * it recognizes this well-known SID. 606*02d09e03SGordon Ross */ 607*02d09e03SGordon Ross #define IS_WKSID_EVERYONE 11 608*02d09e03SGordon Ross 609*02d09e03SGordon Ross /* 610*02d09e03SGordon Ross * Build an idmap request. Cleanup is 611*02d09e03SGordon Ross * handled by the caller (error or not) 612*02d09e03SGordon Ross */ 613*02d09e03SGordon Ross static int 614*02d09e03SGordon Ross mkrq_idmap_sid2ux( 615*02d09e03SGordon Ross idmap_get_handle_t *idmap_gh, 616*02d09e03SGordon Ross i_ntsid_t *sid, 617*02d09e03SGordon Ross struct mapinfo *mip) 618*02d09e03SGordon Ross { 619*02d09e03SGordon Ross char sid_prefix[256]; 620*02d09e03SGordon Ross uint32_t rid; 621*02d09e03SGordon Ross idmap_stat idms; 622*02d09e03SGordon Ross 623*02d09e03SGordon Ross if (smbfs_sid2str(sid, sid_prefix, sizeof (sid_prefix), &rid) < 0) 624*02d09e03SGordon Ross return (EINVAL); 625*02d09e03SGordon Ross 626*02d09e03SGordon Ross /* 627*02d09e03SGordon Ross * Give the "Everyone" group special treatment. 628*02d09e03SGordon Ross */ 629*02d09e03SGordon Ross if (strcmp(sid_prefix, "S-1-1") == 0 && rid == 0) { 630*02d09e03SGordon Ross /* This is "Everyone" */ 631*02d09e03SGordon Ross mip->mi_uid = (uid_t)-1; 632*02d09e03SGordon Ross mip->mi_isuser = IS_WKSID_EVERYONE; 633*02d09e03SGordon Ross mip->mi_status = 0; 634*02d09e03SGordon Ross return (0); 635*02d09e03SGordon Ross } 636*02d09e03SGordon Ross 637*02d09e03SGordon Ross idms = I_GetPidBySid(idmap_gh, sid_prefix, rid, 638*02d09e03SGordon Ross &mip->mi_uid, &mip->mi_isuser, &mip->mi_status); 639*02d09e03SGordon Ross if (idms != IDMAP_SUCCESS) 640*02d09e03SGordon Ross return (EINVAL); 641*02d09e03SGordon Ross 642*02d09e03SGordon Ross return (0); 643*02d09e03SGordon Ross } 644*02d09e03SGordon Ross 645*02d09e03SGordon Ross static void 646*02d09e03SGordon Ross ntace2zace(ace_t *zacep, i_ntace_t *ntace, struct mapinfo *mip) 647*02d09e03SGordon Ross { 648*02d09e03SGordon Ross uint32_t zamask; 649*02d09e03SGordon Ross uint16_t zflags, ntflags; 650*02d09e03SGordon Ross uint8_t zatype = ntace->ace_type; 651*02d09e03SGordon Ross 652*02d09e03SGordon Ross /* 653*02d09e03SGordon Ross * Translate NT ACE flags to ZFS ACE flags. 654*02d09e03SGordon Ross * The low four bits are the same, but not 655*02d09e03SGordon Ross * others: INHERITED_ACE_FLAG, etc. 656*02d09e03SGordon Ross */ 657*02d09e03SGordon Ross ntflags = ntace->ace_flags; 658*02d09e03SGordon Ross zflags = 0; 659*02d09e03SGordon Ross 660*02d09e03SGordon Ross if (ntflags & OBJECT_INHERIT_ACE_FLAG) 661*02d09e03SGordon Ross zflags |= ACE_FILE_INHERIT_ACE; 662*02d09e03SGordon Ross if (ntflags & CONTAINER_INHERIT_ACE_FLAG) 663*02d09e03SGordon Ross zflags |= ACE_DIRECTORY_INHERIT_ACE; 664*02d09e03SGordon Ross if (ntflags & NO_PROPAGATE_INHERIT_ACE_FLAG) 665*02d09e03SGordon Ross zflags |= ACE_NO_PROPAGATE_INHERIT_ACE; 666*02d09e03SGordon Ross if (ntflags & INHERIT_ONLY_ACE_FLAG) 667*02d09e03SGordon Ross zflags |= ACE_INHERIT_ONLY_ACE; 668*02d09e03SGordon Ross if (ntflags & INHERITED_ACE_FLAG) 669*02d09e03SGordon Ross zflags |= ACE_INHERITED_ACE; 670*02d09e03SGordon Ross 671*02d09e03SGordon Ross if (ntflags & SUCCESSFUL_ACCESS_ACE_FLAG) 672*02d09e03SGordon Ross zflags |= ACE_SUCCESSFUL_ACCESS_ACE_FLAG; 673*02d09e03SGordon Ross if (ntflags & FAILED_ACCESS_ACE_FLAG) 674*02d09e03SGordon Ross zflags |= ACE_FAILED_ACCESS_ACE_FLAG; 675*02d09e03SGordon Ross 676*02d09e03SGordon Ross /* 677*02d09e03SGordon Ross * Add the "ID type" flags to the ZFS ace flags. 678*02d09e03SGordon Ross * Would be nice if the idmap header defined some 679*02d09e03SGordon Ross * manifest constants for these "isuser" values. 680*02d09e03SGordon Ross */ 681*02d09e03SGordon Ross switch (mip->mi_isuser) { 682*02d09e03SGordon Ross case IS_WKSID_EVERYONE: 683*02d09e03SGordon Ross zflags |= ACE_EVERYONE; 684*02d09e03SGordon Ross break; 685*02d09e03SGordon Ross case 0: /* it's a GID */ 686*02d09e03SGordon Ross zflags |= ACE_IDENTIFIER_GROUP; 687*02d09e03SGordon Ross break; 688*02d09e03SGordon Ross default: 689*02d09e03SGordon Ross case 1: /* it's a UID */ 690*02d09e03SGordon Ross break; 691*02d09e03SGordon Ross } 692*02d09e03SGordon Ross 693*02d09e03SGordon Ross /* 694*02d09e03SGordon Ross * The access mask bits are the same, but 695*02d09e03SGordon Ross * mask off any bits we don't expect. 696*02d09e03SGordon Ross * Should not see any GENERIC_xxx flags, 697*02d09e03SGordon Ross * as those are only valid in requested 698*02d09e03SGordon Ross * access masks, not ACLs. But if we do, 699*02d09e03SGordon Ross * get those, silently clear them here. 700*02d09e03SGordon Ross */ 701*02d09e03SGordon Ross zamask = ntace->ace_rights & ACE_ALL_PERMS; 702*02d09e03SGordon Ross 703*02d09e03SGordon Ross /* 704*02d09e03SGordon Ross * Verify that it's a known ACE type. 705*02d09e03SGordon Ross * Only handle the types that appear in 706*02d09e03SGordon Ross * V2, V3, V4 ACLs for now. Avoid failing 707*02d09e03SGordon Ross * the whole conversion if we get unknown 708*02d09e03SGordon Ross * ace types, but convert them to something 709*02d09e03SGordon Ross * that will have no effect on access. 710*02d09e03SGordon Ross */ 711*02d09e03SGordon Ross if (zatype > SYSTEM_ALARM_OBJECT_ACE_TYPE) { 712*02d09e03SGordon Ross zatype = ACCESS_ALLOWED_ACE_TYPE; 713*02d09e03SGordon Ross zamask = 0; /* harmless */ 714*02d09e03SGordon Ross } 715*02d09e03SGordon Ross 716*02d09e03SGordon Ross /* 717*02d09e03SGordon Ross * Fill in the ZFS-style ACE 718*02d09e03SGordon Ross */ 719*02d09e03SGordon Ross zacep->a_who = mip->mi_uid; /* from ace_sid */ 720*02d09e03SGordon Ross zacep->a_access_mask = zamask; 721*02d09e03SGordon Ross zacep->a_flags = zflags; 722*02d09e03SGordon Ross zacep->a_type = zatype; 723*02d09e03SGordon Ross } 724*02d09e03SGordon Ross 725*02d09e03SGordon Ross /* 726*02d09e03SGordon Ross * Convert an internal SD to a ZFS-style ACL. 727*02d09e03SGordon Ross * Note optional args: vsa/acl, uidp, gidp. 728*02d09e03SGordon Ross */ 729*02d09e03SGordon Ross int 730*02d09e03SGordon Ross smbfs_acl_sd2zfs( 731*02d09e03SGordon Ross i_ntsd_t *sd, 732*02d09e03SGordon Ross #ifdef _KERNEL 733*02d09e03SGordon Ross vsecattr_t *acl_info, 734*02d09e03SGordon Ross #else /* _KERNEL */ 735*02d09e03SGordon Ross acl_t *acl_info, 736*02d09e03SGordon Ross #endif /* _KERNEL */ 737*02d09e03SGordon Ross uid_t *uidp, gid_t *gidp) 738*02d09e03SGordon Ross { 739*02d09e03SGordon Ross struct mapinfo *mip, *mapinfo = NULL; 740*02d09e03SGordon Ross int error, i, mapcnt, zacecnt, zacl_size; 741*02d09e03SGordon Ross ace_t *zacep; 742*02d09e03SGordon Ross i_ntacl_t *ntacl; 743*02d09e03SGordon Ross i_ntace_t **ntacep; 744*02d09e03SGordon Ross #ifndef _KERNEL 745*02d09e03SGordon Ross idmap_handle_t *idmap_h = NULL; 746*02d09e03SGordon Ross #endif /* _KERNEL */ 747*02d09e03SGordon Ross idmap_get_handle_t *idmap_gh = NULL; 748*02d09e03SGordon Ross idmap_stat idms; 749*02d09e03SGordon Ross 750*02d09e03SGordon Ross /* 751*02d09e03SGordon Ross * sanity checks 752*02d09e03SGordon Ross */ 753*02d09e03SGordon Ross #ifndef _KERNEL 754*02d09e03SGordon Ross if (acl_info) { 755*02d09e03SGordon Ross if (acl_info->acl_type != ACE_T || 756*02d09e03SGordon Ross acl_info->acl_aclp != NULL || 757*02d09e03SGordon Ross acl_info->acl_entry_size != sizeof (ace_t)) 758*02d09e03SGordon Ross return (EINVAL); 759*02d09e03SGordon Ross } 760*02d09e03SGordon Ross #endif /* _KERNEL */ 761*02d09e03SGordon Ross 762*02d09e03SGordon Ross /* 763*02d09e03SGordon Ross * First, get all the SID mappings. 764*02d09e03SGordon Ross * How many? 765*02d09e03SGordon Ross */ 766*02d09e03SGordon Ross mapcnt = 0; 767*02d09e03SGordon Ross if (sd->sd_owner) 768*02d09e03SGordon Ross mapcnt++; 769*02d09e03SGordon Ross if (sd->sd_group) 770*02d09e03SGordon Ross mapcnt++; 771*02d09e03SGordon Ross if (sd->sd_sacl) 772*02d09e03SGordon Ross mapcnt += sd->sd_sacl->acl_acecount; 773*02d09e03SGordon Ross if (sd->sd_dacl) 774*02d09e03SGordon Ross mapcnt += sd->sd_dacl->acl_acecount; 775*02d09e03SGordon Ross if (mapcnt == 0) 776*02d09e03SGordon Ross return (EINVAL); 777*02d09e03SGordon Ross 778*02d09e03SGordon Ross mapinfo = MALLOC(mapcnt * sizeof (*mapinfo)); 779*02d09e03SGordon Ross if (mapinfo == NULL) { 780*02d09e03SGordon Ross error = ENOMEM; 781*02d09e03SGordon Ross goto errout; 782*02d09e03SGordon Ross } 783*02d09e03SGordon Ross bzero(mapinfo, mapcnt * sizeof (*mapinfo)); 784*02d09e03SGordon Ross 785*02d09e03SGordon Ross 786*02d09e03SGordon Ross /* 787*02d09e03SGordon Ross * Build our request to the idmap deamon. 788*02d09e03SGordon Ross */ 789*02d09e03SGordon Ross #ifdef _KERNEL 790*02d09e03SGordon Ross idmap_gh = kidmap_get_create(curproc->p_zone); 791*02d09e03SGordon Ross #else /* _KERNEL */ 792*02d09e03SGordon Ross idms = idmap_init(&idmap_h); 793*02d09e03SGordon Ross if (idms != IDMAP_SUCCESS) { 794*02d09e03SGordon Ross error = ENOTACTIVE; 795*02d09e03SGordon Ross goto errout; 796*02d09e03SGordon Ross } 797*02d09e03SGordon Ross idms = idmap_get_create(idmap_h, &idmap_gh); 798*02d09e03SGordon Ross if (idms != IDMAP_SUCCESS) { 799*02d09e03SGordon Ross error = ENOTACTIVE; 800*02d09e03SGordon Ross goto errout; 801*02d09e03SGordon Ross } 802*02d09e03SGordon Ross #endif /* _KERNEL */ 803*02d09e03SGordon Ross 804*02d09e03SGordon Ross mip = mapinfo; 805*02d09e03SGordon Ross if (sd->sd_owner) { 806*02d09e03SGordon Ross error = mkrq_idmap_sid2ux( 807*02d09e03SGordon Ross idmap_gh, sd->sd_owner, mip); 808*02d09e03SGordon Ross if (error) 809*02d09e03SGordon Ross goto errout; 810*02d09e03SGordon Ross mip++; 811*02d09e03SGordon Ross } 812*02d09e03SGordon Ross if (sd->sd_group) { 813*02d09e03SGordon Ross error = mkrq_idmap_sid2ux( 814*02d09e03SGordon Ross idmap_gh, sd->sd_group, mip); 815*02d09e03SGordon Ross if (error) 816*02d09e03SGordon Ross goto errout; 817*02d09e03SGordon Ross mip++; 818*02d09e03SGordon Ross } 819*02d09e03SGordon Ross if (sd->sd_sacl) { 820*02d09e03SGordon Ross ntacl = sd->sd_sacl; 821*02d09e03SGordon Ross ntacep = &ntacl->acl_acevec[0]; 822*02d09e03SGordon Ross for (i = 0; i < ntacl->acl_acecount; i++) { 823*02d09e03SGordon Ross error = mkrq_idmap_sid2ux( 824*02d09e03SGordon Ross idmap_gh, (*ntacep)->ace_sid, mip); 825*02d09e03SGordon Ross if (error) 826*02d09e03SGordon Ross goto errout; 827*02d09e03SGordon Ross ntacep++; 828*02d09e03SGordon Ross mip++; 829*02d09e03SGordon Ross } 830*02d09e03SGordon Ross } 831*02d09e03SGordon Ross if (sd->sd_dacl) { 832*02d09e03SGordon Ross ntacl = sd->sd_dacl; 833*02d09e03SGordon Ross ntacep = &ntacl->acl_acevec[0]; 834*02d09e03SGordon Ross for (i = 0; i < ntacl->acl_acecount; i++) { 835*02d09e03SGordon Ross error = mkrq_idmap_sid2ux( 836*02d09e03SGordon Ross idmap_gh, (*ntacep)->ace_sid, mip); 837*02d09e03SGordon Ross if (error) 838*02d09e03SGordon Ross goto errout; 839*02d09e03SGordon Ross ntacep++; 840*02d09e03SGordon Ross mip++; 841*02d09e03SGordon Ross } 842*02d09e03SGordon Ross } 843*02d09e03SGordon Ross 844*02d09e03SGordon Ross idms = I_GetMappings(idmap_gh); 845*02d09e03SGordon Ross if (idms != IDMAP_SUCCESS) { 846*02d09e03SGordon Ross /* creative error choice */ 847*02d09e03SGordon Ross error = EIDRM; 848*02d09e03SGordon Ross goto errout; 849*02d09e03SGordon Ross } 850*02d09e03SGordon Ross 851*02d09e03SGordon Ross /* 852*02d09e03SGordon Ross * With any luck, we now have Unix user/group IDs 853*02d09e03SGordon Ross * for every Windows SID in the security descriptor. 854*02d09e03SGordon Ross * The remaining work is just format conversion. 855*02d09e03SGordon Ross */ 856*02d09e03SGordon Ross mip = mapinfo; 857*02d09e03SGordon Ross if (sd->sd_owner) { 858*02d09e03SGordon Ross if (uidp) { 859*02d09e03SGordon Ross if (mip->mi_isuser == 1) 860*02d09e03SGordon Ross *uidp = mip->mi_uid; 861*02d09e03SGordon Ross else 862*02d09e03SGordon Ross *uidp = (uid_t)-1; 863*02d09e03SGordon Ross } 864*02d09e03SGordon Ross mip++; 865*02d09e03SGordon Ross } else { 866*02d09e03SGordon Ross if (uidp) 867*02d09e03SGordon Ross *uidp = (uid_t)-1; 868*02d09e03SGordon Ross } 869*02d09e03SGordon Ross if (sd->sd_group) { 870*02d09e03SGordon Ross if (gidp) { 871*02d09e03SGordon Ross if (mip->mi_isuser == 0) 872*02d09e03SGordon Ross *gidp = (gid_t)mip->mi_uid; 873*02d09e03SGordon Ross else 874*02d09e03SGordon Ross *gidp = (gid_t)-1; 875*02d09e03SGordon Ross } 876*02d09e03SGordon Ross mip++; 877*02d09e03SGordon Ross } else { 878*02d09e03SGordon Ross if (gidp) 879*02d09e03SGordon Ross *gidp = (gid_t)-1; 880*02d09e03SGordon Ross } 881*02d09e03SGordon Ross 882*02d09e03SGordon Ross if (acl_info == NULL) { 883*02d09e03SGordon Ross /* Caller only wanted uid/gid */ 884*02d09e03SGordon Ross goto ok_out; 885*02d09e03SGordon Ross } 886*02d09e03SGordon Ross 887*02d09e03SGordon Ross /* 888*02d09e03SGordon Ross * Build the ZFS-style ACL 889*02d09e03SGordon Ross */ 890*02d09e03SGordon Ross zacecnt = 0; 891*02d09e03SGordon Ross if (sd->sd_sacl) 892*02d09e03SGordon Ross zacecnt += sd->sd_sacl->acl_acecount; 893*02d09e03SGordon Ross if (sd->sd_dacl) 894*02d09e03SGordon Ross zacecnt += sd->sd_dacl->acl_acecount; 895*02d09e03SGordon Ross zacl_size = zacecnt * sizeof (ace_t); 896*02d09e03SGordon Ross zacep = MALLOC(zacl_size); 897*02d09e03SGordon Ross #ifdef _KERNEL 898*02d09e03SGordon Ross acl_info->vsa_aclentp = zacep; 899*02d09e03SGordon Ross acl_info->vsa_aclentsz = zacl_size; 900*02d09e03SGordon Ross #else /* _KERNEL */ 901*02d09e03SGordon Ross if (zacep == NULL) { 902*02d09e03SGordon Ross error = ENOMEM; 903*02d09e03SGordon Ross goto errout; 904*02d09e03SGordon Ross } 905*02d09e03SGordon Ross acl_info->acl_cnt = zacecnt; 906*02d09e03SGordon Ross acl_info->acl_aclp = zacep; 907*02d09e03SGordon Ross #endif /* _KERNEL */ 908*02d09e03SGordon Ross 909*02d09e03SGordon Ross if (sd->sd_sacl) { 910*02d09e03SGordon Ross ntacl = sd->sd_sacl; 911*02d09e03SGordon Ross ntacep = &ntacl->acl_acevec[0]; 912*02d09e03SGordon Ross for (i = 0; i < ntacl->acl_acecount; i++) { 913*02d09e03SGordon Ross ntace2zace(zacep, *ntacep, mip); 914*02d09e03SGordon Ross zacep++; 915*02d09e03SGordon Ross ntacep++; 916*02d09e03SGordon Ross mip++; 917*02d09e03SGordon Ross } 918*02d09e03SGordon Ross } 919*02d09e03SGordon Ross if (sd->sd_dacl) { 920*02d09e03SGordon Ross ntacl = sd->sd_dacl; 921*02d09e03SGordon Ross ntacep = &ntacl->acl_acevec[0]; 922*02d09e03SGordon Ross for (i = 0; i < ntacl->acl_acecount; i++) { 923*02d09e03SGordon Ross ntace2zace(zacep, *ntacep, mip); 924*02d09e03SGordon Ross zacep++; 925*02d09e03SGordon Ross ntacep++; 926*02d09e03SGordon Ross mip++; 927*02d09e03SGordon Ross } 928*02d09e03SGordon Ross } 929*02d09e03SGordon Ross 930*02d09e03SGordon Ross ok_out: 931*02d09e03SGordon Ross error = 0; 932*02d09e03SGordon Ross 933*02d09e03SGordon Ross errout: 934*02d09e03SGordon Ross if (mapinfo) 935*02d09e03SGordon Ross FREESZ(mapinfo, mapcnt * sizeof (*mapinfo)); 936*02d09e03SGordon Ross 937*02d09e03SGordon Ross return (error); 938*02d09e03SGordon Ross } 939*02d09e03SGordon Ross 940*02d09e03SGordon Ross 941*02d09e03SGordon Ross /* 942*02d09e03SGordon Ross * Convert an internal SD to a ZFS-style ACL. 943*02d09e03SGordon Ross * Include owner/group too if uid/gid != -1. 944*02d09e03SGordon Ross * Note optional arg: vsa/acl 945*02d09e03SGordon Ross */ 946*02d09e03SGordon Ross /*ARGSUSED*/ 947*02d09e03SGordon Ross int smbfs_acl_zfs2sd( 948*02d09e03SGordon Ross #ifdef _KERNEL 949*02d09e03SGordon Ross vsecattr_t *vsa, 950*02d09e03SGordon Ross #else /* _KERNEL */ 951*02d09e03SGordon Ross acl_t *acl, 952*02d09e03SGordon Ross #endif /* _KERNEL */ 953*02d09e03SGordon Ross uid_t uid, gid_t gid, 954*02d09e03SGordon Ross i_ntsd_t **sdp) 955*02d09e03SGordon Ross { 956*02d09e03SGordon Ross /* XXX - todo */ 957*02d09e03SGordon Ross return (ENOSYS); 958*02d09e03SGordon Ross } 959