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