diff options
| -rw-r--r-- | net/sunrpc/svcauth_unix.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 117f68a8aa4..97cc3de7432 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
| @@ -655,23 +655,25 @@ static struct unix_gid *unix_gid_lookup(uid_t uid) | |||
| 655 | return NULL; | 655 | return NULL; |
| 656 | } | 656 | } |
| 657 | 657 | ||
| 658 | static int unix_gid_find(uid_t uid, struct group_info **gip, | 658 | static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp) |
| 659 | struct svc_rqst *rqstp) | ||
| 660 | { | 659 | { |
| 661 | struct unix_gid *ug = unix_gid_lookup(uid); | 660 | struct unix_gid *ug; |
| 661 | struct group_info *gi; | ||
| 662 | int ret; | ||
| 663 | |||
| 664 | ug = unix_gid_lookup(uid); | ||
| 662 | if (!ug) | 665 | if (!ug) |
| 663 | return -EAGAIN; | 666 | return ERR_PTR(-EAGAIN); |
| 664 | switch (cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle)) { | 667 | ret = cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle); |
| 668 | switch (ret) { | ||
| 665 | case -ENOENT: | 669 | case -ENOENT: |
| 666 | *gip = NULL; | 670 | return ERR_PTR(-ENOENT); |
| 667 | return 0; | ||
| 668 | case 0: | 671 | case 0: |
| 669 | *gip = ug->gi; | 672 | gi = get_group_info(ug->gi); |
| 670 | get_group_info(*gip); | ||
| 671 | cache_put(&ug->h, &unix_gid_cache); | 673 | cache_put(&ug->h, &unix_gid_cache); |
| 672 | return 0; | 674 | return gi; |
| 673 | default: | 675 | default: |
| 674 | return -EAGAIN; | 676 | return ERR_PTR(-EAGAIN); |
| 675 | } | 677 | } |
| 676 | } | 678 | } |
| 677 | 679 | ||
| @@ -681,6 +683,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) | |||
| 681 | struct sockaddr_in *sin; | 683 | struct sockaddr_in *sin; |
| 682 | struct sockaddr_in6 *sin6, sin6_storage; | 684 | struct sockaddr_in6 *sin6, sin6_storage; |
| 683 | struct ip_map *ipm; | 685 | struct ip_map *ipm; |
| 686 | struct group_info *gi; | ||
| 687 | struct svc_cred *cred = &rqstp->rq_cred; | ||
| 684 | 688 | ||
| 685 | switch (rqstp->rq_addr.ss_family) { | 689 | switch (rqstp->rq_addr.ss_family) { |
| 686 | case AF_INET: | 690 | case AF_INET: |
| @@ -722,6 +726,17 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) | |||
| 722 | ip_map_cached_put(rqstp, ipm); | 726 | ip_map_cached_put(rqstp, ipm); |
| 723 | break; | 727 | break; |
| 724 | } | 728 | } |
| 729 | |||
| 730 | gi = unix_gid_find(cred->cr_uid, rqstp); | ||
| 731 | switch (PTR_ERR(gi)) { | ||
| 732 | case -EAGAIN: | ||
| 733 | return SVC_DROP; | ||
| 734 | case -ENOENT: | ||
| 735 | break; | ||
| 736 | default: | ||
| 737 | put_group_info(cred->cr_group_info); | ||
| 738 | cred->cr_group_info = gi; | ||
| 739 | } | ||
| 725 | return SVC_OK; | 740 | return SVC_OK; |
| 726 | } | 741 | } |
| 727 | 742 | ||
| @@ -818,19 +833,11 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
| 818 | slen = svc_getnl(argv); /* gids length */ | 833 | slen = svc_getnl(argv); /* gids length */ |
| 819 | if (slen > 16 || (len -= (slen + 2)*4) < 0) | 834 | if (slen > 16 || (len -= (slen + 2)*4) < 0) |
| 820 | goto badcred; | 835 | goto badcred; |
| 821 | if (unix_gid_find(cred->cr_uid, &cred->cr_group_info, rqstp) | 836 | cred->cr_group_info = groups_alloc(slen); |
| 822 | == -EAGAIN) | 837 | if (cred->cr_group_info == NULL) |
| 823 | return SVC_DROP; | 838 | return SVC_DROP; |
| 824 | if (cred->cr_group_info == NULL) { | 839 | for (i = 0; i < slen; i++) |
| 825 | cred->cr_group_info = groups_alloc(slen); | 840 | GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv); |
| 826 | if (cred->cr_group_info == NULL) | ||
| 827 | return SVC_DROP; | ||
| 828 | for (i = 0; i < slen; i++) | ||
| 829 | GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv); | ||
| 830 | } else { | ||
| 831 | for (i = 0; i < slen ; i++) | ||
| 832 | svc_getnl(argv); | ||
| 833 | } | ||
| 834 | if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { | 841 | if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { |
| 835 | *authp = rpc_autherr_badverf; | 842 | *authp = rpc_autherr_badverf; |
| 836 | return SVC_DENIED; | 843 | return SVC_DENIED; |
