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