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