nfs4acl.c (22328B)
1/* 2 * Common NFSv4 ACL handling code. 3 * 4 * Copyright (c) 2002, 2003 The Regents of the University of Michigan. 5 * All rights reserved. 6 * 7 * Marius Aamodt Eriksen <marius@umich.edu> 8 * Jeff Sedlak <jsedlak@umich.edu> 9 * J. Bruce Fields <bfields@umich.edu> 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its 21 * contributors may be used to endorse or promote products derived 22 * from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 31 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37#include <linux/fs.h> 38#include <linux/slab.h> 39#include <linux/posix_acl.h> 40 41#include "nfsfh.h" 42#include "nfsd.h" 43#include "acl.h" 44#include "vfs.h" 45 46#define NFS4_ACL_TYPE_DEFAULT 0x01 47#define NFS4_ACL_DIR 0x02 48#define NFS4_ACL_OWNER 0x04 49 50/* mode bit translations: */ 51#define NFS4_READ_MODE (NFS4_ACE_READ_DATA) 52#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA) 53#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE 54#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | NFS4_ACE_SYNCHRONIZE) 55#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL) 56 57/* flags used to simulate posix default ACLs */ 58#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \ 59 | NFS4_ACE_DIRECTORY_INHERIT_ACE) 60 61#define NFS4_SUPPORTED_FLAGS (NFS4_INHERITANCE_FLAGS \ 62 | NFS4_ACE_INHERIT_ONLY_ACE \ 63 | NFS4_ACE_IDENTIFIER_GROUP) 64 65static u32 66mask_from_posix(unsigned short perm, unsigned int flags) 67{ 68 int mask = NFS4_ANYONE_MODE; 69 70 if (flags & NFS4_ACL_OWNER) 71 mask |= NFS4_OWNER_MODE; 72 if (perm & ACL_READ) 73 mask |= NFS4_READ_MODE; 74 if (perm & ACL_WRITE) 75 mask |= NFS4_WRITE_MODE; 76 if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR)) 77 mask |= NFS4_ACE_DELETE_CHILD; 78 if (perm & ACL_EXECUTE) 79 mask |= NFS4_EXECUTE_MODE; 80 return mask; 81} 82 83static u32 84deny_mask_from_posix(unsigned short perm, u32 flags) 85{ 86 u32 mask = 0; 87 88 if (perm & ACL_READ) 89 mask |= NFS4_READ_MODE; 90 if (perm & ACL_WRITE) 91 mask |= NFS4_WRITE_MODE; 92 if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR)) 93 mask |= NFS4_ACE_DELETE_CHILD; 94 if (perm & ACL_EXECUTE) 95 mask |= NFS4_EXECUTE_MODE; 96 return mask; 97} 98 99/* XXX: modify functions to return NFS errors; they're only ever 100 * used by nfs code, after all.... */ 101 102/* We only map from NFSv4 to POSIX ACLs when setting ACLs, when we err on the 103 * side of being more restrictive, so the mode bit mapping below is 104 * pessimistic. An optimistic version would be needed to handle DENY's, 105 * but we expect to coalesce all ALLOWs and DENYs before mapping to mode 106 * bits. */ 107 108static void 109low_mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags) 110{ 111 u32 write_mode = NFS4_WRITE_MODE; 112 113 if (flags & NFS4_ACL_DIR) 114 write_mode |= NFS4_ACE_DELETE_CHILD; 115 *mode = 0; 116 if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE) 117 *mode |= ACL_READ; 118 if ((perm & write_mode) == write_mode) 119 *mode |= ACL_WRITE; 120 if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE) 121 *mode |= ACL_EXECUTE; 122} 123 124static short ace2type(struct nfs4_ace *); 125static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, 126 unsigned int); 127 128int 129nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, 130 struct nfs4_acl **acl) 131{ 132 struct inode *inode = d_inode(dentry); 133 int error = 0; 134 struct posix_acl *pacl = NULL, *dpacl = NULL; 135 unsigned int flags = 0; 136 int size = 0; 137 138 pacl = get_acl(inode, ACL_TYPE_ACCESS); 139 if (!pacl) 140 pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); 141 142 if (IS_ERR(pacl)) 143 return PTR_ERR(pacl); 144 145 /* allocate for worst case: one (deny, allow) pair each: */ 146 size += 2 * pacl->a_count; 147 148 if (S_ISDIR(inode->i_mode)) { 149 flags = NFS4_ACL_DIR; 150 dpacl = get_acl(inode, ACL_TYPE_DEFAULT); 151 if (IS_ERR(dpacl)) { 152 error = PTR_ERR(dpacl); 153 goto rel_pacl; 154 } 155 156 if (dpacl) 157 size += 2 * dpacl->a_count; 158 } 159 160 *acl = kmalloc(nfs4_acl_bytes(size), GFP_KERNEL); 161 if (*acl == NULL) { 162 error = -ENOMEM; 163 goto out; 164 } 165 (*acl)->naces = 0; 166 167 _posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT); 168 169 if (dpacl) 170 _posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT); 171 172out: 173 posix_acl_release(dpacl); 174rel_pacl: 175 posix_acl_release(pacl); 176 return error; 177} 178 179struct posix_acl_summary { 180 unsigned short owner; 181 unsigned short users; 182 unsigned short group; 183 unsigned short groups; 184 unsigned short other; 185 unsigned short mask; 186}; 187 188static void 189summarize_posix_acl(struct posix_acl *acl, struct posix_acl_summary *pas) 190{ 191 struct posix_acl_entry *pa, *pe; 192 193 /* 194 * Only pas.users and pas.groups need initialization; previous 195 * posix_acl_valid() calls ensure that the other fields will be 196 * initialized in the following loop. But, just to placate gcc: 197 */ 198 memset(pas, 0, sizeof(*pas)); 199 pas->mask = 07; 200 201 pe = acl->a_entries + acl->a_count; 202 203 FOREACH_ACL_ENTRY(pa, acl, pe) { 204 switch (pa->e_tag) { 205 case ACL_USER_OBJ: 206 pas->owner = pa->e_perm; 207 break; 208 case ACL_GROUP_OBJ: 209 pas->group = pa->e_perm; 210 break; 211 case ACL_USER: 212 pas->users |= pa->e_perm; 213 break; 214 case ACL_GROUP: 215 pas->groups |= pa->e_perm; 216 break; 217 case ACL_OTHER: 218 pas->other = pa->e_perm; 219 break; 220 case ACL_MASK: 221 pas->mask = pa->e_perm; 222 break; 223 } 224 } 225 /* We'll only care about effective permissions: */ 226 pas->users &= pas->mask; 227 pas->group &= pas->mask; 228 pas->groups &= pas->mask; 229} 230 231/* We assume the acl has been verified with posix_acl_valid. */ 232static void 233_posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, 234 unsigned int flags) 235{ 236 struct posix_acl_entry *pa, *group_owner_entry; 237 struct nfs4_ace *ace; 238 struct posix_acl_summary pas; 239 unsigned short deny; 240 int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ? 241 NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0); 242 243 BUG_ON(pacl->a_count < 3); 244 summarize_posix_acl(pacl, &pas); 245 246 pa = pacl->a_entries; 247 ace = acl->aces + acl->naces; 248 249 /* We could deny everything not granted by the owner: */ 250 deny = ~pas.owner; 251 /* 252 * but it is equivalent (and simpler) to deny only what is not 253 * granted by later entries: 254 */ 255 deny &= pas.users | pas.group | pas.groups | pas.other; 256 if (deny) { 257 ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; 258 ace->flag = eflag; 259 ace->access_mask = deny_mask_from_posix(deny, flags); 260 ace->whotype = NFS4_ACL_WHO_OWNER; 261 ace++; 262 acl->naces++; 263 } 264 265 ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; 266 ace->flag = eflag; 267 ace->access_mask = mask_from_posix(pa->e_perm, flags | NFS4_ACL_OWNER); 268 ace->whotype = NFS4_ACL_WHO_OWNER; 269 ace++; 270 acl->naces++; 271 pa++; 272 273 while (pa->e_tag == ACL_USER) { 274 deny = ~(pa->e_perm & pas.mask); 275 deny &= pas.groups | pas.group | pas.other; 276 if (deny) { 277 ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; 278 ace->flag = eflag; 279 ace->access_mask = deny_mask_from_posix(deny, flags); 280 ace->whotype = NFS4_ACL_WHO_NAMED; 281 ace->who_uid = pa->e_uid; 282 ace++; 283 acl->naces++; 284 } 285 ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; 286 ace->flag = eflag; 287 ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, 288 flags); 289 ace->whotype = NFS4_ACL_WHO_NAMED; 290 ace->who_uid = pa->e_uid; 291 ace++; 292 acl->naces++; 293 pa++; 294 } 295 296 /* In the case of groups, we apply allow ACEs first, then deny ACEs, 297 * since a user can be in more than one group. */ 298 299 /* allow ACEs */ 300 301 group_owner_entry = pa; 302 303 ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; 304 ace->flag = eflag; 305 ace->access_mask = mask_from_posix(pas.group, flags); 306 ace->whotype = NFS4_ACL_WHO_GROUP; 307 ace++; 308 acl->naces++; 309 pa++; 310 311 while (pa->e_tag == ACL_GROUP) { 312 ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; 313 ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; 314 ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, 315 flags); 316 ace->whotype = NFS4_ACL_WHO_NAMED; 317 ace->who_gid = pa->e_gid; 318 ace++; 319 acl->naces++; 320 pa++; 321 } 322 323 /* deny ACEs */ 324 325 pa = group_owner_entry; 326 327 deny = ~pas.group & pas.other; 328 if (deny) { 329 ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; 330 ace->flag = eflag; 331 ace->access_mask = deny_mask_from_posix(deny, flags); 332 ace->whotype = NFS4_ACL_WHO_GROUP; 333 ace++; 334 acl->naces++; 335 } 336 pa++; 337 338 while (pa->e_tag == ACL_GROUP) { 339 deny = ~(pa->e_perm & pas.mask); 340 deny &= pas.other; 341 if (deny) { 342 ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; 343 ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; 344 ace->access_mask = deny_mask_from_posix(deny, flags); 345 ace->whotype = NFS4_ACL_WHO_NAMED; 346 ace->who_gid = pa->e_gid; 347 ace++; 348 acl->naces++; 349 } 350 pa++; 351 } 352 353 if (pa->e_tag == ACL_MASK) 354 pa++; 355 ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; 356 ace->flag = eflag; 357 ace->access_mask = mask_from_posix(pa->e_perm, flags); 358 ace->whotype = NFS4_ACL_WHO_EVERYONE; 359 acl->naces++; 360} 361 362static bool 363pace_gt(struct posix_acl_entry *pace1, struct posix_acl_entry *pace2) 364{ 365 if (pace1->e_tag != pace2->e_tag) 366 return pace1->e_tag > pace2->e_tag; 367 if (pace1->e_tag == ACL_USER) 368 return uid_gt(pace1->e_uid, pace2->e_uid); 369 if (pace1->e_tag == ACL_GROUP) 370 return gid_gt(pace1->e_gid, pace2->e_gid); 371 return false; 372} 373 374static void 375sort_pacl_range(struct posix_acl *pacl, int start, int end) { 376 int sorted = 0, i; 377 378 /* We just do a bubble sort; easy to do in place, and we're not 379 * expecting acl's to be long enough to justify anything more. */ 380 while (!sorted) { 381 sorted = 1; 382 for (i = start; i < end; i++) { 383 if (pace_gt(&pacl->a_entries[i], 384 &pacl->a_entries[i+1])) { 385 sorted = 0; 386 swap(pacl->a_entries[i], 387 pacl->a_entries[i + 1]); 388 } 389 } 390 } 391} 392 393static void 394sort_pacl(struct posix_acl *pacl) 395{ 396 /* posix_acl_valid requires that users and groups be in order 397 * by uid/gid. */ 398 int i, j; 399 400 /* no users or groups */ 401 if (!pacl || pacl->a_count <= 4) 402 return; 403 404 i = 1; 405 while (pacl->a_entries[i].e_tag == ACL_USER) 406 i++; 407 sort_pacl_range(pacl, 1, i-1); 408 409 BUG_ON(pacl->a_entries[i].e_tag != ACL_GROUP_OBJ); 410 j = ++i; 411 while (pacl->a_entries[j].e_tag == ACL_GROUP) 412 j++; 413 sort_pacl_range(pacl, i, j-1); 414 return; 415} 416 417/* 418 * While processing the NFSv4 ACE, this maintains bitmasks representing 419 * which permission bits have been allowed and which denied to a given 420 * entity: */ 421struct posix_ace_state { 422 u32 allow; 423 u32 deny; 424}; 425 426struct posix_user_ace_state { 427 union { 428 kuid_t uid; 429 kgid_t gid; 430 }; 431 struct posix_ace_state perms; 432}; 433 434struct posix_ace_state_array { 435 int n; 436 struct posix_user_ace_state aces[]; 437}; 438 439/* 440 * While processing the NFSv4 ACE, this maintains the partial permissions 441 * calculated so far: */ 442 443struct posix_acl_state { 444 int empty; 445 struct posix_ace_state owner; 446 struct posix_ace_state group; 447 struct posix_ace_state other; 448 struct posix_ace_state everyone; 449 struct posix_ace_state mask; /* Deny unused in this case */ 450 struct posix_ace_state_array *users; 451 struct posix_ace_state_array *groups; 452}; 453 454static int 455init_state(struct posix_acl_state *state, int cnt) 456{ 457 int alloc; 458 459 memset(state, 0, sizeof(struct posix_acl_state)); 460 state->empty = 1; 461 /* 462 * In the worst case, each individual acl could be for a distinct 463 * named user or group, but we don't know which, so we allocate 464 * enough space for either: 465 */ 466 alloc = sizeof(struct posix_ace_state_array) 467 + cnt*sizeof(struct posix_user_ace_state); 468 state->users = kzalloc(alloc, GFP_KERNEL); 469 if (!state->users) 470 return -ENOMEM; 471 state->groups = kzalloc(alloc, GFP_KERNEL); 472 if (!state->groups) { 473 kfree(state->users); 474 return -ENOMEM; 475 } 476 return 0; 477} 478 479static void 480free_state(struct posix_acl_state *state) { 481 kfree(state->users); 482 kfree(state->groups); 483} 484 485static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_state *astate) 486{ 487 state->mask.allow |= astate->allow; 488} 489 490static struct posix_acl * 491posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) 492{ 493 struct posix_acl_entry *pace; 494 struct posix_acl *pacl; 495 int nace; 496 int i; 497 498 /* 499 * ACLs with no ACEs are treated differently in the inheritable 500 * and effective cases: when there are no inheritable ACEs, 501 * calls ->set_acl with a NULL ACL structure. 502 */ 503 if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) 504 return NULL; 505 506 /* 507 * When there are no effective ACEs, the following will end 508 * up setting a 3-element effective posix ACL with all 509 * permissions zero. 510 */ 511 if (!state->users->n && !state->groups->n) 512 nace = 3; 513 else /* Note we also include a MASK ACE in this case: */ 514 nace = 4 + state->users->n + state->groups->n; 515 pacl = posix_acl_alloc(nace, GFP_KERNEL); 516 if (!pacl) 517 return ERR_PTR(-ENOMEM); 518 519 pace = pacl->a_entries; 520 pace->e_tag = ACL_USER_OBJ; 521 low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags); 522 523 for (i=0; i < state->users->n; i++) { 524 pace++; 525 pace->e_tag = ACL_USER; 526 low_mode_from_nfs4(state->users->aces[i].perms.allow, 527 &pace->e_perm, flags); 528 pace->e_uid = state->users->aces[i].uid; 529 add_to_mask(state, &state->users->aces[i].perms); 530 } 531 532 pace++; 533 pace->e_tag = ACL_GROUP_OBJ; 534 low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags); 535 add_to_mask(state, &state->group); 536 537 for (i=0; i < state->groups->n; i++) { 538 pace++; 539 pace->e_tag = ACL_GROUP; 540 low_mode_from_nfs4(state->groups->aces[i].perms.allow, 541 &pace->e_perm, flags); 542 pace->e_gid = state->groups->aces[i].gid; 543 add_to_mask(state, &state->groups->aces[i].perms); 544 } 545 546 if (state->users->n || state->groups->n) { 547 pace++; 548 pace->e_tag = ACL_MASK; 549 low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags); 550 } 551 552 pace++; 553 pace->e_tag = ACL_OTHER; 554 low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags); 555 556 return pacl; 557} 558 559static inline void allow_bits(struct posix_ace_state *astate, u32 mask) 560{ 561 /* Allow all bits in the mask not already denied: */ 562 astate->allow |= mask & ~astate->deny; 563} 564 565static inline void deny_bits(struct posix_ace_state *astate, u32 mask) 566{ 567 /* Deny all bits in the mask not already allowed: */ 568 astate->deny |= mask & ~astate->allow; 569} 570 571static int find_uid(struct posix_acl_state *state, kuid_t uid) 572{ 573 struct posix_ace_state_array *a = state->users; 574 int i; 575 576 for (i = 0; i < a->n; i++) 577 if (uid_eq(a->aces[i].uid, uid)) 578 return i; 579 /* Not found: */ 580 a->n++; 581 a->aces[i].uid = uid; 582 a->aces[i].perms.allow = state->everyone.allow; 583 a->aces[i].perms.deny = state->everyone.deny; 584 585 return i; 586} 587 588static int find_gid(struct posix_acl_state *state, kgid_t gid) 589{ 590 struct posix_ace_state_array *a = state->groups; 591 int i; 592 593 for (i = 0; i < a->n; i++) 594 if (gid_eq(a->aces[i].gid, gid)) 595 return i; 596 /* Not found: */ 597 a->n++; 598 a->aces[i].gid = gid; 599 a->aces[i].perms.allow = state->everyone.allow; 600 a->aces[i].perms.deny = state->everyone.deny; 601 602 return i; 603} 604 605static void deny_bits_array(struct posix_ace_state_array *a, u32 mask) 606{ 607 int i; 608 609 for (i=0; i < a->n; i++) 610 deny_bits(&a->aces[i].perms, mask); 611} 612 613static void allow_bits_array(struct posix_ace_state_array *a, u32 mask) 614{ 615 int i; 616 617 for (i=0; i < a->n; i++) 618 allow_bits(&a->aces[i].perms, mask); 619} 620 621static void process_one_v4_ace(struct posix_acl_state *state, 622 struct nfs4_ace *ace) 623{ 624 u32 mask = ace->access_mask; 625 int i; 626 627 state->empty = 0; 628 629 switch (ace2type(ace)) { 630 case ACL_USER_OBJ: 631 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { 632 allow_bits(&state->owner, mask); 633 } else { 634 deny_bits(&state->owner, mask); 635 } 636 break; 637 case ACL_USER: 638 i = find_uid(state, ace->who_uid); 639 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { 640 allow_bits(&state->users->aces[i].perms, mask); 641 } else { 642 deny_bits(&state->users->aces[i].perms, mask); 643 mask = state->users->aces[i].perms.deny; 644 deny_bits(&state->owner, mask); 645 } 646 break; 647 case ACL_GROUP_OBJ: 648 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { 649 allow_bits(&state->group, mask); 650 } else { 651 deny_bits(&state->group, mask); 652 mask = state->group.deny; 653 deny_bits(&state->owner, mask); 654 deny_bits(&state->everyone, mask); 655 deny_bits_array(state->users, mask); 656 deny_bits_array(state->groups, mask); 657 } 658 break; 659 case ACL_GROUP: 660 i = find_gid(state, ace->who_gid); 661 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { 662 allow_bits(&state->groups->aces[i].perms, mask); 663 } else { 664 deny_bits(&state->groups->aces[i].perms, mask); 665 mask = state->groups->aces[i].perms.deny; 666 deny_bits(&state->owner, mask); 667 deny_bits(&state->group, mask); 668 deny_bits(&state->everyone, mask); 669 deny_bits_array(state->users, mask); 670 deny_bits_array(state->groups, mask); 671 } 672 break; 673 case ACL_OTHER: 674 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { 675 allow_bits(&state->owner, mask); 676 allow_bits(&state->group, mask); 677 allow_bits(&state->other, mask); 678 allow_bits(&state->everyone, mask); 679 allow_bits_array(state->users, mask); 680 allow_bits_array(state->groups, mask); 681 } else { 682 deny_bits(&state->owner, mask); 683 deny_bits(&state->group, mask); 684 deny_bits(&state->other, mask); 685 deny_bits(&state->everyone, mask); 686 deny_bits_array(state->users, mask); 687 deny_bits_array(state->groups, mask); 688 } 689 } 690} 691 692static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, 693 struct posix_acl **pacl, struct posix_acl **dpacl, 694 unsigned int flags) 695{ 696 struct posix_acl_state effective_acl_state, default_acl_state; 697 struct nfs4_ace *ace; 698 int ret; 699 700 ret = init_state(&effective_acl_state, acl->naces); 701 if (ret) 702 return ret; 703 ret = init_state(&default_acl_state, acl->naces); 704 if (ret) 705 goto out_estate; 706 ret = -EINVAL; 707 for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { 708 if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE && 709 ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) 710 goto out_dstate; 711 if (ace->flag & ~NFS4_SUPPORTED_FLAGS) 712 goto out_dstate; 713 if ((ace->flag & NFS4_INHERITANCE_FLAGS) == 0) { 714 process_one_v4_ace(&effective_acl_state, ace); 715 continue; 716 } 717 if (!(flags & NFS4_ACL_DIR)) 718 goto out_dstate; 719 /* 720 * Note that when only one of FILE_INHERIT or DIRECTORY_INHERIT 721 * is set, we're effectively turning on the other. That's OK, 722 * according to rfc 3530. 723 */ 724 process_one_v4_ace(&default_acl_state, ace); 725 726 if (!(ace->flag & NFS4_ACE_INHERIT_ONLY_ACE)) 727 process_one_v4_ace(&effective_acl_state, ace); 728 } 729 *pacl = posix_state_to_acl(&effective_acl_state, flags); 730 if (IS_ERR(*pacl)) { 731 ret = PTR_ERR(*pacl); 732 *pacl = NULL; 733 goto out_dstate; 734 } 735 *dpacl = posix_state_to_acl(&default_acl_state, 736 flags | NFS4_ACL_TYPE_DEFAULT); 737 if (IS_ERR(*dpacl)) { 738 ret = PTR_ERR(*dpacl); 739 *dpacl = NULL; 740 posix_acl_release(*pacl); 741 *pacl = NULL; 742 goto out_dstate; 743 } 744 sort_pacl(*pacl); 745 sort_pacl(*dpacl); 746 ret = 0; 747out_dstate: 748 free_state(&default_acl_state); 749out_estate: 750 free_state(&effective_acl_state); 751 return ret; 752} 753 754__be32 755nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, 756 struct nfs4_acl *acl) 757{ 758 __be32 error; 759 int host_error; 760 struct dentry *dentry; 761 struct inode *inode; 762 struct posix_acl *pacl = NULL, *dpacl = NULL; 763 unsigned int flags = 0; 764 765 /* Get inode */ 766 error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR); 767 if (error) 768 return error; 769 770 dentry = fhp->fh_dentry; 771 inode = d_inode(dentry); 772 773 if (S_ISDIR(inode->i_mode)) 774 flags = NFS4_ACL_DIR; 775 776 host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags); 777 if (host_error == -EINVAL) 778 return nfserr_attrnotsupp; 779 if (host_error < 0) 780 goto out_nfserr; 781 782 fh_lock(fhp); 783 784 host_error = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, pacl); 785 if (host_error < 0) 786 goto out_drop_lock; 787 788 if (S_ISDIR(inode->i_mode)) { 789 host_error = set_posix_acl(&init_user_ns, inode, 790 ACL_TYPE_DEFAULT, dpacl); 791 } 792 793out_drop_lock: 794 fh_unlock(fhp); 795 796 posix_acl_release(pacl); 797 posix_acl_release(dpacl); 798out_nfserr: 799 if (host_error == -EOPNOTSUPP) 800 return nfserr_attrnotsupp; 801 else 802 return nfserrno(host_error); 803} 804 805 806static short 807ace2type(struct nfs4_ace *ace) 808{ 809 switch (ace->whotype) { 810 case NFS4_ACL_WHO_NAMED: 811 return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ? 812 ACL_GROUP : ACL_USER); 813 case NFS4_ACL_WHO_OWNER: 814 return ACL_USER_OBJ; 815 case NFS4_ACL_WHO_GROUP: 816 return ACL_GROUP_OBJ; 817 case NFS4_ACL_WHO_EVERYONE: 818 return ACL_OTHER; 819 } 820 BUG(); 821 return -1; 822} 823 824/* 825 * return the size of the struct nfs4_acl required to represent an acl 826 * with @entries entries. 827 */ 828int nfs4_acl_bytes(int entries) 829{ 830 return sizeof(struct nfs4_acl) + entries * sizeof(struct nfs4_ace); 831} 832 833static struct { 834 char *string; 835 int stringlen; 836 int type; 837} s2t_map[] = { 838 { 839 .string = "OWNER@", 840 .stringlen = sizeof("OWNER@") - 1, 841 .type = NFS4_ACL_WHO_OWNER, 842 }, 843 { 844 .string = "GROUP@", 845 .stringlen = sizeof("GROUP@") - 1, 846 .type = NFS4_ACL_WHO_GROUP, 847 }, 848 { 849 .string = "EVERYONE@", 850 .stringlen = sizeof("EVERYONE@") - 1, 851 .type = NFS4_ACL_WHO_EVERYONE, 852 }, 853}; 854 855int 856nfs4_acl_get_whotype(char *p, u32 len) 857{ 858 int i; 859 860 for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { 861 if (s2t_map[i].stringlen == len && 862 0 == memcmp(s2t_map[i].string, p, len)) 863 return s2t_map[i].type; 864 } 865 return NFS4_ACL_WHO_NAMED; 866} 867 868__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who) 869{ 870 __be32 *p; 871 int i; 872 873 for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { 874 if (s2t_map[i].type != who) 875 continue; 876 p = xdr_reserve_space(xdr, s2t_map[i].stringlen + 4); 877 if (!p) 878 return nfserr_resource; 879 p = xdr_encode_opaque(p, s2t_map[i].string, 880 s2t_map[i].stringlen); 881 return 0; 882 } 883 WARN_ON_ONCE(1); 884 return nfserr_serverfault; 885}