Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
0003 
0004 #include <linux/sched.h>
0005 #include "nfsd.h"
0006 #include "auth.h"
0007 
0008 int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
0009 {
0010     struct exp_flavor_info *f;
0011     struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors;
0012 
0013     for (f = exp->ex_flavors; f < end; f++) {
0014         if (f->pseudoflavor == rqstp->rq_cred.cr_flavor)
0015             return f->flags;
0016     }
0017     return exp->ex_flags;
0018 
0019 }
0020 
0021 int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
0022 {
0023     struct group_info *rqgi;
0024     struct group_info *gi;
0025     struct cred *new;
0026     int i;
0027     int flags = nfsexp_flags(rqstp, exp);
0028 
0029     validate_process_creds();
0030 
0031     /* discard any old override before preparing the new set */
0032     revert_creds(get_cred(current_real_cred()));
0033     new = prepare_creds();
0034     if (!new)
0035         return -ENOMEM;
0036 
0037     new->fsuid = rqstp->rq_cred.cr_uid;
0038     new->fsgid = rqstp->rq_cred.cr_gid;
0039 
0040     rqgi = rqstp->rq_cred.cr_group_info;
0041 
0042     if (flags & NFSEXP_ALLSQUASH) {
0043         new->fsuid = exp->ex_anon_uid;
0044         new->fsgid = exp->ex_anon_gid;
0045         gi = groups_alloc(0);
0046         if (!gi)
0047             goto oom;
0048     } else if (flags & NFSEXP_ROOTSQUASH) {
0049         if (uid_eq(new->fsuid, GLOBAL_ROOT_UID))
0050             new->fsuid = exp->ex_anon_uid;
0051         if (gid_eq(new->fsgid, GLOBAL_ROOT_GID))
0052             new->fsgid = exp->ex_anon_gid;
0053 
0054         gi = groups_alloc(rqgi->ngroups);
0055         if (!gi)
0056             goto oom;
0057 
0058         for (i = 0; i < rqgi->ngroups; i++) {
0059             if (gid_eq(GLOBAL_ROOT_GID, rqgi->gid[i]))
0060                 gi->gid[i] = exp->ex_anon_gid;
0061             else
0062                 gi->gid[i] = rqgi->gid[i];
0063         }
0064 
0065         /* Each thread allocates its own gi, no race */
0066         groups_sort(gi);
0067     } else {
0068         gi = get_group_info(rqgi);
0069     }
0070 
0071     if (uid_eq(new->fsuid, INVALID_UID))
0072         new->fsuid = exp->ex_anon_uid;
0073     if (gid_eq(new->fsgid, INVALID_GID))
0074         new->fsgid = exp->ex_anon_gid;
0075 
0076     set_groups(new, gi);
0077     put_group_info(gi);
0078 
0079     if (!uid_eq(new->fsuid, GLOBAL_ROOT_UID))
0080         new->cap_effective = cap_drop_nfsd_set(new->cap_effective);
0081     else
0082         new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
0083                             new->cap_permitted);
0084     validate_process_creds();
0085     put_cred(override_creds(new));
0086     put_cred(new);
0087     validate_process_creds();
0088     return 0;
0089 
0090 oom:
0091     abort_creds(new);
0092     return -ENOMEM;
0093 }
0094