1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
27663dacdSJ. Bruce Fields /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
31da177e4SLinus Torvalds
41da177e4SLinus Torvalds #include <linux/sched.h>
59a74af21SBoaz Harrosh #include "nfsd.h"
6a254b246SHarvey Harrison #include "auth.h"
71da177e4SLinus Torvalds
nfsexp_flags(struct svc_rqst * rqstp,struct svc_export * exp)8c7d51402SJ. Bruce Fields int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
91269bc69SJ. Bruce Fields {
101269bc69SJ. Bruce Fields struct exp_flavor_info *f;
111269bc69SJ. Bruce Fields struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors;
121269bc69SJ. Bruce Fields
131269bc69SJ. Bruce Fields for (f = exp->ex_flavors; f < end; f++) {
14d5497fc6SJ. Bruce Fields if (f->pseudoflavor == rqstp->rq_cred.cr_flavor)
151269bc69SJ. Bruce Fields return f->flags;
161269bc69SJ. Bruce Fields }
171269bc69SJ. Bruce Fields return exp->ex_flags;
181269bc69SJ. Bruce Fields
191269bc69SJ. Bruce Fields }
201269bc69SJ. Bruce Fields
nfsd_setuser(struct svc_rqst * rqstp,struct svc_export * exp)211da177e4SLinus Torvalds int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
221da177e4SLinus Torvalds {
23d84f4f99SDavid Howells struct group_info *rqgi;
24d84f4f99SDavid Howells struct group_info *gi;
25d84f4f99SDavid Howells struct cred *new;
261da177e4SLinus Torvalds int i;
271269bc69SJ. Bruce Fields int flags = nfsexp_flags(rqstp, exp);
281da177e4SLinus Torvalds
293b11a1deSDavid Howells /* discard any old override before preparing the new set */
30ae4b884fSJeff Layton revert_creds(get_cred(current_real_cred()));
31d84f4f99SDavid Howells new = prepare_creds();
32d84f4f99SDavid Howells if (!new)
33d84f4f99SDavid Howells return -ENOMEM;
34d84f4f99SDavid Howells
35d84f4f99SDavid Howells new->fsuid = rqstp->rq_cred.cr_uid;
36d84f4f99SDavid Howells new->fsgid = rqstp->rq_cred.cr_gid;
37d84f4f99SDavid Howells
38d84f4f99SDavid Howells rqgi = rqstp->rq_cred.cr_group_info;
39d84f4f99SDavid Howells
401269bc69SJ. Bruce Fields if (flags & NFSEXP_ALLSQUASH) {
41d84f4f99SDavid Howells new->fsuid = exp->ex_anon_uid;
42d84f4f99SDavid Howells new->fsgid = exp->ex_anon_gid;
43d84f4f99SDavid Howells gi = groups_alloc(0);
44bf935a78SJ. Bruce Fields if (!gi)
45bf935a78SJ. Bruce Fields goto oom;
461269bc69SJ. Bruce Fields } else if (flags & NFSEXP_ROOTSQUASH) {
476fab8779SEric W. Biederman if (uid_eq(new->fsuid, GLOBAL_ROOT_UID))
48d84f4f99SDavid Howells new->fsuid = exp->ex_anon_uid;
496fab8779SEric W. Biederman if (gid_eq(new->fsgid, GLOBAL_ROOT_GID))
50d84f4f99SDavid Howells new->fsgid = exp->ex_anon_gid;
51d84f4f99SDavid Howells
52d84f4f99SDavid Howells gi = groups_alloc(rqgi->ngroups);
53d84f4f99SDavid Howells if (!gi)
54d84f4f99SDavid Howells goto oom;
55d84f4f99SDavid Howells
56d84f4f99SDavid Howells for (i = 0; i < rqgi->ngroups; i++) {
5781243eacSAlexey Dobriyan if (gid_eq(GLOBAL_ROOT_GID, rqgi->gid[i]))
5881243eacSAlexey Dobriyan gi->gid[i] = exp->ex_anon_gid;
591da177e4SLinus Torvalds else
6081243eacSAlexey Dobriyan gi->gid[i] = rqgi->gid[i];
61*19952667SBen Hutchings }
62bdcf0a42SThiago Rafael Becker
63bdcf0a42SThiago Rafael Becker /* Each thread allocates its own gi, no race */
64bdcf0a42SThiago Rafael Becker groups_sort(gi);
651da177e4SLinus Torvalds } else {
66d84f4f99SDavid Howells gi = get_group_info(rqgi);
671da177e4SLinus Torvalds }
68d84f4f99SDavid Howells
696fab8779SEric W. Biederman if (uid_eq(new->fsuid, INVALID_UID))
70d84f4f99SDavid Howells new->fsuid = exp->ex_anon_uid;
716fab8779SEric W. Biederman if (gid_eq(new->fsgid, INVALID_GID))
72d84f4f99SDavid Howells new->fsgid = exp->ex_anon_gid;
73d84f4f99SDavid Howells
748f6c5ffcSWang YanQing set_groups(new, gi);
75d84f4f99SDavid Howells put_group_info(gi);
76d84f4f99SDavid Howells
776fab8779SEric W. Biederman if (!uid_eq(new->fsuid, GLOBAL_ROOT_UID))
78d84f4f99SDavid Howells new->cap_effective = cap_drop_nfsd_set(new->cap_effective);
79d84f4f99SDavid Howells else
80d84f4f99SDavid Howells new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
81d84f4f99SDavid Howells new->cap_permitted);
823b11a1deSDavid Howells put_cred(override_creds(new));
83b914152aSJ. Bruce Fields put_cred(new);
843b11a1deSDavid Howells return 0;
85d84f4f99SDavid Howells
86d84f4f99SDavid Howells oom:
87d84f4f99SDavid Howells abort_creds(new);
8861a27f08SKinglong Mee return -ENOMEM;
891da177e4SLinus Torvalds }
90b6dff3ecSDavid Howells
91