1789Sahrens /* 2789Sahrens * CDDL HEADER START 3789Sahrens * 4789Sahrens * The contents of this file are subject to the terms of the 51544Seschrock * Common Development and Distribution License (the "License"). 61544Seschrock * You may not use this file except in compliance with the License. 7789Sahrens * 8789Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9789Sahrens * or http://www.opensolaris.org/os/licensing. 10789Sahrens * See the License for the specific language governing permissions 11789Sahrens * and limitations under the License. 12789Sahrens * 13789Sahrens * When distributing Covered Code, include this CDDL HEADER in each 14789Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15789Sahrens * If applicable, add the following below this CDDL HEADER, with the 16789Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 17789Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18789Sahrens * 19789Sahrens * CDDL HEADER END 20789Sahrens */ 21789Sahrens /* 224300Smarks * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23789Sahrens * Use is subject to license terms. 24789Sahrens */ 25789Sahrens 26789Sahrens #pragma ident "%Z%%M% %I% %E% SMI" 27789Sahrens 28789Sahrens #include <sys/types.h> 29789Sahrens #include <sys/param.h> 30789Sahrens #include <sys/time.h> 31789Sahrens #include <sys/systm.h> 32789Sahrens #include <sys/sysmacros.h> 33789Sahrens #include <sys/resource.h> 34789Sahrens #include <sys/vfs.h> 35789Sahrens #include <sys/vnode.h> 36*5331Samw #include <sys/sid.h> 37789Sahrens #include <sys/file.h> 38789Sahrens #include <sys/stat.h> 39789Sahrens #include <sys/kmem.h> 40789Sahrens #include <sys/cmn_err.h> 41789Sahrens #include <sys/errno.h> 42789Sahrens #include <sys/unistd.h> 431576Smarks #include <sys/sdt.h> 44789Sahrens #include <sys/fs/zfs.h> 45789Sahrens #include <sys/mode.h> 46789Sahrens #include <sys/policy.h> 47789Sahrens #include <sys/zfs_znode.h> 48*5331Samw #include <sys/zfs_fuid.h> 49789Sahrens #include <sys/zfs_acl.h> 50789Sahrens #include <sys/zfs_dir.h> 51789Sahrens #include <sys/zfs_vfsops.h> 52789Sahrens #include <sys/dmu.h> 53*5331Samw #include <sys/dnode.h> 54789Sahrens #include <sys/zap.h> 55789Sahrens #include "fs/fs_subr.h" 56789Sahrens #include <acl/acl_common.h> 57789Sahrens 58789Sahrens #define ALLOW ACE_ACCESS_ALLOWED_ACE_TYPE 59789Sahrens #define DENY ACE_ACCESS_DENIED_ACE_TYPE 60*5331Samw #define MAX_ACE_TYPE ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE 61789Sahrens 62789Sahrens #define OWNING_GROUP (ACE_GROUP|ACE_IDENTIFIER_GROUP) 63789Sahrens #define EVERYONE_ALLOW_MASK (ACE_READ_ACL|ACE_READ_ATTRIBUTES | \ 64789Sahrens ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE) 65789Sahrens #define EVERYONE_DENY_MASK (ACE_WRITE_ACL|ACE_WRITE_OWNER | \ 66789Sahrens ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS) 67789Sahrens #define OWNER_ALLOW_MASK (ACE_WRITE_ACL | ACE_WRITE_OWNER | \ 68789Sahrens ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS) 69*5331Samw #define WRITE_MASK_DATA (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_NAMED_ATTRS) 70*5331Samw 71*5331Samw #define ZFS_CHECKED_MASKS (ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_DATA| \ 72*5331Samw ACE_READ_NAMED_ATTRS|ACE_WRITE_DATA|ACE_WRITE_ATTRIBUTES| \ 73*5331Samw ACE_WRITE_NAMED_ATTRS|ACE_APPEND_DATA|ACE_EXECUTE|ACE_WRITE_OWNER| \ 74*5331Samw ACE_WRITE_ACL|ACE_DELETE|ACE_DELETE_CHILD|ACE_SYNCHRONIZE) 75*5331Samw 76*5331Samw #define WRITE_MASK (WRITE_MASK_DATA|ACE_WRITE_ATTRIBUTES|ACE_WRITE_ACL|\ 77*5331Samw ACE_WRITE_OWNER) 78789Sahrens 79789Sahrens #define OGE_CLEAR (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \ 80789Sahrens ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE) 81789Sahrens 82789Sahrens #define OKAY_MASK_BITS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \ 83789Sahrens ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE) 84789Sahrens 85789Sahrens #define ALL_INHERIT (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE | \ 86*5331Samw ACE_NO_PROPAGATE_INHERIT_ACE|ACE_INHERIT_ONLY_ACE|ACE_INHERITED_ACE) 87789Sahrens 881576Smarks #define SECURE_CLEAR (ACE_WRITE_ACL|ACE_WRITE_OWNER) 89789Sahrens 90*5331Samw #define V4_ACL_WIDE_FLAGS (ZFS_ACL_AUTO_INHERIT|ZFS_ACL_DEFAULTED|\ 91*5331Samw ZFS_ACL_PROTECTED) 92*5331Samw 93*5331Samw #define ZFS_ACL_WIDE_FLAGS (V4_ACL_WIDE_FLAGS|ZFS_ACL_TRIVIAL|ZFS_INHERIT_ACE|\ 94*5331Samw ZFS_ACL_OBJ_ACE) 95*5331Samw 96*5331Samw static uint16_t 97*5331Samw zfs_ace_v0_get_type(void *acep) 98*5331Samw { 99*5331Samw return (((zfs_oldace_t *)acep)->z_type); 100*5331Samw } 101*5331Samw 102*5331Samw static uint16_t 103*5331Samw zfs_ace_v0_get_flags(void *acep) 104*5331Samw { 105*5331Samw return (((zfs_oldace_t *)acep)->z_flags); 106*5331Samw } 107*5331Samw 108*5331Samw static uint32_t 109*5331Samw zfs_ace_v0_get_mask(void *acep) 110*5331Samw { 111*5331Samw return (((zfs_oldace_t *)acep)->z_access_mask); 112*5331Samw } 113*5331Samw 114*5331Samw static uint64_t 115*5331Samw zfs_ace_v0_get_who(void *acep) 116*5331Samw { 117*5331Samw return (((zfs_oldace_t *)acep)->z_fuid); 118*5331Samw } 119*5331Samw 120*5331Samw static void 121*5331Samw zfs_ace_v0_set_type(void *acep, uint16_t type) 122*5331Samw { 123*5331Samw ((zfs_oldace_t *)acep)->z_type = type; 124*5331Samw } 125*5331Samw 126*5331Samw static void 127*5331Samw zfs_ace_v0_set_flags(void *acep, uint16_t flags) 128*5331Samw { 129*5331Samw ((zfs_oldace_t *)acep)->z_flags = flags; 130*5331Samw } 131*5331Samw 132*5331Samw static void 133*5331Samw zfs_ace_v0_set_mask(void *acep, uint32_t mask) 134*5331Samw { 135*5331Samw ((zfs_oldace_t *)acep)->z_access_mask = mask; 136*5331Samw } 137*5331Samw 138*5331Samw static void 139*5331Samw zfs_ace_v0_set_who(void *acep, uint64_t who) 140*5331Samw { 141*5331Samw ((zfs_oldace_t *)acep)->z_fuid = who; 142*5331Samw } 143*5331Samw 144*5331Samw /*ARGSUSED*/ 145*5331Samw static size_t 146*5331Samw zfs_ace_v0_size(void *acep) 147*5331Samw { 148*5331Samw return (sizeof (zfs_oldace_t)); 149*5331Samw } 150*5331Samw 151*5331Samw static size_t 152*5331Samw zfs_ace_v0_abstract_size(void) 153*5331Samw { 154*5331Samw return (sizeof (zfs_oldace_t)); 155*5331Samw } 156*5331Samw 157*5331Samw static int 158*5331Samw zfs_ace_v0_mask_off(void) 159*5331Samw { 160*5331Samw return (offsetof(zfs_oldace_t, z_access_mask)); 161*5331Samw } 162*5331Samw 163*5331Samw /*ARGSUSED*/ 164*5331Samw static int 165*5331Samw zfs_ace_v0_data(void *acep, void **datap) 166*5331Samw { 167*5331Samw *datap = NULL; 168*5331Samw return (0); 169*5331Samw } 170*5331Samw 171*5331Samw static acl_ops_t zfs_acl_v0_ops = { 172*5331Samw zfs_ace_v0_get_mask, 173*5331Samw zfs_ace_v0_set_mask, 174*5331Samw zfs_ace_v0_get_flags, 175*5331Samw zfs_ace_v0_set_flags, 176*5331Samw zfs_ace_v0_get_type, 177*5331Samw zfs_ace_v0_set_type, 178*5331Samw zfs_ace_v0_get_who, 179*5331Samw zfs_ace_v0_set_who, 180*5331Samw zfs_ace_v0_size, 181*5331Samw zfs_ace_v0_abstract_size, 182*5331Samw zfs_ace_v0_mask_off, 183*5331Samw zfs_ace_v0_data 184*5331Samw }; 185*5331Samw 186*5331Samw static uint16_t 187*5331Samw zfs_ace_fuid_get_type(void *acep) 188*5331Samw { 189*5331Samw return (((zfs_ace_hdr_t *)acep)->z_type); 190*5331Samw } 191*5331Samw 192*5331Samw static uint16_t 193*5331Samw zfs_ace_fuid_get_flags(void *acep) 194*5331Samw { 195*5331Samw return (((zfs_ace_hdr_t *)acep)->z_flags); 196*5331Samw } 197*5331Samw 198*5331Samw static uint32_t 199*5331Samw zfs_ace_fuid_get_mask(void *acep) 200*5331Samw { 201*5331Samw return (((zfs_ace_hdr_t *)acep)->z_access_mask); 202*5331Samw } 203*5331Samw 204*5331Samw static uint64_t 205*5331Samw zfs_ace_fuid_get_who(void *args) 206*5331Samw { 207*5331Samw uint16_t entry_type; 208*5331Samw zfs_ace_t *acep = args; 209*5331Samw 210*5331Samw entry_type = acep->z_hdr.z_flags & ACE_TYPE_FLAGS; 211789Sahrens 212*5331Samw if (entry_type == ACE_OWNER || entry_type == OWNING_GROUP || 213*5331Samw entry_type == ACE_EVERYONE) 214*5331Samw return (-1); 215*5331Samw return (((zfs_ace_t *)acep)->z_fuid); 216*5331Samw } 217*5331Samw 218*5331Samw static void 219*5331Samw zfs_ace_fuid_set_type(void *acep, uint16_t type) 220*5331Samw { 221*5331Samw ((zfs_ace_hdr_t *)acep)->z_type = type; 222*5331Samw } 223*5331Samw 224*5331Samw static void 225*5331Samw zfs_ace_fuid_set_flags(void *acep, uint16_t flags) 226*5331Samw { 227*5331Samw ((zfs_ace_hdr_t *)acep)->z_flags = flags; 228*5331Samw } 229*5331Samw 230*5331Samw static void 231*5331Samw zfs_ace_fuid_set_mask(void *acep, uint32_t mask) 232*5331Samw { 233*5331Samw ((zfs_ace_hdr_t *)acep)->z_access_mask = mask; 234*5331Samw } 235*5331Samw 236*5331Samw static void 237*5331Samw zfs_ace_fuid_set_who(void *arg, uint64_t who) 238*5331Samw { 239*5331Samw zfs_ace_t *acep = arg; 240*5331Samw 241*5331Samw uint16_t entry_type = acep->z_hdr.z_flags & ACE_TYPE_FLAGS; 242*5331Samw 243*5331Samw if (entry_type == ACE_OWNER || entry_type == OWNING_GROUP || 244*5331Samw entry_type == ACE_EVERYONE) 245*5331Samw return; 246*5331Samw acep->z_fuid = who; 247*5331Samw } 248*5331Samw 249*5331Samw static size_t 250*5331Samw zfs_ace_fuid_size(void *acep) 251*5331Samw { 252*5331Samw zfs_ace_hdr_t *zacep = acep; 253*5331Samw uint16_t entry_type; 254*5331Samw 255*5331Samw switch (zacep->z_type) { 256*5331Samw case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 257*5331Samw case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 258*5331Samw case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 259*5331Samw case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 260*5331Samw return (sizeof (zfs_object_ace_t)); 261*5331Samw case ALLOW: 262*5331Samw case DENY: 263*5331Samw entry_type = 264*5331Samw (((zfs_ace_hdr_t *)acep)->z_flags & ACE_TYPE_FLAGS); 265*5331Samw if (entry_type == ACE_OWNER || 266*5331Samw entry_type == (ACE_GROUP | ACE_IDENTIFIER_GROUP) || 267*5331Samw entry_type == ACE_EVERYONE) 268*5331Samw return (sizeof (zfs_ace_hdr_t)); 269*5331Samw /*FALLTHROUGH*/ 270*5331Samw default: 271*5331Samw return (sizeof (zfs_ace_t)); 272*5331Samw } 273*5331Samw } 274*5331Samw 275*5331Samw static size_t 276*5331Samw zfs_ace_fuid_abstract_size(void) 277*5331Samw { 278*5331Samw return (sizeof (zfs_ace_hdr_t)); 279*5331Samw } 280*5331Samw 281*5331Samw static int 282*5331Samw zfs_ace_fuid_mask_off(void) 283*5331Samw { 284*5331Samw return (offsetof(zfs_ace_hdr_t, z_access_mask)); 285*5331Samw } 286*5331Samw 287*5331Samw static int 288*5331Samw zfs_ace_fuid_data(void *acep, void **datap) 289*5331Samw { 290*5331Samw zfs_ace_t *zacep = acep; 291*5331Samw zfs_object_ace_t *zobjp; 292*5331Samw 293*5331Samw switch (zacep->z_hdr.z_type) { 294*5331Samw case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 295*5331Samw case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 296*5331Samw case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 297*5331Samw case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 298*5331Samw zobjp = acep; 299*5331Samw *datap = (caddr_t)zobjp + sizeof (zfs_ace_t); 300*5331Samw return (sizeof (zfs_object_ace_t) - sizeof (zfs_ace_t)); 301*5331Samw default: 302*5331Samw *datap = NULL; 303*5331Samw return (0); 304*5331Samw } 305*5331Samw } 306*5331Samw 307*5331Samw static acl_ops_t zfs_acl_fuid_ops = { 308*5331Samw zfs_ace_fuid_get_mask, 309*5331Samw zfs_ace_fuid_set_mask, 310*5331Samw zfs_ace_fuid_get_flags, 311*5331Samw zfs_ace_fuid_set_flags, 312*5331Samw zfs_ace_fuid_get_type, 313*5331Samw zfs_ace_fuid_set_type, 314*5331Samw zfs_ace_fuid_get_who, 315*5331Samw zfs_ace_fuid_set_who, 316*5331Samw zfs_ace_fuid_size, 317*5331Samw zfs_ace_fuid_abstract_size, 318*5331Samw zfs_ace_fuid_mask_off, 319*5331Samw zfs_ace_fuid_data 320*5331Samw }; 321*5331Samw 322*5331Samw static int 323*5331Samw zfs_acl_version(int version) 324*5331Samw { 325*5331Samw if (version < ZPL_VERSION_FUID) 326*5331Samw return (ZFS_ACL_VERSION_INITIAL); 327*5331Samw else 328*5331Samw return (ZFS_ACL_VERSION_FUID); 329*5331Samw } 330*5331Samw 331*5331Samw static int 332*5331Samw zfs_acl_version_zp(znode_t *zp) 333*5331Samw { 334*5331Samw return (zfs_acl_version(zp->z_zfsvfs->z_version)); 335*5331Samw } 336789Sahrens 337789Sahrens static zfs_acl_t * 338*5331Samw zfs_acl_alloc(int vers) 339789Sahrens { 340789Sahrens zfs_acl_t *aclp; 341789Sahrens 342789Sahrens aclp = kmem_zalloc(sizeof (zfs_acl_t), KM_SLEEP); 343*5331Samw list_create(&aclp->z_acl, sizeof (zfs_acl_node_t), 344*5331Samw offsetof(zfs_acl_node_t, z_next)); 345*5331Samw aclp->z_version = vers; 346*5331Samw if (vers == ZFS_ACL_VERSION_FUID) 347*5331Samw aclp->z_ops = zfs_acl_fuid_ops; 348*5331Samw else 349*5331Samw aclp->z_ops = zfs_acl_v0_ops; 350*5331Samw return (aclp); 351*5331Samw } 352*5331Samw 353*5331Samw static zfs_acl_node_t * 354*5331Samw zfs_acl_node_alloc(size_t bytes) 355*5331Samw { 356*5331Samw zfs_acl_node_t *aclnode; 357*5331Samw 358*5331Samw aclnode = kmem_zalloc(sizeof (zfs_acl_node_t), KM_SLEEP); 359*5331Samw if (bytes) { 360*5331Samw aclnode->z_acldata = kmem_alloc(bytes, KM_SLEEP); 361*5331Samw aclnode->z_allocdata = aclnode->z_acldata; 362*5331Samw aclnode->z_allocsize = bytes; 363*5331Samw aclnode->z_size = bytes; 364789Sahrens } 365*5331Samw 366*5331Samw return (aclnode); 367*5331Samw } 368*5331Samw 369*5331Samw static void 370*5331Samw zfs_acl_node_free(zfs_acl_node_t *aclnode) 371*5331Samw { 372*5331Samw if (aclnode->z_allocsize) 373*5331Samw kmem_free(aclnode->z_allocdata, aclnode->z_allocsize); 374*5331Samw kmem_free(aclnode, sizeof (zfs_acl_node_t)); 375789Sahrens } 376789Sahrens 377789Sahrens void 378789Sahrens zfs_acl_free(zfs_acl_t *aclp) 379789Sahrens { 380*5331Samw zfs_acl_node_t *aclnode; 381*5331Samw 382*5331Samw while (aclnode = list_head(&aclp->z_acl)) { 383*5331Samw list_remove(&aclp->z_acl, aclnode); 384*5331Samw zfs_acl_node_free(aclnode); 385789Sahrens } 386*5331Samw 387*5331Samw list_destroy(&aclp->z_acl); 388789Sahrens kmem_free(aclp, sizeof (zfs_acl_t)); 389789Sahrens } 390789Sahrens 391*5331Samw static boolean_t 392*5331Samw zfs_ace_valid(vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags) 393789Sahrens { 394*5331Samw /* 395*5331Samw * first check type of entry 396*5331Samw */ 397*5331Samw 398*5331Samw switch (iflags & ACE_TYPE_FLAGS) { 399*5331Samw case ACE_OWNER: 400*5331Samw case (ACE_IDENTIFIER_GROUP | ACE_GROUP): 401*5331Samw case ACE_IDENTIFIER_GROUP: 402*5331Samw case ACE_EVERYONE: 403*5331Samw case 0: /* User entry */ 404*5331Samw break; 405*5331Samw default: 406*5331Samw return (B_FALSE); 407*5331Samw 408*5331Samw } 409*5331Samw 410*5331Samw /* 411*5331Samw * next check inheritance level flags 412*5331Samw */ 413*5331Samw 414*5331Samw if (type != ALLOW && type > MAX_ACE_TYPE) { 415*5331Samw return (B_FALSE); 416*5331Samw } 417*5331Samw 418*5331Samw switch (type) { 419*5331Samw case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 420*5331Samw case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 421*5331Samw case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 422*5331Samw case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 423*5331Samw if (aclp->z_version < ZFS_ACL_VERSION_FUID) 424*5331Samw return (B_FALSE); 425*5331Samw aclp->z_hints |= ZFS_ACL_OBJ_ACE; 426*5331Samw } 427789Sahrens 4281576Smarks /* 429*5331Samw * Only directories should have inheritance flags. 4301576Smarks */ 431*5331Samw if (obj_type != VDIR && (iflags & 432*5331Samw (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE| 433*5331Samw ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE))) { 434*5331Samw return (B_FALSE); 435*5331Samw } 436*5331Samw 437*5331Samw if (iflags & (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE)) 438*5331Samw aclp->z_hints |= ZFS_INHERIT_ACE; 439*5331Samw 440*5331Samw if (iflags & (ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE)) { 441*5331Samw if ((iflags & (ACE_FILE_INHERIT_ACE| 442*5331Samw ACE_DIRECTORY_INHERIT_ACE)) == 0) { 443*5331Samw return (B_FALSE); 444*5331Samw } 445*5331Samw } 446*5331Samw 447*5331Samw return (B_TRUE); 448*5331Samw } 449*5331Samw 450*5331Samw static void * 451*5331Samw zfs_acl_next_ace(zfs_acl_t *aclp, void *start, uint64_t *who, 452*5331Samw uint32_t *access_mask, uint16_t *iflags, uint16_t *type) 453*5331Samw { 454*5331Samw zfs_acl_node_t *aclnode; 455*5331Samw 456*5331Samw if (start == NULL) { 457*5331Samw aclnode = list_head(&aclp->z_acl); 458*5331Samw if (aclnode == NULL) 459*5331Samw return (NULL); 460*5331Samw 461*5331Samw aclp->z_next_ace = aclnode->z_acldata; 462*5331Samw aclp->z_curr_node = aclnode; 463*5331Samw aclnode->z_ace_idx = 0; 464*5331Samw } 465*5331Samw 466*5331Samw aclnode = aclp->z_curr_node; 467*5331Samw 468*5331Samw if (aclnode == NULL) 469*5331Samw return (NULL); 470*5331Samw 471*5331Samw if (aclnode->z_ace_idx >= aclnode->z_ace_count) { 472*5331Samw aclnode = list_next(&aclp->z_acl, aclnode); 473*5331Samw if (aclnode == NULL) 474*5331Samw return (NULL); 475*5331Samw else { 476*5331Samw aclp->z_curr_node = aclnode; 477*5331Samw aclnode->z_ace_idx = 0; 478*5331Samw aclp->z_next_ace = aclnode->z_acldata; 479*5331Samw } 480*5331Samw } 481*5331Samw 482*5331Samw if (aclnode->z_ace_idx < aclnode->z_ace_count) { 483*5331Samw void *acep = aclp->z_next_ace; 484*5331Samw *iflags = aclp->z_ops.ace_flags_get(acep); 485*5331Samw *type = aclp->z_ops.ace_type_get(acep); 486*5331Samw *access_mask = aclp->z_ops.ace_mask_get(acep); 487*5331Samw *who = aclp->z_ops.ace_who_get(acep); 488*5331Samw aclp->z_next_ace = (caddr_t)aclp->z_next_ace + 489*5331Samw aclp->z_ops.ace_size(acep); 490*5331Samw aclnode->z_ace_idx++; 491*5331Samw return ((void *)acep); 492*5331Samw } 493*5331Samw return (NULL); 494*5331Samw } 495*5331Samw 496*5331Samw /*ARGSUSED*/ 497*5331Samw static uint64_t 498*5331Samw zfs_ace_walk(void *datap, uint64_t cookie, int aclcnt, 499*5331Samw uint16_t *flags, uint16_t *type, uint32_t *mask) 500*5331Samw { 501*5331Samw zfs_acl_t *aclp = datap; 502*5331Samw zfs_ace_hdr_t *acep = (zfs_ace_hdr_t *)(uintptr_t)cookie; 503*5331Samw uint64_t who; 504*5331Samw 505*5331Samw acep = zfs_acl_next_ace(aclp, acep, &who, mask, 506*5331Samw flags, type); 507*5331Samw return ((uint64_t)(uintptr_t)acep); 508*5331Samw } 509*5331Samw 510*5331Samw static zfs_acl_node_t * 511*5331Samw zfs_acl_curr_node(zfs_acl_t *aclp) 512*5331Samw { 513*5331Samw ASSERT(aclp->z_curr_node); 514*5331Samw return (aclp->z_curr_node); 515*5331Samw } 516*5331Samw 517*5331Samw /* 518*5331Samw * Copy ACE to internal ZFS format. 519*5331Samw * While processing the ACL each ACE will be validated for correctness. 520*5331Samw * ACE FUIDs will be created later. 521*5331Samw */ 522*5331Samw int 523*5331Samw zfs_copy_ace_2_fuid(vtype_t obj_type, zfs_acl_t *aclp, void *datap, 524*5331Samw zfs_ace_t *z_acl, int aclcnt, size_t *size) 525*5331Samw { 526*5331Samw int i; 527*5331Samw uint16_t entry_type; 528*5331Samw zfs_ace_t *aceptr = z_acl; 529*5331Samw ace_t *acep = datap; 530*5331Samw zfs_object_ace_t *zobjacep; 531*5331Samw ace_object_t *aceobjp; 532*5331Samw 533*5331Samw for (i = 0; i != aclcnt; i++) { 534*5331Samw aceptr->z_hdr.z_access_mask = acep->a_access_mask; 535*5331Samw aceptr->z_hdr.z_flags = acep->a_flags; 536*5331Samw aceptr->z_hdr.z_type = acep->a_type; 537*5331Samw entry_type = aceptr->z_hdr.z_flags & ACE_TYPE_FLAGS; 538*5331Samw if (entry_type != ACE_OWNER && entry_type != OWNING_GROUP && 539*5331Samw entry_type != ACE_EVERYONE) 540*5331Samw aceptr->z_fuid = (uint64_t)acep->a_who; 541*5331Samw /* 542*5331Samw * Make sure ACE is valid 543*5331Samw */ 544*5331Samw if (zfs_ace_valid(obj_type, aclp, aceptr->z_hdr.z_type, 545*5331Samw aceptr->z_hdr.z_flags) != B_TRUE) 546*5331Samw return (EINVAL); 547*5331Samw 548*5331Samw switch (acep->a_type) { 549*5331Samw case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 550*5331Samw case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 551*5331Samw case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 552*5331Samw case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 553*5331Samw zobjacep = (zfs_object_ace_t *)aceptr; 554*5331Samw aceobjp = (ace_object_t *)acep; 555*5331Samw 556*5331Samw bcopy(aceobjp->a_obj_type, zobjacep->z_object_type, 557*5331Samw sizeof (aceobjp->a_obj_type)); 558*5331Samw bcopy(aceobjp->a_inherit_obj_type, 559*5331Samw zobjacep->z_inherit_type, 560*5331Samw sizeof (aceobjp->a_inherit_obj_type)); 561*5331Samw acep = (ace_t *)((caddr_t)acep + sizeof (ace_object_t)); 562*5331Samw break; 563*5331Samw default: 564*5331Samw acep = (ace_t *)((caddr_t)acep + sizeof (ace_t)); 565*5331Samw } 566*5331Samw 567*5331Samw aceptr = (zfs_ace_t *)((caddr_t)aceptr + 568*5331Samw aclp->z_ops.ace_size(aceptr)); 569*5331Samw } 570*5331Samw 571*5331Samw *size = (caddr_t)aceptr - (caddr_t)z_acl; 572789Sahrens 573*5331Samw return (0); 574*5331Samw } 575*5331Samw 576*5331Samw /* 577*5331Samw * Copy ZFS ACEs to fixed size ace_t layout 578*5331Samw */ 579*5331Samw static void 580*5331Samw zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *datap, int filter) 581*5331Samw { 582*5331Samw uint64_t who; 583*5331Samw uint32_t access_mask; 584*5331Samw uint16_t iflags, type; 585*5331Samw zfs_ace_hdr_t *zacep = NULL; 586*5331Samw ace_t *acep = datap; 587*5331Samw ace_object_t *objacep; 588*5331Samw zfs_object_ace_t *zobjacep; 589*5331Samw zfs_fuid_hdl_t hdl = { 0 }; 590*5331Samw size_t ace_size; 591*5331Samw uint16_t entry_type; 592*5331Samw 593*5331Samw while (zacep = zfs_acl_next_ace(aclp, zacep, 594*5331Samw &who, &access_mask, &iflags, &type)) { 595*5331Samw 596*5331Samw switch (type) { 597*5331Samw case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 598*5331Samw case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 599*5331Samw case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 600*5331Samw case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 601*5331Samw if (filter) { 602*5331Samw continue; 603*5331Samw } 604*5331Samw zobjacep = (zfs_object_ace_t *)zacep; 605*5331Samw objacep = (ace_object_t *)acep; 606*5331Samw bcopy(zobjacep->z_object_type, 607*5331Samw objacep->a_obj_type, 608*5331Samw sizeof (zobjacep->z_object_type)); 609*5331Samw bcopy(zobjacep->z_inherit_type, 610*5331Samw objacep->a_inherit_obj_type, 611*5331Samw sizeof (zobjacep->z_inherit_type)); 612*5331Samw ace_size = sizeof (ace_object_t); 613*5331Samw break; 614*5331Samw default: 615*5331Samw ace_size = sizeof (ace_t); 616*5331Samw break; 617*5331Samw } 618*5331Samw 619*5331Samw entry_type = (iflags & ACE_TYPE_FLAGS); 620*5331Samw if ((entry_type != ACE_OWNER && 621*5331Samw entry_type != (ACE_GROUP | ACE_IDENTIFIER_GROUP) && 622*5331Samw entry_type != ACE_EVERYONE)) 623*5331Samw zfs_fuid_queue_map_id(zfsvfs, &hdl, who, 624*5331Samw (entry_type & ACE_IDENTIFIER_GROUP) ? 625*5331Samw ZFS_ACE_GROUP : ZFS_ACE_USER, &acep->a_who); 626*5331Samw else 627*5331Samw acep->a_who = (uid_t)(int64_t)who; 628*5331Samw acep->a_access_mask = access_mask; 629*5331Samw acep->a_flags = iflags; 630*5331Samw acep->a_type = type; 631*5331Samw acep = (ace_t *)((caddr_t)acep + ace_size); 632*5331Samw } 633*5331Samw zfs_fuid_get_mappings(&hdl); 634*5331Samw } 635*5331Samw 636*5331Samw static int 637*5331Samw zfs_copy_ace_2_oldace(vtype_t obj_type, zfs_acl_t *aclp, ace_t *acep, 638*5331Samw zfs_oldace_t *z_acl, int aclcnt, size_t *size) 639*5331Samw { 640*5331Samw int i; 641*5331Samw zfs_oldace_t *aceptr = z_acl; 642*5331Samw 643*5331Samw for (i = 0; i != aclcnt; i++, aceptr++) { 644*5331Samw aceptr->z_access_mask = acep[i].a_access_mask; 645*5331Samw aceptr->z_type = acep[i].a_type; 646*5331Samw aceptr->z_flags = acep[i].a_flags; 647*5331Samw aceptr->z_fuid = acep[i].a_who; 648*5331Samw /* 649*5331Samw * Make sure ACE is valid 650*5331Samw */ 651*5331Samw if (zfs_ace_valid(obj_type, aclp, aceptr->z_type, 652*5331Samw aceptr->z_flags) != B_TRUE) 653*5331Samw return (EINVAL); 654*5331Samw } 655*5331Samw *size = (caddr_t)aceptr - (caddr_t)z_acl; 656*5331Samw return (0); 657*5331Samw } 658*5331Samw 659*5331Samw /* 660*5331Samw * convert old ACL format to new 661*5331Samw */ 662*5331Samw void 663*5331Samw zfs_acl_xform(znode_t *zp, zfs_acl_t *aclp) 664*5331Samw { 665*5331Samw zfs_oldace_t *oldaclp; 666*5331Samw int i; 667*5331Samw uint16_t type, iflags; 668*5331Samw uint32_t access_mask; 669*5331Samw uint64_t who; 670*5331Samw void *cookie = NULL; 671*5331Samw zfs_acl_node_t *aclnode, *newaclnode; 672*5331Samw 673*5331Samw ASSERT(aclp->z_version == ZFS_ACL_VERSION_INITIAL); 674*5331Samw /* 675*5331Samw * First create the ACE in a contiguous piece of memory 676*5331Samw * for zfs_copy_ace_2_fuid(). 677*5331Samw * 678*5331Samw * We only convert an ACL once, so this won't happen 679*5331Samw * everytime. 680*5331Samw */ 681*5331Samw oldaclp = kmem_alloc(sizeof (zfs_oldace_t) * aclp->z_acl_count, 682*5331Samw KM_SLEEP); 683*5331Samw i = 0; 684*5331Samw while (cookie = zfs_acl_next_ace(aclp, cookie, &who, 685*5331Samw &access_mask, &iflags, &type)) { 686*5331Samw oldaclp[i].z_flags = iflags; 687*5331Samw oldaclp[i].z_type = type; 688*5331Samw oldaclp[i].z_fuid = who; 689*5331Samw oldaclp[i++].z_access_mask = access_mask; 690*5331Samw } 691*5331Samw 692*5331Samw newaclnode = zfs_acl_node_alloc(aclp->z_acl_count * 693*5331Samw sizeof (zfs_object_ace_t)); 694*5331Samw aclp->z_ops = zfs_acl_fuid_ops; 695*5331Samw VERIFY(zfs_copy_ace_2_fuid(ZTOV(zp)->v_type, aclp, oldaclp, 696*5331Samw newaclnode->z_acldata, aclp->z_acl_count, 697*5331Samw &newaclnode->z_size) == 0); 698*5331Samw aclp->z_acl_bytes = newaclnode->z_size; 699*5331Samw newaclnode->z_ace_count = aclp->z_acl_count; 700*5331Samw aclp->z_version = ZFS_ACL_VERSION; 701*5331Samw kmem_free(oldaclp, aclp->z_acl_count * sizeof (zfs_oldace_t)); 702*5331Samw 703*5331Samw /* 704*5331Samw * Release all previous ACL nodes 705*5331Samw */ 706*5331Samw 707*5331Samw while (aclnode = list_head(&aclp->z_acl)) { 708*5331Samw list_remove(&aclp->z_acl, aclnode); 709*5331Samw if (aclnode->z_allocsize) 710*5331Samw kmem_free(aclnode->z_allocdata, aclnode->z_allocsize); 711*5331Samw kmem_free(aclnode, sizeof (zfs_acl_node_t)); 712*5331Samw } 713*5331Samw list_insert_head(&aclp->z_acl, newaclnode); 714789Sahrens } 715789Sahrens 716789Sahrens /* 717789Sahrens * Convert unix access mask to v4 access mask 718789Sahrens */ 719789Sahrens static uint32_t 720789Sahrens zfs_unix_to_v4(uint32_t access_mask) 721789Sahrens { 722789Sahrens uint32_t new_mask = 0; 723789Sahrens 724*5331Samw if (access_mask & S_IXOTH) 725*5331Samw new_mask |= ACE_EXECUTE; 726*5331Samw if (access_mask & S_IWOTH) 727*5331Samw new_mask |= ACE_WRITE_DATA; 728*5331Samw if (access_mask & S_IROTH) 729789Sahrens new_mask |= ACE_READ_DATA; 730789Sahrens return (new_mask); 731789Sahrens } 732789Sahrens 733789Sahrens static void 734*5331Samw zfs_set_ace(zfs_acl_t *aclp, void *acep, uint32_t access_mask, 735*5331Samw uint16_t access_type, uint64_t fuid, uint16_t entry_type) 736789Sahrens { 737*5331Samw uint16_t type = entry_type & ACE_TYPE_FLAGS; 738*5331Samw 739*5331Samw aclp->z_ops.ace_mask_set(acep, access_mask); 740*5331Samw aclp->z_ops.ace_type_set(acep, access_type); 741*5331Samw aclp->z_ops.ace_flags_set(acep, entry_type); 742*5331Samw if ((type != ACE_OWNER && type != (ACE_GROUP | ACE_IDENTIFIER_GROUP) && 743*5331Samw type != ACE_EVERYONE)) 744*5331Samw aclp->z_ops.ace_who_set(acep, fuid); 745789Sahrens } 746789Sahrens 747*5331Samw /* 748*5331Samw * Determine mode of file based on ACL. 749*5331Samw * Also, create FUIDs for any User/Group ACEs 750*5331Samw */ 751789Sahrens static uint64_t 752*5331Samw zfs_mode_fuid_compute(znode_t *zp, zfs_acl_t *aclp, zfs_fuid_info_t **fuidp, 753*5331Samw dmu_tx_t *tx) 754789Sahrens { 755*5331Samw int entry_type; 756*5331Samw mode_t mode; 757*5331Samw mode_t seen = 0; 758*5331Samw zfs_ace_hdr_t *acep = NULL; 759*5331Samw uint64_t who; 760*5331Samw uint16_t iflags, type; 761*5331Samw uint32_t access_mask; 762789Sahrens 763*5331Samw mode = (zp->z_phys->zp_mode & (S_IFMT | S_ISUID | S_ISGID | S_ISVTX)); 764*5331Samw 765*5331Samw while (acep = zfs_acl_next_ace(aclp, acep, &who, 766*5331Samw &access_mask, &iflags, &type)) { 767*5331Samw entry_type = (iflags & ACE_TYPE_FLAGS); 7684869Smarks 7694869Smarks /* 7704869Smarks * Skip over inherit only ACEs 7714869Smarks */ 772*5331Samw if (entry_type == ACE_INHERIT_ONLY_ACE) 7734869Smarks continue; 7744869Smarks 775789Sahrens if (entry_type == ACE_OWNER) { 776*5331Samw if ((access_mask & ACE_READ_DATA) && 777789Sahrens (!(seen & S_IRUSR))) { 778789Sahrens seen |= S_IRUSR; 779*5331Samw if (type == ALLOW) { 780789Sahrens mode |= S_IRUSR; 781789Sahrens } 782789Sahrens } 783*5331Samw if ((access_mask & ACE_WRITE_DATA) && 784789Sahrens (!(seen & S_IWUSR))) { 785789Sahrens seen |= S_IWUSR; 786*5331Samw if (type == ALLOW) { 787789Sahrens mode |= S_IWUSR; 788789Sahrens } 789789Sahrens } 790*5331Samw if ((access_mask & ACE_EXECUTE) && 791789Sahrens (!(seen & S_IXUSR))) { 792789Sahrens seen |= S_IXUSR; 793*5331Samw if (type == ALLOW) { 794789Sahrens mode |= S_IXUSR; 795789Sahrens } 796789Sahrens } 797789Sahrens } else if (entry_type == OWNING_GROUP) { 798*5331Samw if ((access_mask & ACE_READ_DATA) && 799789Sahrens (!(seen & S_IRGRP))) { 800789Sahrens seen |= S_IRGRP; 801*5331Samw if (type == ALLOW) { 802789Sahrens mode |= S_IRGRP; 803789Sahrens } 804789Sahrens } 805*5331Samw if ((access_mask & ACE_WRITE_DATA) && 806789Sahrens (!(seen & S_IWGRP))) { 807789Sahrens seen |= S_IWGRP; 808*5331Samw if (type == ALLOW) { 809789Sahrens mode |= S_IWGRP; 810789Sahrens } 811789Sahrens } 812*5331Samw if ((access_mask & ACE_EXECUTE) && 813789Sahrens (!(seen & S_IXGRP))) { 814789Sahrens seen |= S_IXGRP; 815*5331Samw if (type == ALLOW) { 816789Sahrens mode |= S_IXGRP; 817789Sahrens } 818789Sahrens } 819789Sahrens } else if (entry_type == ACE_EVERYONE) { 820*5331Samw if ((access_mask & ACE_READ_DATA)) { 821789Sahrens if (!(seen & S_IRUSR)) { 822789Sahrens seen |= S_IRUSR; 823*5331Samw if (type == ALLOW) { 824789Sahrens mode |= S_IRUSR; 825789Sahrens } 826789Sahrens } 827789Sahrens if (!(seen & S_IRGRP)) { 828789Sahrens seen |= S_IRGRP; 829*5331Samw if (type == ALLOW) { 830789Sahrens mode |= S_IRGRP; 831789Sahrens } 832789Sahrens } 833789Sahrens if (!(seen & S_IROTH)) { 834789Sahrens seen |= S_IROTH; 835*5331Samw if (type == ALLOW) { 836789Sahrens mode |= S_IROTH; 837789Sahrens } 838789Sahrens } 839789Sahrens } 840*5331Samw if ((access_mask & ACE_WRITE_DATA)) { 841789Sahrens if (!(seen & S_IWUSR)) { 842789Sahrens seen |= S_IWUSR; 843*5331Samw if (type == ALLOW) { 844789Sahrens mode |= S_IWUSR; 845789Sahrens } 846789Sahrens } 847789Sahrens if (!(seen & S_IWGRP)) { 848789Sahrens seen |= S_IWGRP; 849*5331Samw if (type == ALLOW) { 850789Sahrens mode |= S_IWGRP; 851789Sahrens } 852789Sahrens } 853789Sahrens if (!(seen & S_IWOTH)) { 854789Sahrens seen |= S_IWOTH; 855*5331Samw if (type == ALLOW) { 856789Sahrens mode |= S_IWOTH; 857789Sahrens } 858789Sahrens } 859789Sahrens } 860*5331Samw if ((access_mask & ACE_EXECUTE)) { 861789Sahrens if (!(seen & S_IXUSR)) { 862789Sahrens seen |= S_IXUSR; 863*5331Samw if (type == ALLOW) { 864789Sahrens mode |= S_IXUSR; 865789Sahrens } 866789Sahrens } 867789Sahrens if (!(seen & S_IXGRP)) { 868789Sahrens seen |= S_IXGRP; 869*5331Samw if (type == ALLOW) { 870789Sahrens mode |= S_IXGRP; 871789Sahrens } 872789Sahrens } 873789Sahrens if (!(seen & S_IXOTH)) { 874789Sahrens seen |= S_IXOTH; 875*5331Samw if (type == ALLOW) { 876789Sahrens mode |= S_IXOTH; 877789Sahrens } 878789Sahrens } 879789Sahrens } 880789Sahrens } 881*5331Samw /* 882*5331Samw * Now handle FUID create for user/group ACEs 883*5331Samw */ 884*5331Samw if (entry_type == 0 || entry_type == ACE_IDENTIFIER_GROUP) { 885*5331Samw aclp->z_ops.ace_who_set(acep, 886*5331Samw zfs_fuid_create(zp->z_zfsvfs, who, 887*5331Samw entry_type == 0 ? ZFS_ACE_USER : ZFS_ACE_GROUP, tx, 888*5331Samw fuidp)); 889*5331Samw } 890789Sahrens } 891789Sahrens return (mode); 892789Sahrens } 893789Sahrens 894789Sahrens static zfs_acl_t * 895*5331Samw zfs_acl_node_read_internal(znode_t *zp, boolean_t will_modify) 896789Sahrens { 897789Sahrens zfs_acl_t *aclp; 898*5331Samw zfs_acl_node_t *aclnode; 899789Sahrens 900*5331Samw aclp = zfs_acl_alloc(zp->z_phys->zp_acl.z_acl_version); 901*5331Samw 902*5331Samw /* 903*5331Samw * Version 0 to 1 znode_acl_phys has the size/count fields swapped. 904*5331Samw * Version 0 didn't have a size field, only a count. 905*5331Samw */ 906*5331Samw if (zp->z_phys->zp_acl.z_acl_version == ZFS_ACL_VERSION_INITIAL) { 907*5331Samw aclp->z_acl_count = zp->z_phys->zp_acl.z_acl_size; 908*5331Samw aclp->z_acl_bytes = ZFS_ACL_SIZE(aclp->z_acl_count); 909*5331Samw } else { 910*5331Samw aclp->z_acl_count = zp->z_phys->zp_acl.z_acl_count; 911*5331Samw aclp->z_acl_bytes = zp->z_phys->zp_acl.z_acl_size; 912*5331Samw } 913*5331Samw 914*5331Samw aclnode = zfs_acl_node_alloc(will_modify ? aclp->z_acl_bytes : 0); 915*5331Samw aclnode->z_ace_count = aclp->z_acl_count; 916*5331Samw if (will_modify) { 917*5331Samw bcopy(zp->z_phys->zp_acl.z_ace_data, aclnode->z_acldata, 918*5331Samw aclp->z_acl_bytes); 919*5331Samw } else { 920*5331Samw aclnode->z_size = aclp->z_acl_bytes; 921*5331Samw aclnode->z_acldata = &zp->z_phys->zp_acl.z_ace_data[0]; 922*5331Samw } 923*5331Samw 924*5331Samw list_insert_head(&aclp->z_acl, aclnode); 925789Sahrens 926789Sahrens return (aclp); 927789Sahrens } 928789Sahrens 929789Sahrens /* 930789Sahrens * Read an external acl object. 931789Sahrens */ 9321544Seschrock static int 933*5331Samw zfs_acl_node_read(znode_t *zp, zfs_acl_t **aclpp, boolean_t will_modify) 934789Sahrens { 935789Sahrens uint64_t extacl = zp->z_phys->zp_acl.z_acl_extern_obj; 936789Sahrens zfs_acl_t *aclp; 937*5331Samw size_t aclsize; 938*5331Samw size_t acl_count; 939*5331Samw zfs_acl_node_t *aclnode; 9401544Seschrock int error; 941789Sahrens 942789Sahrens ASSERT(MUTEX_HELD(&zp->z_acl_lock)); 943789Sahrens 9441544Seschrock if (zp->z_phys->zp_acl.z_acl_extern_obj == 0) { 945*5331Samw *aclpp = zfs_acl_node_read_internal(zp, will_modify); 9461544Seschrock return (0); 9471544Seschrock } 948789Sahrens 949*5331Samw aclp = zfs_acl_alloc(zp->z_phys->zp_acl.z_acl_version); 950*5331Samw if (zp->z_phys->zp_acl.z_acl_version == ZFS_ACL_VERSION_INITIAL) { 951*5331Samw zfs_acl_phys_v0_t *zacl0 = 952*5331Samw (zfs_acl_phys_v0_t *)&zp->z_phys->zp_acl; 953789Sahrens 954*5331Samw aclsize = ZFS_ACL_SIZE(zacl0->z_acl_count); 955*5331Samw acl_count = zacl0->z_acl_count; 956*5331Samw } else { 957*5331Samw aclsize = zp->z_phys->zp_acl.z_acl_size; 958*5331Samw acl_count = zp->z_phys->zp_acl.z_acl_count; 959*5331Samw if (aclsize == 0) 960*5331Samw aclsize = acl_count * sizeof (zfs_ace_t); 961*5331Samw } 962*5331Samw aclnode = zfs_acl_node_alloc(aclsize); 963*5331Samw list_insert_head(&aclp->z_acl, aclnode); 9641544Seschrock error = dmu_read(zp->z_zfsvfs->z_os, extacl, 0, 965*5331Samw aclsize, aclnode->z_acldata); 966*5331Samw aclnode->z_ace_count = acl_count; 967*5331Samw aclp->z_acl_count = acl_count; 968*5331Samw aclp->z_acl_bytes = aclsize; 969*5331Samw 9701544Seschrock if (error != 0) { 9711544Seschrock zfs_acl_free(aclp); 9721544Seschrock return (error); 9731544Seschrock } 974789Sahrens 9751544Seschrock *aclpp = aclp; 9761544Seschrock return (0); 977789Sahrens } 978789Sahrens 979789Sahrens /* 980*5331Samw * common code for setting ACLs. 981789Sahrens * 982789Sahrens * This function is called from zfs_mode_update, zfs_perm_init, and zfs_setacl. 983789Sahrens * zfs_setacl passes a non-NULL inherit pointer (ihp) to indicate that it's 984789Sahrens * already checked the acl and knows whether to inherit. 985789Sahrens */ 986789Sahrens int 987*5331Samw zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, zfs_fuid_info_t **fuidp, 988*5331Samw dmu_tx_t *tx) 989789Sahrens { 990789Sahrens int error; 991789Sahrens znode_phys_t *zphys = zp->z_phys; 992*5331Samw zfs_acl_phys_t *zacl = &zphys->zp_acl; 993789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 994789Sahrens uint64_t aoid = zphys->zp_acl.z_acl_extern_obj; 995*5331Samw uint64_t off = 0; 996*5331Samw dmu_object_type_t otype; 997*5331Samw zfs_acl_node_t *aclnode; 998789Sahrens 999789Sahrens ASSERT(MUTEX_HELD(&zp->z_lock)); 1000789Sahrens ASSERT(MUTEX_HELD(&zp->z_acl_lock)); 1001789Sahrens 1002*5331Samw dmu_buf_will_dirty(zp->z_dbuf, tx); 1003789Sahrens 1004*5331Samw zphys->zp_mode = zfs_mode_fuid_compute(zp, aclp, fuidp, tx); 1005789Sahrens 1006789Sahrens /* 1007*5331Samw * Decide which opbject type to use. If we are forced to 1008*5331Samw * use old ACL format than transform ACL into zfs_oldace_t 1009*5331Samw * layout. 1010789Sahrens */ 1011*5331Samw if (!zfsvfs->z_use_fuids) { 1012*5331Samw otype = DMU_OT_OLDACL; 1013*5331Samw } else { 1014*5331Samw if ((aclp->z_version == ZFS_ACL_VERSION_INITIAL) && 1015*5331Samw (zfsvfs->z_version >= ZPL_VERSION_FUID)) 1016*5331Samw zfs_acl_xform(zp, aclp); 1017*5331Samw ASSERT(aclp->z_version >= ZFS_ACL_VERSION_FUID); 1018*5331Samw otype = DMU_OT_ACL; 1019*5331Samw } 1020*5331Samw 1021*5331Samw if (aclp->z_acl_bytes > ZFS_ACE_SPACE) { 1022*5331Samw /* 1023*5331Samw * If ACL was previously external and we are now 1024*5331Samw * converting to new ACL format then release old 1025*5331Samw * ACL object and create a new one. 1026*5331Samw */ 1027*5331Samw if (aoid && aclp->z_version != zacl->z_acl_version) { 1028*5331Samw error = dmu_object_free(zfsvfs->z_os, 1029*5331Samw zp->z_phys->zp_acl.z_acl_extern_obj, tx); 1030*5331Samw if (error) 1031*5331Samw return (error); 1032*5331Samw aoid = 0; 1033*5331Samw } 1034789Sahrens if (aoid == 0) { 1035789Sahrens aoid = dmu_object_alloc(zfsvfs->z_os, 1036*5331Samw otype, aclp->z_acl_bytes, 1037*5331Samw otype == DMU_OT_ACL ? DMU_OT_SYSACL : DMU_OT_NONE, 1038*5331Samw otype == DMU_OT_ACL ? DN_MAX_BONUSLEN : 0, tx); 1039789Sahrens } else { 1040789Sahrens (void) dmu_object_set_blocksize(zfsvfs->z_os, aoid, 1041*5331Samw aclp->z_acl_bytes, 0, tx); 1042789Sahrens } 1043789Sahrens zphys->zp_acl.z_acl_extern_obj = aoid; 1044*5331Samw for (aclnode = list_head(&aclp->z_acl); aclnode; 1045*5331Samw aclnode = list_next(&aclp->z_acl, aclnode)) { 1046*5331Samw if (aclnode->z_ace_count == 0) 1047*5331Samw continue; 1048*5331Samw dmu_write(zfsvfs->z_os, aoid, off, 1049*5331Samw aclnode->z_size, aclnode->z_acldata, tx); 1050*5331Samw off += aclnode->z_size; 1051*5331Samw } 1052789Sahrens } else { 1053*5331Samw void *start = zacl->z_ace_data; 1054789Sahrens /* 1055789Sahrens * Migrating back embedded? 1056789Sahrens */ 1057789Sahrens if (zphys->zp_acl.z_acl_extern_obj) { 1058789Sahrens error = dmu_object_free(zfsvfs->z_os, 10594300Smarks zp->z_phys->zp_acl.z_acl_extern_obj, tx); 1060789Sahrens if (error) 1061789Sahrens return (error); 1062789Sahrens zphys->zp_acl.z_acl_extern_obj = 0; 1063789Sahrens } 1064*5331Samw 1065*5331Samw for (aclnode = list_head(&aclp->z_acl); aclnode; 1066*5331Samw aclnode = list_next(&aclp->z_acl, aclnode)) { 1067*5331Samw if (aclnode->z_ace_count == 0) 1068*5331Samw continue; 1069*5331Samw bcopy(aclnode->z_acldata, start, aclnode->z_size); 1070*5331Samw start = (caddr_t)start + aclnode->z_size; 1071*5331Samw } 1072789Sahrens } 1073905Smarks 1074*5331Samw /* 1075*5331Samw * If Old version then swap count/bytes to match old 1076*5331Samw * layout of znode_acl_phys_t. 1077*5331Samw */ 1078*5331Samw if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) { 1079*5331Samw zphys->zp_acl.z_acl_size = aclp->z_acl_count; 1080*5331Samw zphys->zp_acl.z_acl_count = aclp->z_acl_bytes; 1081*5331Samw } else { 1082*5331Samw zphys->zp_acl.z_acl_size = aclp->z_acl_bytes; 1083*5331Samw zphys->zp_acl.z_acl_count = aclp->z_acl_count; 1084905Smarks } 1085789Sahrens 1086*5331Samw zphys->zp_acl.z_acl_version = aclp->z_version; 1087*5331Samw 1088*5331Samw /* 1089*5331Samw * Replace ACL wide bits, but first clear them. 1090*5331Samw */ 1091*5331Samw zp->z_phys->zp_flags &= ~ZFS_ACL_WIDE_FLAGS; 1092*5331Samw 1093*5331Samw zp->z_phys->zp_flags |= aclp->z_hints; 1094*5331Samw 1095*5331Samw if (ace_trivial_common(aclp, 0, zfs_ace_walk) == 0) 1096*5331Samw zp->z_phys->zp_flags |= ZFS_ACL_TRIVIAL; 1097*5331Samw 1098789Sahrens zfs_time_stamper_locked(zp, STATE_CHANGED, tx); 1099789Sahrens return (0); 1100789Sahrens } 1101789Sahrens 1102789Sahrens /* 1103*5331Samw * Remove ACE from aclp 1104789Sahrens */ 1105789Sahrens static void 1106*5331Samw zfs_ace_remove(zfs_acl_t *aclp, void *acep) 1107789Sahrens { 1108*5331Samw zfs_acl_node_t *currnode = zfs_acl_curr_node(aclp); 1109*5331Samw size_t length; 1110789Sahrens 1111*5331Samw /* 1112*5331Samw * If first entry then just alter acldata ptr 1113*5331Samw * 1114*5331Samw * Otherwise split node in two 1115*5331Samw */ 1116*5331Samw if (currnode->z_ace_count > 1) { 1117*5331Samw length = currnode->z_size - ((caddr_t)aclp->z_next_ace - 1118*5331Samw (caddr_t)currnode->z_acldata); 1119*5331Samw (void) memmove(acep, aclp->z_next_ace, length); 1120*5331Samw currnode->z_size = currnode->z_size - 1121*5331Samw aclp->z_ops.ace_size(acep); 1122*5331Samw aclp->z_next_ace = acep; 1123*5331Samw aclp->z_acl_bytes -= ((caddr_t)aclp->z_next_ace - 1124*5331Samw (caddr_t)currnode->z_acldata); 1125*5331Samw } else { 1126*5331Samw list_remove(&aclp->z_acl, currnode); 1127*5331Samw aclp->z_next_ace = NULL; 1128*5331Samw aclp->z_acl_bytes = 0; 1129789Sahrens } 1130*5331Samw currnode->z_ace_count--; 1131*5331Samw currnode->z_ace_idx--; 1132*5331Samw aclp->z_acl_count--; 1133789Sahrens } 1134789Sahrens 1135789Sahrens /* 1136789Sahrens * Update access mask for prepended ACE 1137789Sahrens * 1138789Sahrens * This applies the "groupmask" value for aclmode property. 1139789Sahrens */ 1140789Sahrens static void 1141*5331Samw zfs_acl_prepend_fixup(zfs_acl_t *aclp, void *acep, void *origacep, 1142*5331Samw mode_t mode, uint64_t owner) 1143789Sahrens { 1144789Sahrens int rmask, wmask, xmask; 1145789Sahrens int user_ace; 1146*5331Samw uint16_t aceflags; 1147*5331Samw uint32_t origmask, acepmask; 1148*5331Samw uint64_t fuid; 1149789Sahrens 1150*5331Samw aceflags = aclp->z_ops.ace_flags_get(acep); 1151*5331Samw fuid = aclp->z_ops.ace_who_get(acep); 1152*5331Samw origmask = aclp->z_ops.ace_mask_get(origacep); 1153*5331Samw acepmask = aclp->z_ops.ace_mask_get(acep); 1154*5331Samw 1155*5331Samw user_ace = (!(aceflags & 1156789Sahrens (ACE_OWNER|ACE_GROUP|ACE_IDENTIFIER_GROUP))); 1157789Sahrens 1158*5331Samw if (user_ace && (fuid == owner)) { 1159789Sahrens rmask = S_IRUSR; 1160789Sahrens wmask = S_IWUSR; 1161789Sahrens xmask = S_IXUSR; 1162789Sahrens } else { 1163789Sahrens rmask = S_IRGRP; 1164789Sahrens wmask = S_IWGRP; 1165789Sahrens xmask = S_IXGRP; 1166789Sahrens } 1167789Sahrens 1168*5331Samw if (origmask & ACE_READ_DATA) { 1169*5331Samw if (mode & rmask) { 1170*5331Samw acepmask &= ~ACE_READ_DATA; 1171*5331Samw } else { 1172*5331Samw acepmask |= ACE_READ_DATA; 1173*5331Samw } 1174789Sahrens } 1175789Sahrens 1176*5331Samw if (origmask & ACE_WRITE_DATA) { 1177*5331Samw if (mode & wmask) { 1178*5331Samw acepmask &= ~ACE_WRITE_DATA; 1179*5331Samw } else { 1180*5331Samw acepmask |= ACE_WRITE_DATA; 1181*5331Samw } 1182789Sahrens } 1183789Sahrens 1184*5331Samw if (origmask & ACE_APPEND_DATA) { 1185*5331Samw if (mode & wmask) { 1186*5331Samw acepmask &= ~ACE_APPEND_DATA; 1187*5331Samw } else { 1188*5331Samw acepmask |= ACE_APPEND_DATA; 1189*5331Samw } 1190789Sahrens } 1191789Sahrens 1192*5331Samw if (origmask & ACE_EXECUTE) { 1193*5331Samw if (mode & xmask) { 1194*5331Samw acepmask &= ~ACE_EXECUTE; 1195*5331Samw } else { 1196*5331Samw acepmask |= ACE_EXECUTE; 1197*5331Samw } 1198789Sahrens } 1199*5331Samw aclp->z_ops.ace_mask_set(acep, acepmask); 1200789Sahrens } 1201789Sahrens 1202789Sahrens /* 1203789Sahrens * Apply mode to canonical six ACEs. 1204789Sahrens */ 1205789Sahrens static void 1206789Sahrens zfs_acl_fixup_canonical_six(zfs_acl_t *aclp, mode_t mode) 1207789Sahrens { 1208*5331Samw zfs_acl_node_t *aclnode = list_tail(&aclp->z_acl); 1209*5331Samw void *acep; 1210*5331Samw int maskoff = aclp->z_ops.ace_mask_off(); 1211*5331Samw size_t abstract_size = aclp->z_ops.ace_abstract_size(); 1212789Sahrens 1213*5331Samw ASSERT(aclnode != NULL); 1214*5331Samw 1215*5331Samw acep = (void *)((caddr_t)aclnode->z_acldata + 1216*5331Samw aclnode->z_size - (abstract_size * 6)); 1217789Sahrens 1218789Sahrens /* 1219789Sahrens * Fixup final ACEs to match the mode 1220789Sahrens */ 1221789Sahrens 1222*5331Samw adjust_ace_pair_common(acep, maskoff, abstract_size, 1223*5331Samw (mode & 0700) >> 6); /* owner@ */ 1224*5331Samw 1225*5331Samw acep = (caddr_t)acep + (abstract_size * 2); 1226*5331Samw 1227*5331Samw adjust_ace_pair_common(acep, maskoff, abstract_size, 1228*5331Samw (mode & 0070) >> 3); /* group@ */ 1229*5331Samw 1230*5331Samw acep = (caddr_t)acep + (abstract_size * 2); 1231*5331Samw adjust_ace_pair_common(acep, maskoff, 1232*5331Samw abstract_size, mode); /* everyone@ */ 1233789Sahrens } 1234789Sahrens 1235789Sahrens 1236789Sahrens static int 1237*5331Samw zfs_acl_ace_match(zfs_acl_t *aclp, void *acep, int allow_deny, 1238*5331Samw int entry_type, int accessmask) 1239789Sahrens { 1240*5331Samw uint32_t mask = aclp->z_ops.ace_mask_get(acep); 1241*5331Samw uint16_t type = aclp->z_ops.ace_type_get(acep); 1242*5331Samw uint16_t flags = aclp->z_ops.ace_flags_get(acep); 1243*5331Samw 1244*5331Samw return (mask == accessmask && type == allow_deny && 1245*5331Samw ((flags & ACE_TYPE_FLAGS) == entry_type)); 1246789Sahrens } 1247789Sahrens 1248789Sahrens /* 1249789Sahrens * Can prepended ACE be reused? 1250789Sahrens */ 1251789Sahrens static int 1252*5331Samw zfs_reuse_deny(zfs_acl_t *aclp, void *acep, void *prevacep) 1253789Sahrens { 1254789Sahrens int okay_masks; 1255*5331Samw uint16_t prevtype; 1256*5331Samw uint16_t prevflags; 1257*5331Samw uint16_t flags; 1258*5331Samw uint32_t mask, prevmask; 1259789Sahrens 1260*5331Samw if (prevacep == NULL) 1261789Sahrens return (B_FALSE); 1262789Sahrens 1263*5331Samw prevtype = aclp->z_ops.ace_type_get(prevacep); 1264*5331Samw prevflags = aclp->z_ops.ace_flags_get(prevacep); 1265*5331Samw flags = aclp->z_ops.ace_flags_get(acep); 1266*5331Samw mask = aclp->z_ops.ace_mask_get(acep); 1267*5331Samw prevmask = aclp->z_ops.ace_mask_get(prevacep); 1268*5331Samw 1269*5331Samw if (prevtype != DENY) 1270789Sahrens return (B_FALSE); 1271789Sahrens 1272*5331Samw if (prevflags != (flags & ACE_IDENTIFIER_GROUP)) 1273789Sahrens return (B_FALSE); 1274789Sahrens 1275*5331Samw okay_masks = (mask & OKAY_MASK_BITS); 1276789Sahrens 1277*5331Samw if (prevmask & ~okay_masks) 1278789Sahrens return (B_FALSE); 1279789Sahrens 1280789Sahrens return (B_TRUE); 1281789Sahrens } 1282789Sahrens 1283789Sahrens 1284*5331Samw /* 1285*5331Samw * Insert new ACL node into chain of zfs_acl_node_t's 1286*5331Samw * 1287*5331Samw * This will result in two possible results. 1288*5331Samw * 1. If the ACL is currently just a single zfs_acl_node and 1289*5331Samw * we are prepending the entry then current acl node will have 1290*5331Samw * a new node inserted above it. 1291*5331Samw * 1292*5331Samw * 2. If we are inserting in the middle of current acl node then 1293*5331Samw * the current node will be split in two and new node will be inserted 1294*5331Samw * in between the two split nodes. 1295*5331Samw */ 1296*5331Samw static zfs_acl_node_t * 1297*5331Samw zfs_acl_ace_insert(zfs_acl_t *aclp, void *acep) 1298*5331Samw { 1299*5331Samw zfs_acl_node_t *newnode; 1300*5331Samw zfs_acl_node_t *trailernode = NULL; 1301*5331Samw zfs_acl_node_t *currnode = zfs_acl_curr_node(aclp); 1302*5331Samw int curr_idx = aclp->z_curr_node->z_ace_idx; 1303*5331Samw int trailer_count; 1304*5331Samw size_t oldsize; 1305789Sahrens 1306*5331Samw newnode = zfs_acl_node_alloc(aclp->z_ops.ace_size(acep)); 1307*5331Samw newnode->z_ace_count = 1; 1308*5331Samw 1309*5331Samw oldsize = currnode->z_size; 1310*5331Samw 1311*5331Samw if (curr_idx != 1) { 1312*5331Samw trailernode = zfs_acl_node_alloc(0); 1313*5331Samw trailernode->z_acldata = acep; 1314*5331Samw 1315*5331Samw trailer_count = currnode->z_ace_count - curr_idx + 1; 1316*5331Samw currnode->z_ace_count = curr_idx - 1; 1317*5331Samw currnode->z_size = (caddr_t)acep - (caddr_t)currnode->z_acldata; 1318*5331Samw trailernode->z_size = oldsize - currnode->z_size; 1319*5331Samw trailernode->z_ace_count = trailer_count; 1320789Sahrens } 1321789Sahrens 1322*5331Samw aclp->z_acl_count += 1; 1323*5331Samw aclp->z_acl_bytes += aclp->z_ops.ace_size(acep); 1324789Sahrens 1325*5331Samw if (curr_idx == 1) 1326*5331Samw list_insert_before(&aclp->z_acl, currnode, newnode); 1327*5331Samw else 1328*5331Samw list_insert_after(&aclp->z_acl, currnode, newnode); 1329*5331Samw if (trailernode) { 1330*5331Samw list_insert_after(&aclp->z_acl, newnode, trailernode); 1331*5331Samw aclp->z_curr_node = trailernode; 1332*5331Samw trailernode->z_ace_idx = 1; 1333789Sahrens } 1334789Sahrens 1335*5331Samw return (newnode); 1336789Sahrens } 1337789Sahrens 1338789Sahrens /* 1339789Sahrens * Prepend deny ACE 1340789Sahrens */ 1341*5331Samw static void * 1342*5331Samw zfs_acl_prepend_deny(znode_t *zp, zfs_acl_t *aclp, void *acep, 1343789Sahrens mode_t mode) 1344789Sahrens { 1345*5331Samw zfs_acl_node_t *aclnode; 1346*5331Samw void *newacep; 1347*5331Samw uint64_t fuid; 1348*5331Samw uint16_t flags; 1349789Sahrens 1350*5331Samw aclnode = zfs_acl_ace_insert(aclp, acep); 1351*5331Samw newacep = aclnode->z_acldata; 1352*5331Samw fuid = aclp->z_ops.ace_who_get(acep); 1353*5331Samw flags = aclp->z_ops.ace_flags_get(acep); 1354*5331Samw zfs_set_ace(aclp, newacep, 0, DENY, fuid, (flags & ACE_TYPE_FLAGS)); 1355*5331Samw zfs_acl_prepend_fixup(aclp, newacep, acep, mode, zp->z_phys->zp_uid); 1356*5331Samw 1357*5331Samw return (newacep); 1358789Sahrens } 1359789Sahrens 1360789Sahrens /* 1361789Sahrens * Split an inherited ACE into inherit_only ACE 1362789Sahrens * and original ACE with inheritance flags stripped off. 1363789Sahrens */ 1364789Sahrens static void 1365*5331Samw zfs_acl_split_ace(zfs_acl_t *aclp, zfs_ace_hdr_t *acep) 1366789Sahrens { 1367*5331Samw zfs_acl_node_t *aclnode; 1368*5331Samw zfs_acl_node_t *currnode = zfs_acl_curr_node(aclp); 1369*5331Samw void *newacep; 1370*5331Samw uint16_t type, flags; 1371*5331Samw uint32_t mask; 1372*5331Samw uint64_t fuid; 1373789Sahrens 1374*5331Samw type = aclp->z_ops.ace_type_get(acep); 1375*5331Samw flags = aclp->z_ops.ace_flags_get(acep); 1376*5331Samw mask = aclp->z_ops.ace_mask_get(acep); 1377*5331Samw fuid = aclp->z_ops.ace_who_get(acep); 1378*5331Samw 1379*5331Samw aclnode = zfs_acl_ace_insert(aclp, acep); 1380*5331Samw newacep = aclnode->z_acldata; 1381*5331Samw 1382*5331Samw aclp->z_ops.ace_type_set(newacep, type); 1383*5331Samw aclp->z_ops.ace_flags_set(newacep, flags | ACE_INHERIT_ONLY_ACE); 1384*5331Samw aclp->z_ops.ace_mask_set(newacep, mask); 1385*5331Samw aclp->z_ops.ace_type_set(newacep, type); 1386*5331Samw aclp->z_ops.ace_who_set(newacep, fuid); 1387*5331Samw aclp->z_next_ace = acep; 1388*5331Samw flags &= ~ALL_INHERIT; 1389*5331Samw aclp->z_ops.ace_flags_set(acep, flags); 1390*5331Samw currnode->z_ace_idx -= 1; 1391789Sahrens } 1392789Sahrens 1393789Sahrens /* 1394789Sahrens * Are ACES started at index i, the canonical six ACES? 1395789Sahrens */ 1396789Sahrens static int 1397*5331Samw zfs_have_canonical_six(zfs_acl_t *aclp) 1398789Sahrens { 1399*5331Samw void *acep; 1400*5331Samw zfs_acl_node_t *aclnode = list_tail(&aclp->z_acl); 1401*5331Samw int i = 0; 1402*5331Samw size_t abstract_size = aclp->z_ops.ace_abstract_size(); 1403*5331Samw 1404*5331Samw ASSERT(aclnode != NULL); 1405789Sahrens 1406*5331Samw if (aclnode->z_ace_count < 6) 1407*5331Samw return (0); 1408*5331Samw 1409*5331Samw acep = (void *)((caddr_t)aclnode->z_acldata + 1410*5331Samw aclnode->z_size - (aclp->z_ops.ace_abstract_size() * 6)); 1411*5331Samw 1412*5331Samw if ((zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++), 1413789Sahrens DENY, ACE_OWNER, 0) && 1414*5331Samw zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++), 1415*5331Samw ALLOW, ACE_OWNER, OWNER_ALLOW_MASK) && 1416*5331Samw zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++), DENY, 1417*5331Samw OWNING_GROUP, 0) && zfs_acl_ace_match(aclp, (caddr_t)acep + 1418*5331Samw (abstract_size * i++), 1419*5331Samw ALLOW, OWNING_GROUP, 0) && 1420*5331Samw zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++), 1421789Sahrens DENY, ACE_EVERYONE, EVERYONE_DENY_MASK) && 1422*5331Samw zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++), 1423*5331Samw ALLOW, ACE_EVERYONE, EVERYONE_ALLOW_MASK))) { 1424789Sahrens return (1); 1425789Sahrens } else { 1426789Sahrens return (0); 1427789Sahrens } 1428789Sahrens } 1429789Sahrens 1430*5331Samw 1431789Sahrens /* 1432789Sahrens * Apply step 1g, to group entries 1433789Sahrens * 1434789Sahrens * Need to deal with corner case where group may have 1435789Sahrens * greater permissions than owner. If so then limit 1436789Sahrens * group permissions, based on what extra permissions 1437789Sahrens * group has. 1438789Sahrens */ 1439789Sahrens static void 1440*5331Samw zfs_fixup_group_entries(zfs_acl_t *aclp, void *acep, void *prevacep, 1441*5331Samw mode_t mode) 1442789Sahrens { 1443*5331Samw uint32_t prevmask = aclp->z_ops.ace_mask_get(prevacep); 1444*5331Samw uint32_t mask = aclp->z_ops.ace_mask_get(acep); 1445*5331Samw uint16_t prevflags = aclp->z_ops.ace_flags_get(prevacep); 1446789Sahrens mode_t extramode = (mode >> 3) & 07; 1447789Sahrens mode_t ownermode = (mode >> 6); 1448789Sahrens 1449*5331Samw if (prevflags & ACE_IDENTIFIER_GROUP) { 1450789Sahrens 1451789Sahrens extramode &= ~ownermode; 1452789Sahrens 1453789Sahrens if (extramode) { 1454*5331Samw if (extramode & S_IROTH) { 1455*5331Samw prevmask &= ~ACE_READ_DATA; 1456*5331Samw mask &= ~ACE_READ_DATA; 1457789Sahrens } 1458*5331Samw if (extramode & S_IWOTH) { 1459*5331Samw prevmask &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA); 1460*5331Samw mask &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA); 1461789Sahrens } 1462*5331Samw if (extramode & S_IXOTH) { 1463*5331Samw prevmask &= ~ACE_EXECUTE; 1464*5331Samw mask &= ~ACE_EXECUTE; 1465789Sahrens } 1466789Sahrens } 1467789Sahrens } 1468*5331Samw aclp->z_ops.ace_mask_set(acep, mask); 1469*5331Samw aclp->z_ops.ace_mask_set(prevacep, prevmask); 1470789Sahrens } 1471789Sahrens 1472789Sahrens /* 1473789Sahrens * Apply the chmod algorithm as described 1474789Sahrens * in PSARC/2002/240 1475789Sahrens */ 1476789Sahrens static int 1477789Sahrens zfs_acl_chmod(znode_t *zp, uint64_t mode, zfs_acl_t *aclp, 1478789Sahrens dmu_tx_t *tx) 1479789Sahrens { 1480789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1481*5331Samw void *acep = NULL, *prevacep = NULL; 1482*5331Samw uint64_t who; 1483789Sahrens int i; 1484789Sahrens int error; 1485789Sahrens int entry_type; 1486789Sahrens int reuse_deny; 1487789Sahrens int need_canonical_six = 1; 1488*5331Samw uint16_t iflags, type; 1489*5331Samw uint32_t access_mask; 1490789Sahrens 1491789Sahrens ASSERT(MUTEX_HELD(&zp->z_acl_lock)); 1492789Sahrens ASSERT(MUTEX_HELD(&zp->z_lock)); 1493789Sahrens 1494*5331Samw aclp->z_hints = (zp->z_phys->zp_flags & V4_ACL_WIDE_FLAGS); 1495*5331Samw while (acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask, 1496*5331Samw &iflags, &type)) { 1497*5331Samw 1498*5331Samw entry_type = (iflags & ACE_TYPE_FLAGS); 1499*5331Samw iflags = (iflags & ALL_INHERIT); 1500789Sahrens 1501*5331Samw if ((type != ALLOW && type != DENY) || 1502905Smarks (iflags & ACE_INHERIT_ONLY_ACE)) { 1503905Smarks if (iflags) 1504*5331Samw aclp->z_hints |= ZFS_INHERIT_ACE; 1505*5331Samw switch (type) { 1506*5331Samw case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 1507*5331Samw case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 1508*5331Samw case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 1509*5331Samw case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 1510*5331Samw aclp->z_hints |= ZFS_ACL_OBJ_ACE; 1511*5331Samw break; 1512*5331Samw } 1513*5331Samw goto nextace; 1514789Sahrens } 1515789Sahrens 15162676Seschrock if (zfsvfs->z_acl_mode == ZFS_ACL_DISCARD) { 1517*5331Samw zfs_ace_remove(aclp, acep); 1518*5331Samw goto nextace; 1519789Sahrens } 1520789Sahrens /* 1521789Sahrens * Need to split ace into two? 1522789Sahrens */ 1523905Smarks if ((iflags & (ACE_FILE_INHERIT_ACE| 1524789Sahrens ACE_DIRECTORY_INHERIT_ACE)) && 1525905Smarks (!(iflags & ACE_INHERIT_ONLY_ACE))) { 1526*5331Samw zfs_acl_split_ace(aclp, acep); 1527*5331Samw aclp->z_hints |= ZFS_INHERIT_ACE; 1528*5331Samw goto nextace; 1529789Sahrens } 1530789Sahrens 1531789Sahrens if (entry_type == ACE_OWNER || entry_type == ACE_EVERYONE || 1532789Sahrens (entry_type == OWNING_GROUP)) { 1533*5331Samw access_mask &= ~OGE_CLEAR; 1534*5331Samw aclp->z_ops.ace_mask_set(acep, access_mask); 1535*5331Samw goto nextace; 1536789Sahrens } else { 1537*5331Samw reuse_deny = B_TRUE; 1538*5331Samw if (type == ALLOW) { 1539789Sahrens 1540789Sahrens /* 1541789Sahrens * Check preceding ACE if any, to see 1542789Sahrens * if we need to prepend a DENY ACE. 1543789Sahrens * This is only applicable when the acl_mode 1544789Sahrens * property == groupmask. 1545789Sahrens */ 15462676Seschrock if (zfsvfs->z_acl_mode == ZFS_ACL_GROUPMASK) { 1547789Sahrens 1548*5331Samw reuse_deny = zfs_reuse_deny(aclp, acep, 1549*5331Samw prevacep); 1550789Sahrens 1551789Sahrens if (reuse_deny == B_FALSE) { 1552*5331Samw prevacep = 1553*5331Samw zfs_acl_prepend_deny(zp, 1554*5331Samw aclp, acep, mode); 1555789Sahrens } else { 1556789Sahrens zfs_acl_prepend_fixup( 1557*5331Samw aclp, prevacep, 1558*5331Samw acep, mode, 1559789Sahrens zp->z_phys->zp_uid); 1560789Sahrens } 1561*5331Samw zfs_fixup_group_entries(aclp, acep, 1562*5331Samw prevacep, mode); 1563*5331Samw 1564789Sahrens } 1565789Sahrens } 1566789Sahrens } 1567*5331Samw nextace: 1568*5331Samw prevacep = acep; 1569789Sahrens } 1570789Sahrens 1571789Sahrens /* 1572789Sahrens * Check out last six aces, if we have six. 1573789Sahrens */ 1574789Sahrens 1575789Sahrens if (aclp->z_acl_count >= 6) { 1576*5331Samw if (zfs_have_canonical_six(aclp)) { 1577789Sahrens need_canonical_six = 0; 1578789Sahrens } 1579789Sahrens } 1580789Sahrens 1581789Sahrens if (need_canonical_six) { 1582*5331Samw size_t abstract_size = aclp->z_ops.ace_abstract_size(); 1583*5331Samw void *zacep; 1584*5331Samw zfs_acl_node_t *aclnode = 1585*5331Samw zfs_acl_node_alloc(abstract_size * 6); 1586789Sahrens 1587*5331Samw aclnode->z_size = abstract_size * 6; 1588*5331Samw aclnode->z_ace_count = 6; 1589*5331Samw aclp->z_acl_bytes += aclnode->z_size; 1590*5331Samw list_insert_tail(&aclp->z_acl, aclnode); 1591*5331Samw 1592*5331Samw zacep = aclnode->z_acldata; 1593*5331Samw 1594*5331Samw i = 0; 1595*5331Samw zfs_set_ace(aclp, (caddr_t)zacep + (abstract_size * i++), 1596*5331Samw 0, DENY, -1, ACE_OWNER); 1597*5331Samw zfs_set_ace(aclp, (caddr_t)zacep + (abstract_size * i++), 1598*5331Samw OWNER_ALLOW_MASK, ALLOW, -1, ACE_OWNER); 1599*5331Samw zfs_set_ace(aclp, (caddr_t)zacep + (abstract_size * i++), 0, 1600*5331Samw DENY, -1, OWNING_GROUP); 1601*5331Samw zfs_set_ace(aclp, (caddr_t)zacep + (abstract_size * i++), 0, 1602*5331Samw ALLOW, -1, OWNING_GROUP); 1603*5331Samw zfs_set_ace(aclp, (caddr_t)zacep + (abstract_size * i++), 1604*5331Samw EVERYONE_DENY_MASK, DENY, -1, ACE_EVERYONE); 1605*5331Samw zfs_set_ace(aclp, (caddr_t)zacep + (abstract_size * i++), 1606*5331Samw EVERYONE_ALLOW_MASK, ALLOW, -1, ACE_EVERYONE); 1607789Sahrens aclp->z_acl_count += 6; 1608789Sahrens } 1609789Sahrens 1610789Sahrens zfs_acl_fixup_canonical_six(aclp, mode); 1611789Sahrens zp->z_phys->zp_mode = mode; 1612*5331Samw error = zfs_aclset_common(zp, aclp, NULL, tx); 1613789Sahrens return (error); 1614789Sahrens } 1615789Sahrens 1616789Sahrens int 1617789Sahrens zfs_acl_chmod_setattr(znode_t *zp, uint64_t mode, dmu_tx_t *tx) 1618789Sahrens { 16191544Seschrock zfs_acl_t *aclp = NULL; 1620789Sahrens int error; 1621789Sahrens 1622789Sahrens ASSERT(MUTEX_HELD(&zp->z_lock)); 1623789Sahrens mutex_enter(&zp->z_acl_lock); 1624*5331Samw error = zfs_acl_node_read(zp, &aclp, B_TRUE); 16251544Seschrock if (error == 0) 16261544Seschrock error = zfs_acl_chmod(zp, mode, aclp, tx); 1627789Sahrens mutex_exit(&zp->z_acl_lock); 16281544Seschrock if (aclp) 16291544Seschrock zfs_acl_free(aclp); 1630789Sahrens return (error); 1631789Sahrens } 1632789Sahrens 1633789Sahrens /* 1634789Sahrens * strip off write_owner and write_acl 1635789Sahrens */ 1636789Sahrens static void 1637*5331Samw zfs_securemode_update(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *acep) 1638789Sahrens { 1639*5331Samw uint32_t mask = aclp->z_ops.ace_mask_get(acep); 1640*5331Samw 16412676Seschrock if ((zfsvfs->z_acl_inherit == ZFS_ACL_SECURE) && 1642*5331Samw (aclp->z_ops.ace_type_get(acep) == ALLOW)) { 1643*5331Samw mask &= ~SECURE_CLEAR; 1644*5331Samw aclp->z_ops.ace_mask_set(acep, mask); 1645*5331Samw } 1646*5331Samw } 1647*5331Samw 1648*5331Samw /* 1649*5331Samw * Should ACE be inherited? 1650*5331Samw */ 1651*5331Samw static int 1652*5331Samw zfs_ace_can_use(znode_t *zp, uint16_t acep_flags) 1653*5331Samw { 1654*5331Samw int vtype = ZTOV(zp)->v_type; 1655*5331Samw int iflags = (acep_flags & 0xf); 1656*5331Samw 1657*5331Samw if ((vtype == VDIR) && (iflags & ACE_DIRECTORY_INHERIT_ACE)) 1658*5331Samw return (1); 1659*5331Samw else if (iflags & ACE_FILE_INHERIT_ACE) 1660*5331Samw return (!((vtype == VDIR) && 1661*5331Samw (iflags & ACE_NO_PROPAGATE_INHERIT_ACE))); 1662*5331Samw return (0); 1663789Sahrens } 1664789Sahrens 1665789Sahrens /* 1666789Sahrens * inherit inheritable ACEs from parent 1667789Sahrens */ 1668789Sahrens static zfs_acl_t * 1669789Sahrens zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp) 1670789Sahrens { 1671789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1672*5331Samw void *pacep; 1673*5331Samw void *acep, *acep2; 1674*5331Samw zfs_acl_node_t *aclnode, *aclnode2; 1675789Sahrens zfs_acl_t *aclp = NULL; 1676*5331Samw uint64_t who; 1677*5331Samw uint32_t access_mask; 1678*5331Samw uint16_t iflags, newflags, type; 1679*5331Samw size_t ace_size; 1680*5331Samw void *data1, *data2; 1681*5331Samw size_t data1sz, data2sz; 1682789Sahrens 1683*5331Samw pacep = NULL; 1684*5331Samw aclp = zfs_acl_alloc(zfs_acl_version_zp(zp)); 16852676Seschrock if (zfsvfs->z_acl_inherit != ZFS_ACL_DISCARD) { 1686*5331Samw while (pacep = zfs_acl_next_ace(paclp, pacep, &who, 1687*5331Samw &access_mask, &iflags, &type)) { 1688789Sahrens 16892676Seschrock if (zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW && 1690*5331Samw type == ALLOW) 1691789Sahrens continue; 1692789Sahrens 1693*5331Samw ace_size = aclp->z_ops.ace_size(pacep); 1694789Sahrens 1695*5331Samw if (zfs_ace_can_use(zp, iflags)) { 1696*5331Samw aclnode = 1697*5331Samw zfs_acl_node_alloc(ace_size); 1698789Sahrens 1699*5331Samw list_insert_tail(&aclp->z_acl, aclnode); 1700*5331Samw acep = aclnode->z_acldata; 1701*5331Samw zfs_set_ace(aclp, acep, access_mask, type, 1702*5331Samw who, iflags|ACE_INHERITED_ACE); 17031576Smarks 1704789Sahrens /* 1705*5331Samw * Copy special opaque data if any 1706789Sahrens */ 1707*5331Samw if ((data1sz = paclp->z_ops.ace_data(pacep, 1708*5331Samw &data1)) != 0) { 1709*5331Samw VERIFY((data2sz = 1710*5331Samw aclp->z_ops.ace_data(acep, 1711*5331Samw &data2)) == data1sz); 1712*5331Samw bcopy(data1, data2, data2sz); 1713*5331Samw } 1714*5331Samw aclp->z_acl_count++; 1715*5331Samw aclnode->z_ace_count++; 1716*5331Samw aclp->z_acl_bytes += aclnode->z_size; 1717*5331Samw newflags = aclp->z_ops.ace_flags_get(acep); 1718*5331Samw if ((iflags & 17191576Smarks ACE_NO_PROPAGATE_INHERIT_ACE) || 17201576Smarks (ZTOV(zp)->v_type != VDIR)) { 1721*5331Samw newflags &= ~ALL_INHERIT; 1722*5331Samw aclp->z_ops.ace_flags_set(acep, 1723*5331Samw newflags|ACE_INHERITED_ACE); 1724*5331Samw zfs_securemode_update(zfsvfs, 1725*5331Samw aclp, acep); 1726789Sahrens continue; 1727789Sahrens } 1728789Sahrens 1729789Sahrens ASSERT(ZTOV(zp)->v_type == VDIR); 1730789Sahrens 1731*5331Samw newflags = aclp->z_ops.ace_flags_get(acep); 1732*5331Samw if ((iflags & (ACE_FILE_INHERIT_ACE | 17331576Smarks ACE_DIRECTORY_INHERIT_ACE)) != 1734865Smarks ACE_FILE_INHERIT_ACE) { 1735*5331Samw aclnode2 = zfs_acl_node_alloc(ace_size); 1736*5331Samw list_insert_tail(&aclp->z_acl, 1737*5331Samw aclnode2); 1738*5331Samw acep2 = aclnode2->z_acldata; 1739*5331Samw zfs_set_ace(aclp, acep2, 1740*5331Samw access_mask, type, who, 1741*5331Samw iflags|ACE_INHERITED_ACE); 1742*5331Samw newflags |= ACE_INHERIT_ONLY_ACE; 1743*5331Samw aclp->z_ops.ace_flags_set(acep, 1744*5331Samw newflags); 1745*5331Samw newflags &= ~ALL_INHERIT; 1746*5331Samw aclp->z_ops.ace_flags_set(acep2, 1747*5331Samw newflags|ACE_INHERITED_ACE); 1748*5331Samw 1749*5331Samw /* 1750*5331Samw * Copy special opaque data if any 1751*5331Samw */ 1752*5331Samw if ((data1sz = 1753*5331Samw aclp->z_ops.ace_data(acep, 1754*5331Samw &data1)) != 0) { 1755*5331Samw VERIFY((data2sz = 1756*5331Samw aclp->z_ops.ace_data(acep2, 1757*5331Samw &data2)) == data1sz); 1758*5331Samw bcopy(data1, data2, data1sz); 1759*5331Samw } 1760*5331Samw aclp->z_acl_count++; 1761*5331Samw aclnode2->z_ace_count++; 1762*5331Samw aclp->z_acl_bytes += aclnode->z_size; 1763*5331Samw zfs_securemode_update(zfsvfs, 1764*5331Samw aclp, acep2); 1765865Smarks } else { 1766*5331Samw newflags |= ACE_INHERIT_ONLY_ACE; 1767*5331Samw aclp->z_ops.ace_flags_set(acep, 1768*5331Samw newflags|ACE_INHERITED_ACE); 1769865Smarks } 1770*5331Samw 1771789Sahrens } 1772789Sahrens } 1773789Sahrens } 1774789Sahrens return (aclp); 1775789Sahrens } 1776789Sahrens 1777789Sahrens /* 1778789Sahrens * Create file system object initial permissions 1779789Sahrens * including inheritable ACEs. 1780789Sahrens */ 1781789Sahrens void 1782789Sahrens zfs_perm_init(znode_t *zp, znode_t *parent, int flag, 1783*5331Samw vattr_t *vap, dmu_tx_t *tx, cred_t *cr, 1784*5331Samw zfs_acl_t *setaclp, zfs_fuid_info_t **fuidp) 1785789Sahrens { 1786789Sahrens uint64_t mode; 1787*5331Samw uint64_t uid; 1788*5331Samw uint64_t gid; 1789789Sahrens int error; 1790789Sahrens int pull_down; 1791*5331Samw zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1792*5331Samw zfs_acl_t *aclp = NULL; 1793*5331Samw zfs_acl_t *paclp; 1794*5331Samw xvattr_t *xvap = (xvattr_t *)vap; 1795*5331Samw 1796*5331Samw if (setaclp) 1797*5331Samw aclp = setaclp; 1798789Sahrens 1799789Sahrens mode = MAKEIMODE(vap->va_type, vap->va_mode); 1800789Sahrens 1801789Sahrens /* 1802789Sahrens * Determine uid and gid. 1803789Sahrens */ 1804789Sahrens if ((flag & (IS_ROOT_NODE | IS_REPLAY)) || 1805789Sahrens ((flag & IS_XATTR) && (vap->va_type == VDIR))) { 1806*5331Samw uid = zfs_fuid_create(zfsvfs, vap->va_uid, 1807*5331Samw ZFS_OWNER, tx, fuidp); 1808*5331Samw gid = zfs_fuid_create(zfsvfs, vap->va_gid, 1809*5331Samw ZFS_GROUP, tx, fuidp); 1810789Sahrens } else { 1811*5331Samw uid = zfs_fuid_create_cred(zfsvfs, crgetuid(cr), 1812*5331Samw ZFS_OWNER, tx, cr, fuidp); 1813789Sahrens if ((vap->va_mask & AT_GID) && 1814789Sahrens ((vap->va_gid == parent->z_phys->zp_gid) || 1815789Sahrens groupmember(vap->va_gid, cr) || 1816*5331Samw secpolicy_vnode_create_gid(cr) == 0)) { 1817*5331Samw gid = zfs_fuid_create_cred(zfsvfs, vap->va_gid, 1818*5331Samw ZFS_GROUP, tx, cr, fuidp); 1819*5331Samw } else { 1820789Sahrens gid = (parent->z_phys->zp_mode & S_ISGID) ? 1821789Sahrens parent->z_phys->zp_gid : crgetgid(cr); 1822*5331Samw gid = zfs_fuid_create_cred(zfsvfs, gid, 1823*5331Samw ZFS_GROUP, tx, cr, fuidp); 1824*5331Samw } 1825789Sahrens } 1826789Sahrens 1827789Sahrens /* 1828789Sahrens * If we're creating a directory, and the parent directory has the 1829789Sahrens * set-GID bit set, set in on the new directory. 1830789Sahrens * Otherwise, if the user is neither privileged nor a member of the 1831789Sahrens * file's new group, clear the file's set-GID bit. 1832789Sahrens */ 1833789Sahrens 1834789Sahrens if ((parent->z_phys->zp_mode & S_ISGID) && (vap->va_type == VDIR)) 1835789Sahrens mode |= S_ISGID; 1836789Sahrens else { 1837789Sahrens if ((mode & S_ISGID) && 1838789Sahrens secpolicy_vnode_setids_setgids(cr, gid) != 0) 1839789Sahrens mode &= ~S_ISGID; 1840789Sahrens } 1841789Sahrens 1842789Sahrens zp->z_phys->zp_uid = uid; 1843789Sahrens zp->z_phys->zp_gid = gid; 1844789Sahrens zp->z_phys->zp_mode = mode; 1845789Sahrens 1846*5331Samw if (aclp == NULL) { 1847*5331Samw mutex_enter(&parent->z_lock); 1848*5331Samw pull_down = (parent->z_phys->zp_flags & ZFS_INHERIT_ACE); 1849*5331Samw if (pull_down) { 1850*5331Samw mutex_enter(&parent->z_acl_lock); 1851*5331Samw VERIFY(0 == zfs_acl_node_read(parent, &paclp, B_FALSE)); 1852*5331Samw mutex_exit(&parent->z_acl_lock); 1853*5331Samw aclp = zfs_acl_inherit(zp, paclp); 1854*5331Samw zfs_acl_free(paclp); 1855*5331Samw } else { 1856*5331Samw aclp = zfs_acl_alloc(zfs_acl_version_zp(zp)); 1857*5331Samw } 1858*5331Samw mutex_exit(&parent->z_lock); 1859*5331Samw mutex_enter(&zp->z_lock); 1860*5331Samw mutex_enter(&zp->z_acl_lock); 1861*5331Samw error = zfs_acl_chmod(zp, mode, aclp, tx); 1862789Sahrens } else { 1863*5331Samw mutex_enter(&zp->z_lock); 1864*5331Samw mutex_enter(&zp->z_acl_lock); 1865789Sahrens } 1866*5331Samw 1867*5331Samw /* Force auto_inherit on all new directory objects */ 1868*5331Samw if (vap->va_type == VDIR) 1869*5331Samw aclp->z_hints |= ZFS_ACL_AUTO_INHERIT; 1870*5331Samw 1871*5331Samw error = zfs_aclset_common(zp, aclp, fuidp, tx); 1872*5331Samw 1873*5331Samw /* Set optional attributes if any */ 1874*5331Samw if (vap->va_mask & AT_XVATTR) 1875*5331Samw zfs_xvattr_set(zp, xvap); 1876*5331Samw 1877789Sahrens mutex_exit(&zp->z_lock); 1878789Sahrens mutex_exit(&zp->z_acl_lock); 1879789Sahrens ASSERT3U(error, ==, 0); 1880789Sahrens 1881*5331Samw if (aclp != setaclp) { 1882*5331Samw zfs_acl_free(aclp); 1883*5331Samw } 1884789Sahrens } 1885789Sahrens 1886789Sahrens /* 1887789Sahrens * Retrieve a files ACL 1888789Sahrens */ 1889789Sahrens int 1890*5331Samw zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) 1891789Sahrens { 1892789Sahrens zfs_acl_t *aclp; 1893*5331Samw ulong_t mask; 1894789Sahrens int error; 1895*5331Samw int count = 0; 1896*5331Samw int largeace = 0; 1897789Sahrens 1898*5331Samw mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT | 1899*5331Samw VSA_ACE_ACLFLAGS | VSA_ACE_ALLTYPES); 1900*5331Samw 1901*5331Samw if (error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr)) 1902*5331Samw return (error); 1903789Sahrens 1904789Sahrens if (mask == 0) 1905789Sahrens return (ENOSYS); 1906789Sahrens 1907789Sahrens mutex_enter(&zp->z_acl_lock); 1908789Sahrens 1909*5331Samw error = zfs_acl_node_read(zp, &aclp, B_FALSE); 19101544Seschrock if (error != 0) { 19111544Seschrock mutex_exit(&zp->z_acl_lock); 19121544Seschrock return (error); 19131544Seschrock } 19141544Seschrock 1915*5331Samw /* 1916*5331Samw * Scan ACL to determine number of ACEs 1917*5331Samw */ 1918*5331Samw if ((zp->z_phys->zp_flags & ZFS_ACL_OBJ_ACE) && 1919*5331Samw !(mask & VSA_ACE_ALLTYPES)) { 1920*5331Samw void *zacep = NULL; 1921*5331Samw uint64_t who; 1922*5331Samw uint32_t access_mask; 1923*5331Samw uint16_t type, iflags; 1924*5331Samw 1925*5331Samw while (zacep = zfs_acl_next_ace(aclp, zacep, 1926*5331Samw &who, &access_mask, &iflags, &type)) { 1927*5331Samw switch (type) { 1928*5331Samw case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 1929*5331Samw case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 1930*5331Samw case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 1931*5331Samw case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 1932*5331Samw largeace++; 1933*5331Samw continue; 1934*5331Samw default: 1935*5331Samw count++; 1936*5331Samw } 1937*5331Samw } 1938*5331Samw vsecp->vsa_aclcnt = count; 1939*5331Samw } else 1940*5331Samw count = aclp->z_acl_count; 1941789Sahrens 1942789Sahrens if (mask & VSA_ACECNT) { 1943*5331Samw vsecp->vsa_aclcnt = count; 1944789Sahrens } 1945789Sahrens 1946789Sahrens if (mask & VSA_ACE) { 1947*5331Samw size_t aclsz; 1948*5331Samw 1949*5331Samw zfs_acl_node_t *aclnode = list_head(&aclp->z_acl); 1950*5331Samw 1951*5331Samw aclsz = count * sizeof (ace_t) + 1952*5331Samw sizeof (ace_object_t) * largeace; 1953*5331Samw 1954*5331Samw vsecp->vsa_aclentp = kmem_alloc(aclsz, KM_SLEEP); 1955*5331Samw vsecp->vsa_aclentsz = aclsz; 1956*5331Samw 1957*5331Samw if (aclp->z_version == ZFS_ACL_VERSION_FUID) 1958*5331Samw zfs_copy_fuid_2_ace(zp->z_zfsvfs, aclp, 1959*5331Samw vsecp->vsa_aclentp, !(mask & VSA_ACE_ALLTYPES)); 1960*5331Samw else { 1961*5331Samw bcopy(aclnode->z_acldata, vsecp->vsa_aclentp, 1962*5331Samw count * sizeof (ace_t)); 1963*5331Samw } 1964*5331Samw } 1965*5331Samw if (mask & VSA_ACE_ACLFLAGS) { 1966*5331Samw vsecp->vsa_aclflags = 0; 1967*5331Samw if (zp->z_phys->zp_flags & ZFS_ACL_DEFAULTED) 1968*5331Samw vsecp->vsa_aclflags |= ACL_DEFAULTED; 1969*5331Samw if (zp->z_phys->zp_flags & ZFS_ACL_PROTECTED) 1970*5331Samw vsecp->vsa_aclflags |= ACL_PROTECTED; 1971*5331Samw if (zp->z_phys->zp_flags & ZFS_ACL_AUTO_INHERIT) 1972*5331Samw vsecp->vsa_aclflags |= ACL_AUTO_INHERIT; 1973789Sahrens } 1974789Sahrens 1975789Sahrens mutex_exit(&zp->z_acl_lock); 1976789Sahrens 1977789Sahrens zfs_acl_free(aclp); 1978789Sahrens 1979789Sahrens return (0); 1980789Sahrens } 1981789Sahrens 1982*5331Samw int 1983*5331Samw zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type, 1984*5331Samw vsecattr_t *vsecp, zfs_acl_t **zaclp) 1985*5331Samw { 1986*5331Samw zfs_acl_t *aclp; 1987*5331Samw zfs_acl_node_t *aclnode; 1988*5331Samw int aclcnt = vsecp->vsa_aclcnt; 1989*5331Samw int error; 1990*5331Samw 1991*5331Samw if (vsecp->vsa_aclcnt > MAX_ACL_ENTRIES || vsecp->vsa_aclcnt <= 0) 1992*5331Samw return (EINVAL); 1993*5331Samw 1994*5331Samw aclp = zfs_acl_alloc(zfs_acl_version(zfsvfs->z_version)); 1995*5331Samw 1996*5331Samw aclp->z_hints = 0; 1997*5331Samw aclnode = zfs_acl_node_alloc(aclcnt * sizeof (zfs_object_ace_t)); 1998*5331Samw if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) { 1999*5331Samw if ((error = zfs_copy_ace_2_oldace(obj_type, aclp, 2000*5331Samw (ace_t *)vsecp->vsa_aclentp, aclnode->z_acldata, 2001*5331Samw aclcnt, &aclnode->z_size)) != 0) { 2002*5331Samw zfs_acl_free(aclp); 2003*5331Samw zfs_acl_node_free(aclnode); 2004*5331Samw return (error); 2005*5331Samw } 2006*5331Samw } else { 2007*5331Samw if ((error = zfs_copy_ace_2_fuid(obj_type, aclp, 2008*5331Samw vsecp->vsa_aclentp, aclnode->z_acldata, aclcnt, 2009*5331Samw &aclnode->z_size)) != 0) { 2010*5331Samw zfs_acl_free(aclp); 2011*5331Samw zfs_acl_node_free(aclnode); 2012*5331Samw return (error); 2013*5331Samw } 2014*5331Samw } 2015*5331Samw aclp->z_acl_bytes = aclnode->z_size; 2016*5331Samw aclnode->z_ace_count = aclcnt; 2017*5331Samw aclp->z_acl_count = aclcnt; 2018*5331Samw list_insert_head(&aclp->z_acl, aclnode); 2019*5331Samw 2020*5331Samw /* 2021*5331Samw * If flags are being set then add them to z_hints 2022*5331Samw */ 2023*5331Samw if (vsecp->vsa_mask & VSA_ACE_ACLFLAGS) { 2024*5331Samw if (vsecp->vsa_aclflags & ACL_PROTECTED) 2025*5331Samw aclp->z_hints |= ZFS_ACL_PROTECTED; 2026*5331Samw if (vsecp->vsa_aclflags & ACL_DEFAULTED) 2027*5331Samw aclp->z_hints |= ZFS_ACL_DEFAULTED; 2028*5331Samw if (vsecp->vsa_aclflags & ACL_AUTO_INHERIT) 2029*5331Samw aclp->z_hints |= ZFS_ACL_AUTO_INHERIT; 2030*5331Samw } 2031*5331Samw 2032*5331Samw *zaclp = aclp; 2033*5331Samw 2034*5331Samw return (0); 2035*5331Samw } 2036*5331Samw 2037789Sahrens /* 2038789Sahrens * Set a files ACL 2039789Sahrens */ 2040789Sahrens int 2041*5331Samw zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) 2042789Sahrens { 2043789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 2044789Sahrens zilog_t *zilog = zfsvfs->z_log; 2045789Sahrens ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT); 2046789Sahrens dmu_tx_t *tx; 2047789Sahrens int error; 2048789Sahrens zfs_acl_t *aclp; 2049*5331Samw zfs_fuid_info_t *fuidp = NULL; 2050789Sahrens 2051789Sahrens if (mask == 0) 20524300Smarks return (ENOSYS); 2053789Sahrens 2054*5331Samw if (zp->z_phys->zp_flags & ZFS_IMMUTABLE) 2055*5331Samw return (EPERM); 2056*5331Samw 2057*5331Samw if (error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)) 2058*5331Samw return (error); 2059*5331Samw 2060*5331Samw error = zfs_vsec_2_aclp(zfsvfs, ZTOV(zp)->v_type, vsecp, &aclp); 2061*5331Samw if (error) 2062*5331Samw return (error); 2063*5331Samw 2064*5331Samw /* 2065*5331Samw * If ACL wide flags aren't being set then preserve any 2066*5331Samw * existing flags. 2067*5331Samw */ 2068*5331Samw if (!(vsecp->vsa_mask & VSA_ACE_ACLFLAGS)) { 2069*5331Samw aclp->z_hints |= (zp->z_phys->zp_flags & V4_ACL_WIDE_FLAGS); 2070*5331Samw } 2071789Sahrens top: 2072*5331Samw if (error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)) { 2073*5331Samw zfs_acl_free(aclp); 2074*5331Samw return (error); 2075789Sahrens } 2076789Sahrens 2077789Sahrens mutex_enter(&zp->z_lock); 2078789Sahrens mutex_enter(&zp->z_acl_lock); 2079789Sahrens 2080789Sahrens tx = dmu_tx_create(zfsvfs->z_os); 2081789Sahrens dmu_tx_hold_bonus(tx, zp->z_id); 2082789Sahrens 2083789Sahrens if (zp->z_phys->zp_acl.z_acl_extern_obj) { 2084*5331Samw /* Are we upgrading ACL? */ 2085*5331Samw if (zfsvfs->z_version <= ZPL_VERSION_FUID && 2086*5331Samw zp->z_phys->zp_acl.z_acl_version == 2087*5331Samw ZFS_ACL_VERSION_INITIAL) { 2088*5331Samw dmu_tx_hold_free(tx, 2089*5331Samw zp->z_phys->zp_acl.z_acl_extern_obj, 2090*5331Samw 0, DMU_OBJECT_END); 2091*5331Samw dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 2092*5331Samw 0, sizeof (zfs_object_ace_t) * 2048 + 6); 2093*5331Samw } else { 2094*5331Samw dmu_tx_hold_write(tx, 2095*5331Samw zp->z_phys->zp_acl.z_acl_extern_obj, 2096*5331Samw 0, aclp->z_acl_bytes); 2097*5331Samw } 2098*5331Samw } else if (aclp->z_acl_bytes > ZFS_ACE_SPACE) { 2099*5331Samw dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, aclp->z_acl_bytes); 2100*5331Samw } 2101*5331Samw if (zfsvfs->z_fuid_obj == 0) { 2102*5331Samw dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); 2103*5331Samw dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, 2104*5331Samw SPA_MAXBLOCKSIZE); 2105*5331Samw dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, FALSE, NULL); 2106*5331Samw } else { 2107*5331Samw dmu_tx_hold_bonus(tx, zfsvfs->z_fuid_obj); 2108*5331Samw dmu_tx_hold_write(tx, zfsvfs->z_fuid_obj, 0, 2109*5331Samw SPA_MAXBLOCKSIZE); 2110789Sahrens } 2111789Sahrens 2112789Sahrens error = dmu_tx_assign(tx, zfsvfs->z_assign); 2113789Sahrens if (error) { 2114789Sahrens mutex_exit(&zp->z_acl_lock); 2115789Sahrens mutex_exit(&zp->z_lock); 2116789Sahrens 2117789Sahrens if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) { 21182113Sahrens dmu_tx_wait(tx); 21192113Sahrens dmu_tx_abort(tx); 2120789Sahrens goto top; 2121789Sahrens } 21222113Sahrens dmu_tx_abort(tx); 2123*5331Samw zfs_acl_free(aclp); 2124789Sahrens return (error); 2125789Sahrens } 2126789Sahrens 2127*5331Samw error = zfs_aclset_common(zp, aclp, &fuidp, tx); 2128789Sahrens ASSERT(error == 0); 2129789Sahrens 2130*5331Samw zfs_log_acl(zilog, tx, zp, vsecp, fuidp); 2131*5331Samw 2132*5331Samw if (fuidp) 2133*5331Samw zfs_fuid_info_free(fuidp); 2134789Sahrens zfs_acl_free(aclp); 2135789Sahrens dmu_tx_commit(tx); 2136789Sahrens done: 2137789Sahrens mutex_exit(&zp->z_acl_lock); 2138789Sahrens mutex_exit(&zp->z_lock); 2139789Sahrens 2140789Sahrens return (error); 2141789Sahrens } 2142789Sahrens 2143*5331Samw /* 2144*5331Samw * working_mode returns the permissions that were not granted 2145*5331Samw */ 2146789Sahrens static int 2147*5331Samw zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode, 2148*5331Samw boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr) 2149789Sahrens { 2150789Sahrens zfs_acl_t *aclp; 2151789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 21521544Seschrock int error; 2153789Sahrens int access_deny = ACCESS_UNDETERMINED; 2154789Sahrens uid_t uid = crgetuid(cr); 2155*5331Samw uint64_t who; 2156*5331Samw uint16_t type, iflags; 2157*5331Samw uint16_t entry_type; 2158*5331Samw uint32_t access_mask; 2159*5331Samw zfs_ace_hdr_t *acep = NULL; 2160*5331Samw boolean_t checkit; 2161*5331Samw uid_t fowner; 2162*5331Samw uid_t gowner; 2163*5331Samw 2164*5331Samw /* 2165*5331Samw * Short circuit empty requests 2166*5331Samw */ 2167*5331Samw if (v4_mode == 0) 2168*5331Samw return (0); 2169*5331Samw 2170*5331Samw *check_privs = B_TRUE; 2171789Sahrens 21722638Sperrin if (zfsvfs->z_assign >= TXG_INITIAL) { /* ZIL replay */ 21732638Sperrin *working_mode = 0; 21742638Sperrin return (0); 21752638Sperrin } 2176789Sahrens 21772638Sperrin *working_mode = v4_mode; 2178789Sahrens 2179789Sahrens if ((v4_mode & WRITE_MASK) && 2180789Sahrens (zp->z_zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) && 2181789Sahrens (!IS_DEVVP(ZTOV(zp)))) { 2182*5331Samw *check_privs = B_FALSE; 2183789Sahrens return (EROFS); 2184789Sahrens } 2185789Sahrens 2186*5331Samw /* 2187*5331Samw * Only check for READONLY on non-directories. 2188*5331Samw */ 2189*5331Samw if ((v4_mode & WRITE_MASK_DATA) && 2190*5331Samw (((ZTOV(zp)->v_type != VDIR) && 2191*5331Samw (zp->z_phys->zp_flags & (ZFS_READONLY | ZFS_IMMUTABLE))) || 2192*5331Samw (ZTOV(zp)->v_type == VDIR && 2193*5331Samw (zp->z_phys->zp_flags & ZFS_IMMUTABLE)))) { 2194*5331Samw *check_privs = B_FALSE; 2195*5331Samw return (EPERM); 2196*5331Samw } 2197*5331Samw 2198*5331Samw if ((v4_mode & (ACE_DELETE | ACE_DELETE_CHILD)) && 2199*5331Samw (zp->z_phys->zp_flags & ZFS_NOUNLINK)) { 2200*5331Samw *check_privs = B_FALSE; 2201*5331Samw return (EPERM); 2202*5331Samw } 2203*5331Samw 2204*5331Samw if (((v4_mode & (ACE_READ_DATA|ACE_EXECUTE)) && 2205*5331Samw (zp->z_phys->zp_flags & ZFS_AV_QUARANTINED))) { 2206*5331Samw *check_privs = B_FALSE; 2207*5331Samw return (EACCES); 2208*5331Samw } 2209*5331Samw 2210*5331Samw /* 2211*5331Samw * The caller requested that the ACL check be skipped. This 2212*5331Samw * would only happen if the caller checked VOP_ACCESS() with a 2213*5331Samw * 32 bit ACE mask and already had the appropriate permissions. 2214*5331Samw */ 2215*5331Samw if (skipaclchk) { 2216*5331Samw *working_mode = 0; 2217*5331Samw return (0); 2218*5331Samw } 2219*5331Samw 2220*5331Samw zfs_fuid_map_ids(zp, &fowner, &gowner); 2221*5331Samw 2222789Sahrens mutex_enter(&zp->z_acl_lock); 2223789Sahrens 2224*5331Samw error = zfs_acl_node_read(zp, &aclp, B_FALSE); 22251544Seschrock if (error != 0) { 22261544Seschrock mutex_exit(&zp->z_acl_lock); 22271544Seschrock return (error); 22281544Seschrock } 22291544Seschrock 2230*5331Samw while (acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask, 2231*5331Samw &iflags, &type)) { 2232789Sahrens 2233*5331Samw if (iflags & ACE_INHERIT_ONLY_ACE) 2234789Sahrens continue; 2235789Sahrens 2236*5331Samw entry_type = (iflags & ACE_TYPE_FLAGS); 2237*5331Samw 2238*5331Samw checkit = B_FALSE; 2239*5331Samw 2240789Sahrens switch (entry_type) { 2241789Sahrens case ACE_OWNER: 2242*5331Samw if (uid == fowner) 2243*5331Samw checkit = B_TRUE; 2244789Sahrens break; 2245*5331Samw case OWNING_GROUP: 2246*5331Samw who = gowner; 2247*5331Samw /*FALLTHROUGH*/ 2248789Sahrens case ACE_IDENTIFIER_GROUP: 2249*5331Samw checkit = zfs_groupmember(zfsvfs, who, cr); 2250789Sahrens break; 2251789Sahrens case ACE_EVERYONE: 2252*5331Samw checkit = B_TRUE; 2253789Sahrens break; 2254789Sahrens 2255789Sahrens /* USER Entry */ 2256789Sahrens default: 2257789Sahrens if (entry_type == 0) { 2258*5331Samw uid_t newid; 2259*5331Samw 2260*5331Samw zfs_fuid_map_id(zfsvfs, who, 2261*5331Samw ZFS_ACE_USER, &newid); 2262*5331Samw if (newid != IDMAP_WK_CREATOR_OWNER_UID && 2263*5331Samw uid == newid) 2264*5331Samw checkit = B_TRUE; 2265789Sahrens break; 2266*5331Samw } else { 2267*5331Samw zfs_acl_free(aclp); 2268*5331Samw mutex_exit(&zp->z_acl_lock); 2269*5331Samw return (EIO); 2270789Sahrens } 2271*5331Samw } 2272*5331Samw 2273*5331Samw if (checkit) { 2274*5331Samw if (access_mask & *working_mode) { 2275*5331Samw if (type == ALLOW) { 2276*5331Samw *working_mode &= 2277*5331Samw ~(*working_mode & access_mask); 2278*5331Samw if (*working_mode == 0) { 2279*5331Samw access_deny = 0; 2280*5331Samw } 2281*5331Samw } else if (type == DENY) { 2282*5331Samw access_deny = EACCES; 2283*5331Samw } 2284*5331Samw } 2285789Sahrens } 2286789Sahrens 2287789Sahrens if (access_deny != ACCESS_UNDETERMINED) 2288789Sahrens break; 2289789Sahrens } 2290789Sahrens 2291789Sahrens mutex_exit(&zp->z_acl_lock); 2292789Sahrens zfs_acl_free(aclp); 2293*5331Samw out: 2294789Sahrens return (access_deny); 2295789Sahrens } 2296789Sahrens 2297*5331Samw static int 2298*5331Samw zfs_zaccess_append(znode_t *zp, uint32_t *working_mode, boolean_t *check_privs, 2299*5331Samw cred_t *cr) 2300*5331Samw { 2301*5331Samw if (*working_mode != ACE_WRITE_DATA) 2302*5331Samw return (EACCES); 2303*5331Samw 2304*5331Samw return (zfs_zaccess_common(zp, ACE_APPEND_DATA, working_mode, 2305*5331Samw check_privs, B_FALSE, cr)); 2306*5331Samw } 2307789Sahrens 2308789Sahrens /* 2309789Sahrens * Determine whether Access should be granted/denied, invoking least 2310789Sahrens * priv subsytem when a deny is determined. 2311789Sahrens */ 2312789Sahrens int 2313*5331Samw zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) 2314789Sahrens { 2315*5331Samw uint32_t working_mode; 2316*5331Samw int error; 2317*5331Samw int is_attr; 2318*5331Samw zfsvfs_t *zfsvfs = zp->z_zfsvfs; 2319*5331Samw boolean_t check_privs; 2320*5331Samw znode_t *xzp; 2321*5331Samw znode_t *check_zp = zp; 2322789Sahrens 2323789Sahrens is_attr = ((zp->z_phys->zp_flags & ZFS_XATTR) && 2324789Sahrens (ZTOV(zp)->v_type == VDIR)); 2325789Sahrens 2326789Sahrens /* 2327789Sahrens * If attribute then validate against base file 2328789Sahrens */ 2329789Sahrens if (is_attr) { 2330789Sahrens if ((error = zfs_zget(zp->z_zfsvfs, 2331789Sahrens zp->z_phys->zp_parent, &xzp)) != 0) { 2332789Sahrens return (error); 2333789Sahrens } 2334*5331Samw 2335789Sahrens check_zp = xzp; 2336*5331Samw 2337789Sahrens /* 2338789Sahrens * fixup mode to map to xattr perms 2339789Sahrens */ 2340789Sahrens 2341789Sahrens if (mode & (ACE_WRITE_DATA|ACE_APPEND_DATA)) { 2342789Sahrens mode &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA); 2343789Sahrens mode |= ACE_WRITE_NAMED_ATTRS; 2344789Sahrens } 2345789Sahrens 2346789Sahrens if (mode & (ACE_READ_DATA|ACE_EXECUTE)) { 2347789Sahrens mode &= ~(ACE_READ_DATA|ACE_EXECUTE); 2348789Sahrens mode |= ACE_READ_NAMED_ATTRS; 2349789Sahrens } 2350789Sahrens } 2351789Sahrens 2352*5331Samw if ((error = zfs_zaccess_common(check_zp, mode, &working_mode, 2353*5331Samw &check_privs, skipaclchk, cr)) == 0) { 2354*5331Samw if (is_attr) 2355*5331Samw VN_RELE(ZTOV(xzp)); 2356*5331Samw return (0); 2357*5331Samw } 2358789Sahrens 2359*5331Samw if (error && check_privs == B_FALSE) { 2360789Sahrens if (is_attr) 2361789Sahrens VN_RELE(ZTOV(xzp)); 2362789Sahrens return (error); 2363789Sahrens } 2364789Sahrens 2365*5331Samw if (error && (flags & V_APPEND)) { 2366*5331Samw error = zfs_zaccess_append(zp, &working_mode, &check_privs, cr); 2367*5331Samw } 2368*5331Samw 2369*5331Samw if (error && check_privs) { 2370*5331Samw uid_t owner; 2371*5331Samw mode_t checkmode = 0; 2372*5331Samw 2373*5331Samw zfs_fuid_map_id(zfsvfs, check_zp->z_phys->zp_uid, 2374*5331Samw ZFS_OWNER, &owner); 2375*5331Samw 2376*5331Samw /* 2377*5331Samw * First check for implicit owner permission on 2378*5331Samw * read_acl/read_attributes 2379*5331Samw */ 2380*5331Samw 2381*5331Samw error = 0; 2382*5331Samw ASSERT(working_mode != 0); 2383*5331Samw 2384*5331Samw if ((working_mode & (ACE_READ_ACL|ACE_READ_ATTRIBUTES) && 2385*5331Samw owner == crgetuid(cr))) 2386*5331Samw working_mode &= ~(ACE_READ_ACL|ACE_READ_ATTRIBUTES); 2387*5331Samw 2388*5331Samw if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS| 2389*5331Samw ACE_READ_ACL|ACE_READ_ATTRIBUTES)) 2390*5331Samw checkmode |= VREAD; 2391*5331Samw if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS| 2392*5331Samw ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES)) 2393*5331Samw checkmode |= VWRITE; 2394*5331Samw if (working_mode & ACE_EXECUTE) 2395*5331Samw checkmode |= VEXEC; 2396*5331Samw 2397*5331Samw if (checkmode) 2398*5331Samw error = secpolicy_vnode_access(cr, ZTOV(check_zp), 2399*5331Samw owner, checkmode); 2400*5331Samw 2401*5331Samw if (error == 0 && (working_mode & ACE_WRITE_OWNER)) 2402*5331Samw error = secpolicy_vnode_create_gid(cr); 2403*5331Samw if (error == 0 && (working_mode & ACE_WRITE_ACL)) 2404*5331Samw error = secpolicy_vnode_setdac(cr, owner); 2405*5331Samw 2406*5331Samw if (error == 0 && (working_mode & 2407*5331Samw (ACE_DELETE|ACE_DELETE_CHILD))) 2408*5331Samw error = secpolicy_vnode_remove(cr); 2409*5331Samw 2410*5331Samw if (error == 0 && (working_mode & ACE_SYNCHRONIZE)) 2411*5331Samw error = secpolicy_vnode_owner(cr, owner); 2412*5331Samw 2413*5331Samw if (error == 0) { 2414*5331Samw /* 2415*5331Samw * See if any bits other than those already checked 2416*5331Samw * for are still present. If so then return EACCES 2417*5331Samw */ 2418*5331Samw if (working_mode & ~(ZFS_CHECKED_MASKS)) { 2419*5331Samw error = EACCES; 2420*5331Samw } 2421*5331Samw } 2422789Sahrens } 2423789Sahrens 2424789Sahrens if (is_attr) 2425789Sahrens VN_RELE(ZTOV(xzp)); 2426789Sahrens 2427789Sahrens return (error); 2428789Sahrens } 2429789Sahrens 2430789Sahrens /* 2431*5331Samw * Translate traditional unix VREAD/VWRITE/VEXEC mode into 2432*5331Samw * native ACL format and call zfs_zaccess() 2433789Sahrens */ 2434789Sahrens int 2435*5331Samw zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr) 2436789Sahrens { 2437*5331Samw return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr)); 2438789Sahrens } 2439789Sahrens 2440789Sahrens /* 2441*5331Samw * Access function for secpolicy_vnode_setattr 2442789Sahrens */ 2443789Sahrens int 2444*5331Samw zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr) 2445789Sahrens { 2446789Sahrens int v4_mode = zfs_unix_to_v4(mode >> 6); 2447789Sahrens 2448*5331Samw return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr)); 2449789Sahrens } 2450789Sahrens 24512604Smarks static int 24522604Smarks zfs_delete_final_check(znode_t *zp, znode_t *dzp, cred_t *cr) 24532604Smarks { 24542604Smarks int error; 2455*5331Samw uid_t downer; 2456*5331Samw zfsvfs_t *zfsvfs = zp->z_zfsvfs; 24572604Smarks 2458*5331Samw zfs_fuid_map_id(zfsvfs, dzp->z_phys->zp_uid, ZFS_OWNER, &downer); 2459*5331Samw 2460*5331Samw error = secpolicy_vnode_access(cr, ZTOV(zp), downer, S_IWRITE|S_IEXEC); 24612604Smarks 24622604Smarks if (error == 0) 24632604Smarks error = zfs_sticky_remove_access(dzp, zp, cr); 24642604Smarks 24652604Smarks return (error); 24662604Smarks } 24672604Smarks 2468789Sahrens /* 2469789Sahrens * Determine whether Access should be granted/deny, without 2470789Sahrens * consulting least priv subsystem. 2471789Sahrens * 2472789Sahrens * 2473789Sahrens * The following chart is the recommended NFSv4 enforcement for 2474789Sahrens * ability to delete an object. 2475789Sahrens * 2476789Sahrens * ------------------------------------------------------- 2477789Sahrens * | Parent Dir | Target Object Permissions | 2478789Sahrens * | permissions | | 2479789Sahrens * ------------------------------------------------------- 2480789Sahrens * | | ACL Allows | ACL Denies| Delete | 2481789Sahrens * | | Delete | Delete | unspecified| 2482789Sahrens * ------------------------------------------------------- 2483789Sahrens * | ACL Allows | Permit | Permit | Permit | 2484789Sahrens * | DELETE_CHILD | | 2485789Sahrens * ------------------------------------------------------- 2486789Sahrens * | ACL Denies | Permit | Deny | Deny | 2487789Sahrens * | DELETE_CHILD | | | | 2488789Sahrens * ------------------------------------------------------- 2489789Sahrens * | ACL specifies | | | | 2490789Sahrens * | only allow | Permit | Permit | Permit | 2491789Sahrens * | write and | | | | 2492789Sahrens * | execute | | | | 2493789Sahrens * ------------------------------------------------------- 2494789Sahrens * | ACL denies | | | | 2495789Sahrens * | write and | Permit | Deny | Deny | 2496789Sahrens * | execute | | | | 2497789Sahrens * ------------------------------------------------------- 2498789Sahrens * ^ 2499789Sahrens * | 2500789Sahrens * No search privilege, can't even look up file? 2501789Sahrens * 2502789Sahrens */ 2503789Sahrens int 2504789Sahrens zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) 2505789Sahrens { 2506*5331Samw uint32_t dzp_working_mode = 0; 2507*5331Samw uint32_t zp_working_mode = 0; 2508789Sahrens int dzp_error, zp_error; 2509*5331Samw boolean_t dzpcheck_privs = B_TRUE; 2510*5331Samw boolean_t zpcheck_privs = B_TRUE; 2511789Sahrens 2512789Sahrens /* 2513789Sahrens * Arghh, this check is going to require a couple of questions 2514789Sahrens * to be asked. We want specific DELETE permissions to 2515789Sahrens * take precedence over WRITE/EXECUTE. We don't 2516789Sahrens * want an ACL such as this to mess us up. 25172604Smarks * user:joe:write_data:deny,user:joe:delete:allow 2518789Sahrens * 2519789Sahrens * However, deny permissions may ultimately be overridden 2520789Sahrens * by secpolicy_vnode_access(). 2521789Sahrens */ 2522789Sahrens 2523*5331Samw if (zp->z_phys->zp_flags & (ZFS_IMMUTABLE | ZFS_NOUNLINK)) 2524*5331Samw return (EPERM); 2525*5331Samw 2526789Sahrens dzp_error = zfs_zaccess_common(dzp, ACE_DELETE_CHILD, 2527*5331Samw &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr); 2528*5331Samw zp_error = zfs_zaccess_common(zp, ACE_DELETE, &zp_working_mode, 2529*5331Samw &zpcheck_privs, B_FALSE, cr); 2530789Sahrens 2531*5331Samw if ((dzp_error && dzpcheck_privs == B_FALSE) || 2532*5331Samw (zp_error && zpcheck_privs == B_FALSE)) 2533789Sahrens return (dzp_error); 2534789Sahrens 2535789Sahrens /* 25362604Smarks * First check the first row. 25372604Smarks * We only need to see if parent Allows delete_child 2538789Sahrens */ 25391576Smarks if ((dzp_working_mode & ACE_DELETE_CHILD) == 0) 2540789Sahrens return (0); 2541789Sahrens 2542789Sahrens /* 2543789Sahrens * Second row 25442604Smarks * we already have the necessary information in 25452604Smarks * zp_working_mode, zp_error and dzp_error. 2546789Sahrens */ 2547789Sahrens 25481576Smarks if ((zp_working_mode & ACE_DELETE) == 0) 2549789Sahrens return (0); 2550789Sahrens 2551789Sahrens /* 25522604Smarks * Now zp_error should either be EACCES which indicates 25532604Smarks * a "deny" delete entry or ACCESS_UNDETERMINED if the "delete" 25542604Smarks * entry exists on the target. 25552604Smarks * 25562604Smarks * dzp_error should be either EACCES which indicates a "deny" 25572604Smarks * entry for delete_child or ACCESS_UNDETERMINED if no delete_child 25582604Smarks * entry exists. If value is EACCES then we are done 25592604Smarks * and zfs_delete_final_check() will make the final decision 25602604Smarks * regarding to allow the delete. 25612604Smarks */ 25622604Smarks 25632604Smarks ASSERT(zp_error != 0 && dzp_error != 0); 25642604Smarks if (dzp_error == EACCES) 25652604Smarks return (zfs_delete_final_check(zp, dzp, cr)); 25662604Smarks 25672604Smarks /* 2568789Sahrens * Third Row 25692604Smarks * Only need to check for write/execute on parent 2570789Sahrens */ 2571789Sahrens 2572789Sahrens dzp_error = zfs_zaccess_common(dzp, ACE_WRITE_DATA|ACE_EXECUTE, 2573*5331Samw &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr); 2574789Sahrens 2575*5331Samw if (dzp_error && dzpcheck_privs == B_FALSE) 2576789Sahrens return (dzp_error); 2577789Sahrens 25781576Smarks if ((dzp_working_mode & (ACE_WRITE_DATA|ACE_EXECUTE)) == 0) 25792604Smarks return (zfs_sticky_remove_access(dzp, zp, cr)); 2580789Sahrens 2581789Sahrens /* 2582789Sahrens * Fourth Row 2583789Sahrens */ 2584789Sahrens 25851576Smarks if (((dzp_working_mode & (ACE_WRITE_DATA|ACE_EXECUTE)) != 0) && 25861576Smarks ((zp_working_mode & ACE_DELETE) == 0)) 25872604Smarks return (zfs_sticky_remove_access(dzp, zp, cr)); 2588789Sahrens 25892604Smarks return (zfs_delete_final_check(zp, dzp, cr)); 2590789Sahrens } 2591789Sahrens 2592789Sahrens int 2593789Sahrens zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp, 2594789Sahrens znode_t *tzp, cred_t *cr) 2595789Sahrens { 2596789Sahrens int add_perm; 2597789Sahrens int error; 2598789Sahrens 2599*5331Samw if (szp->z_phys->zp_flags & ZFS_AV_QUARANTINED) 2600*5331Samw return (EACCES); 2601*5331Samw 2602789Sahrens add_perm = (ZTOV(szp)->v_type == VDIR) ? 2603789Sahrens ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE; 2604789Sahrens 2605789Sahrens /* 2606789Sahrens * Rename permissions are combination of delete permission + 2607789Sahrens * add file/subdir permission. 2608789Sahrens */ 2609789Sahrens 2610789Sahrens /* 2611789Sahrens * first make sure we do the delete portion. 2612789Sahrens * 2613789Sahrens * If that succeeds then check for add_file/add_subdir permissions 2614789Sahrens */ 2615789Sahrens 2616789Sahrens if (error = zfs_zaccess_delete(sdzp, szp, cr)) 2617789Sahrens return (error); 2618789Sahrens 2619789Sahrens /* 2620789Sahrens * If we have a tzp, see if we can delete it? 2621789Sahrens */ 2622789Sahrens if (tzp) { 2623789Sahrens if (error = zfs_zaccess_delete(tdzp, tzp, cr)) 2624789Sahrens return (error); 2625789Sahrens } 2626789Sahrens 2627789Sahrens /* 2628789Sahrens * Now check for add permissions 2629789Sahrens */ 2630*5331Samw error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr); 2631789Sahrens 2632789Sahrens return (error); 2633789Sahrens } 2634