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