aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/auth.c')
-rw-r--r--fs/nfsd/auth.c92
1 files changed, 52 insertions, 40 deletions
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c
index 808fc03a6fbd..836ffa1047d9 100644
--- a/fs/nfsd/auth.c
+++ b/fs/nfsd/auth.c
@@ -27,55 +27,67 @@ int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
27 27
28int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) 28int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
29{ 29{
30 struct cred *act_as = current->cred ; 30 struct group_info *rqgi;
31 struct svc_cred cred = rqstp->rq_cred; 31 struct group_info *gi;
32 struct cred *new;
32 int i; 33 int i;
33 int flags = nfsexp_flags(rqstp, exp); 34 int flags = nfsexp_flags(rqstp, exp);
34 int ret; 35 int ret;
35 36
37 new = prepare_creds();
38 if (!new)
39 return -ENOMEM;
40
41 new->fsuid = rqstp->rq_cred.cr_uid;
42 new->fsgid = rqstp->rq_cred.cr_gid;
43
44 rqgi = rqstp->rq_cred.cr_group_info;
45
36 if (flags & NFSEXP_ALLSQUASH) { 46 if (flags & NFSEXP_ALLSQUASH) {
37 cred.cr_uid = exp->ex_anon_uid; 47 new->fsuid = exp->ex_anon_uid;
38 cred.cr_gid = exp->ex_anon_gid; 48 new->fsgid = exp->ex_anon_gid;
39 cred.cr_group_info = groups_alloc(0); 49 gi = groups_alloc(0);
40 } else if (flags & NFSEXP_ROOTSQUASH) { 50 } else if (flags & NFSEXP_ROOTSQUASH) {
41 struct group_info *gi; 51 if (!new->fsuid)
42 if (!cred.cr_uid) 52 new->fsuid = exp->ex_anon_uid;
43 cred.cr_uid = exp->ex_anon_uid; 53 if (!new->fsgid)
44 if (!cred.cr_gid) 54 new->fsgid = exp->ex_anon_gid;
45 cred.cr_gid = exp->ex_anon_gid;
46 gi = groups_alloc(cred.cr_group_info->ngroups);
47 if (gi)
48 for (i = 0; i < cred.cr_group_info->ngroups; i++) {
49 if (!GROUP_AT(cred.cr_group_info, i))
50 GROUP_AT(gi, i) = exp->ex_anon_gid;
51 else
52 GROUP_AT(gi, i) = GROUP_AT(cred.cr_group_info, i);
53 }
54 cred.cr_group_info = gi;
55 } else
56 get_group_info(cred.cr_group_info);
57
58 if (cred.cr_uid != (uid_t) -1)
59 act_as->fsuid = cred.cr_uid;
60 else
61 act_as->fsuid = exp->ex_anon_uid;
62 if (cred.cr_gid != (gid_t) -1)
63 act_as->fsgid = cred.cr_gid;
64 else
65 act_as->fsgid = exp->ex_anon_gid;
66 55
67 if (!cred.cr_group_info) 56 gi = groups_alloc(rqgi->ngroups);
68 return -ENOMEM; 57 if (!gi)
69 ret = set_groups(act_as, cred.cr_group_info); 58 goto oom;
70 put_group_info(cred.cr_group_info); 59
71 if ((cred.cr_uid)) { 60 for (i = 0; i < rqgi->ngroups; i++) {
72 act_as->cap_effective = 61 if (!GROUP_AT(rqgi, i))
73 cap_drop_nfsd_set(act_as->cap_effective); 62 GROUP_AT(gi, i) = exp->ex_anon_gid;
63 else
64 GROUP_AT(gi, i) = GROUP_AT(rqgi, i);
65 }
74 } else { 66 } else {
75 act_as->cap_effective = 67 gi = get_group_info(rqgi);
76 cap_raise_nfsd_set(act_as->cap_effective,
77 act_as->cap_permitted);
78 } 68 }
69
70 if (new->fsuid == (uid_t) -1)
71 new->fsuid = exp->ex_anon_uid;
72 if (new->fsgid == (gid_t) -1)
73 new->fsgid = exp->ex_anon_gid;
74
75 ret = set_groups(new, gi);
76 put_group_info(gi);
77 if (!ret)
78 goto error;
79
80 if (new->uid)
81 new->cap_effective = cap_drop_nfsd_set(new->cap_effective);
82 else
83 new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
84 new->cap_permitted);
85 return commit_creds(new);
86
87oom:
88 ret = -ENOMEM;
89error:
90 abort_creds(new);
79 return ret; 91 return ret;
80} 92}
81 93