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