^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include "nfsd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "auth.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) struct exp_flavor_info *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) for (f = exp->ex_flavors; f < end; f++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) if (f->pseudoflavor == rqstp->rq_cred.cr_flavor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) return f->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) return exp->ex_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct group_info *rqgi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct group_info *gi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct cred *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int flags = nfsexp_flags(rqstp, exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) validate_process_creds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* discard any old override before preparing the new set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) revert_creds(get_cred(current_real_cred()));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) new = prepare_creds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (!new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) new->fsuid = rqstp->rq_cred.cr_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) new->fsgid = rqstp->rq_cred.cr_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) rqgi = rqstp->rq_cred.cr_group_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (flags & NFSEXP_ALLSQUASH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) new->fsuid = exp->ex_anon_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) new->fsgid = exp->ex_anon_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) gi = groups_alloc(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (!gi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) goto oom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) } else if (flags & NFSEXP_ROOTSQUASH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (uid_eq(new->fsuid, GLOBAL_ROOT_UID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) new->fsuid = exp->ex_anon_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (gid_eq(new->fsgid, GLOBAL_ROOT_GID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) new->fsgid = exp->ex_anon_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) gi = groups_alloc(rqgi->ngroups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (!gi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) goto oom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) for (i = 0; i < rqgi->ngroups; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (gid_eq(GLOBAL_ROOT_GID, rqgi->gid[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) gi->gid[i] = exp->ex_anon_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) gi->gid[i] = rqgi->gid[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Each thread allocates its own gi, no race */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) groups_sort(gi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) gi = get_group_info(rqgi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (uid_eq(new->fsuid, INVALID_UID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) new->fsuid = exp->ex_anon_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (gid_eq(new->fsgid, INVALID_GID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) new->fsgid = exp->ex_anon_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) set_groups(new, gi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) put_group_info(gi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!uid_eq(new->fsuid, GLOBAL_ROOT_UID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) new->cap_effective = cap_drop_nfsd_set(new->cap_effective);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) new->cap_permitted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) validate_process_creds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) put_cred(override_creds(new));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) put_cred(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) validate_process_creds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) oom:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) abort_creds(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)