aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4acl.c627
1 files changed, 273 insertions, 354 deletions
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index edb107e61b91..f2f66b3da7ac 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -96,24 +96,26 @@ deny_mask(u32 allow_mask, unsigned int flags)
96/* XXX: modify functions to return NFS errors; they're only ever 96/* XXX: modify functions to return NFS errors; they're only ever
97 * used by nfs code, after all.... */ 97 * used by nfs code, after all.... */
98 98
99static int 99/* We only map from NFSv4 to POSIX ACLs when setting ACLs, when we err on the
100mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags) 100 * side of being more restrictive, so the mode bit mapping below is
101 * pessimistic. An optimistic version would be needed to handle DENY's,
102 * but we espect to coalesce all ALLOWs and DENYs before mapping to mode
103 * bits. */
104
105static void
106low_mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
101{ 107{
102 u32 ignore = 0; 108 u32 write_mode = NFS4_WRITE_MODE;
103 109
104 if (!(flags & NFS4_ACL_DIR)) 110 if (flags & NFS4_ACL_DIR)
105 ignore |= NFS4_ACE_DELETE_CHILD; /* ignore it */ 111 write_mode |= NFS4_ACE_DELETE_CHILD;
106 perm |= ignore;
107 *mode = 0; 112 *mode = 0;
108 if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE) 113 if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE)
109 *mode |= ACL_READ; 114 *mode |= ACL_READ;
110 if ((perm & NFS4_WRITE_MODE) == NFS4_WRITE_MODE) 115 if ((perm & write_mode) == write_mode)
111 *mode |= ACL_WRITE; 116 *mode |= ACL_WRITE;
112 if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE) 117 if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE)
113 *mode |= ACL_EXECUTE; 118 *mode |= ACL_EXECUTE;
114 if (!MASK_EQUAL(perm, ignore|mask_from_posix(*mode, flags)))
115 return -EINVAL;
116 return 0;
117} 119}
118 120
119struct ace_container { 121struct ace_container {
@@ -338,38 +340,6 @@ sort_pacl(struct posix_acl *pacl)
338 return; 340 return;
339} 341}
340 342
341static int
342write_pace(struct nfs4_ace *ace, struct posix_acl *pacl,
343 struct posix_acl_entry **pace, short tag, unsigned int flags)
344{
345 struct posix_acl_entry *this = *pace;
346
347 if (*pace == pacl->a_entries + pacl->a_count)
348 return -EINVAL; /* fell off the end */
349 (*pace)++;
350 this->e_tag = tag;
351 if (tag == ACL_USER_OBJ)
352 flags |= NFS4_ACL_OWNER;
353 if (mode_from_nfs4(ace->access_mask, &this->e_perm, flags))
354 return -EINVAL;
355 this->e_id = (tag == ACL_USER || tag == ACL_GROUP ?
356 ace->who : ACL_UNDEFINED_ID);
357 return 0;
358}
359
360static struct nfs4_ace *
361get_next_v4_ace(struct list_head **p, struct list_head *head)
362{
363 struct nfs4_ace *ace;
364
365 *p = (*p)->next;
366 if (*p == head)
367 return NULL;
368 ace = list_entry(*p, struct nfs4_ace, l_ace);
369
370 return ace;
371}
372
373int 343int
374nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl, 344nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl,
375 struct posix_acl **dpacl, unsigned int flags) 345 struct posix_acl **dpacl, unsigned int flags)
@@ -429,349 +399,311 @@ out:
429 return error; 399 return error;
430} 400}
431 401
402/*
403 * While processing the NFSv4 ACE, this maintains bitmasks representing
404 * which permission bits have been allowed and which denied to a given
405 * entity: */
406struct posix_ace_state {
407 u32 allow;
408 u32 deny;
409};
410
411struct posix_user_ace_state {
412 uid_t uid;
413 struct posix_ace_state perms;
414};
415
416struct posix_ace_state_array {
417 int n;
418 struct posix_user_ace_state aces[];
419};
420
421/*
422 * While processing the NFSv4 ACE, this maintains the partial permissions
423 * calculated so far: */
424
425struct posix_acl_state {
426 struct posix_ace_state owner;
427 struct posix_ace_state group;
428 struct posix_ace_state other;
429 struct posix_ace_state everyone;
430 struct posix_ace_state mask; /* Deny unused in this case */
431 struct posix_ace_state_array *users;
432 struct posix_ace_state_array *groups;
433};
434
432static int 435static int
433same_who(struct nfs4_ace *a, struct nfs4_ace *b) 436init_state(struct posix_acl_state *state, int cnt)
434{ 437{
435 return a->whotype == b->whotype && 438 int alloc;
436 (a->whotype != NFS4_ACL_WHO_NAMED || a->who == b->who); 439
440 memset(state, 0, sizeof(struct posix_acl_state));
441 /*
442 * In the worst case, each individual acl could be for a distinct
443 * named user or group, but we don't no which, so we allocate
444 * enough space for either:
445 */
446 alloc = sizeof(struct posix_ace_state_array)
447 + cnt*sizeof(struct posix_ace_state);
448 state->users = kzalloc(alloc, GFP_KERNEL);
449 if (!state->users)
450 return -ENOMEM;
451 state->groups = kzalloc(alloc, GFP_KERNEL);
452 if (!state->groups) {
453 kfree(state->users);
454 return -ENOMEM;
455 }
456 return 0;
437} 457}
438 458
439static int 459static void
440complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny, 460free_state(struct posix_acl_state *state) {
441 unsigned int flags) 461 kfree(state->users);
442{ 462 kfree(state->groups);
443 int ignore = 0;
444 if (!(flags & NFS4_ACL_DIR))
445 ignore |= NFS4_ACE_DELETE_CHILD;
446 return MASK_EQUAL(ignore|deny_mask(allow->access_mask, flags),
447 ignore|deny->access_mask) &&
448 allow->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
449 deny->type == NFS4_ACE_ACCESS_DENIED_ACE_TYPE &&
450 allow->flag == deny->flag &&
451 same_who(allow, deny);
452} 463}
453 464
454static inline int 465static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_state *astate)
455user_obj_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
456 struct posix_acl *pacl, struct posix_acl_entry **pace,
457 unsigned int flags)
458{ 466{
459 int error = -EINVAL; 467 state->mask.allow |= astate->allow;
460 struct nfs4_ace *ace, *ace2;
461
462 ace = get_next_v4_ace(p, &n4acl->ace_head);
463 if (ace == NULL)
464 goto out;
465 if (ace2type(ace) != ACL_USER_OBJ)
466 goto out;
467 error = write_pace(ace, pacl, pace, ACL_USER_OBJ, flags);
468 if (error < 0)
469 goto out;
470 error = -EINVAL;
471 ace2 = get_next_v4_ace(p, &n4acl->ace_head);
472 if (ace2 == NULL)
473 goto out;
474 if (!complementary_ace_pair(ace, ace2, flags))
475 goto out;
476 error = 0;
477out:
478 return error;
479} 468}
480 469
481static inline int 470/*
482users_from_v4(struct nfs4_acl *n4acl, struct list_head **p, 471 * Certain bits (SYNCHRONIZE, DELETE, WRITE_OWNER, READ/WRITE_NAMED_ATTRS,
483 struct nfs4_ace **mask_ace, 472 * READ_ATTRIBUTES, READ_ACL) are currently unenforceable and don't translate
484 struct posix_acl *pacl, struct posix_acl_entry **pace, 473 * to traditional read/write/execute permissions.
485 unsigned int flags) 474 *
486{ 475 * It's problematic to reject acls that use certain mode bits, because it
487 int error = -EINVAL; 476 * places the burden on users to learn the rules about which bits one
488 struct nfs4_ace *ace, *ace2; 477 * particular server sets, without giving the user a lot of help--we return an
478 * error that could mean any number of different things. To make matters
479 * worse, the problematic bits might be introduced by some application that's
480 * automatically mapping from some other acl model.
481 *
482 * So wherever possible we accept anything, possibly erring on the side of
483 * denying more permissions than necessary.
484 *
485 * However we do reject *explicit* DENY's of a few bits representing
486 * permissions we could never deny:
487 */
489 488
490 ace = get_next_v4_ace(p, &n4acl->ace_head); 489static inline int check_deny(u32 mask, int isowner)
491 if (ace == NULL) 490{
492 goto out; 491 if (mask & (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL))
493 while (ace2type(ace) == ACL_USER) { 492 return -EINVAL;
494 if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) 493 if (!isowner)
495 goto out; 494 return 0;
496 if (*mask_ace && 495 if (mask & (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL))
497 !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask)) 496 return -EINVAL;
498 goto out; 497 return 0;
499 *mask_ace = ace;
500 ace = get_next_v4_ace(p, &n4acl->ace_head);
501 if (ace == NULL)
502 goto out;
503 if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
504 goto out;
505 error = write_pace(ace, pacl, pace, ACL_USER, flags);
506 if (error < 0)
507 goto out;
508 error = -EINVAL;
509 ace2 = get_next_v4_ace(p, &n4acl->ace_head);
510 if (ace2 == NULL)
511 goto out;
512 if (!complementary_ace_pair(ace, ace2, flags))
513 goto out;
514 if ((*mask_ace)->flag != ace2->flag ||
515 !same_who(*mask_ace, ace2))
516 goto out;
517 ace = get_next_v4_ace(p, &n4acl->ace_head);
518 if (ace == NULL)
519 goto out;
520 }
521 error = 0;
522out:
523 return error;
524} 498}
525 499
526static inline int 500static struct posix_acl *
527group_obj_and_groups_from_v4(struct nfs4_acl *n4acl, struct list_head **p, 501posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
528 struct nfs4_ace **mask_ace,
529 struct posix_acl *pacl, struct posix_acl_entry **pace,
530 unsigned int flags)
531{ 502{
532 int error = -EINVAL; 503 struct posix_acl_entry *pace;
533 struct nfs4_ace *ace, *ace2; 504 struct posix_acl *pacl;
534 struct ace_container *ac; 505 int nace;
535 struct list_head group_l; 506 int i, error = 0;
536
537 INIT_LIST_HEAD(&group_l);
538 ace = list_entry(*p, struct nfs4_ace, l_ace);
539
540 /* group owner (mask and allow aces) */
541 507
542 if (pacl->a_count != 3) { 508 nace = 4 + state->users->n + state->groups->n;
543 /* then the group owner should be preceded by mask */ 509 pacl = posix_acl_alloc(nace, GFP_KERNEL);
544 if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) 510 if (!pacl)
545 goto out; 511 return ERR_PTR(-ENOMEM);
546 if (*mask_ace &&
547 !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
548 goto out;
549 *mask_ace = ace;
550 ace = get_next_v4_ace(p, &n4acl->ace_head);
551 if (ace == NULL)
552 goto out;
553 512
554 if ((*mask_ace)->flag != ace->flag || !same_who(*mask_ace, ace)) 513 pace = pacl->a_entries;
555 goto out; 514 pace->e_tag = ACL_USER_OBJ;
515 error = check_deny(state->owner.deny, 1);
516 if (error)
517 goto out_err;
518 low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags);
519 pace->e_id = ACL_UNDEFINED_ID;
520
521 for (i=0; i < state->users->n; i++) {
522 pace++;
523 pace->e_tag = ACL_USER;
524 error = check_deny(state->users->aces[i].perms.deny, 0);
525 if (error)
526 goto out_err;
527 low_mode_from_nfs4(state->users->aces[i].perms.allow,
528 &pace->e_perm, flags);
529 pace->e_id = state->users->aces[i].uid;
530 add_to_mask(state, &state->users->aces[i].perms);
556 } 531 }
557 532
558 if (ace2type(ace) != ACL_GROUP_OBJ) 533 pace++;
559 goto out; 534 pace->e_tag = ACL_GROUP_OBJ;
560 535 error = check_deny(state->group.deny, 0);
561 ac = kmalloc(sizeof(*ac), GFP_KERNEL); 536 if (error)
562 error = -ENOMEM; 537 goto out_err;
563 if (ac == NULL) 538 low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags);
564 goto out; 539 pace->e_id = ACL_UNDEFINED_ID;
565 ac->ace = ace; 540 add_to_mask(state, &state->group);
566 list_add_tail(&ac->ace_l, &group_l); 541
567 542 for (i=0; i < state->groups->n; i++) {
568 error = -EINVAL; 543 pace++;
569 if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) 544 pace->e_tag = ACL_GROUP;
570 goto out; 545 error = check_deny(state->groups->aces[i].perms.deny, 0);
571 546 if (error)
572 error = write_pace(ace, pacl, pace, ACL_GROUP_OBJ, flags); 547 goto out_err;
573 if (error < 0) 548 low_mode_from_nfs4(state->groups->aces[i].perms.allow,
574 goto out; 549 &pace->e_perm, flags);
575 550 pace->e_id = state->groups->aces[i].uid;
576 error = -EINVAL; 551 add_to_mask(state, &state->groups->aces[i].perms);
577 ace = get_next_v4_ace(p, &n4acl->ace_head); 552 }
578 if (ace == NULL)
579 goto out;
580
581 /* groups (mask and allow aces) */
582
583 while (ace2type(ace) == ACL_GROUP) {
584 if (*mask_ace == NULL)
585 goto out;
586
587 if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE ||
588 !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
589 goto out;
590 *mask_ace = ace;
591 553
592 ace = get_next_v4_ace(p, &n4acl->ace_head); 554 pace++;
593 if (ace == NULL) 555 pace->e_tag = ACL_MASK;
594 goto out; 556 low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags);
595 ac = kmalloc(sizeof(*ac), GFP_KERNEL); 557 pace->e_id = ACL_UNDEFINED_ID;
596 error = -ENOMEM;
597 if (ac == NULL)
598 goto out;
599 error = -EINVAL;
600 if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE ||
601 !same_who(ace, *mask_ace))
602 goto out;
603 558
604 ac->ace = ace; 559 pace++;
605 list_add_tail(&ac->ace_l, &group_l); 560 pace->e_tag = ACL_OTHER;
561 error = check_deny(state->other.deny, 0);
562 if (error)
563 goto out_err;
564 low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags);
565 pace->e_id = ACL_UNDEFINED_ID;
606 566
607 error = write_pace(ace, pacl, pace, ACL_GROUP, flags); 567 return pacl;
608 if (error < 0) 568out_err:
609 goto out; 569 posix_acl_release(pacl);
610 error = -EINVAL; 570 return ERR_PTR(error);
611 ace = get_next_v4_ace(p, &n4acl->ace_head); 571}
612 if (ace == NULL)
613 goto out;
614 }
615 572
616 /* group owner (deny ace) */ 573static inline void allow_bits(struct posix_ace_state *astate, u32 mask)
574{
575 /* Allow all bits in the mask not already denied: */
576 astate->allow |= mask & ~astate->deny;
577}
617 578
618 if (ace2type(ace) != ACL_GROUP_OBJ) 579static inline void deny_bits(struct posix_ace_state *astate, u32 mask)
619 goto out; 580{
620 ac = list_entry(group_l.next, struct ace_container, ace_l); 581 /* Deny all bits in the mask not already allowed: */
621 ace2 = ac->ace; 582 astate->deny |= mask & ~astate->allow;
622 if (!complementary_ace_pair(ace2, ace, flags)) 583}
623 goto out;
624 list_del(group_l.next);
625 kfree(ac);
626 584
627 /* groups (deny aces) */ 585static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid)
586{
587 int i;
628 588
629 while (!list_empty(&group_l)) { 589 for (i = 0; i < a->n; i++)
630 ace = get_next_v4_ace(p, &n4acl->ace_head); 590 if (a->aces[i].uid == uid)
631 if (ace == NULL) 591 return i;
632 goto out; 592 /* Not found: */
633 if (ace2type(ace) != ACL_GROUP) 593 a->n++;
634 goto out; 594 a->aces[i].uid = uid;
635 ac = list_entry(group_l.next, struct ace_container, ace_l); 595 a->aces[i].perms.allow = state->everyone.allow;
636 ace2 = ac->ace; 596 a->aces[i].perms.deny = state->everyone.deny;
637 if (!complementary_ace_pair(ace2, ace, flags))
638 goto out;
639 list_del(group_l.next);
640 kfree(ac);
641 }
642 597
643 ace = get_next_v4_ace(p, &n4acl->ace_head); 598 return i;
644 if (ace == NULL)
645 goto out;
646 if (ace2type(ace) != ACL_OTHER)
647 goto out;
648 error = 0;
649out:
650 while (!list_empty(&group_l)) {
651 ac = list_entry(group_l.next, struct ace_container, ace_l);
652 list_del(group_l.next);
653 kfree(ac);
654 }
655 return error;
656} 599}
657 600
658static inline int 601static void deny_bits_array(struct posix_ace_state_array *a, u32 mask)
659mask_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
660 struct nfs4_ace **mask_ace,
661 struct posix_acl *pacl, struct posix_acl_entry **pace,
662 unsigned int flags)
663{ 602{
664 int error = -EINVAL; 603 int i;
665 struct nfs4_ace *ace;
666 604
667 ace = list_entry(*p, struct nfs4_ace, l_ace); 605 for (i=0; i < a->n; i++)
668 if (pacl->a_count != 3) { 606 deny_bits(&a->aces[i].perms, mask);
669 if (*mask_ace == NULL)
670 goto out;
671 (*mask_ace)->access_mask = deny_mask((*mask_ace)->access_mask, flags);
672 write_pace(*mask_ace, pacl, pace, ACL_MASK, flags);
673 }
674 error = 0;
675out:
676 return error;
677} 607}
678 608
679static inline int 609static void allow_bits_array(struct posix_ace_state_array *a, u32 mask)
680other_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
681 struct posix_acl *pacl, struct posix_acl_entry **pace,
682 unsigned int flags)
683{ 610{
684 int error = -EINVAL; 611 int i;
685 struct nfs4_ace *ace, *ace2;
686 612
687 ace = list_entry(*p, struct nfs4_ace, l_ace); 613 for (i=0; i < a->n; i++)
688 if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) 614 allow_bits(&a->aces[i].perms, mask);
689 goto out;
690 error = write_pace(ace, pacl, pace, ACL_OTHER, flags);
691 if (error < 0)
692 goto out;
693 error = -EINVAL;
694 ace2 = get_next_v4_ace(p, &n4acl->ace_head);
695 if (ace2 == NULL)
696 goto out;
697 if (!complementary_ace_pair(ace, ace2, flags))
698 goto out;
699 error = 0;
700out:
701 return error;
702} 615}
703 616
704static int 617static void process_one_v4_ace(struct posix_acl_state *state,
705calculate_posix_ace_count(struct nfs4_acl *n4acl) 618 struct nfs4_ace *ace)
706{ 619{
707 if (n4acl->naces == 6) /* owner, owner group, and other only */ 620 u32 mask = ace->access_mask;
708 return 3; 621 int i;
709 else { /* Otherwise there must be a mask entry. */ 622
710 /* Also, the remaining entries are for named users and 623 switch (ace2type(ace)) {
711 * groups, and come in threes (mask, allow, deny): */ 624 case ACL_USER_OBJ:
712 if (n4acl->naces < 7) 625 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
713 return -EINVAL; 626 allow_bits(&state->owner, mask);
714 if ((n4acl->naces - 7) % 3) 627 } else {
715 return -EINVAL; 628 deny_bits(&state->owner, mask);
716 return 4 + (n4acl->naces - 7)/3; 629 }
630 break;
631 case ACL_USER:
632 i = find_uid(state, state->users, ace->who);
633 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
634 allow_bits(&state->users->aces[i].perms, mask);
635 } else {
636 deny_bits(&state->users->aces[i].perms, mask);
637 mask = state->users->aces[i].perms.deny;
638 deny_bits(&state->owner, mask);
639 }
640 break;
641 case ACL_GROUP_OBJ:
642 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
643 allow_bits(&state->group, mask);
644 } else {
645 deny_bits(&state->group, mask);
646 mask = state->group.deny;
647 deny_bits(&state->owner, mask);
648 deny_bits(&state->everyone, mask);
649 deny_bits_array(state->users, mask);
650 deny_bits_array(state->groups, mask);
651 }
652 break;
653 case ACL_GROUP:
654 i = find_uid(state, state->groups, ace->who);
655 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
656 allow_bits(&state->groups->aces[i].perms, mask);
657 } else {
658 deny_bits(&state->groups->aces[i].perms, mask);
659 mask = state->groups->aces[i].perms.deny;
660 deny_bits(&state->owner, mask);
661 deny_bits(&state->group, mask);
662 deny_bits(&state->everyone, mask);
663 deny_bits_array(state->users, mask);
664 deny_bits_array(state->groups, mask);
665 }
666 break;
667 case ACL_OTHER:
668 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
669 allow_bits(&state->owner, mask);
670 allow_bits(&state->group, mask);
671 allow_bits(&state->other, mask);
672 allow_bits(&state->everyone, mask);
673 allow_bits_array(state->users, mask);
674 allow_bits_array(state->groups, mask);
675 } else {
676 deny_bits(&state->owner, mask);
677 deny_bits(&state->group, mask);
678 deny_bits(&state->other, mask);
679 deny_bits(&state->everyone, mask);
680 deny_bits_array(state->users, mask);
681 deny_bits_array(state->groups, mask);
682 }
717 } 683 }
718} 684}
719 685
720
721static struct posix_acl * 686static struct posix_acl *
722_nfsv4_to_posix_one(struct nfs4_acl *n4acl, unsigned int flags) 687_nfsv4_to_posix_one(struct nfs4_acl *n4acl, unsigned int flags)
723{ 688{
689 struct posix_acl_state state;
724 struct posix_acl *pacl; 690 struct posix_acl *pacl;
725 int error = -EINVAL, nace = 0; 691 struct nfs4_ace *ace;
726 struct list_head *p; 692 int ret;
727 struct nfs4_ace *mask_ace = NULL;
728 struct posix_acl_entry *pace;
729
730 nace = calculate_posix_ace_count(n4acl);
731 if (nace < 0)
732 goto out_err;
733
734 pacl = posix_acl_alloc(nace, GFP_KERNEL);
735 error = -ENOMEM;
736 if (pacl == NULL)
737 goto out_err;
738
739 pace = &pacl->a_entries[0];
740 p = &n4acl->ace_head;
741
742 error = user_obj_from_v4(n4acl, &p, pacl, &pace, flags);
743 if (error)
744 goto out_acl;
745
746 error = users_from_v4(n4acl, &p, &mask_ace, pacl, &pace, flags);
747 if (error)
748 goto out_acl;
749 693
750 error = group_obj_and_groups_from_v4(n4acl, &p, &mask_ace, pacl, &pace, 694 ret = init_state(&state, n4acl->naces);
751 flags); 695 if (ret)
752 if (error) 696 return ERR_PTR(ret);
753 goto out_acl;
754 697
755 error = mask_from_v4(n4acl, &p, &mask_ace, pacl, &pace, flags); 698 list_for_each_entry(ace, &n4acl->ace_head, l_ace)
756 if (error) 699 process_one_v4_ace(&state, ace);
757 goto out_acl;
758 error = other_from_v4(n4acl, &p, pacl, &pace, flags);
759 if (error)
760 goto out_acl;
761 700
762 error = -EINVAL; 701 pacl = posix_state_to_acl(&state, flags);
763 if (p->next != &n4acl->ace_head)
764 goto out_acl;
765 if (pace != pacl->a_entries + pacl->a_count)
766 goto out_acl;
767 702
768 sort_pacl(pacl); 703 free_state(&state);
769 704
770 return pacl; 705 if (!IS_ERR(pacl))
771out_acl: 706 sort_pacl(pacl);
772 posix_acl_release(pacl);
773out_err:
774 pacl = ERR_PTR(error);
775 return pacl; 707 return pacl;
776} 708}
777 709
@@ -785,6 +717,10 @@ nfs4_acl_split(struct nfs4_acl *acl, struct nfs4_acl *dacl)
785 list_for_each_safe(h, n, &acl->ace_head) { 717 list_for_each_safe(h, n, &acl->ace_head) {
786 ace = list_entry(h, struct nfs4_ace, l_ace); 718 ace = list_entry(h, struct nfs4_ace, l_ace);
787 719
720 if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
721 ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
722 return -EINVAL;
723
788 if ((ace->flag & NFS4_INHERITANCE_FLAGS) 724 if ((ace->flag & NFS4_INHERITANCE_FLAGS)
789 != NFS4_INHERITANCE_FLAGS) 725 != NFS4_INHERITANCE_FLAGS)
790 continue; 726 continue;
@@ -930,23 +866,6 @@ nfs4_acl_write_who(int who, char *p)
930 return -1; 866 return -1;
931} 867}
932 868
933static inline int
934match_who(struct nfs4_ace *ace, uid_t owner, gid_t group, uid_t who)
935{
936 switch (ace->whotype) {
937 case NFS4_ACL_WHO_NAMED:
938 return who == ace->who;
939 case NFS4_ACL_WHO_OWNER:
940 return who == owner;
941 case NFS4_ACL_WHO_GROUP:
942 return who == group;
943 case NFS4_ACL_WHO_EVERYONE:
944 return 1;
945 default:
946 return 0;
947 }
948}
949
950EXPORT_SYMBOL(nfs4_acl_new); 869EXPORT_SYMBOL(nfs4_acl_new);
951EXPORT_SYMBOL(nfs4_acl_free); 870EXPORT_SYMBOL(nfs4_acl_free);
952EXPORT_SYMBOL(nfs4_acl_add_ace); 871EXPORT_SYMBOL(nfs4_acl_add_ace);