1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "@(#)zfs_acl.c 1.20 08/01/04 SMI" 27 28 #include <sys/types.h> 29 #include <sys/param.h> 30 #include <sys/time.h> 31 #include <sys/systm.h> 32 #include <sys/sysmacros.h> 33 #include <sys/resource.h> 34 #include <sys/vfs.h> 35 #include <sys/vnode.h> 36 #include <sys/sid.h> 37 #include <sys/file.h> 38 #include <sys/stat.h> 39 #include <sys/kmem.h> 40 #include <sys/cmn_err.h> 41 #include <sys/errno.h> 42 #include <sys/unistd.h> 43 #include <sys/sdt.h> 44 #include <sys/fs/zfs.h> 45 #include <sys/mode.h> 46 #include <sys/policy.h> 47 #include <sys/zfs_znode.h> 48 #include <sys/zfs_fuid.h> 49 #include <sys/zfs_acl.h> 50 #include <sys/zfs_dir.h> 51 #include <sys/zfs_vfsops.h> 52 #include <sys/dmu.h> 53 #include <sys/dnode.h> 54 #include <sys/zap.h> 55 #include "fs/fs_subr.h" 56 #include <acl/acl_common.h> 57 58 #define ALLOW ACE_ACCESS_ALLOWED_ACE_TYPE 59 #define DENY ACE_ACCESS_DENIED_ACE_TYPE 60 #define MAX_ACE_TYPE ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE 61 62 #define OWNING_GROUP (ACE_GROUP|ACE_IDENTIFIER_GROUP) 63 #define EVERYONE_ALLOW_MASK (ACE_READ_ACL|ACE_READ_ATTRIBUTES | \ 64 ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE) 65 #define EVERYONE_DENY_MASK (ACE_WRITE_ACL|ACE_WRITE_OWNER | \ 66 ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS) 67 #define OWNER_ALLOW_MASK (ACE_WRITE_ACL | ACE_WRITE_OWNER | \ 68 ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS) 69 #define WRITE_MASK_DATA (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_NAMED_ATTRS) 70 71 #define ZFS_CHECKED_MASKS (ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_DATA| \ 72 ACE_READ_NAMED_ATTRS|ACE_WRITE_DATA|ACE_WRITE_ATTRIBUTES| \ 73 ACE_WRITE_NAMED_ATTRS|ACE_APPEND_DATA|ACE_EXECUTE|ACE_WRITE_OWNER| \ 74 ACE_WRITE_ACL|ACE_DELETE|ACE_DELETE_CHILD|ACE_SYNCHRONIZE) 75 76 #define WRITE_MASK (WRITE_MASK_DATA|ACE_WRITE_ATTRIBUTES|ACE_WRITE_ACL|\ 77 ACE_WRITE_OWNER) 78 79 #define OGE_CLEAR (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \ 80 ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE) 81 82 #define OKAY_MASK_BITS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \ 83 ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE) 84 85 #define ALL_INHERIT (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE | \ 86 ACE_NO_PROPAGATE_INHERIT_ACE|ACE_INHERIT_ONLY_ACE|ACE_INHERITED_ACE) 87 88 #define SECURE_CLEAR (ACE_WRITE_ACL|ACE_WRITE_OWNER) 89 90 #define V4_ACL_WIDE_FLAGS (ZFS_ACL_AUTO_INHERIT|ZFS_ACL_DEFAULTED|\ 91 ZFS_ACL_PROTECTED) 92 93 #define ZFS_ACL_WIDE_FLAGS (V4_ACL_WIDE_FLAGS|ZFS_ACL_TRIVIAL|ZFS_INHERIT_ACE|\ 94 ZFS_ACL_OBJ_ACE) 95 96 static uint16_t 97 zfs_ace_v0_get_type(void *acep) 98 { 99 return (((zfs_oldace_t *)acep)->z_type); 100 } 101 102 static uint16_t 103 zfs_ace_v0_get_flags(void *acep) 104 { 105 return (((zfs_oldace_t *)acep)->z_flags); 106 } 107 108 static uint32_t 109 zfs_ace_v0_get_mask(void *acep) 110 { 111 return (((zfs_oldace_t *)acep)->z_access_mask); 112 } 113 114 static uint64_t 115 zfs_ace_v0_get_who(void *acep) 116 { 117 return (((zfs_oldace_t *)acep)->z_fuid); 118 } 119 120 static void 121 zfs_ace_v0_set_type(void *acep, uint16_t type) 122 { 123 ((zfs_oldace_t *)acep)->z_type = type; 124 } 125 126 static void 127 zfs_ace_v0_set_flags(void *acep, uint16_t flags) 128 { 129 ((zfs_oldace_t *)acep)->z_flags = flags; 130 } 131 132 static void 133 zfs_ace_v0_set_mask(void *acep, uint32_t mask) 134 { 135 ((zfs_oldace_t *)acep)->z_access_mask = mask; 136 } 137 138 static void 139 zfs_ace_v0_set_who(void *acep, uint64_t who) 140 { 141 ((zfs_oldace_t *)acep)->z_fuid = who; 142 } 143 144 /*ARGSUSED*/ 145 static size_t 146 zfs_ace_v0_size(void *acep) 147 { 148 return (sizeof (zfs_oldace_t)); 149 } 150 151 static size_t 152 zfs_ace_v0_abstract_size(void) 153 { 154 return (sizeof (zfs_oldace_t)); 155 } 156 157 static int 158 zfs_ace_v0_mask_off(void) 159 { 160 return (offsetof(zfs_oldace_t, z_access_mask)); 161 } 162 163 /*ARGSUSED*/ 164 static int 165 zfs_ace_v0_data(void *acep, void **datap) 166 { 167 *datap = NULL; 168 return (0); 169 } 170 171 static acl_ops_t zfs_acl_v0_ops = { 172 zfs_ace_v0_get_mask, 173 zfs_ace_v0_set_mask, 174 zfs_ace_v0_get_flags, 175 zfs_ace_v0_set_flags, 176 zfs_ace_v0_get_type, 177 zfs_ace_v0_set_type, 178 zfs_ace_v0_get_who, 179 zfs_ace_v0_set_who, 180 zfs_ace_v0_size, 181 zfs_ace_v0_abstract_size, 182 zfs_ace_v0_mask_off, 183 zfs_ace_v0_data 184 }; 185 186 static uint16_t 187 zfs_ace_fuid_get_type(void *acep) 188 { 189 return (((zfs_ace_hdr_t *)acep)->z_type); 190 } 191 192 static uint16_t 193 zfs_ace_fuid_get_flags(void *acep) 194 { 195 return (((zfs_ace_hdr_t *)acep)->z_flags); 196 } 197 198 static uint32_t 199 zfs_ace_fuid_get_mask(void *acep) 200 { 201 return (((zfs_ace_hdr_t *)acep)->z_access_mask); 202 } 203 204 static uint64_t 205 zfs_ace_fuid_get_who(void *args) 206 { 207 uint16_t entry_type; 208 zfs_ace_t *acep = args; 209 210 entry_type = acep->z_hdr.z_flags & ACE_TYPE_FLAGS; 211 212 if (entry_type == ACE_OWNER || entry_type == OWNING_GROUP || 213 entry_type == ACE_EVERYONE) 214 return (-1); 215 return (((zfs_ace_t *)acep)->z_fuid); 216 } 217 218 static void 219 zfs_ace_fuid_set_type(void *acep, uint16_t type) 220 { 221 ((zfs_ace_hdr_t *)acep)->z_type = type; 222 } 223 224 static void 225 zfs_ace_fuid_set_flags(void *acep, uint16_t flags) 226 { 227 ((zfs_ace_hdr_t *)acep)->z_flags = flags; 228 } 229 230 static void 231 zfs_ace_fuid_set_mask(void *acep, uint32_t mask) 232 { 233 ((zfs_ace_hdr_t *)acep)->z_access_mask = mask; 234 } 235 236 static void 237 zfs_ace_fuid_set_who(void *arg, uint64_t who) 238 { 239 zfs_ace_t *acep = arg; 240 241 uint16_t entry_type = acep->z_hdr.z_flags & ACE_TYPE_FLAGS; 242 243 if (entry_type == ACE_OWNER || entry_type == OWNING_GROUP || 244 entry_type == ACE_EVERYONE) 245 return; 246 acep->z_fuid = who; 247 } 248 249 static size_t 250 zfs_ace_fuid_size(void *acep) 251 { 252 zfs_ace_hdr_t *zacep = acep; 253 uint16_t entry_type; 254 255 switch (zacep->z_type) { 256 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 257 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 258 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 259 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 260 return (sizeof (zfs_object_ace_t)); 261 case ALLOW: 262 case DENY: 263 entry_type = 264 (((zfs_ace_hdr_t *)acep)->z_flags & ACE_TYPE_FLAGS); 265 if (entry_type == ACE_OWNER || 266 entry_type == (ACE_GROUP | ACE_IDENTIFIER_GROUP) || 267 entry_type == ACE_EVERYONE) 268 return (sizeof (zfs_ace_hdr_t)); 269 /*FALLTHROUGH*/ 270 default: 271 return (sizeof (zfs_ace_t)); 272 } 273 } 274 275 static size_t 276 zfs_ace_fuid_abstract_size(void) 277 { 278 return (sizeof (zfs_ace_hdr_t)); 279 } 280 281 static int 282 zfs_ace_fuid_mask_off(void) 283 { 284 return (offsetof(zfs_ace_hdr_t, z_access_mask)); 285 } 286 287 static int 288 zfs_ace_fuid_data(void *acep, void **datap) 289 { 290 zfs_ace_t *zacep = acep; 291 zfs_object_ace_t *zobjp; 292 293 switch (zacep->z_hdr.z_type) { 294 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 295 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 296 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 297 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 298 zobjp = acep; 299 *datap = (caddr_t)zobjp + sizeof (zfs_ace_t); 300 return (sizeof (zfs_object_ace_t) - sizeof (zfs_ace_t)); 301 default: 302 *datap = NULL; 303 return (0); 304 } 305 } 306 307 static acl_ops_t zfs_acl_fuid_ops = { 308 zfs_ace_fuid_get_mask, 309 zfs_ace_fuid_set_mask, 310 zfs_ace_fuid_get_flags, 311 zfs_ace_fuid_set_flags, 312 zfs_ace_fuid_get_type, 313 zfs_ace_fuid_set_type, 314 zfs_ace_fuid_get_who, 315 zfs_ace_fuid_set_who, 316 zfs_ace_fuid_size, 317 zfs_ace_fuid_abstract_size, 318 zfs_ace_fuid_mask_off, 319 zfs_ace_fuid_data 320 }; 321 322 static int 323 zfs_acl_version(int version) 324 { 325 if (version < ZPL_VERSION_FUID) 326 return (ZFS_ACL_VERSION_INITIAL); 327 else 328 return (ZFS_ACL_VERSION_FUID); 329 } 330 331 static int 332 zfs_acl_version_zp(znode_t *zp) 333 { 334 return (zfs_acl_version(zp->z_zfsvfs->z_version)); 335 } 336 337 static zfs_acl_t * 338 zfs_acl_alloc(int vers) 339 { 340 zfs_acl_t *aclp; 341 342 aclp = kmem_zalloc(sizeof (zfs_acl_t), KM_SLEEP); 343 list_create(&aclp->z_acl, sizeof (zfs_acl_node_t), 344 offsetof(zfs_acl_node_t, z_next)); 345 aclp->z_version = vers; 346 if (vers == ZFS_ACL_VERSION_FUID) 347 aclp->z_ops = zfs_acl_fuid_ops; 348 else 349 aclp->z_ops = zfs_acl_v0_ops; 350 return (aclp); 351 } 352 353 static zfs_acl_node_t * 354 zfs_acl_node_alloc(size_t bytes) 355 { 356 zfs_acl_node_t *aclnode; 357 358 aclnode = kmem_zalloc(sizeof (zfs_acl_node_t), KM_SLEEP); 359 if (bytes) { 360 aclnode->z_acldata = kmem_alloc(bytes, KM_SLEEP); 361 aclnode->z_allocdata = aclnode->z_acldata; 362 aclnode->z_allocsize = bytes; 363 aclnode->z_size = bytes; 364 } 365 366 return (aclnode); 367 } 368 369 static void 370 zfs_acl_node_free(zfs_acl_node_t *aclnode) 371 { 372 if (aclnode->z_allocsize) 373 kmem_free(aclnode->z_allocdata, aclnode->z_allocsize); 374 kmem_free(aclnode, sizeof (zfs_acl_node_t)); 375 } 376 377 static void 378 zfs_acl_release_nodes(zfs_acl_t *aclp) 379 { 380 zfs_acl_node_t *aclnode; 381 382 while (aclnode = list_head(&aclp->z_acl)) { 383 list_remove(&aclp->z_acl, aclnode); 384 zfs_acl_node_free(aclnode); 385 } 386 aclp->z_acl_count = 0; 387 aclp->z_acl_bytes = 0; 388 } 389 390 void 391 zfs_acl_free(zfs_acl_t *aclp) 392 { 393 zfs_acl_release_nodes(aclp); 394 list_destroy(&aclp->z_acl); 395 kmem_free(aclp, sizeof (zfs_acl_t)); 396 } 397 398 static boolean_t 399 zfs_ace_valid(vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags) 400 { 401 /* 402 * first check type of entry 403 */ 404 405 switch (iflags & ACE_TYPE_FLAGS) { 406 case ACE_OWNER: 407 case (ACE_IDENTIFIER_GROUP | ACE_GROUP): 408 case ACE_IDENTIFIER_GROUP: 409 case ACE_EVERYONE: 410 case 0: /* User entry */ 411 break; 412 default: 413 return (B_FALSE); 414 415 } 416 417 /* 418 * next check inheritance level flags 419 */ 420 421 if (type != ALLOW && type > MAX_ACE_TYPE) { 422 return (B_FALSE); 423 } 424 425 switch (type) { 426 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 427 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 428 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 429 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 430 if (aclp->z_version < ZFS_ACL_VERSION_FUID) 431 return (B_FALSE); 432 aclp->z_hints |= ZFS_ACL_OBJ_ACE; 433 } 434 435 /* 436 * Only directories should have inheritance flags. 437 */ 438 if (obj_type != VDIR && (iflags & 439 (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE| 440 ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE))) { 441 return (B_FALSE); 442 } 443 444 if (iflags & (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE)) 445 aclp->z_hints |= ZFS_INHERIT_ACE; 446 447 if (iflags & (ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE)) { 448 if ((iflags & (ACE_FILE_INHERIT_ACE| 449 ACE_DIRECTORY_INHERIT_ACE)) == 0) { 450 return (B_FALSE); 451 } 452 } 453 454 return (B_TRUE); 455 } 456 457 static void * 458 zfs_acl_next_ace(zfs_acl_t *aclp, void *start, uint64_t *who, 459 uint32_t *access_mask, uint16_t *iflags, uint16_t *type) 460 { 461 zfs_acl_node_t *aclnode; 462 463 if (start == NULL) { 464 aclnode = list_head(&aclp->z_acl); 465 if (aclnode == NULL) 466 return (NULL); 467 468 aclp->z_next_ace = aclnode->z_acldata; 469 aclp->z_curr_node = aclnode; 470 aclnode->z_ace_idx = 0; 471 } 472 473 aclnode = aclp->z_curr_node; 474 475 if (aclnode == NULL) 476 return (NULL); 477 478 if (aclnode->z_ace_idx >= aclnode->z_ace_count) { 479 aclnode = list_next(&aclp->z_acl, aclnode); 480 if (aclnode == NULL) 481 return (NULL); 482 else { 483 aclp->z_curr_node = aclnode; 484 aclnode->z_ace_idx = 0; 485 aclp->z_next_ace = aclnode->z_acldata; 486 } 487 } 488 489 if (aclnode->z_ace_idx < aclnode->z_ace_count) { 490 void *acep = aclp->z_next_ace; 491 *iflags = aclp->z_ops.ace_flags_get(acep); 492 *type = aclp->z_ops.ace_type_get(acep); 493 *access_mask = aclp->z_ops.ace_mask_get(acep); 494 *who = aclp->z_ops.ace_who_get(acep); 495 aclp->z_next_ace = (caddr_t)aclp->z_next_ace + 496 aclp->z_ops.ace_size(acep); 497 aclnode->z_ace_idx++; 498 return ((void *)acep); 499 } 500 return (NULL); 501 } 502 503 /*ARGSUSED*/ 504 static uint64_t 505 zfs_ace_walk(void *datap, uint64_t cookie, int aclcnt, 506 uint16_t *flags, uint16_t *type, uint32_t *mask) 507 { 508 zfs_acl_t *aclp = datap; 509 zfs_ace_hdr_t *acep = (zfs_ace_hdr_t *)(uintptr_t)cookie; 510 uint64_t who; 511 512 acep = zfs_acl_next_ace(aclp, acep, &who, mask, 513 flags, type); 514 return ((uint64_t)(uintptr_t)acep); 515 } 516 517 static zfs_acl_node_t * 518 zfs_acl_curr_node(zfs_acl_t *aclp) 519 { 520 ASSERT(aclp->z_curr_node); 521 return (aclp->z_curr_node); 522 } 523 524 /* 525 * Copy ACE to internal ZFS format. 526 * While processing the ACL each ACE will be validated for correctness. 527 * ACE FUIDs will be created later. 528 */ 529 int 530 zfs_copy_ace_2_fuid(vtype_t obj_type, zfs_acl_t *aclp, void *datap, 531 zfs_ace_t *z_acl, int aclcnt, size_t *size) 532 { 533 int i; 534 uint16_t entry_type; 535 zfs_ace_t *aceptr = z_acl; 536 ace_t *acep = datap; 537 zfs_object_ace_t *zobjacep; 538 ace_object_t *aceobjp; 539 540 for (i = 0; i != aclcnt; i++) { 541 aceptr->z_hdr.z_access_mask = acep->a_access_mask; 542 aceptr->z_hdr.z_flags = acep->a_flags; 543 aceptr->z_hdr.z_type = acep->a_type; 544 entry_type = aceptr->z_hdr.z_flags & ACE_TYPE_FLAGS; 545 if (entry_type != ACE_OWNER && entry_type != OWNING_GROUP && 546 entry_type != ACE_EVERYONE) 547 aceptr->z_fuid = (uint64_t)acep->a_who; 548 /* 549 * Make sure ACE is valid 550 */ 551 if (zfs_ace_valid(obj_type, aclp, aceptr->z_hdr.z_type, 552 aceptr->z_hdr.z_flags) != B_TRUE) 553 return (EINVAL); 554 555 switch (acep->a_type) { 556 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 557 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 558 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 559 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 560 zobjacep = (zfs_object_ace_t *)aceptr; 561 aceobjp = (ace_object_t *)acep; 562 563 bcopy(aceobjp->a_obj_type, zobjacep->z_object_type, 564 sizeof (aceobjp->a_obj_type)); 565 bcopy(aceobjp->a_inherit_obj_type, 566 zobjacep->z_inherit_type, 567 sizeof (aceobjp->a_inherit_obj_type)); 568 acep = (ace_t *)((caddr_t)acep + sizeof (ace_object_t)); 569 break; 570 default: 571 acep = (ace_t *)((caddr_t)acep + sizeof (ace_t)); 572 } 573 574 aceptr = (zfs_ace_t *)((caddr_t)aceptr + 575 aclp->z_ops.ace_size(aceptr)); 576 } 577 578 *size = (caddr_t)aceptr - (caddr_t)z_acl; 579 580 return (0); 581 } 582 583 /* 584 * Copy ZFS ACEs to fixed size ace_t layout 585 */ 586 static void 587 zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr, 588 void *datap, int filter) 589 { 590 uint64_t who; 591 uint32_t access_mask; 592 uint16_t iflags, type; 593 zfs_ace_hdr_t *zacep = NULL; 594 ace_t *acep = datap; 595 ace_object_t *objacep; 596 zfs_object_ace_t *zobjacep; 597 zfs_fuid_hdl_t hdl = { 0 }; 598 size_t ace_size; 599 uint16_t entry_type; 600 601 while (zacep = zfs_acl_next_ace(aclp, zacep, 602 &who, &access_mask, &iflags, &type)) { 603 604 switch (type) { 605 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE: 606 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE: 607 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE: 608 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE: 609 if (filter) { 610 continue; 611 } 612 zobjacep = (zfs_object_ace_t *)zacep; 613 objacep = (ace_object_t *)acep; 614 bcopy(zobjacep->z_object_type, 615 objacep->a_obj_type, 616 sizeof (zobjacep->z_object_type)); 617 bcopy(zobjacep->z_inherit_type, 618 objacep->a_inherit_obj_type, 619 sizeof (zobjacep->z_inherit_type)); 620 ace_size = sizeof (ace_object_t); 621 break; 622 default: 623 ace_size = sizeof (ace_t); 624 break; 625 } 626 627 entry_type = (iflags & ACE_TYPE_FLAGS); 628 if ((entry_type != ACE_OWNER && 629 entry_type != (ACE_GROUP | ACE_IDENTIFIER_GROUP) && 630 entry_type != ACE_EVERYONE)) 631 zfs_fuid_queue_map_id(zfsvfs, &hdl, who, cr, 632 (entry_type & ACE_IDENTIFIER_GROUP) ? 633 ZFS_ACE_GROUP : ZFS_ACE_USER, &acep->a_who); 634 else 635 acep->a_who = (uid_t)(int64_t)who; 636 acep->a_access_mask = access_mask; 637 acep->a_flags = iflags; 638 acep->a_type = type; 639 acep = (ace_t *)((caddr_t)acep + ace_size); 640 } 641 zfs_fuid_get_mappings(&hdl); 642 } 643 644 static int 645 zfs_copy_ace_2_oldace(vtype_t obj_type, zfs_acl_t *aclp, ace_t *acep, 646 zfs_oldace_t *z_acl, int aclcnt, size_t *size) 647 { 648 int i; 649 zfs_oldace_t *aceptr = z_acl; 650 651 for (i = 0; i != aclcnt; i++, aceptr++) { 652 aceptr->z_access_mask = acep[i].a_access_mask; 653 aceptr->z_type = acep[i].a_type; 654 aceptr->z_flags = acep[i].a_flags; 655 aceptr->z_fuid = acep[i].a_who; 656 /* 657 * Make sure ACE is valid 658 */ 659 if (zfs_ace_valid(obj_type, aclp, aceptr->z_type, 660 aceptr->z_flags) != B_TRUE) 661 return (EINVAL); 662 } 663 *size = (caddr_t)aceptr - (caddr_t)z_acl; 664 return (0); 665 } 666 667 /* 668 * convert old ACL format to new 669 */ 670 void 671 zfs_acl_xform(znode_t *zp, zfs_acl_t *aclp) 672 { 673 zfs_oldace_t *oldaclp; 674 int i; 675 uint16_t type, iflags; 676 uint32_t access_mask; 677 uint64_t who; 678 void *cookie = NULL; 679 zfs_acl_node_t *newaclnode; 680 681 ASSERT(aclp->z_version == ZFS_ACL_VERSION_INITIAL); 682 /* 683 * First create the ACE in a contiguous piece of memory 684 * for zfs_copy_ace_2_fuid(). 685 * 686 * We only convert an ACL once, so this won't happen 687 * everytime. 688 */ 689 oldaclp = kmem_alloc(sizeof (zfs_oldace_t) * aclp->z_acl_count, 690 KM_SLEEP); 691 i = 0; 692 while (cookie = zfs_acl_next_ace(aclp, cookie, &who, 693 &access_mask, &iflags, &type)) { 694 oldaclp[i].z_flags = iflags; 695 oldaclp[i].z_type = type; 696 oldaclp[i].z_fuid = who; 697 oldaclp[i++].z_access_mask = access_mask; 698 } 699 700 newaclnode = zfs_acl_node_alloc(aclp->z_acl_count * 701 sizeof (zfs_object_ace_t)); 702 aclp->z_ops = zfs_acl_fuid_ops; 703 VERIFY(zfs_copy_ace_2_fuid(ZTOV(zp)->v_type, aclp, oldaclp, 704 newaclnode->z_acldata, aclp->z_acl_count, 705 &newaclnode->z_size) == 0); 706 newaclnode->z_ace_count = aclp->z_acl_count; 707 aclp->z_version = ZFS_ACL_VERSION; 708 kmem_free(oldaclp, aclp->z_acl_count * sizeof (zfs_oldace_t)); 709 710 /* 711 * Release all previous ACL nodes 712 */ 713 714 zfs_acl_release_nodes(aclp); 715 716 list_insert_head(&aclp->z_acl, newaclnode); 717 718 aclp->z_acl_bytes = newaclnode->z_size; 719 aclp->z_acl_count = newaclnode->z_ace_count; 720 721 } 722 723 /* 724 * Convert unix access mask to v4 access mask 725 */ 726 static uint32_t 727 zfs_unix_to_v4(uint32_t access_mask) 728 { 729 uint32_t new_mask = 0; 730 731 if (access_mask & S_IXOTH) 732 new_mask |= ACE_EXECUTE; 733 if (access_mask & S_IWOTH) 734 new_mask |= ACE_WRITE_DATA; 735 if (access_mask & S_IROTH) 736 new_mask |= ACE_READ_DATA; 737 return (new_mask); 738 } 739 740 static void 741 zfs_set_ace(zfs_acl_t *aclp, void *acep, uint32_t access_mask, 742 uint16_t access_type, uint64_t fuid, uint16_t entry_type) 743 { 744 uint16_t type = entry_type & ACE_TYPE_FLAGS; 745 746 aclp->z_ops.ace_mask_set(acep, access_mask); 747 aclp->z_ops.ace_type_set(acep, access_type); 748 aclp->z_ops.ace_flags_set(acep, entry_type); 749 if ((type != ACE_OWNER && type != (ACE_GROUP | ACE_IDENTIFIER_GROUP) && 750 type != ACE_EVERYONE)) 751 aclp->z_ops.ace_who_set(acep, fuid); 752 } 753 754 /* 755 * Determine mode of file based on ACL. 756 * Also, create FUIDs for any User/Group ACEs 757 */ 758 static uint64_t 759 zfs_mode_fuid_compute(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, 760 zfs_fuid_info_t **fuidp, dmu_tx_t *tx) 761 { 762 int entry_type; 763 mode_t mode; 764 mode_t seen = 0; 765 zfs_ace_hdr_t *acep = NULL; 766 uint64_t who; 767 uint16_t iflags, type; 768 uint32_t access_mask; 769 770 mode = (zp->z_phys->zp_mode & (S_IFMT | S_ISUID | S_ISGID | S_ISVTX)); 771 772 while (acep = zfs_acl_next_ace(aclp, acep, &who, 773 &access_mask, &iflags, &type)) { 774 775 /* 776 * Skip over inherit only ACEs 777 */ 778 if (iflags & ACE_INHERIT_ONLY_ACE) 779 continue; 780 781 entry_type = (iflags & ACE_TYPE_FLAGS); 782 783 if (entry_type == ACE_OWNER) { 784 if ((access_mask & ACE_READ_DATA) && 785 (!(seen & S_IRUSR))) { 786 seen |= S_IRUSR; 787 if (type == ALLOW) { 788 mode |= S_IRUSR; 789 } 790 } 791 if ((access_mask & ACE_WRITE_DATA) && 792 (!(seen & S_IWUSR))) { 793 seen |= S_IWUSR; 794 if (type == ALLOW) { 795 mode |= S_IWUSR; 796 } 797 } 798 if ((access_mask & ACE_EXECUTE) && 799 (!(seen & S_IXUSR))) { 800 seen |= S_IXUSR; 801 if (type == ALLOW) { 802 mode |= S_IXUSR; 803 } 804 } 805 } else if (entry_type == OWNING_GROUP) { 806 if ((access_mask & ACE_READ_DATA) && 807 (!(seen & S_IRGRP))) { 808 seen |= S_IRGRP; 809 if (type == ALLOW) { 810 mode |= S_IRGRP; 811 } 812 } 813 if ((access_mask & ACE_WRITE_DATA) && 814 (!(seen & S_IWGRP))) { 815 seen |= S_IWGRP; 816 if (type == ALLOW) { 817 mode |= S_IWGRP; 818 } 819 } 820 if ((access_mask & ACE_EXECUTE) && 821 (!(seen & S_IXGRP))) { 822 seen |= S_IXGRP; 823 if (type == ALLOW) { 824 mode |= S_IXGRP; 825 } 826 } 827 } else if (entry_type == ACE_EVERYONE) { 828 if ((access_mask & ACE_READ_DATA)) { 829 if (!(seen & S_IRUSR)) { 830 seen |= S_IRUSR; 831 if (type == ALLOW) { 832 mode |= S_IRUSR; 833 } 834 } 835 if (!(seen & S_IRGRP)) { 836 seen |= S_IRGRP; 837 if (type == ALLOW) { 838 mode |= S_IRGRP; 839 } 840 } 841 if (!(seen & S_IROTH)) { 842 seen |= S_IROTH; 843 if (type == ALLOW) { 844 mode |= S_IROTH; 845 } 846 } 847 } 848 if ((access_mask & ACE_WRITE_DATA)) { 849 if (!(seen & S_IWUSR)) { 850 seen |= S_IWUSR; 851 if (type == ALLOW) { 852 mode |= S_IWUSR; 853 } 854 } 855 if (!(seen & S_IWGRP)) { 856 seen |= S_IWGRP; 857 if (type == ALLOW) { 858 mode |= S_IWGRP; 859 } 860 } 861 if (!(seen & S_IWOTH)) { 862 seen |= S_IWOTH; 863 if (type == ALLOW) { 864 mode |= S_IWOTH; 865 } 866 } 867 } 868 if ((access_mask & ACE_EXECUTE)) { 869 if (!(seen & S_IXUSR)) { 870 seen |= S_IXUSR; 871 if (type == ALLOW) { 872 mode |= S_IXUSR; 873 } 874 } 875 if (!(seen & S_IXGRP)) { 876 seen |= S_IXGRP; 877 if (type == ALLOW) { 878 mode |= S_IXGRP; 879 } 880 } 881 if (!(seen & S_IXOTH)) { 882 seen |= S_IXOTH; 883 if (type == ALLOW) { 884 mode |= S_IXOTH; 885 } 886 } 887 } 888 } 889 /* 890 * Now handle FUID create for user/group ACEs 891 */ 892 if (entry_type == 0 || entry_type == ACE_IDENTIFIER_GROUP) { 893 aclp->z_ops.ace_who_set(acep, 894 zfs_fuid_create(zp->z_zfsvfs, who, cr, 895 entry_type == 0 ? ZFS_ACE_USER : ZFS_ACE_GROUP, tx, 896 fuidp)); 897 } 898 } 899 return (mode); 900 } 901 902 static zfs_acl_t * 903 zfs_acl_node_read_internal(znode_t *zp, boolean_t will_modify) 904 { 905 zfs_acl_t *aclp; 906 zfs_acl_node_t *aclnode; 907 908 aclp = zfs_acl_alloc(zp->z_phys->zp_acl.z_acl_version); 909 910 /* 911 * Version 0 to 1 znode_acl_phys has the size/count fields swapped. 912 * Version 0 didn't have a size field, only a count. 913 */ 914 if (zp->z_phys->zp_acl.z_acl_version == ZFS_ACL_VERSION_INITIAL) { 915 aclp->z_acl_count = zp->z_phys->zp_acl.z_acl_size; 916 aclp->z_acl_bytes = ZFS_ACL_SIZE(aclp->z_acl_count); 917 } else { 918 aclp->z_acl_count = zp->z_phys->zp_acl.z_acl_count; 919 aclp->z_acl_bytes = zp->z_phys->zp_acl.z_acl_size; 920 } 921 922 aclnode = zfs_acl_node_alloc(will_modify ? aclp->z_acl_bytes : 0); 923 aclnode->z_ace_count = aclp->z_acl_count; 924 if (will_modify) { 925 bcopy(zp->z_phys->zp_acl.z_ace_data, aclnode->z_acldata, 926 aclp->z_acl_bytes); 927 } else { 928 aclnode->z_size = aclp->z_acl_bytes; 929 aclnode->z_acldata = &zp->z_phys->zp_acl.z_ace_data[0]; 930 } 931 932 list_insert_head(&aclp->z_acl, aclnode); 933 934 return (aclp); 935 } 936 937 /* 938 * Read an external acl object. 939 */ 940 static int 941 zfs_acl_node_read(znode_t *zp, zfs_acl_t **aclpp, boolean_t will_modify) 942 { 943 uint64_t extacl = zp->z_phys->zp_acl.z_acl_extern_obj; 944 zfs_acl_t *aclp; 945 size_t aclsize; 946 size_t acl_count; 947 zfs_acl_node_t *aclnode; 948 int error; 949 950 ASSERT(MUTEX_HELD(&zp->z_acl_lock)); 951 952 if (zp->z_phys->zp_acl.z_acl_extern_obj == 0) { 953 *aclpp = zfs_acl_node_read_internal(zp, will_modify); 954 return (0); 955 } 956 957 aclp = zfs_acl_alloc(zp->z_phys->zp_acl.z_acl_version); 958 if (zp->z_phys->zp_acl.z_acl_version == ZFS_ACL_VERSION_INITIAL) { 959 zfs_acl_phys_v0_t *zacl0 = 960 (zfs_acl_phys_v0_t *)&zp->z_phys->zp_acl; 961 962 aclsize = ZFS_ACL_SIZE(zacl0->z_acl_count); 963 acl_count = zacl0->z_acl_count; 964 } else { 965 aclsize = zp->z_phys->zp_acl.z_acl_size; 966 acl_count = zp->z_phys->zp_acl.z_acl_count; 967 if (aclsize == 0) 968 aclsize = acl_count * sizeof (zfs_ace_t); 969 } 970 aclnode = zfs_acl_node_alloc(aclsize); 971 list_insert_head(&aclp->z_acl, aclnode); 972 error = dmu_read(zp->z_zfsvfs->z_os, extacl, 0, 973 aclsize, aclnode->z_acldata); 974 aclnode->z_ace_count = acl_count; 975 aclp->z_acl_count = acl_count; 976 aclp->z_acl_bytes = aclsize; 977 978 if (error != 0) { 979 zfs_acl_free(aclp); 980 return (error); 981 } 982 983 *aclpp = aclp; 984 return (0); 985 } 986 987 /* 988 * common code for setting ACLs. 989 * 990 * This function is called from zfs_mode_update, zfs_perm_init, and zfs_setacl. 991 * zfs_setacl passes a non-NULL inherit pointer (ihp) to indicate that it's 992 * already checked the acl and knows whether to inherit. 993 */ 994 int 995 zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, 996 zfs_fuid_info_t **fuidp, dmu_tx_t *tx) 997 { 998 int error; 999 znode_phys_t *zphys = zp->z_phys; 1000 zfs_acl_phys_t *zacl = &zphys->zp_acl; 1001 zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1002 uint64_t aoid = zphys->zp_acl.z_acl_extern_obj; 1003 uint64_t off = 0; 1004 dmu_object_type_t otype; 1005 zfs_acl_node_t *aclnode; 1006 1007 ASSERT(MUTEX_HELD(&zp->z_lock)); 1008 ASSERT(MUTEX_HELD(&zp->z_acl_lock)); 1009 1010 dmu_buf_will_dirty(zp->z_dbuf, tx); 1011 1012 zphys->zp_mode = zfs_mode_fuid_compute(zp, aclp, cr, fuidp, tx); 1013 1014 /* 1015 * Decide which opbject type to use. If we are forced to 1016 * use old ACL format than transform ACL into zfs_oldace_t 1017 * layout. 1018 */ 1019 if (!zfsvfs->z_use_fuids) { 1020 otype = DMU_OT_OLDACL; 1021 } else { 1022 if ((