+- add patches.fixes/linux-post-2.6.3-20040220
[linux-flexiantxendom0-3.2.10.git] / fs / nfsd / auth.c
index 6b1327d..5f630c6 100644 (file)
 #include <linux/nfsd/nfsd.h>
 
 #define        CAP_NFSD_MASK (CAP_FS_MASK|CAP_TO_MASK(CAP_SYS_RESOURCE))
-void
-nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
+
+int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
 {
        struct svc_cred *cred = &rqstp->rq_cred;
-       int             i;
+       struct group_info *group_info;
+       int ngroups;
+       int i;
+       int ret;
+
+       ngroups = 0;
+       if (!(exp->ex_flags & NFSEXP_ALLSQUASH)) {
+               for (i = 0; i < SVC_CRED_NGROUPS; i++) {
+                       if (cred->cr_groups[i] == (gid_t)NOGROUP)
+                               break;
+                       ngroups++;
+               }
+       }
+       group_info = groups_alloc(ngroups);
+       if (group_info == NULL)
+               return -ENOMEM;
 
        if (exp->ex_flags & NFSEXP_ALLSQUASH) {
                cred->cr_uid = exp->ex_anon_uid;
@@ -26,7 +41,7 @@ nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
                        cred->cr_uid = exp->ex_anon_uid;
                if (!cred->cr_gid)
                        cred->cr_gid = exp->ex_anon_gid;
-               for (i = 0; i < NGROUPS; i++)
+               for (i = 0; i < SVC_CRED_NGROUPS; i++)
                        if (!cred->cr_groups[i])
                                cred->cr_groups[i] = exp->ex_anon_gid;
        }
@@ -39,19 +54,24 @@ nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
                current->fsgid = cred->cr_gid;
        else
                current->fsgid = exp->ex_anon_gid;
-       for (i = 0; i < NGROUPS; i++) {
+
+       for (i = 0; i < SVC_CRED_NGROUPS; i++) {
                gid_t group = cred->cr_groups[i];
                if (group == (gid_t) NOGROUP)
                        break;
-               current->groups[i] = group;
+               GROUP_AT(group_info, i) = group;
        }
-       current->ngroups = i;
 
-       if ((cred->cr_uid)) {
-               cap_t(current->cap_effective) &= ~CAP_NFSD_MASK;
-       } else {
-               cap_t(current->cap_effective) |= (CAP_NFSD_MASK &
-                                                 current->cap_permitted);
+       ret = set_current_groups(group_info);
+       if (ret == 0) {
+               if ((cred->cr_uid)) {
+                       cap_t(current->cap_effective) &= ~CAP_NFSD_MASK;
+               } else {
+                       cap_t(current->cap_effective) |= (CAP_NFSD_MASK &
+                                                       current->cap_permitted);
+               }
        }
+       put_group_info(group_info);
 
+       return ret;
 }