Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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