1 /* 2 * Copyright (c) 2001-2002,2005 Silicon Graphics, Inc. 3 * All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 #include "xfs.h" 19 #include "xfs_fs.h" 20 #include "xfs_types.h" 21 #include "xfs_bit.h" 22 #include "xfs_inum.h" 23 #include "xfs_ag.h" 24 #include "xfs_dir2.h" 25 #include "xfs_bmap_btree.h" 26 #include "xfs_alloc_btree.h" 27 #include "xfs_ialloc_btree.h" 28 #include "xfs_dir2_sf.h" 29 #include "xfs_attr_sf.h" 30 #include "xfs_dinode.h" 31 #include "xfs_inode.h" 32 #include "xfs_btree.h" 33 #include "xfs_acl.h" 34 #include "xfs_attr.h" 35 #include "xfs_vnodeops.h" 36 37 #include <linux/capability.h> 38 #include <linux/posix_acl_xattr.h> 39 40 STATIC int xfs_acl_setmode(bhv_vnode_t *, xfs_acl_t *, int *); 41 STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *); 42 STATIC void xfs_acl_get_endian(xfs_acl_t *); 43 STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *); 44 STATIC int xfs_acl_invalid(xfs_acl_t *); 45 STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *); 46 STATIC void xfs_acl_get_attr(bhv_vnode_t *, xfs_acl_t *, int, int, int *); 47 STATIC void xfs_acl_set_attr(bhv_vnode_t *, xfs_acl_t *, int, int *); 48 STATIC int xfs_acl_allow_set(bhv_vnode_t *, int); 49 50 kmem_zone_t *xfs_acl_zone; 51 52 53 /* 54 * Test for existence of access ACL attribute as efficiently as possible. 55 */ 56 int 57 xfs_acl_vhasacl_access( 58 bhv_vnode_t *vp) 59 { 60 int error; 61 62 xfs_acl_get_attr(vp, NULL, _ACL_TYPE_ACCESS, ATTR_KERNOVAL, &error); 63 return (error == 0); 64 } 65 66 /* 67 * Test for existence of default ACL attribute as efficiently as possible. 68 */ 69 int 70 xfs_acl_vhasacl_default( 71 bhv_vnode_t *vp) 72 { 73 int error; 74 75 if (!VN_ISDIR(vp)) 76 return 0; 77 xfs_acl_get_attr(vp, NULL, _ACL_TYPE_DEFAULT, ATTR_KERNOVAL, &error); 78 return (error == 0); 79 } 80 81 /* 82 * Convert from extended attribute representation to in-memory for XFS. 83 */ 84 STATIC int 85 posix_acl_xattr_to_xfs( 86 posix_acl_xattr_header *src, 87 size_t size, 88 xfs_acl_t *dest) 89 { 90 posix_acl_xattr_entry *src_entry; 91 xfs_acl_entry_t *dest_entry; 92 int n; 93 94 if (!src || !dest) 95 return EINVAL; 96 97 if (size < sizeof(posix_acl_xattr_header)) 98 return EINVAL; 99 100 if (src->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION)) 101 return EOPNOTSUPP; 102 103 memset(dest, 0, sizeof(xfs_acl_t)); 104 dest->acl_cnt = posix_acl_xattr_count(size); 105 if (dest->acl_cnt < 0 || dest->acl_cnt > XFS_ACL_MAX_ENTRIES) 106 return EINVAL; 107 108 /* 109 * acl_set_file(3) may request that we set default ACLs with 110 * zero length -- defend (gracefully) against that here. 111 */ 112 if (!dest->acl_cnt) 113 return 0; 114 115 src_entry = (posix_acl_xattr_entry *)((char *)src + sizeof(*src)); 116 dest_entry = &dest->acl_entry[0]; 117 118 for (n = 0; n < dest->acl_cnt; n++, src_entry++, dest_entry++) { 119 dest_entry->ae_perm = le16_to_cpu(src_entry->e_perm); 120 if (_ACL_PERM_INVALID(dest_entry->ae_perm)) 121 return EINVAL; 122 dest_entry->ae_tag = le16_to_cpu(src_entry->e_tag); 123 switch(dest_entry->ae_tag) { 124 case ACL_USER: 125 case ACL_GROUP: 126 dest_entry->ae_id = le32_to_cpu(src_entry->e_id); 127 break; 128 case ACL_USER_OBJ: 129 case ACL_GROUP_OBJ: 130 case ACL_MASK: 131 case ACL_OTHER: 132 dest_entry->ae_id = ACL_UNDEFINED_ID; 133 break; 134 default: 135 return EINVAL; 136 } 137 } 138 if (xfs_acl_invalid(dest)) 139 return EINVAL; 140 141 return 0; 142 } 143 144 /* 145 * Comparison function called from xfs_sort(). 146 * Primary key is ae_tag, secondary key is ae_id. 147 */ 148 STATIC int 149 xfs_acl_entry_compare( 150 const void *va, 151 const void *vb) 152 { 153 xfs_acl_entry_t *a = (xfs_acl_entry_t *)va, 154 *b = (xfs_acl_entry_t *)vb; 155 156 if (a->ae_tag == b->ae_tag) 157 return (a->ae_id - b->ae_id); 158 return (a->ae_tag - b->ae_tag); 159 } 160 161 /* 162 * Convert from in-memory XFS to extended attribute representation. 163 */ 164 STATIC int 165 posix_acl_xfs_to_xattr( 166 xfs_acl_t *src, 167 posix_acl_xattr_header *dest, 168 size_t size) 169 { 170 int n; 171 size_t new_size = posix_acl_xattr_size(src->acl_cnt); 172 posix_acl_xattr_entry *dest_entry; 173 xfs_acl_entry_t *src_entry; 174 175 if (size < new_size) 176 return -ERANGE; 177 178 /* Need to sort src XFS ACL by <ae_tag,ae_id> */ 179 xfs_sort(src->acl_entry, src->acl_cnt, sizeof(src->acl_entry[0]), 180 xfs_acl_entry_compare); 181 182 dest->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION); 183 dest_entry = &dest->a_entries[0]; 184 src_entry = &src->acl_entry[0]; 185 for (n = 0; n < src->acl_cnt; n++, dest_entry++, src_entry++) { 186 dest_entry->e_perm = cpu_to_le16(src_entry->ae_perm); 187 if (_ACL_PERM_INVALID(src_entry->ae_perm)) 188 return -EINVAL; 189 dest_entry->e_tag = cpu_to_le16(src_entry->ae_tag); 190 switch (src_entry->ae_tag) { 191 case ACL_USER: 192 case ACL_GROUP: 193 dest_entry->e_id = cpu_to_le32(src_entry->ae_id); 194 break; 195 case ACL_USER_OBJ: 196 case ACL_GROUP_OBJ: 197 case ACL_MASK: 198 case ACL_OTHER: 199 dest_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID); 200 break; 201 default: 202 return -EINVAL; 203 } 204 } 205 return new_size; 206 } 207 208 int 209 xfs_acl_vget( 210 bhv_vnode_t *vp, 211 void *acl, 212 size_t size, 213 int kind) 214 { 215 int error; 216 xfs_acl_t *xfs_acl = NULL; 217 posix_acl_xattr_header *ext_acl = acl; 218 int flags = 0; 219 220 VN_HOLD(vp); 221 if(size) { 222 if (!(_ACL_ALLOC(xfs_acl))) { 223 error = ENOMEM; 224 goto out; 225 } 226 memset(xfs_acl, 0, sizeof(xfs_acl_t)); 227 } else 228 flags = ATTR_KERNOVAL; 229 230 xfs_acl_get_attr(vp, xfs_acl, kind, flags, &error); 231 if (error) 232 goto out; 233 234 if (!size) { 235 error = -posix_acl_xattr_size(XFS_ACL_MAX_ENTRIES); 236 } else { 237 if (xfs_acl_invalid(xfs_acl)) { 238 error = EINVAL; 239 goto out; 240 } 241 if (kind == _ACL_TYPE_ACCESS) { 242 bhv_vattr_t va; 243 244 va.va_mask = XFS_AT_MODE; 245 error = xfs_getattr(xfs_vtoi(vp), &va, 0); 246 if (error) 247 goto out; 248 xfs_acl_sync_mode(va.va_mode, xfs_acl); 249 } 250 error = -posix_acl_xfs_to_xattr(xfs_acl, ext_acl, size); 251 } 252 out: 253 VN_RELE(vp); 254 if(xfs_acl) 255 _ACL_FREE(xfs_acl); 256 return -error; 257 } 258 259 int 260 xfs_acl_vremove( 261 bhv_vnode_t *vp, 262 int kind) 263 { 264 int error; 265 266 VN_HOLD(vp); 267 error = xfs_acl_allow_set(vp, kind); 268 if (!error) { 269 error = xfs_attr_remove(xfs_vtoi(vp), 270 kind == _ACL_TYPE_DEFAULT? 271 SGI_ACL_DEFAULT: SGI_ACL_FILE, 272 ATTR_ROOT); 273 if (error == ENOATTR) 274 error = 0; /* 'scool */ 275 } 276 VN_RELE(vp); 277 return -error; 278 } 279 280 int 281 xfs_acl_vset( 282 bhv_vnode_t *vp, 283 void *acl, 284 size_t size, 285 int kind) 286 { 287 posix_acl_xattr_header *ext_acl = acl; 288 xfs_acl_t *xfs_acl; 289 int error; 290 int basicperms = 0; /* more than std unix perms? */ 291 292 if (!acl) 293 return -EINVAL; 294 295 if (!(_ACL_ALLOC(xfs_acl))) 296 return -ENOMEM; 297 298 error = posix_acl_xattr_to_xfs(ext_acl, size, xfs_acl); 299 if (error) { 300 _ACL_FREE(xfs_acl); 301 return -error; 302 } 303 if (!xfs_acl->acl_cnt) { 304 _ACL_FREE(xfs_acl); 305 return 0; 306 } 307 308 VN_HOLD(vp); 309 error = xfs_acl_allow_set(vp, kind); 310 311 /* Incoming ACL exists, set file mode based on its value */ 312 if (!error && kind == _ACL_TYPE_ACCESS) 313 error = xfs_acl_setmode(vp, xfs_acl, &basicperms); 314 315 if (error) 316 goto out; 317 318 /* 319 * If we have more than std unix permissions, set up the actual attr. 320 * Otherwise, delete any existing attr. This prevents us from 321 * having actual attrs for permissions that can be stored in the 322 * standard permission bits. 323 */ 324 if (!basicperms) { 325 xfs_acl_set_attr(vp, xfs_acl, kind, &error); 326 } else { 327 error = -xfs_acl_vremove(vp, _ACL_TYPE_ACCESS); 328 } 329 330 out: 331 VN_RELE(vp); 332 _ACL_FREE(xfs_acl); 333 return -error; 334 } 335 336 int 337 xfs_acl_iaccess( 338 xfs_inode_t *ip, 339 mode_t mode, 340 cred_t *cr) 341 { 342 xfs_acl_t *acl; 343 int rval; 344 345 if (!(_ACL_ALLOC(acl))) 346 return -1; 347 348 /* If the file has no ACL return -1. */ 349 rval = sizeof(xfs_acl_t); 350 if (xfs_attr_fetch(ip, SGI_ACL_FILE, SGI_ACL_FILE_SIZE, 351 (char *)acl, &rval, ATTR_ROOT | ATTR_KERNACCESS, cr)) { 352 _ACL_FREE(acl); 353 return -1; 354 } 355 xfs_acl_get_endian(acl); 356 357 /* If the file has an empty ACL return -1. */ 358 if (acl->acl_cnt == XFS_ACL_NOT_PRESENT) { 359 _ACL_FREE(acl); 360 return -1; 361 } 362 363 /* Synchronize ACL with mode bits */ 364 xfs_acl_sync_mode(ip->i_d.di_mode, acl); 365 366 rval = xfs_acl_access(ip->i_d.di_uid, ip->i_d.di_gid, acl, mode, cr); 367 _ACL_FREE(acl); 368 return rval; 369 } 370 371 STATIC int 372 xfs_acl_allow_set( 373 bhv_vnode_t *vp, 374 int kind) 375 { 376 xfs_inode_t *ip = xfs_vtoi(vp); 377 bhv_vattr_t va; 378 int error; 379 380 if (vp->i_flags & (S_IMMUTABLE|S_APPEND)) 381 return EPERM; 382 if (kind == _ACL_TYPE_DEFAULT && !VN_ISDIR(vp)) 383 return ENOTDIR; 384 if (vp->i_sb->s_flags & MS_RDONLY) 385 return EROFS; 386 va.va_mask = XFS_AT_UID; 387 error = xfs_getattr(ip, &va, 0); 388 if (error) 389 return error; 390 if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) 391 return EPERM; 392 return error; 393 } 394 395 /* 396 * Note: cr is only used here for the capability check if the ACL test fails. 397 * It is not used to find out the credentials uid or groups etc, as was 398 * done in IRIX. It is assumed that the uid and groups for the current 399 * thread are taken from "current" instead of the cr parameter. 400 */ 401 STATIC int 402 xfs_acl_access( 403 uid_t fuid, 404 gid_t fgid, 405 xfs_acl_t *fap, 406 mode_t md, 407 cred_t *cr) 408 { 409 xfs_acl_entry_t matched; 410 int i, allows; 411 int maskallows = -1; /* true, but not 1, either */ 412 int seen_userobj = 0; 413 414 matched.ae_tag = 0; /* Invalid type */ 415 matched.ae_perm = 0; 416 417 for (i = 0; i < fap->acl_cnt; i++) { 418 /* 419 * Break out if we've got a user_obj entry or 420 * a user entry and the mask (and have processed USER_OBJ) 421 */ 422 if (matched.ae_tag == ACL_USER_OBJ) 423 break; 424 if (matched.ae_tag == ACL_USER) { 425 if (maskallows != -1 && seen_userobj) 426 break; 427 if (fap->acl_entry[i].ae_tag != ACL_MASK && 428 fap->acl_entry[i].ae_tag != ACL_USER_OBJ) 429 continue; 430 } 431 /* True if this entry allows the requested access */ 432 allows = ((fap->acl_entry[i].ae_perm & md) == md); 433 434 switch (fap->acl_entry[i].ae_tag) { 435 case ACL_USER_OBJ: 436 seen_userobj = 1; 437 if (fuid != current->fsuid) 438 continue; 439 matched.ae_tag = ACL_USER_OBJ; 440 matched.ae_perm = allows; 441 break; 442 case ACL_USER: 443 if (fap->acl_entry[i].ae_id != current->fsuid) 444 continue; 445 matched.ae_tag = ACL_USER; 446 matched.ae_perm = allows; 447 break; 448 case ACL_GROUP_OBJ: 449 if ((matched.ae_tag == ACL_GROUP_OBJ || 450 matched.ae_tag == ACL_GROUP) && !allows) 451 continue; 452 if (!in_group_p(fgid)) 453 continue; 454 matched.ae_tag = ACL_GROUP_OBJ; 455 matched.ae_perm = allows; 456 break; 457 case ACL_GROUP: 458 if ((matched.ae_tag == ACL_GROUP_OBJ || 459 matched.ae_tag == ACL_GROUP) && !allows) 460 continue; 461 if (!in_group_p(fap->acl_entry[i].ae_id)) 462 continue; 463 matched.ae_tag = ACL_GROUP; 464 matched.ae_perm = allows; 465 break; 466 case ACL_MASK: 467 maskallows = allows; 468 break; 469 case ACL_OTHER: 470 if (matched.ae_tag != 0) 471 continue; 472 matched.ae_tag = ACL_OTHER; 473 matched.ae_perm = allows; 474 break; 475 } 476 } 477 /* 478 * First possibility is that no matched entry allows access. 479 * The capability to override DAC may exist, so check for it. 480 */ 481 switch (matched.ae_tag) { 482 case ACL_OTHER: 483 case ACL_USER_OBJ: 484 if (matched.ae_perm) 485 return 0; 486 break; 487 case ACL_USER: 488 case ACL_GROUP_OBJ: 489 case ACL_GROUP: 490 if (maskallows && matched.ae_perm) 491 return 0; 492 break; 493 case 0: 494 break; 495 } 496 497 /* EACCES tells generic_permission to check for capability overrides */ 498 return EACCES; 499 } 500 501 /* 502 * ACL validity checker. 503 * This acl validation routine checks each ACL entry read in makes sense. 504 */ 505 STATIC int 506 xfs_acl_invalid( 507 xfs_acl_t *aclp) 508 { 509 xfs_acl_entry_t *entry, *e; 510 int user = 0, group = 0, other = 0, mask = 0; 511 int mask_required = 0; 512 int i, j; 513 514 if (!aclp) 515 goto acl_invalid; 516 517 if (aclp->acl_cnt > XFS_ACL_MAX_ENTRIES) 518 goto acl_invalid; 519 520 for (i = 0; i < aclp->acl_cnt; i++) { 521 entry = &aclp->acl_entry[i]; 522 switch (entry->ae_tag) { 523 case ACL_USER_OBJ: 524 if (user++) 525 goto acl_invalid; 526 break; 527 case ACL_GROUP_OBJ: 528 if (group++) 529 goto acl_invalid; 530 break; 531 case ACL_OTHER: 532 if (other++) 533 goto acl_invalid; 534 break; 535 case ACL_USER: 536 case ACL_GROUP: 537 for (j = i + 1; j < aclp->acl_cnt; j++) { 538 e = &aclp->acl_entry[j]; 539 if (e->ae_id == entry->ae_id && 540 e->ae_tag == entry->ae_tag) 541 goto acl_invalid; 542 } 543 mask_required++; 544 break; 545 case ACL_MASK: 546 if (mask++) 547 goto acl_invalid; 548 break; 549 default: 550 goto acl_invalid; 551 } 552 } 553 if (!user || !group || !other || (mask_required && !mask)) 554 goto acl_invalid; 555 else 556 return 0; 557 acl_invalid: 558 return EINVAL; 559 } 560 561 /* 562 * Do ACL endian conversion. 563 */ 564 STATIC void 565 xfs_acl_get_endian( 566 xfs_acl_t *aclp) 567 { 568 xfs_acl_entry_t *ace, *end; 569 570 INT_SET(aclp->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); 571 end = &aclp->acl_entry[0]+aclp->acl_cnt; 572 for (ace = &aclp->acl_entry[0]; ace < end; ace++) { 573 INT_SET(ace->ae_tag, ARCH_CONVERT, ace->ae_tag); 574 INT_SET(ace->ae_id, ARCH_CONVERT, ace->ae_id); 575 INT_SET(ace->ae_perm, ARCH_CONVERT, ace->ae_perm); 576 } 577 } 578 579 /* 580 * Get the ACL from the EA and do endian conversion. 581 */ 582 STATIC void 583 xfs_acl_get_attr( 584 bhv_vnode_t *vp, 585 xfs_acl_t *aclp, 586 int kind, 587 int flags, 588 int *error) 589 { 590 int len = sizeof(xfs_acl_t); 591 592 ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1); 593 flags |= ATTR_ROOT; 594 *error = xfs_attr_get(xfs_vtoi(vp), 595 kind == _ACL_TYPE_ACCESS ? 596 SGI_ACL_FILE : SGI_ACL_DEFAULT, 597 (char *)aclp, &len, flags, sys_cred); 598 if (*error || (flags & ATTR_KERNOVAL)) 599 return; 600 xfs_acl_get_endian(aclp); 601 } 602 603 /* 604 * Set the EA with the ACL and do endian conversion. 605 */ 606 STATIC void 607 xfs_acl_set_attr( 608 bhv_vnode_t *vp, 609 xfs_acl_t *aclp, 610 int kind, 611 int *error) 612 { 613 xfs_acl_entry_t *ace, *newace, *end; 614 xfs_acl_t *newacl; 615 int len; 616 617 if (!(_ACL_ALLOC(newacl))) { 618 *error = ENOMEM; 619 return; 620 } 621 622 len = sizeof(xfs_acl_t) - 623 (sizeof(xfs_acl_entry_t) * (XFS_ACL_MAX_ENTRIES - aclp->acl_cnt)); 624 end = &aclp->acl_entry[0]+aclp->acl_cnt; 625 for (ace = &aclp->acl_entry[0], newace = &newacl->acl_entry[0]; 626 ace < end; 627 ace++, newace++) { 628 INT_SET(newace->ae_tag, ARCH_CONVERT, ace->ae_tag); 629 INT_SET(newace->ae_id, ARCH_CONVERT, ace->ae_id); 630 INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm); 631 } 632 INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); 633 *error = xfs_attr_set(xfs_vtoi(vp), 634 kind == _ACL_TYPE_ACCESS ? 635 SGI_ACL_FILE: SGI_ACL_DEFAULT, 636 (char *)newacl, len, ATTR_ROOT); 637 _ACL_FREE(newacl); 638 } 639 640 int 641 xfs_acl_vtoacl( 642 bhv_vnode_t *vp, 643 xfs_acl_t *access_acl, 644 xfs_acl_t *default_acl) 645 { 646 bhv_vattr_t va; 647 int error = 0; 648 649 if (access_acl) { 650 /* 651 * Get the Access ACL and the mode. If either cannot 652 * be obtained for some reason, invalidate the access ACL. 653 */ 654 xfs_acl_get_attr(vp, access_acl, _ACL_TYPE_ACCESS, 0, &error); 655 if (!error) { 656 /* Got the ACL, need the mode... */ 657 va.va_mask = XFS_AT_MODE; 658 error = xfs_getattr(xfs_vtoi(vp), &va, 0); 659 } 660 661 if (error) 662 access_acl->acl_cnt = XFS_ACL_NOT_PRESENT; 663 else /* We have a good ACL and the file mode, synchronize. */ 664 xfs_acl_sync_mode(va.va_mode, access_acl); 665 } 666 667 if (default_acl) { 668 xfs_acl_get_attr(vp, default_acl, _ACL_TYPE_DEFAULT, 0, &error); 669 if (error) 670 default_acl->acl_cnt = XFS_ACL_NOT_PRESENT; 671 } 672 return error; 673 } 674 675 /* 676 * This function retrieves the parent directory's acl, processes it 677 * and lets the child inherit the acl(s) that it should. 678 */ 679 int 680 xfs_acl_inherit( 681 bhv_vnode_t *vp, 682 mode_t mode, 683 xfs_acl_t *pdaclp) 684 { 685 xfs_acl_t *cacl; 686 int error = 0; 687 int basicperms = 0; 688 689 /* 690 * If the parent does not have a default ACL, or it's an 691 * invalid ACL, we're done. 692 */ 693 if (!vp) 694 return 0; 695 if (!pdaclp || xfs_acl_invalid(pdaclp)) 696 return 0; 697 698 /* 699 * Copy the default ACL of the containing directory to 700 * the access ACL of the new file and use the mode that 701 * was passed in to set up the correct initial values for 702 * the u::,g::[m::], and o:: entries. This is what makes 703 * umask() "work" with ACL's. 704 */ 705 706 if (!(_ACL_ALLOC(cacl))) 707 return ENOMEM; 708 709 memcpy(cacl, pdaclp, sizeof(xfs_acl_t)); 710 xfs_acl_filter_mode(mode, cacl); 711 error = xfs_acl_setmode(vp, cacl, &basicperms); 712 if (error) 713 goto out_error; 714 715 /* 716 * Set the Default and Access ACL on the file. The mode is already 717 * set on the file, so we don't need to worry about that. 718 * 719 * If the new file is a directory, its default ACL is a copy of 720 * the containing directory's default ACL. 721 */ 722 if (VN_ISDIR(vp)) 723 xfs_acl_set_attr(vp, pdaclp, _ACL_TYPE_DEFAULT, &error); 724 if (!error && !basicperms) 725 xfs_acl_set_attr(vp, cacl, _ACL_TYPE_ACCESS, &error); 726 out_error: 727 _ACL_FREE(cacl); 728 return error; 729 } 730 731 /* 732 * Set up the correct mode on the file based on the supplied ACL. This 733 * makes sure that the mode on the file reflects the state of the 734 * u::,g::[m::], and o:: entries in the ACL. Since the mode is where 735 * the ACL is going to get the permissions for these entries, we must 736 * synchronize the mode whenever we set the ACL on a file. 737 */ 738 STATIC int 739 xfs_acl_setmode( 740 bhv_vnode_t *vp, 741 xfs_acl_t *acl, 742 int *basicperms) 743 { 744 bhv_vattr_t va; 745 xfs_acl_entry_t *ap; 746 xfs_acl_entry_t *gap = NULL; 747 int i, error, nomask = 1; 748 749 *basicperms = 1; 750 751 if (acl->acl_cnt == XFS_ACL_NOT_PRESENT) 752 return 0; 753 754 /* 755 * Copy the u::, g::, o::, and m:: bits from the ACL into the 756 * mode. The m:: bits take precedence over the g:: bits. 757 */ 758 va.va_mask = XFS_AT_MODE; 759 error = xfs_getattr(xfs_vtoi(vp), &va, 0); 760 if (error) 761 return error; 762 763 va.va_mask = XFS_AT_MODE; 764 va.va_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO); 765 ap = acl->acl_entry; 766 for (i = 0; i < acl->acl_cnt; ++i) { 767 switch (ap->ae_tag) { 768 case ACL_USER_OBJ: 769 va.va_mode |= ap->ae_perm << 6; 770 break; 771 case ACL_GROUP_OBJ: 772 gap = ap; 773 break; 774 case ACL_MASK: /* more than just standard modes */ 775 nomask = 0; 776 va.va_mode |= ap->ae_perm << 3; 777 *basicperms = 0; 778 break; 779 case ACL_OTHER: 780 va.va_mode |= ap->ae_perm; 781 break; 782 default: /* more than just standard modes */ 783 *basicperms = 0; 784 break; 785 } 786 ap++; 787 } 788 789 /* Set the group bits from ACL_GROUP_OBJ if there's no ACL_MASK */ 790 if (gap && nomask) 791 va.va_mode |= gap->ae_perm << 3; 792 793 return xfs_setattr(xfs_vtoi(vp), &va, 0, sys_cred); 794 } 795 796 /* 797 * The permissions for the special ACL entries (u::, g::[m::], o::) are 798 * actually stored in the file mode (if there is both a group and a mask, 799 * the group is stored in the ACL entry and the mask is stored on the file). 800 * This allows the mode to remain automatically in sync with the ACL without 801 * the need for a call-back to the ACL system at every point where the mode 802 * could change. This function takes the permissions from the specified mode 803 * and places it in the supplied ACL. 804 * 805 * This implementation draws its validity from the fact that, when the ACL 806 * was assigned, the mode was copied from the ACL. 807 * If the mode did not change, therefore, the mode remains exactly what was 808 * taken from the special ACL entries at assignment. 809 * If a subsequent chmod() was done, the POSIX spec says that the change in 810 * mode must cause an update to the ACL seen at user level and used for 811 * access checks. Before and after a mode change, therefore, the file mode 812 * most accurately reflects what the special ACL entries should permit/deny. 813 * 814 * CAVEAT: If someone sets the SGI_ACL_FILE attribute directly, 815 * the existing mode bits will override whatever is in the 816 * ACL. Similarly, if there is a pre-existing ACL that was 817 * never in sync with its mode (owing to a bug in 6.5 and 818 * before), it will now magically (or mystically) be 819 * synchronized. This could cause slight astonishment, but 820 * it is better than inconsistent permissions. 821 * 822 * The supplied ACL is a template that may contain any combination 823 * of special entries. These are treated as place holders when we fill 824 * out the ACL. This routine does not add or remove special entries, it 825 * simply unites each special entry with its associated set of permissions. 826 */ 827 STATIC void 828 xfs_acl_sync_mode( 829 mode_t mode, 830 xfs_acl_t *acl) 831 { 832 int i, nomask = 1; 833 xfs_acl_entry_t *ap; 834 xfs_acl_entry_t *gap = NULL; 835 836 /* 837 * Set ACL entries. POSIX1003.1eD16 requires that the MASK 838 * be set instead of the GROUP entry, if there is a MASK. 839 */ 840 for (ap = acl->acl_entry, i = 0; i < acl->acl_cnt; ap++, i++) { 841 switch (ap->ae_tag) { 842 case ACL_USER_OBJ: 843 ap->ae_perm = (mode >> 6) & 0x7; 844 break; 845 case ACL_GROUP_OBJ: 846 gap = ap; 847 break; 848 case ACL_MASK: 849 nomask = 0; 850 ap->ae_perm = (mode >> 3) & 0x7; 851 break; 852 case ACL_OTHER: 853 ap->ae_perm = mode & 0x7; 854 break; 855 default: 856 break; 857 } 858 } 859 /* Set the ACL_GROUP_OBJ if there's no ACL_MASK */ 860 if (gap && nomask) 861 gap->ae_perm = (mode >> 3) & 0x7; 862 } 863 864 /* 865 * When inheriting an Access ACL from a directory Default ACL, 866 * the ACL bits are set to the intersection of the ACL default 867 * permission bits and the file permission bits in mode. If there 868 * are no permission bits on the file then we must not give them 869 * the ACL. This is what what makes umask() work with ACLs. 870 */ 871 STATIC void 872 xfs_acl_filter_mode( 873 mode_t mode, 874 xfs_acl_t *acl) 875 { 876 int i, nomask = 1; 877 xfs_acl_entry_t *ap; 878 xfs_acl_entry_t *gap = NULL; 879 880 /* 881 * Set ACL entries. POSIX1003.1eD16 requires that the MASK 882 * be merged with GROUP entry, if there is a MASK. 883 */ 884 for (ap = acl->acl_entry, i = 0; i < acl->acl_cnt; ap++, i++) { 885 switch (ap->ae_tag) { 886 case ACL_USER_OBJ: 887 ap->ae_perm &= (mode >> 6) & 0x7; 888 break; 889 case ACL_GROUP_OBJ: 890 gap = ap; 891 break; 892 case ACL_MASK: 893 nomask = 0; 894 ap->ae_perm &= (mode >> 3) & 0x7; 895 break; 896 case ACL_OTHER: 897 ap->ae_perm &= mode & 0x7; 898 break; 899 default: 900 break; 901 } 902 } 903 /* Set the ACL_GROUP_OBJ if there's no ACL_MASK */ 904 if (gap && nomask) 905 gap->ae_perm &= (mode >> 3) & 0x7; 906 } 907